أتمتة الإصدارات
تُنشأ إصدارات Libre WebUI من جذر المستودع باستخدام نص الإصدار البرمجي. يقرأ النص سجل Git الحقيقي منذ وسم الإصدار السابق، ويحدّث إصدارات الحزم، ويكتب سجل التغييرات، ويشغّل فحوصات الإصدار، وينشئ التزام الإصدار ووسمه. GitHub هو مصدر البناء ونشر الملفات الثنائية؛ وتُنسخ بيانات الإصدار وروابط العناصر المسماة إلى مستودع Forgejo الخاص بالمشروع.
الإعداد المحلي لمرة واحدة
ثبّت الاعتماديات وفعّل خطاطيف المستودع:
npm install
npm run setup-hooks
يضبط إعداد الخطاطيف ما يلي:
.githooks/commit-msgللتحقق من تنسيق Conventional Commit.githooks/pre-commitلفحوصات التنسيق.gitmessageقالبًا محليًا لرسائل الالتزام
إنشاء إصدار
شغّل نص الإصدار من شجرة عمل نظيفة على الفرع الذي تنوي وسمه:
# Patch release
npm run release
# Minor release
npm run release:minor
# Major release
npm run release:major
ينفّذ النص تلقائيًا ما يلي:
- يتحقق من نظافة شجرة العمل ومن توفر الوسم المحلي التالي.
- يجمع أدلة الالتزامات والملفات والاعتماديات واللغات وسجل التغييرات غير المنشور.
- يولّد ملاحظات الإصدار من تلك الأدلة.
- يحدّث
package.jsonوملفات حزم مساحة العمل وpackage-lock.jsonوإصداري chart Helm والتطبيق وCHANGELOG.md. - يشغّل
npm run release:checkبما يشمل التنسيق وlint والبناء والاختبارات وتدقيق الأمان ومحاكاة نشر npm. - لا ينشئ التزام الإصدار ووسم الإصدار المشروح إلا بعد نجاح كل فحص.
توليد سجل التغييرات
عاين القسم التالي من سجل التغييرات من دون تعديل الملفات:
npm run changelog
حدّث CHANGELOG.md يدويًا من القسم المولّد:
npm run changelog -- update
يمكن لمولّد السجل افتراضيًا أن يطلب من نموذج محلي متوافق مع Ollama مسودة مصقولة، ثم يتحقق منها مقابل أدلة Git المجمعة. إذا لم يتوفر AI أو بدت النتيجة غير آمنة، يعود النص إلى مولّد حتمي.
تجاوزات مفيدة:
CHANGELOG_AI=0 npm run release:minor
CHANGELOG_AI_MODEL=glm-5.2:cloud npm run changelog
OLLAMA_BASE_URL=http://127.0.0.1:11434 npm run release
دفع إصدار
بعد إنشاء التزام الإصدار والوسم المشروح، انشر فقط التزام الفرع والوسم الدقيقين اللذين يعرضهما النص. يُدفع فرع الإنتاج إلى Forgejo أولًا ثم GitHub، مع تعطيل الوسوم المتبوعة صراحةً:
git -c push.followTags=false push \
https://git.kroonen.ai/libre-webui/libre-webui.git \
HEAD:refs/heads/main
git ls-remote \
https://git.kroonen.ai/libre-webui/libre-webui.git \
refs/heads/main
git -c push.followTags=false push \
https://github.com/libre-webui/libre-webui.git \
HEAD:refs/heads/main
git ls-remote \
https://github.com/libre-webui/libre-webui.git \
refs/heads/main
يجب أن يساوي SHA المعاد لكل فرع التزام الإصدار المحلي المقصود. انتظر نجاح عمليات GitHub المطلوبة لذلك الالتزام بعينه قبل نشر الوسم.
تأكد من عدم وجود وسم الإصدار على أي من الخدمتين، ثم ادفع ذلك الوسم وحده إلى Forgejo أولًا وGitHub ثانيًا:
git ls-remote \
https://git.kroonen.ai/libre-webui/libre-webui.git \
'refs/tags/vX.Y.Z' 'refs/tags/vX.Y.Z^{}'
git ls-remote \
https://github.com/libre-webui/libre-webui.git \
'refs/tags/vX.Y.Z' 'refs/tags/vX.Y.Z^{}'
git -c push.followTags=false push \
https://git.kroonen.ai/libre-webui/libre-webui.git \
refs/tags/vX.Y.Z:refs/tags/vX.Y.Z
git -c push.followTags=false push \
https://github.com/libre-webui/libre-webui.git \
refs/tags/vX.Y.Z:refs/tags/vX.Y.Z
git ls-remote \
https://git.kroonen.ai/libre-webui/libre-webui.git \
'refs/tags/vX.Y.Z' 'refs/tags/vX.Y.Z^{}'
git ls-remote \
https://github.com/libre-webui/libre-webui.git \
'refs/tags/vX.Y.Z' 'refs/tags/vX.Y.Z^{}'
استبدل vX.Y.Z بوسم الإصدار. في الوسم المشروح، تحقق من SHA لكائن الوسم
ومن SHA للالتزام الذي يشير إليه. لا تستخدم git push --tags أبدًا، فقد
ينشر وسومًا محلية غير ذات صلة.
مسار الإصدار في CI
يؤدي دفع وسم v* إلى تشغيل سير عمل إصدار GitHub. ويقوم هذا السير بما يلي:
- تشغيل
npm run release:check - بناء عناصر Electron لـ macOS وWindows وLinux
- إنشاء إصدار GitHub من القسم المطابق في
CHANGELOG.md - نسخ سجل الإصدار وروابط العناصر المسماة إلى Forgejo
- بناء صور Docker
- نشر chart Helm بالإصدار نفسه الموجود في وسم الإصدار
- نشر حزمة npm باستخدام
NPM_TOKEN
يمكن تشغيل الفحص نفسه محليًا قبل وضع الوسم:
npm run release:check
مرآة إصدارات Forgejo
تستخدم المرآة رمز وصول شخصيًا لـ Forgejo محفوظًا في سر GitHub Actions المشفّر
FORGEJO_TOKEN. امنح الرمز نطاق write:repository فقط، وتأكد من أن مالكه
يمكنه الكتابة إلى libre-webui/libre-webui، ولا تلتزم الرمز أو تطبعه مطلقًا.
صُممت المرآة لتكون idempotent. تبحث عن الإصدارات بالوسم، ولا تنشئ إلا سجلات الإصدار المفقودة، وتطابق بياناتها مع إصدار GitHub، وتتجاوز روابط العناصر الموجودة. لذلك تُكمل إعادة المحاولة بعد تعطل الشبكة أو سير العمل ما تبقى من دون تكرار الإصدارات أو العناصر.
عناصر إصدارات Forgejo هي روابط خارجية مسماة إلى browser_download_url
العام المقابل في GitHub. يظل GitHub مضيف الملفات الثنائية، بينما يعرض Forgejo
أسماء الملفات القابلة للتنزيل نفسها من دون تكرار عشرات الجيجابايت من عناصر
تطبيقات سطح المكتب. وتُنشأ أرشيفات المصدر بصورة مستقلة من الوسم الدقيق في كل خدمة.
معاينة إصدار واحد أو استكماله
افحص ما سيتغير من دون الكتابة إلى Forgejo:
node scripts/mirror-forgejo-releases.mjs --tag vX.Y.Z --dry-run
بعد تحميل FORGEJO_TOKEN وGITHUB_TOKEN في بيئة العملية من مدير أسرار
المشرف، انسخ ذلك الإصدار:
node scripts/mirror-forgejo-releases.mjs --tag vX.Y.Z
يجب أن يكون الوسم الدقيق موجودًا على GitHub وForgejo وأن يُحل إلى كائن الوسم والالتزام المشار إليه نفسيهما قبل نسخ الإصدار.
معاينة كل الإصدارات أو استكمالها
دقّق كل إصدار GitHub مقابل Forgejo:
node scripts/mirror-forgejo-releases.mjs --all --dry-run
استكمل كل إصدار Forgejo مفقود أو ناقص:
node scripts/mirror-forgejo-releases.mjs --all
يلزم GITHUB_TOKEN مع --all، بما في ذلك عمليات المحاكاة، لأن التحقق من
تطابق الوسوم واكتشاف العناصر يتطلبان طلبات أكثر مما يسمح به حد API المجهول
في GitHub. ويلزم FORGEJO_TOKEN أيضًا كلما لم يُستخدم --dry-run.
يصفّح مسار --all كلتا واجهتي API ويعالج كائنات GitHub Release، لا كل
وسوم Git. يبقى الوسم الذي لا يملك إصدار GitHub عمدًا مجرد وسم على Forgejo.
شغّل المحاكاة مجددًا بعد الاستكمال؛ وينبغي ألا تبلغ عن تغييرات معلقة.
سياسة ثبات الوسوم
وسوم الإصدارات المنشورة ثابتة. بعد وجود وسم على أي خادم بعيد:
- لا تحذفه.
- لا تدفعه بالقوة.
- لا تنقله إلى التزام مصحح.
- لا تعِد استخدام إصداره الدلالي لمحتوى مختلف.
إذا كان محتوى الإصدار المنشور خاطئًا، فصحح المصدر وسجل التغييرات وانشر الإصدار التصحيحي التالي. وإذا كانت صفحة الإصدار أو رابط عنصر خارجي فقط مفقودًا، فأعد تشغيل المرآة idempotent من دون لمس الوسم.
خضع وسم Forgejo v0.8.6 لإعادة محاذاة استثنائية ومعتمدة صراحةً عند
إدخال النسخ المزدوج للإصدارات. أصلحت العملية كائني وسم تاريخيين يصفان
شجرتي مصدر متطابقتين لكنهما يتبعان سلسلتي التزامات مختلفتين. لا تشكّل تلك
الهجرة المدققة سابقةً لنقل الوسوم المنشورة.
سياسة إصدارات Helm
تستخدم version الخاصة بـ chart Helm وappVersion وإصدار الحزمة الجذرية
ووسم الإصدار عمدًا الإصدار الدلالي نفسه. يرفعها نص الإصدار معًا، وترفض CI
أي عدم تطابق.
لا يُنشر chart إلا من وسم إصدار v* ثابت. لا تنشر محتوى chart معدلًا
بإصدار chart موجود. يجب أن يمر أي تغيير في chart عبر إصدار التطبيق التالي
كي يحصل على إصدار جديد.
يحمل chart الإصدار 0.14.1 تجاوز digest لمرة واحدة، لأن ذلك الإصدار يسبق
وسوم Docker الدلالية. يحدد digest صورة 0.14.1 متعددة البنى التي تم التحقق منها.
يمحو نص الإصدار هذا التجاوز عند إنشاء الإصدار التالي، وبعدها تُحل الصورة
الافتراضية إلى appVersion الخاصة بـ chart.
ينشر سير عمل Docker وسم الإصدار الدلالي هذا إلى GHCR وDocker Hub من وسم
الإصدار v* نفسه. ينتظر نشر Helm حتى 20 دقيقة ظهور صورة Docker Hub العامة
المطابقة، ويفشل بدل نشر chart بصورته الافتراضية المفقودة. تظل صورة Ollama
المضمّنة قابلة للضبط بصورة مستقلة، وتستخدم وسم upstream latest افتراضيًا.
Conventional Commits
ينبغي أن تستخدم رسائل الالتزام تنسيق Conventional Commit:
<type>[optional scope]: <description>
الأنواع الشائعة:
feat: ميزة يراها المستخدمfix: إصلاح خطأdocs: تحديث المستنداتrefactor: إعادة هيكلة داخلية للشيفرةperf: تحسين الأداءtest: تغطية الاختباراتchore: صيانة أو إصدار أو عمل بناء
تستخدم التغييرات الكاسرة !:
git commit -m "feat!: remove deprecated endpoint"
git commit -m "fix(auth)!: change token validation"
استكشاف الأخطاء وإصلاحها
دليل العمل غير نظيف
التزم التغييرات المحلية أو خزّنها مؤقتًا قبل الإصدار:
git status --short
git add .
git commit -m "fix: resolve pending changes"
لا توجد تغييرات قابلة للإصدار
تحقق من الالتزامات منذ الوسم السابق:
git log $(git describe --tags --abbrev=0)..HEAD --oneline
يحتاج سجل التغييرات إلى تحرير يدوي
حرر CHANGELOG.md، ثم التزم التصحيح قبل نشر الوسم:
git add CHANGELOG.md
git commit -m "docs: refine changelog"
التراجع عن التزام إصدار محلي
إذا لم يُدفع التزام الإصدار ولا وسمه:
git tag -d v0.12.0
git reset --soft HEAD~1
إذا كان الوسم موجودًا على أي خادم بعيد، فلا تحذفه ولا تستبدله. أصلح
المشكلة على main، وأنشئ الإصدار التصحيحي التالي، وانشر ذلك الوسم الثابت
الجديد عبر البوابة الكاملة.
مرآة Forgejo ناقصة
تحقق أولًا من تطابق SHA لكائن الوسم والالتزام المشار إليه على الخادمين. ثم عاين الإصدار المتأثر وأعد المحاولة:
node scripts/mirror-forgejo-releases.mjs --tag vX.Y.Z --dry-run
node scripts/mirror-forgejo-releases.mjs --tag vX.Y.Z
يعني فشل التفويض أن FORGEJO_TOKEN مفقود أو منتهي الصلاحية أو يملكه مستخدم
لا يصل إلى المستودع أو يفتقر إلى write:repository. يجب التحقيق بصورة منفصلة
في الوسم البعيد المفقود أو المختلف؛ فلا تنشئ مرآة الإصدارات وسوم Git ولا تنقلها.
ملفات المشرف
.gitmessage- قالب رسالة الالتزام.githooks/commit-msg- التحقق من Conventional Commit.githooks/pre-commit- فحص التنسيق الأوليscripts/release.js- تنسيق الإصدارscripts/mirror-forgejo-releases.mjs- مرآة إصدارات Forgejo idempotent واستكمال الإصدارات السابقةscripts/generate-changelog.js- أمر معاينة سجل التغييرات وتحديثهscripts/lib/releaseNotes.js- جمع الأدلة وتوليد سجل التغييرات.github/workflows/release.yml- سير إصدار CI مدفوع بالوسم.github/workflows/helm-publish.yml- التحقق من Helm ونشر الوسم
لمزيد من المعلومات عن Conventional Commits، زر https://www.conventionalcommits.org/.