CI/CD والنشر على متاجر التطبيقات

CI/CD باستخدام Codemagic: سير العمل والمحفزات

16 دقيقة الدرس 7 من 12

CI/CD باستخدام Codemagic: سير العمل والمحفزات

Codemagic هي منصة CI/CD سحابية مصممة خصيصاً لتطبيقات Flutter والتطبيقات المحمولة. بدلاً من التعامل مع أدوات CI العامة، تفهم Codemagic نظام بناء Flutter فوراً — فهي تتولى إدارة إصدارات Flutter، والتوقيع الخاص بكل منصة، والنشر المباشر على Google Play ومتجر التطبيقات دون الحاجة إلى برمجة إضافية. في هذا الدرس ستتعلم كيفية تعريف خطوط أنابيب بناء آلية قابلة للتكرار باستخدام كلٍّ من ملف codemagic.yaml التعريفي ومحرر سير العمل عبر واجهة المستخدم الرسومية.

ملف codemagic.yaml

الطريقة المفضلة لتكوين Codemagic هي وضع ملف codemagic.yaml في جذر المستودع. هذا الأسلوب خاضع للتحكم بالإصدار، ويمكن مراجعته في طلبات الدمج، ويمكنه تعريف سير عمل مستقلة متعددة في ملف واحد. كل مفتاح رئيسي تحت workflows هو خط أنابيب منفصل مُسمَّى.

هيكل codemagic.yaml الأساسي

# codemagic.yaml — ضعه في جذر المستودع
workflows:
  android-release:
    name: Android Release
    max_build_duration: 60          # بالدقائق؛ يُلغى البناء عند تجاوزها
    environment:
      flutter: stable               # أو إصدار محدد مثل 3.22.0
      android_signing:
        - my_keystore                # يشير إلى هوية توقيع مخزنة في Codemagic
    triggering:
      events:
        - tag                        # يعمل فقط عند دفع وسم git
      tag_patterns:
        - pattern: 'v*'
          include: true
    scripts:
      - name: Get dependencies
        script: flutter pub get
      - name: Run tests
        script: flutter test
      - name: Build release APK
        script: |
          flutter build apk --release \
            --build-name=$PROJECT_BUILD_NUMBER \
            --build-number=$BUILD_NUMBER
    artifacts:
      - build/**/outputs/**/*.apk
    publishing:
      google_play:
        credentials: $GPLAY_SERVICE_ACCOUNT_JSON
        track: internal
ملاحظة: يُحمَّل ملف codemagic.yaml وقت البناء من الإيداع (commit) الذي يُبنى. هذا يعني أن التغييرات على خط الأنابيب تصبح سارية فور وصولها إلى الفرع المستهدف — دون الحاجة إلى إعادة تكوين يدوية في لوحة تحكم Codemagic.

تشغيل البناء: الأحداث والأنماط

يحدد كتلة triggering متى يعمل سير العمل. تدعم Codemagic خمسة أحداث تشغيل رئيسية:

  • push — كل إيداع يُدفع إلى الفروع المطابقة
  • pull_request — عند فتح طلب دمج أو استقبال إيداعات جديدة على فرعه الرئيسي
  • tag — عند دفع وسم git (مثالي لبنيات الإصدار)
  • scheduled — تشغيلات ليلية أو أسبوعية مبنية على cron
  • manual — يُشغَّل فقط من لوحة تحكم Codemagic أو عبر API

تستخدم أنماط الفروع والوسوم صياغة glob. يمكنك الجمع بين إدخالات include: true وinclude: false لإدراج أو استثناء مراجع محددة:

أمثلة على أنماط الفروع والوسوم

triggering:
  events:
    - push
    - pull_request
  branch_patterns:
    - pattern: 'main'
      include: true
      source: true         # الفرع المصدر لطلب الدمج
    - pattern: 'release/*'
      include: true
    - pattern: 'wip/*'
      include: false       # لا تبني أبداً فروع العمل الجاري
  tag_patterns:
    - pattern: 'v[0-9]*.[0-9]*.[0-9]*'   # وسوم semver مثل v1.4.2
      include: true
  cancel_previous_builds: true            # تجنب تراكم البنيات المتكررة

إدارة هويات التوقيع في تخزين Codemagic الآمن

بيانات اعتماد توقيع الكود — مخازن مفاتيح Android وشهادات iOS وملفات تعريف التوفير — يجب ألا تُودَع أبداً في المستودع. توفر Codemagic التخزين الآمن (مشفر في حالة الراحة، يُحقن كمتغيرات بيئة أو ملفات وقت البناء) عبر آليتين:

  • مجموعات متغيرات البيئة — تخزين الأسرار المشفرة بـ base64 أو رموز API النصية؛ يُشار إليها في codemagic.yaml بمفتاح groups تحت environment.vars.
  • هويات توقيع الكود (Android) — ارفع ملف .jks أو .keystore عبر لوحة تحكم Codemagic؛ أشر إلى اسمه المستعار تحت android_signing. تضبط Codemagic متغيرات البيئة CM_KEYSTORE وCM_KEY_ALIAS وCM_KEY_PASSWORD وCM_KEYSTORE_PASSWORD تلقائياً.
  • التوقيع التلقائي لـ iOS — اربط حساب Apple Developer مرة واحدة في Codemagic؛ فتتولى تجديد الشهادات وملفات تعريف التوفير. أشر إلى معرف الحزمة تحت ios_signing.

توصيل توقيع Android في codemagic.yaml

workflows:
  android-production:
    name: Android Production
    environment:
      flutter: stable
      android_signing:
        - my_production_keystore     # الاسم المستعار المضبوط في لوحة تحكم Codemagic
      groups:
        - google_play_credentials    # مجموعة متغيرات البيئة المحتوية على GPLAY_SERVICE_ACCOUNT_JSON
    scripts:
      - name: Build release bundle
        script: |
          flutter build appbundle --release \
            --build-name=1.0.$BUILD_NUMBER \
            --build-number=$BUILD_NUMBER
    artifacts:
      - build/**/outputs/**/*.aab
    publishing:
      google_play:
        credentials: $GPLAY_SERVICE_ACCOUNT_JSON
        track: production
        submit_as_draft: false
تحذير: لا تُضمِّن أبداً كلمات مرور مخزن المفاتيح أو مفاتيح API أو JSON لحساب الخدمة بشكل مباشر في codemagic.yaml. يعيش الملف في مستودعك العام. أشر دائماً إلى الأسرار عبر متغيرات بيئة التخزين الآمن في Codemagic.

نشر القطع الأثرية تلقائياً إلى المختبرين

بعد بناء ناجح، يمكن لـ Codemagic دفع القطع الأثرية مباشرة إلى قنوات التوزيع دون أي خطوات يدوية:

  • Firebase App Distribution — رفع ملفات APK/IPA وإبلاغ مجموعات المختبرين فوراً.
  • Google Play — نشر ملفات AAB على مسارات الاختبار الداخلي أو ألفا أو بيتا أو الإنتاج.
  • App Store Connect (TestFlight) — تقديم ملفات IPA للمراجعة عبر TestFlight تلقائياً.
  • إشعارات البريد الإلكتروني / Slack — تنبيه أصحاب المصلحة عند نجاح البناء أو فشله.

النشر على Firebase App Distribution

publishing:
  firebase:
    firebase_token: $FIREBASE_TOKEN      # من التخزين الآمن في Codemagic
    android:
      app_id: $FIREBASE_ANDROID_APP_ID
      groups:
        - qa-team
        - beta-testers
      artifact_type: apk
  email:
    recipients:
      - dev@example.com
    notify:
      success: true
      failure: true

محرر سير العمل الرسومي مقابل codemagic.yaml

بالنسبة للفرق الجديدة على CI/CD، يوفر محرر سير العمل الرسومي في Codemagic (المتاح في لوحة التحكم) بديلاً بالنقر والسحب. يكتب نفس التكوين الداخلي لكنه يعرضه عبر حقول نماذج. المقايضة هي أن سير العمل الرسومي لا يُخزَّن في المستودع — يمكن أن ينجرف بعيداً عن قاعدة الكود. التوصية هي البدء بواجهة المستخدم الرسومية لتعلم الخيارات، ثم التصدير إلى codemagic.yaml لقابلية الصيانة على المدى البعيد.

نصيحة: استخدم أسلوب codemagic.yaml من اليوم الأول في المشاريع الإنتاجية. إذ يمنحك سجلاً تدقيقياً كاملاً عبر تاريخ git، ويتيح مراجعة الأقران لتغييرات خط الأنابيب، ويسمح لمطورين متعددين بإدارة تكوين CI بنفس الطريقة التي يديرون بها كود التطبيق.

الملخص

تجلب Codemagic CI/CD على مستوى الإنتاج إلى Flutter بأقل قدر من النمطية. ملف codemagic.yaml في جذر مستودعك يعرّف سير عمل مُسمَّاة واحدة أو أكثر، لكل منها قواعد تشغيل خاصة (push أو وسم أو طلب دمج أو جدول)، وبيئة (إصدار Flutter، هويات التوقيع من التخزين الآمن)، وسكريبتات البناء، ووجهات النشر. إبقاء الأسرار خارج المستودع واستخدام مجموعات المتغيرات المشفرة في Codemagic إلزامي لخطوط أنابيب آمنة. بمجرد التكوين، يمكن لكل إيداع ناجح على main أو كل وسم v* أن يبني تطبيق Flutter ويوقعه وينشره تلقائياً للمختبرين أو المتاجر.