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

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

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

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

المنصة

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

الدعم

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

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

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

Preview Environments بالعربي: اختبر كل Pull Request قبل الدمج

📅 ٢٤ أبريل ٢٠٢٦⏱ 4 دقائق قراءة
Preview Environments بالعربي: اختبر كل Pull Request قبل الدمج

Preview Environments بالعربي: اختبر كل Pull Request قبل الدمج

لو كل Pull Request عندك بيتراجع بالعين فقط، المقال ده هيديك طريقة تشغل نسخة مؤقتة من التطبيق وتكشف مشاكل التكامل قبل الدمج.

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

اللي بيحصل فعلاً إن المراجعة بتشوف naming، structure، وربما test unit بسيط. لكن أول مرة الـ frontend يكلم الـ API والـ API يكلم PostgreSQL بتكون بعد الدمج أو على staging. هنا الباج بيبقى أغلى.

الافتراض إن عندك تطبيق صغير أو متوسط: API، قاعدة بيانات، وربما frontend. أقل من 20 خدمة. لو عندك منصة Kubernetes كبيرة، نفس الفكرة تنفع، لكن التنفيذ هيبقى بأدوات مختلفة.

رفوف خوادم مضاءة تمثل بيئة Preview معزولة قبل النشر

الفكرة ببساطة

Preview Environment يعني نسخة مؤقتة من التطبيق مرتبطة بـ Pull Request معين. افتح PR رقم 42، يتبني image، يتشغل compose project باسم مختلف، وبعدها يتعمل smoke test. لو الاختبار فشل، الـ PR يتوقف قبل ما يلمس main.

ركز في النقطة دي: الهدف مش تعمل staging ثاني دائم. الهدف إنك تعمل بيئة قصيرة العمر. مثل مكتب صغير بيجهز عينة من المنتج للعميل، وبعد الموافقة يرجع يفكها. التكلفة وقت runner ومساحة Docker، والمكسب إنك تكشف كسر التكامل قبل الدمج.

في سيناريو واقعي، فريق عنده 8 مطورين و12 Pull Request يوميًا. لو كل PR بياخد 5 دقائق Preview وSmoke Test، هتدفع تقريبًا 60 دقيقة runner يوميًا. مقابل ده، ممكن تمنع incident واحد أسبوعيًا كان بياخد ساعتين debug على staging.

إعداد Docker Compose لبيئة مؤقتة

أفضل طريقة للمشاريع الصغيرة: استخدم Docker Compose project name مختلف لكل PR. كده الشبكات والـ volumes تتعزل بدل ما الخدمات تدوس على بعض.

YAML
# compose.preview.yml
services:
  api:
    build: .
    environment:
      DATABASE_URL: postgres://app:app@db:5432/app
    depends_on:
      db:
        condition: service_healthy
    ports:
      - "8080"

  db:
    image: postgres:16-alpine
    environment:
      POSTGRES_USER: app
      POSTGRES_PASSWORD: app
      POSTGRES_DB: app
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U app -d app"]
      interval: 5s
      timeout: 3s
      retries: 10

  smoke:
    image: curlimages/curl:8.7.1
    depends_on:
      api:
        condition: service_started
    command: ["sh", "-c", "curl -fsS http://api:3000/health"]
    profiles: ["test"]

الـ healthcheck هنا مش رفاهية. Docker Compose يدعم انتظار الخدمة التي عليها service_healthy قبل تشغيل الخدمة التابعة لها. ده يمنع حالة شائعة: الـ API يبدأ قبل PostgreSQL بثانيتين، فيفشل الاختبار مع إن الكود سليم.

GitHub Actions Workflow قابل للنسخ

استخدم workflow بسيط على حدث pull_request. الرقم المهم هنا هو COMPOSE_PROJECT_NAME. بدل ما كل PR يستخدم نفس الشبكة، كل PR ياخد namespace منفصل.

YAML
# .github/workflows/preview.yml
name: preview-smoke-test

on:
  pull_request:
    branches: [main]

concurrency:
  group: preview-${{ github.event.pull_request.number }}
  cancel-in-progress: true

jobs:
  preview:
    runs-on: ubuntu-latest
    timeout-minutes: 10
    env:
      COMPOSE_PROJECT_NAME: pr-${{ github.event.pull_request.number }}
    steps:
      - uses: actions/checkout@v4

      - name: Build preview stack
        run: docker compose -f compose.preview.yml up -d --build api db

      - name: Run smoke test
        run: docker compose -f compose.preview.yml --profile test run --rm smoke

      - name: Show logs on failure
        if: failure()
        run: docker compose -f compose.preview.yml logs --no-color

      - name: Cleanup
        if: always()
        run: docker compose -f compose.preview.yml down -v --remove-orphans

لو الـ build بياخد 3 دقائق والـ smoke test بياخد 30 ثانية، خلي timeout-minutes عند 10 دقائق. الرقم ده عملي: يكشف التعليق بدل ما runner يفضل شغال ساعة كاملة.

حاسوب محمول يعرض لوحة عمل رقمية لاختبارات CI قبل الدمج

الـ trade-off هنا

هتكسب signal أقوى من unit tests وحدها. الاختبار بيشغل database حقيقية، network حقيقي، وcontainer startup حقيقي. هتخسر وقت CI ومساحة مؤقتة على runner. لو عندك 30 PR في اليوم، دقيقة زيادة لكل PR معناها 30 دقيقة runner يوميًا.

الطريقة دي بتفشل لو استخدمتها كبديل لاختبارات الوحدة. Preview Environment ممتازة لاكتشاف مشاكل الربط، migration ناقصة، env var غلط، أو endpoint ميت. لكنها مش مكان مناسب لاختبار كل branch منطقي في الكود.

تقدر تقلل التكلفة بتشغيلها على PRs التي تغير ملفات مؤثرة فقط. مثال: لو التغيير داخل docs، لا تشغل preview. لو التغيير داخل src/ أو compose.preview.yml، شغلها.

متى لا تستخدم هذه الطريقة

لا تستخدم Docker Compose Preview لو التطبيق محتاج خدمات سحابية حقيقية لا يمكن محاكاتها، أو لو عندك 50 microservice بتحتاج شبكة داخلية معقدة. في الحالة دي استخدم namespace مؤقت في Kubernetes أو منصة preview مخصصة.

لا تستخدمها أيضًا لو زمن الـ build أكبر من 15 دقيقة ولا يوجد cache. ركز الأول على تحسين build cache، وبعدها أضف preview. غير كده هتزود friction على كل PR.

مصادر اعتمد عليها المقال

  • GitHub Docs: Deploying with GitHub Actions
  • GitHub Docs: Managing environments for deployment
  • Docker Docs: Control startup order
  • Docker Docs: Use service profiles

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

افتح repo واحد عندك، أضف compose.preview.yml والـ workflow فوق، وخلي أول smoke test يضرب /health فقط. لو نجح 10 مرات متتالية، زوّد اختبار endpoint واحد يعتمد على قاعدة البيانات.

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

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

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