مقدمة: من خطوط الأنابيب الأساسية إلى الحلول الصناعية
خط أنابيب CI/CD الأساسي لمشروع جافا هو أمر جيد. لكن في التطوير الفعلي، عندما ينمو المشروع ليضم عشرات الوحدات، ويتكون الفريق من عدة مطورين، فإن الأمر البسيط `mvn clean test` لم يعد يلبي المتطلبات. تظهر أسئلة: كيف نسرّع عملية البناء؟ كيف نختبر على إصدارات مختلفة من JDK؟ كيف ننظم تشغيل الاختبارات بشكل متوازٍ؟ كيف ننشر القطع الأثرية تلقائياً في Docker Hub؟
في هذه المقالة، سنستعرض التقنيات المتقدمة لإعداد GitHub Actions لمشاريع جافا. ستتعلم كيف تحوّل خط الأنابيب الخاص بك من تسلسل خطي للخطوات إلى نظام قوي ومتوازٍ ومحسّن للتكامل والتسليم المستمرين.
1. البناء المصفوفي: الاختبار على إصدارات متعددة من JDK وأنظمة تشغيل
إحدى المهام الرئيسية لـ CI هي ضمان أن كود جافا الخاص بك يعمل على جميع المنصات المدعومة. التشغيل اليدوي للاختبارات على Windows و macOS و Linux بإصدارات مختلفة من JDK (11, 17, 21) هو رفاهية لا يمكن تحملها. يقدم GitHub Actions حلاً أنيقاً: البناء المصفوفي (matrix builds).
كيف يعمل
تقوم بتحديد مصفوفة من المعاملات (إصدارات JDK، أنظمة التشغيل)، ويقوم GitHub تلقائياً بإنشاء وظيفة منفصلة لكل مجموعة. جميعها تعمل بشكل متوازٍ.
مثال على التكوين
name: Java CI Matrixon: [push, pull_request]
jobs: build: runs-on: ${{ matrix.os }} strategy: matrix: os: [ubuntu-latest, windows-latest, macos-latest] java: [11, 17, 21] exclude: - os: windows-latest java: 21 # استبعاد JDK 21 على Windows إذا لم يكن مدعوماً fail-fast: false # لا توقف الوظائف الأخرى عند حدوث خطأ في واحدة
steps: - uses: actions/checkout@v4 - name: Set up JDK ${{ matrix.java }} uses: actions/setup-java@v4 with: java-version: ${{ matrix.java }} distribution: 'temurin' - name: Build with Maven run: mvn -B clean verify --file pom.xmlالنقاط الرئيسية:
strategy.matrix— يحدد مجموعات المعاملات.exclude— يسمح باستبعاد المجموعات غير العاملة أو غير الضرورية بشكل مؤكد.fail-fast: false— إذا فشلت وظيفة واحدة، ستستمر الوظائف الأخرى في العمل. هذا يعطي صورة كاملة عن التوافق.
2. التخزين المؤقت للتبعيات: تسريع البناء بمقدار 2-3 مرات
كل تشغيل لخط الأنابيب يبدأ ببيئة نظيفة. يقوم Maven أو Gradle بتنزيل جميع التبعيات من المستودعات من جديد. قد يستغرق هذا من 3 إلى 5 دقائق. التخزين المؤقت يحل هذه المشكلة عن طريق حفظ مجلد ~/.m2/repository (لـ Maven) أو ~/.gradle/caches (لـ Gradle) بين عمليات التشغيل.
يوفر GitHub Actions إجراءً مدمجاً actions/cache. يتم إنشاء مفتاح التخزين المؤقت بناءً على ملف التبعيات (pom.xml). إذا لم يتغير الملف، يتم استعادة التخزين المؤقت على الفور.
مثال لـ Maven
steps: - uses: actions/checkout@v4
- name: Cache Maven dependencies uses: actions/cache@v3 with: path: ~/.m2/repository key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }} restore-keys: | ${{ runner.os }}-maven-
- name: Set up JDK 17 uses: actions/setup-java@v4 with: java-version: '17' distribution: 'temurin'
- name: Build with Maven run: mvn -B clean verify --file pom.xmlهام: يجب أن يكون التخزين المؤقت قبل خطوة البناء. المفتاح hashFiles('**/pom.xml') يضمن تحديث التخزين المؤقت فقط عند تغيير التبعيات.
3. التنفيذ المتوازي للاختبارات وقطع البناء الأثرية
عندما يحتوي مشروعك على مئات أو آلاف الاختبارات، و