Runbook zum Release-Zyklus
Vollständiger Release-Workflow von den lokalen Gates über das signierte GitHub Release bis zur npm-Veröffentlichung.
Dieses Runbook führt ein vX.Y.Z-Release von apothem von einem sauberen
Arbeitsbaum zu verifizierten Distributionsoberflächen. Das Verfahren ist für
den Maintainer geschrieben, der gh, git und die Shell der Release-Ebene
bedient; es endet mit einer verifizierten Release-Seite, einem abgelegten
CHANGELOG und einem Installationspfad-Smoke-Test, der bestätigt, dass jede
benutzerseitige Oberfläche auf den kanonischen Installationsbefehl antwortet.
Das Release-Modell ist additiv. Jedes Release fügt einen Commit auf main
und ein signiertes, annotiertes vX.Y.Z-Tag hinzu; nichts wird per Force-Push
übertragen, und kein früheres Tag, kein GitHub Release und keine npm-Version
wird entfernt. Jedes Release behält sein Tag, sein GitHub Release und seine npm-Version, und alle bleiben veröffentlicht:
npm-Versionen sind unveränderlich (ein veröffentlichtes name@version kann
niemals ersetzt werden), und gepinnte Installationen hängen von den Tags ab.
Der Tag-Push startet drei Workflows. .github/workflows/release.yml baut,
signiert, attestiert und veröffentlicht das GitHub Release mit seinem
vollständigen Artefaktsatz: sdist, Wheel, CycloneDX-SBOM,
Sigstore-cosign-Bundles, SLSA-3-Provenienz und die Plattform-Laufzeitarchive.
publish-npm.yml veröffentlicht @ahmed-g-gad/apothem über npm Trusted
Publishing auf npmjs.com, und publish-vscode.yml paketiert die
VS Code-Erweiterung und veröffentlicht sie im Visual Studio Marketplace. Der
versionierte CHANGELOG-Abschnitt landet im
Release-Commit; der Operator führt den Installationspfad-Smoke-Test aus,
nachdem beide Workflows abgeschlossen sind.
1. Voraussetzungen
Der Maintainer bestätigt vor dem Taggen Folgendes:
-
Arbeitsbaum. Sauber (
git statuszeigt nichts Ausstehendes). Die gesamte Feature-Arbeit für das Release ist aufmain. -
CI grün. Für den neuesten Stand von
maingibtgh run list --branch=main --limit=1 --json conclusion --jq '.[0].conclusion'den Wertsuccesszurück. -
Werkzeuge.
gh(GitHub CLI) Version 2.40 oder neuer, authentifiziert gegenahmed-g-gad;git2.40 oder neuer mit geladenem GPG-Signier-Unterschlüssel; die npm-Trusted-Publisher-Bindung für@ahmed-g-gad/apothemist aktiv (verifiziert gemäß dem Runbook zur Einrichtung des Publisher-Kontos). -
Versionsanker ausgerichtet. Die in
pyproject.tomldeklarierte Versionszeichenkette stimmt ohne dasv-Präfix mit dem geplanten Tag überein (§2.1 setzt sie, zusammen mit jedem anderen Anker). Verifizieren Sie:grep '^version' pyproject.tomlErwartete Ausgabe (für ein
vX.Y.Z-Release; die Platzhalter stehen für das laufende Release-Tag):version = "X.Y.Z" -
CHANGELOG-Einträge vorbereitet. Die Release-Punkte stehen unter
## [Unreleased]in Keep-a-Changelog-Überschriften; §2.1 macht daraus den datierten Versionsabschnitt in dem Commit, der das Tag landet.
2. Taggen und auslösen
2.1 Den Release-Commit verfassen
Die Version steht in mehr als einem Dutzend Dateien, bearbeiten Sie sie also nicht von Hand. Ein einziger Befehl ändert sie alle:
git checkout main
git pull --ff-only origin main
python scripts/release/bump_version.py X.Y.Zbump_version.py aktualisiert jeden Versionsanker gemeinsam:
-
Jedes Paketierungs-, Erweiterungs-, Plugin- und Marketplace-Manifest sowie die Zitationsdatei (Version und Release-Datum). Die vollständige Liste:
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: Die[Unreleased]-Einträge werden zu einem datierten## [X.Y.Z]-Abschnitt,[Unreleased]vergleicht abvX.Y.Z, und ein[X.Y.Z]-Link wird hinzugefügt. -
SECURITY.md: Eine neue Minor-Version erhält eine unterstützteX.Y.x-Zeile. Ob ältere Minor-Versionen gelistet bleiben, entscheiden Sie; das Skript gibt eine Erinnerung aus.
Danach erzeugt es die abgeleiteten Bäume neu: das Claude Code-Plugin-Paket, die
Behavior-Diff-Goldens sowie die Referenz- und Changelog-Seiten der
Dokumentation. Übergeben Sie --dry-run, um die Änderungen zuerst aufzulisten,
--date YYYY-MM-DD, um das Release-Datum festzulegen (Standard: heute in UTC), oder
--no-regen, um die Neuerzeugung zu überspringen. Das Skript lehnt eine
fehlerhafte Version oder ein Downgrade ab, und ein erneuter Aufruf mit der
aktuellen Version richtet nur abweichende Anker neu aus.
Prüfen Sie den Diff und committen Sie dann:
git add -A
git commit -S -m "chore(release): cut vX.Y.Z"
git push origin mainDas Flag -S signiert den Commit mit dem GPG-Schlüssel. Der Push löst die
Standard-CI-Matrix aus (lint, test, build); warten Sie auf Grün, bevor Sie
taggen.
Die Prüfung in §2.4 setzt außerdem voraus, dass CodeQL und Conformity für den
Release-Commit grün sind. Beide Workflows laufen nur, wenn sich ihre eigenen
Pfade ändern, und ein Release-Commit ändert in der Regel keinen dieser Pfade.
Starten Sie sie daher, sobald der Release-Commit der HEAD von main ist, und
bestätigen Sie anschließend, dass jeder Lauf diesem Commit zugeordnet ist:
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 1Warten Sie, bis beide erfolgreich abgeschlossen sind, bevor Sie taggen, und
pushen Sie bis zur Veröffentlichung des Releases nichts anderes auf main: Ein
späterer Push verschiebt main vom Release-Commit weg, und CI bricht einen
noch laufenden Lauf auf demselben Branch ab.
2.2 Das Tag signieren und pushen
git tag -a -s vX.Y.Z -m "vX.Y.Z"
git push origin vX.Y.ZDie Kombination -a -s erzeugt ein annotiertes, GPG-signiertes Tag. Der Push
löst .github/workflows/release.yml aus, das baut, signiert, attestiert und
veröffentlicht.
2.3 Bestätigen, dass der Release-Workflow abgeschlossen ist
gh run watch $(gh run list --workflow=release.yml --limit=1 --json databaseId --jq '.[0].databaseId')Der Workflow führt den Build (sdist + Wheel, danach ein CycloneDX-SBOM dieser
Distributionen, das neben sie geschrieben wird), die schlüssellose
cosign-Signierung, die Erzeugung und Verifizierung der SLSA-3-Provenienz, die
Plattform-Archiv-Builds (darwin / linux / windows), die Archiv-Signierung mit
einem aggregierten SHA256SUMS-Manifest und die finale Veröffentlichung des
GitHub Release aus. Der Maintainer durchsucht das Protokoll des Jobs
publish GitHub Release nach den Bestätigungen der Asset-Uploads.
Der Job publish GitHub Release läuft in der Umgebung release, die die
Genehmigung des Maintainers verlangt. Daher wartet der Lauf dort, sobald die
vorherigen Jobs erfolgreich abgeschlossen sind. Genehmigen Sie ihn auf der
Seite des Laufs (Review deployments) oder über die 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"Der Tag-Push startet außerdem die Workflows für npm und die VS Code-Erweiterung. Deren Veröffentlichungsjobs warten auf dieselbe Genehmigung, bis Sie §2.4 erreichen.
2.4 Die npm-Veröffentlichung bestätigen
Der Tag-Push führt auch publish-npm.yml neben release.yml aus. Der npm-Workflow wartet nicht auf den Release-Workflow; die Genehmigung der Umgebung release ist das Gate. Sobald der Release-Workflow aus §2.3 abgeschlossen ist, bestätigen Sie die Bereitschaft. Die Prüfung liest Releases, Workflow-Läufe und die veröffentlichte SBOM; richten Sie daher zuerst zwei Eingaben ein:
GH_TOKEN. Das Skript verweigert den Lauf ohne dieses Token, selbst wennghbereits angemeldet ist. Verwenden Sie ein feingranulares persönliches Zugriffstoken, das aufahmed-g-gad/apothembeschränkt ist, mit Actions: Read (Workflow-Läufe) und Contents: Read (Releases). Die Prüfung schreibt nichts, daher ist keine Schreibberechtigung nötig. Ein Token ausgh auth tokenträgt jeden Geltungsbereich der Anmeldung; bevorzugen Sie daher das feingranulare Token.- Die veröffentlichte SBOM. Die Prüfung liest
dist/release-assets/sbom.cdx.json, die CycloneDX-Datei, die das Release anhängt. Laden Sie die Kopie herunter, die das Release veröffentlicht hat, statt eines lokalen Builds.
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.ZDie Prüfung schlägt fehl, wenn das Release ein Entwurf oder eine Vorabversion ist, wenn ein erforderlicher Workflow für den Commit des Tags nicht grün ist, wenn die SBOM fehlt, wenn sie eine andere Version beschreibt oder wenn sie ein vendorisiertes Paket auslässt. Die Fehlermeldung nennt die Ursache.
Wenn die Prüfung besteht, genehmigen Sie den wartenden Lauf Publish npm auf
dieselbe Weise wie in §2.3 (seine Lauf-ID stammt aus
gh run list --workflow=publish-npm.yml). Der Workflow veröffentlicht
@ahmed-g-gad/[email protected] über npm Trusted Publishing (OIDC) auf npmjs.com;
im Repository ist kein Registry-Token gespeichert. Genehmigen Sie außerdem den
wartenden Lauf Publish VS Code Extension. Er paketiert apothem.vsix und
veröffentlicht es im Visual Studio Marketplace als ahmed-g-gad.apothem-vscode.
Der Veröffentlichungsschritt läuft nur, solange die Repository-Variable
VSCODE_MARKETPLACE_READY den Wert true hat und eine Zugangsberechtigung
konfiguriert ist: die Variable VSCE_AUTH=oidc (Marketplace Trusted Publishing,
kein gespeichertes Secret), die Variablen VSCE_AUTH=entra, AZURE_CLIENT_ID
und AZURE_TENANT_ID (ein kurzlebiges Microsoft Entra ID-Token, kein
gespeichertes Secret) oder das Secret VSCE_PAT. Ist keine davon konfiguriert,
paketiert der Lauf die Erweiterung und überspringt die Veröffentlichung. Die
Zugangsberechtigung ist ein Schalter, kein Wiederholungsversuch: Eine
fehlgeschlagene Veröffentlichung auf einem Weg fällt nicht von selbst auf einen
anderen zurück. Die Einrichtung jedes Wegs steht unten in
Marketplace-Veröffentlichung mit Trusted Publishing
(bevorzugt) und
Marketplace-Veröffentlichung mit Microsoft Entra ID.
Um nach einem fehlgeschlagenen Lauf erneut zu veröffentlichen, starten Sie den
Workflow für dasselbe Tag
(gh workflow run publish-npm.yml --field tag=vX.Y.Z). Er überspringt die
Veröffentlichung, wenn die Version bereits in der Registry ist, weil
npm-Versionen unveränderlich sind.
Marketplace-Veröffentlichung mit Trusted Publishing
Mit Trusted Publishing akzeptiert der Marketplace das GitHub-OIDC-Token dieses
Repositorys direkt: vsce publish --oidc tauscht das Token des
Veröffentlichungsjobs gegen eine kurzlebige Marketplace-Zugangsberechtigung.
Es gibt kein gespeichertes Secret und keine Azure-Ressource, daher ist dies der
bevorzugte Weg. Der Entra-Weg unten und das Secret VSCE_PAT bleiben als
Alternativen bestehen, die der Operator auswählt.
-
Ein vsce-Release verwenden, das ihn unterstützt. Auf diesem Weg prüft der Veröffentlichungsjob vor dem Veröffentlichen das in
tools/vscegesperrte vsce-Release und bricht mit einem Fehler ab, der das Mindest-Release nennt, wenn die Sperre älter ist. Dependabot schlägt vsce-Updates für diese Lockdatei vor; mergen Sie dasjenige, das das Minimum erreicht, bevor Sie umschalten. -
Die Richtlinie anlegen. Melden Sie sich als Owner des Publishers an, öffnen Sie
https://marketplace.visualstudio.com/manage/publishers/ahmed-g-gadund fügen Sie unter Trusted Publishing eine Richtlinie hinzu:- Richtlinienname: ein beliebiger Name, etwa
apothem-release - Repository-Eigentümer:
Ahmed-G-Gad - Repository:
apothem - Workflow:
publish-vscode.yml - Umgebung:
release
Die Feldnamen sind die, die der VS Code-Veröffentlichungsleitfaden in seinem Abschnitt zur Veröffentlichung mit GitHub Actions und Trusted Publishing aufführt (
https://code.visualstudio.com/api/working-with-extensions/publishing-extension). Unbestätigt: ob jeder Publisher den Tab Trusted Publishing bereits sieht. Wenn Ihrer ihn nicht sieht, verwenden Sie den Entra-Weg. - Richtlinienname: ein beliebiger Name, etwa
-
Den Weg umschalten. Lassen Sie
VSCODE_MARKETPLACE_READYauftrueund setzen Sie den Selektor. Setzen Sie ihn, wenn kein Tag wartet, denn der nächste Tag-Push veröffentlicht über diesen Weg.gh variable set VSCE_AUTH --body oidc -
Veröffentlichen. Der nächste Tag-Push oder ein Start für ein bestehendes Tag veröffentlicht über Trusted Publishing. Dieser Weg hat keinen Probelauf: Die erste Veröffentlichung ist die Prüfung, und ein Start mit
dry_runwarnt nur, dass nichts verifiziert wurde. -
Bei einem Fehlschlag zurückfallen. Löschen Sie den Selektor und starten Sie erneut für dasselbe Tag; ist das Secret
VSCE_PATgesetzt, veröffentlicht der Token-Weg. Eine fehlgeschlagene Veröffentlichung hat nichts veröffentlicht, daher kann dasselbe Tag erneut gestartet werden.gh variable delete VSCE_AUTH
Marketplace-Veröffentlichung mit Microsoft Entra ID
Der Entra-Weg ersetzt das gespeicherte persönliche Zugriffstoken durch ein
kurzlebiges Token. publish-vscode.yml fordert bei GitHub ein OIDC-Token an,
die Aktion Azure/login tauscht es über eine föderierte Zugangsberechtigung
gegen eine Entra-Anmeldung, und vsce publish --azure-credential
veröffentlicht mit dem resultierenden Token. Es existiert kein Client-Secret.
Das Secret VSCE_PAT bleibt als Rückfalloption bestehen, die der Operator
auswählt; der Workflow wechselt nie von selbst darauf.
Das in tools/vsce gepinnte vsce-Release unterstützt diesen Weg. Er erfordert
einen Entra-Mandanten, eine Anwendungsregistrierung und eine
Publisher-Mitgliedschaft, was Trusted Publishing oben nicht erfordert;
verwenden Sie ihn, wenn Trusted Publishing für den Publisher nicht verfügbar
ist.
-
Die Voraussetzungen prüfen. Ermitteln Sie das Konto, dem der Publisher
ahmed-g-gadgehört (der Tab Members unterhttps://marketplace.visualstudio.com/manage/publishers/ahmed-g-gad), und den Entra-Mandanten, in dem Sie Anwendungen registrieren können. Unbestätigt: ob der Mandant des Publisher-Eigentümers mit dem Mandanten der Anwendung übereinstimmen muss und ob die Azure DevOps-OrganisationAhmed-G-Gadmit Entra verbunden sein muss (dev.azure.com/Ahmed-G-Gad, Organization settings, Microsoft Entra). Keine Quelle nennt eines von beiden. Wenn Schritt 5 oder 6 fehlschlägt, prüfen Sie diese Punkte zuerst. -
Die Anwendung registrieren. Öffnen Sie in
https://entra.microsoft.comApp registrations und dann New registration. Nennen Sie sieapothem-vscode-publish, wählen Sie einen einzelnen Mandanten und lassen Sie die Umleitungs-URI leer. Kopieren Sie unter Overview die Application (client) ID und die Directory (tenant) ID. Legen Sie kein Client-Secret an und erteilen Sie keine API-Berechtigung. Der Schritt erfordert Anwendungseigentümerrechte oder eine Entra-Rolle wie Application Administrator. -
Die föderierte Zugangsberechtigung hinzufügen. Öffnen Sie in dieser Anwendung Certificates & secrets, Federated credentials, Add credential, und wählen Sie das Szenario „GitHub Actions deploying Azure resources“. Geben Sie die Organisation
Ahmed-G-Gad, das Repositoryapothem, den EntitätstypEnvironment, den Umgebungsnamenreleaseund den Namen der Zugangsberechtigungapothem-releaseein. Die erzeugten Felder müssen lauten:issuer: https://token.actions.githubusercontent.com subject: repo:Ahmed-G-Gad/apothem:environment:release audience: api://AzureADTokenExchangeDer Abgleich ist exakt und unterscheidet Groß- und Kleinschreibung. Wenn eine spätere Anmeldung mit AADSTS700213 oder AADSTS7002138 fehlschlägt, vergleichen Sie die Zugangsberechtigung mit der Zeile
subject claim, dieAzure/loginin das Job-Protokoll schreibt. AADSTS70021 direkt nach dem Anlegen bedeutet, dass sich die Zugangsberechtigung noch nicht verbreitet hat; warten Sie einige Minuten und versuchen Sie es erneut. -
Die Repository-Variablen setzen. Solange
VSCODE_MARKETPLACE_READYden Werttruehat, ist der Entra-Weg aktiv, sobald alle drei gesetzt sind; setzen Sie sie daher, wenn kein Release-Tag auf Genehmigung wartet. OhneVSCODE_MARKETPLACE_READY=truemeldet sich nichts an, und der Lauf überspringt die Veröffentlichung.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 entraLassen Sie
VSCODE_MARKETPLACE_READYundVSCE_PATunverändert. WennVSCE_AUTHden Wertentrahat,AZURE_CLIENT_IDoderAZURE_TENANT_IDaber leer ist, protokolliert der Workflow eine Warnung, unabhängig davon, obVSCE_PATgesetzt ist, und verwendet den Entra-Weg nicht. Er verwendet dann das SecretVSCE_PAT, sofern es gesetzt ist; ohne Secret veröffentlicht er nichts, und der Lauf endet trotzdem grün; achten Sie daher auf die Warnung. -
Den Probelauf ausführen. Starten Sie den Workflow für ein bestehendes Release-Tag mit gesetztem
dry_run. Auf dem Entra-Weg meldet er sich an, gibt das Azure DevOps-Profil aus und verifiziert den Publisher-Zugriff, ohne zu veröffentlichen. Der Token-Weg hat keinen Probelauf: Zeigt das ProtokollMarketplace credential mode: pat, endet der Lauf grün mit einer Warnung und hat nichts verifiziert. Genehmigen Sie den wartenden Lauf der Umgebungrelease.gh workflow run publish-vscode.yml --ref main -f tag=vX.Y.Z -f dry_run=trueErwartet:
Marketplace credential mode: entra, eine Zeilesubject claim, die dem Subjekt aus Schritt 3 entspricht, sowie die Profil-WerteidunddisplayName, die der erste Probelauf-Schritt ausgibt. Der Verifizierungsschritt schlägt erwartungsgemäß bis Schritt 6 mit einem 403 fehl. Unbestätigt: dass eine Anmeldung ohne Azure-Abonnement über die Azure CLI ein Token für den Marketplace liefert. Dieser Lauf ist der erste Test dafür. Schlägt er hier fehl, registrieren Sie stattdessen eine benutzerseitig zugewiesene verwaltete Identität in einem Abonnement; das ist der Weg, den Microsoft dokumentiert. -
Die Anwendung zum Publisher hinzufügen. Melden Sie sich im Tab Members aus Schritt 1 als Owner des Publishers an und fügen Sie ein Mitglied mit der Profil-
idaus Schritt 5 und der Rolle Contributor hinzu. Unbestätigt: die Feldbezeichnung des Dialogs und ob er die ID akzeptiert, bevor die Anwendung Mitglied einer Azure DevOps-Organisation ist. Azure DevOps fügt Anwendungsidentitäten in der Regel pro Organisation hinzu. Lehnt der Dialog die ID ab, fügen Sie den Dienstprinzipal der OrganisationAhmed-G-Gadhinzu (Organization settings, Users, mit der Object ID der Enterprise application) und versuchen Sie es erneut. Ebenfalls unbestätigt: ob das Profil vor dem ersten Azure DevOps-Aufruf der Identität existiert. -
Den Probelauf wiederholen. Der Verifizierungsschritt gelingt nun mit „verification succeeded for the publisher“; seine Meldungen sprechen weiterhin von Personal Access Token, weil das Entra-Token denselben Pfad nimmt. Die Prüfung belegt die Publisher-Mitgliedschaft (Creator, Owner, Contributor oder Reader), nicht Veröffentlichungsrechte. Unbestätigt: dass Contributor genügt, um ein Update zu veröffentlichen. Microsofts Rollenbeschreibung sagt, dass es genügt, und keine Quelle zeigt eine Veröffentlichung damit; daher ist die erste echte Veröffentlichung der Beweis.
-
Ein Release veröffentlichen. Taggen Sie wie in §2.2 und genehmigen Sie den Lauf. Der Schritt
Publish to Visual Studio Marketplace (Entra ID)läuft, sein Umgebungs-Header führt nurAZURE_TENANT_IDauf, der Token-Rückfallschritt wird übersprungen, und vsce gibtDONE Published ahmed-g-gad.apothem-vscodeaus. Die Marketplace-Galerie führt die neue Version nach etwa vier Minuten auf. -
Über das Token entscheiden. Behalten Sie
VSCE_PATbis zur ersten erfolgreichen Entra-Veröffentlichung und löschen Sie das Secret dann, wenn keine Rückfalloption gewünscht ist. Sobald es entfernt ist, lässt eine gelöschte oder leere Entra-Variable den Lauf ohne Veröffentlichung grün enden: mit einer Warnung, wennVSCE_AUTHnochentraist, und nur mit dem Überspringen-Hinweis, wenn nicht. Lesen Sie nach jedem Tag die Annotationen des Laufs. Um eine Rückfalloption über die Abschaffung globaler persönlicher Zugriffstoken hinaus zu behalten, erstellen Sie ein auf die Organisation beschränktes Token fürAhmed-G-Gadmit dem benutzerdefinierten Geltungsbereich Marketplace Manage und der kürzesten Ablaufzeit, die Sie akzeptieren, und speichern Sie es alsVSCE_PAT. Unbestätigt: Die Portal-Bezeichnungen in diesem Schritt stammen aus dem Gedächtnis, nicht aus einer Primärquelle; Microsoft bezeichnet auf die Organisation beschränkte Token als vorübergehende Notlösung und kann aufhören, sie anzuerkennen; und Microsofts Seiten widersprechen sich beim Abschaffungsdatum globaler Token. -
Auf das Token zurückfallen. Löschen Sie den Selektor, starten Sie erneut und genehmigen Sie dann den Lauf. Eine fehlgeschlagene Entra-Veröffentlichung hat nichts veröffentlicht, daher kann dasselbe Tag erneut gestartet werden; prüfen Sie zuerst die Marketplace-Seite, denn eine gelandete Version kann nicht zweimal veröffentlicht werden.
gh variable delete VSCE_AUTH gh workflow run publish-vscode.yml --ref main -f tag=vX.Y.Z
Wenn die Entra-Veröffentlichung fehlschlägt, lesen Sie das Schrittprotokoll:
- Eine Meldung, die mit „Can not acquire a Microsoft Entra ID access token“
beginnt, bedeutet, dass die Anmeldung oder die Kette der Zugangsberechtigungen
fehlgeschlagen ist. Prüfen Sie zuerst den Schritt
Sign in to Microsoft Entra IDund die föderierte Zugangsberechtigung. Ist die Anmeldung grün, entfernen SieAZURE_TENANT_IDaus demenvdes vsce-Schritts im Workflow; GitHubs eigener Release-Workflow für Erweiterungen exportiert es nicht. - „InvalidAccessException“ oder „not allowed“ bedeutet, dass die Identität des
Tokens kein Publisher-Mitglied ist. Vergleichen Sie die Profil-
idaus dem Probelauf mit dem Tab Members. - Ein 403 aus dem Verifizierungsschritt des Probelaufs bedeutet, dass die Anwendung noch keine Rolle hat.
Für diesen Weg gelten drei Einschränkungen:
id-token: writewird dem gesamten Veröffentlichungsjob gewährt, daher kann jeder Schritt darin ein OIDC-Token anfordern, auch im Token-Modus. Das Subjekt des Tokens ist an die Umgebungreleasegebunden, die die Genehmigung eines Reviewers verlangt.- Die Umgebung
releasehat keine Deployment-Richtlinie für Branches oder Tags, daher kann jede Ref, die ein Maintainer genehmigt, das Umgebungs-Subjekt-Token erhalten. Eine Beschränkung aufv*.*.*-Tags erfordert zuerst eine Prüfung dessen, wasrelease.ymlundpublish-npm.ymlstarten. - Eine Umbenennung oder Übertragung des Repositorys ändert das Format des
OIDC-Subjekts und bricht die föderierte Zugangsberechtigung stillschweigend.
Kopieren Sie nach jeder Umbenennung das Subjekt aus dem
Azure/login-Protokoll erneut in die Zugangsberechtigung.
2.5 Den Template-Digest-Pin aktualisieren
Sobald das Tag existiert, setzen Sie _LATEST_RELEASE und
_LATEST_RELEASE_DIGESTS in tests/unit/test_template_digests.py auf das neue
Release und den SHA-256-Digest jedes Klartext-Templates, wie dieses Release es
ausgeliefert hat (git show vX.Y.Z:<template path> | sha256sum). Tun Sie dies
in der nächsten Änderung an main, und fügen Sie den vorherigen Digest zu den
earlier_digests des Manifest-Eintrags hinzu, wenn sich das Template geändert
hat. Der CI-Job release-preflight checkt jedes Tag aus und schlägt daher mit
den Tag-Namen fehl, bis der Pin aktualisiert ist.
3. Distributionsoberflächen
Jede Oberfläche hat einen Verifizierungsbefehl, der die Frage „Ist das Release hier gelandet?“ beantwortet:
| # | Oberfläche | Artefakt | Verifizierung |
|---|---|---|---|
| 1 | GitHub Release (Python-Distributionen) | apothem-X.Y.Z.tar.gz (sdist) + apothem-X.Y.Z-py3-none-any.whl | gh release view vX.Y.Z --json assets --jq '.assets[].name' enthält beide Dateinamen |
| 2 | GitHub Release (SBOM) | sbom.cdx.json + sbom.cdx.json.cosign.bundle | die Asset-Liste enthält beide; das metadata.component.purl des SBOM ist pkg:pypi/[email protected], und seine Komponenten umfassen jedes Paket in src/apothem/_vendor/vendor.txt |
| 3 | GitHub Release (Signaturen) | ein <asset>.cosign.bundle je sdist, Wheel, SBOM, VS Code-Erweiterung, Plattformarchiv und SHA256SUMS (frühere Releases benennen die Archiv- und SHA256SUMS-Bundles <asset>.sig) | cosign verify-blob mit der exakten Identität aus §5.5 endet mit 0 |
| 4 | GitHub Release (Provenienz) | provenance.intoto.jsonl | bash scripts/release/verify-provenance.sh <download-dir> endet mit 0 (§5.5) |
| 5 | GitHub Release (Plattformarchive) | apothem-vX.Y.Z-darwin.tar.gz, apothem-vX.Y.Z-linux.tar.gz, apothem-vX.Y.Z-windows.zip | die Asset-Liste enthält jedes Archiv plus SHA256SUMS. Die darwin- und linux-Archive sind dieselben Bytes unter zwei Namen (die Laufzeit ist plattformneutral; --platform wählt nur tar.gz oder zip), daher zeigen ihre SHA256SUMS-Zeilen denselben Digest zweimal |
| 6 | GitHub Release (VS Code-Erweiterung) | apothem.vsix + apothem.vsix.cosign.bundle | die Asset-Liste enthält beide; code --install-extension apothem.vsix installiert sie. Releases aus der Zeit, bevor der Release-Workflow die Erweiterung paketierte, enthalten keines von beiden |
| 7 | npmjs.com | @ahmed-g-gad/[email protected] | npm view @ahmed-g-gad/apothem version gibt X.Y.Z zurück; npx @ahmed-g-gad/[email protected] --version gibt Apothem, version X.Y.Z aus |
| 8 | Pages (Skript-Installer) | install.sh / install.ps1 auf der Dokumentationsseite | curl -fsSL https://apothem.ahmedgad.com/install.sh | head -n 1 gibt den Skript-Header zurück |
| 9 | Visual Studio Marketplace | ahmed-g-gad.apothem-vscode Version X.Y.Z | die Marketplace-Seite der Erweiterung führt X.Y.Z auf; code --install-extension ahmed-g-gad.apothem-vscode installiert sie |
Das GitHub Release ist die kanonische Artefaktoberfläche; das npm-Paket und die Skript-Installer sind die darauf aufsetzenden Installationspfade. Die npm-Veröffentlichung läuft beim selben Tag-Push neben dem Release-Workflow.
4. CHANGELOG-Disziplin
CHANGELOG.md trägt einen Abschnitt pro Release nach der
Keep-a-Changelog-Konvention. Die CHANGELOG-Bearbeitung des Release-Commits:
- Bestätigt, dass der Versionsabschnitt die Überschrift
## [X.Y.Z] - YYYY-MM-DDverwendet (ein Bindestrich;bump_version.pyschreibt sie, undextract_release_notes.pygleicht das Präfix## [X.Y.Z]ab). - Bestätigt, dass die Standardüberschriften — Added, Changed, Deprecated, Removed, Fixed, Security — verwendet werden, wo zutreffend. Leere Überschriften werden aus der gerenderten Datei entfernt.
- Erfasst Fähigkeiten, nicht die Implementierung. Nur Domänensprache; keine plan-internen Referenzen; keine Commit-Hashes; keine Plan- oder Phasenbezeichner.
Ein CHANGELOG-Abschnitt, der die Prüfung durch den Maintainer überstanden hat, dient als Release-Notes-Anker für die Ankündigungserzählung.
5. Installationspfad-Smoke-Test
Nachdem beide Stufen abgeschlossen sind, führt der Maintainer den Smoke-Test aus. Der Smoke-Test ist die kanonische Verifizierung, dass die benutzerseitigen Installationsbefehle antworten.
5.1 Claude Code-Plugin
/plugin marketplace add ahmed-g-gad/apothem
/plugin install apothem@apothemErwartet: Das Plugin wird installiert, und die apothem-Befehle sind innerhalb
von Claude Code verfügbar.
5.2 Node.js (npx)
npx @ahmed-g-gad/[email protected] --versionErwartete Ausgabe: Apothem, version X.Y.Z.
5.3 Ein-Schritt-Skript-Installer (POSIX)
Der Installer schreibt den Starter apothem nach ~/.local/bin oder in das Verzeichnis, das APOTHEM_BIN_DIR nennt, sofern diese Variable gesetzt ist. Die Prüfung unten braucht dieses Verzeichnis in PATH. Ist das nicht der Fall, gibt der Installer die Zeile export PATH aus, die hinzugefügt werden muss. Solange dieses Verzeichnis nicht in PATH liegt, findet die Shell apothem nicht, und die Prüfung schlägt fehl. Kann der Installer den Starter nicht ablegen, gibt er eine Warnung aus und keine Zeile export PATH. Auf einem Host, der den Maintainer-Signaturschlüssel noch nicht hat, importiert die erste Zeile ihn; ohne diesen Schlüssel bricht der Installer ab.
curl -fsSL https://github.com/ahmed-g-gad.gpg | gpg --import
curl -fsSL https://apothem.ahmedgad.com/install.sh | sh
apothem --versionErwartete Ausgabe: Apothem, version X.Y.Z.
5.4 Ein-Schritt-Skript-Installer (Windows)
Die erste Zeile importiert den Maintainer-Signaturschlüssel über Gits eigene bash, deren gpg-Schlüsselbund derjenige ist, den git verify-tag liest.
& "$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 --versionErwartete Ausgabe: Apothem, version X.Y.Z.
5.5 Artefakt-Verifizierung (Lieferketten-Nachweis)
Laden Sie jedes Asset in ein leeres Verzeichnis herunter und verifizieren Sie
dann. Die Zertifikatsidentität ist der Release-Workflow bei genau diesem Tag.
Identitätsprüfungen unterscheiden Groß- und Kleinschreibung, und die
Zertifikate tragen den Eigentümer so, wie GitHub ihn meldet, Ahmed-G-Gad;
ein kleingeschriebener Eigentümer schlägt daher fehl.
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 .Erwartet: Verified OK, PASSED: SLSA verification passed und
verify-provenance: chain OK (3 of 3 layers verified). Das Skript prüft
SHA256SUMS, jedes Signatur-Bundle und die Provenienz in einem Lauf; es
leitet das Tag aus dem Wheel-Namen ab (--tag vX.Y.Z überschreibt es).
Der Smoke-Test erzeugt eine einzeilige PASS / FAIL-Zeile pro Oberfläche; vermerken Sie die Zeilen im Release-Protokoll des Maintainers.
6. Fehlerbehebung
Der Release-Workflow hat dokumentierte Fehlermodi für die Release-Engine und den npm-Publisher:
| Fehler | Diagnose | Behebung |
|---|---|---|
| Tag-Push abgelehnt (Signierfehler) | git push origin vX.Y.Z gibt error: failed to push some refs mit einer GPG-bezogenen Meldung zurück | Verifizieren Sie, dass der GPG-Unterschlüssel geladen ist (gpg --list-secret-keys --keyid-format=long); taggen Sie lokal mit -s neu, nachdem Sie den Schlüsselbund repariert haben; pushen Sie erneut |
Release-Build stoppt bei Check the plugin version changed with the plugin | Das Protokoll des Build-Jobs nennt das Plugin und das vorherige Tag; es wurde kein Asset gebaut oder veröffentlicht | Das Plugin-Paket hat sich seit dem vorherigen Release geändert, seine Version aber nicht. Löschen Sie das Tag (git push --delete origin vX.Y.Z, git tag -d vX.Y.Z), führen Sie python scripts/release/bump_version.py X.Y.Z aus, committen Sie, und signieren und pushen Sie das Tag dann erneut (§2.2). Dieselbe Prüfung läuft bei jedem Pull Request als Warnungs-Annotation, sodass dies normalerweise vor dem Taggen auffällt |
Ein release.yml-Job scheitert an einer einzelnen Stufe | gh run view <run-id> --log nennt den fehlgeschlagenen Job (build, der auch das SBOM schreibt / sign / provenance / archive / publish) | Führen Sie den fehlgeschlagenen Job allein über gh run rerun <run-id> --failed erneut aus; wenn der Fehler erneut auftritt, beheben Sie die Eingabe des Jobs an ihrer Quelle, bevor Sie neu taggen |
| Die SLSA-Provenienz-Verifizierung scheitert | Der Job verify SLSA provenance artifact endet mit einem Wert ungleich null | Untersuchen Sie das Provenienz-Artefakt auf eine Abweichung des Subjekt-Digests; bauen Sie aus demselben Tag neu — die Provenienz bindet sich an die exakten Artefakt-Digests, sodass jede Neuerzeugung eines Artefakts eine vollständige erneute Ausführung des Workflows erfordert |
| Veröffentlichung auf npmjs.com abgelehnt | Der npm-Job endet während npm publish mit einem Wert ungleich null; ein Registry-404 während PUT ist eine Abweichung bei Autorisierung / Trusted Publisher, kein Beweis dafür, dass der Paketcode fehlt | Verifizieren Sie, dass npm Trusted Publishing für @ahmed-g-gad/apothem den Eigentümer ahmed-g-gad, das Repository apothem, den Workflow publish-npm.yml und die erlaubte Aktion npm publish nennt; bestätigen Sie, dass der Job mit der Node-Version und dem npm-CLI-OIDC-Mindeststand läuft, die im Workflow gepinnt sind |
| Tag sichtbar, aber Assets fehlen | gh release view vX.Y.Z gibt ein Stub-Release zurück | Führen Sie den Publish-Job des Release-Workflows erneut aus; er bearbeitet das bestehende Release und lädt jedes Asset erneut hoch. Löschen Sie das Tag und taggen Sie neu nur dann, wenn nichts aus dem Tag Benutzer erreicht hat (keine Assets, keine npm-Version); andernfalls korrigieren Sie nach vorn mit dem nächsten Patch-Release (Runbook zur Release-Wiederherstellung §2) |
Wenn ein Behebungszyklus eine Oberfläche nicht innerhalb eines einzigen Diagnosedurchlaufs landen kann, wird die Oberfläche als bekannter Fehler in den Release-Notes mit einem Link zum offenen Issue protokolliert; nachgelagerte Benutzer werden auf die funktionierenden Oberflächen verwiesen, während die defekte in einem Patch-Release behoben wird.
7. Querverweise
- Publisher-Einrichtung. Das Runbook zur Einrichtung des Publisher-Kontos etabliert die npm-Trusted-Publisher-Bindung und die GitHub-seitigen Voraussetzungen, von denen dieses Runbook ausgeht.
- Wiederherstellungsablauf. Das Runbook zur Release-Wiederherstellung folgt demselben additiven Modell: Es stellt ein fehlgeschlagenes Tag oder einen fehlgeschlagenen Publisher Stufe für Stufe wieder her und rollt zurück, indem es die Korrektur als neue Patch-Version veröffentlicht, niemals durch Löschen oder Neuausrichten eines veröffentlichten Tags, eines Releases oder einer npm-Version.
- Pages-Aktivierung. Der Workflow
publish-static-site.ymlvalidiert und deployt die Projekt-Website auf die benutzerdefinierte Domain; das Pages-Aktivierungs-Runbook (site/content/docs/runbooks/pages-enablement.mdx) ist das vorgelagerte Verfahren, das die benutzerdefinierte Domain ursprünglich eingerichtet hat. - Versionierungsrichtlinie.
site/content/docs/governance/release-engineering-policy.mdxenthält die Richtlinie zu SemVer + Signierung + Veraltung, die dieses Runbook einhält.