TL;DR
- actions/checkoutがチェックアウトするブランチは、Pull Requestのブランチの最新コミットではなく、
refs/pull/<pr_number>/merge
になる refs/pull/<pr_number>/merge
は、Pull Requestをマージしたときの結果を確認するために作成される仮想リファレンス- ローカルで同じ状況を再現したければ、
refs/pull/<pr_number>/merge
をfetchしてチェックアウトする
発生した問題
GitHub ActionsでlintのCIが落ちていたが、ローカルでlintを実行しても、エラーの再現ができなかった。
CIのログを見ていると、CIの実行されるブランチが、ローカルにはないコミットSHAになっていることに気づいた。
Pull RequestイベントでCIが実行されるブランチ
GitHub Actionsのactions/checkoutでは、ref
を明示的に指定しない場合github.context.ref
にチェックアウトされる。
参照:actions/checkout - input-helper.ts
Pull Requestイベントでは、github.context.ref
はrefs/pull/<pr_number>/merge
が指定される。
refs/pull/<pr_number>/merge
は、Pull Requestを作成したときにGitHubが自動作成するリファレンスで、Pull Requestをマージしたときの結果を確認するために作成される。
つまり、このリファレンスにはPull Requestの「base」に指定したブランチと、Pull Requestのブランチ(headブランチ)をマージした結果が格納されている。
今回、Pull Requestのブランチを切った時点からbaseに指定したブランチが進んでいて、lintが失敗する状態になっていると、Pull Requestのブランチ内では問題なさそうに見えてもCIは落ちてしまう。
ローカルでPull Requestのブランチのheadに対してlintを実行しても、問題が再現しない。
Pull Requestのheadに対してCIを実行する方法
actions/checkoutのref
にPull Requestのheadを指定する。
- uses: actions/checkout@v4
with:
ref: ${{ github.event.pull_request.head.sha }}
CIが実行されるブランチをローカルで確認する方法
ローカルでは、refs/pull/<pr_number>/merge
に移動してを確認する必要がある。
移動するには、refs/pull/<pr_number>/merge
をfetchして、その結果が格納されているFETCH_HEAD
にチェックアウトする。
git fetch origin pull/<pr_number>/merge
# git fetch origin pull/10/merge
git checkout FETCH_HEAD