これは 2021/12/12 時点の情報で github actions のアップデートが早いので近いうちに治っているかも。
また、軽く調査しただけなので、間違ったことを発信しているかも。
やりたいこと
github で PR の CI が全部通ったら自動的にマージしてほしい
前提条件
レポジトリの workflow は簡略化した具体例を書いておきます(動きません)
ポイントとしては以下のとおりです。
- フロントとバックエンドで workflow が別れている
- path で workflow の起動条件を絞っている
- バックエンドは jobs を2つに分けており直列実行している
- テスト分割のため martix を利用しており、job を1つにすることが難しい
サンプル
name: front on: pull_request: types: - opened - synchronize - reopened path: - "front/**" jobs: test: runs-on: ubuntu-latest steps: - name: test run: yarn test
name: backend on: pull_request: types: - opened - synchronize - reopened path: - "backend/**" jobs: build: runs-on: ubuntu-latest steps: - name: build run: docker build && docker push test: runs-on: ubuntu-latest strategy: matrix: test_id: ["01", "02"] needs: build steps: - name: docker run test${test_id}
auto-merge
やりたいことを実現するために、まず思いつくのが公式が用意している auto-merge です。
If you enable auto-merge for a pull request, the pull request will merge automatically when all required reviews are met and status checks have passed
プルリクエストを自動的にマージする - GitHub Docs
とまさにやりたいことができるような感じがします。
status checks で CI がすべて通ったときを選択できれば一件落着だったんですが、そう簡単には行きません。
Search for status checks, selecting the checks you want to require.
branch protection rule で status checks を選び、それらが全て成功していれば auto-merge されるという仕組みでした。
status checks は github actions の job 名にあたるようです。
ここからは実際に検証した内容です。
検証
branch protection rule に指定されているが、path の対象外で workflow が起動しない場合
例
以下の指定で foo/xxx のファイルしか変更しなかった場合
name: echo1 on: pull_request: types: - xxx path: - "bar/**"
結果
required のまま動かなくなります(それはそうって感じ)
branch protection rule に指定されており、その job 名が複数 workflow で指定されていた場合
例
branch protection rule が echo で workflow は以下のような感じです
name: echo1 jobs: echo: steps:
name: echo2 jobs: echo: steps:
結果
起動中の同名の job が全て終わった後に auto-merge されます。
ただし、同名でも起動していない場合はそれを待たずに auto-merge されます。
以下の例だと echo2.init-echo の sleep が長いため、echo2.echo が起動する前に echo1.echo が完了し、そのタイミングで auto-merge されてしまいます。
name: echo1 jobs: init-echo: steps: run: sleep 20 echo: steps: run: sleep 10
name: echo2 jobs: init-echo: steps: run: sleep 900 echo: steps: run: sleep 10
検証からわかったこと
auto-merge がうまくいくケース
paths を使っていない
素朴に branch protection rule に全ての job を入れればうまくいくはずです(未検証)
pathsは使っているが、全ての workflow で job が1個
全て job 名を同じにして branch protection rule にその job 名を入れればうまくいくはずです
pathsは使っており、全ての workflow で job が複数あるが、workflow 内で直列実行してない
ちょっとトリッキーですが、以下の方法がとれます。
I created another workflow with dummy jobs that have the same names with those required jobs that are not always triggered.
auto-merge がうまくいかないケース
上に当てはめることができないケースで、私のレポジトリでは適用が難しそうでした。
paths の指定を無しにするもの、テスト分割実行をやめるわけにもいかないので...。
で、どうするかというと、外からポーリングしてPRの状態を見るようにするのが地道だけどうまくいきそうだと思っています。
すでに marketplace に何かあるかもしれません。
actions で良い機能ないか調べてみたんですが workflow_run で待ち合わせするのはしんどそうで、check_suite っていうそれっぽい trigger もあるんですけど使い方が悪いのかなんだか動いてません。
まとめ
私の用途では使えなさそうでした。
またこれに限らず、workflow は個々で動いているのでCIが全部終わったらみたいな制御はしんどいなと思っています(通知とかも難しい)