Skip to content
Apothem
Runbooks

Runbook du cycle de publication

Flux de publication complet depuis les contrôles locaux, en passant par le GitHub Release signé, jusqu'au déclenchement optionnel de la publication npm.

Ce runbook mène une publication vX.Y.Z de apothem d'un arbre de travail propre jusqu'aux surfaces de distribution vérifiées. La procédure est écrite pour le mainteneur qui manie gh, git et le shell de niveau de publication ; elle se termine par une page de Release vérifiée, un CHANGELOG archivé et un test de fumée du chemin d'installation confirmant que chaque surface destinée à l'utilisateur répond à la commande d'installation canonique.

La forme de la publication est une seule étiquette, deux étapes. Une étiquette de publication signée sur main déclenche .github/workflows/release.yml, qui compile, signe, atteste et publie le GitHub Release avec son ensemble complet d'artefacts — sdist, wheel, SBOM CycloneDX, paquets cosign de Sigstore, provenance SLSA-3 et les archives du runtime de chaque plateforme. La deuxième étape optionnelle est un déclenchement manuel de publish-npm.yml, qui publie @ahmed-g-gad/apothem sur npmjs.com une fois que scripts/release/check-release-ready.sh est au vert. La section versionnée du CHANGELOG est rédigée avec le commit de l'étiquette ; l'opérateur exécute le test de fumée du chemin d'installation après que les deux étapes aient atterri.

1. Prérequis

Le mainteneur confirme les éléments suivants avant d'étiqueter :

  • Arbre de travail. Propre (git status n'affiche rien en attente). Tout le travail de fonctionnalités de la publication est sur main.

  • CI au vert. Le dernier main gh run list --branch=main --limit=1 --json conclusion --jq '.[0].conclusion' renvoie success.

  • Outillage. gh (GitHub CLI) version 2.40 ou ultérieure authentifié contre ahmed-g-gad ; git 2.40 ou ultérieure avec la sous-clé de signature GPG chargée ; le lien d'éditeur de confiance npm pour @ahmed-g-gad/apothem est actif (vérifié selon le runbook de configuration du compte d'éditeur).

  • Ancrages de version alignés. La chaîne de version déclarée dans pyproject.toml correspond à l'étiquette prévue sans le préfixe v. Vérifiez :

    grep '^version' pyproject.toml

    Sortie attendue (pour une publication vX.Y.Z ; les espaces réservés représentent l'étiquette de la publication en cours) :

    version = "X.Y.Z"
  • Section du CHANGELOG préparée. CHANGELOG.md porte une section versionnée sous les en-têtes Keep-a-Changelog. Le mainteneur met à jour la date et les points de la publication dans le même commit qui fait atterrir l'étiquette.

2. Étiqueter et déclencher

2.1 Rédiger le commit de publication

Le commit de publication fait atterrir deux changements :

  • La section de version de CHANGELOG.md datée de la date UTC réelle de la publication.
  • La version de pyproject.toml montée à la nouvelle version (uniquement lorsque le commit précédent sur main porte déjà l'épingle de la version précédente et qu'une nouvelle montée est requise ; le commit peut aussi atterrir pendant le cycle de montée de version, des jours avant le moment de l'étiquetage).

Commit d'exemple :

git checkout main
git pull --ff-only origin main
# Rédigez les modifications de CHANGELOG et pyproject.toml via l'outil Edit, puis :
git add CHANGELOG.md pyproject.toml
git commit -S -m "chore(release): cut vX.Y.Z"
git push origin main

Le drapeau -S signe le commit avec la clé GPG. Le push déclenche la matrice de CI standard (lint, test, build) ; attendez le vert avant d'étiqueter.

2.2 Signer et pousser l'étiquette

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

La combinaison -a -s produit une étiquette annotée et signée avec GPG. Le push déclenche .github/workflows/release.yml, qui compile, signe, atteste et publie.

2.3 Confirmer que le flux de travail de publication est terminé

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

Le flux de travail exécute la compilation (sdist + wheel), la génération du SBOM (CycloneDX), la signature cosign sans clé, la génération et la vérification de la provenance SLSA-3, les compilations d'archives de plateforme (darwin / linux / windows), la signature d'archives avec un manifeste SHA256SUMS agrégé, et la publication finale du GitHub Release. Le mainteneur parcourt le journal du job publish GitHub Release à la recherche des confirmations de téléversement d'artefacts.

2.4 Déclencher la publication npm (étape optionnelle)

Après que le GitHub Release et la barrière de préparation soient au vert :

bash scripts/release/check-release-ready.sh vX.Y.Z
gh workflow run publish-npm.yml --field tag=vX.Y.Z

Approuvez le déploiement de l'environnement npmjs lorsque vous y êtes invité. Le flux de travail publie @ahmed-g-gad/[email protected] sur npmjs.com via npm Trusted Publishing (OIDC) ; aucun jeton de registre n'est stocké dans le dépôt.

3. Surfaces de distribution

Chaque surface possède une commande de vérification répondant à « la publication a-t-elle atterri ici ? » :

#SurfaceArtefactVérification
1GitHub Release (distributions 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' inclut les deux noms de fichier
2GitHub Release (SBOM)sbom.cdx.jsoncomme la ligne 1 ; la liste des actifs inclut le SBOM CycloneDX
3GitHub Release (signatures)*.cosign.bundle par artefact de distribution ; *.sig par archive ; SHA256SUMS + SHA256SUMS.sigcosign verify-blob --bundle <artifact>.cosign.bundle <artifact> se termine avec 0 (avec les drapeaux d'identité du flux de travail)
4GitHub Release (provenance)provenance.intoto.jsonlbash scripts/release/verify-provenance.sh vX.Y.Z se termine avec 0
5GitHub Release (archives de plateforme)apothem-vX.Y.Z-darwin.tar.gz, apothem-vX.Y.Z-linux.tar.gz, apothem-vX.Y.Z-windows.zipla liste des actifs inclut chaque archive plus SHA256SUMS
6npmjs.com@ahmed-g-gad/[email protected]npm view @ahmed-g-gad/apothem version renvoie X.Y.Z ; npx @ahmed-g-gad/[email protected] --version affiche apothem X.Y.Z
7Pages (installateurs de script)install.sh / install.ps1 sur le site de documentationcurl -fsSL https://apothem.ahmedgad.com/install.sh | head -n 1 renvoie l'en-tête du script

Le GitHub Release est la surface canonique d'artefacts ; le paquet npm et les installateurs de script sont les chemins d'installation superposés par-dessus. La publication npm est délibérément la dernière étape.

4. Discipline du CHANGELOG

CHANGELOG.md porte une section par publication selon la convention Keep-a-Changelog. La modification du CHANGELOG dans le commit de publication :

  • Confirme que la section de version utilise l'en-tête ## [X.Y.Z] — YYYY-MM-DD.
  • Confirme que les en-têtes standard — Added, Changed, Deprecated, Removed, Fixed, Security — sont utilisés là où c'est applicable. Les en-têtes vides sont supprimés du fichier rendu.
  • Capture les capacités, pas l'implémentation. Langage du domaine uniquement ; aucune référence interne au plan ; aucun hash de commit ; aucun identifiant de plan ni de phase.

Une section du CHANGELOG qui a survécu à la revue du mainteneur se lit comme l'ancre des notes de publication pour le récit de l'annonce.

5. Test de fumée du chemin d'installation

Après que les deux étapes soient terminées, le mainteneur exécute le test de fumée. Le test de fumée est la vérification canonique que les commandes d'installation destinées à l'utilisateur répondent.

5.1 Plugin Claude Code

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

Attendu : le plugin s'installe et les commandes apothem sont disponibles dans Claude Code.

5.2 Node.js (npx)

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

Sortie attendue : apothem X.Y.Z.

5.3 Installateur de script en une seule étape (POSIX)

curl -fsSL https://apothem.ahmedgad.com/install.sh | sh
apothem --version

Sortie attendue : apothem X.Y.Z.

5.4 Installateur de script en une seule étape (Windows)

irm https://apothem.ahmedgad.com/install.ps1 | iex
apothem --version

Sortie attendue : apothem X.Y.Z.

5.5 Vérification des artefacts (preuve de chaîne d'approvisionnement)

gh release download vX.Y.Z --pattern 'apothem-X.Y.Z*' --pattern '*.cosign.bundle'
cosign verify-blob \
  --bundle apothem-X.Y.Z-py3-none-any.whl.cosign.bundle \
  --certificate-identity-regexp 'github.com/ahmed-g-gad/apothem' \
  --certificate-oidc-issuer https://token.actions.githubusercontent.com \
  apothem-X.Y.Z-py3-none-any.whl
bash scripts/release/verify-provenance.sh vX.Y.Z

Attendu : les deux vérifications se terminent avec 0.

Le test de fumée produit une ligne PASS / FAIL par surface ; consignez les lignes dans le journal de publication du mainteneur.

6. Récupération après échec

Le flux de travail de publication a des modes de défaillance documentés pour le moteur de publication et l'éditeur npm :

ÉchecDiagnosticRécupération
Push de l'étiquette rejeté (échec de signature)git push origin vX.Y.Z renvoie error: failed to push some refs avec un message lié à GPGVérifiez que la sous-clé GPG est chargée (gpg --list-secret-keys --keyid-format=long) ; ré-étiquetez localement avec -s après avoir corrigé le trousseau ; repoussez
Un job de release.yml échoue à une seule étapegh run view <run-id> --log nomme le job en échec (build / sbom / sign / provenance / archive / publish)Ré-exécutez le job en échec seul via gh run rerun <run-id> --failed ; si l'échec se répète, corrigez l'entrée du job à sa source avant de ré-étiqueter
La vérification de provenance SLSA échoueLe job verify SLSA provenance artifact se termine avec un code non nulInspectez l'artefact de provenance pour une incohérence de digest du sujet ; recompilez à partir de la même étiquette — la provenance se lie aux digests exacts des artefacts, donc toute régénération d'artefacts nécessite une ré-exécution complète du flux de travail
Publication sur npmjs.com rejetéeLe job npm se termine avec un code non nul pendant npm publish ; un 404 du registre pendant PUT est une incohérence d'autorisation / éditeur de confiance, pas une preuve que le code du paquet est absentVérifiez que npm Trusted Publishing pour @ahmed-g-gad/apothem nomme le propriétaire ahmed-g-gad, le dépôt apothem, le flux de travail publish-npm.yml et l'action autorisée npm publish ; confirmez que le job s'exécute avec la version de Node et le plancher OIDC de la CLI npm épinglés dans le flux de travail
Étiquette visible mais artefacts absentsgh release view vX.Y.Z renvoie une release ébaucheRé-exécutez le job de publication du flux de travail de publication ; si l'ébauche persiste, supprimez la page de la release (gh release delete vX.Y.Z --cleanup-tag) et ré-étiquetez à partir du même SHA

Si un cycle de récupération ne parvient pas à faire atterrir une surface en une seule passe de diagnostic, la surface est consignée comme un échec connu dans les notes de publication avec un lien vers le problème ouvert ; les utilisateurs en aval sont orientés vers les surfaces qui fonctionnent pendant que celle qui est cassée est corrigée dans une publication corrective.

7. Références croisées

  • Configuration de l'éditeur. Le runbook de configuration du compte d'éditeur établit le lien d'éditeur de confiance npm et les prérequis côté GitHub que ce runbook suppose.
  • Flux de récupération. Le runbook de récupération de publication (site/content/docs/runbooks/release-recovery.mdx) régit le chemin de défaillance inter-étapes lors d'une bascule de publication, et non les défaillances de publication par surface nommées au §6.
  • Activation de Pages. Le flux de travail publish-static-site.yml valide et déploie le site web du projet vers le domaine personnalisé ; le runbook d'activation de Pages (site/content/docs/runbooks/pages-enablement.mdx) est la procédure en amont qui a établi le domaine personnalisé en premier lieu.
  • Politique de versionnage. site/content/docs/governance/release-engineering-policy.mdx porte la politique SemVer + signature + dépréciation que ce runbook honore.

On this page