دليل تشغيل دورة الإصدار
سير عمل إصدار كامل من البوابات المحلية مرورًا بإصدار GitHub موقَّع وصولًا إلى إرسال النشر الاختياري إلى npm.
يقود دليل التشغيل هذا إصدار vX.Y.Z لـapothem من
شجرة عمل نظيفة إلى أسطح توزيع مُتحقَّق منها. كُتب الإجراء للمشرف الذي يستخدم
gh وgit وصدفة طبقة الإصدار؛ وينتهي بصفحة
Release مُتحقَّق منها، وCHANGELOG مُعبَّأ، واختبار
دخان لمسار التثبيت يؤكد أن كل سطح يواجه المستخدم يستجيب لأمر التثبيت
المعياري.
شكل الإصدار وسم واحد، مرحلتان. وسم إصدار موقَّع واحد على
main يُشغِّل .github/workflows/release.yml، الذي
يبني ويُوقِّع ويُشهِد ويَنشُر إصدار GitHub بمجموعة الأدوات
الكاملة الخاصة به — sdist وwheel وCycloneDX
SBOM وحُزم Sigstore cosign ومنشأ SLSA-3 وأرشيفات
وقت تشغيل المنصة. المرحلة الثانية الاختيارية هي إرسال يدوي لـpublish-npm.yml،
الذي ينشر @ahmed-g-gad/apothem على npmjs.com بعد أن
يصبح scripts/release/check-release-ready.sh أخضر. يُكتب قسم
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 الفرعي؛ ورابط الناشر الموثوق لـnpm الخاص بـ@ahmed-g-gad/apothemنشط (مُتحقَّق منه وفق دليل تشغيل إعداد حساب الناشر). -
مراسي الإصدار متوائمة. سلسلة الإصدار المُعلَنة في
pyproject.tomlتطابق الوسم المخطط له دون البادئةv. تحقَّق:grep '^version' pyproject.tomlالمخرجات المتوقعة (لإصدار
vX.Y.Z؛ النوائب تُمثِّل وسم الإصدار الجاري):version = "X.Y.Z" -
قسم CHANGELOG مُجهَّز. يحمل
CHANGELOG.mdقسمًا مُرقَّمًا بالإصدار تحت عناوين Keep-a-Changelog. يُحدِّث المشرف التاريخ ونقاط الإصدار في الكوميت نفسه الذي يُهبِط الوسم.
2. الوسم والتشغيل
2.1 تأليف كوميت الإصدار
يُهبِط كوميت الإصدار تغييرَين:
- قسم إصدار
CHANGELOG.mdمُؤرَّخ بتاريخ UTC الفعلي للإصدار. - إصدار
pyproject.tomlمرفوع إلى الإصدار الجديد (فقط عندما يحمل الكوميت السابق علىmainبالفعل تثبيت الإصدار السابق وتلزم زيادة جديدة؛ قد يهبط الكوميت أيضًا أثناء دورة رفع الإصدار قبل وقت الوسم بأيام).
كوميت مثال:
git checkout main
git pull --ff-only origin main
# Author CHANGELOG and pyproject.toml edits via Edit tool, then:
git add CHANGELOG.md pyproject.toml
git commit -S -m "chore(release): cut vX.Y.Z"
git push origin mainتُوقِّع الراية -S الكوميت بمفتاح GPG. يُشغِّل الدفع
مصفوفة CI القياسية (lint وtest
وbuild)؛ انتظر الأخضر قبل الوسم.
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)، وتوليد
SBOM (CycloneDX)، وتوقيع cosign دون مفتاح،
وتوليد منشأ SLSA-3 والتحقق منه، وبناء أرشيفات المنصة
(darwin / linux / windows)، وتوقيع الأرشيفات بملف بيان
SHA256SUMS مُجمَّع، ونشر إصدار GitHub النهائي. يفحص
المشرف سجل مهمة publish GitHub Release بحثًا عن تأكيدات رفع
الأصول.
2.4 إرسال نشر npm (مرحلة اختيارية)
بعد أن يصبح إصدار GitHub وبوابة الجاهزية أخضرَين:
bash scripts/release/check-release-ready.sh vX.Y.Z
gh workflow run publish-npm.yml --field tag=vX.Y.Zاعتمد نشر بيئة npmjs عند المطالبة. يَنشُر سير العمل
@ahmed-g-gad/[email protected] على npmjs.com عبر
npm Trusted Publishing (OIDC)؛ لا يُخزَّن أي رمز سجل
في المستودع.
3. أسطح التوزيع
يملك كل سطح أمر تحقق يجيب على «هل هبط الإصدار هنا؟»:
| # | السطح | الأداة | التحقق |
|---|---|---|---|
| 1 | إصدار GitHub (توزيعات 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 (SBOM) | sbom.cdx.json | كما في الصف 1؛ تتضمن قائمة الأصول CycloneDX SBOM |
| 3 | إصدار GitHub (التوقيعات) | *.cosign.bundle لكل أداة توزيع؛ *.sig لكل أرشيف؛ SHA256SUMS + SHA256SUMS.sig | cosign verify-blob --bundle <artifact>.cosign.bundle <artifact> يخرج بالقيمة 0 (مع رايات هوية سير العمل) |
| 4 | إصدار GitHub (المنشأ) | provenance.intoto.jsonl | bash scripts/release/verify-provenance.sh vX.Y.Z يخرج بالقيمة 0 |
| 5 | إصدار GitHub (أرشيفات المنصة) | apothem-vX.Y.Z-darwin.tar.gz، apothem-vX.Y.Z-linux.tar.gz، apothem-vX.Y.Z-windows.zip | تتضمن قائمة الأصول كل أرشيف بالإضافة إلى SHA256SUMS |
| 6 | 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 X.Y.Z |
| 7 | Pages (مُثبِّتات السكربت) | install.sh / install.ps1 على موقع الوثائق | curl -fsSL https://apothem.ahmedgad.com/install.sh | head -n 1 يُرجِع ترويسة السكربت |
إصدار GitHub هو سطح الأدوات المعياري؛ وحزمة npm ومُثبِّتات السكربت هي مسارات التثبيت المُركَّبة فوقه. نشر npm هو عمدًا المرحلة الأخيرة.
4. انضباط CHANGELOG
يحمل CHANGELOG.md قسمًا واحدًا لكل إصدار وفق اتفاقية
Keep-a-Changelog. تعديل CHANGELOG في كوميت الإصدار:
- يؤكد أن قسم الإصدار يستخدم العنوان
## [X.Y.Z] — YYYY-MM-DD. - يؤكد أن العناوين القياسية — 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 X.Y.Z.
5.3 مُثبِّت سكربت بخطوة واحدة (POSIX)
curl -fsSL https://apothem.ahmedgad.com/install.sh | sh
apothem --versionالمخرجات المتوقعة: apothem X.Y.Z.
5.4 مُثبِّت سكربت بخطوة واحدة (Windows)
irm https://apothem.ahmedgad.com/install.ps1 | iex
apothem --versionالمخرجات المتوقعة: apothem X.Y.Z.
5.5 التحقق من الأدوات (دليل سلسلة التوريد)
gh release download vX.Y.Z --pattern 'apothem-X.Y.Z*' --pattern '*.cosign.bundle'
cosign verify-blob \
--bundle apothem-X.Y.Z-py3-none-any.whl.cosign.bundle \
--certificate-identity-regexp 'github.com/ahmed-g-gad/apothem' \
--certificate-oidc-issuer https://token.actions.githubusercontent.com \
apothem-X.Y.Z-py3-none-any.whl
bash scripts/release/verify-provenance.sh vX.Y.Zالمتوقع: يخرج كلا التحققَين بالقيمة 0.
يُنتج اختبار الدخان صفًا واحدًا PASS / FAIL لكل سطح؛ سجِّل الصفوف في سجل إصدار المشرف.
6. التعافي من الفشل
يملك سير عمل الإصدار أنماط فشل موثَّقة لمحرك الإصدار وناشر npm:
| الفشل | التشخيص | التعافي |
|---|---|---|
| رُفض دفع الوسم (فشل التوقيع) | git push origin vX.Y.Z يُرجِع error: failed to push some refs برسالة متعلقة بـGPG | تحقَّق من تحميل مفتاح GPG الفرعي (gpg --list-secret-keys --keyid-format=long)؛ أعِد الوسم محليًا بـ-s بعد إصلاح حلقة المفاتيح؛ أعِد الدفع |
فشل مهمة 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؛ خطأ سجل 404 أثناء PUT هو عدم تطابق في التفويض / الناشر الموثوق، لا دليل على أن كود الحزمة مفقود | تحقَّق من أن npm Trusted Publishing لـ@ahmed-g-gad/apothem يُسمِّي المالك ahmed-g-gad والمستودع apothem وسير العمل publish-npm.yml والإجراء المسموح npm publish؛ أكِّد أن المهمة تعمل بإصدار Node وأرضية OIDC لـnpm CLI المُثبَّتَين في سير العمل |
| الوسم ظاهر لكن الأصول مفقودة | gh release view vX.Y.Z يُرجِع إصدارًا جذعيًا | أعِد تشغيل مهمة النشر في سير عمل الإصدار؛ إذا بقي الجذع، احذف صفحة الإصدار (gh release delete vX.Y.Z --cleanup-tag) وأعِد الوسم من SHA نفسه |
إذا فشلت دورة تعافٍ في إهباط سطح خلال تمريرة تشخيصية واحدة، يُسجَّل السطح بوصفه فشلًا معروفًا في ملاحظات الإصدار مع رابط للمشكلة المفتوحة؛ ويُوجَّه المستخدمون النهائيون إلى الأسطح العاملة بينما يُصلَح السطح المعطوب في إصدار تصحيحي.
7. المراجع المتقاطعة
- إعداد الناشر. دليل تشغيل إعداد حساب الناشر يُؤسِّس رابط الناشر الموثوق لـnpm والمتطلبات المسبقة على جانب GitHub التي يفترضها دليل التشغيل هذا.
- تدفق التعافي. دليل تشغيل تعافي الإصدار
(
site/content/docs/runbooks/release-recovery.mdx) يحكم مسار الفشل عبر المراحل أثناء انتقال الإصدار، لا حالات فشل الإصدار لكل سطح المُسمَّاة في §6. - تفعيل Pages. يتحقق سير العمل
publish-static-site.ymlمن موقع المشروع ويَنشُره على النطاق المخصص؛ ودليل تشغيل تفعيل Pages (site/content/docs/runbooks/pages-enablement.mdx) هو الإجراء الأعلى الذي أسَّس النطاق المخصص في المقام الأول. - سياسة الإصدارات.
site/content/docs/governance/release-engineering-policy.mdxيحمل سياسة SemVer + التوقيع + الإهمال التي يحترمها دليل التشغيل هذا.