prod-watch #263
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
| # prod-watch — vigia o que o EDGE está servindo, não o que o repo diz. | |
| # | |
| # O CASO QUE COMPROU ESTE WORKFLOW (08/08/2026): o site inteiro fora do ar com | |
| # "The requested module './fparms.js' does not provide an export named 'preloadStaticVm'" | |
| # A origem Vercel estava íntegra; a Cloudflare (edge TTL de 1 mês sobre /js/*, | |
| # `?v=2` fixo na época) servia main.js de um deploy com fparms.js de outro. | |
| # Repo verde, build verde, produção morta — nenhum portão media a interseção. | |
| # O probe é `tools/eval/prod-coherence.mjs` (leia o cabeçalho dele). | |
| # | |
| # DOIS GATILHOS: | |
| # · cron a cada 15 min — cache podre pode nascer a qualquer deploy; | |
| # · deployment_status success em production — a janela de risco é logo após | |
| # publicar; aproveita e PURGA o edge (Fase 3: cinto e suspensório, ver | |
| # scripts/cloudflare-setup.sh para a regra que segura /js/* por 1 mês). | |
| # | |
| # EM FALHA: dispara repository_dispatch `prod-crash`, que o crash-fix.yml | |
| # consome. O GITHUB_TOKEN dispara dispatch com `actions: write` (a proteção | |
| # anti-recursão do GitHub barra eventos de PUSH criados pelo token, não | |
| # repository_dispatch — é o caminho oficial entre workflows). | |
| name: prod-watch | |
| on: | |
| schedule: | |
| - cron: '*/15 * * * *' | |
| deployment_status: | |
| workflow_dispatch: | |
| permissions: | |
| # contents: write é o que autoriza POST /dispatches com GITHUB_TOKEN | |
| # (actions: write NÃO autoriza — o dispatch morria 403 e o crash-fix nunca | |
| # rodava; pego na review do Greptile, PR #95) | |
| contents: write | |
| jobs: | |
| probe: | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 10 | |
| # deployment_status: só produção bem-sucedida interessa (preview não é prod). | |
| if: >- | |
| github.event_name != 'deployment_status' || | |
| (github.event.deployment_status.state == 'success' && | |
| github.event.deployment.environment == 'production') | |
| env: | |
| CF_API_TOKEN: ${{ secrets.CF_API_TOKEN }} | |
| steps: | |
| - uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 | |
| - uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 | |
| with: { node-version: 22 } | |
| # Purge pós-deploy ANTES do probe: medir o edge velho acusaria o deploy | |
| # novo. Sem o secret cadastrado, pula — o probe ainda vale. | |
| # (o secret mora no env DO JOB: `if` de step não enxerga env do próprio step) | |
| - name: purge do edge Cloudflare (/js/* + /style.css) | |
| if: env.CF_API_TOKEN != '' | |
| run: | | |
| ZONE_ID=$(curl -sS -H "Authorization: Bearer $CF_API_TOKEN" \ | |
| "https://api.cloudflare.com/client/v4/zones?name=csbrasil.online" \ | |
| | node -e "let s='';process.stdin.on('data',d=>s+=d).on('end',()=>console.log(JSON.parse(s).result[0].id))") | |
| curl -sS -X POST -H "Authorization: Bearer $CF_API_TOKEN" -H "Content-Type: application/json" \ | |
| --data '{"prefixes":["www.csbrasil.online/js/","www.csbrasil.online/style.css"]}' \ | |
| "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/purge_cache" | |
| - name: probe de coerência do edge | |
| id: probe | |
| run: node tools/eval/prod-coherence.mjs https://www.csbrasil.online | |
| - name: probe do banco e schema de telemetria | |
| run: | | |
| node --input-type=module - <<'NODE' | |
| const response = await fetch('https://www.csbrasil.online/api/health'); | |
| const body = await response.json().catch(() => ({})); | |
| console.log(JSON.stringify(body)); | |
| if (!response.ok || body.database !== true || body.telemetrySchema !== true || body.fresh !== true) { | |
| process.exit(1); | |
| } | |
| NODE | |
| - name: produção inconsistente → dispara prod-crash | |
| if: failure() | |
| env: | |
| GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| run: | | |
| gh api repos/{owner}/{repo}/dispatches -X POST \ | |
| -f event_type=prod-crash \ | |
| -F 'client_payload[fingerprint]=producao-inconsistente' \ | |
| -F 'client_payload[message]=prod-watch: edge, banco ou schema de telemetria reprovou' \ | |
| -F 'client_payload[source]=prod-watch.yml' \ | |
| -F 'client_payload[version]=desconhecida' |