تخطَّ إلى المحتوى

🚀 شرح DevOps و CI/CD

GitLab CI/CD — بديل لـ GitHub Actions

الدرس 28 من 32· ⏱ 4 دقائق قراءة· 🗓 آخر تحديث: ٣١ أغسطس ٢٠٢٦

GitHub Actions ليست الخيار الوحيد

كل الدروس السابقة في هذا المسار بُنيت على GitHub Actions لأنها الأكثر انتشاراً لمشاريع GitHub، لكن لو كان مشروعك مستضافاً على GitLab (سواء GitLab.com أو نسخة ذاتية الاستضافة)، فالأداة المدمجة هي GitLab CI/CD — والمفاهيم الأساسية متقاربة جداً، فمعرفتك بـ CI/CD من الدروس السابقة تنتقل مباشرة.

ملف .gitlab-ci.yml

بدل مجلد .github/workflows/ مع عدة ملفات، GitLab يستخدم ملف YAML واحد في جذر المستودع اسمه .gitlab-ci.yml.

build-job:
  stage: build
  script:
    - npm ci
    - npm run build

test-job:
  stage: test
  script:
    - npm test

deploy-job:
  stage: deploy
  script:
    - echo "نشر الفرع $CI_COMMIT_BRANCH"
  environment: production
  only:
    - main

Stages وJobs: نفس الفكرة، تسمية مختلفة

المفهوم يقابل تماماً jobs في GitHub Actions لكن بترتيب مختلف قليلاً:

  • Stage (مرحلة): مجموعة من الوظائف تُنفَّذ بالتتابع — لا تبدأ مرحلة إلا بعد نجاح كل وظائف المرحلة السابقة
  • Job (وظيفة): وحدة العمل الفعلية، تحتوي script (الأوامر المُنفَّذة). كل الوظائف داخل نفس المرحلة تعمل بالتوازي تلقائياً

في المثال أعلاه: build-job تشتغل أولاً، وبعد نجاحها فقط تشتغل test-job، وبعدها deploy-job. لو أضفنا وظيفة أخرى بنفس stage: test، كانت ستشتغل بالتوازي مع test-job.

متغيرات مدمجة (Predefined Variables)

مثل github.sha وgithub.ref في GitHub Actions، GitLab يوفر متغيرات جاهزة داخل كل pipeline:

المتغيرالمعادل في GitHub Actionsالوصف
$CI_COMMIT_BRANCHgithub.ref_nameاسم الفرع الحالي
$CI_COMMIT_SHAgithub.shaهاش الـ commit
$CI_PROJECT_NAMEgithub.repositoryاسم المشروع
$CI_PIPELINE_IDgithub.run_idمعرّف التشغيلة

Runners: من يُنفّذ الوظائف فعلياً

الـ Runner هو العملية (agent) التي تُنفّذ أوامر script فعلياً — يقابل مفهوم runs-on في GitHub Actions لكنه أكثر مرونة في إدارته. GitLab.com يوفر runners جاهزة مشتركة (shared runners)، أو يمكنك تسجيل runner خاص بك (self-hosted) على خادمك، بأنواع تنفيذ (executor) مختلفة مثل shell أو docker.

test-job:
  stage: test
  tags:
    - docker   # يحدد أي runner (بهذا الـ tag) يُنفّذ الوظيفة
  script:
    - npm test

مثال: Pipeline مع Docker ونشر شرطي

stages:
  - build
  - test
  - deploy

build:
  stage: build
  image: node:20
  script:
    - npm ci
    - npm run build
  artifacts:
    paths:
      - dist/
    expire_in: 1 week

test:
  stage: test
  image: node:20
  script:
    - npm test

deploy:
  stage: deploy
  image: node:20
  script:
    - echo "نشر ناتج البناء"
  rules:
    - if: '$CI_COMMIT_BRANCH == "main"'
  • image يحدد صورة Docker التي تشتغل فيها الوظيفة — لا حاجة لخطوة تسجيل دخول منفصلة كما في GitHub Actions
  • artifacts هنا مفهوم مدمج في نفس بنية الـ job (وليس action منفصل مثل upload-artifact)، ويُمرَّر تلقائياً للمراحل التالية
  • rules تتحكم بشرط تشغيل الوظيفة — أشبه بـ if على مستوى الخطوة في GitHub Actions

⚠️ لا يوجد needs إلزامي بين المراحل لأن الترتيب التسلسلي بين الـ stages مضمون تلقائياً؛ استخدم needs فقط إذا أردت كسر هذا الترتيب الافتراضي وتشغيل وظيفة أبكر (DAG pipelines).

إدارة الأسرار في .gitlab-ci.yml

المعادل المباشر لـ GitHub Actions secrets هو CI/CD Variables — قيم تُضبط من إعدادات المشروع (Settings → CI/CD → Variables)، وتُعلَّم كـ Masked لإخفائها من سجلّات التشغيل، وProtected لحصرها على الفروع/الوسوم المحمية فقط. هذه هي البداية الافتراضية لأي سر بسيط، تماماً كما شرحنا الأسرار على مستوى المستودع في درس أمن خط الأنابيب لـ GitHub Actions.

لأسرار تُدار خارج GitLab نفسه (مثل HashiCorp Vault أو مدير أسرار سحابي)، توفّر الكلمة المفتاحية secrets: على مستوى الوظيفة طريقة لسحب القيمة وقت التشغيل بدل نسخها كـ CI/CD Variable ثابتة:

deploy:
  stage: deploy
  secrets:
    DATABASE_PASSWORD:
      vault: production/db/password@secret   # يُسحب من HashiCorp Vault وقت التشغيل
  script:
    - deploy --password "$DATABASE_PASSWORD"
  • افتراضياً تصل القيمة كملف مؤقت، والمتغيّر نفسه يحمل مسار ذلك الملف لا القيمة مباشرة — تقليل احتمال تسرّبها في سجلّات أو subprocesses تطبع متغيرات البيئة بالكامل
  • لو كان تطبيقك يقرأ القيمة كمتغيّر بيئة عادي فقط (لا كملف)، أضف file: false صراحة

في أغسطس 2026 (إصدار GitLab 19.3)، أصبح GitLab Secrets Manager — مدير الأسرار المدمج في GitLab نفسه بدل مزوّد خارجي — متاحاً عاماً كإضافة مدفوعة على GitLab.com (بعد فترة تجريبية public beta)، بنفس بنية secrets: لكن بمزوّد مختلف:

deploy:
  secrets:
    DATABASE_PASSWORD:
      gitlab_secrets_manager:
        name: db-password   # اسم السر داخل GitLab Secrets Manager
  script:
    - deploy --password "$DATABASE_PASSWORD"

⚠️ gitlab_secrets_manager إضافة مدفوعة بتوفّر محدود لحساب كتابة هذا الدرس — تحقق من خطتك وتوفّرها في منطقتك قبل الاعتماد عليها. أما vault وaws_secrets_manager وazure_key_vault فمتاحة منذ وقت أطول ولا تتطلب إضافة مدفوعة إضافية بحد ذاتها (تحتاج فقط اشتراكك بالخدمة الخارجية نفسها).

متى تفضّل GitLab CI/CD؟

  • مشروعك مستضاف أصلاً على GitLab (أو تحتاج نسخة self-hosted كاملة من منصة DevOps)
  • تريد Container Registry وIssue Tracking وCI/CD في نفس المنصة المتكاملة بدل ربط أدوات متعددة
  • لو مشروعك على GitHub، لا داعي للتبديل — كل ما تعلمته عن GitHub Actions بهذا المسار يبقى الخيار الأنسب

🎯 التالي: أمان GitHub Actions: Pwn Requests و persist-credentials

شرح GitLab CI/CD — بديل لـ GitHub Actions — DevOps و CI/CD بالعربي
GitLab CI/CD — بديل لـ GitHub ActionsDevOps و CI/CD بالعربي · The Code Fix

هل كان هذا الدرس مفيدًا؟