MENU

[Github Actions]Renovateのprを安全にauto mergeするまで

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する手順を考察してみる。

目次

手順

以下ステップで実装。

  1. renovate.jsonを設定
  2. Github Actionsのworkflowを作成
  3. 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(有効)」になっている。
  1. auto-merge タグが付与
  2. auto-merge が有効(enabled)に設定
  3. pull requestがapprovedされた
  4. 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に追加すれば良いだけなので、
拡張性という意味でも、いい感じかと思います。

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

この記事を書いた人

コメント

コメントする

目次