dependabotのPRに自動でビルド成果物をコミットする
ビルド成果物をリポジトリに含める必要がある場合、どのタイミングでコミットするかが問題になります。 例えばGitHub Actionsのように、JavaScriptの成果物をリポジトリに含める必要があるようなケースです。 リリースを打つ時にビルド成果物をコミットするという方法もありますが、この記事ではメインブランチへのマージ時にはビルドしないといけないという前提があることにします。
人間がPRを出す場合は手元からビルドして成果物も一緒にコミットできますが、dependabotのようなbotにはビルドをさせることができません。 しかし、GitHub Actionsを使えば、dependabotのPRに対してもビルド成果物をコミットすることができます。
name: CI on: push: branches: - main pull_request: jobs: test: name: Test runs-on: ubuntu-latest permissions: contents: read steps: - name: Checkout code uses: actions/checkout@v4 with: ref: ${{ github.event.pull_request.head.sha || github.sha }} token: ${{ secrets.DEPENDABOT_TOKEN || secrets.GITHUB_TOKEN }} fetch-depth: ${{ github.actor == 'dependabot[bot]' && 2 || 1 }} - name: Setup Node.js uses: actions/setup-node@v4 with: node-version: 20 cache: npm - name: Install Dependencies run: npm ci - name: Run tests run: npm run test - name: Build run: npm run build - name: Check for dist changes id: dist-changes run: git diff --exit-code - name: Push dist changes for dependabot if: github.actor == 'dependabot[bot]' && failure() && steps.dist-changes.outcome == 'failure' run: | git config user.name "$(git show -s --format=%an)" git config user.email "$(git show -s --format=%ae)" git commit --all --amend --no-edit git push --force origin "HEAD:${GITHUB_HEAD_REF}"
GITHUB_TOKEN
の権限を強めたくないので、permissions
は読み取り権限のみにしています。Dependabot secretを使うことで、dependabotのPRでしか利用できないシークレットを設定できます。このシークレットには該当リポジトリへのwrite権限を付与したアクセストークンを設定しておきます。pull_request
イベントでactions/checkout
を使うと、マージコミットをチェックアウトしてしまいます。今回はPRにコミットを積みたいので、ref
にgithub.event.pull_request.head.sha
とpush
イベント時のフォールバックを指定します。- あとはテストとビルドを行います。そしてビルド成果物が変更されているかを確認し、もし変更があればdependabotのPRにコミットします。今回はパッケージの更新コミットにamendしたかったので、
push --force
で更新しています。また、fetch-depth
も2にしています。もしamendしない場合はpush --force
も不要でfetch-depth
を指定しないでも問題ありません。
ポイントはチェックアウトするときのref
と、Dependabot secretを使うことでしょうか。
GitHub Actionsがそうなのですが、ビルド成果物をコミットしなければならないというシチュエーションはそもそも珍しいかもしれません。
しかし、Dependabot secretの存在を知っておくと、dependabotのPRにのみ利用できるシークレットを設定できるのでとても便利ですね。
それではまた!