diff --git a/README.md b/README.md index bca008d..a466bd4 100644 --- a/README.md +++ b/README.md @@ -65,12 +65,14 @@ GITEA_REPO="iKeyMon" `GITEA_TARGET_COMMIT` defaults to the current `HEAD` commit, so overriding it lets you publish from another branch if needed. Whenever those variables are set, the script will create (or reuse) tag `v` and upload both ZIP and DMG as release assets automatically. +If you re-run the release script for the same version, it removes any existing assets with the same filenames before uploading, so you never end up with duplicate ZIP/DMG files on the release page. + ### Sparkle updates iKeyMon uses [Sparkle](https://sparkle-project.org/) for macOS-safe updates. 1. Generate an EdDSA key pair once (`./Packages/Sparkle/bin/generate_keys`). Store the private key on-disk (for example `~/.config/Sparkle/iKeyMon.key`, which the build script expects) and copy the public key into the `SUPublicEDKey` entry (see Info.plist notes below). -2. `./scripts/build_release.sh` signs the ZIP with Sparkle’s `sign_update` tool and invokes `generate_appcast` automatically when the Sparkle variables are present. The generated feed is written to `Sparkle/appcast.xml`, so commit that file after every release. Point `SPARKLE_DOWNLOAD_BASE_TEMPLATE` at your release download prefix to ensure the feed URLs resolve correctly. +2. `./scripts/build_release.sh` signs the ZIP with Sparkle’s `sign_update` tool and invokes `generate_appcast` automatically when the Sparkle variables are present. The generated feed is written to `Sparkle/appcast.xml`, so commit that file after every release. Point `SPARKLE_DOWNLOAD_BASE_TEMPLATE` at your release download prefix to ensure the feed URLs resolve correctly. The feed stays inside the repo (it is not uploaded as a release asset). 3. Set `SUFeedURL` in Info.plist (or the corresponding build setting) to the raw URL of `Sparkle/appcast.xml` inside this repo (e.g. `https://git.24unix.net/tracer/iKeyMon/raw/branch/master/Sparkle/appcast.xml`). Preferences expose Sparkle’s built-in toggles for “Automatically check” and “Automatically download”, and the toolbar button simply calls Sparkle’s “Check for Updates…” sheet. diff --git a/Sparkle/appcast.xml b/Sparkle/appcast.xml index c155b12..b7e2506 100644 --- a/Sparkle/appcast.xml +++ b/Sparkle/appcast.xml @@ -2,6 +2,14 @@ iKeyMon + + 26.0.15 + Tue, 25 Nov 2025 18:11:17 +0100 + 35 + 26.0.15 + 15.2 + + 26.0.15 Tue, 25 Nov 2025 17:42:56 +0100 diff --git a/iKeyMon.xcodeproj/project.pbxproj b/iKeyMon.xcodeproj/project.pbxproj index 13f2a12..1103b57 100644 --- a/iKeyMon.xcodeproj/project.pbxproj +++ b/iKeyMon.xcodeproj/project.pbxproj @@ -310,7 +310,7 @@ CODE_SIGN_ENTITLEMENTS = iKeyMon.entitlements; CODE_SIGN_STYLE = Automatic; COMBINE_HIDPI_IMAGES = YES; - CURRENT_PROJECT_VERSION = 34; + CURRENT_PROJECT_VERSION = 35; DEVELOPMENT_ASSET_PATHS = "\"Preview Content\""; DEVELOPMENT_TEAM = Q5486ZVAFT; ENABLE_HARDENED_RUNTIME = YES; @@ -341,7 +341,7 @@ CODE_SIGN_ENTITLEMENTS = iKeyMon.entitlements; CODE_SIGN_STYLE = Automatic; COMBINE_HIDPI_IMAGES = YES; - CURRENT_PROJECT_VERSION = 34; + CURRENT_PROJECT_VERSION = 35; DEVELOPMENT_ASSET_PATHS = "\"Preview Content\""; DEVELOPMENT_TEAM = Q5486ZVAFT; ENABLE_HARDENED_RUNTIME = YES; diff --git a/scripts/publish_release.sh b/scripts/publish_release.sh index 41b0958..3c78c8c 100755 --- a/scripts/publish_release.sh +++ b/scripts/publish_release.sh @@ -63,11 +63,28 @@ if [[ -z "$release_id" || "$release_id" == "null" ]]; then exit 1 fi +delete_existing_asset() { + local filename="$1" + local asset_id + asset_id="$(curl -sS \ + -H "Authorization: token ${GITEA_TOKEN}" \ + "${API_URL}/releases/${release_id}/assets" | jq -r --arg name "$filename" '.[] | select(.name == $name) | .id' | head -n 1)" + if [[ -n "$asset_id" && "$asset_id" != "null" ]]; then + echo "🗑️ Removing existing asset ${filename}" + curl -sS \ + -H "Authorization: token ${GITEA_TOKEN}" \ + -X DELETE \ + "${API_URL}/releases/${release_id}/assets/${asset_id}" >/dev/null + fi +} + upload_asset() { local file="$1" local filename filename="$(basename "$file")" + delete_existing_asset "$filename" + echo "⬆️ Uploading ${filename}" curl -sS \ -H "Authorization: token ${GITEA_TOKEN}" \ @@ -78,8 +95,4 @@ upload_asset() { upload_asset "$ZIP_PATH" upload_asset "$DMG_PATH" -if [[ -n "${SPARKLE_APPCAST_OUTPUT:-}" && -f "${SPARKLE_APPCAST_OUTPUT}" ]]; then - upload_asset "$SPARKLE_APPCAST_OUTPUT" -fi - echo "🎉 Release ${RELEASE_TAG} assets uploaded."