0014 — Smoke de produção pós-deploy (adota a central 0031)¶
Status: Aprovado · Responsável: Gustavo Madruga · Atualizado em: 2026-09-08 · Decidido em: 2026-09-08
Contexto¶
O deploy do tradutor sai pelo control-plane (POST /api/ci/deploy, central
0026, adotada localmente na
0013) e esse POST é assíncrono: ele retorna sucesso e o
pipeline fica verde antes de o container novo servir. O /health que o Coolify observa é
liveness — o processo subiu e o Flyway passou —, não "as telas respondem". Entre os dois cabe a
classe de falha que a frota já entregou com o app healthy: tela em 500 e segredo ausente que só
apareceu como 401 no cliente.
Aqui a superfície é concreta: o tradutor serve views JTE atrás de sessão (/, /admin,
/admin/monitor) e roda native (0011), onde o AOT pode podar
uma rota registrada — 404 no binário e 200 no jar, sem erro de build. Até agora nada no pipeline
afirmava produção depois do deploy.
A casa fixou o alvo na ADR central 0031 — Smoke de produção pós-deploy (constituição §9; receita em smoke-producao).
Decisão¶
Adotar a central 0031 neste repo, sem variação local. O que isso significa aqui:
- Job
smokenopipeline.yml, depois dodeploy, rodandoscripts/smoke.pyda toolchain. Reprovou em qualquer camada → reverte para a tag imutável<imagem>:<sha anterior>-<target>, confirma a reversão e fica vermelho. - Manifesto em
docs/app.json→smoke: basehttps://webstorm.thoms.xadm.biz, projetothoms-integracao-produto-ecomno GlitchTip e as rotas críticas —/healthe/logincomopublic;/,/admine/admin/monitorcomosession. Sem rotam2m: os dois endpoints Bearer do tradutor (POST /api/csv/processar,POST /api/integrador/produto) são POST, e o smoke só fazGET— declarar um deles daria 405, não cobertura. A mesma lista serve o e2e native (afirma ≠404 no binário, antes do deploy). - Seam de sessão do
xadm-seguranca0.7.0 (POST /smoke/session, headerX-Smoke-Token), ligado porsmoke.token← envSMOKE_TOKEN. Nasce desligado: sem a env o@Requires(pattern=".+")reprova e/smoke/**nem existe (404). Sem ele as rotassessiondegradariam para asserção negativa (302/401), que é o que o login Google interativo permite. - Identidade de build cabeada:
XADM_COMMIT=${{ github.sha }}como build-arg nos dois jobs de build eARG/ENVtarde nos dois Dockerfiles (declarado no topo, invalidaria o cache e onativeCompilede ~13 min rodaria em todo build). O mesmo valor é ocommitdo/health, areleaseno Sentry e o sufixo da tag imutável.
Consequências¶
- Dois segredos novos por ambiente.
SMOKE_TOKENprecisa existir igual nos dois lados — secret no GitHub (jobsmoke) e env no recurso do Coolify (o app) —;GT_TOKEN(read-only do GlitchTip) habilita a camada 3. Faltando oGT_TOKEN, a camada é pulada; faltando oSMOKE_TOKENde um dos lados, as rotassessionreprovam. basescobre uma URL. O app tem dois alvos de deploy (jarenative) e o manifesto declara aproduction_url. Se os dois flavors servirem hostnames distintos, o smoke só afirma o que está declarado — a segunda base tem de entrar na lista, senão metade do deploy fica sem asserção.- A reversão é por imagem, não por instância. O
POSTdo control-plane não tem eixo de instância: uma reversão reverte todas as bases. Divergência de commit entre bases é tratada como drift e trava o rollback, por desenho da central. - O smoke não prova regressão visual nem que o container velho não respondeu durante a troca (ponto cego declarado na central).
Alternativas descartadas¶
- Seguir só com o
/healthdo Coolify. É liveness: foi exatamente o que deixou tela em 500 com apphealthypassar por deploy bem-sucedido. - Esperar o e2e native cobrir. Ele roda antes do deploy, contra o binário, e afirma só ≠404 — não vê o que produção responde depois que o container troca.
- Reusar credencial de gente no seam. Daria mais permissão do que o smoke precisa e apagaria a
fronteira entre quem testou e quem opera; o principal
smokeé próprio, e só-leitura por verbo.