fix(tracker-web): versioned BFF base /api/v1 + build .dockerignore (GT-447) #54
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Deploy check (kind + Helm + smoke) | |
| # Este job vivia en `ci.yml` y se saco a su propio fichero por UNA razon: poder | |
| # filtrarlo por rutas. Tarda ~7 minutos —levanta un cluster de Kubernetes, construye | |
| # dos imagenes y redespliega en perfil de produccion— y se disparaba tambien cuando | |
| # el cambio eran dos ficheros markdown. Medido el 2026-07-20: publicar la ficha | |
| # GT-474, que solo tocaba documentacion, costo 14 minutos de CI entre `develop` y | |
| # `main`. | |
| # | |
| # SE USA `paths-ignore` Y NO `paths`, Y LA DIFERENCIA ES DE SEGURIDAD, NO DE ESTILO. | |
| # Una lista blanca (`paths`) se queda obsoleta EN SILENCIO: alguien anade una carpeta | |
| # de codigo nueva, nadie la incluye, y el despliegue deja de comprobarse sin que nada | |
| # avise — exactamente la clase de hueco que este job existe para cerrar. Una lista | |
| # negra falla al reves: ante la duda, corre. | |
| # | |
| # Por eso lo ignorado es SOLO lo demostrablemente inerte. `.harness/` NO esta: sus | |
| # scripts los ejecuta CI. | |
| # NO corre en push a `main`, y es deliberado. El merge a `main` es contenido | |
| # IDENTICO al de `develop` —siempre `--no-ff` de develop, nunca commits sueltos— | |
| # que ya paso este mismo job minutos antes. Correrlo dos veces sobre el mismo | |
| # arbol costaba 7 minutos por nada: era la mitad del tiempo de publicar. | |
| # | |
| # EL RIESGO, dicho: un commit directo a `main` que no venga de `develop` se salta | |
| # esta comprobacion. El flujo del repositorio no hace eso —se publica siempre por | |
| # develop— pero si alguien empieza a hacerlo, esto deja de cubrirlo y hay que | |
| # volver a poner `main` aqui. Queda escrito para que la decision se revise a | |
| # proposito y no se descubra por sorpresa. | |
| on: | |
| push: | |
| branches: [develop] | |
| paths-ignore: | |
| - 'docs/**' | |
| - '*.md' | |
| pull_request: | |
| branches: [main, develop] | |
| paths-ignore: | |
| - 'docs/**' | |
| - '*.md' | |
| permissions: | |
| contents: read | |
| concurrency: | |
| group: deploy-${{ github.workflow }}-${{ github.ref }} | |
| cancel-in-progress: true | |
| jobs: | |
| deploy: | |
| name: Deploy (kind + Helm + smoke) | |
| runs-on: ubuntu-latest | |
| # Anadido el 2026-07-20, despues de que el PRIMER despliegue real destapara tres defectos | |
| # de golpe (GT-460, CD-15, GT-461) que ni las 894 pruebas ni el resto de CI podian ver. | |
| # | |
| # Los tres vivian en el hueco entre lo que CI ejercitaba y lo que producción recorre: CI | |
| # aplicaba migraciones con `dotnet ef database update` y el clúster usa el BUNDLE de la | |
| # imagen —caminos distintos, y solo uno cubierto—; los secretos que el chart exige no los | |
| # creaba nadie; y el smoke apuntaba a rutas anteriores al versionado de la API. Ninguno | |
| # era detectable leyendo: aparecieron al desplegar. | |
| # | |
| # Este job cierra ese hueco corriendo LITERALMENTE el mismo comando que corre un | |
| # desarrollador. Por eso `kind` se instala como binario en vez de usar una accion que | |
| # cree el clúster por su cuenta: si CI usara un camino propio, volveria a haber dos | |
| # caminos y uno sin cubrir, que es la causa raiz que este job existe para eliminar. | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v4 | |
| - name: Instalar kind | |
| # kubectl, helm y docker vienen en el runner; kind no. | |
| # | |
| # `sudo install` y no `curl -o` directo: el runner no puede dar permisos de ejecucion | |
| # dentro de /usr/local/bin, asi que la descarga cuela y el `chmod` revienta despues. | |
| run: | | |
| curl -fsSLo /tmp/kind \ | |
| https://kind.sigs.k8s.io/dl/v0.24.0/kind-linux-amd64 | |
| sudo install -m 0755 /tmp/kind /usr/local/bin/kind | |
| kind --version | |
| - name: Levantar el stack (kind + build + load + Helm + migraciones) | |
| run: bash product/infra/helm/local-test.sh up | |
| - name: Smoke contra el despliegue vivo | |
| env: | |
| SMOKE_OBSERVE_SECONDS: "25" | |
| run: bash product/infra/helm/local-test.sh smoke | |
| # OPP-003 / RoboSoft — agentes E2E deterministicos contra el despliegue LOCAL | |
| # (dev-bypass). Corre aqui, mientras el perfil local esta desplegado y antes del | |
| # redespliegue de produccion, porque los robots actuan por `x-tenant-id` (dev-bypass). | |
| # Ejercitan el funnel SDLC completo, el ciclo ProviderConnection y el aislamiento de | |
| # tenant contra el tracker-api + Postgres reales. `core-integration` se excluye: necesita | |
| # el Core (otro producto), que no se despliega en este pipeline. Este paso MUERDE. | |
| - name: RoboSoft E2E (agentes deterministicos contra el despliegue local) | |
| run: bash product/infra/helm/local-test.sh robosoft | |
| # GT-464 — hasta aqui el despliegue se probaba SOLO con el perimetro abierto: | |
| # `values-local.yaml` corre en Development con `dev-bypass`, que autentica cualquier | |
| # peticion como administrador con todos los permisos. Lo de abajo lo prueba cerrado, | |
| # que es como corre de verdad. | |
| - name: Fail-closed sobre la imagen (el bypass no es alcanzable en Production) | |
| # Va antes de redesplegar porque no necesita clúster: son dos `docker run`, con | |
| # control incluido. Si esto cae, el resto da igual. | |
| run: bash product/infra/helm/local-test.sh verify-failclosed | |
| - name: Redesplegar con el PERFIL DE PRODUCCION | |
| env: | |
| TRACKER_PROFILE: prod | |
| run: | | |
| bash product/infra/helm/local-test.sh down | |
| bash product/infra/helm/local-test.sh install | |
| - name: Smoke de produccion (perimetro CERRADO) | |
| env: | |
| SMOKE_OBSERVE_SECONDS: "25" | |
| run: bash product/infra/helm/local-test.sh smoke-prod | |
| - name: Diagnostico (solo si algo fallo) | |
| # En un runner efimero no queda clúster al que asomarse. El modo de fallo real de | |
| # CD-15 fue `helm --wait` agotandose SIN decir por que: el motivo solo estaba en el | |
| # `describe` del pod. Lo que no se imprima aqui, se pierde. | |
| if: failure() | |
| run: bash product/infra/helm/local-test.sh diagnose | |