التكامل والنشر المستمران باستخدام GitHub Actions
اختبر وانشر PHP تلقائيًا مع كل عملية دفع
التكامل والنشر المستمران باستخدام GitHub Actions درس مجاني في PHP Academy على CoddyKit. هذا هو الدرس 4 من أصل 4. يمكنك قراءة الدرس كاملاً أدناه مجاناً — ثم تمرن عليه مباشرة في المتصفح باستخدام محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7. هذا الدرس جزء من مسار التعلم في PHP Academy، وتقدمك يتزامن عبر الويب وتطبيق CoddyKit. تتضمن دورة PHP Academy 4 دروس في المجموع.
CI/CD لـ PHP
ينبغي اختبار كل عملية دفع، وفحصها باستخدام lint، وتحليلها تحليلاً ساكنًا، ثم، عند نجاحها على الفرع الرئيسي، تحويلها إلى صورة ونشرها. تنفّذ GitHub Actions خط أنابيب العمل هذا على منفّذات مُدارة، ويُشغّله أحداث المستودع.
سننشئ سير عمل يشغّل PHPUnit باستخدام خدمة MySQL حقيقية، ويخزّن Composer مؤقتًا، ويشغّل PHPStan، ويبني صورة Docker، ثم ينشرها.
بنية سير العمل
يوجد سير العمل في .github/workflows/*.yml. ويحتوي على مشغلات on: ومهمة واحدة أو أكثر ضمن jobs:، بينما تحتوي كل مهمة على خطوات steps:. تعمل المهام على منفّذات معزولة بالتوازي، ما لم تربطها needs:.
name: CI
on:
push:
branches: [main]
pull_request:
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4إجراء setup-php
يُعد shivammathur/setup-php الطريقة القياسية لتثبيت إصدار PHP محدد مع الامتدادات والأدوات المطلوبة (مثل Composer وPHPStan وغيرها) على المنفّذ، وهو أسرع بكثير من بناء صورة لمجرد إجراء الاختبارات.
- name: Setup PHP
uses: shivammathur/setup-php@v2
with:
php-version: '8.3'
extensions: pdo_mysql, intl, redis, zip
coverage: pcov
tools: composer:v2, phpstanتخزين Composer مؤقتًا
إعادة تنزيل الاعتماديات في كل تشغيل تهدر دقائق. خزّنوا مجلد Composer مؤقتًا باستخدام تجزئة composer.lock كمفتاح، حتى لا تُبطَل صلاحية ذاكرة التخزين المؤقت إلا عند تغيّر الاعتماديات.
- name: Get Composer cache dir
id: composer-cache
run: echo "dir=$(composer config cache-files-dir)" >> $GITHUB_OUTPUT
- uses: actions/cache@v4
with:
path: ${{ steps.composer-cache.outputs.dir }}
key: composer-${{ hashFiles('**/composer.lock') }}
restore-keys: composer-
- run: composer install --prefer-dist --no-progressحاويات الخدمات
يمكن للمهام تشغيل حاويات خدمات، مثل MySQL أو Redis حقيقي يمكن للمنفّذ الوصول إليه عبر 127.0.0.1. أضيفوا فحص صحة عبر options حتى لا تُشغّل الخطوات قبل جاهزية قاعدة البيانات.
test:
runs-on: ubuntu-latest
services:
mysql:
image: mysql:8.4
env:
MYSQL_DATABASE: app_test
MYSQL_ROOT_PASSWORD: root
ports: ['3306:3306']
options: >-
--health-cmd="mysqladmin ping -proot"
--health-interval=5s --health-retries=10تشغيل الاختبارات والتغطية
بعد تثبيت الاعتماديات وتشغيل MySQL، شغّلوا PHPUnit. وجّهوا DSN الاختبارات إلى 127.0.0.1:3306. أنشئوا تقرير التغطية، ويمكنكم اختياريًا إفشال البناء إذا انخفضت عن حد معين.
- name: Run PHPUnit
env:
DATABASE_URL: "mysql://root:root@127.0.0.1:3306/app_test"
run: vendor/bin/phpunit --coverage-clover=coverage.xml
- name: Static analysis
run: phpstan analyse src --level=8 --no-progressعمليات البناء المصفوفية
ينبغي للمكتبات اجتياز الاختبارات على إصدارات متعددة من PHP. توزّع strategy.matrix المهمة على عمليات تشغيل متوازية، واحدة لكل تركيبة، مع إدراج ${{ matrix.php }} ضمن الخطوات.
test:
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
php: ['8.2', '8.3', '8.4']
steps:
- uses: actions/checkout@v4
- uses: shivammathur/setup-php@v2
with:
php-version: ${{ matrix.php }}حساب وسم الصورة
تحتاج عمليات النشر إلى وسم صورة فريد يمكن تتبعه. ويُعد SHA الخاص بالـ commit الخيار المعتاد. يوضح هذا المقطع منطق اشتقاق الوسم الذي ستعبّرون عنه في سير العمل، إذ يحوّل المرجع وSHA إلى وسم في السجل.
<?php
// Mirrors what the workflow computes for the image tag
$ref = 'refs/heads/main';
$sha = '9f41efadc0de1234567890abcdef0000deadbeef';
$branch = str_replace('refs/heads/', '', $ref);
$shortSha = substr($sha, 0, 7);
$tag = sprintf('registry.example.com/app:%s-%s', $branch, $shortSha);
echo $tag . PHP_EOL; // registry.example.com/app:main-9f41efa
echo 'is_main: ' . ($branch === 'main' ? 'yes' : 'no') . PHP_EOL;
?>بناء الصورة ودفعها
على الفرع الرئيسي، ابنوا صورة Docker باستخدام docker/build-push-action مع BuildKit وذاكرة التخزين المؤقت في GitHub Actions. سجّلوا الدخول إلى السجل باستخدام رمز سري أولًا، ولا تضعوا بيانات الاعتماد في الشيفرة مطلقًا.
build:
needs: test
if: github.ref == 'refs/heads/main'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- uses: docker/build-push-action@v6
with:
push: true
target: runtime
tags: ghcr.io/${{ github.repository }}:${{ github.sha }}
cache-from: type=gha
cache-to: type=gha,mode=maxالأسرار وOIDC
خزّنوا بيانات الاعتماد في أسرار المستودع أو البيئة، وأشيروا إليها باستخدام ${{ secrets.NAME }}، إذ تُخفى في السجلات. أما عمليات النشر السحابية، ففضّلوا لها OIDC؛ إذ يحصل المنفّذ على رمز قصير الأجل من AWS/GCP عبر permissions: id-token: write، فلا توجد مفاتيح طويلة الأجل داخل المستودع.
deploy:
needs: build
runs-on: ubuntu-latest
permissions:
id-token: write # enables OIDC
contents: read
steps:
- uses: aws-actions/configure-aws-credentials@v4
with:
role-to-assume: arn:aws:iam::123456789012:role/deploy
aws-region: eu-central-1خطوة النشر والبيئات
قيّدوا عمليات النشر إلى الإنتاج خلف environment في GitHub، مع إمكانية اشتراط مراجعين محددين. ثم تشغّل خطوة النشر عملية التحديث التدريجي لديكم، مثل تحديث عملية نشر Kubernetes أو خدمة ECS أو الاتصال عبر SSH لسحب الصورة الجديدة.
deploy:
needs: build
runs-on: ubuntu-latest
environment:
name: production # can require manual approval
url: https://app.example.com
steps:
- name: Roll out
run: |
kubectl set image deployment/app \
app=ghcr.io/${{ github.repository }}:${{ github.sha }}
kubectl rollout status deployment/app --timeout=120sفحص سريع
ما الميزة الأمنية الأساسية لـ OIDC مقارنةً بمفاتيح السحابة المخزّنة في Actions؟
مراجعة
أنشأتم خط أنابيب CI/CD لـ PHP في GitHub Actions: مشغلات عند الدفع وطلبات السحب، وsetup-php مع الامتدادات، وComposer مخزّنًا مؤقتًا باستخدام ملف القفل كمفتاح، وحاوية خدمة MySQL مع فحص صحة، وPHPUnit وPHPStan، ومصفوفة إصدارات، ثم بناءً ودفعًا خاصين بالفرع الرئيسي باستخدام ذاكرة GHA المؤقتة، ونشرًا موثّقًا عبر OIDC ومقيّدًا ببيئة.
المبادئ: خزّنوا مؤقتًا باستخدام تجزئات ملف القفل، وتحققوا من جاهزية الخدمات عبر فحوصات الصحة، ووسموا الصور باستخدام SHA، وفضّلوا OIDC على المفاتيح المخزّنة.
الأسئلة الشائعة
هل درس «التكامل والنشر المستمران باستخدام GitHub Actions» مجاني؟
نعم — نص درس «التكامل والنشر المستمران باستخدام GitHub Actions» كامل متاح مجاناً هنا على الويب. لتمرينه بشكل تفاعلي (محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7) وفتح باقي دورة PHP Academy، انتقل إلى CoddyKit PRO. تتضمن دورة PHP Academy 4 دروس في المجموع.
ماذا ستتعلم في «التكامل والنشر المستمران باستخدام GitHub Actions»؟
اختبر وانشر PHP تلقائيًا مع كل عملية دفع تتمرن على PHP Academy مع أكواد عملية تشغلها مباشرة في المتصفح، ومدرس ذكاء اصطناعي متاح 24/7 يجيب على أسئلتك أثناء عملك.
هل أحتاج إلى خبرة سابقة لأبدأ PHP Academy؟
لا تُشترط خبرة سابقة. PHP Academy على CoddyKit منظم للمبتدئين حتى المتقدمين، لذا يمكنك البدء من هنا أو من البداية والتقدم بسرعتك الخاصة. هذا هو الدرس 4 من أصل 4.
كم من الوقت يستغرق درس «التكامل والنشر المستمران باستخدام GitHub Actions»؟
معظم دروس CoddyKit تستغرق حوالي 5–10 دقائق. كل منها موجز وتفاعلي، لذا تحرز تقدماً مستمراً وتستأنف من حيث توقفت عبر الويب والتطبيق.
هل يمكنني كتابة وتشغيل أكواد في درس PHP Academy هذا؟
نعم. كل درس في PHP Academy يتضمن محرر أكواد مدمج، لذا تكتب وتشغل أكواداً حقيقية مباشرة في متصفحك وتحصل على تعليقات فورية من الذكاء الاصطناعي — بدون إعداد محلي.
جميع الدروس في هذه الدورة
- وضع تطبيق PHP في حاوية
- البناء متعدد المراحل والتحسين
- Docker Compose للبيئات المحلية
- التكامل والنشر المستمران باستخدام GitHub Actions