概要
GitLab CI/CDでマージリクエスト時に、適切にパイプラインが実行されませんでした。
その問題についてと、修正方法について説明します。
環境
- GitLab 17.10
- GitLab Runner 17.10
問題について
GitLabのリポジトリについて、プッシュ時にCI/CDの実行を設定しています。このCI/CDの設定について、マージリクエストを作成したときに、適切にパイプラインが実行されないという問題にぶつかりました。
このパイプラインの設定として、.gitlab-ci.yml
は次のように記述していました。
image: registry.gitlab.com/pages/hugo/hugo_extended:latest
variables:
HUGO_ENV: production
GIT_SUBMODULE_STRATEGY: recursive
stages:
- test
- deploy
textlint:
image: node:lts-alpine
stage: test
script:
- npm ci
- npm run textlint
test:
stage: test
script:
- hugo
rules:
- if: $CI_COMMIT_REF_NAME != $CI_DEFAULT_BRANCH
pages:
stage: deploy
script:
- ./build.sh
artifacts:
paths:
- public
rules:
- if: $CI_COMMIT_REF_NAME == $CI_DEFAULT_BRANCH
この.gitlab-ci.yml
では、Hugoを利用して静的なHTMLサイトをビルドし、GitLab Pagesにアップロードしているものになります。また、textlint
を利用して、記事の内容のチェックを行なっています。
上記の設定をしていた際にマージリクエストを行うと、textlint
のテストが行われません。branchでのパイプラインでは行われています。
原因として考えられるのは、test
やpages
でのrules:
設定の影響です。textlint
ではrules:
を設定していないので、rules:
の条件に関わらず必ず実行されるものと思っていましたが、そうではありませんでした。
解決方法
GitLab CI/CDのrules:
の設定には、癖があるようです。具体的には、rules:
の設定によっては複数のパイプラインが実行されたり、適切なジョブが実行されなかったりするというものです。
今回は、設定が間違っていることから、適切にジョブが実行されなかったものと思われます。
こちらについて、今回は次のように修正しました。
image: registry.gitlab.com/pages/hugo/hugo_extended:latest
variables:
HUGO_ENV: production
GIT_SUBMODULE_STRATEGY: recursive
stages:
- test
- deploy
workflow:
rules:
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
- if: $CI_COMMIT_BRANCH && $CI_OPEN_MERGE_REQUESTS
when: never
- if: $CI_COMMIT_BRANCH
textlint:
image: node:lts-alpine
stage: test
script:
- npm ci
- npm run textlint
rules:
- if: $CI_COMMIT_REF_NAME != $CI_DEFAULT_BRANCH
- if: $CI_COMMIT_REF_NAME == $CI_DEFAULT_BRANCH
test:
stage: test
script:
- hugo
rules:
- if: $CI_COMMIT_REF_NAME != $CI_DEFAULT_BRANCH
pages:
stage: deploy
script:
- apk add bash imagemagick libwebp libwebp-tools
- ./build.sh
artifacts:
paths:
- public
rules:
- if: $CI_COMMIT_REF_NAME == $CI_DEFAULT_BRANCH
修正した項目は、workflow:
の追加と、textlint
ジョブへのrules:
の追加です。
workflow:
は、全体のパイプラインについて、どのような時に実行するのかを制御する項目です。今回は次のようにしました。
if: $CI_PIPELINE_SOURCE == "merge_request_event"
- マージリクエストのイベント時にパイプラインを実行
if: $CI_COMMIT_BRANCH && $CI_OPEN_MERGE_REQUESTS
- マージリクエストの作成されているブランチについて、
when: never
を設定することでパイプラインを実行しない CI_OPEN_MERGE_REQUESTS
でマージリクエストが作成されているかを確認しています
- マージリクエストの作成されているブランチについて、
if: $CI_COMMIT_BRANCH
- 上記の条件に当てはらない場合で、ブランチのプッシュの場合、パイプラインを実行
これらの条件は、ORで設定するものになります。上から評価されて、当てはまるものがあればそこで判定は終了です。
これで、余計なパイプラインの実行は止められるようになりました。
さらに、textlint
ジョブにrules:
を追加しました。条件は他のrules:
のものを記述しており、test
とpages
の両方のジョブ実行時にtextlint
ジョブを実行するようにしました。
これで、正常にパイプラインが実行されるようになりました。
さいごに
CI/CDの設定はとても便利ですが設定が難しいという印象です。
今回の設定の重要な部分は、rules
とworkflow
です。rules
は、昔使われていたonly
やexcept
を置き換えるものとして追加されました。workflow
は、マージリクエストの際など複数のパイプラインが作成される問題への対処として追加されたようです。これらは、昔はなかった設定になります。そのためあまり情報が少ない印象です。
他の方の参考になれば幸いです。