أحمد حايس
الرئيسيةمن أناالدوراتالمدونةالعروض
أحمد حايس

دورات عربية متخصصة في التقنية والبرمجة والذكاء الاصطناعي.

المنصة مبنية على الوضوح، التطبيق، والنتيجة النافعة: شرح مرتب يساعدك تفهم الأدوات، تكتب كودًا أفضل، وتستخدم الذكاء الاصطناعي بوعي داخل العمل الحقيقي.

تعلم أسرعوصول مباشر للدورات والمسارات من الموبايل.
تنقل أوضحالروابط الأساسية والدعم في مكان واحد بدون تشتيت.

المنصة

  • الرئيسية
  • من أنا
  • الدورات
  • العروض
  • المدونة

الدعم

  • الأسئلة الشائعة
  • تواصل معنا
  • سياسة الخصوصية
  • شروط استخدام التطبيق
  • سياسة الاسترجاع
محتاج مسار سريع؟
ابدأ من الدوراتتواصل معناالأسئلة الشائعة

© 2026 أحمد حايس. جميع الحقوق محفوظة.

الرئيسيةالدوراتالعروضالمدونةالدخول

أتمتة توليد Changelog و GitHub Releases بـ release-please — وداعًا للتحرير اليدوي

📅 ٢٠ أبريل ٢٠٢٦⏱ 6 دقائق قراءة
أتمتة توليد Changelog و GitHub Releases بـ release-please — وداعًا للتحرير اليدوي

أتمتة توليد Changelog و GitHub Releases بـ release-please

لو بتقعد كل أسبوع 20 دقيقة تفتح CHANGELOG.md وتلصق فيه "أضفنا كذا، صلّحنا كذا" يدويًا، وبعدين تفتح تاب GitHub Releases وتلصق نفس الكلام تاني، وتزوّد رقم الـ version في package.json بإيدك — ده شغل روبوت بتعمله إنت. release-please من Google بيعمل الثلاثة دول من commits الموجودة عندك أصلاً، بدون ما تتعلم أداة جديدة. الناتج: Release PR واحد بيقعد مفتوح على main، لمّا تعمله merge، بيتولّد CHANGELOG محدّث، tag جديد، و GitHub Release رسمي — كله في 15 ثانية.

واجهة GitHub تعرض Release PR مفتوح مع CHANGELOG مُولّد تلقائيًا من commits

المشكلة باختصار

الـ CHANGELOG اليدوي بيفشل لأربع أسباب. الأول: الناس بتنساه. الثاني: بيتكتب يوم الـ release بس، فبيعتمد على ذاكرة اللي بيكتب. الثالث: الـ version في package.json والـ tag في git والـ release على GitHub — ثلاثتهم لازم يطابقوا، وده بيحصل مرة من كل عشرة. الرابع: في monorepo فيه 5 packages، الشغل ده بيتضرب في 5. الحل المنطقي إن الـ source of truth يكون الـ commits نفسها، طالما إنت بتكتبها بصيغة منظّمة.

مثال بسيط الأول: ليه Conventional Commits أصلاً

تخيّل إنك قاعد في مطعم، والجرسون بدل ما يقولّك "عندنا أكل"، بيقولّك: "الطبق الجديد: مكرونة بالبشاميل. التعديل على الطبق القديم: الكبسة بقت بتوابل أقل. مشكلة اتحلّت: الحمّص مبقاش فيه ملح زيادة." ده بالظبط اللي Conventional Commits بتعمله للـ git: بتخلّي كل commit يقول لنفسه هو feature جديد، تصليح bug، ولا مجرد تنسيق.

كل commit بيبدأ بـ نوع محدد:

  • feat: ميزة جديدة → بيزوّد الـ minor version (1.2.0 → 1.3.0)
  • fix: تصليح bug → بيزوّد الـ patch version (1.2.0 → 1.2.1)
  • feat!: أو BREAKING CHANGE: → بيزوّد الـ major version (1.2.0 → 2.0.0)
  • chore:, docs:, refactor:, test: → مش بتظهر في الـ changelog غالبًا

التعريف العلمي الدقيق

Conventional Commits هي مواصفة (specification) لصياغة رسائل الـ commits بصيغة قابلة للقراءة آليًا، مبنية فوق Semantic Versioning (SemVer). كل رسالة بتتكوّن من type + scope اختياري + description. الأدوات اللي بتلتزم بالمواصفة دي تقدر تستنتج رقم الإصدار التالي بدون تدخّل بشري. release-please بيطبّق نفس المنطق ده: بيفحص كل الـ commits من آخر tag، يحدّد أكبر نوع فيهم (major > minor > patch)، ويحسب الـ version الجديد.

إزاي release-please بيشتغل فعلاً

الـ flow بسيط لدرجة مدهشة:

  1. إنت بتدفع commits عادي على main بصيغة Conventional Commits.
  2. release-please بيشتغل كـ GitHub Action على كل push.
  3. بيلاقي الـ commits اللي بعد آخر release، يحسب الـ version الجديد، ويفتح (أو يحدّث) Release PR فيه: CHANGELOG جديد + package.json معدّل + .release-please-manifest.json متغيّر.
  4. إنت بتعمل review للـ PR ده عادي. لو جاهز، بتضغط merge.
  5. عند الـ merge، release-please بيتحرّك تاني: بيعمل git tag، ينشر GitHub Release بنفس محتوى الـ CHANGELOG، وبيقفل الـ PR.

نقطة مهمة: الـ Release PR دايمًا موجود. طول ما في commits مفيهاش release، هو مفتوح. ده الـ trade-off الرئيسي: في كل مشروع هتلاقي PR اسمه "chore: release 1.x.x" دايمًا في القائمة. ناس بتحبه، ناس بتكرهه.

الإعداد الكامل — ملف واحد workflow + ملفّين config

افتح repo فيه package.json وحط الملفات دي.

1) .github/workflows/release-please.yml

YAML
name: release-please

on:
  push:
    branches: [main]

permissions:
  contents: write
  pull-requests: write

jobs:
  release-please:
    runs-on: ubuntu-latest
    steps:
      - uses: googleapis/release-please-action@v4
        with:
          token: ${{ secrets.GITHUB_TOKEN }}
          config-file: release-please-config.json
          manifest-file: .release-please-manifest.json

2) release-please-config.json — بيحدد نوع الـ release وإعدادات الـ changelog:

JSON
{
  "packages": {
    ".": {
      "release-type": "node",
      "package-name": "my-app",
      "changelog-sections": [
        { "type": "feat", "section": "المزايا الجديدة" },
        { "type": "fix", "section": "تصليحات" },
        { "type": "perf", "section": "تحسينات أداء" },
        { "type": "refactor", "section": "إعادة هيكلة", "hidden": true },
        { "type": "chore", "section": "صيانة", "hidden": true }
      ],
      "include-v-in-tag": true,
      "bump-minor-pre-major": true
    }
  }
}

3) .release-please-manifest.json — الـ source of truth للـ version الحالي:

JSON
{
  ".": "0.1.0"
}

ادفع الثلاثة على main. بعد أول push، استنى 30 ثانية. هتلاقي PR جديد اسمه "chore(main): release 0.2.0" فيه الـ CHANGELOG. افتحه واعمله merge. خلاص — أول Release رسمي اتعمل.

مثال Commits حقيقية وناتجها

شاشة محرر كود تعرض سجل commits منظّم بصيغة Conventional Commits بألوان feat و fix

لو عملت الـ commits دي على main خلال أسبوع:

feat(auth): add OAuth login with Google
fix(api): handle 429 rate limit errors gracefully
feat(ui): dark mode toggle in settings
fix(db): prevent connection pool leak on timeout
docs: update README installation steps
chore: bump eslint to 9.2

release-please هيفتحلك PR ناتجه:

  • version: من 0.1.0 لـ 0.2.0 (لأن فيه feat → minor bump)
  • CHANGELOG.md: قسم "المزايا الجديدة" فيه بندين، قسم "تصليحات" فيه بندين. الـ docs و chore مش هيظهروا.
  • GitHub Release v0.2.0: بنفس المحتوى، بيتعمل أوتوماتيكيًا لما تـ merge.

Monorepo — لو عندك أكتر من package

release-please v13 بيدعم monorepos بشكل first-class. لو عندك packages/api و packages/web و packages/shared، الـ config بيبقى:

JSON
{
  "packages": {
    "packages/api": { "release-type": "node", "package-name": "@myorg/api" },
    "packages/web": { "release-type": "node", "package-name": "@myorg/web" },
    "packages/shared": { "release-type": "node", "package-name": "@myorg/shared" }
  },
  "plugins": [
    { "type": "node-workspace" },
    { "type": "linked-versions", "group-name": "main", "components": ["@myorg/api", "@myorg/web"] }
  ],
  "separate-pull-requests": false
}

الـ plugin node-workspace بيحدّث الـ internal dependencies بين الـ packages تلقائيًا. لو api بتستخدم shared ونزل Release جديد لـ shared، الـ api/package.json هيتحدّث أوتوماتيك.

الأرقام اللي تهمّك

  • الوقت اليدوي قبل: ~20 دقيقة/release × 4 releases شهريًا = 80 دقيقة شهريًا.
  • الوقت مع release-please: ~2 دقيقة review لكل PR × 4 = 8 دقائق.
  • التوفير الشهري: 72 دقيقة (90%).
  • أخطاء version mismatch: من ~2 شهريًا لـ 0 (بحكم إن الـ bump deterministic).
  • تكلفة GitHub Actions: صفر للمشاريع العامة؛ للخاصة ~3 دقائق/شهر × $0.008 = أقل من 3 سنت/شهر.

Trade-offs حقيقية لازم تعرفها

هتكسب: CHANGELOG دقيق، version صحيح دايمًا، GitHub Release تلقائي، source of truth واحد هو الـ commits، دعم monorepos قوي.

هتخسر:

  • انضباط في صياغة الـ commits. لو فريقك بيكتب "update stuff" في كل commit، release-please مش هيفيدك.
  • الـ Release PR هيقعد مفتوح دايمًا، ناس بتشوفه ضوضاء.
  • الـ CHANGELOG بالإنجليزي افتراضيًا. تعريبه محتاج changelog-sections كـ ما فوق، مش اللغة كلها.
  • مش بيشوف الـ commits اللي قبل ما تفعّله. أول run بيبدأ من نقطة الصفر.

متى لا تستخدم release-please

تجنّبه لو: (1) المشروع شخصي ومش بتعمل releases أصلاً، (2) فريقك مش ملتزم بـ Conventional Commits ومش هتقدر تفرضها (استخدم commitlint مع pre-commit hook لو عاوز تفرضها)، (3) الـ release لديك محتاج خطوات يدوية حرجة زي migrations أو approvals من Compliance — release-please ممكن يقفّزك عليها. في الحالة دي استخدم publish_now: false أو semantic-release اللي بيدي تحكّم أكتر في مراحل النشر.

الخطوة التالية

اختار أصغر repo عندك دلوقتي، وحط الـ 3 ملفات اللي فوق عليه. ادفعهم على branch منفصل، افتح PR، و شوف release-please بيتصرّف إزاي. لو في commits موجودة مش بصيغة Conventional Commits، حوّل الفريق للصيغة دي في الـ commits الجديدة فقط — مش لازم تعدّل التاريخ. بعد أول release ناجح، طبّقه على بقية المشاريع.

المصادر

  • googleapis/release-please — المستودع الرسمي
  • release-please-action على GitHub Marketplace
  • توثيق manifest releaser ودعم monorepos
  • مواصفة Conventional Commits الرسمية
  • Semantic Versioning Specification

هل استفدت من المقال؟

اطّلع على المزيد من المقالات والدروس المجانية من نفس المسار المعرفي.

تصفّح المدونة