見出し画像

includeキーワードを使用して.gitlab-ci.ymlの共通モジュールプロジェクトを作成する


はじめに


こんにちは。SHIFTテスト自動化アーキテクトの牧野です。
最近は風来人となり石を運びました。

最近はもう一つ、Gitlab CI/CDにてYamlファイルを共通プロジェクトの形でモジュール化する方法を探ったので、その成果を紹介します。

目標は .gitlab-ci.yml の省力化および共通化


gitlab-ciの構築において、yaml構文ではincludeキーワードを使用して他のyamlファイルを利用することができます。

これは、C言語のincludeと似た挙動を示します。つまり、指定したyamlファイルの内容が指定元のyamlファイルにコピーされるというものです。変数の値は展開されず、変数定義がコピーされてから評価されます。

この機能を利用すると、.gitlab-ci.ymlの記述を共通化するためのユーティリティプロジェクトを作成し、それを利用して省力化および共通化することができます。

今回はこの手法を利用して、よく使うテスト実行などのyamlパターンを自作テンプレートプロジェクトに保存し、それをincludeすることでCI/CDにてテストやレポート機能を実現します。

参考資料


GitLabドキュメント - include

具体的な実装内容


  • テストの実行

  • テスト結果をgitlabのtestタブに表示

  • テストレポート(Allure Report)の生成

  • テスト結果の保存と履歴の管理

また、ユーティリティプロジェクトを参照する側では以下も行います

  • テスト実行部分の上書きによるカスタマイズ

今回はnpmを用いて各種ツールのインストールなどを行い、PlaywrightのGUIテストを実行し、Allure ReportにてGitlabに表示する例を紹介いたします。

始めに具体的なYamlファイルを紹介し、ユーティリティプロジェクトを作成するときに検討すべきことを説明いたします。

ユーティリティを参照する側のYAML作成例


ユーティリティプロジェクトを利用する側のYamlはとてもシンプルにする事が出来ます。

include:
  - project: 'MyGroup/gitlab-ci-utility'
    file: 'playwright.test.yml'

ユーティリティプロジェクトを作成していれば、この記述だけで具体的な実装内容に上げた項目を達成することができてしまいます。

ユーティリティプロジェクトのYAML作成例


ユーティリティプロジェクトでは具体的な実装内容にあげた機能を全て実現するためのYamlファイルを、今回はplaywright.test.ymlとして作成します。

stages:
  - test
  - allure
  - deploy

.download_history:
  after_script:
    - apt-get update
    - apt-get upgrade -y
    - apt-get install -y unzip
    - mkdir backup && cd backup || true
    - "curl --location --output report.zip --request GET \"https://gitlab.com/api/v4/projects/${CI_PROJECT_ID}/jobs/artifacts/main/download?job=pages\" --header \"Authorization: Bearer ${CI_DEPLOY_TOKEN}\" || true"
    - (unzip report.zip) || true
    - cd ../
    - (cp -r backup/public/history/ allure-results/history) || true

.test_template:
  allow_failure: true
  stage: test
  image: mcr.microsoft.com/playwright:v1.41.2-jammy
  script:
    - npm install @playwright/test
    - npx playwright test
  artifacts:
    when: always
    paths:
      - allure-results/
    reports:
      junit: results.xml

smoke:
  extends:
    - .download_history
    - .test_template

allure_report:
  stage: allure
  when: always
  image: timbru31/java-node
  dependencies:
    - smoke
  script:
    - npm install
    - npx allure generate
  artifacts:
    when: always
    paths:
      - allure-report/
      - allure-results/
  only:
    - main
 
pages:
  stage: deploy
  when: always
  dependencies:
    - allure_report
  script:
    - mv allure-report/ public/
  artifacts:
    paths:
      - public
    expire_in: 30 days
  only:
    - main

今回は詳細は割愛させていただきますが、各機能と実現するセクションは以下の対応になっています。

  • テストの実行

    • smoke

      • .test_templateとして分割

  • テスト結果をgitlabのtestタブに表示

    • smoke

      • .test_templateとして分割

  • テストレポート(Allure Report)の生成

    • allure_report

    • pages

  • テスト結果の保存と履歴の管理

    • smoke

      • .download_historyとして分割

可読性や後の扱いやすさのため、一部はextendsキーワードを利用して記述を分割しています。これはGitLabのために調整されたYamlアンカーのようなものです。詳細を知りたい方は以下のドキュメントをご参照ください。

GitLabドキュメント - extendsキーワードを使用して構成セクションを再利用する

ユーティリティを参照する側の検討事項


各includeファイルの内容を把握する

個別のプロジェクトでincludeを使用する際には、すべてのincludeファイルの内容を把握しておく必要があります。includeは重複する定義がある場合は後で定義されたものが優先されます。そのため、どのファイルで何が定義されているかを把握しておくことが重要です。

include内容の上書きによるカスタマイズ

個別のプロジェクトでincludeしたファイルの設定を上書きする場合は、同じキーを持つ項目を新たに定義します。これにより、プロジェクトごとに設定をカスタマイズすることができます。

たとえば、以下の例ではユーティリティプロジェクトのYAML作成例の節で上げたYamlの内容をベースにsmoke(.test_template)のscript部分の上書きを行い、テスト実行部分をカスタマイズする事が出来ます。

今回は、テスト実行前後にメッセージ("override this!", "great!")を出力するようにカスタマイズする例を紹介します。

カスタマイズYaml例

smoke:
  script:
    - echo "override this!"
    - npm install @playwright/test
    - npx playwright test
    - echo "great!"

CI出力

$ echo "override this!"
override this!
$ npm install @playwright/test
added 9 packages, and audited 10 packages in 2s
found 0 vulnerabilities
$ npx playwright test
Running 6 tests using 1 worker
······
  6 passed (9.8s)
$ echo "great!"
great!

「完全な設定」タブを参考にする

上書きによるカスタマイズは便利ですが、どのセクションのどの部分を上書きしなければいけないのか、今のカスタマイズ結果はどのようになっているか把握が難しいです。

GitLabではパイプラインエディタの「完全な設定」タブにて、現在カスタマイズしているYamlのプレビューを見ることが出来ます。

たとえば、先のカスタマイズを行っている時は以下のようなプレビューが行われます。(一部抜粋)

smoke:
  after_script:
    - apt-get update
    - apt-get upgrade -y
    - apt-get install -y unzip
    - mkdir backup && cd backup || true
    - 'curl --location --output report.zip --request GET "https://gitlab.com/api/v4/projects/${CI_PROJECT_ID}/jobs/artifacts/main/download?job=pages"
    --header "Authorization: Bearer ${CI_DEPLOY_TOKEN}" || true'
    - "(unzip report.zip) || true"
    - cd ../
    - "(cp -r backup/public/history/ allure-results/history) || true"
  allow_failure: true
  stage: test
  image: mcr.microsoft.com/playwright:v1.41.2-jammy
  script:
    - echo "override this!"
    - npm install @playwright/test
    - npx playwright test
    - echo "great!"

「完全な設定」タブはパイプラインエディタ画面の「編集」タブなどと同列に、以下の画像のように配置されています。

ユーティリティプロジェクトの設計事項


include方法の検討

ユーティリティプロジェクトを利用してもらう際、includeキーワードに記述する必要がある情報を決定する必要があります。

以下のドキュメント参考に、ベストなincude方法を検討し、そのために決定・公開する内容を検討します。

GitLabドキュメント - include

多くの場合はinclude:projectが適しているでしょう。

この方法は社内など自身の所属するグループに公開する際に適しており、同じ GitLab インスタンス上の別のプロジェクトへ公開ができます。

公開の際に検討・周知すべき情報は以下の通りです。

  • project: プロジェクト名そのままになります。公開後は安易にプロジェクト名を変更できないと把握することが重要です。

  • file: 公開するファイルのプロジェクトルートからのパスとなります。こちらも安易に変更できないと把握することが重要です。

  • ref: ファイルを取得するブランチ等を指定します。オプションであり、省略した場合はHEAD(多くの場合mainブランチ)が利用されます。

改めてincludeを行う側の記述例を紹介します。

本書までの内容を踏まえてご確認ください。

include:
  - project: 'MyGroup/gitlab-ci-utility'
    file: 'playwright.test.yml'

詳細は以下のドキュメントをご覧ください。 GitLabドキュメント - include:project

注意点


ジョブの再実行時、include対象は再取得されず、パイプライン再実行の際は再取得する

ジョブ単位での再実行の場合、includeされたファイルは再取得されませんが、パイプラインの場合は再取得されます。つまり、include先の変更を反映させるには、パイプラインから再実行する必要があります。

終わりに


GitLab CI/CDのキーとなる .gitlab-ci.yml を複数プロジェクトで共通化する方法を実践しました。

CI/CDはプロジェクト構築の際に1から作り直すことが多く、既存資産を再利用しにくく重複が発生したり、ナレッジを共有することが難しいと感じています。

今回紹介した方法を使えばチームの負担を軽減しつつ、ナレッジを共有してより良いCI/CDを構築する助けになると考えています。ぜひトライしてみてください。


執筆者プロフィール:牧野 真哉
自動テストで生計を立てています

お問合せはお気軽に

SHIFTについて(コーポレートサイト)
https://www.shiftinc.jp/

SHIFTのサービスについて(サービスサイト)
https://service.shiftinc.jp/

SHIFTの導入事例
https://service.shiftinc.jp/case/

お役立ち資料はこちら
https://service.shiftinc.jp/resources/

SHIFTの採用情報はこちら

PHOTO:UnsplashKarlis Reimanis