LoginSignup
22
9

More than 1 year has passed since last update.

.gitlab-ci.yml を書くときに知っておくといいことあるかも

Posted at

グローバル設定

グローバル設定として、imagebefore_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_scriptscript で設定された環境変数・シェル変数・エイリアスは引き継がれません
job:
  before_script:
    - export VAR1=before
  script:
    - echo $VAR1 # "before"
    - export VAR2=script
  after_script:
    - echo $VAR1 # 何も表示されない
    - echo $VAR2 # 何も表示されない
  • nvm などのエイリアスを使う仕組みは after_script に引き継がれません
  • プロセス番号を環境変数に設定して、after_scriptkill しようとしてもできません
  • 値を引き継ぎたいときはファイルに書き出して、after_script で読み込んでください

私はこれを忘れてしょっちゅうはまってます。

after_script は挙動が少し特殊なのではまりやすいです。(私はしょっちゅう忘れてはまります)

最後に

公式ドキュメントに書いてあることばかりですが、あらかじめ知っておくといいかなと思います。

22
9
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
22
9