Skip to content
Apothem
Runbooks

Runbook do ciclo de lançamento

Fluxo de lançamento completo, dos portões locais, passando pelo GitHub Release assinado, até a publicação no npm.

Este runbook conduz um lançamento vX.Y.Z do apothem de uma árvore de trabalho limpa até superfícies de distribuição verificadas. O procedimento é escrito para o mantenedor que maneja gh, git e o shell de nível de lançamento; ele termina com uma página de Release verificada, um CHANGELOG registrado e um teste de fumaça da rota de instalação que confirma que cada superfície voltada ao usuário responde ao comando de instalação canônico.

O modelo de lançamento é aditivo. Cada lançamento adiciona um commit em main e uma tag vX.Y.Z assinada e anotada; nada recebe force-push e nenhuma tag, GitHub Release ou versão do npm anterior é removida. Cada lançamento mantém sua tag, seu GitHub Release e sua versão do npm, e todos permanecem publicados: as versões do npm são imutáveis (um name@version publicado nunca pode ser substituído), e as instalações fixadas dependem das tags.

O push da tag inicia três fluxos de trabalho. .github/workflows/release.yml compila, assina, atesta e publica o GitHub Release com seu conjunto completo de artefatos: sdist, wheel, SBOM CycloneDX, bundles cosign do Sigstore, procedência SLSA-3 e os arquivos de runtime de cada plataforma. publish-npm.yml publica @ahmed-g-gad/apothem no npmjs.com por meio da publicação confiável do npm, e publish-vscode.yml empacota a extensão do VS Code e a publica no Visual Studio Marketplace. A seção versionada do CHANGELOG entra no commit de lançamento; o operador executa o teste de fumaça da rota de instalação depois que ambos os fluxos de trabalho terminam.

1. Pré-requisitos

O mantenedor confirma o seguinte antes de marcar a tag:

  • Árvore de trabalho. Limpa (git status não mostra nada pendente). Todo o trabalho de funcionalidades do lançamento está em main.

  • CI em verde. No main mais recente, gh run list --branch=main --limit=1 --json conclusion --jq '.[0].conclusion' retorna success.

  • Ferramentas. gh (GitHub CLI) versão 2.40 ou posterior autenticado em ahmed-g-gad; git 2.40 ou posterior com a subchave de assinatura GPG carregada; o vínculo de publicador confiável do npm para @ahmed-g-gad/apothem está ativo (verificado conforme o runbook de configuração da conta de publicador).

  • Âncoras de versão alinhadas. A string de versão declarada em pyproject.toml corresponde à tag planejada sem o prefixo v (a §2.1 a define, junto com todas as outras âncoras). Verifique:

    grep '^version' pyproject.toml

    Saída esperada (para um lançamento vX.Y.Z; os marcadores de posição representam a tag do lançamento em andamento):

    version = "X.Y.Z"
  • Entradas do CHANGELOG preparadas. Os itens do lançamento ficam em ## [Unreleased], nos cabeçalhos do Keep-a-Changelog; a §2.1 os transforma na seção de versão datada no commit em que a tag é aplicada.

2. Marcar a tag e disparar

2.1 Redigir o commit de lançamento

A versão fica em mais de uma dúzia de arquivos, então não os edite à mão. Um único comando altera todos eles:

git checkout main
git pull --ff-only origin main
python scripts/release/bump_version.py X.Y.Z

bump_version.py atualiza todas as âncoras de versão juntas:

  • Todos os manifestos de empacotamento, extensão, plugin e marketplace, além do arquivo de citação (versão e data de lançamento). A lista completa:

    pyproject.toml
    package.json
    site/package.json
    site/package-lock.json            (the project entries only)
    vscode-extension/package.json
    gemini-extension.json
    qwen-extension.json
    .claude-plugin/marketplace.json   (top level and metadata)
    plugins/apothem/plugin.json
    plugins/apothem/.codex-plugin/plugin.json
    CITATION.cff
  • CHANGELOG.md: as entradas de [Unreleased] se tornam uma seção ## [X.Y.Z] datada, [Unreleased] passa a comparar a partir de vX.Y.Z, e um link [X.Y.Z] é adicionado.

  • SECURITY.md: uma nova versão menor ganha uma linha X.Y.x suportada. Se as versões menores mais antigas continuam listadas é decisão sua; o script exibe um lembrete.

Em seguida, ele regenera as árvores derivadas: o pacote do plugin do Claude Code, os goldens de diff de comportamento e as páginas de referência e de changelog da documentação. Passe --dry-run para listar as mudanças primeiro, --date YYYY-MM-DD para definir a data de lançamento (padrão: hoje em UTC), ou --no-regen para pular a regeneração. O script recusa uma versão malformada ou um downgrade, e executá-lo novamente com a versão atual apenas realinha âncoras dispersas.

Revise o diff e depois faça o commit:

git add -A
git commit -S -m "chore(release): cut vX.Y.Z"
git push origin main

O sinalizador -S assina o commit com a chave GPG. O push dispara a matriz de CI padrão (lint, test, build); aguarde o verde antes de marcar a tag.

A verificação de prontidão da §2.4 também exige CodeQL e Conformity em verde no commit de lançamento. Os dois só são executados quando os caminhos próprios de cada um mudam, e um commit de lançamento normalmente não altera nenhum deles; por isso, inicie-os depois que o commit de lançamento for o último commit de main, e então confirme que cada execução identifica esse commit:

gh workflow run codeql.yml --ref main
gh workflow run conformity.yml --ref main
gh run list --workflow codeql.yml --commit "$(git rev-parse HEAD)" --limit 1
gh run list --workflow conformity.yml --commit "$(git rev-parse HEAD)" --limit 1

Aguarde os dois terminarem com sucesso antes de marcar a tag, e não envie mais nada para main até que o lançamento esteja publicado: um push posterior afasta main do commit de lançamento, e o CI cancela a execução que ainda estiver em andamento na mesma branch.

2.2 Assinar e enviar a tag

git tag -a -s vX.Y.Z -m "vX.Y.Z"
git push origin vX.Y.Z

A combinação -a -s produz uma tag anotada e assinada com GPG. O push dispara .github/workflows/release.yml, que compila, assina, atesta e publica.

2.3 Confirmar que o fluxo de trabalho de lançamento foi concluído

gh run watch $(gh run list --workflow=release.yml --limit=1 --json databaseId --jq '.[0].databaseId')

O fluxo de trabalho executa a compilação (sdist + wheel, depois um SBOM CycloneDX dessas distribuições gravado ao lado delas), a assinatura cosign sem chave, a geração e a verificação da procedência SLSA-3, as compilações dos arquivos de plataforma (darwin / linux / windows), a assinatura dos arquivos com um manifesto SHA256SUMS agregado e a publicação final do GitHub Release. O mantenedor examina o log do job publish GitHub Release em busca das confirmações de upload dos ativos.

O job publish GitHub Release é executado no ambiente release, que exige a aprovação do mantenedor; por isso, a execução aguarda ali assim que os jobs anteriores passam. Aprove-a na página da execução (Review deployments, revisar implantações), ou pelo shell:

run_id=$(gh run list --workflow=release.yml --limit=1 --json databaseId --jq '.[0].databaseId')
env_id=$(gh api repos/ahmed-g-gad/apothem/environments/release --jq .id)
gh api -X POST "repos/ahmed-g-gad/apothem/actions/runs/${run_id}/pending_deployments" \
  -F "environment_ids[]=${env_id}" -f state=approved -f comment="vX.Y.Z"

O push da tag também inicia os fluxos de trabalho do npm e da extensão do VS Code. Os jobs de publicação deles ficam aguardando essa mesma aprovação até a §2.4.

2.4 Confirmar a publicação no npm

O push da tag também executa publish-npm.yml ao lado de release.yml. O fluxo de trabalho do npm não espera pelo fluxo de trabalho de lançamento; a aprovação do ambiente release é o portão. Quando o fluxo de trabalho de lançamento da §2.3 tiver terminado, confirme a prontidão. A verificação lê os lançamentos, as execuções de fluxos de trabalho e o SBOM publicado; por isso, prepare duas entradas antes:

  • GH_TOKEN. O script se recusa a rodar sem ele, mesmo quando o gh já está autenticado. Use um token de acesso pessoal de granularidade fina limitado a ahmed-g-gad/apothem, com Actions: Read (execuções de fluxos de trabalho) e Contents: Read (lançamentos). A verificação não grava nada, por isso nenhuma permissão de escrita é necessária. Um token obtido com gh auth token carrega todos os escopos do login; prefira, portanto, o token de granularidade fina.
  • O SBOM publicado. A verificação lê dist/release-assets/sbom.cdx.json, o arquivo CycloneDX que o lançamento anexa. Baixe a cópia que o lançamento publicou, em vez de um build local.
read -rs GH_TOKEN && export GH_TOKEN
mkdir -p dist/release-assets
gh release download vX.Y.Z --repo ahmed-g-gad/apothem \
  --pattern sbom.cdx.json --dir dist/release-assets --clobber
bash scripts/release/check-release-ready.sh vX.Y.Z

A verificação falha quando o lançamento é um rascunho ou um pré-lançamento, quando um fluxo de trabalho exigido para o commit da tag não está verde, quando o SBOM está ausente, quando ele descreve outra versão ou quando omite um pacote incorporado. A mensagem de falha informa a causa.

Quando a verificação passar, aprove a execução Publish npm que está aguardando, do mesmo modo que na §2.3 (o ID da execução vem de gh run list --workflow=publish-npm.yml). O fluxo de trabalho publica @ahmed-g-gad/[email protected] no npmjs.com por meio da publicação confiável do npm (OIDC); nenhum token de registro é armazenado no repositório. Aprove também a execução Publish VS Code Extension que está aguardando. Ela empacota apothem.vsix e o publica no Visual Studio Marketplace como ahmed-g-gad.apothem-vscode. A etapa de publicação roda somente enquanto a variável do repositório VSCODE_MARKETPLACE_READY for true e uma credencial estiver configurada: a variável VSCE_AUTH=oidc (Trusted Publishing do Marketplace, sem segredo armazenado), as variáveis VSCE_AUTH=entra, AZURE_CLIENT_ID e AZURE_TENANT_ID (um token de curta duração do Microsoft Entra ID, sem segredo armazenado), ou o segredo VSCE_PAT. Sem nenhuma delas, a execução empacota a extensão e pula a publicação. A credencial é uma chave seletora, não uma nova tentativa: uma publicação com falha em uma rota não recorre a outra por conta própria. A configuração de cada rota está em Publicação no Marketplace com Trusted Publishing (preferida) e Publicação no Marketplace com Microsoft Entra ID abaixo.

Para publicar novamente após uma execução com falha, despache o fluxo de trabalho para a mesma tag (gh workflow run publish-npm.yml --field tag=vX.Y.Z). Ele pula a publicação quando a versão já está no registro, porque as versões do npm são imutáveis.

Publicação no Marketplace com Trusted Publishing

O Trusted Publishing permite que o Marketplace aceite diretamente o token OIDC do GitHub deste repositório: vsce publish --oidc troca o token do job de publicação por uma credencial de curta duração do Marketplace. Não há segredo armazenado nem recurso do Azure, por isso esta é a rota preferida. A rota do Entra abaixo e o segredo VSCE_PAT permanecem como alternativas que o operador seleciona.

  1. Use uma versão do vsce que dê suporte a ela. Nesta rota, o job de publicação verifica a versão do vsce travada em tools/vsce antes de publicar e para com um erro que nomeia a versão mínima quando a trava é mais antiga. O Dependabot propõe atualizações do vsce para esse lockfile; faça o merge daquela que alcança a versão mínima antes de trocar de rota.

  2. Crie a política. Entre como Owner do publicador, abra https://marketplace.visualstudio.com/manage/publishers/ahmed-g-gad e adicione uma política em Trusted Publishing:

    • Nome da política: qualquer nome, como apothem-release
    • Proprietário do repositório: Ahmed-G-Gad
    • Repositório: apothem
    • Fluxo de trabalho: publish-vscode.yml
    • Ambiente: release

    Os nomes dos campos são os que o guia de publicação do VS Code lista, na sua seção sobre publicação com GitHub Actions e Trusted Publishing (https://code.visualstudio.com/api/working-with-extensions/publishing-extension). Não confirmado: se todo publicador já vê a aba Trusted Publishing. Se o seu não vir, use a rota do Entra.

  3. Troque a rota. Mantenha VSCODE_MARKETPLACE_READY definida como true e defina o seletor. Defina-o quando nenhuma tag estiver aguardando, porque o próximo push de tag publica por esta rota.

    gh variable set VSCE_AUTH --body oidc
  4. Publique. O próximo push de tag, ou um despacho para uma tag existente, publica por meio do Trusted Publishing. Esta rota não tem execução de teste (dry run): a primeira publicação é a verificação, e um despacho com dry_run apenas avisa que nada foi verificado.

  5. Recorra à alternativa se falhar. Exclua o seletor e despache novamente para a mesma tag; com o segredo VSCE_PAT definido, a rota do token publica. Uma publicação com falha não publicou nada, então a mesma tag pode ser despachada novamente.

    gh variable delete VSCE_AUTH

Publicação no Marketplace com Microsoft Entra ID

A rota do Entra substitui o token de acesso pessoal armazenado por um token de curta duração. publish-vscode.yml pede ao GitHub um token OIDC, a action Azure/login o troca por um login do Entra por meio de uma credencial federada, e vsce publish --azure-credential publica com o token resultante. Não existe nenhum segredo de cliente. O segredo VSCE_PAT permanece como uma alternativa que o operador seleciona; o fluxo de trabalho nunca muda para ele por conta própria.

A versão do vsce fixada em tools/vsce dá suporte a esta rota. Ela exige um tenant do Entra, um registro de aplicativo e a associação ao publicador, o que o Trusted Publishing acima não exige; use-a quando o Trusted Publishing não estiver disponível para o publicador.

  1. Verifique as pré-condições. Encontre a conta proprietária do publicador ahmed-g-gad (a aba Members em https://marketplace.visualstudio.com/manage/publishers/ahmed-g-gad) e o tenant do Entra em que você pode registrar aplicativos. Não confirmado: se o tenant do proprietário do publicador precisa corresponder ao tenant do aplicativo, e se a organização do Azure DevOps Ahmed-G-Gad precisa estar conectada ao Entra (dev.azure.com/Ahmed-G-Gad, Organization settings, Microsoft Entra). Nenhuma fonte afirma nenhuma das duas coisas. Se a etapa 5 ou 6 falhar, verifique estes pontos primeiro.

  2. Registre o aplicativo. Em https://entra.microsoft.com, abra App registrations e depois New registration. Dê a ele o nome apothem-vscode-publish, escolha um único tenant e deixe o URI de redirecionamento vazio. Em Overview, copie o Application (client) ID e o Directory (tenant) ID. Não crie nenhum segredo de cliente e não conceda nenhuma permissão de API. A etapa exige direitos de proprietário do aplicativo ou uma função do Entra como Application Administrator.

  3. Adicione a credencial federada. Nesse aplicativo, abra Certificates & secrets, Federated credentials, Add credential, e escolha o cenário "GitHub Actions deploying Azure resources". Informe a organização Ahmed-G-Gad, o repositório apothem, o tipo de entidade Environment, o nome de ambiente release e o nome de credencial apothem-release. Os campos gerados devem mostrar:

    issuer:   https://token.actions.githubusercontent.com
    subject:  repo:Ahmed-G-Gad/apothem:environment:release
    audience: api://AzureADTokenExchange

    A correspondência é exata e diferencia maiúsculas de minúsculas. Se um login posterior falhar com AADSTS700213 ou AADSTS7002138, compare a credencial com a linha subject claim que Azure/login grava no log do job. AADSTS70021 logo após a criação significa que a credencial ainda não se propagou; aguarde alguns minutos e tente novamente.

  4. Defina as variáveis do repositório. Enquanto VSCODE_MARKETPLACE_READY for true, a rota do Entra fica ativa assim que as três estiverem definidas; por isso, defina-as quando nenhuma tag de lançamento estiver aguardando aprovação. Sem VSCODE_MARKETPLACE_READY=true, nada faz login e a execução pula a publicação.

    gh variable set AZURE_CLIENT_ID --body "<application-client-id>"
    gh variable set AZURE_TENANT_ID --body "<directory-tenant-id>"
    gh variable set VSCE_AUTH --body entra

    Deixe VSCODE_MARKETPLACE_READY e VSCE_PAT como estão. Quando VSCE_AUTH é entra, mas AZURE_CLIENT_ID ou AZURE_TENANT_ID está vazia, o fluxo de trabalho registra um aviso, esteja ou não VSCE_PAT definido, e não usa a rota do Entra. Ele então usa o segredo VSCE_PAT, se estiver definido; sem o segredo, não publica nada e a execução ainda termina em verde, então procure o aviso.

  5. Faça a execução de teste. Despache o fluxo de trabalho para uma tag de lançamento existente com dry_run definido. Na rota do Entra, ele faz login, imprime o perfil do Azure DevOps e verifica o acesso ao publicador sem publicar. A rota do token não tem execução de teste: se o log mostrar Marketplace credential mode: pat, a execução termina em verde com um aviso e não verificou nada. Aprove a execução do ambiente release que está aguardando.

    gh workflow run publish-vscode.yml --ref main -f tag=vX.Y.Z -f dry_run=true

    Esperado: Marketplace credential mode: entra, uma linha subject claim igual ao subject da etapa 3, e o id e o displayName do perfil impressos pela primeira etapa da execução de teste. Espera-se que a etapa de verificação falhe com um 403 até a etapa 6. Não confirmado: que um login sem uma assinatura do Azure produza um token para o Marketplace por meio da CLI do Azure. Esta execução é o primeiro teste disso. Se falhar aqui, registre em vez disso uma identidade gerenciada atribuída pelo usuário em uma assinatura, que é a rota que a Microsoft documenta.

  6. Adicione o aplicativo ao publicador. Na aba Members da etapa 1, entre como Owner do publicador e adicione um membro usando o id do perfil da etapa 5, com a função Contributor. Não confirmado: o rótulo do campo da caixa de diálogo, e se ela aceita o id antes de o aplicativo ser membro de uma organização do Azure DevOps. Como regra geral, o Azure DevOps adiciona identidades de aplicativo por organização. Se a caixa de diálogo rejeitar o id, adicione a entidade de serviço à organização Ahmed-G-Gad (Organization settings, Users, usando o Object ID do Enterprise application) e tente novamente. Também não confirmado: se o perfil existe antes da primeira chamada da identidade ao Azure DevOps.

  7. Repita a execução de teste. A etapa de verificação agora é bem-sucedida com "verification succeeded for the publisher"; suas mensagens ainda falam em Personal Access Token, porque o token do Entra percorre o mesmo caminho. A verificação comprova a associação ao publicador (Creator, Owner, Contributor ou Reader), não os direitos de publicação. Não confirmado: que Contributor baste para publicar uma atualização. A descrição de funções da Microsoft diz que basta, e nenhuma fonte mostra uma publicação com ela, então a primeira publicação real é a prova.

  8. Publique um lançamento. Marque a tag como na §2.2 e aprove a execução. A etapa Publish to Visual Studio Marketplace (Entra ID) é executada, o cabeçalho de ambiente dela lista apenas AZURE_TENANT_ID, a etapa alternativa do token é pulada, e o vsce imprime DONE Published ahmed-g-gad.apothem-vscode. A galeria do Marketplace lista a nova versão após cerca de quatro minutos.

  9. Decida sobre o token. Mantenha VSCE_PAT até a primeira publicação bem-sucedida pelo Entra e depois exclua o segredo se nenhuma alternativa for desejada. Depois que ele não existir mais, uma variável do Entra excluída ou vazia deixa a execução em verde sem publicação: com um aviso quando VSCE_AUTH ainda é entra, e apenas com o aviso de pulo quando não é. Leia as anotações da execução após cada tag. Para manter uma alternativa além da aposentadoria dos tokens de acesso pessoal globais, crie um token com escopo de organização para Ahmed-G-Gad com o escopo personalizado Marketplace Manage e a validade mais curta que você aceitar, e armazene-o como VSCE_PAT. Não confirmado: os rótulos do portal nesta etapa vêm da memória, não de uma fonte primária; a Microsoft chama os tokens com escopo de organização de solução temporária e pode deixar de aceitá-los; e as páginas da Microsoft divergem sobre a data de aposentadoria dos tokens globais.

  10. Recorra ao token. Exclua o seletor e despache novamente; depois, aprove a execução. Uma publicação com falha pelo Entra não publicou nada, então a mesma tag pode ser despachada novamente; verifique antes a página do Marketplace, porque uma versão que chegou lá não pode ser publicada duas vezes.

    gh variable delete VSCE_AUTH
    gh workflow run publish-vscode.yml --ref main -f tag=vX.Y.Z

Quando a publicação pelo Entra falhar, leia o log da etapa:

  • Uma mensagem que começa com "Can not acquire a Microsoft Entra ID access token" significa que o login ou a cadeia de credenciais falhou. Verifique primeiro a etapa Sign in to Microsoft Entra ID e a credencial federada. Se o login estiver em verde, remova AZURE_TENANT_ID do env da etapa do vsce no fluxo de trabalho; o próprio fluxo de trabalho de lançamento de extensão do GitHub não o exporta.
  • "InvalidAccessException" ou "not allowed" significa que a identidade do token não é membro do publicador. Compare o id do perfil da execução de teste com a aba Members.
  • Um 403 da etapa de verificação da execução de teste significa que o aplicativo ainda não tem função.

Três limites se aplicam a esta rota:

  • id-token: write é concedido a todo o job de publicação, de modo que qualquer etapa dele pode solicitar um token OIDC, também no modo token. O subject do token está vinculado ao ambiente release, que exige a aprovação de um revisor.
  • O ambiente release não tem política de branch ou de tag de implantação, de modo que qualquer ref que um mantenedor aprove pode obter o token com o subject do ambiente. Restringi-lo a tags v*.*.* exige verificar antes o que release.yml e publish-npm.yml despacham.
  • Uma renomeação ou transferência do repositório muda o formato do subject OIDC e quebra silenciosamente a credencial federada. Copie novamente o subject do log do Azure/login para a credencial após qualquer renomeação.

2.5 Atualizar a fixação do digest dos templates

Depois que a tag existir, defina _LATEST_RELEASE e _LATEST_RELEASE_DIGESTS em tests/unit/test_template_digests.py com o novo lançamento e o digest SHA-256 de cada template de texto simples tal como esse lançamento o entregou (git show vX.Y.Z:<template path> | sha256sum). Faça isso na próxima mudança em main e adicione o digest anterior a earlier_digests da entrada do manifesto quando o template tiver mudado. O job de CI release-preflight faz checkout de cada tag, por isso falha com os nomes das tags até que a fixação seja atualizada.

3. Superfícies de distribuição

Cada superfície tem um comando de verificação que responde "o lançamento chegou aqui?":

#SuperfícieArtefatoVerificação
1GitHub Release (distribuições Python)apothem-X.Y.Z.tar.gz (sdist) + apothem-X.Y.Z-py3-none-any.whlgh release view vX.Y.Z --json assets --jq '.assets[].name' inclui ambos os nomes de arquivo
2GitHub Release (SBOM)sbom.cdx.json + sbom.cdx.json.cosign.bundlea lista de ativos inclui ambos; o metadata.component.purl do SBOM é pkg:pypi/[email protected] e seus componentes incluem todos os pacotes de src/apothem/_vendor/vendor.txt
3GitHub Release (assinaturas)um <asset>.cosign.bundle por sdist, wheel, SBOM, extensão do VS Code, arquivo de plataforma e SHA256SUMS (os lançamentos anteriores nomeiam os bundles dos arquivos e de SHA256SUMS como <asset>.sig)cosign verify-blob com a identidade exata da §5.5 sai com 0
4GitHub Release (procedência)provenance.intoto.jsonlbash scripts/release/verify-provenance.sh <download-dir> sai com 0 (§5.5)
5GitHub Release (arquivos de plataforma)apothem-vX.Y.Z-darwin.tar.gz, apothem-vX.Y.Z-linux.tar.gz, apothem-vX.Y.Z-windows.zipa lista de ativos inclui cada arquivo mais SHA256SUMS. Os arquivos darwin e linux são os mesmos bytes sob dois nomes (o runtime é neutro em relação à plataforma; --platform apenas escolhe entre tar.gz e zip), de modo que suas linhas em SHA256SUMS mostram o mesmo digest duas vezes
6GitHub Release (extensão do VS Code)apothem.vsix + apothem.vsix.cosign.bundlea lista de ativos inclui ambos; code --install-extension apothem.vsix a instala. Os lançamentos anteriores ao empacotamento da extensão pelo fluxo de trabalho de lançamento não trazem nenhum dos dois
7npmjs.com@ahmed-g-gad/[email protected]npm view @ahmed-g-gad/apothem version retorna X.Y.Z; npx @ahmed-g-gad/[email protected] --version imprime Apothem, version X.Y.Z
8Pages (instaladores de script)install.sh / install.ps1 no site de documentaçãocurl -fsSL https://apothem.ahmedgad.com/install.sh | head -n 1 retorna o cabeçalho do script
9Visual Studio Marketplaceahmed-g-gad.apothem-vscode versão X.Y.Za página da extensão no Marketplace lista X.Y.Z; code --install-extension ahmed-g-gad.apothem-vscode a instala

O GitHub Release é a superfície canônica de artefatos; o pacote do npm e os instaladores de script são as rotas de instalação sobrepostas a ele. A publicação no npm é executada ao lado do fluxo de trabalho de lançamento, no mesmo push da tag.

4. Disciplina do CHANGELOG

O CHANGELOG.md carrega uma seção por lançamento sob a convenção Keep-a-Changelog. A edição do CHANGELOG no commit de lançamento:

  • Confirma que a seção de versão usa o cabeçalho ## [X.Y.Z] - YYYY-MM-DD (um hífen; bump_version.py o escreve, e extract_release_notes.py corresponde ao prefixo ## [X.Y.Z]).
  • Confirma que os cabeçalhos padrão — Added, Changed, Deprecated, Removed, Fixed, Security — são usados onde aplicável. Cabeçalhos vazios são removidos do arquivo renderizado.
  • Captura capacidades, não implementação. Apenas linguagem de domínio; sem referências internas ao plano; sem hashes de commit; sem identificadores de plano ou de fase.

Uma seção do CHANGELOG que passou pela revisão do mantenedor serve como âncora das notas de lançamento para a narrativa do anúncio.

5. Teste de fumaça da rota de instalação

Depois que ambos os estágios forem concluídos, o mantenedor executa o teste de fumaça. O teste de fumaça é a verificação canônica de que os comandos de instalação voltados ao usuário respondem.

5.1 Plugin do Claude Code

/plugin marketplace add ahmed-g-gad/apothem
/plugin install apothem@apothem

Esperado: o plugin é instalado e os comandos apothem ficam disponíveis dentro do Claude Code.

5.2 Node.js (npx)

npx @ahmed-g-gad/[email protected] --version

Saída esperada: Apothem, version X.Y.Z.

5.3 Instalador de script de um único passo (POSIX)

O instalador grava o lançador apothem em ~/.local/bin, ou no diretório indicado por APOTHEM_BIN_DIR quando essa variável está definida. A verificação abaixo precisa que esse diretório esteja no PATH. Quando não está, o instalador imprime a linha export PATH a ser adicionada. Enquanto esse diretório não estiver no PATH, o shell não encontra apothem, e a verificação falha. Se o instalador não conseguir colocar o lançador no lugar, ele imprime um aviso e nenhuma linha export PATH. Em um host que ainda não tem a chave de assinatura do mantenedor, a primeira linha abaixo a importa; sem ela, o instalador para.

curl -fsSL https://github.com/ahmed-g-gad.gpg | gpg --import
curl -fsSL https://apothem.ahmedgad.com/install.sh | sh
apothem --version

Saída esperada: Apothem, version X.Y.Z.

5.4 Instalador de script de um único passo (Windows)

A primeira linha importa a chave de assinatura do mantenedor pelo próprio bash do Git, cujo chaveiro gpg é o que o git verify-tag lê.

& "$env:ProgramFiles\Git\bin\bash.exe" -c 'curl -fsSL https://github.com/ahmed-g-gad.gpg | gpg --import'
irm https://apothem.ahmedgad.com/install.ps1 | iex
apothem --version

Saída esperada: Apothem, version X.Y.Z.

5.5 Verificação de artefatos (evidência da cadeia de suprimentos)

Baixe todos os ativos para um diretório vazio e depois verifique. A identidade do certificado é o fluxo de trabalho de lançamento nesta tag exata. As verificações de identidade diferenciam maiúsculas de minúsculas, e os certificados trazem o proprietário como o GitHub o informa, Ahmed-G-Gad, de modo que um proprietário em minúsculas falha.

mkdir release-vX.Y.Z && cd release-vX.Y.Z
gh release download vX.Y.Z --repo ahmed-g-gad/apothem
cosign verify-blob \
  --bundle apothem-X.Y.Z-py3-none-any.whl.cosign.bundle \
  --certificate-identity https://github.com/Ahmed-G-Gad/apothem/.github/workflows/release.yml@refs/tags/vX.Y.Z \
  --certificate-oidc-issuer https://token.actions.githubusercontent.com \
  apothem-X.Y.Z-py3-none-any.whl
slsa-verifier verify-artifact \
  --provenance-path provenance.intoto.jsonl \
  --source-uri github.com/Ahmed-G-Gad/apothem \
  --source-tag vX.Y.Z \
  apothem-X.Y.Z-py3-none-any.whl apothem-X.Y.Z.tar.gz
bash ../scripts/release/verify-provenance.sh .

Esperado: Verified OK, PASSED: SLSA verification passed e verify-provenance: chain OK (3 of 3 layers verified). O script verifica SHA256SUMS, cada bundle de assinatura e a procedência em uma única execução; ele deriva a tag do nome do wheel (--tag vX.Y.Z a substitui).

O teste de fumaça produz uma linha de PASS / FAIL por superfície; registre as linhas no log de lançamento do mantenedor.

6. Recuperação de falhas

O fluxo de trabalho de lançamento tem modos de falha documentados para o motor de lançamento e o publicador do npm:

FalhaDiagnósticoRecuperação
Push da tag rejeitado (falha de assinatura)git push origin vX.Y.Z retorna error: failed to push some refs com uma mensagem relacionada a GPGVerifique se a subchave GPG está carregada (gpg --list-secret-keys --keyid-format=long); marque a tag novamente, localmente, com -s depois de corrigir o chaveiro; envie novamente
A compilação do lançamento para em Check the plugin version changed with the pluginO log do job de compilação nomeia o plugin e a tag anterior; nenhum ativo foi compilado ou publicadoO pacote do plugin mudou desde o lançamento anterior, mas sua versão não. Exclua a tag (git push --delete origin vX.Y.Z, git tag -d vX.Y.Z), execute python scripts/release/bump_version.py X.Y.Z, faça o commit e então assine e envie a tag novamente (§2.2). A mesma verificação é executada em todo pull request como uma anotação de aviso, então isso normalmente aparece antes de marcar a tag
Um job de release.yml falha em um único estágiogh run view <run-id> --log nomeia o job que falhou (build, que também grava o SBOM / sign / provenance / archive / publish)Execute novamente apenas o job que falhou via gh run rerun <run-id> --failed; se a falha se repetir, corrija a entrada do job na origem antes de marcar a tag novamente
A verificação da procedência SLSA falhaO job verify SLSA provenance artifact sai com código diferente de zeroInspecione o artefato de procedência em busca de incompatibilidade de digest do sujeito; recompile a partir da mesma tag — a procedência se vincula aos digests exatos dos artefatos, então qualquer regeneração de artefatos exige uma reexecução completa do fluxo de trabalho
Publicação no npmjs.com rejeitadaO job do npm sai com código diferente de zero durante npm publish; um 404 do registro durante PUT é uma incompatibilidade de autorização / publicador confiável, não prova de que o código do pacote está ausenteVerifique se o npm Trusted Publishing para @ahmed-g-gad/apothem nomeia o proprietário ahmed-g-gad, o repositório apothem, o fluxo de trabalho publish-npm.yml e a ação permitida npm publish; confirme que o job é executado com a versão do Node e o piso OIDC da CLI do npm fixados no fluxo de trabalho
Tag visível, mas ativos ausentesgh release view vX.Y.Z retorna um lançamento vazioExecute novamente o job de publicação do fluxo de trabalho de lançamento; ele edita o lançamento existente e reenvia todos os ativos. Exclua a tag e marque-a novamente somente quando nada da tag tiver chegado aos usuários (nenhum ativo, nenhuma versão do npm); caso contrário, corrija para frente com o próximo lançamento de patch (runbook de recuperação de lançamento §2)

Se um ciclo de recuperação não conseguir fazer uma superfície chegar ao destino em um único passe de diagnóstico, a superfície é registrada como uma falha conhecida nas notas de lançamento, com um link para a issue aberta; os usuários a jusante são direcionados às superfícies que funcionam enquanto a quebrada é corrigida em um lançamento de patch.

7. Referências cruzadas

  • Configuração do publicador. O runbook de configuração da conta de publicador estabelece o vínculo de publicador confiável do npm e os pré-requisitos do lado do GitHub que este runbook pressupõe.
  • Fluxo de recuperação. O runbook de recuperação de lançamento segue o mesmo modelo aditivo: ele recupera uma tag ou um estágio de publicador com falha, estágio por estágio, e faz a reversão lançando a correção como uma nova versão de patch, nunca excluindo ou redirecionando uma tag, um lançamento ou uma versão do npm publicados.
  • Habilitação do Pages. O fluxo de trabalho publish-static-site.yml valida e implanta o site do projeto no domínio personalizado; o runbook de habilitação do Pages (site/content/docs/runbooks/pages-enablement.mdx) é o procedimento anterior que estabeleceu o domínio personalizado em primeiro lugar.
  • Política de versionamento. site/content/docs/governance/release-engineering-policy.mdx contém a política de SemVer + assinatura + descontinuação que este runbook respeita.

On this page