一覧SE-07-2 · ビルドとCI

CIのトリガーとジョブ管理

起動条件、依存するジョブの結果、再利用する入力の同一性を確認し、成功・失敗・スキップを読み取れるようになります。

説明

CIでは、変更をきっかけに検査やビルドを実行します。どの変更で起動するか、どの検査が成功したら次へ進むか、失敗後にどこからやり直すかを決める必要があります。以前の成功を再利用する場合は、対象の入力が同じかも確認します。

8%加算の金額計算を検査する小さなジョブ実行プログラムを使います。構文検査とテストを並列に実行し、両方が成功したらビルド、続いてZIP作成へ進みます。固定の誤実装を直し、入力が変わった場合と同じ場合の再実行を比較します。

起動条件、依存するジョブの結果、再利用する入力の同一性を確認し、成功・失敗・スキップを読み取れるようになります。

1起動条件とジョブの依存

pipeline.jsonを読みます。この実行プログラムではneedsが前提ジョブ、commandが実行するコマンドです。

cat pipeline.jsonイベント・対象パス・ジョブの依存を読む

syntaxとtestに依存先はなく、同じ段階で動かせます。buildは両方の成功、packageはbuildの成功が必要です。syntaxはPythonの構文検査で、業務上の正しさを調べるものではありません。

2対象外の変更では起動しない

pushイベントでも、docsだけの変更は対象パスに一致しません。

python3 ci.py --event push --changed docs/guide.mdイベントと変更パスを指定する

workflowがskippedになります。これはテストが成功した意味ではなく、今回の起動条件では実行しなかったという意味です。

3テスト失敗で後続を止める

対象のsrc/calc.pyが変更された場合として実行します。現在のコードは8%のはずが10%を加算します。

python3 ci.py --event push --changed src/calc.py対象コードの変更でパイプラインを起動する

構文検査は成功、テストは110と108の不一致で失敗します。buildとpackageは依存条件を満たさずスキップされます。構文が正しいだけで成果物を作ってよいわけではありません。

4同じ入力の失敗ジョブを再実行

testとその後続を再実行します。入力のハッシュが同じなので、成功済みのsyntaxは再利用します。

python3 ci.py --rerun testtestとそれに依存する後続を再実行する

syntaxはreusedですが、同じ計算の誤りでtestは再び失敗します。決定的な不具合は、やり直すだけでは直りません。

5入力を変えたら前の成功を使わない

8%の修正案を反映し、前回の実行の一部だけを再実行しようとします。

cp calc-fixed.py src/calc.py8%の計算へ修正する python3 ci.py --rerun test以前と同じ入力か照合する

inputs changedとして拒否されます。この実行プログラムは、コードや試験・設定のハッシュが違う場合、前回のsyntax成功を流用しません。新しい入力として検査を開始します。

6新しい入力で最初から検査する

修正後のコードを、新しい実行として処理します。

python3 ci.py --event push --changed src/calc.py修正後の入力で全体を新しく実行する

syntaxとtestが成功し、build、packageの順に進みます。依存のない二つは並列実行し、出力は確認しやすい順にまとめて表示しています。

7同じ入力ならアーカイブ作成だけを再実行できる

入力を変えず、packageだけをやり直します。 この実行プログラムは、再利用する上流の成果物についても保存したハッシュと照合します。

python3 ci.py --rerun package同じビルド結果からZIPを作り直す

syntax・test・buildはreused、packageだけsuccessです。再実行の範囲を絞れるのは、上流が同じ入力で成功済みであることを確認しているためです。

8ジョブの成功と成果物を対応させる

ZIPのファイル名と内容を読みます。

python3 inspect_package.pyZIP内の成果物を読み出す

result.jsonのinputは100、totalは108です。ジョブの緑表示だけで終わらず、今回の処理で作られた成果物が何を含むか確認できました。

まとめ

起動条件に合わずスキップした場合と、実行して成功した場合を分けて読みます。

ジョブの依存関係に従い、必要な検査が失敗したら後続のビルドや包装を止めます。

同じ入力の成功を再利用する場合と、入力変更後に新しく検査する場合を分け、作られた成果物まで確認します。

操作履歴と解説を振り返れます。

シェル / Python 3

1
cat pipeline.json
{
  "events": [
    "push",
    "pull_request"
  ],
  "paths": [
    "src/",
    "tests/",
    "build.py",
    "package.py",
    "pipeline.json",
    "ci.py",
    "run_tests.py"
  ],
  "jobs": {
    "syntax": {
      "needs": [],
      "command": "python3 -m py_compile src/calc.py"
    },
    "test": {
      "needs": [],
      "command": "python3 run_tests.py tests.test_calc"
    },
    "build": {
      "needs": [
        "syntax",
        "test"
      ],
      "command": "python3 build.py",
      "outputs": [
        "build/result.json"
      ]
    },
    "package": {
      "needs": [
        "build"
      ],
      "command": "python3 package.py",
      "outputs": [
        "artifact.zip"
      ]
    }
  }
}
2
python3 ci.py --event push --changed docs/guide.md
workflow: skipped (event or paths)
3
python3 ci.py --event push --changed src/calc.py
syntax: success
test: failed
FAIL tests.test_calc.Tax.test_hundred: 110 != 108
PASS tests.test_calc.Tax.test_zero
tests=2 failures=1 errors=0
build: skipped
package: skipped
4
python3 ci.py --rerun test
syntax: reused
test: failed
FAIL tests.test_calc.Tax.test_hundred: 110 != 108
PASS tests.test_calc.Tax.test_zero
tests=2 failures=1 errors=0
build: skipped
package: skipped
5
cp calc-fixed.py src/calc.py python3 ci.py --rerun test
rerun refused: inputs changed; start a new run
6
python3 ci.py --event push --changed src/calc.py
syntax: success
test: success
PASS tests.test_calc.Tax.test_hundred
PASS tests.test_calc.Tax.test_zero
tests=2 failures=0 errors=0
build: success
built build/result.json
package: success
packaged artifact.zip
7
python3 ci.py --rerun package
syntax: reused
test: reused
build: reused
package: success
packaged artifact.zip
8
python3 inspect_package.py
files=result.json
{"input": 100, "total": 108}

演習完了