グローバル設定
グローバル設定として、image
や before_script
などが書けたのですが、将来廃止されます。
代わりに default
キーワードが追加されました。
image: ruby:3.0
ではなく、
default:
image: ruby:3.0
にします。
default
キーワードにはもともとグローバルには設定できなかった tags
などが書けるようになりました。ちょっとうれしい。
まだどのバージョンでというのはありませんが、今から書くものは default
キーワードを使ったほうがよいでしょう。
変数の設定
変数の設定は variables
キーワードを利用しますが、グローバルとジョブ個別の両方に設定できます。(グローバルは default
キーワードではなく、今まで通り直下に書きます)
この variables
キーワードは、グローバル設定とジョブ個別の設定がマージされます。
variables:
VAR1: global1
VAR2: global2
job1:
variables:
VAR1: job1
script:
- echo $VAR1 $VAR2 # "job1 global2"
グローバル設定を無視したいときは、ジョブ設定に inherit:variables: false
を追加します。
変数は他の変数の展開ができます。
variables:
WORKING: $CI_PROJECT_DIR/.working
TEMPORARY: ${WORKING}/temporary
展開できる変数は次の通りです。
一般的な Linux 環境の環境変数 (Ex: HOSTNAME) は展開できません。
before_script
before_script キーワードに書かれた処理は script
キーワードのものよりも前に動作します。
基本的に script
に書いても before_script
に書いても変わりはないようです。
ただし、default
キーワードに書けますので、共通の初期化処理がある場合は活用できます。
初期化処理がジョブごとにばらばらでも次のようにごまかす方法もあります。
default:
before_script:
- which dotnet && dotnet restore
- which npm && npm install
- which docker && docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
ジョブでデフォルトの before_script
を使いたくないときは []
を設定します。
job:
before_script: []
デフォルト設定とジョブ設定の両方を設定した場合、variables
キーワードとは異なり、ジョブ設定の方だけが使われます。(どちらかというと、variables
キーワードが特殊)
default:
before_script:
# これは実行されません
- echo don't execute
job:
before_script:
- echo execute
script:
- echo done
もし、デフォルトの before_script
の後に処理を実行したい場合は、YAML アンカーが使えます。
default:
before_script: &before_script
- echo default
job:
before_script:
- *before_script
- echo job
script:
- echo done
ですが、こういった小細工を覚えなくてもいい、シェルスクリプトの活用をお勧めします。
default:
before_script:
- ./ci/setup-default.sh
job:
before_script:
- ./ci/setup-default.sh
- ./ci/setup-job.sh
script:
- echo done
script
before_script
で実行した結果の環境変数・シェル変数・エイリアスはそのまま引き継がれます。
job:
before_script:
- export VAR1=var1
script:
- echo $VAR1 # "var1"
エイリアスを使う nvm も使うことができます。
job:
before_script:
- nvm install 12
script:
- node --version
複数行を書きたいときはいろいろ方法がありますが - |
がよさげです。
job:
script:
- |
echo first line
echo second line
CI ジョブのデバッグは結構大変です。.gitlab-ci.yml
を修正して、プッシュして下手したら 10 分以上待ってバグに気が付きます。長い処理を書くのを避け、シェルスクリプトやビルドツールを使ったほうがよいでしょう。
build:
script:
- echo first process
- echo second process
- echo third process
- ...
と書くよりは、
build:
script: ./ci/build.sh
や
build:
before_script: npm install
script: npm run build
のようにすることをお勧めします。
このやり方だと、パソコン側で動作確認がやりやすいので、CI ジョブのデバッグ時間を節約できます。
after_script
ジョブの後始末は after_script キーワードに書くことができます。before_script
キーワードと同様に、デフォルト設定とジョブ設定の両方に書くことができます。
ただし、結構注意が必要です。
-
before_script
もしくはscript
が失敗しても、after_script
は必ず実行されます -
after_script
でエラーが発生しても、ジョブの成否には影響しません - 必ず 5 分でタイムアウトします。タイムアウトしてもジョブの成否には影響しません
完全に後始末用ですね。
もう一つはまりやすい仕様があります。
-
before_script
やscript
で設定された環境変数・シェル変数・エイリアスは引き継がれません
job:
before_script:
- export VAR1=before
script:
- echo $VAR1 # "before"
- export VAR2=script
after_script:
- echo $VAR1 # 何も表示されない
- echo $VAR2 # 何も表示されない
-
nvm
などのエイリアスを使う仕組みはafter_script
に引き継がれません - プロセス番号を環境変数に設定して、
after_script
でkill
しようとしてもできません - 値を引き継ぎたいときはファイルに書き出して、
after_script
で読み込んでください
私はこれを忘れてしょっちゅうはまってます。
after_script
は挙動が少し特殊なのではまりやすいです。(私はしょっちゅう忘れてはまります)
最後に
公式ドキュメントに書いてあることばかりですが、あらかじめ知っておくといいかなと思います。