fix(v1.27 migration): qualify repo with owner so gh rename actually runs

`gh repo rename --repo` and `gh repo edit` both require the
"[HOST/]OWNER/REPO" form. The v1.27.0.0 migration was passing a bare
repo name (e.g. `gstack-brain-Brandon`), which `gh` rejects with:

  expected the "[HOST/]OWNER/REPO" format, got "gstack-brain-Brandon"

Both invocations suppressed stderr with `2>/dev/null`, so the failure
surfaced only as the generic "repo may not exist or permission denied"
warning — misdirecting users who actually have ADMIN on the repo.
The step was then `mark_done`'d, so re-running the upgrade does not
retry. The local pointer at ~/.gstack-artifacts-remote.txt ends up
referencing a non-existent repo until the user notices.

Reproduction (before fix):

  $ gh repo rename gstack-artifacts-Brandon --repo gstack-brain-Brandon --yes
  expected the "[HOST/]OWNER/REPO" format, got "gstack-brain-Brandon"

Fix: resolve the authenticated user's login via `gh api user --jq .login`
and qualify both the existing-repo check (`gh repo view`) and the
rename/edit calls. Capture stderr from each attempt so the warning
includes the real `gh` error instead of a generic guess.

The fake-gh test fixture grows a single case for `gh api user` so the
existing test matrix continues to drive the rename path.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
Brandon Pugsley 2026-05-11 18:03:08 -04:00
parent 74895062fb
commit 3c64fbf405
2 changed files with 42 additions and 10 deletions

View File

@ -184,19 +184,42 @@ if ! journal_done "gh_repo_renamed"; then
case "$HOST" in
github)
if command -v gh >/dev/null 2>&1 && gh auth status >/dev/null 2>&1; then
# Idempotent: if new name already exists, treat as success.
if gh repo view "$NEW_REPO_NAME" >/dev/null 2>&1; then
echo " repo already named $NEW_REPO_NAME on GitHub — no-op" >&2
# `gh repo rename --repo` and `gh repo edit` both require the
# "[HOST/]OWNER/REPO" form. Passing a bare repo name (as earlier
# versions of this migration did) fails with:
# expected the "[HOST/]OWNER/REPO" format, got "<name>"
# Resolve the authenticated user's login and qualify both names.
GH_OWNER=$(gh api user --jq .login 2>/dev/null || echo "")
if [ -z "$GH_OWNER" ]; then
echo " WARNING: could not resolve gh authenticated user — skipping rename" >&2
echo " manual: gh repo rename $NEW_REPO_NAME --repo <owner>/$OLD_REPO_NAME --yes" >&2
mark_done "gh_repo_renamed"
else
if gh repo rename "$NEW_REPO_NAME" --repo "$OLD_REPO_NAME" --yes 2>/dev/null \
|| gh repo edit "$OLD_REPO_NAME" --name "$NEW_REPO_NAME" 2>/dev/null; then
echo " renamed on GitHub" >&2
OLD_QUALIFIED="${GH_OWNER}/${OLD_REPO_NAME}"
NEW_QUALIFIED="${GH_OWNER}/${NEW_REPO_NAME}"
# Idempotent: if new name already exists, treat as success.
if gh repo view "$NEW_QUALIFIED" >/dev/null 2>&1; then
echo " repo already named $NEW_REPO_NAME on GitHub — no-op" >&2
mark_done "gh_repo_renamed"
else
echo " WARNING: gh rename failed (repo may not exist or permission denied)" >&2
echo " skipping step 1; subsequent steps still run" >&2
mark_done "gh_repo_renamed"
RENAME_ERR=""
RENAME_ERR2=""
RENAME_OK=0
if RENAME_ERR=$(gh repo rename "$NEW_REPO_NAME" --repo "$OLD_QUALIFIED" --yes 2>&1); then
RENAME_OK=1
elif RENAME_ERR2=$(gh repo edit "$OLD_QUALIFIED" --name "$NEW_REPO_NAME" 2>&1); then
RENAME_OK=1
fi
if [ "$RENAME_OK" = "1" ]; then
echo " renamed on GitHub" >&2
mark_done "gh_repo_renamed"
else
echo " WARNING: gh rename failed for $OLD_QUALIFIED" >&2
[ -n "$RENAME_ERR" ] && echo " gh repo rename: $RENAME_ERR" >&2
[ -n "$RENAME_ERR2" ] && echo " gh repo edit: $RENAME_ERR2" >&2
echo " skipping step 1; subsequent steps still run" >&2
mark_done "gh_repo_renamed"
fi
fi
fi
else

View File

@ -27,11 +27,20 @@ function makeFakeGh(opts: { authStatus?: 'ok' | 'fail'; renameSucceeds?: boolean
echo "gh $@" >> "${callLog}"
case "$1" in
auth) ${authStatus === 'ok' ? 'exit 0' : 'exit 1'} ;;
api)
# gh api user --jq .login print authenticated login
shift
if [ "\${1:-}" = "user" ]; then
echo "testuser"
exit 0
fi
exit 0
;;
repo)
shift
case "$1" in
view)
# gh repo view <name>
# gh repo view <owner/name> | <name>
shift
${alreadyRenamed ? `if echo "$@" | grep -q gstack-artifacts; then exit 0; else exit 1; fi` : `exit 1`}
;;