إعداد التكامل المستمر (CI) لمسارك مهم جدًا، لأنه يساعد في اكتشاف الأخطاء.
تستخدم مستودعات Exercism (بما فيها مستودعات المسارات) GitHub Actions لتشغيل التكامل المستمر. تستند GitHub Actions إلى سير العمل، وهي تُعرّف سكربتات تُشغَّل تلقائيًا كلما وقع حدث معيّن (مثل دفع commit). لمزيد من المعلومات عن سير عمل GitHub Actions، اطّلع على وثائق سير العمل.
تأتي المسارات مزوّدة مسبقًا بعدد من سير العمل، ومعظمها لا ينبغي أن تعدّله (وتُسمّى سير العمل المشتركة). لكن هناك سير عمل واحد ينبغي أن تغيّره، وهو سير العمل test.yml.
هدف سير العمل test.yml هو التحقق من أن تمارين المسار في حالة سليمة. سير العمل مهيّأ ليعمل تلقائيًا (بمصطلحات GitHub Actions: يُطلَق) عند دفع إلى فرع main أو إلى فرع طلب سحب.
سير العمل نفسه لا ينبغي أن يفعل الكثير، عدا ما يلي:
كما ذُكر، تُتحقق التمارين عبر سكربت، هو سكربت bin/verify-exercises (بلغة bash). هذا السكربت شبه جاهز، وهو يقوم بما يلي:
unskip_tests التي يمكنك فيها إلغاء تخطي الاختبارات في ملفات الاختبار (اختياري)run_tests التي ينبغي أن تشغّل فيها الاختبارات (مطلوب)دالتا run_tests وunskip_tests هما الشيء الوحيد الذي تحتاج إلى تنفيذه.
إذا كان مسارك يدعم تخطي الاختبارات، علينا التأكد من عدم تخطي أي اختبار عند التحقق من حل المثال/النموذج لأي تمرين. عمومًا، هناك أسلوبان تدعم بهما المسارات "إلغاء التخطي":
test.skip إلى test.SKIP_TESTS=false.إذا كان تخطي الاختبارات قائمًا على الملفات (الخيار الأول أعلاه)، عدّل الدالة unskip_tests لتعديل ملفات الاختبار (الكود الحالي يتعامل بالفعل مع المرور على ملفات الاختبار).
تعمل الدالة unskip_test على نسخة من مجلد التمرين، فلا تتردد في تعديل الملفات كما تراه مناسبًا.
يستخدم ملف bin/verify-exercises في مسار Arturo الأمر sed لإلغاء تخطي الاختبارات داخل ملفات الاختبار:
unskip_tests() {
jq -r '.files.test[]' .meta/config.json | while read -r test_file; do
sed -i 's/test.skip/test/g' "${test_file}"
done
}
إذا كان إلغاء تخطي الاختبارات يتطلب ضبط متغير بيئة، فتأكد من ضبطه داخل الدالة run_tests.
الدالة run_tests مسؤولة عن تشغيل اختبارات التمرين. عند استدعاء الدالة، ستكون ملفات المثال/النموذج قد نُسخت بالفعل إلى ملفات الحل (الهيكل)، لذا تحتاج فقط إلى استدعاء الأمر الصحيح لتشغيل الاختبارات.
يجب أن تُرجع الدالة صفرًا كرمز خروج إذا نجحت جميع الاختبارات، وإلا فعليها إرجاع رمز خروج غير صفري.
تعمل الدالة run_tests على نسخة من مجلد التمرين، فلا تتردد في تعديل الملفات كما تراه مناسبًا.
الخيار الافتراضي لسكربت التحقق من التمارين هو استخدام أدوات اللغة (SDK/ملف تنفيذي/إلخ)، وهو ما تستخدمه معظم المسارات. سيكون لكل مسار أسلوبه الخاص في تشغيل الاختبارات، لكنه عادة أمر واحد فقط.
يعدّل ملف bin/verify-exercises في مسار Arturo الدالة run_tests ليستدعي ببساطة الأمر arturo على ملف الاختبار:
run_tests() {
arturo tester.art
}
الخيار الثاني هو التحقق من التمارين بتشغيل مُشغّل الاختبارات الخاص بالمسار. وهذا بالطبع يعتمد على أن يكون لدى المسار مُشغّل اختبارات يعمل.
إذا لم يكن لدى مسارك مُشغّل اختبارات بعد، فيمكنك إما:
يجب إجراء التعديلات التالية على سكربت bin/verify-exercises file الافتراضي:
docker
docker run لتشغيل صورة Docker الخاصة بمُشغّل الاختبارات على كل تمرينjq للتحقق من أن ملف results.json الذي تُرجعه حاوية Docker يشير إلى نجاح جميع الاختباراتunskip_test والاستدعاء الخاص بهاالميزة الأساسية لهذا الأسلوب أنه يحاكي على أفضل وجه الكيفية التي تُشغَّل بها الاختبارات في الإنتاج (على الموقع). وبهذا الأسلوب، تقل احتمالية فشل أشياء في الإنتاج كانت قد نجحت في التكامل المستمر. أما العيب في هذا الأسلوب فهو أنه عادة أبطأ، بسبب الحاجة إلى سحب صورة Docker وما يضيفه Docker من عبء.
يضيف ملف bin/verify-exercises file في مسار Unison التحقق من أن الأمر docker مثبّت أيضًا:
required_tool docker
ثم يسحب صورة مُشغّل الاختبارات الخاص بالمسار:
docker pull exercism/unison-test-runner
ثم يعدّل الدالة run_tests لتستخدم docker run لتشغيل مُشغّل الاختبارات على التمرين الحالي (الموجود في مجلد العمل)، يتبع ذلك أمر jq للتحقق من الحالة الصحيحة:
run_tests() {
local slug
slug="${1}"
docker run \
--rm \
--network none \
--mount type=bind,src="${PWD}",dst=/solution \
--mount type=bind,src="${PWD}",dst=/output \
--tmpfs /tmp:rw \
exercism/unison-test-runner "${slug}" "/solution" "/output"
jq -e '.status == "pass"' "${PWD}/results.json" >/dev/null 2>&1
}
أخيرًا، نحتاج إلى تعديل استدعاء الأمر run_tests، لأنه يتطلب الآن المعرّف:
run_tests "${slug}"
الآن وقد انتهى سكربت verify-exercises، حان وقت إنهاء سير العمل test.yml. تعتمد كيفية القيام بذلك على الخيار الذي اخترته لتنفيذ سكربت verify-exercises.
إذا كان سكربت verify-exercises يستخدم أدوات اللغة مباشرة، فسيحتاج سير عمل الاختبار إلى تثبيت:
وبعد الانتهاء من ذلك، ينبغي أن يعمل verify-exercises كما هو متوقع، وتكون قد أعددت التكامل المستمر بنجاح!
للاستطلاع على مثال، اطّلع على سير العمل test.yml في مسار Arturo:
name: Test
on:
push:
branches: [main]
pull_request:
branches: [main]
workflow_dispatch:
jobs:
ci:
runs-on: ubuntu-22.04
steps:
- name: Checkout repository
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332
- name: Install dependencies
run: |
sudo apt-get update
sudo apt-get install libgtk-3-dev libwebkit2gtk-4.0-dev libmpfr-dev
- name: Install Arturo
run: bin/install-arturo
env:
GH_TOKEN: ${{ github.token }}
- name: Verify all exercises
run: bin/verify-exercises
الخيار الثاني هو التحقق من التمارين بتشغيل مُشغّل الاختبارات الخاص بالمسار. ويتطلب هذا الخيار تحقق أمرين:
verify-exercises صورة Docker الخاصة بمُشغّل الاختبارات لتشغيل اختبارات التمرينإذا لم يكن لدى مسارك مُشغّل اختبارات بعد، فيمكنك إما:
لهذا الأسلوب ميزتان:
العيب الأساسي أنه غالبًا أبطأ، بسبب الحاجة إلى سحب صورة Docker وما يضيفه Docker من عبء.
هناك عدة أساليب لسحب صورة Docker الخاصة بمُشغّل الاختبارات:
verify-exercises.
هذا هو الأسلوب الذي يتبعه مسار Unison.فأي أسلوب تختار؟ نوصي على الأقل بتنفيذ الأسلوب رقم 1، لجعل سكربت verify-exercises مستقلًا بذاته. إذا كانت صورتك كبيرة بشكل خاص، فقد يكون من المفيد تنفيذ الأسلوب 3 أيضًا، الذي يخزّن صورة Docker المبنية في ذاكرة التخزين المؤقت لـ GitHub Actions. بعدها يمكن للتشغيلات اللاحقة قراءة صورة Docker من ذاكرة التخزين المؤقت مباشرة بدلًا من تنزيلها، وقد يكون ذلك أفضل للأداء (قِس بنفسك للتأكد).
الخيار الثالث، وهو خيار بديل، مزيج من الخيارين السابقين. هنا أيضًا نستخدم صورة Docker الخاصة بمُشغّل الاختبارات، لكننا هذه المرة نشغّل سكربت verify-exercises داخل تلك الصورة. ولتمكين هذا الخيار، نحتاج إلى ضبط حاوية سير العمل على مُشغّل الاختبارات:
container:
image: exercism/vimscript-test-runner
ثم يمكننا تخطي خطوتي تثبيت التبعيات والأدوات (لأنها ستكون مثبّتة داخل صورة Docker الخاصة بمُشغّل الاختبارات) والمتابعة بتشغيل سكربت bin/verify-exercises file.
يستخدم سير العمل test.yml في مسار vimscript هذا الخيار:
name: Verify Exercises
on:
push:
branches: [main]
pull_request:
workflow_dispatch:
jobs:
ci:
runs-on: ubuntu-24.04
container:
image: exercism/vimscript-test-runner
steps:
- name: Checkout repository
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332
- name: Verify all exercises
run: bin/verify-exercises