Gitee 也做成幂等:已存在就复用 + 先删同名附件

重发时 Gitee 直接 400「该标签已经存在发行版」,
而且拿不到 id,后面的附件也传不上。

改成和 EzHub 一样的流程:
先按标签查已有的(查到就复用 id),复用前删掉同名旧附件,再传。
这样重跑多少次,两边的附件数都稳定。
This commit is contained in:
xmz7891
2026-10-07 12:37:06 +08:00
parent 2425f8694e
commit ae7e1cf269
+56 -17
View File
@@ -99,24 +99,63 @@ def gitee_release(token: str, version: str, body: str,
api = "https://gitee.com/api/v5/repos/xmz7891/ykxmz"
tag = "v" + version
payload = json.dumps({
"access_token": token, "tag_name": tag,
"name": "ykxmz " + version, "body": body,
"target_commitish": "main", "prerelease": False,
}).encode("utf-8")
req = urllib.request.Request(
api + "/releases", data=payload, method="POST",
headers={"Content-Type": "application/json;charset=UTF-8",
"User-Agent": "ykxmz-release"})
# 先看标签有没有发行版。
# 不先查的话,重发会直接 400「该标签已经存在发行版」——
# 而且没有可复用的 id,后面的附件也就传不上。
rid = None
try:
with urllib.request.urlopen(req, timeout=90) as resp:
reply = json.loads(resp.read().decode("utf-8", "replace"))
rid = reply.get("id")
print(" ✓ 发行版已建 id=%s" % rid)
except urllib.error.HTTPError as exc:
detail = exc.read().decode("utf-8", "replace")[:300]
print(" ✗ 建发行版失败 HTTP %s: %s" % (exc.code, detail))
return False
with urllib.request.urlopen(
"%s/releases/tags/%s?access_token=%s" % (api, tag, token),
timeout=60) as resp:
rid = json.loads(resp.read().decode("utf-8", "replace")).get("id")
print(" • 该标签已有发行版 id=%s,复用" % rid)
except urllib.error.HTTPError:
pass
if not rid:
payload = json.dumps({
"access_token": token, "tag_name": tag,
"name": "ykxmz " + version, "body": body,
"target_commitish": "main", "prerelease": False,
}).encode("utf-8")
req = urllib.request.Request(
api + "/releases", data=payload, method="POST",
headers={"Content-Type": "application/json;charset=UTF-8",
"User-Agent": "ykxmz-release"})
try:
with urllib.request.urlopen(req, timeout=90) as resp:
reply = json.loads(resp.read().decode("utf-8", "replace"))
rid = reply.get("id")
print(" ✓ 发行版已建 id=%s" % rid)
except urllib.error.HTTPError as exc:
detail = exc.read().decode("utf-8", "replace")[:300]
print(" ✗ 建发行版失败 HTTP %s: %s" % (exc.code, detail))
return False
# 复用已有发行版时先把同名旧附件删掉,否则每跑一次多一份。
try:
with urllib.request.urlopen(
"%s/releases/%s?access_token=%s" % (api, rid, token),
timeout=60) as resp:
existing = json.loads(resp.read().decode("utf-8", "replace"))
wanted = {p.name for p in files}
# Gitee 叫 attach_files,Gitea 叫 assets
old_assets = (existing.get("assets")
or existing.get("attach_files") or [])
for asset in old_assets:
name = asset.get("name") or asset.get("filename")
aid = asset.get("id")
if name in wanted and aid:
del_url = ("%s/releases/%s/attach_files/%s"
"?access_token=%s" % (api, rid, aid, token))
dreq = urllib.request.Request(del_url, method="DELETE")
try:
urllib.request.urlopen(dreq, timeout=60)
print(" • 删掉同名旧附件 %s" % name)
except urllib.error.HTTPError as exc:
print(" • 删 %s 失败 HTTP %s(继续)" % (name, exc.code))
except Exception as exc: # noqa: BLE001
print(" • 清理旧附件时出错(继续): %s" % exc)
ok = 0
for path in files: