Fix auto-skip detection in build-staged.yml#81
Conversation
The previous diff direction (HEAD^2..HEAD) compared the PR head against the synthetic merge commit, which only returns changes that landed on base since the PR branched off — typically empty or docs-only. As a result, DOCS_ONLY stayed true and every PR got auto-skipped regardless of what it actually changed. Use HEAD^1..HEAD^2 (base..PR head) instead, which is the PR's actual diff. Add a comment explaining why, since the merge-commit parent semantics are easy to get wrong.
There was a problem hiding this comment.
Pull request overview
This PR fixes the auto-skip (“docs-only”) detection in the staged container build workflow by correcting how changed files are computed for pull_request runs, aligning the workflow behavior with the intended CI policy (skip only when PR changes are documentation-only).
Changes:
- Fixes the
git diffinvocation used to collect changed files for PRs. - Adds an inline comment explaining synthetic merge commit parent semantics to prevent regressions.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| # where HEAD^1 is the base (main) and HEAD^2 is the PR head. The PR's own | ||
| # changes are the diff from HEAD^1 to HEAD^2, NOT from HEAD^2 to HEAD | ||
| # (the latter only reflects changes that landed on base after the PR branched). | ||
| if [[ "$EVENT_NAME" == "pull_request" ]]; then | ||
| CHANGED_FILES=$(git diff --name-only HEAD^2 HEAD 2>/dev/null || git diff --name-only HEAD^ HEAD 2>/dev/null || echo "") | ||
| CHANGED_FILES=$(git diff --name-only HEAD^1 HEAD^2 2>/dev/null || git diff --name-only HEAD^ HEAD 2>/dev/null || echo "") |
Per Copilot review: HEAD^1..HEAD^2 (base..PR head) can include base-side changes since the PR branched, surfacing them as PR-side deletions and misclassifying a docs-only PR as needing a build. Use HEAD^1..HEAD (base..merge) instead — this represents exactly what the PR contributes on top of the current base, and is what the build will actually be testing. Expand the comment to document both failure modes (the original HEAD^2..HEAD bug and the HEAD^1..HEAD^2 edge case) so future maintainers see why we picked this form.
|
Copilot 指摘に対応しました (commit d060b0e)。 対応内容
指摘の妥当性
CI 検証修正版 (ee59bcc) の CI run 25669561988 は 52m49s で success、 コメントの拡充将来の保守者が同じ罠を踏まないよう、2 つの失敗モード ( |
| # Detect changed files for auto-skip detection. | ||
| # For pull_request events, GitHub Actions checks out a synthetic merge | ||
| # commit where HEAD^1 is the base (main) and HEAD^2 is the PR head. | ||
| # Diffing HEAD^1 against HEAD (the merge result) gives exactly what this | ||
| # PR would introduce on top of the current base; this avoids two failure | ||
| # modes of the previous logic: | ||
| # - HEAD^2..HEAD returned base-side changes since the PR branched, | ||
| # so non-doc PRs were misclassified as docs-only. | ||
| # - HEAD^1..HEAD^2 would, if main has advanced since the PR branched, | ||
| # surface those base-only changes as PR-side deletions and | ||
| # misclassify a docs-only PR as needing a build. | ||
| if [[ "$EVENT_NAME" == "pull_request" ]]; then | ||
| CHANGED_FILES=$(git diff --name-only HEAD^2 HEAD 2>/dev/null || git diff --name-only HEAD^ HEAD 2>/dev/null || echo "") | ||
| CHANGED_FILES=$(git diff --name-only HEAD^1 HEAD 2>/dev/null || git diff --name-only HEAD^ HEAD 2>/dev/null || echo "") | ||
| else | ||
| CHANGED_FILES=$(git diff --name-only HEAD^ HEAD 2>/dev/null || echo "") |
|
Copilot 指摘 (description と実装の乖離) に対応しました。 対応内容PR description を最新実装 ( なおこの修正は description のみで、ソースコードへの変更はありません。 CI 結果最新コミット d060b0e の CI run 25705473206 は 32m8s で success。 |
resolve #80
Summary
build-staged.ymlの auto-skip 検出が、PR の差分ではなく「PR 分岐後に base 側に追加された差分」を見ていたため、ほぼ全ての PR でDOCS_ONLY=trueと誤判定され、Dockerfile / TOML / yaml の変更すらビルドがスキップされていました。git diffの比較対象を base から merge commit (= 本 PR がテストする対象そのもの) に変更します。Root cause
GitHub Actions が
pull_requestイベントでチェックアウトする synthetic merge commit では:HEAD= merge commit (base と PR head を合成)HEAD^1= base (main)HEAD^2= PR head旧コード
git diff HEAD^2 HEADは PR head から merge commit への差分、つまり「base 側が PR 分岐後に追加した変更」を返します。main が静止している間は空 (もしくは docs-only) になり、PR がどんな変更をしていてもDOCS_ONLY=trueに倒れていました。Fix
git diff HEAD^1 HEAD(base → merge commit) に変更しました。これは「merge を取り込んだ後にレポジトリがどう変わるか」=「PR が base の上に追加する内容」を直接表します。なぜ
HEAD^1 HEAD^2ではなくHEAD^1 HEADなのか初期実装では
HEAD^1 HEAD^2(base → PR head) を採用していましたが、レビュー過程で次のエッジケースが指摘されました:new.cppを追加HEAD^1(current main) にはnew.cppありHEAD^2(PR head, frozen) にはnew.cppなしgit diff HEAD^1 HEAD^2でnew.cppが 削除として 検出されるHEAD^1 HEADなら merge 結果に base のすべての変更が既に取り込まれているので、上記のノイズが入りません。コミット d060b0e で改善しました。Changes
.github/workflows/build-staged.ymlL77: diff の比較対象をHEAD^2 HEAD→HEAD^1 HEADに修正HEAD^2..HEAD旧バグ /HEAD^1..HEAD^2のエッジケース) を説明するコメントを追加fetch-depth: 2のまま動作します (merge commit と 2 つの親はすべてフェッチ済み)。Verification
CI run (commit d060b0e)
run 25705473206 が 32m8s で success。
[build-all]タグなしで Lite ビルドが正常起動し、判定ログで以下を確認できました:過去の検証 (commit ee59bcc, 初期実装の HEAD^1 HEAD^2)
run 25669561988 が 52m49s で success。base が進んでいない単純ケースでは旧実装でも動作していたが、エッジケース耐性のため d060b0e で更に改善しました。
Test plan
determine-strategyログでDocumentation-only change: falseを確認[build-all]タグなしで)影響範囲