يُعَد إعداد تطبيقات الويب لعمليتيْ التكامل المستمر Continuous Integration والنشر المستمر Continuous Deployment مرحلةً بالغة الأهمية في مجال التطوير، ويُرمَز لها اختصارًا بـ CI/CD، فقد تتعرض جميع المشاريع البرمجية للأخطاء مهما كانت أحجامها وخاصةً عندما يجتمع الفريق البرمجي ليَعمَل على مشروعٍ واحدٍ، إذ يَسُهل إيجاد وإصلاح هذه الأخطاء إذا كان هناك تكاملٌ وإعدادٌ دائمٌ لنشر التطبيقات بصورةٍ مستمرةٍ وذلك باستخدام اختباراتٍ مُحكمَة الإعداد.
سنتعرّف في هذا المقال على كيفية التحقق من تغطية الاختبار test coverage، كما سنُعِدّ تطبيقات الويب لعمليتيْ التكامل المستمر والنشر المستمرة CI/CD، وذلك باستخدام CircleCI وCoveralls، وسنتطرق كذلك إلى كيفية نَشْر تطبيق Vue فيو جي إس على منصة هيروكو Heroku، ستستفيد من هذا المقال حتى إذا كنت مِمن لا يُفضّل هذا الخليط من الأدوات، حيث يمكنك أن تَستخدِم إطار عملٍ مختلفٍ عن فيو جي إس مثلًا لكتابة جافاسكربت، إذ ستبقى المبادئ الأساسية هي ذاتها.
وقبل ذلك إليك بعض المصطلحات.
- التكامل المستمر Continuous integration: وفيها يُثبّت commit المُطوّرون الكود الذي يكتبونه مُبكرًا وبصورةٍ مستمرةٍ، مما يتيح إمكانية تطبيق اختباراتٍ وعمليات بناءٍ عديدةٍ قَبل الدمج أو النشر.
- النشر المستمر Continuous deployment: وفيه يَحرِص المُطوّرون على أن تَقبَل البرمجية النشْر في كل الأوقات.
- تغطية الاختبار Test Coverage: وهو مقياسٌ يَصِف درجة اختبار البرمجية، حيث يُشير مصطلح البرمجية ذات التغطية العالية إلى أن غالبية كود هذه البرمجية يَخضَع للاختبار.
ولتحقيق أقصى استفادةٍ من هذا البرنامج التعليمي يُستحسَن أن يكون لديك ما يلي:
- حساب في منصة CircleCI: وهي منصةٌ للتكامل المستمر والنشر المستمر CI/CD، وسنستفيد منها في برنامجنا التعليمي عن طريق استخدامها للنّشْر الآلي الذي يتضمن اختبار وبناء التطبيق قَبل النّشْر.
- حساب في موقع غيت هاب Github: وهو الموقع الذي سنُخزّن في مُستودَعٍ repository فيه كود المشروع واختباراته.
- حساب في منصة هيروكو Heroku: وهي منصةٌ خاصةٌ بنشر وتوسيع نطاق التطبيقات، وسنستخدمه من أجل نَشْر واستضافة hosting التطبيق.
- حساب في منصة Coveralls: وسنستخدم هذه المنصة لإظهار وتسجيل درجة وكفاءة تغطية الكود code coverage.
- حزمة NYC: وسنستخدم هذه الحزمة لنتحقق من خضوع الكود للتغطية بصورةٍ جيدةٍ.
اقتباسملاحظة: يتَوفّر المُستودَع repository الذي يحتوي على المثال الموجود في هذا المقال على غيت هاب.
سنجهز الآن ما يلزمنا للعمل
سنبدأ بتثبيت حِزمة NYC في مُجلد المشروع، هكذا:
npm i nyc
بعدها سنُعدّل نصوص ملف package.json
البرمجية لنتحقق من تغطية الاختبار، وإذا كنا سنتحقق من التغطية أثناء إجراء اختبارات الوِحدة unit tests، فسيتوجّب علينا تعديل النَّص البرمجي للاختبار، كما يأتي:
"scripts": { "test:unit": "nyc vue-cli-service test:unit", },
لقد بُنَي الأمر السابق command على افتراض أننا سنبرمج تطبيق الويب باستخدام إطار عمل فيو Vue، إذ تُشير الخدمة vue-cli-service
إليه، ولذلك إذا كنا سنستخدم إطار عملٍ آخرٍ في المشروع، فسيتعيّن علينا تغيير هذا الأمر؛ أما إذا كنا سنتحقق من التغطية بصورةٍ منفصلةٍ، فحينها سيتوجّب علينا إضافة سطرٍ آخرٍ إلى النصوص البرمجية، كما يلي:
"scripts": { "test:unit": "nyc vue-cli-service test:unit", "coverage": "nyc npm run test:unit" },
وبعدها يمكننا التحقق من التغطية باستخدام أمر npm run coverage
المُضّمن في واجهة سطر الأوامر terminal كالآتي:
npm run coverage
ثم سنُثبّت خدمة Coveralls، فهي مسؤولةٌ عن إيجاد وإظهار التغطية، هكذا:
npm i coveralls
وبعد ذلك سنضيف خدمة Coveralls
مثل نَّصٍ برمجيٍ في ملف package.json
، حيث سيساعدنا هذا النَّص على حفظ تقرير تغطية الاختبار في Coveralls:
"scripts": { "test:unit": "nyc vue-cli-service test:unit", "coverage": "nyc npm run test:unit", "coveralls": "nyc report --reporter=text-lcov | coveralls" },
كما سنستخدم هيروكو Heroku لاستضافة تطبيقنا، ولذلك سننتقل إلى لوحة إعداد dashboard هيروكو لنُسجّل التطبيق.
وسنستخدم منصة CircleCI لأتمتة عمليتيْ التكامل المستمر والنشر المستمر CI/CD، ولذلك سننتقل إلى لوحة إعداد CircleCI لنُهيّئ مشروعنا.
ويمكننا استعراض قائمة مشاريعنا في غيت هاب بالانتقال إلى تبويب Projects في الشريط الجانبي لمنصة CircleCI، فبالنَّقر فوق زِرّ (أيقونة) Set Up Project أو إعداد المشروع، ستظهر صفحةٌ جديدةٌ تسألك عن ما إذا كنت تريد استخدام التهيئة config الموجودة مسبقًا أم لا، وبما أننا نمتلك تهيئةً مُعدّةً مسبقًا، فسنختار use an existing config أو استخدام تهيئةٍ موجودةٍ مسبقًا، وبعدها سننتقل إلى تبويب pipeline الخاص بالمشروع،
بهذا نكون قد انتهينا من إعداد الاتصال بين مستودع repository غيت هاب ومنصة CircleCI، حيث حان دور إضافة متغيّرات البيئة إلى مشروع CircleCI.
ولإضافة متغيراتٍ جديدةٍ، يجب علينا الانتقال إلى إعدادات المشروع، هكذا.
ستجد في الشريط الجانبي في إعدادات المشروع تبويب Environment Variables أو متغيّرات البيئة، وهو مكان تخزين المتغيّرات التي سنضيفها.
والمتغيّرات التي سنحتاجها في هذا البرنامج التعليمي هي:
- HEROKU_APP_NAME: اسم تطبيق هيروكو.
- HEROKU_API_KEY: مفتاح واجهة التطبيقات البرمجية API لمنصة هيروكو Heroku.
- COVERALLS_REPO_TOKEN: مفتاحٌ مساعدٌ token لمستودع Coveralls.
ويمكننا إيجاد مفتاح واجهة التطبيقات البرمجية API لمنصة هيروكو Heroku في قسم account الموجود في لوحة إعداد هيروكو.
ويوجد المفتاح المساعد token للمستودع repository في حساب Coveralls، ولذلك سنضيف المستودع إلى Coveralls أولًا، وهنا سنختار مستودع غيت هاب المناسب من قائمة المستودعات المتوفرة، كما هو موضح بالصورة الآتية.
والآن بعد أن أضفنا المستودع إلى Coveralls، يمكننا النقر على المستودع لجَلْب المفتاح المُساعد token.
دمج CircleCI
بعد أن أنهينا ربط CircleCI مع مستودع غيت هاب، فسيُبَلّغ CircleCI عند حدوث تغيير ٍأو إجراءٍ في مستودع غيت هاب، وسنتّبع الآن الخطوات المناسبة لإبلاغ CircleCI بالعمليات التي نريد تنفيذها بعد حدوث تغييرٍ في المستودع، بعد ذلكسننشئ مجلدًا باسم circleci
في مجلد الجذر root لمشروعنا المحلي، وسنضع فيه ملفًا باسم config.yml
وهو الملف الذي سيحتوي على كلّ عمليات CircleCI.
وإليك الشيفرة البرمجية التي سنضعها في الملف:
version: 2.1 orbs: node: circleci/node@1.1 // node orb heroku: circleci/heroku@0.0.10 // heroku orb coveralls: coveralls/coveralls@1.0.6 // coveralls orb workflows: heroku_deploy: jobs: - build - heroku/deploy-via-git: # Use the pre-configured job requires: - build filters: branches: only: master jobs: build: docker: - image: circleci/node:10.16.0 steps: - checkout - restore_cache: key: dependency-cache-{{ checksum "package.json" }} - run: name: install-npm-dependencies command: npm install - save_cache: key: dependency-cache-{{ checksum "package.json" }} paths: - ./node_modules - run: # run tests name: test command: npm run test:unit - run: # run code coverage report name: code-coverage command: npm run coveralls - run: # run build name: Build command: npm run build # - coveralls/upload
كما تلاحظ؛ تُعَد هذه الشيفرة البرمجية كبيرة ولذلك سنقسمها إلى أجزاءٍ لنشرح كلّ جزءٍ على حدةٍ.
حزم Orbs
orbs: node: circleci/node@1.1 // node orb heroku: circleci/heroku@0.0.10 // heroku orb coveralls: coveralls/coveralls@1.0.6 // coveralls orb
تُعَد Orbs حِزمًا مفتوحة المصدر، فهي تُستَخدم لتبسيط تكامل البرامج والحِزم في المشاريع، وقد سبق وأشرنا في الكود الخاص بنا إلى حِزم orbs التي نستخدمها في عمليتيْ التكامل المستمر والنشر المستمر CI/CD، وإلى حِزمة orbs التي تَحمِل الاسم node
وذلك لأننا نستخدم جافاسكربت، وإلى هيروكو Heroku لأننا نُنفّذ النشر المؤتمت باستخدام سيْر عمل workflow من هيروكو، وأيضًا إلى حِزمة coveralls
من orbs لأننا نُخَطّط لإرسال نتائج تغطية الاختبار إلى Coveralls.
تُعَد حزمتيْ Heroku
وCoveralls
من orbs حزمًا خارجيةً، فعند تشغيل التطبيق عن طريق الاختبار، فسيؤدي ذلك إلى حدوث خطأ يمكننا التخلص منه بالانتقال إلى صفحة Organization Settings في حساب CircleCI.
بعد ذلك سننتقل إلى تبويب Security أو الأمان، بحيث نُفعّل حِزم orbs غير المعتمدة.
سير العمل Workflow
workflows: heroku_deploy: jobs: - build - heroku/deploy-via-git: # Use the pre-configured job requires: - build filters: branches: only: master
يُستخدم سير العمل لتحديد مجموعةٍ من الوظائف ثم تشغيلها بالترتيب، وهذا القِسم من الكود مسؤول عن الاستضافة المؤتمتة، فهو يوعز إلى CircleCI ببناء المشروع ثم نشره، حيث تشير requires
إلى أن وظيفة heroku/deploy-via-git
تتطلب اكتمال البناء، مما يعني أن عملية النشر لن تَحصُل قبل اكتمال البناء.
الوظائف Jobs
jobs: build: docker: - image: circleci/node:10.16.0 steps: - checkout - restore_cache: key: dependency-cache-{{ checksum "package.json" }} - run: name: install-npm-dependencies command: npm install - save_cache: key: dependency-cache-{{ checksum "package.json" }} paths: - ./node_modules
تُعَبر الوظيفة job عن مجموعةٍ من الخطوات، حيث سنستعيد في هذا القِسم من الكود التبعيات dependencies التي ثُبّتت أثناء عمليات البناء السابقة للمشروع وذلك من خلال الوظيفة restore_cache
أو استعادة الذاكرة المؤقتة، ثم سنُثبّت التبعيات غير المخبّأة uncached dependencies، وسنحفظها كي لا نُعيد تثبيتها أثناء عملية البناء التالية. بعد ذلك سنطلب من CircleCI إجراء الاختبارات التي كتبناها للمشروع، بالإضافة إلى التحقق من التغطية الاختبارية للمشروع.
اقتباسلاحظ أن إجراء عملية تخبئة caching على التبعيات dependencies تجعل عمليات البناء اللاحقة أسرع، وذلك لأننا نُخزّن التبعيات، وبالتالي لا حاجة لإعادة تثبيت تلك التبعيات أثناء عملية البناء التالية.
رفع تغطية الكود الخاص بنا إلى منصة coveralls
- run: # run tests name: test command: npm run test:unit - run: # run code coverage report name: code-coverage command: npm run coveralls # - coveralls/upload
وستظهر قدرات coveralls بصورةٍ جليةٍ، بوصلنا إلى مكان إجراء اختبارات الوِحدة تَذكّر أننا أضفنا الأمر nyc
إلى النص البرمجي الذي يُسمّى test:unit
إلى ملف package.json
، حيث ستَوفّر اختبارات الوِحدة تغطيةً الكود بفضل هذا الأمر.
اقتباستوفر اختبارات الوحدة تغطية للكود أيضًا، لذلك سنضمنها في تقرير التغطية، ما يفسّر سبب استدعائنا للأمر هنا.
في النهاية، سيُشغّل الكود النَّص البرمجي الذي يُسمّى Coveralls والذي سبق وأضفناه إلى ملف package.json
، حيث سيتولى هذا النَّص مَهمّة إرسال تقرير التغطية الخاص بنا إلى coveralls، ولعلك لاحظت عدم خضوع السطر coveralls/upload
للتنفيذ (تعليق comment)، إذ كان من المفترض أن يكون السطر النهائي في العملية، ولكنه أصبح في النهاية مُعوّقًا كما يقول المطورون، وأوقفته عن التنفيذ بتعليقه (تعليق comment)، ولم أحذفه لأنه قد يكون ورقةً رابحةً لمطورٍ آخرٍ.
تجهيز الأمور ودمجها سوية
إليك تطبيقنا الجاهز بعد تطبيق كلّ من التكامل المستمر والنشر المستمر
حيث تظهر فائدة التكامل والنشر المستمر في كثيرٍ من الحالات، ومن الأمثلة الشائعة لها؛ الحالة التي تكون فيها البرمجيّة في طور الاختبار، ففي هذه المرحلة تَحدُث الكثير من عمليات التصحيح على الكود، مما يؤدي إلى عمليات تثبيتٍ commit كثيرةٍ للكود البرمجي، ولنكون واقعيين، ,ولتفادي التكرار، فلا نودّ تشغيل الاختبارات ونشر التطبيق بصورةٍ يدويةٍ بعد كلّ تغييرٍ طفيفٍ يحدث.
في الواقع، لقد كنا على درايةٍ بالتكامل المستمر والنشر المستمر CI/CD منذ فترةٍ طويلةٍ نسبيًا، ومع ذلك تجاهلنا هاتين العمليتين لأن الأمر كان يبدو صعبًا للغاية أو قد يستغرق وقتًا طويلاً، ولكن الآن بعد أن رأيت مدى سهولة الإعداد والفوائد التي تنتج عنهما، فيمكنك تُجرّبهما في مشروعك القادم.
ترجمة -وبتصرف- للمقال A Continuous Integration and Deployment Setup with CircleCI and Coveralls من موقع CSS Tricks.
أفضل التعليقات
لا توجد أية تعليقات بعد
انضم إلى النقاش
يمكنك أن تنشر الآن وتسجل لاحقًا. إذا كان لديك حساب، فسجل الدخول الآن لتنشر باسم حسابك.