Renovate周りのあれこれを理解するべく記事を書いてきた。
Renovate(onboarding)
Renovateをgithub Actionsで実行してみる
Renovate scheduleとgroupingとrangeStrategyと(on Github Actions)
[Github Actions]Branch protection「status check」用のJobを作ってみる
今回の趣旨は以下の通り
「Renovate」 + 「Github Actions」 + 「Github のBranch Protection」を使って、 Renovateで作成したpull requestを安全にauto mergeする手順を考察してみる。
手順
以下ステップで実装。
- renovate.jsonを設定
- Github Actionsのworkflowを作成
- Github のBranch Protectionを設定
1. renovate.jsonを設定
{
"$schema": "https://docs.renovatebot.com/renovate-schema.json",
"extends": [
"config:recommended"
],
"branchPrefix": "renovate/",
"labels": [
"renovate"
],
"schedule": [
"after 7pm every weekday",
"before 5am every weekday",
"every weekend"
],
"timezone": "Asia/Tokyo",
"prHourlyLimit": 0,
"rangeStrategy": "bump",
"dependencyDashboard": false,
"packageRules": [
// major updateは、pull requestを作成しない
{
"matchUpdateTypes": [
"major"
],
"enabled": false
},
// minor-patch updateはgrouping
{
"groupName": "all non-major dependencies",
"groupSlug": "all-minor-patch",
"matchPackagePatterns": [
"*"
],
"matchUpdateTypes": [
"minor",
"patch"
],
// automergeを有効にする
"automerge": true,
// pull requestにタグ「auto-merge」を付ける
"addLabels": ["auto-merge"]
}
]
}
#### ポイント
1)minor-patch のpull requestをgroupingする
「minorとpatchのupdateは、破壊的な変更は基本的に無い」という前提で、 groupingしてまとめてauto mergeできるように設定していきます。
2)「1)」のpull requestにauto-merge用のタグを付与する
詳細は後述しますが、 Renovateで作成したpull requestをauto mergeするためには、Github 上でauto mergeの許可が必要です。
その辺りをGithub Actionsでいい感じで設定するために、 Renovateで作成するpull requestには、「auto-merge」という名前のタグを付与しておきます。
2. Github Actionsのworkflowを作成
以下3つのworkflowを作成しています。
- renovate.yml
- status-check.yml
- toggle-auto-merge.yml
それぞれ詳細は説明します。
renovate.yml
name: Renovate
on:
# 定期実行(15分ごと)
schedule:
- cron: '0/15 * * * *'
workflow_dispatch:
jobs:
renovate:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4.1.1
- name: Self-hosted Renovate
uses: renovatebot/github-action@v40.1.7
with:
token: ${{ secrets.RENOVATE_TOKEN}}
env:
LOG_LEVEL: 'debug'
RENOVATE_REPOSITORIES: 'kokiwaku/test-renovate-template'
RENOVATE_USERNAME: 'renovate[bot]'
RENOVATE_PLATFORM: 'github'
特筆する点はありません。 cronでRenovateを定期実行しています。
status-check.yml
name: status-check
on:
workflow_dispatch:
pull_request:
jobs:
# テスト1:eslist
eslint:
name: eslint
runs-on: ubuntu-latest
permissions:
contents: read
pull-requests: write
steps:
- uses: actions/checkout@v4
# see https://github.com/reviewdog/action-eslint
- uses: reviewdog/action-eslint@v1
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
workdir: './src/'
eslint_flags: 'resources/**/*.{js,ts}'
fail_on_error: true
# テスト2:php-cs-fixer
php-cs-fixer:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Set up PHP
uses: shivammathur/setup-php@v2
with:
php-version: '8.3'
- name: Install dependencies
run: |
cd src
composer install
- name: Run PHP CS Fixer
run: |
cd src
composer run cs-fixer-dry-run
# Branch Protectionの「Require status checks to pass before merging」に指定するjob
# このjobが失敗(exit)すると、上記Protectionによりprがマージ不可となる。
status-check:
runs-on: ubuntu-latest
# needsに設定しているjobが実行された後に、このjobは動作する
needs:
- eslint
- php-cs-fixer
permissions:
pull-requests: write
contents: write
steps:
# status-checkに成功した場合、PRをapproveする
- name: Approve PR
env:
PR_URL: ${{github.event.pull_request.html_url}}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
if: success()
run: gh pr review "$PR_URL" --approve
# status-checkに失敗した場合、RPのapproveを取り消して終了
- name: Dismiss PR and exit
if: failure()
run: |
gh pr review "$PR_URL" --request-changes
exit 1
workflow中のコメントに尽きるが、ポイントを記載。
ポイント
このworkflowの主な役割は、 「status-check のjobの成否に応じて、pull requestのmerge 可否を制御すること」です。
詳しくは以下記事で記載しているのですが、
[Github Actions]Branch protection「status check」用のJobを作ってみる
後述する通り、status-checkのjobを、 Branch Protectionの「Require status checks to pass before merging」というルールのチェック対象jobとして指定しているので、 status-checkのjobが失敗(exit 1)した場合には、pull requestがmerge できない状態になります。
また、 status-check のjobには、needsで同workflow内の他のjobを指定しています。
そのため、以下のような挙動となります。
「status-checkのneedsに設定しているjobが全て成功した場合のみ、pull request全般のmerge が可能となる」
toggle-auto-merge.yml
name: auto-merge
on:
pull_request:
types:
- labeled
- unlabeled
- synchronize
- opened
- edited
- ready_for_review
- reopened
- unlocked
permissions:
pull-requests: write
contents: write
jobs:
toggle-auto-merge:
runs-on: ubuntu-latest
env:
PR_URL: ${{github.event.pull_request.html_url}}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
steps:
- name: Checkout
uses: actions/checkout@v4
# prにlabel:auto-mergeが付いている場合、prをauto merge可能にする
- name: Enable auto-merge for Steward PRs
if: ${{ (contains(github.event.pull_request.labels.*.name, 'auto-merge')) }}
run: gh pr merge --merge --auto "$PR_URL"
# prにlabel:auto-mergeが付いていない場合、prをauto merge不可にする
- name: Disable auto-merge for Steward PRs
if: ${{ !(contains(github.event.pull_request.labels.*.name, 'auto-merge')) }}
run: gh pr merge --disable-auto "$PR_URL"
ポイント
Renovateで作成したpull requestをauto mergeには、以下いずれかの設定により、 Github 上でauto mergeを許可する必要があります。
- Repository単位の設定:Repositoryで作成したpull request全体に共通して設定する
- pull request単位:Repositoryで作成したpull request単体について、設定する
今回は、後者を採用します。
pull requestに「label:auto-merge」の有無に応じて、 ghを使ってauto-merge可否を制御しています。
「1. renovate.jsonを設定」で記載した通り、 Renovateが作成したminor・patch version upのpull requestについては、 「auto-merge」タグを付けています。
そのため、以下の挙動となります。
「Renovateで作成したminor・patch version upのpull requestは、Githubによるauto mergeを可能にする」
3. Github のBranch Protectionを設定
Default branch向けのBranch Protectionルールを設定します。
#### ポイント
前述のGithub Actionsの「workflow > status-check.yml」に定義した「status-check」のjobがpassした場合のみ、 pull request のmerge が可能となるように設定しています。
これで準備okです。
実際に動作を確認してみます。
挙動を確認
- Renovateにより作成されたpull requestが以下の通り。
- Reviewers:githuub-actionsによりapproveされている。
- Labels:auto-merge が付与されている。
- 「Auto merge:Enabled(有効)」になっている。
- auto-merge タグが付与
- auto-merge が有効(enabled)に設定
- pull requestがapprovedされた
- pull requestがmergeされた
一応、想定通りの挙動となっていますが、GIthub Actionsの各workflow実行結果も見てみます。
- status-check.yml
- auto-merge
まとめ
本当は、
Branch Protectionの「Require status checks to pass before merging」ルールのチェック対象jobで、unit testも実行できれば良いかなと思います。
というか、それがないとRenovateのprを安全にauto mergeできているとは言い難いですね。
とはいえ、仕組みとしてはこんな感じで良さそうかな、と感触は掴めました。
もし、unit testのciをstatus checkに追加したい場合には、
status-check.yml > job:status-check > needsに追加すれば良いだけなので、
拡張性という意味でも、いい感じかと思います。
コメント