ابدأ في CI/CD Pipeline: خطوتك الأولى الملموسة اليوم

CI CD Pipeline : الأساسيات في مقال واحد — كود حقيقي، مخططات وخطوات ملموسة، مقتطفات من دورة مكونة من 20 درسًا.

ابدأ في CI/CD Pipeline: خطوتك الأولى الملموسة اليوم

أفضل طريقة لتعلم CI CD Pipeline هي بالممارسة. يساعدك هذا المقال على البدء مع مقتطفات عملية مستمدة من دورة تتكون من 20 درسًا — ما يكفي للحصول على نتيجة أولى اليوم.

tl;dr
  • مقدمة في CICD
  • التكامل المستمر
  • جودة الكود
  • تحسين خط الأنابيب
  • النشر المستمر
~$ cat ./parcours.md # CI CD Pipeline — 6 فصول
01
مقدمة في CICD
→ فصل 00.1 — فلسفة CI/CD : لماذا الأتمتة ؟→ فصل 00.2 — نظام أدوات CI/CD البيئي+ 1 دروس أخرى
02
التكامل المستمر
→ فصل 01.1 — استراتيجيات فروع Git→ فصل 01.2 — البناء الآلي وخطوط أنابيب YAML المتقدمة+ 1 دروس أخرى
03
جودة الكود
→ فصل 02.1 — التحليل الثابت باستخدام SonarQube→ فصل 02.2 — الأمان في CI/CD : SAST، DAST والتبعيات+ 1 دروس أخرى
04
تحسين الـ Pipeline
→ فصل 03.1 — تحسين الـ Pipeline : التخزين المؤقت، التوازي والمصفوفات→ فصل 03.2 — تحسين بناء Docker+ 1 دروس أخرى
05
النشر المستمر
→ فصل 04.1 — استراتيجيات النشر المتقدمة→ فصل 04.2 — البيئات، الأسرار والتراجع+ 1 دروس أخرى
06
المراقبة والملاحظة
→ فصل 05.1 — المراقبة والملاحظة بعد النشر→ فصل 05.2 — SLO، SLA ومقاييس DORA
🏁
المشروع النهائي
→ ستغادر بمشروع ملموس وقابل للعرض

تغطية الكود وعتبات الجودة

الفصل 02 • الدرس 03 • المدة: 45 دقيقة

NOTE🎯 الأهداف
  • فهم ما هي تغطية الكود وحدودها
  • قياس التغطية باستخدام الأدوات القياسية (pytest-cov, jest, JaCoCo)
  • تحديد عتبات ذكية (line, branch, mutation)
  • حظر طلب سحب إذا انخفضت التغطية
  • عرض التقارير في Codecov أو SonarQube

1. ما هي تغطية الكود؟

تقيس تغطية الكود النسبة المئوية للأسطر (أو الفروع، الشروط، الدوال) المنفذة بواسطة الاختبارات الآلية.

النوعالقياسمثال
Line Coverageنسبة الأسطر المنفذة80 % = 80 سطرًا من أصل 100 تم لمسها
Branch Coverageنسبة الفروع الشرطية المختبرةif/else, switch — يجب أن يمر المساران
Function Coverageنسبة الدوال المستدعاةهل تم اختبار جميع الدوال المصدرة؟
Statement Coverageنسبة التعليمات المنفذةقريب من line coverage
Mutation Coverageنسبة الطفرات المكتشفة بالاختباراتأكثر موثوقية لكنه مكلف (mutation testing)
WARNING⚠️ الفخ الكلاسيكي

100 % تغطية لا تعني 100 % جودة. يمكن الحصول على 100 % أسطر منفذة دون التحقق من النتائج. assert مهم بقدر تنفيذ الكود.

2. التغطية في بايثون باستخدام pytest-cov

output
pip install pytest pytest-cov

# تشغيل الاختبارات مع التغطية
pytest --cov=mon_module --cov-report=term --cov-report=html

# مخرجات الطرفية:
# Name            Stmts   Miss  Cover
# -------------------------------------
# mon_module.py     50      5    90%
# -------------------------------------
# TOTAL             50      5    90%

# تقرير HTML تفاعلي في htmlcov/index.html

التهيئة عبر pyproject.toml

output
[tool.pytest.ini_options]
addopts = "--cov=src --cov-report=term-missing --cov-report=xml --cov-fail-under=80"

[tool.coverage.run]
source = ["src"]
omit = [
    "*/tests/*",
    "*/migrations/*",
    "*/__init__.py"
]

[tool.coverage.report]
exclude_lines = [
    "pragma: no cover",
    "raise NotImplementedError",
    "if __name__ == .__main__.:",
]
fail_under = 80
show_missing = true

3. التغطية في جافا سكريبت باستخدام Jest

output
npm install --save-dev jest

# package.json
{
  "scripts": {
    "test": "jest",
    "test:coverage": "jest --coverage"
  },
  "jest": {
    "collectCoverageFrom": [
      "src/**/*.{js,ts}",
      "!src/**/*.d.ts",
      "!src/index.ts"
    ],
    "coverageThreshold": {
      "global": {
        "branches": 75,
        "functions": 80,
        "lines": 80,
        "statements": 80
      }
    },
    "coverageReporters": ["text", "lcov", "html", "cobertura"]
  }
}

# تشغيل
npm run test:coverage

# إذا لم يتم الوصول إلى العتبة:
# Jest: "global" coverage threshold for lines (80%) not met: 73.5%
# → فشل البناء

4. التغطية في جافا باستخدام JaCoCo

output
<!-- pom.xml -->
<plugin>
  <groupId>org.jacoco</groupId>
  <artifactId>jacoco-maven-plugin</artifactId>
  <version>0.8.11</version>
  <executions>
    <execution>
      <goals><goal>prepare-agent</goal></goals>
    </execution>
    <execution>
      <id>report</id>
      <phase>test</phase>
      <goals><goal>report</goal></goals>
    </execution>
    <execution>
      <id>jacoco-check</id>
      <goals><goal>check</goal></goals>
      <configuration>
        <rules>
          <rule>
            <element>BUNDLE</element>
            <limits>
              <limit>
                <counter>LINE</counter>
                <value>COVEREDRATIO</value>
                <minimum>0.80</minimum>
              </limit>
            </limits>
          </rule>
        </rules>
      </configuration>
    </execution>
  </executions>
</plugin>

mvn clean test
# التقرير في target/site/jacoco/index.html

5. تحديد عتبات ذكية

نوع المشروعالعتبة الموصى بها
Critical (banking, healthcare, aerospace)90-95 %
SaaS / Web app production80-85 %
Backend API75-85 %
Frontend (UI logic)60-70 %
Prototype / MVP40-60 %
Script utilitaire0-30 % (غالبًا غير ضروري)
TIP💡 استراتيجية واقعية

بدلًا من عتبة مطلقة، اطلب ألا تنخفض التغطية مقارنة بالفرع main. يقوم Codecov و SonarQube بذلك بشكل أصلي.

6. دمج GitHub Actions

output
name: CI with Coverage

on: [push, pull_request]

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      
      - name: Setup Python
        uses: actions/setup-python@v5
        with:
          python-version: '3.12'
      
      - name: Install
        run: pip install -e ".[dev]"
      
      - name: Tests + coverage
        run: pytest --cov --cov-report=xml --cov-report=term --cov-fail-under=80
      
      - name: Upload coverage to Codecov
        uses: codecov/codecov-action@v4
        with:
          file: ./coverage.xml
          token: ${{ secrets.CODECOV_TOKEN }}
          fail_ci_if_error: true

7. Codecov: العرض والمقارنة

codecov.yml للتخصيص

output
coverage:
  status:
    project:
      default:
        target: 80%
        threshold: 1%
    patch:
      default:
        target: 90%
        threshold: 5%

comment:
  layout: "header, diff, flags, files"
  behavior: default
  require_changes: false

ignore:
  - "tests/**"
  - "**/__init__.py"
  - "migrations/**"

إدارة الـ artifacts والـ registries

الفصل 03 • الدرس 03 • المدة: 45 دقيقة

NOTE🎯 الأهداف
  • فهم ما هو الـ artifact والـ registry
  • تخزين ومشاركة الـ artifacts (zip, jar, wheel) في GitHub Actions
  • رفع صور Docker إلى Docker Hub, GHCR, AWS ECR
  • إدارة الإصدارات الدلالية للـ artifacts
  • وضع قواعد الاحتفاظ لتجنب انفجار التكاليف

1. ما هو الـ artifact؟

الـ artifact هو أي ملف ينتجه البناء ويُقصد استخدامه لاحقًا:

نوع الـ artifactمثالالـ Registry النموذجي
Image containerdevforge-api:1.2.3 (Docker)Docker Hub, GHCR, ECR, Quay
Package Pythonmy-lib-1.0.0.whlPyPI, AWS CodeArtifact, GitHub Packages
Package npmmy-lib-1.0.0.tgznpm registry, GitHub Packages
JAR Javamy-app-1.0.jarMaven Central, Nexus, JFrog Artifactory
Binaire compilémy-cli-linux-amd64GitHub Releases, S3
Helm chartmy-chart-1.0.0.tgzChartMuseum, OCI registries
Fichier ZIP génériquebuild-output.zipGitHub Actions Artifacts, S3

2. Artifacts GitHub Actions (داخل سير العمل)

رفع artifact

output
- name: Build wheel
  run: python -m build

- name: Upload wheel as artifact
  uses: actions/upload-artifact@v4
  with:
    name: python-wheel
    path: dist/*.whl
    retention-days: 30

التنزيل في مهمة لاحقة

output
deploy:
  needs: build
  runs-on: ubuntu-latest
  steps:
    - name: Download wheel
      uses: actions/download-artifact@v4
      with:
        name: python-wheel
        path: ./dist
    
    - name: Install
      run: pip install dist/*.whl
TIP

artifacts GitHub مجانية حتى 500 ميجابايت لكل مستودع عام، وتنتهي صلاحيتها افتراضيًا بعد 90 يومًا.

3. مقارنة Container registries

Registryالتكلفةالمزاياالعيوب
Docker Hubمجاني (عام) / 5 $/user (خاص)الأكثر شعبية، نظام بيئي واسعحدود معدل على السحب
GHCR (GitHub)مجاني (عام) / مشمول مع GitHubتكامل أصلي مع GitHubأقل شهرة
AWS ECR0.10 $/Go/شهرأمان IAM، فحص تلقائي، متكامل مع ECS/EKSخاص بالمنطقة
GCR / Artifact Registry0.10 $/Go/شهرمتكامل مع GCP، متعدد الصيغالتقيد بـ GCP
Azure ACRBasic 5 $/شهرمتكامل مع Azureالتقيد بـ Azure
Quay.ioمجاني (عام) / مدفوع (خاص)كاشف ثغرات قويدعم أقل
Harbor (self-hosted)مجاني (لكن عمليات)بدون اعتماد خارجي، تحكم كامليحتاج صيانة ذاتية

4. الرفع إلى Docker Hub من GitHub Actions

output
- name: Login Docker Hub
  uses: docker/login-action@v3
  with:
    username: ${{ secrets.DOCKERHUB_USERNAME }}
    password: ${{ secrets.DOCKERHUB_TOKEN }}

- name: Build and push
  uses: docker/build-push-action@v5
  with:
    context: .
    push: true
    tags: |
      myuser/myapp:latest
      myuser/myapp:${{ github.sha }}
      myuser/myapp:${{ github.ref_name }}
    platforms: linux/amd64,linux/arm64
    cache-from: type=gha
    cache-to: type=gha,mode=max

5. الرفع إلى GHCR (GitHub Container Registry)

output
- name: Login to GHCR
  uses: docker/login-action@v3
  with:
    registry: ghcr.io
    username: ${{ github.actor }}
    password: ${{ secrets.GITHUB_TOKEN }}

- name: Build and push
  uses: docker/build-push-action@v5
  with:
    push: true
    tags: |
      ghcr.io/${{ github.repository }}:latest
      ghcr.io/${{ github.repository }}:${{ github.sha }}
TIP

لا يحتاج GHCR أي سر إضافي: يكفي GITHUB_TOKEN المولد تلقائيًا.

6. الرفع إلى AWS ECR

output
- name: Configure AWS credentials
  uses: aws-actions/configure-aws-credentials@v4
  with:
    role-to-assume: arn:aws:iam::123456789012:role/github-actions-ecr
    aws-region: eu-west-3

- name: Login to ECR
  id: ecr
  uses: aws-actions/amazon-ecr-login@v2

- name: Build and push
  uses: docker/build-push-action@v5
  with:
    push: true
    tags: |
      ${{ steps.ecr.outputs.registry }}/myapp:latest
      ${{ steps.ecr.outputs.registry }}/myapp:${{ github.sha }}

7. الإصدار الدلالي للصور

اتفاقية SemVer: MAJOR.MINOR.PATCH

الوسممتى يُستخدم
1.2.3الإصدار الدقيق غير القابل للتغيير (إنتاج صارم)
1.2آخر تصحيح للإصدار الثانوي 1.2
1آخر إصدار ثانوي للإصدار الرئيسي 1
latestالأحدث (تجنبه في الإنتاج!)
sha-abc1234وسم مبني على commit Git
main / developالأحدث في الفرع
pr-42خاص بطلب سحب
v1.2.3-rc.1مرشح إصدار

باستخدام docker/metadata-action

output
- name: Generate tags
  id: meta
  uses: docker/metadata-action@v5
  with:
    images: myuser/myapp
    tags: |
      type=ref,event=branch
      type=ref,event=pr
      type=semver,pattern={{version}}
      type=semver,pattern={{major}}.{{minor}}
      type=semver,pattern={{major}}
      type=sha,prefix=sha-,format=short
      type=raw,value=latest,enable={{is_default_branch}}

# مخرجات تلقائية حسب السياق:
# - على main: latest, sha-abc1234, main
# - على الوسم v1.2.3: 1.2.3, 1.2, 1, sha-abc1234
# - على PR #42: pr-42, sha-abc1234

الفصل 00.1 — فلسفة CI/CD: لماذا الأتمتة؟

NOTEهدف هذا الدرس — فهم مشكلات تطوير البرمجيات التقليدي، اكتشاف لماذا أصبحت أتمتة CI/CD ضرورية، وتعلم المبادئ الأساسية التي توجه خط أنابيب حديث.

1. العالم قبل CI/CD — «Integration Hell»

قبل تبني ممارسات CI/CD، كانت فرق التطوير تعمل في صوامع لأسابيع أو أشهر على فروع منفصلة. وعند محاولة دمج الكود، كانت النتيجة غالبًا كارثية. كان يُطلق على هذه الظاهرة اسم Integration Hell (جحيم التكامل).

🔴 قبل CI/CD

🟢 مع CI/CD

WARNINGإحصائية صادمة — وفق تقرير DORA 2023، تنشر الفرق «النخبوية» عدة مرات يوميًا بمعدل فشل نشر أقل من 5 %، مقابل مرة شهريًا أو أقل للفرق «ذات الأداء المنخفض».

2. تكلفة الخطأ — قاعدة «Shift Left»

مبدأ «Shift Left» (الانتقال يسارًا) يعني اكتشاف وإصلاح المشكلات في أقرب وقت ممكن في دورة التطوير. كلما تأخر اكتشاف الخطأ، زادت تكلفة إصلاحه.

يسمح CI/CD برفع المشكلات منذ الـ commit، مما يقلل بشكل كبير من تكلفة التصحيح. تعمل الاختبارات الآلية وتحليل الكود الثابت وفحوصات الأمان عند كل push، قبل وصول الكود إلى الإنتاج بوقت طويل.

3. الأعمدة الثلاثة: CI، CD (التسليم) وCD (النشر)

🔵 CI — التكامل المستمر

يدمج المطورون كودهم في فرع مشترك عدة مرات يوميًا. عند كل دمج، ينطلق خط أنابيب آلي: التجميع، الاختبارات الوحدية، تحليل الكود.

الهدف: اكتشاف التعارضات والأخطاء بسرعة.

🟡 CD — التسليم المستمر

يكون الكود دائمًا في حالة قابلة للنشر. بعد CI، يُعد خط الأنابيب تلقائيًا إصدارًا (حزمة، صورة Docker) جاهزًا للنشر على أي بيئة.

الهدف: القدرة على النشر في أي وقت، مع إمكانية موافقة بشرية.

🟢 CD — النشر المستمر

كل commit يجتاز الاختبارات يُنشر تلقائيًا في الإنتاج، بدون تدخل بشري. هذا هو المستوى الأقصى من الأتمتة، المستخدم من Netflix وAmazon وGoogle.

الهدف: إزالة أي تأخير بين الكود والقيمة للمستخدم.

الممارسةتكرار النشرالموافقة البشريةمستوى الثقة المطلوب
يدويربع سنوي / سنويدائمًامنخفض (العملية)
CI فقطأسبوعي / شهريدائمًامتوسط (اختبارات أساسية)
CI + CD تسليميومي / أسبوعياختياريةمرتفع (اختبارات كاملة)
CI + CD نشرعدة مرات/يومأبدًامرتفع جدًا (اختبارات + مراقبة)

4. خط أنابيب CI/CD — نظرة عامة

خط أنابيب CI/CD هو سلسلة خطوات آلية تحول commit كود إلى تطبيق منشور في الإنتاج.

الخطوةالوصفالأدوات الشائعةالمدة النموذجية
الكوديدفع المطور الكود إلى GitGit, GitHub, GitLab
البناءالتجميع، حل التبعياتMaven, npm, Gradle, Docker1–5 دقائق
اختبار وحدياختبارات سريعة على مستوى الدوالJUnit, Jest, pytest1–3 دقائق
تحليل الجودةتغطية الكود، linting، الأمانSonarQube, ESLint, Snyk2–5 دقائق
الحزمةإنشاء artifact قابل للنشرDocker, JAR, ZIP, Helm2–10 دقائق
اختبار التكاملاختبارات على بيئة كاملةPostman, Cypress, k65–15 دقيقة
نشر Stagingالنشر على بيئة اختبارKubernetes, ECS, Heroku2–5 دقائق
نشر Prodالنشر في الإنتاجRolling, Blue/Green, Canary2–10 دقائق
المراقبةالمراقبة والتنبيهات بعد النشرPrometheus, Grafana, Datadogمستمر

5. مقاييس DORA — قياس أداء DevOps

حدد مشروع DORA (DevOps Research and Assessment) أربعة مقاييس رئيسية تقيس فعالية مؤسسة DevOps. تتيح هذه المقاييس تحديد موقع فريقك وتحديد أهداف التحسين.

📈 Deployment Frequency

va-plus-loin

يغطي هذا المقال المقتطفات الأكثر فائدة — الدورة الكاملة CI CD Pipeline (7 فصول، 20 درسًا، تمارين مصححة ومشروع نهائي) تأخذك إلى النهاية.

./acceder-au-cours-complet دورة مجانية: إتقان Claude Code

الأسئلة الشائعة

كم من الوقت لتعلم CI CD Pipeline؟
مع تقدم منظم (7 فصول، 20 درسًا قصيرًا وعمليًا)، يمكن الوصول إلى مستوى تشغيلي في بضعة أسابيع بمعدل 30 إلى 60 دقيقة يوميًا. المهم هو تطبيق كل مفهوم فورًا.
هل هناك متطلبات مسبقة؟
تكفي أساسيات الحوسبة. إذا كنت تعرف استخدام الطرفية وقراءة كود بسيط، فأنت جاهز.
من أين نبدأ عمليًا؟
أعد إنتاج أوامر هذا المقال، ثم تابع دورة CI CD Pipeline الكاملة: تتسلسل فيها الـ 20 درسًا بالترتيب، مع تمارين ومشروع نهائي.

📬 هل تريد تلقي هذا النوع من الأدلة كل أسبوع؟ اشترك مجانًا — كود حقيقي، بدون ثرثرة.