blog.syfm

徒然なるままに考えていることなどを書いていくブログ

Go の "missing go.sum entry" エラーによって Dependabot による PR が自動でマージできなくなる問題を修正する

今まで設定していたものたち

個人利用のリポジトリや社内リポジトリでは Dependabot を利用していて、依存のアップデートを自動で行うようにしていた。
依存のアップデートがあると Dependabot は Pull Request を出してくれるものの、放置しがちだったので自動で approve してくれるような GitHub Actions を入れていた。

これと GitHub ネイティブではない Dependabot の automerged_updates という設定項目を有効にすることで approve がついたものを Dependabot が自動でマージしてくれるような設定にしていた。 *1

Go 1.16 からの変更

Go 1.16 から go.mod に含まれている依存のうち、go.sum に含まれていないものが1つでもあるとビルドが通らなくなった。これは Go 1.16 Release Notes にも記述されている。

Build commands like go build and go test no longer modify go.mod and go.sum by default. Instead, they report an error if a module requirement or checksum needs to be added or updated (as if the -mod=readonly flag were used). Module requirements and sums may be adjusted with go mod tidy or go get.

これにより、 go mod tidy を行っておらず、新しい依存を go.sum へ記録していないケースではビルドが通らなくなってしまった。

そして、Dependabot は go mod tidy を行うことができないという制約があった。 *2

GitHub ネイティブな Dependabot の go mod tidy サポート

GitHub ネイティブな Dependabot では v2 から go mod tidy が公式にサポートされることになった。

github.blog

これにより、GitHub ネイティブな Dependabot の v2 へ移行することでビルドが通るようになった。

自動マージ問題ふたたび

しかし、GitHub ネイティブな Dependabot へ移行したことにより、自動マージができなくなってしまった。
GitHub が自動マージを削除した理由としては以下のようなものがある。

Auto-merge will not be supported in GitHub-native Dependabot for the foreseeable future. We know some of you have built great workflows that rely on auto-merge, but right now, we’re concerned about auto-merge being used to quickly propagate a malicious package across the ecosystem. We recommend always verifying your dependencies before merging them. *3

理由としては至極まっとうなので、これからもしばらくは自動マージ機能を入れるのは難しいだろうな…と思う。

しかし、Go の場合、Go modules を入れていれば、タグを切らない限り新しい変更が伝搬することはない & リリース前にそれぞれの依存にどんな変更があったのかはチェックしているので、自プロジェクトであれば自動マージを入れても問題ないと判断した。

そこで、GitHub Actions を使って自動的にマージを行ってくれるワークフローを書いた。

name: "Auto approve Pull Requests and enable auto-merge"
on:
  pull_request_target
jobs:
  worker:
    runs-on: ubuntu-latest
    if: github.actor == 'dependabot[bot]'
    steps:
      - name: Auto approve and merge Pull Request
        uses: actions/github-script@v3.1
        with:
          github-token: "${{ secrets.GH_TOKEN }}"
          script: |
            await github.pulls.createReview({
              owner: context.repo.owner,
              repo: context.repo.repo,
              pull_number: context.issue.number,
              event: 'APPROVE'
            })

            const res = await github.graphql(`query {
              repository(owner: "${context.repo.owner}", name: "${context.repo.repo}") {
                pullRequest(number: ${context.issue.number}) {
                  id
                }
              }
            }`)

            await github.graphql(`mutation {
              enablePullRequestAutoMerge(input: { pullRequestId: "${res.repository.pullRequest.id}" }) {
                clientMutationId
              }
            }`)

secrets.GH_TOKEN *4 に対応するアカウントが PR を approve し、Enable auto-merge を有効にしてくれる。これにより、PR がすべてのチェックをパスすると自動的にマージされるようになる。

*1:Dependabot には GitHub ネイティブのものと、そうでないものの2種類がある。GitHub ネイティブのものは自動マージ機能が削除されている。

*2:https://github.com/dependabot/dependabot-core/issues/2229

*3:https://github.com/dependabot/dependabot-core/issues/1973#issuecomment-640918321

*4:デフォルトで設定されている secrets.GITHUB_TOKEN だと enablePullRequestAutoMerge が動かない