रिलीज़-चक्र रनबुक
स्थानीय गेट से लेकर हस्ताक्षरित GitHub Release से होते हुए npm प्रकाशन तक का संपूर्ण रिलीज़ वर्कफ़्लो।
यह रनबुक apothem की vX.Y.Z रिलीज़ को एक स्वच्छ वर्किंग ट्री से सत्यापित
वितरण सतहों तक ले जाता है। यह प्रक्रिया उस अनुरक्षक के लिए लिखी गई है जो gh,
git, और रिलीज़-टियर शेल का उपयोग करता है; यह एक सत्यापित Release पृष्ठ, एक
दर्ज CHANGELOG, और एक इंस्टॉल-पथ स्मोक के साथ समाप्त होती है जो पुष्टि करता है
कि प्रत्येक उपयोगकर्ता-सामना करने वाली सतह कैनोनिकल इंस्टॉल कमांड का उत्तर देती
है।
रिलीज़ मॉडल योगात्मक है। प्रत्येक रिलीज़ main पर एक कमिट और एक
हस्ताक्षरित, एनोटेटेड vX.Y.Z टैग जोड़ती है; कुछ भी फ़ोर्स-पुश नहीं किया जाता
और कोई भी पिछला टैग, GitHub Release या npm संस्करण हटाया नहीं जाता। प्रत्येक रिलीज़ अपना टैग, अपनी GitHub Release और अपना npm संस्करण बनाए रखती है, और सभी प्रकाशित रहती हैं: npm संस्करण अपरिवर्तनीय हैं (किसी प्रकाशित
name@version को कभी बदला नहीं जा सकता), और पिन किए गए इंस्टॉल टैगों पर निर्भर
करते हैं।
टैग पुश तीन वर्कफ़्लो शुरू करता है। .github/workflows/release.yml GitHub Release
को उसके पूर्ण आर्टिफ़ैक्ट सेट के साथ बिल्ड करता है, हस्ताक्षर करता है, अटेस्ट
करता है और प्रकाशित करता है: sdist, wheel, CycloneDX SBOM, Sigstore cosign बंडल,
SLSA-3 प्रोवेनेंस, और प्लेटफ़ॉर्म रनटाइम आर्काइव। publish-npm.yml npm Trusted
Publishing के माध्यम से @ahmed-g-gad/apothem को npmjs.com पर प्रकाशित करता है, और
publish-vscode.yml VS Code एक्सटेंशन को पैकेज करता है और उसे Visual Studio
Marketplace पर प्रकाशित करता है।
संस्करण-युक्त CHANGELOG अनुभाग रिलीज़ कमिट में उतरता है; ऑपरेटर दोनों वर्कफ़्लो
पूरे होने के बाद इंस्टॉल-पथ स्मोक चलाता है।
1. पूर्वापेक्षाएँ
अनुरक्षक टैगिंग से पहले निम्नलिखित की पुष्टि करता है:
-
वर्किंग ट्री। स्वच्छ (
git statusकुछ भी लंबित नहीं दिखाता)। रिलीज़ के लिए सारा फ़ीचर कार्यmainपर है। -
CI हरा। नवीनतम
mainपरgh run list --branch=main --limit=1 --json conclusion --jq '.[0].conclusion'successलौटाता है। -
उपकरण।
gh(GitHub CLI) संस्करण 2.40 या नवीनतर,ahmed-g-gadके विरुद्ध प्रमाणित;git2.40 या नवीनतर, GPG हस्ताक्षर सबकी लोड के साथ;@ahmed-g-gad/apothemके लिए npm विश्वसनीय-प्रकाशक बंधन सक्रिय है (प्रकाशक-खाता-सेटअप रनबुक के अनुसार सत्यापित)। -
संस्करण एंकर संरेखित।
pyproject.tomlपर घोषित संस्करण स्ट्रिंगvउपसर्ग के बिना नियोजित टैग से मेल खाती है (§2.1 इसे, हर अन्य एंकर के साथ, सेट करता है)। सत्यापित करें:grep '^version' pyproject.tomlअपेक्षित आउटपुट (
vX.Y.Zरिलीज़ के लिए; प्लेसहोल्डर इन-फ़्लाइट रिलीज़ टैग का प्रतिनिधित्व करते हैं):version = "X.Y.Z" -
CHANGELOG प्रविष्टियाँ तैयार। रिलीज़ बुलेट Keep-a-Changelog हेडिंग में
## [Unreleased]के अंतर्गत रखे हैं; §2.1 उन्हें उस कमिट में दिनांकित संस्करण अनुभाग में बदल देता है जो टैग को उतारता है।
2. टैग और ट्रिगर
2.1 रिलीज़ कमिट लिखें
संस्करण एक दर्जन से अधिक फ़ाइलों में रहता है, इसलिए उन्हें हाथ से संपादित न करें। एक कमांड उन सभी को आगे बढ़ाता है:
git checkout main
git pull --ff-only origin main
python scripts/release/bump_version.py X.Y.Zbump_version.py हर संस्करण एंकर को एक साथ अपडेट करता है:
-
हर पैकेजिंग, एक्सटेंशन, प्लगइन और मार्केटप्लेस मैनिफ़ेस्ट, साथ ही उद्धरण फ़ाइल (संस्करण और रिलीज़ तिथि)। पूरी सूची:
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:[Unreleased]प्रविष्टियाँ एक दिनांकित## [X.Y.Z]अनुभाग बन जाती हैं,[Unreleased]की तुलनाvX.Y.Zसे शुरू होती है, और एक[X.Y.Z]लिंक जोड़ा जाता है। -
SECURITY.md: एक नए माइनर को एक समर्थितX.Y.xपंक्ति मिलती है। पुराने माइनर सूचीबद्ध रहें या नहीं, यह आपका निर्णय है; स्क्रिप्ट एक अनुस्मारक प्रिंट करती है।
इसके बाद यह व्युत्पन्न वृक्षों को पुनर्जनित करता है: Claude Code प्लगइन पैकेज,
व्यवहार-डिफ़ गोल्डन, और दस्तावेज़ संदर्भ तथा चेंजलॉग पृष्ठ। पहले परिवर्तनों की
सूची देखने के लिए --dry-run, रिलीज़ तिथि सेट करने के लिए --date YYYY-MM-DD (डिफ़ॉल्ट: UTC में आज), या पुनर्जनन छोड़ने के लिए --no-regen पास
करें। स्क्रिप्ट किसी विकृत संस्करण या डाउनग्रेड को अस्वीकार करती है, और वर्तमान
संस्करण के साथ इसे फिर से चलाने पर यह केवल भटके हुए एंकरों को फिर से संरेखित
करती है।
डिफ़ की समीक्षा करें, फिर कमिट करें:
git add -A
git commit -S -m "chore(release): cut vX.Y.Z"
git push origin main-S फ़्लैग कमिट को GPG कुंजी से हस्ताक्षरित करता है। पुश मानक CI मैट्रिक्स
(lint, test, build) को ट्रिगर करता है; टैगिंग से पहले हरे की प्रतीक्षा करें।
§2.4 की तत्परता जाँच के लिए रिलीज़ कमिट पर CodeQL और Conformity का हरा होना भी
आवश्यक है। ये दोनों केवल तब चलते हैं जब उनके अपने पथ बदलते हैं, और रिलीज़ कमिट
आमतौर पर इनमें से किसी भी पथ को नहीं बदलता। इसलिए जब रिलीज़ कमिट main का हेड बन
जाए, तब इन्हें शुरू करें, फिर पुष्टि करें कि हर रन इसी कमिट से जुड़ा है:
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टैग करने से पहले दोनों के सफल होने की प्रतीक्षा करें, और जब तक रिलीज़ जारी न हो जाए,
तब तक main पर कुछ और न पुश करें: बाद का पुश main को रिलीज़ कमिट से दूर ले जाता
है, और CI उसी ब्रांच पर अभी चल रहे रन को रद्द कर देता है।
2.2 टैग पर हस्ताक्षर करें और पुश करें
git tag -a -s vX.Y.Z -m "vX.Y.Z"
git push origin vX.Y.Z-a -s संयोजन एक एनोटेटेड, GPG-हस्ताक्षरित टैग बनाता है। पुश
.github/workflows/release.yml को ट्रिगर करता है, जो बिल्ड करता है, हस्ताक्षर
करता है, अटेस्ट करता है, और प्रकाशित करता है।
2.3 पुष्टि करें कि रिलीज़ वर्कफ़्लो पूर्ण हुआ
gh run watch $(gh run list --workflow=release.yml --limit=1 --json databaseId --jq '.[0].databaseId')वर्कफ़्लो बिल्ड (sdist + wheel, फिर उन वितरणों का एक CycloneDX SBOM जो उनके बगल
में लिखा जाता है), कीलेस cosign हस्ताक्षरण, SLSA-3 प्रोवेनेंस जनरेशन और सत्यापन,
प्लेटफ़ॉर्म आर्काइव बिल्ड (darwin / linux / windows), एक समेकित SHA256SUMS
मैनिफ़ेस्ट के साथ आर्काइव हस्ताक्षरण, और अंतिम GitHub Release प्रकाशन चलाता है।
अनुरक्षक असेट-अपलोड पुष्टियों के लिए publish GitHub Release जॉब लॉग को स्कैन
करता है।
publish GitHub Release जॉब release एनवायरनमेंट में चलता है, जिसके लिए अनुरक्षक का
अनुमोदन आवश्यक है, इसलिए पहले के जॉब पास होने के बाद रन वहीं प्रतीक्षा करता है। रन के
पृष्ठ पर इसे अनुमोदित करें (Review deployments — डिप्लॉयमेंट की समीक्षा करें), या शेल से:
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"टैग पुश npm और VS Code एक्सटेंशन वर्कफ़्लो को भी शुरू करता है। उनके प्रकाशन जॉब §2.4 तक इसी अनुमोदन की प्रतीक्षा करते हैं।
2.4 npm प्रकाशन की पुष्टि करें
टैग पुश release.yml के साथ-साथ publish-npm.yml भी चलाता है। npm वर्कफ़्लो रिलीज़ वर्कफ़्लो की प्रतीक्षा नहीं करता; release एनवायरनमेंट का अनुमोदन ही गेट है। §2.3 का रिलीज़ वर्कफ़्लो पूरा हो जाने के बाद, तत्परता की पुष्टि करें। यह जाँच रिलीज़, वर्कफ़्लो रन और प्रकाशित SBOM पढ़ती है, इसलिए पहले ये दो इनपुट सेट करें:
GH_TOKEN. स्क्रिप्ट इसके बिना चलने से इनकार करती है, भले हीghपहले से लॉग इन हो।ahmed-g-gad/apothemतक सीमित एक फ़ाइन-ग्रेन्ड पर्सनल एक्सेस टोकन उपयोग करें, जिसमें Actions: Read (वर्कफ़्लो रन) और Contents: Read (रिलीज़) हों। जाँच कुछ भी नहीं लिखती, इसलिए किसी भी लिखने की अनुमति की आवश्यकता नहीं है।gh auth tokenसे मिला टोकन लॉगिन के हर स्कोप को वहन करता है, इसलिए फ़ाइन-ग्रेन्ड टोकन को प्राथमिकता दें।- प्रकाशित SBOM। जाँच
dist/release-assets/sbom.cdx.jsonपढ़ती है, वह CycloneDX फ़ाइल जो रिलीज़ के साथ संलग्न होती है। स्थानीय बिल्ड के बजाय वही प्रति डाउनलोड करें जिसे रिलीज़ ने प्रकाशित किया है।
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जाँच तब विफल होती है जब रिलीज़ ड्राफ़्ट या प्रीरिलीज़ हो, जब टैग के कमिट के लिए आवश्यक कोई वर्कफ़्लो हरा न हो, जब SBOM गायब हो, जब वह किसी अन्य संस्करण का वर्णन करे, या जब वह कोई वेंडर्ड पैकेज छोड़ दे। विफलता संदेश कारण का नाम बताता है।
जाँच पास होने पर, §2.3 में बताए गए तरीके से ही प्रतीक्षा कर रहे Publish npm रन को अनुमोदित करें (उसका रन ID gh run list --workflow=publish-npm.yml से मिलता है)। वर्कफ़्लो npm Trusted Publishing (OIDC) के माध्यम से @ahmed-g-gad/[email protected] को npmjs.com पर प्रकाशित करता है; रिपॉज़िटरी में कोई रजिस्ट्री टोकन संग्रहीत नहीं है। प्रतीक्षा कर रहे Publish VS Code Extension रन को भी अनुमोदित करें। यह apothem.vsix पैकेज करता है और उसे ahmed-g-gad.apothem-vscode के रूप में Visual Studio Marketplace पर प्रकाशित करता है। प्रकाशन चरण केवल तभी चलता है जब रिपॉज़िटरी चर VSCODE_MARKETPLACE_READY true हो और एक क्रेडेंशियल कॉन्फ़िगर हो: चर VSCE_AUTH=oidc (Marketplace Trusted Publishing, कोई संग्रहीत सीक्रेट नहीं), चर VSCE_AUTH=entra, AZURE_CLIENT_ID और AZURE_TENANT_ID (एक अल्पकालिक Microsoft Entra ID टोकन, कोई संग्रहीत सीक्रेट नहीं), या VSCE_PAT सीक्रेट। इनमें से कोई न होने पर, रन एक्सटेंशन को पैकेज करता है और प्रकाशन छोड़ देता है। क्रेडेंशियल एक स्विच है, पुनःप्रयास नहीं: एक मार्ग पर विफल प्रकाशन अपने आप किसी दूसरे मार्ग पर फ़ॉलबैक नहीं करता। प्रत्येक मार्ग का सेटअप नीचे Trusted Publishing के साथ Marketplace प्रकाशन (वरीय) और Microsoft Entra ID के साथ Marketplace प्रकाशन में है।
किसी विफल रन के बाद फिर से प्रकाशित करने के लिए, उसी टैग के लिए वर्कफ़्लो डिस्पैच
करें (gh workflow run publish-npm.yml --field tag=vX.Y.Z)। जब संस्करण पहले से
रजिस्ट्री पर हो, तब यह प्रकाशन छोड़ देता है, क्योंकि npm संस्करण अपरिवर्तनीय हैं।
Trusted Publishing के साथ Marketplace प्रकाशन
Trusted Publishing, Marketplace को इस रिपॉज़िटरी का GitHub OIDC टोकन सीधे
स्वीकार करने देता है: vsce publish --oidc प्रकाशन जॉब के टोकन को एक अल्पकालिक
Marketplace क्रेडेंशियल से बदल लेता है। न कोई संग्रहीत सीक्रेट है और न कोई Azure
संसाधन, इसलिए यही वरीय मार्ग है। नीचे दिया गया Entra मार्ग और VSCE_PAT
सीक्रेट विकल्पों के रूप में बने रहते हैं, जिन्हें ऑपरेटर चुनता है।
-
ऐसी vsce रिलीज़ का उपयोग करें जो इसका समर्थन करती हो। इस मार्ग पर प्रकाशन जॉब प्रकाशित करने से पहले
tools/vsceमें लॉक की गई vsce रिलीज़ की जाँच करता है, और लॉक पुराना होने पर न्यूनतम रिलीज़ का नाम बताने वाली त्रुटि के साथ रुक जाता है। Dependabot उस लॉकफ़ाइल के लिए vsce अपडेट प्रस्तावित करता है; स्विच करने से पहले उस अपडेट को मर्ज करें जो न्यूनतम तक पहुँचता है। -
नीति बनाएँ। पब्लिशर के Owner के रूप में साइन इन करें,
https://marketplace.visualstudio.com/manage/publishers/ahmed-g-gadखोलें, और Trusted Publishing के अंतर्गत एक नीति जोड़ें:- नीति का नाम: कोई भी नाम, जैसे
apothem-release - रिपॉज़िटरी स्वामी:
Ahmed-G-Gad - रिपॉज़िटरी:
apothem - वर्कफ़्लो:
publish-vscode.yml - एनवायरनमेंट:
release
फ़ील्ड नाम वही हैं जो VS Code प्रकाशन मार्गदर्शिका GitHub Actions और Trusted Publishing के साथ प्रकाशन वाले अपने अनुभाग में सूचीबद्ध करती है (
https://code.visualstudio.com/api/working-with-extensions/publishing-extension)। अपुष्ट: क्या हर पब्लिशर को Trusted Publishing टैब अभी दिखता है। यदि आपको नहीं दिखता, तो Entra मार्ग का उपयोग करें। - नीति का नाम: कोई भी नाम, जैसे
-
मार्ग स्विच करें।
VSCODE_MARKETPLACE_READYकोtrueपर सेट रहने दें और चयनकर्ता सेट करें। इसे तब सेट करें जब कोई टैग प्रतीक्षा में न हो, क्योंकि अगला टैग पुश इसी मार्ग से प्रकाशित करता है।gh variable set VSCE_AUTH --body oidc -
प्रकाशित करें। अगला टैग पुश, या किसी मौजूदा टैग के लिए डिस्पैच, Trusted Publishing के माध्यम से प्रकाशित करता है। इस मार्ग में कोई ड्राई-रन नहीं है: पहला प्रकाशन ही जाँच है, और
dry_runके साथ डिस्पैच केवल यह चेतावनी देता है कि कुछ भी सत्यापित नहीं हुआ। -
विफल होने पर फ़ॉलबैक करें। चयनकर्ता हटाएँ और उसी टैग के लिए फिर से डिस्पैच करें;
VSCE_PATसीक्रेट सेट होने पर टोकन मार्ग प्रकाशित करता है। विफल प्रकाशन ने कुछ भी प्रकाशित नहीं किया, इसलिए उसी टैग को फिर से डिस्पैच किया जा सकता है।gh variable delete VSCE_AUTH
Microsoft Entra ID के साथ Marketplace प्रकाशन
Entra मार्ग संग्रहीत व्यक्तिगत एक्सेस टोकन को एक अल्पकालिक टोकन से बदल देता है।
publish-vscode.yml GitHub से एक OIDC टोकन माँगता है, Azure/login एक्शन उसे
एक फ़ेडरेटेड क्रेडेंशियल के माध्यम से Entra साइन-इन से बदलता है, और
vsce publish --azure-credential परिणामी टोकन से प्रकाशित करता है। कोई क्लाइंट
सीक्रेट मौजूद नहीं है। VSCE_PAT सीक्रेट एक फ़ॉलबैक के रूप में बना रहता है जिसे
ऑपरेटर चुनता है; वर्कफ़्लो कभी अपने आप उस पर स्विच नहीं करता।
tools/vsce में पिन की गई vsce रिलीज़ इस मार्ग का समर्थन करती है। इसके लिए एक
Entra टेनेंट, एक एप्लिकेशन पंजीकरण और पब्लिशर सदस्यता चाहिए, जो ऊपर दिए गए Trusted
Publishing के लिए आवश्यक नहीं हैं; इसका उपयोग तब करें जब पब्लिशर के लिए Trusted
Publishing उपलब्ध न हो।
-
पूर्व-शर्तों की जाँच करें। वह खाता खोजें जो पब्लिशर
ahmed-g-gadका स्वामी है (https://marketplace.visualstudio.com/manage/publishers/ahmed-g-gadपर Members टैब) और वह Entra टेनेंट जहाँ आप एप्लिकेशन पंजीकृत कर सकते हैं। अपुष्ट: क्या पब्लिशर स्वामी का टेनेंट एप्लिकेशन के टेनेंट से मेल खाना चाहिए, और क्या Azure DevOps संगठनAhmed-G-Gadको Entra से जुड़ा होना चाहिए (dev.azure.com/Ahmed-G-Gad, Organization settings, Microsoft Entra)। कोई भी स्रोत इनमें से किसी का उल्लेख नहीं करता। यदि चरण 5 या 6 विफल हो, तो पहले इन्हीं की जाँच करें। -
एप्लिकेशन पंजीकृत करें।
https://entra.microsoft.comमें App registrations, फिर New registration खोलें। इसका नामapothem-vscode-publishरखें, एकल टेनेंट चुनें, और redirect URI खाली छोड़ दें। Overview से Application (client) ID और Directory (tenant) ID कॉपी करें। कोई क्लाइंट सीक्रेट न बनाएँ और कोई API अनुमति न दें। इस चरण के लिए एप्लिकेशन-स्वामी अधिकार या Application Administrator जैसी कोई Entra भूमिका चाहिए। -
फ़ेडरेटेड क्रेडेंशियल जोड़ें। उस एप्लिकेशन पर Certificates & secrets, Federated credentials, Add credential खोलें, और परिदृश्य "GitHub Actions deploying Azure resources" चुनें। संगठन
Ahmed-G-Gad, रिपॉज़िटरीapothem, एंटिटी प्रकारEnvironment, एनवायरनमेंट नामrelease, और क्रेडेंशियल नामapothem-releaseदर्ज करें। उत्पन्न फ़ील्ड इस प्रकार होने चाहिए:issuer: https://token.actions.githubusercontent.com subject: repo:Ahmed-G-Gad/apothem:environment:release audience: api://AzureADTokenExchangeमिलान सटीक और केस-संवेदी है। यदि बाद में कोई साइन-इन AADSTS700213 या AADSTS7002138 के साथ विफल हो, तो क्रेडेंशियल की तुलना उस
subject claimपंक्ति से करें जोAzure/loginजॉब लॉग में लिखता है। बनाने के तुरंत बाद AADSTS70021 का अर्थ है कि क्रेडेंशियल अभी प्रसारित नहीं हुआ है; कुछ मिनट प्रतीक्षा करें और पुनः प्रयास करें। -
रिपॉज़िटरी चर सेट करें। जब तक
VSCODE_MARKETPLACE_READYtrueहै, तीनों के सेट होते ही Entra मार्ग सक्रिय हो जाता है, इसलिए इन्हें तब सेट करें जब कोई रिलीज़ टैग अनुमोदन की प्रतीक्षा में न हो।VSCODE_MARKETPLACE_READY=trueके बिना कुछ भी साइन इन नहीं करता और रन प्रकाशन छोड़ देता है।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 entraVSCODE_MARKETPLACE_READYऔरVSCE_PATको जैसे हैं वैसे ही छोड़ दें। जबVSCE_AUTHentraहो लेकिनAZURE_CLIENT_IDयाAZURE_TENANT_IDखाली हो, तो वर्कफ़्लो एक चेतावनी लॉग करता है, चाहेVSCE_PATसेट हो या नहीं, और Entra मार्ग का उपयोग नहीं करता। तब वहVSCE_PATसीक्रेट का उपयोग करता है यदि वह सेट हो; सीक्रेट न होने पर वह कुछ भी प्रकाशित नहीं करता और रन फिर भी हरे रंग में समाप्त होता है, इसलिए चेतावनी देखें। -
ड्राई-रन चलाएँ। किसी मौजूदा रिलीज़ टैग के लिए
dry_runसेट करके वर्कफ़्लो डिस्पैच करें। Entra मार्ग पर यह साइन इन करता है, Azure DevOps प्रोफ़ाइल प्रिंट करता है, और प्रकाशित किए बिना पब्लिशर एक्सेस सत्यापित करता है। टोकन मार्ग में कोई ड्राई-रन नहीं है: यदि लॉग मेंMarketplace credential mode: patदिखे, तो रन एक चेतावनी के साथ हरे रंग में समाप्त होता है और उसने कुछ भी सत्यापित नहीं किया है। प्रतीक्षा कर रहेreleaseएनवायरनमेंट रन को अनुमोदित करें।gh workflow run publish-vscode.yml --ref main -f tag=vX.Y.Z -f dry_run=trueअपेक्षित:
Marketplace credential mode: entra, चरण 3 के subject के बराबर एकsubject claimपंक्ति, और पहले ड्राई-रन चरण द्वारा प्रिंट की गई प्रोफ़ाइल कीidऔरdisplayName। चरण 6 तक सत्यापन चरण के 403 के साथ विफल होने की अपेक्षा है। अपुष्ट: कि Azure सब्सक्रिप्शन के बिना साइन-इन Azure CLI के माध्यम से Marketplace के लिए एक टोकन देता है। यह रन इसका पहला परीक्षण है। यदि यह यहाँ विफल हो, तो इसके बजाय किसी सब्सक्रिप्शन में एक उपयोगकर्ता-निर्दिष्ट प्रबंधित पहचान (user-assigned managed identity) पंजीकृत करें, जो Microsoft द्वारा प्रलेखित मार्ग है। -
एप्लिकेशन को पब्लिशर में जोड़ें। चरण 1 वाले Members टैब में, पब्लिशर Owner के रूप में साइन इन करें और चरण 5 की प्रोफ़ाइल
idका उपयोग करके Contributor भूमिका के साथ एक सदस्य जोड़ें। अपुष्ट: डायलॉग का फ़ील्ड लेबल, और क्या वह एप्लिकेशन के किसी Azure DevOps संगठन का सदस्य बनने से पहले id स्वीकार करता है। सामान्य नियम के रूप में Azure DevOps एप्लिकेशन पहचानें प्रति संगठन जोड़ता है। यदि डायलॉग id अस्वीकार कर दे, तो सर्विस प्रिंसिपल को संगठनAhmed-G-Gadमें जोड़ें (Organization settings, Users, Enterprise application Object ID का उपयोग करके) और पुनः प्रयास करें। यह भी अपुष्ट है: क्या प्रोफ़ाइल पहचान की पहली Azure DevOps कॉल से पहले मौजूद होती है। -
ड्राई-रन दोहराएँ। सत्यापन चरण अब "verification succeeded for the publisher" के साथ सफल होता है; उसके संदेश अब भी Personal Access Token कहते हैं, क्योंकि Entra टोकन उसी पथ से गुज़रता है। यह जाँच पब्लिशर सदस्यता (Creator, Owner, Contributor या Reader) सिद्ध करती है, प्रकाशन अधिकार नहीं। अपुष्ट: कि अपडेट प्रकाशित करने के लिए Contributor पर्याप्त है। Microsoft का भूमिका विवरण कहता है कि है, और कोई भी स्रोत इसके साथ प्रकाशन नहीं दिखाता, इसलिए पहला वास्तविक प्रकाशन ही प्रमाण है।
-
एक रिलीज़ प्रकाशित करें। §2.2 की तरह टैग करें और रन को अनुमोदित करें। चरण
Publish to Visual Studio Marketplace (Entra ID)चलता है, उसका एनवायरनमेंट हेडर केवलAZURE_TENANT_IDसूचीबद्ध करता है, टोकन फ़ॉलबैक चरण छोड़ दिया जाता है, और vsceDONE Published ahmed-g-gad.apothem-vscodeप्रिंट करता है। Marketplace गैलरी लगभग चार मिनट बाद नया संस्करण सूचीबद्ध करती है। -
टोकन पर निर्णय लें। पहले सफल Entra प्रकाशन तक
VSCE_PATरखें, फिर यदि कोई फ़ॉलबैक नहीं चाहिए तो सीक्रेट हटा दें। उसके हटने के बाद, हटाया गया या खाली Entra चर रन को बिना प्रकाशन के हरा छोड़ देता है:VSCE_AUTHअब भीentraहो तो एक चेतावनी के साथ, और न हो तो केवल छोड़ने की सूचना के साथ। हर टैग के बाद रन के एनोटेशन पढ़ें। वैश्विक व्यक्तिगत एक्सेस टोकनों की सेवानिवृत्ति के बाद भी फ़ॉलबैक रखने के लिए,Ahmed-G-Gadके लिए कस्टम स्कोप Marketplace Manage और आपको स्वीकार्य सबसे छोटी समाप्ति अवधि के साथ एक संगठन-स्कोप्ड टोकन बनाएँ, और उसेVSCE_PATके रूप में संग्रहीत करें। अपुष्ट: इस चरण के पोर्टल लेबल स्मृति से हैं, किसी प्राथमिक स्रोत से नहीं; Microsoft संगठन-स्कोप्ड टोकनों को एक अस्थायी उपाय कहता है और उन्हें मान्य करना बंद कर सकता है; और वैश्विक टोकनों की सेवानिवृत्ति तिथि पर Microsoft के पृष्ठ असहमत हैं। -
टोकन पर फ़ॉलबैक करें। चयनकर्ता हटाएँ और फिर से डिस्पैच करें, फिर रन को अनुमोदित करें। विफल Entra प्रकाशन ने कुछ भी प्रकाशित नहीं किया, इसलिए उसी टैग को फिर से डिस्पैच किया जा सकता है; पहले Marketplace पृष्ठ जाँचें, क्योंकि जो संस्करण पहुँच चुका है उसे दो बार प्रकाशित नहीं किया जा सकता।
gh variable delete VSCE_AUTH gh workflow run publish-vscode.yml --ref main -f tag=vX.Y.Z
जब Entra प्रकाशन विफल हो, तो चरण का लॉग पढ़ें:
- "Can not acquire a Microsoft Entra ID access token" से शुरू होने वाले संदेश का
अर्थ है कि साइन-इन या क्रेडेंशियल शृंखला विफल हुई। पहले
Sign in to Microsoft Entra IDचरण और फ़ेडरेटेड क्रेडेंशियल की जाँच करें। यदि साइन-इन हरा है, तो वर्कफ़्लो में vsce चरण केenvसेAZURE_TENANT_IDहटा दें; GitHub का अपना एक्सटेंशन रिलीज़ वर्कफ़्लो इसे निर्यात नहीं करता। - "InvalidAccessException" या "not allowed" का अर्थ है कि टोकन की पहचान पब्लिशर
की सदस्य नहीं है। ड्राई-रन की प्रोफ़ाइल
idकी तुलना Members टैब से करें। - ड्राई-रन सत्यापन चरण से 403 का अर्थ है कि एप्लिकेशन के पास अभी कोई भूमिका नहीं है।
इस मार्ग पर तीन सीमाएँ लागू होती हैं:
id-token: writeपूरे प्रकाशन जॉब को दिया जाता है, इसलिए उसका हर चरण OIDC टोकन का अनुरोध कर सकता है, टोकन मोड में भी। टोकन का subjectreleaseएनवायरनमेंट से बंधा है, जिसके लिए समीक्षक का अनुमोदन आवश्यक है।releaseएनवायरनमेंट में कोई डिप्लॉयमेंट ब्रांच या टैग नीति नहीं है, इसलिए अनुरक्षक द्वारा अनुमोदित कोई भी ref एनवायरनमेंट-subject टोकन प्राप्त कर सकता है। इसेv*.*.*टैगों तक सीमित करने के लिए पहले यह जाँचना होगा किrelease.ymlऔरpublish-npm.ymlक्या डिस्पैच करते हैं।- रिपॉज़िटरी का नाम बदलना या स्थानांतरण OIDC subject प्रारूप को बदल देता है और
फ़ेडरेटेड क्रेडेंशियल को चुपचाप तोड़ देता है। किसी भी नाम-परिवर्तन के बाद
Azure/loginलॉग से subject को फिर से क्रेडेंशियल में कॉपी करें।
2.5 टेम्पलेट-डाइजेस्ट पिन को ताज़ा करें
टैग मौजूद होने के बाद, tests/unit/test_template_digests.py में
_LATEST_RELEASE और _LATEST_RELEASE_DIGESTS को नई रिलीज़ और हर सादा-पाठ
टेम्पलेट के SHA-256 डाइजेस्ट पर सेट करें, जैसा उस रिलीज़ ने उसे शिप किया था
(git show vX.Y.Z:<template path> | sha256sum)। यह main में अगले बदलाव में
करें, और जब टेम्पलेट बदला हो तो पिछला डाइजेस्ट मैनिफ़ेस्ट प्रविष्टि के
earlier_digests में जोड़ें। release-preflight CI जॉब हर टैग चेक आउट करता है,
इसलिए पिन ताज़ा होने तक वह टैग नामों के साथ विफल होता है।
3. वितरण सतहें
प्रत्येक सतह के पास एक सत्यापन कमांड है जो "क्या रिलीज़ यहाँ उतरी?" का उत्तर देता है:
| # | सतह | आर्टिफ़ैक्ट | सत्यापन |
|---|---|---|---|
| 1 | GitHub Release (Python वितरण) | 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' में दोनों फ़ाइलनाम शामिल हैं |
| 2 | GitHub Release (SBOM) | sbom.cdx.json + sbom.cdx.json.cosign.bundle | असेट सूची में दोनों शामिल हैं; SBOM का metadata.component.purl pkg:pypi/[email protected] है और उसके घटकों में src/apothem/_vendor/vendor.txt का हर पैकेज शामिल है |
| 3 | GitHub Release (हस्ताक्षर) | प्रत्येक sdist, wheel, SBOM, VS Code एक्सटेंशन, प्लेटफ़ॉर्म आर्काइव और SHA256SUMS के लिए एक <asset>.cosign.bundle (पहले की रिलीज़ आर्काइव और SHA256SUMS बंडलों को <asset>.sig नाम देती हैं) | §5.5 में दी गई सटीक पहचान के साथ cosign verify-blob 0 के साथ बाहर निकलता है |
| 4 | GitHub Release (प्रोवेनेंस) | provenance.intoto.jsonl | bash scripts/release/verify-provenance.sh <download-dir> 0 के साथ बाहर निकलता है (§5.5) |
| 5 | GitHub Release (प्लेटफ़ॉर्म आर्काइव) | apothem-vX.Y.Z-darwin.tar.gz, apothem-vX.Y.Z-linux.tar.gz, apothem-vX.Y.Z-windows.zip | असेट सूची में हर आर्काइव और SHA256SUMS शामिल हैं। darwin और linux आर्काइव दो नामों के अंतर्गत समान बाइट्स हैं (रनटाइम प्लेटफ़ॉर्म-तटस्थ है; --platform केवल tar.gz या zip चुनता है), इसलिए उनकी SHA256SUMS पंक्तियाँ एक ही डाइजेस्ट दो बार दिखाती हैं |
| 6 | GitHub Release (VS Code एक्सटेंशन) | apothem.vsix + apothem.vsix.cosign.bundle | असेट सूची में दोनों शामिल हैं; code --install-extension apothem.vsix इसे इंस्टॉल करता है। रिलीज़ वर्कफ़्लो द्वारा एक्सटेंशन पैकेज किए जाने से पहले की रिलीज़ में इनमें से कोई भी नहीं है |
| 7 | npmjs.com | @ahmed-g-gad/[email protected] | npm view @ahmed-g-gad/apothem version X.Y.Z लौटाता है; npx @ahmed-g-gad/[email protected] --version Apothem, version X.Y.Z प्रिंट करता है |
| 8 | Pages (स्क्रिप्ट इंस्टॉलर) | दस्तावेज़ साइट पर install.sh / install.ps1 | curl -fsSL https://apothem.ahmedgad.com/install.sh | head -n 1 स्क्रिप्ट हेडर लौटाता है |
| 9 | Visual Studio Marketplace | ahmed-g-gad.apothem-vscode संस्करण X.Y.Z | एक्सटेंशन का Marketplace पृष्ठ X.Y.Z सूचीबद्ध करता है; code --install-extension ahmed-g-gad.apothem-vscode इसे इंस्टॉल करता है |
GitHub Release कैनोनिकल आर्टिफ़ैक्ट सतह है; npm पैकेज और स्क्रिप्ट इंस्टॉलर उसके ऊपर परतबद्ध इंस्टॉल पथ हैं। npm प्रकाशन उसी टैग पुश पर रिलीज़ वर्कफ़्लो के साथ-साथ चलता है।
4. CHANGELOG अनुशासन
CHANGELOG.md Keep-a-Changelog परंपरा के अंतर्गत प्रति रिलीज़ एक अनुभाग रखता है।
रिलीज़ कमिट का CHANGELOG संपादन:
- पुष्टि करता है कि संस्करण अनुभाग
## [X.Y.Z] - YYYY-MM-DDहेडिंग का उपयोग करता है (एक हाइफ़न;bump_version.pyइसे लिखता है, औरextract_release_notes.py## [X.Y.Z]उपसर्ग से मिलान करता है)। - पुष्टि करता है कि मानक हेडिंग — Added, Changed, Deprecated, Removed, Fixed, Security — जहाँ लागू हो वहाँ उपयोग की जाती हैं। खाली हेडिंग रेंडर की गई फ़ाइल से हटा दी जाती हैं।
- क्षमताओं को दर्ज करता है, कार्यान्वयन को नहीं। केवल डोमेन भाषा; कोई योजना-आंतरिक संदर्भ नहीं; कोई कमिट हैश नहीं; कोई योजना या चरण पहचानकर्ता नहीं।
जो CHANGELOG अनुभाग अनुरक्षक की समीक्षा से पार हो गया, वह घोषणा कथन के लिए रिलीज़-नोट्स एंकर के रूप में पढ़ा जाता है।
5. इंस्टॉल-पथ स्मोक
दोनों चरण पूर्ण होने के बाद, अनुरक्षक स्मोक चलाता है। स्मोक वह कैनोनिकल सत्यापन है कि उपयोगकर्ता-सामना करने वाले इंस्टॉल कमांड उत्तर देते हैं।
5.1 Claude Code प्लगइन
/plugin marketplace add ahmed-g-gad/apothem
/plugin install apothem@apothemअपेक्षित: प्लगइन इंस्टॉल होता है और apothem कमांड Claude Code के भीतर उपलब्ध
होते हैं।
5.2 Node.js (npx)
npx @ahmed-g-gad/[email protected] --versionअपेक्षित आउटपुट: Apothem, version X.Y.Z।
5.3 एक-चरण स्क्रिप्ट इंस्टॉलर (POSIX)
इंस्टॉलर apothem लॉन्चर को ~/.local/bin में लिखता है, या जब
APOTHEM_BIN_DIR चर सेट हो, तो उसके द्वारा नामित डायरेक्टरी में। नीचे की जाँच
के लिए उस डायरेक्टरी का PATH पर होना आवश्यक है। यदि वह नहीं है, तो इंस्टॉलर
जोड़ने के लिए export PATH पंक्ति प्रिंट करता है। जब तक वह डायरेक्टरी PATH पर
नहीं होती, शेल apothem नहीं ढूँढ सकता, और जाँच विफल हो जाती है। यदि इंस्टॉलर
लॉन्चर नहीं रख सकता, तो वह एक चेतावनी प्रिंट करता है और export PATH पंक्ति प्रिंट नहीं करता। जिस होस्ट के पास अभी मेंटेनर की हस्ताक्षर कुंजी नहीं है, वहाँ पहली पंक्ति
उसे आयात करती है; उसके बिना इंस्टॉलर रुक जाता है।
curl -fsSL https://github.com/ahmed-g-gad.gpg | gpg --import
curl -fsSL https://apothem.ahmedgad.com/install.sh | sh
apothem --versionअपेक्षित आउटपुट: Apothem, version X.Y.Z।
5.4 एक-चरण स्क्रिप्ट इंस्टॉलर (Windows)
पहली पंक्ति मेंटेनर की हस्ताक्षर कुंजी Git के अपने bash के माध्यम से आयात करती
है, जिसकी gpg कीरिंग वही है जिसे 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अपेक्षित आउटपुट: Apothem, version X.Y.Z।
5.5 आर्टिफ़ैक्ट सत्यापन (आपूर्ति-श्रृंखला साक्ष्य)
हर असेट को एक खाली डायरेक्टरी में डाउनलोड करें, फिर सत्यापित करें। प्रमाणपत्र
पहचान इसी सटीक टैग पर रिलीज़ वर्कफ़्लो है। पहचान जाँचें केस-संवेदी होती हैं, और
प्रमाणपत्र स्वामी को उसी रूप में रखते हैं जैसा GitHub उसे रिपोर्ट करता है,
Ahmed-G-Gad, इसलिए छोटे अक्षरों वाला स्वामी विफल होता है।
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 .अपेक्षित: Verified OK, PASSED: SLSA verification passed, और
verify-provenance: chain OK (3 of 3 layers verified)। स्क्रिप्ट एक ही रन में
SHA256SUMS, हर हस्ताक्षर बंडल, और प्रोवेनेंस की जाँच करती है; यह टैग को wheel
नाम से व्युत्पन्न करती है (--tag vX.Y.Z इसे ओवरराइड करता है)।
स्मोक प्रति सतह एक-पंक्ति PASS / FAIL प्रविष्टि उत्पन्न करता है; इन प्रविष्टियों को अनुरक्षक के रिलीज़ लॉग में दर्ज करें।
6. विफलता रिकवरी
रिलीज़ वर्कफ़्लो में रिलीज़ इंजन और npm प्रकाशक के लिए प्रलेखित विफलता मोड हैं:
| विफलता | निदान | रिकवरी |
|---|---|---|
| टैग पुश अस्वीकृत (हस्ताक्षर विफलता) | git push origin vX.Y.Z एक GPG-संबंधित संदेश के साथ error: failed to push some refs लौटाता है | सत्यापित करें कि GPG सबकी लोड है (gpg --list-secret-keys --keyid-format=long); कीरिंग ठीक करने के बाद -s के साथ स्थानीय रूप से फिर से टैग करें; फिर से पुश करें |
रिलीज़ बिल्ड Check the plugin version changed with the plugin पर रुक जाता है | बिल्ड जॉब लॉग प्लगइन और पिछले टैग का नाम बताता है; कोई असेट न बिल्ड हुआ, न प्रकाशित हुआ | पिछली रिलीज़ के बाद से प्लगइन पैकेज बदल गया, लेकिन उसका संस्करण नहीं बदला। टैग हटाएँ (git push --delete origin vX.Y.Z, git tag -d vX.Y.Z), python scripts/release/bump_version.py X.Y.Z चलाएँ, कमिट करें, फिर टैग पर दोबारा हस्ताक्षर करें और उसे पुश करें (§2.2)। यही जाँच हर पुल रिक्वेस्ट पर एक चेतावनी एनोटेशन के रूप में चलती है, इसलिए यह सामान्यतः टैगिंग से पहले ही सामने आ जाती है |
release.yml जॉब किसी एक चरण पर विफल होता है | gh run view <run-id> --log विफल जॉब का नाम बताता है (build, जो SBOM भी लिखता है / sign / provenance / archive / publish) | केवल विफल जॉब को gh run rerun <run-id> --failed के माध्यम से फिर से चलाएँ; यदि विफलता दोहराई जाती है, तो फिर से टैग करने से पहले जॉब के इनपुट को उसके स्रोत पर ठीक करें |
| SLSA प्रोवेनेंस सत्यापन विफल | verify SLSA provenance artifact जॉब गैर-शून्य के साथ बाहर निकलता है | सब्जेक्ट-डाइजेस्ट बेमेल के लिए प्रोवेनेंस आर्टिफ़ैक्ट का निरीक्षण करें; उसी टैग से फिर से बिल्ड करें — प्रोवेनेंस सटीक आर्टिफ़ैक्ट डाइजेस्ट से बँधा होता है, इसलिए किसी भी आर्टिफ़ैक्ट पुनर्जनन के लिए पूर्ण वर्कफ़्लो रीरन आवश्यक है |
| npmjs.com प्रकाशन अस्वीकृत | npm जॉब npm publish के दौरान गैर-शून्य के साथ बाहर निकलता है; PUT के दौरान रजिस्ट्री का 404 एक प्राधिकरण / विश्वसनीय-प्रकाशक बेमेल है, इस बात का प्रमाण नहीं कि पैकेज कोड गायब है | सत्यापित करें कि @ahmed-g-gad/apothem के लिए npm Trusted Publishing स्वामी ahmed-g-gad, रिपॉज़िटरी apothem, वर्कफ़्लो publish-npm.yml, और अनुमत क्रिया npm publish का नाम देता है; पुष्टि करें कि जॉब वर्कफ़्लो में पिन किए गए Node संस्करण और npm CLI OIDC फ़्लोर के साथ चलता है |
| टैग दिखाई देता है पर असेट गायब हैं | gh release view vX.Y.Z एक स्टब रिलीज़ लौटाता है | रिलीज़ वर्कफ़्लो का publish जॉब फिर से चलाएँ; यह मौजूदा रिलीज़ को संपादित करता है और हर असेट फिर से अपलोड करता है। टैग हटाकर फिर से टैग केवल तभी करें जब टैग से कुछ भी उपयोगकर्ताओं तक न पहुँचा हो (कोई असेट नहीं, कोई npm संस्करण नहीं); अन्यथा अगली पैच रिलीज़ के साथ आगे बढ़कर ठीक करें (रिलीज़-रिकवरी रनबुक §2) |
यदि कोई रिकवरी चक्र एक नैदानिक पास के भीतर किसी सतह को उतारने में विफल रहता है, तो उस सतह को खुले इश्यू के लिंक के साथ रिलीज़ नोट्स में एक ज्ञात-विफलता के रूप में दर्ज किया जाता है; जब तक टूटी हुई सतह किसी पैच रिलीज़ में ठीक की जाती है, तब तक डाउनस्ट्रीम उपयोगकर्ताओं को कार्यशील सतहों की ओर निर्देशित किया जाता है।
7. क्रॉस-संदर्भ
- प्रकाशक सेटअप। प्रकाशक-खाता-सेटअप रनबुक npm विश्वसनीय-प्रकाशक बंधन और वे GitHub-पक्ष पूर्वापेक्षाएँ स्थापित करता है जिन्हें यह रनबुक मानकर चलता है।
- रिकवरी प्रवाह। रिलीज़-रिकवरी रनबुक उसी योगात्मक मॉडल का पालन करता है: यह किसी विफल टैग या प्रकाशक को चरण-दर-चरण रिकवर करता है और सुधार को एक नए पैच संस्करण के रूप में रिलीज़ करके रोलबैक करता है, किसी प्रकाशित टैग, रिलीज़ या npm संस्करण को हटाकर या पुनः-इंगित करके कभी नहीं।
- Pages सक्षमीकरण।
publish-static-site.ymlवर्कफ़्लो परियोजना वेबसाइट को कस्टम डोमेन पर सत्यापित और डिप्लॉय करता है; Pages-सक्षमीकरण रनबुक (site/content/docs/runbooks/pages-enablement.mdx) वह अपस्ट्रीम प्रक्रिया है जिसने सबसे पहले कस्टम डोमेन स्थापित किया। - संस्करण नीति।
site/content/docs/governance/release-engineering-policy.mdxवह SemVer + हस्ताक्षरण + डेप्रिकेशन नीति रखता है जिसका यह रनबुक पालन करता है।