JavaScriptを有効にしてください

gitlab-ci 覚えておきたい構文

 ·  ☕ 6 分で読めます · 👀... ページ閲覧数

背景

CICDを作るときにやりたいことの構文をよく忘れるので忘れないうちにメモしておく。
RUNNER等、基本的なgitlab-ciの説明については一旦割愛(そのうちまとめたい)。

gitlab-ciでわからない構文ややりたいことがある場合、公式のドキュメントを探せば大体ある。

新しいことをやりたいときはとりあえずドキュメントをあさるのが良い。

サンプルリポジトリ

以降、記述するgitlab-ciのサンプルリポジトリはここ。

https://gitlab.com/bambi-san/ci-sample

stagesの順序に関係なく並行してJobを実行したい

needs構文を利用する。
(GitLabのバージョンが12.2 以上で利用可能。)

例えば、Pipelineの定義が下記のようであった場合testlintの実行を待たなければならない。
lintの実行を待たずにtestしたいなど、定義したstagesの順序に関係なく実行したい場合に利用する。

1
2
3
stages:
  - lint
  - test

needsを利用したPipeline定義例

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
stages:
  - lint
  - test

go_staticcheck:
  stage: lint
  image: golang:1.17-stretch
  before_script:
    - go mod download
    - go install honnef.co/go/tools/cmd/staticcheck@latest
  script:
    - staticcheck ./...

go_test:
  stage: test
  image: golang:1.17-stretch
  before_script:
    - go mod download
  script:
    - go test


go_test:non_needs
  stage: test
  before_script:
    - go mod download
  needs: []
  image: golang:1.17-stretch
  script:
    - go test

上記のようなCIを定義した場合、挙動は次の通りになる。

  1. [pipeline起動後] go_staticcheck, go_test:non_needs Jobが実行される
  2. [lint stage完了後] go_test Jobが実行される

Job同士に順序性を持たせたい場合はneeds構文の値にJob名を配列で追加する。

同じJobを、リスト形式で登録した変数分実行したい

parallel(matrix)を利用する。

実行するJOBは全く同じだけど変数の値を一部変えて同時に行いたいときなど。それぞれJOBとして再定義する必要がなくなる。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
stages:
  - deploy

deploy_app:
  stage: deploy
  image: ubuntu:20.04
  variables:
    ENV: "develop"
    VERSION: "1.0"
  script:
    - echo  "release info (ENV=${ENV}, VERSION=${VERSION})"
  parallel:
    matrix:
      - ENV:
          - develop
          - staging
          - production
        VERSION: ["1.0", "2.0"]

parallel.matrix の設定で面白いのが、複数の変数をそれぞれ配列として定義することがきる。
例えば上記のように、ENVにdevelop, staging, production を、VERSIONに1.0, 2,0 を設定した場合、3✖️2通りのJOBが実行されることになる。

gitlab-ci_01

システムで設定される環境変数の一覧を確認したい

export構文を利用する。

新しいPipelineやJOBを作成しているときに知りたくなる時がある。
JOBを作成して変数化していくときに知ってると結構便利。

Maskedで登録しているCICD variablesは"[masked]"として値を隠してくれる。
Maskedで登録しないと平文で表示されてしまうので気をつけること。

設定はリポジトリのSettings -> CICD -> Variablesから確認できる。
(ちなみに、VariablesのProtectedはProtectedしたブランチやTagでCICDが実行される時のみに利用可能な変数のこと。)

1
2
3
job_name:
  script:
    - export

特定の条件を満たしたときにJOBを発火するようにしたい

rules構文を利用して定義する。

特定のブランチにPushされた時にJOBを実行したいなぁとか。

似たようなものにreleaseがある。
releaseはPipeline自体の実行を制御するもので、rulesはPipelineに含まれる、一つ一つのJOBを実行するか制御するときに利用する。

これらは比較的新しい機能(2022年1月時点)でGitlabのバージョンが rules>=12.3release>=13.2である必要がある。

rulesは結構ボリュームが多いので、今回は基本的な設定例と忘れそうなことをメモする。
(条件式は Predefined variables referenceを確認すると作るとき少し楽。)

rulesonly/exceptの上位互換となる機能であり、こちらの方がより柔軟にJOBを制御できるため公式でもrulesの利用が推奨されている。

自分も昔only/exceptでJOBをいくつか作っていたが、それまでのonly/exceptではcommitされたブランチごとにJOBで利用する変数の設定値を変えることができなかったり、かゆいところに手が届かない感があった。rulesを利用するとそれらほぼ全てが解決できて嬉しい!

特定のブランチに変更があったときにJOBを発火するようにしたい

この条件を設定することが一番多いと思う。featureブランチでコミットしてpushしたら必ずlintとtestを実行するとか。

1
2
3
4
5
6
7
8
job:
  script: echo "Hello, Rules!"
  rules:
    # MergeリクエストのTargetブランチがデフォルトブランチの場合、発火しない(never)
    - if: '$CI_MERGE_REQUEST_TARGET_BRANCH_NAME != $CI_DEFAULT_BRANCH'
      when: never
    # commitしたブランチが"feature"で始まる場合、発火する
    - if: '$CI_COMMIT_BRANCH =~ /^feature/'

=~などのマッチングについては公式(Syntax of environment variable expressions)に詳しい説明がある。

APIやGUI上からのリクエスト時のみJOBを発火するようにしたい

'$CI_PIPELINE_SOURCE =="web"''$CI_PIPELINE_SOURCE =="api"'で制御できる。

Chatのスラッシュコマンドと連携して発火させたりできる。(CI_PIPELINE_SOURCE に “chat"という値も一応用意されているが、利用条件がかなり限定されるのでどうしてもchatを条件として利用したいという要望等がなければ"api"を利用すればいいかなぁ)

webはCICD -> Pipelines Run Pipelineを選択し、GUIからPipelineを実行することで発火する。

CIでgitlab APIを叩きたい

特定のブランチのMR作ったり。テンプレート作っておくと色々使えて便利。

MRの作成をgitlab apiを利用して行なっている。

global variablesを利用すると組み立てが楽。

  • CI_API_V4_URL:APIのURL(例 CI_API_V4_URL=‘https://gitlab.com/api/v4'
  • CI_PROJECT_ID:CIを実行しているプロジェクトのID(例 CI_PROJECT_ID=‘0001’)

global variablesは、scriptに export を書くと一覧を確認することができる

1
2
scripts:
  - export

例えば、MRの作成をしたい場合は以下のように定義すれば良い。

1
2
3
4
5
    - >-
      curl -v --location --request POST ${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/merge_requests
      --header "PRIVATE-TOKEN: ${GITLAB_TOKEN}"
      --header "Content-Type: application/json"
      --data "{\"source_branch\": \"feature\", \"target_branch\": \"develop\", \"title\": \"MergeRequest Title\"}"      
共有

BAMBi
著者
BAMBi
サーバサイド~インフラがメインでフロントも好きです。趣味はアニメ鑑賞、ゲーム、つまみ細工です。