Renovate からのプルリクを条件付きで自動マージする
概要
Renovate はプロジェクトの依存パッケージを更新するプルリクを自動的に生成してくれるサービスです。
npm において各パッケージの更新は頻繁に行われているため、プルリクを手動で処理していては対応が追いつきません。
そこで main ブランチと Renovate が作成するプルリクのブランチでフロントエンドの build を行い、その差分がない場合だけプルリクをマージする仕組みを構築しました。
この記事ではその仕組みについて紹介します。
この仕組みは次のリポジトリに導入されています。
main ブランチとトピックブランチで build 結果に diff がないか確認する
Actions の定義は https://github.com/odanado/blog/blob/main/.github/workflows/check-build-diff.yml にあります。
各 job の全体像は次の画像の通りです。
それぞれのブランチで build する
main ブランチとトピックブランチで build する部分の job です。それぞれ build-on-main
と build-on-current
という名前がついています。
それぞれの job は
- actions/checkout でブランチを切り替え
-
npm run build
を実行 - actions/upload-artifact で build 結果を保存
という処理を実行しています。
build-on-main:
needs:
- if-label
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
with:
ref: main
- uses: actions/setup-node@v3
with:
cache: npm
node-version-file: .node-version
- run: npm ci
- run: npm run build
env:
ORIGIN: https://blog.odan.dev
- uses: actions/upload-artifact@v3
with:
name: ${{ github.sha }}-main
path: dist
build-on-current:
needs:
- if-label
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
with:
cache: npm
node-version-file: .node-version
- run: npm ci
- run: npm run build
env:
ORIGIN: https://blog.odan.dev
- uses: actions/upload-artifact@v3
with:
name: ${{ github.sha }}-current
path: dist
build 結果の diff を取得する
この job では
- actions/download-artifact でbuild 結果をダウンロード
- gh640/command-result-action 経由で diff コマンドを実行
- job の outputs に diff の内容と diff コマンドの終了コードを保存
という処理を実行しています。
diff コマンドの結果は複数行の文字列が出力されます。複数行の文字列を output で扱う場合、エスケープが必要になります。この問題に対応するために GitHub Actions で複数行の文字列を output にセットする方法 | gotohayato.com で紹介されいている gh640/command-result-action
経由で diff コマンドを実行しています。
check-build-diff:
needs:
- build-on-main
- build-on-current
outputs:
diff-name-only: ${{ steps.diff-name-only.outputs.stdout }}
diff-exit-code: ${{ steps.diff-name-only.outputs.exitCode }}
runs-on: ubuntu-latest
steps:
- uses: actions/download-artifact@v3
with:
name: ${{ github.sha }}-main
path: dist-main
- uses: actions/download-artifact@v3
with:
name: ${{ github.sha }}-current
path: dist-current
- id: diff-name-only
uses: gh640/command-result-action@v1
with:
command: diff -qr dist-main dist-current
diff をプルリクのコメントで通知する
この job では
- mshick/add-pr-comment を使用してコメントを投稿
という処理を実行しています。
mshick/add-pr-comment
はすでにコメントが存在するときは内容を update してくれるなど、 gh cli を使用するより便利な機能が用意されています。
add-pr-comment:
needs:
- check-build-diff
runs-on: ubuntu-latest
permissions:
pull-requests: write
steps:
- uses: mshick/add-pr-comment@v2
with:
message: |
# Check build diff report
```
${{ needs.check-build-diff.outputs.diff-name-only }}
```
diff がないことを表すラベルを付与する
この job では
- diff がない場合に actions-ecosystem/action-add-labels を使用して
no build diff
ラベルを付与
という処理を実行しています。
add-label:
needs:
- check-build-diff
runs-on: ubuntu-latest
permissions:
pull-requests: write
steps:
- uses: actions-ecosystem/action-add-labels@v1
if: ${{ needs.check-build-diff.outputs.diff-exit-code == 0 }}
with:
labels: no build diff
自動マージする
build 結果に差分がないことを確認する仕組みを導入できたので、次は自動マージする方法を導入します。
build 結果に差分がない場合 no build diff
ラベルが付与されることになっているので、このラベルが存在する場合に自動マージすれば良いです。
しかし、このラベルは GitHub Actions 経由で GITHUB_TOKEN
トークンを使用して付与されています。そのためラベルが付与されたときに発生するイベントを起点に GitHub Actions を実行することはできません。
なので自動マージには Mergify という SaaS を利用することにしました。
Mergify は自動マージする条件を yaml で定義しておくと、その条件を満たしたときに自動マージしてくれます。
設定ファイルは https://github.com/odanado/blog/blob/main/.mergify.yml にあります。
今回は次の4つの条件が満たされているときに自動マージされるようにしました。
- プルリクの作成者が Renovate の GitHub App
- build の status が成功している
-
dependencies
ラベルが付与されている -
no build diff
ラベルが付与されている
pull_request_rules:
- name: Automatic merge on approval
conditions:
- author=renovate[bot]
- check-success=build
- label=dependencies
- label=no build diff
actions:
merge:
method: merge
まとめ
Renovate を使用して依存パッケージの自動更新の運用負荷を軽減するために、build 結果に diff がない場合にプルリクを自動マージする仕組みを紹介しました。
Discussion