Add dependabot PR diff-comparing workflow - #2030
Draft
arx-ein wants to merge 5 commits into
Draft
Conversation
|
🚀 Deployed on https://deploy-preview-2030--utelecon.netlify.app |
added 4 commits
September 5, 2026 18:17
- Summarize the comparison with a diff -rq file list instead of dumping the raw diff, which is unreadable for minified output; upload the full diff as an artifact - Add include-hidden-files to upload-artifact so dot-files are compared - Guard the compare job with the same dependabot[bot] condition - Use setup-node's built-in npm cache instead of a separate cache step - Add a concurrency group to cancel superseded runs
The pull_request event from Dependabot gets a read-only GITHUB_TOKEN, so the workflow that builds the pull request cannot write to it. Move the reporting into a separate workflow_run workflow, which runs the master version of the file and never executes pull request code. review-dependabot-prs.yml builds and compares, then leaves the result in an artifact. report-dependabot-review.yml reads that artifact and posts a sticky comment; set MODE to approve or both to also approve when the build output is identical. Rename dependabot.yml to review-dependabot-prs.yml so it is not confused with .github/dependabot.yml, the Dependabot configuration file.
If the build fails, the compare job never runs and no report artifact is produced. Resolve the pull request number from the workflow_run payload instead, so a stale approval is dismissed and the comment says the comparison could not be made.
The pull request body describes comparing the build output of master against the build output of the pull request merged into master, but the workflow was checking out head.sha, which is the tip of the pull request branch. Use refs/pull/N/merge for the pull request side. The base side has to come from the same merge commit: base.sha is frozen when the event fires while the merge ref is recomputed separately, so mixing them reports unrelated master changes as differences.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Dependabot による Pull Request のレビュー (生成物の diff 比較) を自動で行う GitHub Actions workflow を追加します。
概要
Dependabot の PR に対して、master のビルド成果物と PR のビルド成果物を
diffで比較するGitHub Actions workflow を追加します。差分がなければ check passed、差分があれば check failed
となり、人間がレビューする、という運用を想定しています。
これまで各自が手元で「master と PR ブランチをそれぞれビルドして
diff -rする」という手順を実施していたものを、そのまま CI に載せた形です。
workflow は2本に分かれています。
review-dependabot-prs.yml— ビルドと比較(書き込み権限なし)build_basedist-baseとして artifact 化build_prdist-prとして artifact 化comparediff -r/diff -rq。差分があれば exit 13ジョブとも
github.event.pull_request.user.login == 'dependabot[bot]'のガードが付いており、通常の PR では全ジョブが skip されます。
report-dependabot-review.yml— PR への報告(書き込み権限あり)Dependabot 起点の
pull_requestイベントではGITHUB_TOKENが read-only になり、Secrets も渡されません。PR のコードを
npm ciで実行する以上これは妥当な制限で、したがってビルドする側の workflow から PR にコメントや approve はできません。
そこで比較結果を artifact に出し、
workflow_runで発火する別 workflow がpull-requests: writeを持って報告を担当する構成にしました。この workflow はmaster 側のファイルが使われ、PR のコードを一切実行しません。
なお
pull_request_targetは、書き込み権限を持ったまま PR のコードを実行することになるため使用していません。
動作は環境変数で切り替えられます。
現在は
comment(結果を PR にコメントするだけ)にしてあります。動作検証について
この PR は本家では一度も実行されていません(この PR 自体が Dependabot 発ではないため
全ジョブが skip されます)。そのため fork (hyper1FU/utelecon.github.io) 上で
ifの条件を自分のアカウント名に差し替えて検証しました。基本動作
3ジョブとも最後まで通ります。所要時間は約6分(2つのビルドが並列で約5分、比較が25秒〜1分半)。
ビルドは決定的でした。中身を変えていない PR では diff が完全に空になります。
ビルド時刻やコミットハッシュが成果物に埋め込まれる、といった問題はありません。
この仕組みの大前提が満たされていることを確認できました。
actions/upload-artifactは v4 以降ドット始まりのファイルをデフォルトで除外するため、include-hidden-files: trueを追加しています。これがないと隠しファイルが比較対象から漏れます。open な Dependabot PR 15件の実測
現在 open な Dependabot PR すべてについて、master に適用した場合の差分を測りました。
数字は差分のあったファイル数です。
ビルドが通る12件のうち11件が差分ゼロでした。
rollup で出た差分の内容
唯一差分が出た rollup について、849ファイル全件を機械的に検証しました。
rollup が変えたのは、インライン CSS を何個の
<style>要素に分けるかと、ルールをどの順に並べるかだけでした。CSS のルールそのものは1バイトも変わっていません。
例外の1ファイルは
good-practice/index.htmlで、差分は参照している JS のファイル名だけです(
client.D2WMwoKK.js→client.SBHmtuwi.js)。その JS 本体も差し替わっています。Astro はファイル名に中身から計算したハッシュを含めるため、名前が変わった = 中身が変わった、
ということです。
CSS のルール順はカスケードに影響し得るため、機械的に無視してよい差分ではありません。
「差分あり → 人がレビュー」という設計自体は妥当だと考えます。
astro を含む3件について
astro を含む3件は、比較以前にビルドが通りません。
integrations/ignore-assets/index.tsのTESTED_ASTRO_VERSION_RANGEの上限が現行 master の astro バージョンちょうど(5.18.1)で、astro が上がれば必ず落ちる設計です。
astro 7 で
ignore-assets/asset-colocationの動作確認をして定数を更新しない限りマージできません。
この workflow の観点では3件とも check が失敗するので、見落とすことはありません。
サマリの出力方式について
rollup の diff は 19,218,645 バイト / 10,223 行になりました。minify 済みのため1行が
平均 1.9KB あり、当初の
head -c 60000では全体の 0.3% しか表示できません。diff -rqによるファイル名一覧と件数をサマリに出し、全文は artifact に置いてそちらを参照させる方式に変更しています。
承認の状態管理について
MODEをapproveまたはbothにした場合、承認したあとに PR の中身が変わるケース(Dependabot が rebase する、より新しいバージョンで差し替わる等)に備えて、
Bot 自身の承認を取り消す処理を入れてあります。取り消すのは Bot の承認だけで、
人によるレビューには触れません。
通常はブランチ保護の「新しいコミットで既存のレビューを無効化する」設定で行うところですが、
このリポジトリにはブランチ保護がないため workflow 側で行っています。
以下の遷移は fork で確認済みです。
コメントは毎回同じものを上書きするので、PR に積み上がりません。
なお
MODEにapproveを含める場合、リポジトリ設定の「Allow GitHub Actions to create and approve pull requests」を有効にする必要があります
(デフォルトは無効で、そのままでは 422 で失敗します)。
netlify.yml とのビルド重複について
netlify.yml も PR ごとに
npm run buildを実行しているため、Dependabot の PR 1件につき
npm run buildが3回走ることになります(netlify / build_pr / build_base)。
netlify の成果物を再利用するには netlify.yml 側に
upload-artifactを追加し、この workflow を
workflow_runで受ける構成が必要になりますが、全体が読みにくくなります。重複は認識した上で、独立させたほうが単純で堅いと判断してこの構成にしています。
(
build_base(master のビルド)については、他に実行している workflow がないため純粋に新規の実行です。)
確認したい点
1. 比較対象をマージ後の状態に変更しました(事後報告)
元の実装は
base.shaとhead.shaを比較していました。head.shaは PR ブランチの先端で、master にマージした状態ではありません。この PR の説明文および Slack での議論は
「マージした際のビルド成果物」と述べており、江利口さんのスクリプトも
git merge --no-commit --no-ffでマージ後の状態を作って比較しているため、実装のほうを合わせました。
base 側も変える必要がある点が要注意です。
base.shaはイベント発生時点で固定される一方、マージ ref は GitHub が別のタイミングで再計算します。両者がズレると、
PR と無関係な master の変更を差分として拾います。fork で再現したところ、
master に1ページ追加した状態で以下のようになりました。
merge^1とmergeは同じマージコミットの親子なので、定義上ズレません。netlify.yml も
refs/pull/N/mergeを使っています。なお、
@dependabot rebaseを先に打つ運用にすれば PR ブランチ自体が最新 master の上に載るため、
head.shaのままでもマージ後に近い状態を比較できます(孫さんの案)。ただし手動コマンドを挟むことになるため、CI 側で完結する形を採りました。
この判断でよいかご確認ください。
2. 自動承認の条件をどうするか
現状 master にブランチ保護が掛かっておらず、承認ゼロのままマージされている PR が
大半です。つまり approve はマージの条件になっていないため、Bot が approve しても
人の作業は減りません。
その意味では、コメントで結果を伝えるだけでも目的は足りている可能性があります。
approve に意味が出るのは、ブランチ保護でレビューを必須にした上で auto-merge を使い、
人手を介さずマージまで完了させる場合です。
MODEの値をどうするか、ご意見をいただきたいです。別件として提案したいこと
.node-versionの導入リポジトリに
.node-version/.nvmrc/package.jsonのenginesはいずれも存在せず、node-version: 24が netlify.yml / astro.yml / この workflow に直書きされています。Slack で「Node v24 であることを確認(はじめはしていなくて躓いた)」という話が出ていた通り、
一元管理がないことによる実害が既に出ています。
.node-versionを導入してnode-version-fileに統一することを別 issue として提案したいですが、この PR では既存に合わせて直書きのままにしています(この PR だけ変えると浮くため)。
web_developmentラベルの自動付与.github/dependabot.ymlを追加すれば実現できます。これは #2030 とは独立しているので、別 PR として出すのがよいと考えています。
astro のバージョンゲート
TESTED_ASTRO_VERSION_RANGEに引っかかる3件は、astro 7 での動作確認が必要です。別 issue として切るのがよさそうです。