0020 — Adota o smoke de produção pós-deploy — ponteiro do ADR central 0031¶
Status: Aprovado · Responsável: Gustavo Madruga · Atualizado em: 2026-09-09 · Decidido em: 2026-09-09
Contexto¶
Este RD não decide nada novo: o smoke pós-deploy é norma da casa (constituição §9, ADR central 0031, página smoke-producao). O que faltava aqui era o rastro local — o que este app declarou como crítico, e por quê.
O problema que o smoke resolve alcança este repo em cheio: o POST /api/ci/deploy é assíncrono,
então o pipeline ficava verde antes de o container novo servir. E /health verde é liveness —
prova que a JVM subiu e o Flyway passou, não que as telas renderizam. O maxsul-pied é
justamente um app de telas (painel do colaborador, console, captura, dados, destinatários):
render quebrado com o processo saudável é o modo de falha típico daqui, e nenhum gate o pegava
depois do deploy.
Decisão¶
Adota o smoke nas quatro camadas do 0031, declarando o manifesto no docs/app.json:
"smoke": {
"bases": ["https://pied.maxsul.xadm.biz"],
"glitchtip": { "org": "x-adm", "project": "maxsul-pied" },
"routes": [ { "path": "/health", "class": "public", "status": 200 }, … ]
}
Três escolhas locais, com o porquê:
-
basestem UMA entrada — o domínio público. O app roda dois flavors lado a lado desde av0.7.0(rodízio 50/50 jar/native, 0014), e todo release sai comDeploy: jar,native. Os dois atendem empied.maxsul.xadm.biz, então uma base cobre a superfície pública. Se um dia o recurso native ganhar FQDN próprio, ele entra aqui —basesé a lista onde deploy parcial se esconde.Limite conhecido: dois flavors atrás de uma base
A camada 1 aceita a primeira resposta de
/healthcujocommitbate (até 40 tentativas). Com duas instâncias em rodízio na mesma base, uma resposta do flavor já atualizado satisfaz a camada mesmo que o outro esteja velho — o smoke prova "alguém no ar é desta entrega", não "os dois são". O deploy dispara os dois targets no mesmo run, então a janela é estreita; mas é uma janela, e está declarada em vez de suposta.- Toda rota é
class: public. O app roda commicronaut.security.enabled=false— "tudo aberto atrás da rede" (0004/0005) — logo não há credencial a apresentar nem seam de sessão a instalar. A norma é explícita:classé a credencial que a rota exige, não o público-alvo da tela. Ligar auth aqui um dia obriga reclassificar as rotas e repor os secretsSMOKE_TOKEN/SMOKE_M2M_TOKENno pipeline. - As seis rotas são as telas, não os endpoints internos.
/health(identidade),/(painel do colaborador — a tela que o cliente usa),/captura,/console,/dados/estadoe/destinatarios./webhook/piedfica de fora de propósito: éPOSTcom efeito colateral, e a sonda do smoke éGET. A mesma lista serve dois gates — o e2e do binário native afirma ≠404 antes do deploy; o smoke afirma o status depois.
- Toda rota é
A camada 3 (log-guarantee) fica declarada: nenhuma exceção nova no GlitchTip desde a entrega.
Consequências¶
GLITCHTIP_API_TOKEN(read-only) é obrigatório nos secrets do repo no GitHub. Declararsmoke.glitchtipsem o secret REPROVA o smoke — é defeito de configuração, não degradação: sem ele a camada 3 não roda e o job ficaria "verde provando 2 de 3".- O
commitdo/healthpassa a ser o discriminador de entrega:XADM_COMMITentra como build-arg nos dois Dockerfiles e viraENVna imagem; axadm-comum-web≥ 0.9.0 o expõe. Um identificador só atravessa pipeline, imagem,/health, tag imutável e release no GlitchTip. - Reprovar reverte para
<imagem>:<sha anterior>-<target>e confirma a reversão. Isso torna a tag imutável um ativo operacional: podar a tag que está no/healthde um recurso em produção transforma o rollback em "não confirmado" no pior momento. - Este RD é ponteiro: divergência de mérito sobre o mecanismo se resolve no ADR central 0031, não aqui. O que se decide localmente é o manifesto — quais rotas não podem quebrar.