Skip to content
Apothem
Runbooks

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 status zeigt nichts Ausstehendes). Die gesamte Feature-Arbeit für das Release ist auf main.

  • CI grün. Für den neuesten Stand von main gibt gh run list --branch=main --limit=1 --json conclusion --jq '.[0].conclusion' den Wert success zurück.

  • Werkzeuge. gh (GitHub CLI) Version 2.40 oder neuer, authentifiziert gegen ahmed-g-gad; git 2.40 oder neuer mit geladenem GPG-Signier-Unterschlüssel; die npm-Trusted-Publisher-Bindung für @ahmed-g-gad/apothem ist aktiv (verifiziert gemäß dem Runbook zur Einrichtung des Publisher-Kontos).

  • Versionsanker ausgerichtet. Die in pyproject.toml deklarierte Versionszeichenkette stimmt ohne das v-Präfix mit dem geplanten Tag überein (§2.1 setzt sie, zusammen mit jedem anderen Anker). Verifizieren Sie:

    grep '^version' pyproject.toml

    Erwartete 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.Z

bump_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 ab vX.Y.Z, und ein [X.Y.Z]-Link wird hinzugefügt.

  • SECURITY.md: Eine neue Minor-Version erhält eine unterstützte X.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 main

Das 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 1

Warten 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.Z

Die 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 wenn gh bereits angemeldet ist. Verwenden Sie ein feingranulares persönliches Zugriffstoken, das auf ahmed-g-gad/apothem beschrä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 aus gh auth token trä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.Z

Die 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.

  1. Ein vsce-Release verwenden, das ihn unterstützt. Auf diesem Weg prüft der Veröffentlichungsjob vor dem Veröffentlichen das in tools/vsce gesperrte 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.

  2. Die Richtlinie anlegen. Melden Sie sich als Owner des Publishers an, öffnen Sie https://marketplace.visualstudio.com/manage/publishers/ahmed-g-gad und 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.

  3. Den Weg umschalten. Lassen Sie VSCODE_MARKETPLACE_READY auf true und 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
  4. 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_run warnt nur, dass nichts verifiziert wurde.

  5. Bei einem Fehlschlag zurückfallen. Löschen Sie den Selektor und starten Sie erneut für dasselbe Tag; ist das Secret VSCE_PAT gesetzt, 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.

  1. Die Voraussetzungen prüfen. Ermitteln Sie das Konto, dem der Publisher ahmed-g-gad gehört (der Tab Members unter https://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-Organisation Ahmed-G-Gad mit 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.

  2. Die Anwendung registrieren. Öffnen Sie in https://entra.microsoft.com App registrations und dann New registration. Nennen Sie sie apothem-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.

  3. 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 Repository apothem, den Entitätstyp Environment, den Umgebungsnamen release und den Namen der Zugangsberechtigung apothem-release ein. Die erzeugten Felder müssen lauten:

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

    Der 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, die Azure/login in 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.

  4. Die Repository-Variablen setzen. Solange VSCODE_MARKETPLACE_READY den Wert true hat, ist der Entra-Weg aktiv, sobald alle drei gesetzt sind; setzen Sie sie daher, wenn kein Release-Tag auf Genehmigung wartet. Ohne VSCODE_MARKETPLACE_READY=true meldet 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 entra

    Lassen Sie VSCODE_MARKETPLACE_READY und VSCE_PAT unverändert. Wenn VSCE_AUTH den Wert entra hat, AZURE_CLIENT_ID oder AZURE_TENANT_ID aber leer ist, protokolliert der Workflow eine Warnung, unabhängig davon, ob VSCE_PAT gesetzt ist, und verwendet den Entra-Weg nicht. Er verwendet dann das Secret VSCE_PAT, sofern es gesetzt ist; ohne Secret veröffentlicht er nichts, und der Lauf endet trotzdem grün; achten Sie daher auf die Warnung.

  5. 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 Protokoll Marketplace credential mode: pat, endet der Lauf grün mit einer Warnung und hat nichts verifiziert. Genehmigen Sie den wartenden Lauf der Umgebung release.

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

    Erwartet: Marketplace credential mode: entra, eine Zeile subject claim, die dem Subjekt aus Schritt 3 entspricht, sowie die Profil-Werte id und displayName, 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.

  6. 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-id aus 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 Organisation Ahmed-G-Gad hinzu (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.

  7. 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.

  8. 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 nur AZURE_TENANT_ID auf, der Token-Rückfallschritt wird übersprungen, und vsce gibt DONE Published ahmed-g-gad.apothem-vscode aus. Die Marketplace-Galerie führt die neue Version nach etwa vier Minuten auf.

  9. Über das Token entscheiden. Behalten Sie VSCE_PAT bis 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, wenn VSCE_AUTH noch entra ist, 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ür Ahmed-G-Gad mit dem benutzerdefinierten Geltungsbereich Marketplace Manage und der kürzesten Ablaufzeit, die Sie akzeptieren, und speichern Sie es als VSCE_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.

  10. 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 ID und die föderierte Zugangsberechtigung. Ist die Anmeldung grün, entfernen Sie AZURE_TENANT_ID aus dem env des 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-id aus 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: write wird 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 Umgebung release gebunden, die die Genehmigung eines Reviewers verlangt.
  • Die Umgebung release hat keine Deployment-Richtlinie für Branches oder Tags, daher kann jede Ref, die ein Maintainer genehmigt, das Umgebungs-Subjekt-Token erhalten. Eine Beschränkung auf v*.*.*-Tags erfordert zuerst eine Prüfung dessen, was release.yml und publish-npm.yml starten.
  • 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ächeArtefaktVerifizierung
1GitHub Release (Python-Distributionen)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' enthält beide Dateinamen
2GitHub Release (SBOM)sbom.cdx.json + sbom.cdx.json.cosign.bundledie 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
3GitHub 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
4GitHub Release (Provenienz)provenance.intoto.jsonlbash scripts/release/verify-provenance.sh <download-dir> endet mit 0 (§5.5)
5GitHub Release (Plattformarchive)apothem-vX.Y.Z-darwin.tar.gz, apothem-vX.Y.Z-linux.tar.gz, apothem-vX.Y.Z-windows.zipdie 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
6GitHub Release (VS Code-Erweiterung)apothem.vsix + apothem.vsix.cosign.bundledie 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
7npmjs.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
8Pages (Skript-Installer)install.sh / install.ps1 auf der Dokumentationsseitecurl -fsSL https://apothem.ahmedgad.com/install.sh | head -n 1 gibt den Skript-Header zurück
9Visual Studio Marketplaceahmed-g-gad.apothem-vscode Version X.Y.Zdie 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-DD verwendet (ein Bindestrich; bump_version.py schreibt sie, und extract_release_notes.py gleicht 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@apothem

Erwartet: 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] --version

Erwartete 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 --version

Erwartete 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 --version

Erwartete 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:

FehlerDiagnoseBehebung
Tag-Push abgelehnt (Signierfehler)git push origin vX.Y.Z gibt error: failed to push some refs mit einer GPG-bezogenen Meldung zurückVerifizieren 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 pluginDas Protokoll des Build-Jobs nennt das Plugin und das vorherige Tag; es wurde kein Asset gebaut oder veröffentlichtDas 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 Stufegh 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 scheitertDer Job verify SLSA provenance artifact endet mit einem Wert ungleich nullUntersuchen 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 abgelehntDer 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 fehltVerifizieren 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 fehlengh release view vX.Y.Z gibt ein Stub-Release zurückFü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.yml validiert 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.mdx enthält die Richtlinie zu SemVer + Signierung + Veraltung, die dieses Runbook einhält.

On this page