publish-package: read current link state before re-linking

Gitea's /-/link/{repo} endpoint returns HTTP 400 "invalid argument"
whenever the package already has ANY linked repo, and /-/unlink returns
the same 400 when nothing is linked. Both are non-idempotent. Fix by
GET-ing the package version first, comparing the current repository to
the target, and only unlinking/linking when the state actually needs to
change. Idempotent across repeated publishes of the same image.
This commit is contained in:
lyn
2026-04-15 11:03:32 +00:00
parent 7745bc8bbc
commit 1e7af09245

View File

@@ -118,6 +118,35 @@ do_docker() {
fi
fi
# Gitea's link/unlink endpoints are not idempotent: POST /-/link/{repo}
# returns HTTP 400 "invalid argument" when the package already has ANY link
# (even to the same repo), and POST /-/unlink returns 400 when nothing is
# linked. So read the current link first and branch accordingly.
TARGET_LINK="${REPO_OWNER}/${REPO_NAME}"
STATE_RESP=$(curl -s -w "\n%{http_code}" -u "${OWNER}:${TOKEN}" \
"https://git.hangman-lab.top/api/v1/packages/${OWNER}/container/${IMAGE}/${TAG}")
STATE_STATUS=$(printf "%s" "$STATE_RESP" | tail -n1)
STATE_BODY=$(printf "%s" "$STATE_RESP" | sed '$d')
CURRENT_LINK=""
if [[ "$STATE_STATUS" == "200" ]]; then
CURRENT_LINK=$(printf "%s" "$STATE_BODY" | python3 -c \
'import sys, json; p=json.load(sys.stdin); r=p.get("repository") or {}; print(r.get("full_name") or "")' \
2>/dev/null || echo "")
fi
if [[ "$CURRENT_LINK" == "$TARGET_LINK" ]]; then
echo "Package already linked to ${TARGET_LINK}, skipping link step."
else
if [[ -n "$CURRENT_LINK" ]]; then
echo "Package currently linked to ${CURRENT_LINK}, unlinking first..."
UNLINK_STATUS=$(curl -s -o /dev/null -w "%{http_code}" -X POST -u "${OWNER}:${TOKEN}" \
"https://git.hangman-lab.top/api/v1/packages/${OWNER}/container/${IMAGE}/-/unlink")
if [[ "$UNLINK_STATUS" != "204" ]]; then
echo "Warning: unlink returned HTTP $UNLINK_STATUS, proceeding with link attempt anyway..."
fi
fi
LINK_RESP=$(curl -s -w "%{http_code}" -X POST \
-u "${OWNER}:${TOKEN}" \
"https://git.hangman-lab.top/api/v1/packages/${OWNER}/container/${IMAGE}/-/link/${REPO_NAME}")
@@ -130,6 +159,9 @@ do_docker() {
else
echo "Warning: package link failed (HTTP $LINK_STATUS): $LINK_BODY"
fi
else
echo "Linked package to ${TARGET_LINK}."
fi
fi
lock-mgr release "$LOCKFILE" "$KEY"