fix(ci): 发版 create_release/upload_asset 改幂等,重跑不再 409 崩
根因:release-client.sh 建 Release 非幂等——首跑已建好 Release+传齐产物但
deploy 未跑完时,retry 再 POST 同 tag 的 Release,Forgejo 回 409
("Release is has no Tag"),整个 release-deploy 在部署前就硬失败,发版卡死。
- create_release:撞 409 时改为按 tag 取回既有 Release 复用其 id 继续。
- upload_asset:同名 asset 已存在时先删旧再重传,避免重名 409。
重跑发版从此安全;免重编上线用 Manual Deploy(manual.yml)拉既有 Release 产物部署。
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Bupi8Kdqkfx2N5acFsHTx5
This commit is contained in:
@@ -50,6 +50,8 @@ PYEOF
|
||||
}
|
||||
|
||||
# create_release <tag> <body_json_string> — sets global RELEASE_ID on success.
|
||||
# 幂等:若该 tag 的 Release 已存在(重跑发版时 Forgejo 回 409),不再硬失败,
|
||||
# 改为取回既有 Release 复用其 id 继续(配合 upload_asset 的覆盖上传,重跑安全)。
|
||||
create_release() {
|
||||
local tag="$1" body="$2" http_code resp
|
||||
echo "==> release: creating Forgejo Release ${tag}"
|
||||
@@ -60,6 +62,15 @@ create_release() {
|
||||
-d "{\"tag_name\":\"${tag}\",\"name\":\"Release ${tag}\",\"body\":${body},\"draft\":false,\"prerelease\":false}")
|
||||
resp=$(cat /tmp/release_resp.json)
|
||||
echo "==> release: API response (HTTP ${http_code}): ${resp}"
|
||||
if [ "$http_code" = "409" ]; then
|
||||
# Release 已存在(重跑)→ 幂等复用:按 tag 取回既有 Release。
|
||||
echo "==> release: 该 tag 的 Release 已存在,改为复用(幂等重跑)"
|
||||
http_code=$(curl -k -w "%{http_code}" -o /tmp/release_resp.json \
|
||||
-H "Authorization: token ${FORGEJO_TOKEN}" \
|
||||
"${FORGEJO_URL}/api/v1/repos/${GITEA_REPOSITORY}/releases/tags/${tag}")
|
||||
resp=$(cat /tmp/release_resp.json)
|
||||
echo "==> release: 既有 Release 查询 (HTTP ${http_code}): ${resp}"
|
||||
fi
|
||||
if [ "$http_code" -lt 200 ] || [ "$http_code" -ge 300 ]; then
|
||||
echo "==> release: FAILED — HTTP ${http_code}" >&2
|
||||
return 1
|
||||
@@ -69,8 +80,18 @@ create_release() {
|
||||
}
|
||||
|
||||
# upload_asset <file> — requires RELEASE_ID.
|
||||
# 幂等:若同名 asset 已存在(重跑),先删旧再传新,避免 Forgejo 409 重名冲突。
|
||||
upload_asset() {
|
||||
local file="$1" code
|
||||
local file="$1" code name existing_id
|
||||
name=$(basename "$file")
|
||||
existing_id=$(curl -ks -H "Authorization: token ${FORGEJO_TOKEN}" \
|
||||
"${FORGEJO_URL}/api/v1/repos/${GITEA_REPOSITORY}/releases/${RELEASE_ID}/assets" \
|
||||
| python3 -c "import sys,json; a=json.load(sys.stdin); print(next((str(x['id']) for x in a if x.get('name')==sys.argv[1]), ''))" "$name" 2>/dev/null || true)
|
||||
if [ -n "$existing_id" ]; then
|
||||
echo "==> release: asset ${name} 已存在(id=${existing_id}),先删旧再重传"
|
||||
curl -ks -X DELETE -H "Authorization: token ${FORGEJO_TOKEN}" \
|
||||
"${FORGEJO_URL}/api/v1/repos/${GITEA_REPOSITORY}/releases/${RELEASE_ID}/assets/${existing_id}" >/dev/null || true
|
||||
fi
|
||||
code=$(curl -k -w "%{http_code}" -o /tmp/upload_resp.json \
|
||||
-X POST "${FORGEJO_URL}/api/v1/repos/${GITEA_REPOSITORY}/releases/${RELEASE_ID}/assets" \
|
||||
-H "Authorization: token ${FORGEJO_TOKEN}" \
|
||||
|
||||
Reference in New Issue
Block a user