はじめに
Dependabotは、依存関係の更新を自動で行ってくれる便利なツールですが、毎回手動でプルリクエストを承認し、マージするのは手間です。そこで、GitHub Actionsを使用して、Dependabotが作成するプルリクエストを自動で承認し、すべてのチェックが成功した後に自動マージする方法を解説します。
また、ユニットテストやVercelのチェックやGitGuardianのチェックなどが成功する前にマージされると本番に影響してしまうので、下記のコードでは全部のワークフローが成功してからmergeされるように書いてます
設定ファイルの内容
このプロセスには、主に2つの設定ファイルが関与します。
1. dependabot-auto-approve.yml
このファイルは、Dependabotによるプルリクエストを自動で承認するためのワークフローです。
name: Dependabot auto-approve
on: pull_request
permissions:
pull-requests: write
jobs:
dependabot:
runs-on: ubuntu-latest
if: github.event.pull_request.user.login == 'dependabot[bot]' && github.repository == 'owner/repo'
steps:
- name: Dependabot metadata
id: metadata
uses: dependabot/fetch-metadata@v2.2.0
with:
github-token: "${{ secrets.GITHUB_TOKEN }}"
- name: Approve a PR
run: gh pr review --approve "$PR_URL"
env:
PR_URL: ${{ github.event.pull_request.html_url }}
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
2. dependabot-auto-merge.yml
このファイルは、すべてのステータスチェックが成功した場合にDependabotによるプルリクエストを自動でマージするためのワークフローです。
name: Dependabot auto-merge
on: pull_request
permissions:
contents: write
pull-requests: write
checks: read
actions: read
statuses: read
jobs:
dependabot:
runs-on: ubuntu-latest
if: github.event.pull_request.user.login == 'dependabot[bot]' && github.repository == 'owner/repo'
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
PR_URL: ${{github.event.pull_request.html_url}}
steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: SetUp auto-merge
id: auto-merge
uses: dependabot/fetch-metadata@v2.2.0
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
- name: Wait 5 minutes for other checks to complete
run: sleep 300
- name: Check if all workflows have passed
run: |
MAX_RETRIES=6
RETRY_INTERVAL=300 # 5分を秒で指定
ATTEMPT=0
CURRENT_WORKFLOW="Dependabot auto-merge"
while [ $ATTEMPT -lt $MAX_RETRIES ]; do
echo "Fetching PR status checks..."
WORKFLOWS=$(gh pr view "$PR_URL" --json statusCheckRollup -q '.statusCheckRollup')
# デバッグ: 各ステータスチェックの状態を出力
echo "Debug: Current status of all checks:"
WORKFLOW_STATUS=$(jq -r '[.[] | {name: (.workflowName // .name // .context), type: .["__typename"], status: .status, state: .state, conclusion: .conclusion}]' <<< "$WORKFLOWS")
# 現在のワークフロー以外のすべてのチェックが成功したか確認
all_passed=true
while IFS= read -r check; do
name=$(jq -r '.name' <<< "$check")
type=$(jq -r '.type' <<< "$check")
status=$(jq -r 'if .type == "CheckRun" then .conclusion else .state end' <<< "$check")
if [[ "$name" != "$CURRENT_WORKFLOW" && "$status" != "SUCCESS" ]]; then
all_passed=false
echo "Failed check: $name ($type) - Status: $status"
break
fi
done < <(echo "$WORKFLOW_STATUS" | jq -c '.[]')
if $all_passed; then
echo "All other checks have passed"
exit 0
else
echo "Some status checks have not passed. Attempt $((ATTEMPT + 1)) of $MAX_RETRIES."
echo "Retrying in $RETRY_INTERVAL seconds..."
sleep $RETRY_INTERVAL
ATTEMPT=$((ATTEMPT + 1))
fi
done
echo "Failed to merge the PR after $MAX_RETRIES attempts due to failing status checks."
exit 1
- name: Auto-merge for Dependabot PRs
run: gh pr merge --auto --merge "$PR_URL"
設定ポイント
自動承認 (dependabot-auto-approve.yml
)
- イベントのトリガー: プルリクエストが作成されると自動的にワークフローが実行されます。
-
権限設定:
permissions
でpull-requests: write
を指定し、プルリクエストに対する書き込み権限を持たせます。 - 承認処理: Dependabotが作成したプルリクエストを自動的に承認します。
自動マージ (dependabot-auto-merge.yml
)
- 他のワークフローを待つ: 初期実行は他のワークフローが走りだしたばっかなので、5分待ってから下記の処理を開始します。
- ステータスチェックの確認: ステータスチェックが全て成功するまで最大6回リトライを行い、5分ごとに再試行します。
- 自動マージ処理: ステータスチェックが全て成功した場合に自動的にマージを行います。
注意点
-
依存関係のメタデータ:
dependabot/fetch-metadata
は最新のバージョンを使用することを推奨します。 -
チェックの結果:
__typename
によって、成功(SUCESS)を示す項目が異なることに注意が必要です。CheckRun
の場合はconclusion
に、StatusContext
の場合はstate
に結果が格納されてる。 - github.repositoryに自分のアカウント/リポジトリを入れる
まとめ
このように、GitHub Actionsを利用することで、Dependabotによるプルリクエストを自動で承認し、必要なチェックが成功した後に自動マージすることができます。これにより、開発プロセスをスムーズに進めることができ、手動での介入を減らすことが可能になります。
基本的なDependabotなどの説明は割愛してるので、他の記事を参考に試してみてください!
参考資料
https://github.com/dependabot/fetch-metadata
https://docs.github.com/ja/actions/writing-workflows/about-workflows
https://docs.github.com/en/actions/writing-workflows/choosing-what-your-workflow-does/controlling-permissions-for-github_token