From d726682be466bb8626047cfa1ee8e4bd5003a1a5 Mon Sep 17 00:00:00 2001 From: atlas Date: Wed, 16 Sep 2026 19:35:55 +0200 Subject: [PATCH] check-attribution-trailers.sh: resolve base ref regardless of remote name Hardcoding origin/main broke in any checkout whose remote isn't named origin (e.g. an agent worktree, whose remote is renamed to forge). Try BASE_REF if set, else every configured remote in a stable order (origin first to match CI, then the rest alphabetically), fetching each remote's copy of the base branch if not already present. If nothing resolves, exit 1 with a clear message rather than falling back to any guessed range - an unresolvable base must never read as a clean pass. Refs #4449 --- scripts/check-attribution-trailers.sh | 58 ++++++++++++++++++++------- 1 file changed, 44 insertions(+), 14 deletions(-) diff --git a/scripts/check-attribution-trailers.sh b/scripts/check-attribution-trailers.sh index 9f5032f9..6748e640 100755 --- a/scripts/check-attribution-trailers.sh +++ b/scripts/check-attribution-trailers.sh @@ -16,22 +16,52 @@ set -eu trailer_re='^[[:space:]]*co-authored-by:.*(claude|anthropic|noreply@anthropic\.com)' -if [ -n "${GITHUB_BASE_REF:-}" ]; then - base="origin/${GITHUB_BASE_REF}" -else - base="origin/main" -fi +branch="${GITHUB_BASE_REF:-main}" -# actions/checkout@v3 fetches the PR head but may not fetch the base branch -if ! git rev-parse --verify "$base" >/dev/null 2>&1; then - branch="${base#origin/}" - git fetch origin "$branch" 2>/dev/null || true - if ! git rev-parse --verify "$base" >/dev/null 2>&1; then - base="origin/main" - if ! git fetch origin main 2>/dev/null || ! git rev-parse --verify "$base" >/dev/null 2>&1; then - echo 'check-attribution-trailers: base ref unresolvable — cannot fetch origin/main to diff against, refusing to guess a commit range' >&2 - exit 1 +# Remote name varies by checkout — CI's actions/checkout@v3 names it +# `origin`, but an agent worktree renames its remote to `forge` (see the +# hive's subagent briefs). Hardcoding `origin/` here made the script +# unresolvable, and unresolvable, in the old code, silently read as clean +# (fetch-or-`true`, then a fallback to `HEAD~10`) — that fail-open was the +# actual bug. So: try `BASE_REF` if the caller set one, then every +# configured remote in a stable order (an `origin` remote first, to match +# CI, then the rest alphabetically), fetching a remote's copy of `branch` +# if it isn't already present locally. If none of that resolves a base, +# exit 1 with a clear message — never guess a commit range. +base="" +if [ -n "${BASE_REF:-}" ]; then + if git rev-parse --verify "$BASE_REF" >/dev/null 2>&1; then + base="$BASE_REF" + else + echo "check-attribution-trailers: BASE_REF=$BASE_REF does not resolve" >&2 + exit 1 + fi +else + remotes="$(git remote)" + ordered_remotes="" + case " $remotes " in + *" origin "*) ordered_remotes="origin" ;; + esac + for r in $(printf '%s\n' "$remotes" | sort); do + [ "$r" = "origin" ] && continue + ordered_remotes="${ordered_remotes:+$ordered_remotes }$r" + done + + for remote in $ordered_remotes; do + candidate="refs/remotes/${remote}/${branch}" + if ! git rev-parse --verify "$candidate" >/dev/null 2>&1; then + # actions/checkout@v3 fetches the PR head but may not fetch the base branch + git fetch "$remote" "$branch" 2>/dev/null || true fi + if git rev-parse --verify "$candidate" >/dev/null 2>&1; then + base="$candidate" + break + fi + done + + if [ -z "$base" ]; then + echo "check-attribution-trailers: base ref unresolvable — no configured remote has a '${branch}' ref (tried: ${remotes:-none}), refusing to guess a commit range" >&2 + exit 1 fi fi