From 13762fc6d99e523ee295ea884acb3083e9f9f97b Mon Sep 17 00:00:00 2001 From: Pieter Viljoen Date: Fri, 28 Aug 2026 06:15:22 -0700 Subject: [PATCH 1/2] Retry the prose gate's diff-base resolve on a fresh merge tip A freshly created merge commit used as a diff base can miss a git rev-parse lookup for a short window after the caller's own unshallow fetch already lists it as a branch tip, per ProjectTemplate#1049. Retry the resolve check with backoff (0/2/4/8/15/30s) before failing, so replication lag reads as a slow resolve rather than a gate failure with nothing wrong in the change. Fixes #1049 --- .github/actions/prose-gate/action.yml | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/.github/actions/prose-gate/action.yml b/.github/actions/prose-gate/action.yml index e8f9fbe6..bb3d1349 100644 --- a/.github/actions/prose-gate/action.yml +++ b/.github/actions/prose-gate/action.yml @@ -23,7 +23,21 @@ runs: # Check the base resolves before scanning, so an empty or absent ref fails naming itself. # Unresolvable, the run would report the repository's whole backlog against this change. # A shallow checkout is the usual cause, so the caller fetches full history. - if ! git rev-parse --verify --quiet "$BASE^{commit}" >/dev/null; then + # A base that is a merge commit created moments before this run can still miss on the first look. + # ProjectTemplate#1049 saw the caller's own unshallow fetch list the commit as a branch tip while the object itself was not yet fetchable, minutes after a squash-merge created it. + # Retry with backoff before failing, so that replication lag reads as a slow resolve rather than a gate failure with nothing wrong in the change. + resolved=false + for delay in 0 2 4 8 15 30; do + if [ "$delay" -gt 0 ]; then + sleep "$delay" + git fetch --quiet origin "$BASE" 2>/dev/null || true + fi + if git rev-parse --verify --quiet "$BASE^{commit}" >/dev/null; then + resolved=true + break + fi + done + if ! "$resolved"; then echo "::error::Diff base '$BASE' does not resolve in this checkout." >&2 echo "::error::Check the ref name and that the job checks out with fetch-depth 0." >&2 exit 1 From 5cb7940a3105deffa76384c2bab0ce1d95b95a06 Mon Sep 17 00:00:00 2001 From: Pieter Viljoen Date: Fri, 28 Aug 2026 06:21:48 -0700 Subject: [PATCH 2/2] Trim the retry comment to one durable-reason line Per qodo review on PR #1050: keep the inline comment to the durable reason the retry exists, drop the ticket-specific incident narration and issue reference now that it lives in the PR description. --- .github/actions/prose-gate/action.yml | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/.github/actions/prose-gate/action.yml b/.github/actions/prose-gate/action.yml index bb3d1349..edca233c 100644 --- a/.github/actions/prose-gate/action.yml +++ b/.github/actions/prose-gate/action.yml @@ -23,9 +23,7 @@ runs: # Check the base resolves before scanning, so an empty or absent ref fails naming itself. # Unresolvable, the run would report the repository's whole backlog against this change. # A shallow checkout is the usual cause, so the caller fetches full history. - # A base that is a merge commit created moments before this run can still miss on the first look. - # ProjectTemplate#1049 saw the caller's own unshallow fetch list the commit as a branch tip while the object itself was not yet fetchable, minutes after a squash-merge created it. - # Retry with backoff before failing, so that replication lag reads as a slow resolve rather than a gate failure with nothing wrong in the change. + # A base that is a freshly created merge commit can still lag GitHub's own replication, so retry with backoff before failing rather than treat that lag as a gate failure. resolved=false for delay in 0 2 4 8 15 30; do if [ "$delay" -gt 0 ]; then