diff --git a/gstack-upgrade/migrations/v1.27.0.0.sh b/gstack-upgrade/migrations/v1.27.0.0.sh index fb1ce73ce8..f187a35b2e 100755 --- a/gstack-upgrade/migrations/v1.27.0.0.sh +++ b/gstack-upgrade/migrations/v1.27.0.0.sh @@ -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 "" + # 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 /$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 diff --git a/test/migrations-v1.27.0.0.test.ts b/test/migrations-v1.27.0.0.test.ts index 7a1a9908cc..1baa9097ba 100644 --- a/test/migrations-v1.27.0.0.test.ts +++ b/test/migrations-v1.27.0.0.test.ts @@ -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 + # gh repo view | shift ${alreadyRenamed ? `if echo "$@" | grep -q gstack-artifacts; then exit 0; else exit 1; fi` : `exit 1`} ;;