GitHubを利用して開発する際、プルリクエストでCIを利用して様々なチェックを走らせることがあると思います。
私もGitHub Actionsを使ってプルリクにPushするたびに様々なチェックを走らせていたのですが、タイトルの通りエラーを取りこぼしてマージしてしまうことがありました。
状況再現
例えば下記の場合、fuga ciとhoge ciがコケているのでこのプルリクの修正で何か問題が発生したことを検知できます。
説明のためかなり簡素化していますが、上記のプルリクでは下記のコードとそれをテストするGitHub Actionsを定義しています。
#!/bin/bash
exit 1
#!/bin/bash
exit 1
name: hoge ci
on:
push:
paths:
- 'hoge/**'
jobs:
hoge:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2.3.4
- name: run hoge
run: hoge/main.sh
name: fuga ci
on:
push:
paths:
- 'fuga/**'
jobs:
fuga:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2.3.4
- name: run fuga
run: fuga/main.sh
hoge ciはチェック内容がhoge/**
のファイルに依存しているので、hoge配下のファイルが変更された時だけ実行します。
fuga ciも同様の理由でfuga配下のファイルが変更された時だけ実行します。
今回、hogeもfugaも不具合が埋め込まれたことを表現するためにexit 1としています。そのためCIがエラーになっています。
不具合(exit 1)を修正します。
今回はexit 0に直すだけなので両方一気に直せば良いですが、通常開発の場合、まずはhgoeだけ直すなど1つずつ修正していくことが多いと思います。
今回は最初にhogeだけ直してみます。
hoge/main.shが正常終了するように下記のようにexit 0
に修正してpushします。
#!/bin/bash
exit 0
pushした後、プルリクを確認してみると下記のようになりました。
「All checks have passed」
hoge/main.shしか修正しておらず、fuga/main.shの不具合は残ったままにもかかわらずCIが通ってしまいました。
よく見ると、「All checks have passed」の下のchecksにfuga ciが含まれていません。
プルリクのマージボタンの箇所に表示されるChecksの判定は最後に動作したChecksの結果が反映されます。
最後のPushではhoge/main.shしか修正していないため、hoge ciしか動作せず、動作したテストは全て正常終了したためCIがパスしたようです。
fuga/main.shに不具合が残ったままですが、このプルリクを見るとCIはパスしているように見えるのでマージしてしまいそうですよね。
冒頭で記載したエラーを取りこぼしたのはこの状況です。エラーがあることに気づかずマージしてしまい、mainブランチに不具合が混入してしまいました。
では、どのようにすればこの状況を避けられるのでしょうか?
解決策
タイトルに「on: pushで動かしていたらエラーを取りこぼした話」と書いた通り、on: push
の挙動に問題があります。
on: push
を使うと、Pushに含まれるコードをもとに該当するCIが実行されます。
先程の2回目のPushはhoge/main.shのみしか含まれていなかったため、hoge ciのみ実行されました。
この挙動によりfuga ciが実行されずに不具合を見逃してしまいました。
これを避けるためにはon: pull_request
を使用すればよいです。
Github Actionsのonをpull_requestに変更して同様の作業を行います。
name: hoge ci
on:
- push:
+ pull_request:
paths:
- 'hoge/**'
name: fuga ci
on:
- push:
+ pull_request:
paths:
- 'fuga/**'
先ほどと異なり、hogeだけ修正したPushでもfuga ciも動作しています。
on: pull_request
はpushと異なりpull_requestに含まれるコードをもとに該当するCIが実行されます。
そのため、最後のPushにfuga/main.shが含まれていなくても、プルリク全体で見ると含まれているためfuga ciも実行されます。
これであればhoge ciがコケていることが一目瞭然なので誤ってマージしてしまうこともありません。
まとめ
上記の挙動より、プルリクエストのCIとして使う場合はon: pull_request
を使った方が良さそうです。
過去に私が書いた記事はon: pushになっているものが多いので修正しないとな・・・