Skip to content
Apothem
Runbook

Runbook siklus rilis

Alur kerja rilis lengkap dari gerbang lokal melalui GitHub Release yang ditandatangani hingga publikasi npm.

Runbook ini membawa rilis vX.Y.Z dari apothem dari working tree yang bersih menuju permukaan distribusi yang terverifikasi. Prosedur ini ditulis untuk pemelihara yang menggunakan gh, git, dan shell tingkat rilis; prosedur ini berakhir dengan halaman Release yang terverifikasi, CHANGELOG yang tercatat, dan smoke jalur instalasi yang mengonfirmasi bahwa setiap permukaan yang berhadapan dengan pengguna menjawab perintah instalasi kanonis.

Model rilisnya aditif. Setiap rilis menambahkan satu commit di main dan satu tag vX.Y.Z beranotasi yang ditandatangani; tidak ada yang di-force-push dan tidak ada tag, GitHub Release, atau versi npm sebelumnya yang dihapus. Setiap rilis mempertahankan tag-nya, GitHub Release-nya, dan versi npm-nya, dan semuanya tetap terpublikasi: versi npm tidak dapat diubah (name@version yang telah dipublikasikan tidak pernah dapat diganti), dan pemasangan yang dipatok bergantung pada tag-tag tersebut.

Push tag memulai tiga alur kerja. .github/workflows/release.yml membangun, menandatangani, mengatestasi, dan memublikasikan GitHub Release dengan kumpulan artefak lengkapnya: sdist, wheel, SBOM CycloneDX, bundel cosign Sigstore, provenance SLSA-3, dan arsip runtime platform. publish-npm.yml memublikasikan @ahmed-g-gad/apothem ke npmjs.com melalui npm trusted publishing, dan publish-vscode.yml mengemas ekstensi VS Code dan memublikasikannya ke Visual Studio Marketplace. Bagian CHANGELOG berversi mendarat di commit rilis; operator menjalankan smoke jalur instalasi setelah kedua alur kerja selesai.

1. Prasyarat

Pemelihara mengonfirmasi hal berikut sebelum membuat tag:

  • Working tree. Bersih (git status tidak menampilkan apa pun yang tertunda). Semua pekerjaan fitur untuk rilis sudah ada di main.

  • CI hijau. Untuk main terbaru, gh run list --branch=main --limit=1 --json conclusion --jq '.[0].conclusion' mengembalikan success.

  • Perkakas. gh (GitHub CLI) versi 2.40 atau lebih baru yang terautentikasi terhadap ahmed-g-gad; git 2.40 atau lebih baru dengan subkunci penandatanganan GPG dimuat; ikatan trusted-publisher npm untuk @ahmed-g-gad/apothem aktif (diverifikasi sesuai runbook penyiapan akun penerbit).

  • Jangkar versi selaras. String versi yang dideklarasikan di pyproject.toml cocok dengan tag yang direncanakan tanpa awalan v (§2.1 menetapkannya, bersama setiap jangkar lainnya). Verifikasi:

    grep '^version' pyproject.toml

    Keluaran yang diharapkan (untuk rilis vX.Y.Z; placeholder mewakili tag rilis yang sedang berjalan):

    version = "X.Y.Z"
  • Entri CHANGELOG disiapkan. Butir-butir rilis berada di bawah ## [Unreleased] dalam heading Keep-a-Changelog; §2.1 mengubahnya menjadi bagian versi bertanggal dalam commit yang mendaratkan tag.

2. Tag dan picu

2.1 Tulis commit rilis

Versi tersimpan di lebih dari selusin berkas, jadi jangan menyuntingnya secara manual. Satu perintah memindahkan semuanya:

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

bump_version.py memperbarui setiap jangkar versi secara bersamaan:

  • Setiap manifest pengemasan, ekstensi, plugin, dan marketplace, ditambah berkas sitasi (versi dan tanggal rilis). Daftar lengkapnya:

    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: entri [Unreleased] menjadi bagian ## [X.Y.Z] bertanggal, [Unreleased] membandingkan dari vX.Y.Z, dan tautan [X.Y.Z] ditambahkan.

  • SECURITY.md: minor baru mendapat baris X.Y.x yang didukung. Apakah minor yang lebih lama tetap tercantum adalah keputusan Anda; skrip mencetak pengingat.

Skrip kemudian meregenerasi pohon turunan: paket plugin Claude Code, golden behavior-diff, serta halaman referensi dan changelog dokumentasi. Berikan --dry-run untuk mencantumkan perubahan terlebih dahulu, --date YYYY-MM-DD untuk menetapkan tanggal rilis (default: hari ini dalam UTC), atau --no-regen untuk melewati regenerasi. Skrip menolak versi yang salah bentuk atau penurunan versi, dan menjalankannya ulang dengan versi saat ini hanya menyelaraskan ulang jangkar yang menyimpang.

Tinjau diff, lalu commit:

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

Flag -S menandatangani commit dengan kunci GPG. Push memicu matriks CI standar (lint, test, build); tunggu hingga hijau sebelum membuat tag.

Pemeriksaan kesiapan di §2.4 juga memerlukan CodeQL dan Conformity hijau pada commit rilis. Keduanya hanya berjalan ketika path masing-masing berubah, dan commit rilis biasanya tidak mengubah satu pun path tersebut, sehingga jalankan keduanya setelah commit rilis menjadi head main, lalu konfirmasi bahwa setiap run menyebut commit tersebut:

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

Tunggu keduanya berhasil sebelum membuat tag, dan jangan push apa pun lagi ke main sampai rilis dipublikasikan: push berikutnya memindahkan main menjauh dari commit rilis, dan CI membatalkan run yang masih berjalan di branch yang sama.

2.2 Tandatangani dan push tag

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

Kombinasi -a -s menghasilkan tag beranotasi yang ditandatangani GPG. Push memicu .github/workflows/release.yml, yang membangun, menandatangani, mengatestasi, dan memublikasikan.

2.3 Konfirmasi alur kerja rilis selesai

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

Alur kerja menjalankan build (sdist + wheel, lalu SBOM CycloneDX dari distribusi tersebut yang ditulis di sampingnya), penandatanganan cosign keyless, pembuatan dan verifikasi provenance SLSA-3, build arsip platform (darwin / linux / windows), penandatanganan arsip dengan manifest SHA256SUMS teragregasi, dan publikasi GitHub Release akhir. Pemelihara memindai log job publish GitHub Release untuk konfirmasi unggahan aset.

Job publish GitHub Release berjalan di environment release, yang memerlukan persetujuan pemelihara, sehingga run akan menunggu di sana setelah job sebelumnya lolos. Setujui di halaman run-nya lewat Review deployments (tinjau deployment), atau dari 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"

Push tag juga memulai alur kerja npm dan ekstensi VS Code. Job publish keduanya menunggu persetujuan yang sama hingga §2.4.

2.4 Konfirmasi publikasi npm

Push tag juga menjalankan publish-npm.yml di samping release.yml. Alur kerja npm tidak menunggu alur kerja rilis; persetujuan environment release adalah gerbangnya. Setelah alur kerja rilis dari §2.3 selesai, konfirmasikan kesiapan. Pemeriksaan membaca rilis, eksekusi alur kerja, dan SBOM yang dipublikasikan, sehingga siapkan dua masukan terlebih dahulu:

  • GH_TOKEN. Skrip menolak berjalan tanpanya, bahkan ketika gh sudah masuk. Gunakan token akses pribadi berbutir-halus (fine-grained) yang dibatasi pada ahmed-g-gad/apothem, dengan Actions: Read (eksekusi alur kerja) dan Contents: Read (rilis). Pemeriksaan tidak menulis apa pun, sehingga izin tulis tidak diperlukan. Token dari gh auth token membawa setiap cakupan dari login tersebut, jadi utamakan token berbutir-halus.
  • SBOM yang dipublikasikan. Pemeriksaan membaca dist/release-assets/sbom.cdx.json, berkas CycloneDX yang dilampirkan rilis. Unduh salinan yang dipublikasikan rilis, bukan build lokal.
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

Pemeriksaan gagal ketika rilis berupa draf atau prarilis, ketika alur kerja yang diwajibkan untuk commit tag tidak hijau, ketika SBOM tidak ada, ketika SBOM menjelaskan versi lain, atau ketika SBOM menghilangkan paket yang di-vendor. Pesan kegagalan menyebutkan penyebabnya.

Ketika pemeriksaan lolos, setujui run Publish npm yang sedang menunggu dengan cara yang sama seperti di §2.3 (ID run-nya diambil dari gh run list --workflow=publish-npm.yml). Alur kerja memublikasikan @ahmed-g-gad/[email protected] ke npmjs.com melalui npm trusted publishing (OIDC); tidak ada token registri yang disimpan di repositori. Setujui juga run Publish VS Code Extension yang sedang menunggu. Run ini mengemas apothem.vsix dan memublikasikannya ke Visual Studio Marketplace sebagai ahmed-g-gad.apothem-vscode. Langkah publikasi hanya berjalan selama variabel repositori VSCODE_MARKETPLACE_READY bernilai true dan satu kredensial dikonfigurasi: variabel VSCE_AUTH=oidc (Trusted Publishing Marketplace, tanpa rahasia tersimpan), variabel VSCE_AUTH=entra, AZURE_CLIENT_ID dan AZURE_TENANT_ID (token Microsoft Entra ID berumur pendek, tanpa rahasia tersimpan), atau rahasia VSCE_PAT. Tanpa satu pun, run ini mengemas ekstensi dan melewati publikasi. Kredensial adalah sakelar, bukan percobaan ulang: publikasi yang gagal pada satu rute tidak beralih ke rute lain dengan sendirinya. Penyiapan untuk setiap rute ada di Publikasi Marketplace dengan Trusted Publishing (diutamakan) dan Publikasi Marketplace dengan Microsoft Entra ID di bawah.

Untuk memublikasikan lagi setelah run yang gagal, dispatch alur kerja untuk tag yang sama (gh workflow run publish-npm.yml --field tag=vX.Y.Z). Alur kerja melewati publikasi ketika versi sudah ada di registri, karena versi npm tidak dapat diubah.

Publikasi Marketplace dengan Trusted Publishing

Trusted Publishing memungkinkan Marketplace menerima token OIDC GitHub milik repositori ini secara langsung: vsce publish --oidc menukar token job publish dengan kredensial Marketplace berumur pendek. Tidak ada rahasia tersimpan dan tidak ada sumber daya Azure, sehingga ini adalah rute yang diutamakan. Rute Entra di bawah dan rahasia VSCE_PAT tetap menjadi alternatif yang dipilih operator.

  1. Gunakan rilis vsce yang mendukungnya. Pada rute ini job publish memeriksa rilis vsce yang dikunci di tools/vsce sebelum memublikasikan, dan berhenti dengan galat yang menyebutkan rilis minimum ketika kuncinya lebih lama. Dependabot mengusulkan pembaruan vsce untuk lockfile tersebut; gabungkan pembaruan yang mencapai rilis minimum sebelum Anda beralih.

  2. Buat kebijakan. Masuk sebagai Owner penerbit, buka https://marketplace.visualstudio.com/manage/publishers/ahmed-g-gad, dan tambahkan kebijakan di bawah Trusted Publishing:

    • Nama kebijakan: nama apa pun, seperti apothem-release
    • Pemilik repositori: Ahmed-G-Gad
    • Repositori: apothem
    • Alur kerja: publish-vscode.yml
    • Environment: release

    Nama-nama kolom tersebut adalah yang dicantumkan panduan publikasi VS Code, di bagiannya tentang publikasi dengan GitHub Actions dan Trusted Publishing (https://code.visualstudio.com/api/working-with-extensions/publishing-extension). Belum terkonfirmasi: apakah setiap penerbit sudah melihat tab Trusted Publishing. Jika penerbit Anda tidak melihatnya, gunakan rute Entra.

  3. Alihkan rute. Biarkan VSCODE_MARKETPLACE_READY bernilai true dan atur pemilihnya. Atur ketika tidak ada tag yang sedang menunggu, karena push tag berikutnya memublikasikan melalui rute ini.

    gh variable set VSCE_AUTH --body oidc
  4. Publikasikan. Push tag berikutnya, atau dispatch untuk tag yang sudah ada, memublikasikan melalui Trusted Publishing. Rute ini tidak memiliki dry run: publikasi pertama adalah pemeriksaannya, dan dispatch dengan dry_run hanya memperingatkan bahwa tidak ada yang diverifikasi.

  5. Kembali ke rute cadangan jika gagal. Hapus pemilihnya dan dispatch lagi untuk tag yang sama; dengan rahasia VSCE_PAT diatur, rute token memublikasikan. Publikasi yang gagal tidak memublikasikan apa pun, sehingga tag yang sama dapat di-dispatch lagi.

    gh variable delete VSCE_AUTH

Publikasi Marketplace dengan Microsoft Entra ID

Rute Entra mengganti token akses pribadi yang tersimpan dengan token berumur pendek. publish-vscode.yml meminta token OIDC kepada GitHub, aksi Azure/login menukarnya dengan sign-in Entra melalui kredensial federasi, dan vsce publish --azure-credential memublikasikan dengan token yang dihasilkan. Tidak ada rahasia klien. Rahasia VSCE_PAT tetap menjadi cadangan yang dipilih operator; alur kerja tidak pernah beralih ke sana dengan sendirinya.

Rilis vsce yang dipatok di tools/vsce mendukung rute ini. Rute ini memerlukan tenant Entra, pendaftaran aplikasi, dan keanggotaan penerbit, yang tidak diperlukan Trusted Publishing di atas; gunakan rute ini ketika Trusted Publishing tidak tersedia bagi penerbit.

  1. Periksa prasyaratnya. Temukan akun yang memiliki penerbit ahmed-g-gad (tab Members di https://marketplace.visualstudio.com/manage/publishers/ahmed-g-gad) dan tenant Entra tempat Anda dapat mendaftarkan aplikasi. Belum terkonfirmasi: apakah tenant pemilik penerbit harus cocok dengan tenant aplikasi, dan apakah organisasi Azure DevOps Ahmed-G-Gad harus terhubung ke Entra (dev.azure.com/Ahmed-G-Gad, Organization settings, Microsoft Entra). Tidak ada sumber yang menyatakan salah satunya. Jika langkah 5 atau 6 gagal, periksa hal-hal ini terlebih dahulu.

  2. Daftarkan aplikasi. Di https://entra.microsoft.com, buka App registrations, lalu New registration. Beri nama apothem-vscode-publish, pilih single tenant, dan biarkan redirect URI kosong. Dari Overview, salin Application (client) ID dan Directory (tenant) ID. Jangan buat rahasia klien dan jangan berikan izin API apa pun. Langkah ini memerlukan hak pemilik aplikasi atau peran Entra seperti Application Administrator.

  3. Tambahkan kredensial federasi. Pada aplikasi tersebut, buka Certificates & secrets, Federated credentials, Add credential, lalu pilih skenario "GitHub Actions deploying Azure resources". Masukkan organisasi Ahmed-G-Gad, repositori apothem, tipe entitas Environment, nama environment release, dan nama kredensial apothem-release. Kolom yang dihasilkan harus berbunyi:

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

    Pencocokan bersifat persis dan peka huruf besar-kecil. Jika sign-in berikutnya gagal dengan AADSTS700213 atau AADSTS7002138, bandingkan kredensial dengan baris subject claim yang ditulis Azure/login ke log job. AADSTS70021 tepat setelah pembuatan berarti kredensial belum tersebar; tunggu beberapa menit dan coba lagi.

  4. Atur variabel repositori. Selama VSCODE_MARKETPLACE_READY bernilai true, rute Entra aktif segera setelah ketiganya diatur, jadi aturlah ketika tidak ada tag rilis yang sedang menunggu persetujuan. Tanpa VSCODE_MARKETPLACE_READY=true tidak ada yang melakukan sign-in dan run melewati publikasi.

    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

    Biarkan VSCODE_MARKETPLACE_READY dan VSCE_PAT apa adanya. Ketika VSCE_AUTH bernilai entra tetapi AZURE_CLIENT_ID atau AZURE_TENANT_ID kosong, alur kerja mencatat peringatan, baik VSCE_PAT diatur maupun tidak, dan tidak menggunakan rute Entra. Alur kerja kemudian menggunakan rahasia VSCE_PAT jika rahasia itu diatur; tanpa rahasia, alur kerja tidak memublikasikan apa pun dan run tetap berakhir hijau, jadi carilah peringatannya.

  5. Jalankan dry run. Dispatch alur kerja untuk tag rilis yang sudah ada dengan dry_run diatur. Pada rute Entra, alur kerja melakukan sign-in, mencetak profil Azure DevOps, dan memverifikasi akses penerbit tanpa memublikasikan. Rute token tidak memiliki dry run: jika log menampilkan Marketplace credential mode: pat, run berakhir hijau dengan peringatan dan tidak memverifikasi apa pun. Setujui run environment release yang sedang menunggu.

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

    Yang diharapkan: Marketplace credential mode: entra, baris subject claim yang sama dengan subject di langkah 3, serta id dan displayName profil yang dicetak oleh langkah dry-run pertama. Langkah verifikasi diperkirakan gagal dengan 403 hingga langkah 6. Belum terkonfirmasi: bahwa sign-in tanpa langganan Azure menghasilkan token untuk Marketplace melalui Azure CLI. Run ini adalah pengujian pertamanya. Jika gagal di sini, daftarkan managed identity yang ditetapkan pengguna (user-assigned) di sebuah langganan sebagai gantinya, yang merupakan rute yang didokumentasikan Microsoft.

  6. Tambahkan aplikasi ke penerbit. Di tab Members dari langkah 1, masuk sebagai Owner penerbit dan tambahkan anggota menggunakan id profil dari langkah 5, dengan peran Contributor. Belum terkonfirmasi: label kolom pada dialog, dan apakah dialog menerima id tersebut sebelum aplikasi menjadi anggota organisasi Azure DevOps. Azure DevOps menambahkan identitas aplikasi per organisasi sebagai aturan umum. Jika dialog menolak id tersebut, tambahkan service principal ke organisasi Ahmed-G-Gad (Organization settings, Users, menggunakan Object ID Enterprise application) dan coba lagi. Juga belum terkonfirmasi: apakah profil sudah ada sebelum panggilan Azure DevOps pertama dari identitas tersebut.

  7. Ulangi dry run. Langkah verifikasi kini berhasil dengan "verification succeeded for the publisher"; pesannya masih menyebut Personal Access Token, karena token Entra melewati jalur yang sama. Pemeriksaan ini membuktikan keanggotaan penerbit (Creator, Owner, Contributor, atau Reader), bukan hak publikasi. Belum terkonfirmasi: bahwa Contributor cukup untuk memublikasikan pembaruan. Deskripsi peran dari Microsoft menyatakan cukup, dan tidak ada sumber yang menunjukkan publikasi dengan peran itu, sehingga publikasi nyata pertama adalah buktinya.

  8. Publikasikan rilis. Buat tag seperti di §2.2 dan setujui run-nya. Langkah Publish to Visual Studio Marketplace (Entra ID) berjalan, header environment-nya hanya mencantumkan AZURE_TENANT_ID, langkah cadangan token dilewati, dan vsce mencetak DONE Published ahmed-g-gad.apothem-vscode. Galeri Marketplace mencantumkan versi baru setelah sekitar empat menit.

  9. Putuskan tentang token. Pertahankan VSCE_PAT hingga publikasi Entra pertama yang berhasil, lalu hapus rahasia tersebut jika tidak menginginkan cadangan. Setelah rahasia itu hilang, variabel Entra yang terhapus atau kosong membuat run hijau tanpa publikasi: dengan peringatan ketika VSCE_AUTH masih bernilai entra, dan hanya dengan pemberitahuan lewati ketika tidak. Baca anotasi run setelah setiap tag. Untuk mempertahankan cadangan melewati pensiunnya token akses pribadi global, buat token bercakupan organisasi untuk Ahmed-G-Gad dengan cakupan kustom Marketplace Manage dan masa berlaku terpendek yang Anda terima, lalu simpan sebagai VSCE_PAT. Belum terkonfirmasi: label portal dalam langkah ini berasal dari ingatan, bukan dari sumber primer; Microsoft menyebut token bercakupan organisasi sebagai solusi sementara dan dapat berhenti menghormatinya; dan halaman-halaman Microsoft tidak sepakat tentang tanggal pensiun token global.

  10. Kembali ke token. Hapus pemilihnya dan dispatch lagi, lalu setujui run-nya. Publikasi Entra yang gagal tidak memublikasikan apa pun, sehingga tag yang sama dapat di-dispatch lagi; periksa halaman Marketplace terlebih dahulu, karena versi yang sudah mendarat tidak dapat dipublikasikan dua kali.

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

Ketika publikasi Entra gagal, baca log langkahnya:

  • Pesan yang diawali "Can not acquire a Microsoft Entra ID access token" berarti sign-in atau rantai kredensial gagal. Periksa langkah Sign in to Microsoft Entra ID dan kredensial federasi terlebih dahulu. Jika sign-in hijau, hapus AZURE_TENANT_ID dari env langkah vsce di alur kerja; alur kerja rilis ekstensi milik GitHub sendiri tidak mengekspornya.
  • "InvalidAccessException" atau "not allowed" berarti identitas token bukan anggota penerbit. Bandingkan id profil dari dry run dengan tab Members.
  • 403 dari langkah verifikasi dry-run berarti aplikasi belum memiliki peran.

Tiga batasan berlaku untuk rute ini:

  • id-token: write diberikan kepada seluruh job publish, sehingga setiap langkah di dalamnya dapat meminta token OIDC, juga dalam mode token. Subject token terikat pada environment release, yang memerlukan persetujuan peninjau.
  • Environment release tidak memiliki kebijakan branch atau tag deployment, sehingga ref apa pun yang disetujui pemelihara dapat memperoleh token environment-subject. Membatasinya ke tag v*.*.* memerlukan pemeriksaan terlebih dahulu atas apa yang di-dispatch release.yml dan publish-npm.yml.
  • Penggantian nama atau pemindahan repositori mengubah format subject OIDC dan diam-diam merusak kredensial federasi. Salin lagi subject dari log Azure/login ke kredensial setelah penggantian nama apa pun.

2.5 Segarkan pin digest templat

Setelah tag ada, atur _LATEST_RELEASE dan _LATEST_RELEASE_DIGESTS di tests/unit/test_template_digests.py ke rilis baru dan digest SHA-256 dari setiap templat teks biasa sebagaimana dikirimkan rilis tersebut (git show vX.Y.Z:<template path> | sha256sum). Lakukan ini dalam perubahan berikutnya ke main, dan tambahkan digest sebelumnya ke earlier_digests milik entri manifest ketika templat berubah. Job CI release-preflight melakukan checkout setiap tag, sehingga job ini gagal dengan menyebutkan nama-nama tag hingga pin disegarkan.

3. Permukaan Distribusi

Setiap permukaan memiliki perintah verifikasi yang menjawab "apakah rilis mendarat di sini?":

#PermukaanArtefakVerifikasi
1GitHub Release (distribusi 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' menyertakan kedua nama berkas
2GitHub Release (SBOM)sbom.cdx.json + sbom.cdx.json.cosign.bundledaftar aset menyertakan keduanya; metadata.component.purl milik SBOM adalah pkg:pypi/[email protected] dan komponennya mencakup setiap paket di src/apothem/_vendor/vendor.txt
3GitHub Release (tanda tangan)satu <asset>.cosign.bundle per sdist, wheel, SBOM, ekstensi VS Code, arsip platform, dan SHA256SUMS (rilis sebelumnya menamai bundel arsip dan SHA256SUMS sebagai <asset>.sig)cosign verify-blob dengan identitas persis di §5.5 keluar dengan kode 0
4GitHub Release (provenance)provenance.intoto.jsonlbash scripts/release/verify-provenance.sh <download-dir> keluar dengan kode 0 (§5.5)
5GitHub Release (arsip platform)apothem-vX.Y.Z-darwin.tar.gz, apothem-vX.Y.Z-linux.tar.gz, apothem-vX.Y.Z-windows.zipdaftar aset menyertakan setiap arsip ditambah SHA256SUMS. Arsip darwin dan linux adalah byte yang sama dengan dua nama (runtime bersifat netral-platform; --platform hanya memilih tar.gz atau zip), sehingga baris SHA256SUMS keduanya menampilkan satu digest dua kali
6GitHub Release (ekstensi VS Code)apothem.vsix + apothem.vsix.cosign.bundledaftar aset menyertakan keduanya; code --install-extension apothem.vsix memasangnya. Rilis yang dibuat sebelum alur kerja rilis mengemas ekstensi tidak membawa keduanya
7npmjs.com@ahmed-g-gad/[email protected]npm view @ahmed-g-gad/apothem version mengembalikan X.Y.Z; npx @ahmed-g-gad/[email protected] --version mencetak Apothem, version X.Y.Z
8Pages (pemasang skrip)install.sh / install.ps1 di situs dokumentasicurl -fsSL https://apothem.ahmedgad.com/install.sh | head -n 1 mengembalikan header skrip
9Visual Studio Marketplaceahmed-g-gad.apothem-vscode versi X.Y.Zhalaman Marketplace ekstensi mencantumkan X.Y.Z; code --install-extension ahmed-g-gad.apothem-vscode memasangnya

GitHub Release adalah permukaan artefak kanonis; paket npm dan pemasang skrip adalah jalur instalasi yang dilapiskan di atasnya. Publikasi npm berjalan di samping alur kerja rilis pada push tag yang sama.

4. Disiplin CHANGELOG

CHANGELOG.md membawa satu bagian per rilis di bawah konvensi Keep-a-Changelog. Suntingan CHANGELOG pada commit rilis:

  • Memastikan bagian versi menggunakan heading ## [X.Y.Z] - YYYY-MM-DD (tanda hubung; bump_version.py menuliskannya, dan extract_release_notes.py mencocokkan awalan ## [X.Y.Z]).
  • Memastikan heading standar — Added, Changed, Deprecated, Removed, Fixed, Security — digunakan jika berlaku. Heading kosong dihapus dari berkas yang dirender.
  • Menangkap kapabilitas, bukan implementasi. Hanya bahasa domain; tanpa referensi internal-rencana; tanpa hash commit; tanpa pengidentifikasi rencana atau fase.

Bagian CHANGELOG yang lolos tinjauan pemelihara berfungsi sebagai jangkar catatan rilis untuk narasi pengumuman.

5. Smoke jalur instalasi

Setelah kedua tahap selesai, pemelihara menjalankan smoke. Smoke adalah verifikasi kanonis bahwa perintah instalasi yang berhadapan dengan pengguna menjawab.

5.1 Plugin Claude Code

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

Diharapkan: plugin terpasang dan perintah apothem tersedia di dalam Claude Code.

5.2 Node.js (npx)

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

Keluaran yang diharapkan: Apothem, version X.Y.Z.

5.3 Pemasang skrip satu langkah (POSIX)

Pemasang menulis peluncur apothem ke ~/.local/bin, atau ke direktori yang dinamai oleh APOTHEM_BIN_DIR ketika variabel itu diatur. Pemeriksaan di bawah memerlukan direktori tersebut ada di PATH. Ketika tidak ada, pemasang mencetak baris export PATH yang perlu ditambahkan. Selama direktori tersebut belum ada di PATH, shell tidak dapat menemukan apothem, dan pemeriksaan gagal. Jika pemasang tidak dapat menempatkan peluncur, ia mencetak peringatan dan tidak mencetak baris export PATH. Pada host yang belum memegang kunci penandatanganan pemelihara, baris pertama mengimpornya; pemasang berhenti tanpa kunci tersebut.

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

Keluaran yang diharapkan: Apothem, version X.Y.Z.

5.4 Pemasang skrip satu langkah (Windows)

Baris pertama mengimpor kunci penandatanganan pemelihara melalui bash milik Git, yang keyring gpg-nya adalah keyring yang dibaca oleh git verify-tag.

& "$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

Keluaran yang diharapkan: Apothem, version X.Y.Z.

5.5 Verifikasi artefak (bukti rantai pasok)

Unduh setiap aset ke direktori kosong, lalu verifikasi. Identitas sertifikat adalah alur kerja rilis pada tag yang persis ini. Pemeriksaan identitas peka huruf besar-kecil, dan sertifikat membawa pemilik sebagaimana dilaporkan GitHub, Ahmed-G-Gad, sehingga pemilik dengan huruf kecil akan gagal.

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 .

Diharapkan: Verified OK, PASSED: SLSA verification passed, dan verify-provenance: chain OK (3 of 3 layers verified). Skrip memeriksa SHA256SUMS, setiap bundel tanda tangan, dan provenance dalam satu run; skrip menurunkan tag dari nama wheel (--tag vX.Y.Z menimpanya).

Smoke menghasilkan satu baris PASS / FAIL per permukaan; catat baris-baris itu di log rilis pemelihara.

6. Pemulihan kegagalan

Alur kerja rilis memiliki mode kegagalan terdokumentasi untuk engine rilis dan penerbit npm:

KegagalanDiagnostikPemulihan
Push tag ditolak (kegagalan penandatanganan)git push origin vX.Y.Z mengembalikan error: failed to push some refs dengan pesan terkait GPGVerifikasi bahwa subkunci GPG dimuat (gpg --list-secret-keys --keyid-format=long); buat ulang tag secara lokal dengan -s setelah memperbaiki keyring; push ulang
Build rilis berhenti di Check the plugin version changed with the pluginLog job build menyebutkan plugin dan tag sebelumnya; tidak ada aset yang dibangun atau dipublikasikanPaket plugin berubah sejak rilis sebelumnya tetapi versinya tidak. Hapus tag (git push --delete origin vX.Y.Z, git tag -d vX.Y.Z), jalankan python scripts/release/bump_version.py X.Y.Z, commit, lalu tandatangani dan push tag lagi (§2.2). Pemeriksaan yang sama berjalan pada setiap pull request sebagai anotasi peringatan, sehingga hal ini biasanya muncul sebelum pembuatan tag
Job release.yml gagal pada satu tahapgh run view <run-id> --log menyebutkan job yang gagal (build, yang juga menulis SBOM / sign / provenance / archive / publish)Jalankan ulang hanya job yang gagal via gh run rerun <run-id> --failed; jika kegagalan berulang, perbaiki input job di sumbernya sebelum membuat ulang tag
Verifikasi provenance SLSA gagalJob verify SLSA provenance artifact keluar dengan kode bukan nolPeriksa artefak provenance untuk ketidakcocokan subject-digest; bangun ulang dari tag yang sama — provenance terikat ke digest artefak yang persis, sehingga regenerasi artefak apa pun memerlukan rerun alur kerja penuh
Publikasi npmjs.com ditolakJob npm keluar dengan kode bukan nol saat npm publish; 404 registri saat PUT adalah ketidakcocokan otorisasi / trusted-publisher, bukan bukti bahwa kode paket hilangVerifikasi bahwa npm Trusted Publishing untuk @ahmed-g-gad/apothem menyebutkan pemilik ahmed-g-gad, repositori apothem, alur kerja publish-npm.yml, dan aksi yang diizinkan npm publish; konfirmasi bahwa job berjalan dengan versi Node dan batas bawah OIDC npm CLI yang dipatok di alur kerja
Tag terlihat tetapi aset hilanggh release view vX.Y.Z mengembalikan rilis stubJalankan ulang job publish alur kerja rilis; job ini menyunting rilis yang sudah ada dan mengunggah ulang setiap aset. Hapus dan buat ulang tag hanya ketika tidak ada apa pun dari tag tersebut yang sampai ke pengguna (tidak ada aset, tidak ada versi npm); jika tidak, perbaiki maju dengan rilis patch berikutnya (runbook pemulihan rilis §2)

Jika satu siklus pemulihan gagal mendaratkan sebuah permukaan dalam satu pass diagnostik, permukaan tersebut dicatat sebagai known-failure dalam catatan rilis dengan tautan ke isu terbuka; pengguna hilir diarahkan ke permukaan yang berfungsi sementara permukaan yang rusak diperbaiki dalam rilis patch.

7. Referensi silang

  • Penyiapan penerbit. Runbook penyiapan akun penerbit menetapkan ikatan trusted-publisher npm dan prasyarat sisi GitHub yang diasumsikan runbook ini.
  • Alur pemulihan. Runbook pemulihan rilis mengikuti model aditif yang sama: runbook tersebut memulihkan tag atau penerbit yang gagal tahap demi tahap dan melakukan rollback dengan merilis perbaikan sebagai versi patch baru, tidak pernah dengan menghapus atau mengarahkan ulang tag, rilis, atau versi npm yang telah dipublikasikan.
  • Pengaktifan Pages. Alur kerja publish-static-site.yml memvalidasi dan men-deploy situs web proyek ke domain kustom; runbook pengaktifan Pages (site/content/docs/runbooks/pages-enablement.mdx) adalah prosedur hulu yang menetapkan domain kustom sejak awal.
  • Kebijakan versioning. site/content/docs/governance/release-engineering-policy.mdx membawa kebijakan SemVer + penandatanganan + penghentian yang dihormati runbook ini.

On this page