GitLab CI: 6 ميزات من أحدث الإصدارات التي ننتظرها



في عصر CI / CD في كل مكان ، نواجه مجموعة واسعة من الأدوات ذات الصلة ، بما في ذلك أنظمة CI. ومع ذلك ، كان GitLab هو الأقرب بالنسبة لنا ، حقًا "مواطن". اكتسب شعبية ملحوظة في الصناعة ككل *. لم يتخلف مطورو المنتج عن الاهتمام المتزايد باستخدامه ، مما يسعد مجتمع المطورين ومهندسي DevOps بانتظام بإصدارات جديدة.


شهر مستودع GitLab وتجميع العلامات

GitLab هو الحال عندما يجلب التطوير النشط العديد من الميزات الجديدة والمثيرة للاهتمام. إذا كان هذا بالنسبة إلى المستخدمين المحتملين هو أحد عوامل اختيار الأداة ، بالنسبة للأدوات الموجودة ، فإن الوضع هو ما يلي: إذا لم تقم بتحديث تثبيت GitLab في الشهر الماضي ، فعندئذٍ مع احتمال كبير فاتك شيء مثير للاهتمام. بما في ذلك تحديثات الأمان الناشئة بانتظام.

حول الأكثر أهمية - على سبيل المثال مطلوب من قبل مهندسي DevOps وعملائنا - ابتكارات في أحدث إصدارات طبعة المجتمع من GitLab ، وسيتم مناقشة هذه المقالة.

* 5 , «GitLab», : «, GitHub?». — , Google Trends 5- «gitlab» . «» , . , , «» .

№1: needs


  • job'.
  • GitLab: 12.2.
  • .

الفكر dependencies- هذا ما تحتاجه؟ على الأرجح ، لم نكن الوحيدين الذين ارتكبوا خطأ تعيين هذا التوجيه ... هناك حاجة إلى سرد الوظائف السابقة ، والتي ستكون هناك حاجة إلى القطع الأثرية . إنها قطع أثرية ، وليس الاعتماد على أداء المهمة السابقة.

لنفترض أنه حدث في مرحلة واحدة وظائف ليست ضرورية لأداءها ، ولكن لسبب ما لا توجد إمكانية أو مجرد الرغبة في نقلهم إلى مرحلة منفصلة (الكسل هو محرك التقدم ، ولكن لا تنجرف).

الحالة:



كما ترى ، تحتوي مرحلة النشر على أزرار لطرح كل من الإنتاج والمرحلة واختبارات السيلينيوم الوظيفيةلسبب ما لم يتم تنفيذ. الأمر بسيط: إنه ينتظر حتى تكتمل جميع الوظائف من المرحلة السابقة بنجاح. ومع ذلك ، في إطار نفس خط الأنابيب ، لا نحتاج إلى نشر المرحلة الآن لتشغيل الاختبارات (تم ضخها في وقت سابق وليس ضمن العلامة). ماذا أفعل؟ ثم تعال إلى احتياجات الإنقاذ !

ندرج فقط الوظائف السابقة اللازمة لإجراء اختباراتنا:

  needs:
    - To production (Cluster 1)
    - To production (Cluster 2)

... ونحصل على وظيفة ، والتي يتم استدعاؤها تلقائيًا بعد تنفيذ المهام المدرجة فقط: بشكل



ملائم ، أليس كذلك؟ ولكن بمجرد أن توقعت أن التوجيه سيعمل على شيء مثل هذا dependencies...

رقم 2: يمتد



تعبت من قراءة القوائم .gitlab-ci.yaml؟ هل تفتقد مبدأ إعادة استخدام الرمز؟ ثم حاولت بالفعل وربما نجحت في إحضار دولتك .gitlab-ci.yamlإلى حالة مثل هذه:

.base_deploy: &base_deploy
  stage: deploy
  script:
    - my_deploy_command.sh
  variables:
    CLUSTER: "default-cluster"
    MY_VAR: "10"

Deploy Test:
  <<: *base_deploy
  environment:
    url: test.example.com
    name: test

Deploy Production:
  <<: *base_deploy
  environment:
    url: production.example.com
    name: production
  variables:
    CLUSTER: "prod-cluster"
    MY_VAR: "10"

يبدو عظيما؟ ومع ذلك ، إذا نظرت عن كثب ، هناك شيء يلفت انتباهك ... لماذا تغيرنا في الإنتاج ليس فقط variables.CLUSTER، ولكن أيضًا تم وصفه مرة أخرى variables.MY_VAR=10؟ هل يجب أخذ هذا المتغير من base_deploy؟ اتضح أنه لا ينبغي: YAML يعمل بحيث، إعادة ما تسلمه من مرساة، فإنه لا تعظيم وتنويع محتويات الحقول المطابقة، ولكن يحل محله . لذلك ، نحن مضطرون لسرد المتغيرات المعروفة لنا بالفعل في الفقرة المطابقة.

نعم ، "توسيع" هي الكلمة الصحيحة: هذا هو بالضبط ما يطلق عليه الميزة المعنية. Extendsإنها تسمح لنا ليس فقط بإعادة كتابة الحقل ، كما يحدث مع الارتساء ، ولكن لإجراء دمج ذكي له:

.base_deploy: 
  stage: deploy
  script:
    - my_deploy_command.sh
  variables:
    CLUSTER: "default-cluster"
    MY_VAR: "10"

Deploy Production:
  extends: .base_deploy
  environment:
    url: production.example.com
    name: production
  variables:
    CLUSTER: "prod-cluster"

هنا في المهمة النهائية نشر الإنتاج ، سيكون هناك متغير MY_VARبقيمة افتراضية وأخرى متجاوزة CLUSTER.

يبدو أن هذا تافه ، لكن تخيل: لديك base_deployدائرة واحدة و 20 دائرة منتشرة بشكل مشابه. يجب أن يتم تمريرها إلى الآخرين cluster، environment.nameمع الحفاظ على مجموعة معينة من المتغيرات أو الحقول المطابقة الأخرى ... سمحت لنا هذه المتعة الصغيرة بتقليل وصف نشر مجموعة دوائر التطوير بمقدار 2-3 مرات.

رقم 3: يشمل


  • نقسم YAML ضخمة إلى عدة وإعادة استخدامها في مشاريع أخرى.
  • تم تقديمه في Core منذ الإصدار 11.4.
  • docs.gitlab.com/ce/ci/yaml/#include

.gitlab-ci.yamlلا يزال يبدو وكأنه تعليمات قابلة للطي لمكنسة كهربائية بـ 20 لغة (لا تفهم منها سوى لغتك الأم) هل يكون من الصعب عندما تحتاج إلى التعامل مع أحد أقسامها دون تغيير في مواجهة الوظائف غير المعروفة التي تواجهها في الطريق؟

سوف يساعد صديق البرمجة منذ فترة طويلة include:

stages:
  - test
  - build
  - deploy

variables:
  VAR_FOR_ALL: 42

include:
  - local: .gitlab/ci/test.yml
  - local: .gitlab/ci/build.yml
  - local: .gitlab/ci/deploy-base.yml
  - local: .gitlab/ci/deploy-production.yml

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

ولكن ماذا لو كنا نعرف خط أنابيب مشاريعنا العشرين على طول وعبر ، فهل يمكننا شرح منطق كل وظيفة منها؟ كيف سيساعدنا ذلك؟ بالنسبة لأولئك الذين حققوا التنوير في إعادة استخدام التعليمات البرمجية ولجميع الذين لديهم العديد من المشاريع المماثلة ، يمكنك:


عشرات من نفس النوع من المشاريع برمز مختلف ، ولكن تم نشرها بنفس الطريقة - بسهولة ودون الحفاظ على أحدث CI في جميع المستودعات! تم إعطاء

مثال للاستخدام العملي includeأيضًا في هذه المقالة .

رقم 4: فقط / باستثناء المرجع


  • شروط شاملة ، بما في ذلك المتغيرات وتغييرات الملف.
  • نظرًا لأن هذه مجموعة كاملة من الوظائف ، فقد بدأت بعض الأجزاء في الظهور في GitLab 10.0 ، بينما بدأت أجزاء أخرى (على سبيل المثال changes) في الظهور في 11.4.
  • docs.gitlab.com/ce/ci/yaml/#onlyexcept-advanced

أحيانًا يبدو لي أن هذا ليس خط أنابيب يستمع إلينا ، لكننا نحن. تم دمج only/ except- أداة إدارة ممتازة الآن. ماذا يعني هذا؟

في أبسط الحالات (وربما الأكثر متعة) ، مراحل التخطي:

Tests:
  only:
    - master
  except:
    refs:
    - schedules
    - triggers
    variables:
    - $CI_COMMIT_MESSAGE =~ /skip tests/

في المهمة النموذجية ، يتم تشغيلها فقط على فرع رئيسي ، ولكن لا يمكن تشغيلها من خلال جدول أو مشغل (يشارك GitLab مكالمات ومشغلات واجهة برمجة التطبيقات ، على الرغم من أن هذا هو في الأساس نفس واجهة برمجة التطبيقات). لن يتم تنفيذ المهمة إذا كان هناك عبارة مرور تخطي الاختبارات في رسالة الالتزام . على سبيل المثال ، تم إصلاح خطأ مطبعي في README.mdالمشروع أو الوثائق - فلماذا تنتظر نتائج الاختبار؟

"مرحبًا ، 2020 بالخارج!" لماذا يجب أن أشرح للصندوق الحديدي في كل مرة أنه ليس من الضروري إجراء الاختبارات عند تغيير الوثائق؟ " وحقاً: only:changesيسمح لك بإجراء الاختبارات عند تغيير الملفات في دلائل معينة فقط. على سبيل المثال:

  only:
    refs:
      - master
      - merge_requests
    changes:
      - "front/**/*"
      - "jest.config.js"
      - "package.json"

وللعمل العكسي - أي لا تركض - نعم except:changes.

رقم 5: القواعد



هذا التوجيه مشابه جدًا للأوامر السابقة only:*، ولكن مع اختلاف مهم: فهو يسمح لك بالتحكم في المعلمة when. على سبيل المثال ، إذا كنت لا ترغب في إزالة إمكانية بدء وظيفة بالكامل. يمكنك ببساطة ترك الزر ، الذي سيتم استدعاؤه بشكل مستقل ، إذا رغبت في ذلك ، دون تشغيل خط أنابيب جديد أو دون التزام.

# 6: البيئة: auto_stop_in



لقد علمنا بهذه الفرصة قبل نشر المقال مباشرة ولم يكن لدينا الوقت الكافي لتجربتها عمليًا ، ولكن هذا بالتأكيد هو "نفس الشيء" الذي كان متوقعًا في العديد من المشاريع.

يمكنك تحديد معلمة في بيئات GitLab on_stop- وهي مفيدة جدًا عندما تريد إنشاء بيئات وحذفها ديناميكيًا ، على سبيل المثال ، لكل فرع. on_stopيتم تنفيذ المهمة المميزة بـ k ، على سبيل المثال ، عندما يكون دمج MR في الفرع الرئيسي أو عندما يتم إغلاق MR (أو حتى ببساطة عن طريق النقر على الزر) ، حيث يتم حذف البيئة غير الضرورية تلقائيًا.

كل شيء مناسب ومنطقي ويعمل ... إن لم يكن للعامل البشري. يقوم العديد من المطورين بدمج MR ليس بالنقر على زر في GitLab ، ولكن محليًا عبر git merge. يمكنك فهمها: إنها مريحة! ولكن في هذه الحالة ، المنطقon_stopلا يعمل ، لقد تراكمت لدينا محيطات منسية ... هذا هو المكان الذي يكون فيه الذي طال انتظاره في متناول اليد auto_stop_in.

المكافأة: أكواخ مؤقتة عندما لا تكون هناك فرص كافية


على الرغم من كل هذه الوظائف (وغيرها الكثير) ، الوظائف الجديدة والمطلوبة لـ GitLab ، لسوء الحظ ، في بعض الأحيان يكون من المستحيل وصف شروط إنجاز الوظيفة في إطار القدرات المتاحة حاليًا.

إن GitLab ليس مثاليًا ، ولكنه يوفر الأدوات الأساسية لبناء خط أنابيب أحلام ... إذا كنت على استعداد لتجاوز DSL المتواضع ، والانغماس في عالم البرمجة النصية. فيما يلي بعض الحلول من تجربتنا ، والتي لا تدعي بأي حال من الأحوال أنها صحيحة أو موصى بها من الناحية الإيديولوجية ، ولكن يتم تقديم المزيد لإثبات الاحتمالات المختلفة مع الافتقار إلى وظائف API المضمنة.

الحل رقم 1: إطلاق وظيفتين باستخدام زر واحد


script:
  - > 
    export CI_PROD_CL1_JOB_ID=`curl -s -H "PRIVATE-TOKEN: ${GITLAB_API_TOKEN}" \ 
      "https://gitlab.domain/api/v4/projects/${CI_PROJECT_ID}/pipelines/${CI_PIPELINE_ID}/jobs" | \
      jq '[.[] | select(.name == "Deploy (Cluster 1)")][0] | .id'`
  - > 
    export CI_PROD_CL2_JOB_ID=`curl -s -H "PRIVATE-TOKEN: ${GITLAB_API_TOKEN}" \ 
      "https://gitlab.domain/api/v4/projects/${CI_PROJECT_ID}/pipelines/${CI_PIPELINE_ID}/jobs" | \
      jq '[.[] | select(.name == "Deploy (Cluster 2)")][0] | .id'`
  - > 
    curl -s --request POST -H "PRIVATE-TOKEN: ${GITLAB_API_TOKEN}" \ 
      "https://gitlab.domain/api/v4/projects/${CI_PROJECT_ID}/jobs/$CI_PROD_CL1_JOB_ID/play"
  - > 
    curl -s --request POST -H "PRIVATE-TOKEN: ${GITLAB_API_TOKEN}" \ 
      "https://gitlab.domain/api/v4/projects/${CI_PROJECT_ID}/jobs/$CI_PROD_CL2_JOB_ID/play"

ولماذا لا ، إذا كنت تريد ذلك حقًا؟

الحل رقم 2: تم تغيير النقل في ملفات MR rb لـ rubocop داخل الصورة


Rubocop:
  stage: test
  allow_failure: false
  script:
    ...
    - export VARFILE=$(mktemp)
    - export MASTERCOMMIT=$(git merge-base origin/master HEAD)
    - echo -ne 'CHANGED_FILES=' > ${VARFILE}
    - if [ $(git --no-pager diff --name-only ${MASTERCOMMIT} | grep '.rb$' | wc -w |awk '{print $1}') -gt 0 ]; then
        git --no-pager diff --name-only ${MASTERCOMMIT} | grep '.rb$' |tr '\n' ' ' >> ${VARFILE} ;
      fi
    - if [ $(wc -w ${VARFILE} | awk '{print $1}') -gt 1 ]; then
        werf --stages-storage :local run rails-dev --docker-options="--rm --user app --env-file=${VARFILE}" -- bash -c /scripts/rubocop.sh ;
      fi
    - rm ${VARFILE}

لا توجد صورة بالداخل .git، لذلك كان علي الخروج للتحقق من الملفات التي تم تغييرها فقط.

ملاحظة: هذه ليست حالة قياسية جدًا ومحاولة يائسة للامتثال للعديد من شروط المشكلة ، والتي لم يتم تضمين وصفها في نطاق هذه المقالة.

الحل # 3: بدء تشغيل المهام من مستودعات أخرى عند طرحها


  before_script:
    - |
      echo '### Trigger review: infra'
      curl -s -X POST \
        -F "token=$REVIEW_TOKEN_INFRA" \
        -F "ref=master" \
        -F "variables[REVIEW_NS]=$CI_ENVIRONMENT_SLUG" \
        -F "variables[ACTION]=auto_review_start" \
        https://gitlab.example.com/api/v4/projects/${INFRA_PROJECT_ID}/trigger/pipeline

يبدو أن مثل هذا الشيء البسيط والضروري (في عالم الخدمات الدقيقة) يطرح خدمة صغيرة أخرى في دائرة حديثة الإنشاء كاعتماد. ولكن ، ليس هذا مطلوبًا إجراء مكالمة API وميزة مألوفة بالفعل (الموضحة أعلاه):

  only:
    refs:
    - triggers
    variables:
    - $ACTION == "auto_review_start"

ملاحظات:

  • تم تصميم الوظيفة عند التشغيل لتكون مرتبطة بتمرير متغير إلى واجهة برمجة التطبيقات ، على غرار المثال رقم 1. من المنطقي أكثر تنفيذ ذلك على API مع تمرير اسم المهمة.
  • نعم ، الوظيفة موجودة في الإصدار التجاري (EE) من GitLab ، لكننا لا نعتبرها.

استنتاج


يحاول GitLab مواكبة الاتجاهات ، ويطبق تدريجياً ميزات ممتعة ومطلوبة من قبل مجتمع DevOps. إنها سهلة الاستخدام للغاية ، وعندما لا تكون القدرات الأساسية كافية ، يمكن دائمًا توسيعها باستخدام النصوص البرمجية. وإذا رأينا أنه لم يتبين بشكل أنيق ومريح في الدعم ... يبقى انتظار الإصدارات الجديدة من GitLab - أو لمساعدة المشروع بمساهمتنا .

ملاحظة


اقرأ أيضا في مدونتنا:


All Articles