مقدمة: لماذا تعتبر CI/CD أمرًا بالغ الأهمية لمشاريع Kotlin
التطوير الحديث بلغة Kotlin — سواء كان Backend على Spring Boot، أو تطبيق Android، أو مشروع متعدد المنصات — يتطلب دورة تسليم سريعة وموثوقة. عمليات البناء والاختبار اليدوية لا تستهلك الوقت فحسب، بل إنها أيضًا عرضة للأخطاء. هنا يأتي دور CI/CD (التكامل المستمر / النشر المستمر).
GitHub Actions هو نظام أتمتة مدمج يسمح لك بتشغيل سير العمل (workflows) مباشرة في مستودعك. بالنسبة لمشاريع Kotlin، هذا هو الخيار المثالي: فهو يتكامل بسهولة مع Gradle، ويدعم التخزين المؤقت للتبعيات، ويسمح بنشر التطبيقات على أي منصة.
في هذه المقالة، سنشرح كيفية إعداد خط أنابيب CI/CD كامل لمشروع Kotlin باستخدام GitHub Actions: من البناء الأساسي إلى النشر التلقائي.
1. أساسيات GitHub Actions: هيكل سير العمل (workflow)
كل سير عمل في GitHub Actions هو ملف YAML، موجود في الدليل .github/workflows/. دعنا نستعرض المكونات الأساسية باستخدام مثال لمشروع Kotlin.
1.1. المشغلات (on)
يتم تشغيل سير العمل بناءً على أحداث معينة: push إلى فرع، إنشاء Pull Request، أو وفقًا لجدول زمني (cron).
1.2. المهام (Jobs) والخطوات (Steps)
Job هي مجموعة من الخطوات التي يتم تنفيذها على بيئة افتراضية واحدة. يمكن للخطوات تشغيل أوامر، أو نصوص برمجية، أو إجراءات (actions) جاهزة من السوق.
1.3. مثال على سير عمل أدنى
لنقم بإنشاء ملف .github/workflows/ci.yml لمشروع Kotlin على Gradle:
name: CI for Kotlin
on: push: branches: [ main, develop ] pull_request: branches: [ main ]
jobs: build: runs-on: ubuntu-latest
steps: - uses: actions/checkout@v4
- name: Set up JDK 17 uses: actions/setup-java@v4 with: java-version: '17' distribution: 'temurin'
- name: Setup Gradle uses: gradle/actions/setup-gradle@v3
- name: Build with Gradle run: ./gradlew build
- name: Run tests run: ./gradlew testسيقوم خط الأنابيب هذا بتشغيل البناء والاختبارات مع كل push أو PR إلى main/develop.
2. تحسين CI: التخزين المؤقت والمهام المتوازية
بدون تحسين، سيقوم كل تشغيل بتنزيل تبعيات Gradle من جديد. بالنسبة لمشاريع Kotlin، قد يستغرق هذا من 2 إلى 5 دقائق. الحل هو التخزين المؤقت.
2.1. التخزين المؤقت لذاكرة Gradle المؤقتة
يسمح GitHub Actions بتخزين الدليل ~/.gradle/caches مؤقتًا:
- name: Cache Gradle packages uses: actions/cache@v4 with: path: | ~/.gradle/caches ~/.gradle/wrapper key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }} restore-keys: | ${{ runner.os }}-gradle-بعد التشغيل الأول، ستستخدم التشغيلات اللاحقة الذاكرة المؤقتة — تزداد السرعة بمقدار 2-3 مرات.
2.2. مهام متوازية لمهام مختلفة
يمكنك تقسيم الاختبار، والتحليل البرمجي (linting)، والبناء إلى مهام منفصلة يتم تنفيذها بالتوازي:
jobs: lint: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: Run detekt run: ./gradlew detekt
test: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: Run tests run: ./gradlew test
build: needs: [lint, test] runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: Build JAR run: ./gradlew bootJarهنا، سيتم تشغيل build فقط بعد اجتياز التحليل البرمجي والاختبارات بنجاح.
3. سيناريوهات متقدمة لمشاريع Kotlin
دعنا نستعرض المهام الواقعية التي غالبًا ما نواجهها في CI/CD لـ Kotlin.
3.1. نشر القطع الأثرية (Artifacts) في GitHub Packages
إذا كنت تقوم بنشر مكتبة أو تطبيق، فيمكنك نشر القطع الأثرية تلقائيًا إلى GitHub Packages: