From 848e180d8e5d7b62aba8ab74e491316f8ab06e57 Mon Sep 17 00:00:00 2001 From: Claude Date: Mon, 13 Jul 2026 06:51:53 +0000 Subject: [PATCH] fix(autofix): exit cleanly when dispatched PR is no longer conflicted MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The conflict-resolution path of pr-review-autofix.yml failed run 29183204869 with "No merge is in progress after the base merge; refusing to push." when merging the base into the head returned "Already up to date." (no MERGE_HEAD, no conflicted files). That happens when the PR stopped being conflicted between scheduler dispatch and worker execution, e.g. after a head refresh — there is nothing to resolve and nothing to push, so it must be a no-op success, not a failure. Add an explicit branch right after the base merge: if MERGE_HEAD is absent AND there are no conflicted files, no staged or unstaged changes, and no untracked files, log the reason and exit 0. If MERGE_HEAD is absent but the tree is not clean, keep failing closed with an explicit error plus git status output. The existing fail-closed guards (conflict-marker scan, MERGE_HEAD check before push, live-head comparison) are unchanged. Verified: full pytest suite (386 passed) including the pr-review-autofix contract pins, YAML parse, and a local git simulation of both the already-up-to-date no-op and the diverged-base merge-in-progress paths. Co-Authored-By: Claude Fable 5 Claude-Session: https://claude.ai/code/session_01Hw6V6hgwiNNe74eSCFymtP --- .github/workflows/pr-review-autofix.yml | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/.github/workflows/pr-review-autofix.yml b/.github/workflows/pr-review-autofix.yml index 2aa253ba..877afa21 100644 --- a/.github/workflows/pr-review-autofix.yml +++ b/.github/workflows/pr-review-autofix.yml @@ -472,6 +472,24 @@ jobs: conflicted_files="$(git diff --name-only --diff-filter=U || true)" printf 'Conflicted files:\n%s\n' "${conflicted_files:-}" + # No-op success path: the base is already contained in the head + # (git reports "Already up to date"), so there is no merge in + # progress, no conflicts, and nothing to resolve or push. This + # happens when the PR stopped being conflicted between scheduler + # dispatch and worker execution (e.g. the head was refreshed). + if ! git rev-parse -q --verify MERGE_HEAD >/dev/null 2>&1; then + if [ -z "$conflicted_files" ] \ + && git diff --quiet \ + && git diff --cached --quiet \ + && [ -z "$(git ls-files --others --exclude-standard)" ]; then + echo "Base ${PR_BASE_REF} (${PR_BASE_SHA}) is already merged into head ${PR_HEAD_SHA}; no conflict resolution needed. Exiting as a no-op." + exit 0 + fi + echo "::error::Base merge left no merge in progress but the working tree is not clean; refusing to continue." + git status --short + exit 1 + fi + if [ -n "$conflicted_files" ]; then prompt_file="${RUNNER_TEMP}/opencode-conflict-prompt.md" cat >"$prompt_file" <