はじめに
Travis CI (以下 Travis) の仕組み、特にビルドのライフサイクルと設定ファイルである .travis.yml
の構成について、調査中のメモです。
でも、調べてる限りでは、ビルドの構成に関する説明と、設定ファイルの構造とが一致してないような気がする… (後述)
想定されている Travis CI の使い方
ドキュメントを読むに
- レポジトリには「デプロイされるようなもの」のソースが置いてある
- 対象レポジトリをクローンする (自動)
- ソースをビルドするための前提条件をインストールする (install フェーズ)
- Travis はこれをビルド (コンパイルやパッケージング) してテストなどする (script フェーズ)
- 良さそうならサーバにデプロイする (deploy フェーズ)
のような使い方を想定しているっぽい。
例えば GitHub Action でよく見るような、更新されたソースに基づいて新たなファイルを生成して、それをレポジトリに夏季戻す、という用法はあまり想定していない。Travis は対象レポジトリへの書き込み権限を持っていないのでそう推測した。
「ビルド」の構成
ビルド (Build)
Git のレポジトリにある .travis.yml
ファイルが1つのビルド (の設定ファイル) にあたる。
レポジトリに commit が push されたり、PR が submit されたときに動くのはこれ。
ステージ (Stage)
1つのビルドは複数のステージを含む。ステージはファイルへの記載順に順番に実行される。
ステージ内のジョブ (後述) たちは並列に実行される。
つまり、
例
ステージAとステージBがあるとして、これらは順番に実行される。
一方で、ステージ内にジョブ A, B, C があるとして、これはの3ジョブは並列に実行される。
互いに無関係な処理を実行したり、高速化のために並列実行させたりすることができる。
ジョブ (Job)
ジョブは順番に実行されるフェーズからなる。
ステージやジョブを明示的に書かない場合、全体が1つのステージ/ジョブとみなされる。
フェーズ (Phase)
ジョブ内で逐次的に実行される処理の単位。オプショナルなものを含め、多数のフェーズがある。
メインのフェーズは install
と script
の2つである。
注意事項
- install フェーズには言語ごとにデフォルト実装がある。これを disable したいときには
install: skip
と書く - (成果物の build を行う) script フェーズにもデフォルト実装が存在する場合がある
- デフォルトでは、deploy フェーズ前にレポジトリへの変更は stash される。これを避けたい場合は
と書く
deploy: skip_cleanup: true
- フェーズ内の処理が失敗したときに、それをビルド全体の失敗とみなすかどうかはフェーズによって異なる。以下の一覧で先頭に (*) が付いているフェーズが失敗すると、ビルド自体の失敗とみなされる。
フェーズ一覧
- Install
apt addons
[Optional] - Install
cache components
[Optional] - (*)
before_install
- (*)
install
- (*)
before_script
- (*)
script
- before_cache (if and only if caching is effective) [Optional]
- after_success / after_failure
- (*) before_deploy (if and only if deployment is active) [Optional]
- (*) deploy [Optional]
- after_deploy (if and only if deployment is active) [Optional]
- after_script
Job matrix を中心とした「ビルドの構成」の見直し
(以下ドラフト)
上記の構造を頭に入れてドキュメントを読んでもいまいちしっくり来なかった。ドキュメントではあまり前に出てこない Job matrix を中心に考えるのがいいと思った。
新・ビルドファイルの構成
ビルドファイルの構成を、記述されている順に従い、以下のように捉えるとよいと思った:
前提: script
がジョブの本質。これが定義されている部分がジョブ。
-
install
とかbefore_script
とかがあっても、それだけではジョブは定義されない
これを踏まえて、
- グローバル設定 (OS、distribution、キャッシュ設定、言語など)
- Expansion key による Job matrix の定義
- たとえば Python のバージョンが3通り、環境変数の設定が2通りあるとすると、matrix 展開により6個のジョブが定義される
- ここで定義するジョブが0個でもいい
- (
jobs
) 上記 matrix で定義されたジョブを含む、カスタムジョブの追加・除外- これによりジョブの全集合が定義される
- 各ジョブの所属する stage をここで決める。同じ stage に所属するジョブたちは並列実行され得る
- 各ジョブ個別の設定もここで決める
よくある記述パターンは次の2つだと思われる:
-
jobs
は何も書かずに、すべてを matrix 展開で済ませる。この場合script
などもすべてトップレベルに記述する - Expansion key は何も書かずに matrix 展開をしない。必要なジョブはすべて
jobs
の下に個別に記述して、所属する stage などを決める。特にジョブによって使用する言語を変えたい場合にはこの方法を取り、ジョブごとにlanguage
を設定する
これを頭においてドキュメントを読むと、言わんとしていることが理解できるはず。