feat(release): orquestrador fechar release idempotente, auditado e fail-safe [TMFP-65900] #164

Merged
tmf-ia merged 2 commits from feat/TMFP-65900-orquestrador-fechar-release into develop 2026-11-04 00:07:10 -03:00
Owner

O que muda

Terceira peça do "fechar release" no ci-shared (ADR 0022; epic TMFP-60560): o orquestrador. Ele usa o GitProviderPort (TMFP-65898) e o bloco release: do ci-config (TMFP-65899).

  • scripts/release/fechar_release.py (lógica) e scripts/release/fechar-release.py (CLI). Só stdlib.
  • Passos, nesta ordem:
    1. guarda de identidade: só escreve como tmf-ia, fixo no código; falha fechada;
    2. CI verde no SHA; senão para sem escrever;
    3. tag: valida o tag_pattern; cria se não existe; mesmo SHA → pula; outro SHA → recusa sem escrever nada;
    4. publicação: se já existe run para o SHA não dispara de novo; senão dispara na dispatch_branch e confere o run;
    5. Hub (só com hub_close: true): transiciona as issues passadas explicitamente para o status-alvo (padrão approved; done é recusado, é decisão humana) e comenta o resumo em cada uma; issue já no alvo é pulada.
  • Idempotente: reexecutar não duplica tag, run nem transição.
  • Fail-safe: falha depois da tag não desfaz a tag; o passo fica pendente, o exit é 1, e a reexecução retoma.
  • Auditado: quem disparou, identidade que executou, hora UTC e resultado de cada passo, no job summary (markdown) e em JSON opcional.
  • Exit codes: 0 ok/pulado; 1 falhou ou pendente; 2 uso ou config inválida.

Nenhum workflow chama o orquestrador ainda: isso é a TMFP-71790. Ponto para ela: o dispatch roda na ponta da dispatch_branch e a prova do run procura o SHA da tag, então o workflow deve garantir que a tag está na ponta dessa branch.

Prova local

python3 -m unittest discover -s tests/release-orquestrador -q   -> 22 testes OK
python3 -m unittest discover -s tests/release-provider -q       -> 27 testes OK

Critérios de aceite cobertos por teste: duas execuções seguidas sem segunda tag, run ou transição; dispatch falho com a tag mantida, passo pendente e conclusão na segunda execução; tag em outro SHA recusada sem escrita.

TMFP-65900

🤖 Generated with Claude Code

https://claude.ai/code/session_01ES1xwVdpQV69zEsuLLKzx2

## O que muda Terceira peça do "fechar release" no ci-shared (ADR 0022; epic TMFP-60560): o orquestrador. Ele usa o `GitProviderPort` (TMFP-65898) e o bloco `release:` do ci-config (TMFP-65899). - `scripts/release/fechar_release.py` (lógica) e `scripts/release/fechar-release.py` (CLI). Só stdlib. - Passos, nesta ordem: 1. guarda de identidade: só escreve como `tmf-ia`, fixo no código; falha fechada; 2. CI verde no SHA; senão para sem escrever; 3. tag: valida o `tag_pattern`; cria se não existe; mesmo SHA → pula; outro SHA → recusa sem escrever nada; 4. publicação: se já existe run para o SHA não dispara de novo; senão dispara na `dispatch_branch` e confere o run; 5. Hub (só com `hub_close: true`): transiciona as issues passadas explicitamente para o status-alvo (padrão `approved`; `done` é recusado, é decisão humana) e comenta o resumo em cada uma; issue já no alvo é pulada. - **Idempotente:** reexecutar não duplica tag, run nem transição. - **Fail-safe:** falha depois da tag não desfaz a tag; o passo fica `pendente`, o exit é 1, e a reexecução retoma. - **Auditado:** quem disparou, identidade que executou, hora UTC e resultado de cada passo, no job summary (markdown) e em JSON opcional. - Exit codes: 0 ok/pulado; 1 falhou ou pendente; 2 uso ou config inválida. Nenhum workflow chama o orquestrador ainda: isso é a TMFP-71790. Ponto para ela: o dispatch roda na ponta da `dispatch_branch` e a prova do run procura o SHA da tag, então o workflow deve garantir que a tag está na ponta dessa branch. ## Prova local ``` python3 -m unittest discover -s tests/release-orquestrador -q -> 22 testes OK python3 -m unittest discover -s tests/release-provider -q -> 27 testes OK ``` Critérios de aceite cobertos por teste: duas execuções seguidas sem segunda tag, run ou transição; dispatch falho com a tag mantida, passo pendente e conclusão na segunda execução; tag em outro SHA recusada sem escrita. TMFP-65900 🤖 Generated with [Claude Code](https://claude.com/claude-code) https://claude.ai/code/session_01ES1xwVdpQV69zEsuLLKzx2
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01ES1xwVdpQV69zEsuLLKzx2
merge: develop em feat/TMFP-65900-orquestrador-fechar-release (traz o pin do Trivy, #163)
All checks were successful
PR checks (ci-shared) / testes (pull_request) Successful in 5m13s
316b7b4095
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01ES1xwVdpQV69zEsuLLKzx2
tmf-ia merged commit ae29333127 into develop 2026-11-04 00:07:10 -03:00
Sign in to join this conversation.
No reviewers
No labels
seguranca
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
TMF/ci-shared!164
No description provided.