{"id":50718644,"url":"https://github.com/erseco/action-facturascripts-publicar-forja","last_synced_at":"2026-06-09T21:30:43.087Z","repository":{"id":351585459,"uuid":"1211620834","full_name":"erseco/action-facturascripts-publicar-forja","owner":"erseco","description":"GitHub Action que sube un ZIP de plugin como nuevo build en la forja de FacturaScripts","archived":false,"fork":false,"pushed_at":"2026-04-15T15:55:17.000Z","size":211,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-04-15T17:30:39.710Z","etag":null,"topics":["facturascripts","github-actions","plugin-development"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/erseco.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-04-15T15:18:34.000Z","updated_at":"2026-04-15T15:55:21.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/erseco/action-facturascripts-publicar-forja","commit_stats":null,"previous_names":["erseco/action-facturascripts-publicar-forja"],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/erseco/action-facturascripts-publicar-forja","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/erseco%2Faction-facturascripts-publicar-forja","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/erseco%2Faction-facturascripts-publicar-forja/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/erseco%2Faction-facturascripts-publicar-forja/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/erseco%2Faction-facturascripts-publicar-forja/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/erseco","download_url":"https://codeload.github.com/erseco/action-facturascripts-publicar-forja/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/erseco%2Faction-facturascripts-publicar-forja/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34127342,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-09T02:00:06.510Z","response_time":63,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["facturascripts","github-actions","plugin-development"],"created_at":"2026-06-09T21:30:41.448Z","updated_at":"2026-06-09T21:30:43.078Z","avatar_url":"https://github.com/erseco.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# action-facturascripts-publicar-forja\n\nGitHub Action que sube un ZIP de plugin como nuevo *build* en la [forja de FacturaScripts](https://facturascripts.com/forja) tras una *release*, con opción de promover automáticamente el build a `stable`, `beta` o `0` (no disponible).\n\n## Qué hace\n\n1. Inicia sesión en `https://facturascripts.com` haciendo `POST /MeLogin` con `email` y `passwd`.\n2. Pide la pestaña admin del plugin y extrae un `multireqtoken` fresco del formulario `#f_add_build`.\n3. Sube el ZIP como `multipart/form-data` con `action=add-build`.\n4. Parsea la respuesta para confirmar que aparece una nueva fila de build y expone su id como `output`.\n5. Opcionalmente re-abre el modal de edición del build nuevo y hace un segundo `POST action=edit-build` para fijar su estado (`stable` / `beta` / `0`), preservando `min_php`, `min_core` y `max_core`.\n\nFacturaScripts solo admite versiones numéricas en `facturascripts.ini`: un entero (`version = 7`) o un decimal (`version = 7.1`). Los formatos `1.0.1` o `1.0-beta` se rechazan en la validación, así que la action falla pronto si detecta un tag con ese formato.\n\n## Entradas\n\n| Entrada | Obligatorio | Descripción |\n|---|:---:|---|\n| `plugin-slug` | ✓ | Slug del plugin en la forja en minúsculas (ej. `quickcreate`, `aiscan`). |\n| `zip-path` | ✓ | Ruta local al ZIP generado por el paso anterior del release. |\n| `version` | ✓ | Versión del build. FacturaScripts solo admite entero (`7`) o decimal (`7.1`); se acepta un prefijo opcional `v`. Los formatos `1.0.1` o `1.0-beta` se rechazan. |\n| `forja-user` | ✓ | **Email** con el que entras en facturascripts.com. Usa un secret. |\n| `forja-password` | ✓ | Contraseña de la forja. Usa un secret. |\n| `forja-url` | — | URL base de la forja. Por defecto `https://facturascripts.com`. |\n| `status` | — | Estado final del build nuevo: `stable`, `beta` o `0` (no disponible). Si no se pasa, la forja mantiene el estado por defecto (normalmente `beta`). |\n| `dry-run` | — | Si es `true`, hace login y obtiene el CSRF pero no envía el POST de subida. Por defecto `false`. |\n\n## Salidas\n\n| Salida | Descripción |\n|---|---|\n| `build-id` | Id del nuevo build en la forja. |\n| `build-version` | Versión almacenada en la forja (tras normalización). |\n| `build-url` | URL al admin del plugin, ancla al modal del build nuevo. |\n| `build-status` | Estado final del build si se pasó `status`; vacío si no. |\n\n## Uso\n\nAñade un paso al final de tu workflow de release, después de crear la release en GitHub:\n\n```yaml\nname: Release\n\non:\n  push:\n    tags:\n      - '[0-9]*'\n      - 'v[0-9]*'\n\npermissions:\n  contents: write\n\njobs:\n  release:\n    runs-on: ubuntu-latest\n    steps:\n      - uses: actions/checkout@v6\n\n      - name: Preparar zip\n        id: zip\n        run: |\n          VERSION=${GITHUB_REF_NAME#v}\n          echo \"VERSION=$VERSION\" \u003e\u003e $GITHUB_OUTPUT\n          sed -i \"s/^version.*/version = $VERSION/\" facturascripts.ini\n          git add facturascripts.ini\n          git -c user.email=ci@example.com -c user.name=ci commit -m \"ci: $VERSION\" || true\n          git archive --format=zip --prefix=QuickCreate/ HEAD -o QuickCreate-$VERSION.zip\n\n      - uses: softprops/action-gh-release@v2\n        with:\n          files: QuickCreate-${{ steps.zip.outputs.VERSION }}.zip\n\n      - name: Publicar en la forja\n        uses: erseco/action-facturascripts-publicar-forja@v1\n        with:\n          plugin-slug: quickcreate\n          zip-path: QuickCreate-${{ steps.zip.outputs.VERSION }}.zip\n          version: ${{ steps.zip.outputs.VERSION }}\n          status: stable\n          forja-user: ${{ secrets.FS_FORJA_USER }}\n          forja-password: ${{ secrets.FS_FORJA_PASSWORD }}\n```\n\n### Secrets necesarios\n\nEn cada repo de plugin (o a nivel de organización si tienes varios):\n\n- `FS_FORJA_USER` — el **email** con el que inicias sesión en facturascripts.com.\n- `FS_FORJA_PASSWORD` — la contraseña de la forja.\n\n```bash\ngh secret set FS_FORJA_USER --repo erseco/facturascripts-plugin-quickcreate\ngh secret set FS_FORJA_PASSWORD --repo erseco/facturascripts-plugin-quickcreate\n```\n\n## Requisitos del ZIP\n\nLa forja valida el archivo en el servidor. Los tres campos siguientes deben coincidir **exactamente** (sensible a mayúsculas/minúsculas):\n\n1. La carpeta raíz dentro del ZIP (ej. `QuickCreate/`).\n2. El valor del campo `name` en `facturascripts.ini` (ej. `name = 'QuickCreate'`).\n3. El nombre con el que el plugin está registrado en la forja.\n\nPara la mayoría de plugins ese nombre coincide con el *slug* de la URL (en minúsculas), pero no siempre — el plugin `test` está registrado como `test` con carpeta `test/` y `name = 'test'`.\n\nSi la subida falla con `El nombre de la carpeta del zip debe ser X, en lugar de Y` o `Encontrado name = X en el archivo facturascripts.ini, pero se esperaba name = Y`, ajusta los tres campos al valor que te indica el mensaje.\n\n## Desarrollo\n\n```bash\nnpm install\nnpm test          # tests unitarios (sin red)\nnpm run build     # bundle a dist/index.cjs\n```\n\n### Prueba end-to-end en local\n\nCrea un `.env` (nunca lo commitees):\n\n```\nFS_FORJA_USER=tu_email@example.com\nFS_FORJA_PASSWORD=tu_password\n```\n\nY lanza:\n\n```bash\n# Sin subir (dry run): login + CSRF + construcción del request\nnode scripts/dry-run.js test ./test-0.2.zip 0.2\n\n# Subida real\nnode scripts/dry-run.js test ./test-0.2.zip 0.2 --send\n\n# Subida real + promoción a estable\nnode scripts/dry-run.js test ./test-0.2.zip 0.2 --send --status=stable\n```\n\n## Notas de ingeniería inversa\n\nCapturado en `https://facturascripts.com` el 2026-04-15 y verificado subiendo los builds 3474 y 3475 a `https://facturascripts.com/plugins/test`.\n\n**Login** — `POST /MeLogin`, `application/x-www-form-urlencoded`\n\n- `multireqtoken` — token CSRF obtenido de un `GET /MeLogin` previo.\n- `action=login`\n- `return=/`\n- `email` — el email del usuario (no el `fsNick` del core vanilla).\n- `passwd`\n\nUn login correcto devuelve dos cookies `HttpOnly`: `fsIdcontacto` y `fsLogkey`, ambas necesarias para las llamadas posteriores.\n\n**Subida de build** — `POST /plugins/{slug}`, `multipart/form-data`, formulario `#f_add_build`\n\n- `multireqtoken` — CSRF del `GET /plugins/{slug}?activetab=admin`, extraído del bloque del formulario `#f_add_build`.\n- `action=add-build`\n- `activetab=admin`\n- `version` — numérico, se almacena con `floatval` en PHP.\n- `zip` — el archivo del plugin (máx 99 MB) cumpliendo las reglas de layout de arriba.\n\n**Promoción del build** — `POST /plugins/{slug}`, `application/x-www-form-urlencoded`\n\n- `multireqtoken` — CSRF del modal `#build{id}Modal` en `/plugins/{slug}?activetab=admin`.\n- `action=edit-build`\n- `activetab=admin`\n- `id_build` — id del build a editar.\n- `status` — `stable`, `beta` o `0`.\n- `min_php`, `min_core`, `max_core` — deben reenviarse (el endpoint no hace update parcial). La action los lee del modal actual antes de enviar la promoción.\n\n## Licencia\n\nMIT\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ferseco%2Faction-facturascripts-publicar-forja","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ferseco%2Faction-facturascripts-publicar-forja","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ferseco%2Faction-facturascripts-publicar-forja/lists"}