Pular para o conteúdo

Política de release da GitHub Action

O ADR Guard publica sua GitHub Action a partir do mesmo commit validado e da mesma versão de release usados pela .NET Tool e pelas imagens de container.

A linha pública da GitHub Action começa em 1.0.0. Isso promove intencionalmente o baseline do pacote em relação às releases anteriores 0.1.x da CLI, garantindo que a primeira release compatível com o Marketplace publique tanto v1.0.0 quanto a referência de compatibilidade para consumidores v1.

Cada release bem-sucedida publica duas referências da Action:

  • vMAJOR.MINOR.PATCH — imutável. É criada uma única vez e deve sempre apontar para o commit validado daquela release exata.
  • vMAJOR — referência móvel de compatibilidade. Avança para a release bem-sucedida mais recente daquela major e nunca volta para trás quando uma release antiga é reexecutada.

Exemplos:

# Source da Action e versão de runtime reproduzíveis.
uses: rodri-oliveira-dev/adr-guard@v1.2.3
# Recebe atualizações compatíveis dentro da major 1.
uses: rodri-oliveira-dev/adr-guard@v1

A Action nunca faz fallback para latest. Uma tag exata da Action seleciona a tag exata correspondente no GHCR (@v1.2.3 -> :1.2.3). Uma tag major móvel da Action seleciona a tag major móvel correspondente da imagem (@v1 -> :1).

Também é possível fixar o source da Action por SHA de commit. Como o SHA não codifica a versão do container, esse modo exige o input version exato:

uses: rodri-oliveira-dev/adr-guard@<commit-sha>
with:
path: docs/adr
command: check
version: 1.2.3

Merge na main e CI concluído não publicam mais uma release. O workflow Release é disparado somente por workflow_dispatch no GitHub Actions.

Para publicar uma release:

  1. faça merge das alterações desejadas na main;
  2. aguarde o CI normal da main concluir com sucesso;
  3. abra Actions → Release → Run workflow;
  4. selecione a branch main, informe o campo obrigatório version com o SemVer exato da release desejada (geralmente o VersionPrefix do projeto, sem v) e inicie o workflow manualmente.

O input obrigatório version aceita somente o formato estável MAJOR.MINOR.PATCH: sem zeros à esquerda, prefixo v, pré-release ou metadados de build. A versão solicitada deve ser igual ou superior ao VersionPrefix do projeto e maior do que qualquer versão publicada ou reservada. Para recuperar uma publicação incompleta, reexecute a mesma versão no mesmo commit, desde que nenhuma versão mais nova tenha sido reservada ou publicada. O workflow rejeita versões pertencentes a outro commit, regressões e uma segunda versão para o mesmo commit, antes do empacotamento. A versão não é inferida do título do PR ou das mensagens de commit.

O workflow verifica pela API do GitHub Actions que o commit exato da main selecionado no dispatch já possui uma execução CI de push concluída com sucesso. Se esse CI estiver ausente, em andamento, cancelado ou com falha, a release para antes de checkout/publicação. Depois disso, o próprio workflow executa novamente restore, build, testes, empacotamento e smoke tests antes de qualquer publicação. Dispatches feitos a partir de branches diferentes de main são rejeitados pelo gate do job de release, então os artefatos ficam vinculados ao commit da main escolhido explicitamente no dispatch (github.sha). Não existe mais trigger automático por workflow_run, e CI verde por si só não publica nada.

O workflow de release disparado manualmente usa o commit selecionado da main como commit validado da release e segue esta ordem:

  1. faz build, testes e empacotamento do commit validado;
  2. reserva o SemVer resolvido com uma tag interna release-reservation/vMAJOR.MINOR.PATCH vinculada ao commit validado;
  3. publica a .NET Tool no NuGet.org;
  4. publica o pacote no GitHub Packages;
  5. publica o container multi-plataforma no GHCR e Docker Hub, incluindo tags exata, minor, major e latest, além de attestations de SBOM/provenance;
  6. verifica que as referências exata e major do GHCR resolvem para o digest OCI produzido pela release;
  7. executa smoke test da resolução de runtime da Action pelas referências exata e major;
  8. cria ou verifica a tag Git imutável vMAJOR.MINOR.PATCH, atualiza vMAJOR e remove a reserva concluída;
  9. cria a GitHub Release.

As tags da Action só são publicadas depois que o job de container termina com sucesso. Assim, uma falha na publicação do container não consegue expor uma nova tag da Action cujo runtime ainda não exista. A tag interna de reserva não é uma referência suportada da Action e impede que um commit posterior reutilize um SemVer que possa ter artefatos parcialmente publicados.

A tag SemVer exata é imutável. Em uma reexecução:

  • se vMAJOR.MINOR.PATCH já aponta para o commit validado, ela é reutilizada;
  • se aponta para qualquer outro commit, a release falha em vez de repontá-la;
  • se vMAJOR já aponta para a mesma release, nada é alterado;
  • se vMAJOR aponta para uma release mais antiga da mesma major, ela avança;
  • se uma versão mais nova já foi reservada ou publicada, o workflow manual rejeita reexecutar uma versão anterior; o script de publicação das tags da Action também impede que vMAJOR volte para trás;
  • se a tag major existente não puder ser associada a uma tag imutável de release, o workflow se recusa a sobrescrevê-la.

Uma GitHub Release já existente também é tratada como imutável. Um asset ausente pode ser completado, mas um asset existente não é substituído com --clobber.

Para a release v1.2.3, primeiro confira as tags Git:

Terminal
git ls-remote --tags https://github.com/rodri-oliveira-dev/adr-guard.git \
refs/tags/v1.2.3 refs/tags/v1

Logo após a release, ambas devem resolver para o mesmo commit. A tag exata deve continuar apontando para esse commit para sempre; a tag major pode avançar em releases futuras v1.x.y.

Confira as imagens de runtime:

Terminal
docker buildx imagetools inspect ghcr.io/rodri-oliveira-dev/adr-guard:1.2.3
docker buildx imagetools inspect ghcr.io/rodri-oliveira-dev/adr-guard:1

Imediatamente após a publicação, as duas referências devem exibir o mesmo digest OCI de nível superior. Releases posteriores podem mover :1, enquanto :1.2.3 permanece imutável.

Por fim, valide a Action em um repositório consumidor:

permissions:
contents: read
steps:
- uses: actions/checkout@<commit-fixado>
with:
persist-credentials: false
- uses: rodri-oliveira-dev/adr-guard@v1.2.3
with:
path: docs/adr
command: check

Para detalhes de supply chain e isolamento de runtime, consulte o modelo de segurança da GitHub Action e o guia de container e supply chain.