اذهب إلى المحتوى

يُعَد إعداد تطبيقات الويب لعمليتيْ التكامل المستمر 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 هيروكو لنُسجّل التطبيق.

cavv1CkE.png

وسنستخدم منصة CircleCI لأتمتة عمليتيْ التكامل المستمر والنشر المستمر CI/CD، ولذلك سننتقل إلى لوحة إعداد CircleCI لنُهيّئ مشروعنا.

GFXZcxtC.png

ويمكننا استعراض قائمة مشاريعنا في غيت هاب بالانتقال إلى تبويب Projects في الشريط الجانبي لمنصة CircleCI، فبالنَّقر فوق زِرّ (أيقونة) Set Up Project أو إعداد المشروع، ستظهر صفحةٌ جديدةٌ تسألك عن ما إذا كنت تريد استخدام التهيئة config الموجودة مسبقًا أم لا، وبما أننا نمتلك تهيئةً مُعدّةً مسبقًا، فسنختار use an existing config أو استخدام تهيئةٍ موجودةٍ مسبقًا، وبعدها سننتقل إلى تبويب pipeline الخاص بالمشروع،

بهذا نكون قد انتهينا من إعداد الاتصال بين مستودع repository غيت هاب ومنصة CircleCI، حيث حان دور إضافة متغيّرات البيئة إلى مشروع CircleCI.

MrClw8k4.png

ولإضافة متغيراتٍ جديدةٍ، يجب علينا الانتقال إلى إعدادات المشروع، هكذا.

ywfpjoFc.png

ستجد في الشريط الجانبي في إعدادات المشروع تبويب Environment Variables أو متغيّرات البيئة، وهو مكان تخزين المتغيّرات التي سنضيفها.

maHAQR6Q.png

والمتغيّرات التي سنحتاجها في هذا البرنامج التعليمي هي:

  • HEROKU_APP_NAME: اسم تطبيق هيروكو.
  • HEROKU_API_KEY: مفتاح واجهة التطبيقات البرمجية API لمنصة هيروكو Heroku.
  • COVERALLS_REPO_TOKEN: مفتاحٌ مساعدٌ token لمستودع Coveralls.

ويمكننا إيجاد مفتاح واجهة التطبيقات البرمجية API لمنصة هيروكو Heroku في قسم account الموجود في لوحة إعداد هيروكو.

iDzf6rqg.png

ويوجد المفتاح المساعد token للمستودع repository في حساب Coveralls، ولذلك سنضيف المستودع إلى Coveralls أولًا، وهنا سنختار مستودع غيت هاب المناسب من قائمة المستودعات المتوفرة، كما هو موضح بالصورة الآتية.

cjnAMj6I.png

والآن بعد أن أضفنا المستودع إلى Coveralls، يمكننا النقر على المستودع لجَلْب المفتاح المُساعد token.

ug_Ux80t.png

دمج CircleCI

بعد أن أنهينا ربط CircleCI مع مستودع غيت هاب، فسيُبَلّغ CircleCI عند حدوث تغيير ٍأو إجراءٍ في مستودع غيت هاب، وسنتّبع الآن الخطوات المناسبة لإبلاغ CircleCI بالعمليات التي نريد تنفيذها بعد حدوث تغييرٍ في المستودع، بعد ذلكسننشئ مجلدًا باسم circleci في مجلد الجذر root لمشروعنا المحلي، وسنضع فيه ملفًا باسم config.yml وهو الملف الذي سيحتوي على كلّ عمليات CircleCI.

cGszd9c8.png

وإليك الشيفرة البرمجية التي سنضعها في الملف:

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.

5iSnVvuP.png

بعد ذلك سننتقل إلى تبويب Security أو الأمان، بحيث نُفعّل حِزم orbs غير المعتمدة.

k1HYPT9c.png

سير العمل 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)، ولم أحذفه لأنه قد يكون ورقةً رابحةً لمطورٍ آخرٍ.

تجهيز الأمور ودمجها سوية

إليك تطبيقنا الجاهز بعد تطبيق كلّ من التكامل المستمر والنشر المستمر

passimage.png

حيث تظهر فائدة التكامل والنشر المستمر في كثيرٍ من الحالات، ومن الأمثلة الشائعة لها؛ الحالة التي تكون فيها البرمجيّة في طور الاختبار، ففي هذه المرحلة تَحدُث الكثير من عمليات التصحيح على الكود، مما يؤدي إلى عمليات تثبيتٍ commit كثيرةٍ للكود البرمجي، ولنكون واقعيين، ,ولتفادي التكرار، فلا نودّ تشغيل الاختبارات ونشر التطبيق بصورةٍ يدويةٍ بعد كلّ تغييرٍ طفيفٍ يحدث.

في الواقع، لقد كنا على درايةٍ بالتكامل المستمر والنشر المستمر CI/CD منذ فترةٍ طويلةٍ نسبيًا، ومع ذلك تجاهلنا هاتين العمليتين لأن الأمر كان يبدو صعبًا للغاية أو قد يستغرق وقتًا طويلاً، ولكن الآن بعد أن رأيت مدى سهولة الإعداد والفوائد التي تنتج عنهما، فيمكنك تُجرّبهما في مشروعك القادم.

ترجمة -وبتصرف- للمقال A Continuous Integration and Deployment Setup with CircleCI and Coveralls من موقع CSS Tricks.

اقرأ أيضًا


تفاعل الأعضاء

أفضل التعليقات

لا توجد أية تعليقات بعد



انضم إلى النقاش

يمكنك أن تنشر الآن وتسجل لاحقًا. إذا كان لديك حساب، فسجل الدخول الآن لتنشر باسم حسابك.

زائر
أضف تعليق

×   لقد أضفت محتوى بخط أو تنسيق مختلف.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   جرى استعادة المحتوى السابق..   امسح المحرر

×   You cannot paste images directly. Upload or insert images from URL.


×
×
  • أضف...