diff --git a/scripts/release/sync-to-gitee.sh b/scripts/release/sync-to-gitee.sh index 1b7ba321..e7e7532e 100755 --- a/scripts/release/sync-to-gitee.sh +++ b/scripts/release/sync-to-gitee.sh @@ -62,44 +62,68 @@ fi [ -n "$release_id" ] || { echo "❌ Could not get/create Gitee release for ${VERSION}. Response: ${rel_json}" >&2; exit 1; } echo " Gitee release id = ${release_id}" -# ── Names already attached to this Gitee release (for idempotent re-runs) ───── -# Re-fetch the release so the asset list reflects a release we may have just -# created. Skipping already-present files makes a re-run upload only what is -# missing — so a previous run that timed out mid-upload can be repaired cheaply -# instead of re-uploading everything (and creating duplicate attachments). -existing_names="$(curl -fsSL "${base}/releases/${release_id}?access_token=${GITEE_TOKEN}" 2>/dev/null \ +# ── Mirror each artifact, verifying content so re-runs self-heal ───────────── +# Pull the current asset list (name + attach id + download url) so we can, per +# file: +# • skip it when it is already on Gitee AND byte-identical, +# • REPLACE it when present but stale (different bytes) — e.g. the darwin +# binaries are re-signed and so differ between GitHub and a prior mirror +# run, which breaks install.sh's checksums.txt verification on macOS, +# • upload it when missing. +# This brings the Gitee release into byte-for-byte agreement with $DIST_DIR, +# which the caller fills from the GitHub release whose checksums.txt is what +# install.sh verifies against. +assets_map="$(curl -fsSL "${base}/releases/${release_id}?access_token=${GITEE_TOKEN}" 2>/dev/null \ | python3 -c 'import json,sys try: - print("\n".join(a.get("name","") for a in json.load(sys.stdin).get("assets",[]))) + for a in json.load(sys.stdin).get("assets",[]): + n=a.get("name",""); i=a.get("id",""); u=a.get("browser_download_url","") + if n: + print("%s\t%s\t%s" % (n, i, u)) except Exception: pass' 2>/dev/null || true)" -# ── Upload each artifact as a release attachment ────────────────────────────── +sha256_of() { # sha256 of a file ($1) or, with no arg, of stdin + if command -v sha256sum >/dev/null 2>&1; then sha256sum ${1:+"$1"} | awk '{print $1}'; + else shasum -a 256 ${1:+"$1"} | awk '{print $1}'; fi +} + +gitee_attach() { # upload file $1; success when the response carries a download url + printf '%s' "$(curl -fsSL -X POST "${base}/releases/${release_id}/attach_files" \ + -F "access_token=${GITEE_TOKEN}" -F "file=@${1}" 2>/dev/null || true)" \ + | grep -q '"browser_download_url"' +} + uploaded=0 +replaced=0 skipped=0 for f in "$DIST_DIR"/dws-*.tar.gz "$DIST_DIR"/dws-*.zip "$DIST_DIR"/checksums.txt; do [ -f "$f" ] || continue fn="$(basename "$f")" - if printf '%s\n' "$existing_names" | grep -qxF "$fn"; then - echo " ✓ ${fn} already on Gitee — skip" - skipped=$((skipped + 1)) + local_sha="$(sha256_of "$f")" + row="$(printf '%s\n' "$assets_map" | awk -F'\t' -v n="$fn" '$1==n {print; exit}')" + if [ -n "$row" ]; then + aid="$(printf '%s' "$row" | cut -f2)" + aurl="$(printf '%s' "$row" | cut -f3)" + gitee_sha="$(curl -fsSL "$aurl" 2>/dev/null | sha256_of || true)" + if [ "$gitee_sha" = "$local_sha" ]; then + echo " ✓ ${fn} already correct on Gitee — skip" + skipped=$((skipped + 1)) + continue + fi + echo " ↻ ${fn} differs on Gitee (stale) — deleting + re-uploading" + curl -fsSL -X DELETE "${base}/releases/${release_id}/attach_files/${aid}?access_token=${GITEE_TOKEN}" >/dev/null 2>&1 || true + if gitee_attach "$f"; then replaced=$((replaced + 1)); else echo " ⚠ re-upload may have failed for ${fn}" >&2; fi continue fi - echo " ⬆ ${fn}" - resp="$(curl -fsSL -X POST "${base}/releases/${release_id}/attach_files" \ - -F "access_token=${GITEE_TOKEN}" \ - -F "file=@${f}" 2>/dev/null || true)" - if printf '%s' "$resp" | grep -q '"browser_download_url"'; then - uploaded=$((uploaded + 1)) - else - echo " ⚠ upload may have failed for ${fn}: ${resp}" >&2 - fi + echo " ⬆ ${fn} (new)" + if gitee_attach "$f"; then uploaded=$((uploaded + 1)); else echo " ⚠ upload may have failed for ${fn}" >&2; fi done -if [ "$uploaded" -eq 0 ] && [ "$skipped" -eq 0 ]; then - echo "❌ No artifacts found to upload. Did the build (goreleaser) run / were assets downloaded into ${DIST_DIR}?" >&2 +if [ "$uploaded" -eq 0 ] && [ "$replaced" -eq 0 ] && [ "$skipped" -eq 0 ]; then + echo "❌ No artifacts found to mirror. Did the build (goreleaser) run / were assets downloaded into ${DIST_DIR}?" >&2 exit 1 fi -echo "✅ Gitee release ${VERSION}: uploaded ${uploaded} asset(s), skipped ${skipped} already present." +echo "✅ Gitee release ${VERSION}: uploaded ${uploaded}, replaced ${replaced}, skipped ${skipped} (already correct)." echo " China install: DWS_GITEE_REPO=${GITEE_REPO} \\" echo " curl -fsSL https://gitee.com/${GITEE_REPO}/raw/main/scripts/install.sh | sh"