more Sparkle tests
This commit is contained in:
@@ -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<version>` and upload both ZIP and DMG as release assets automatically.
|
`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<version>` 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
|
### Sparkle updates
|
||||||
|
|
||||||
iKeyMon uses [Sparkle](https://sparkle-project.org/) for macOS-safe 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).
|
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`).
|
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.
|
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.
|
||||||
|
|||||||
8
Sparkle/appcast.xml
vendored
8
Sparkle/appcast.xml
vendored
@@ -2,6 +2,14 @@
|
|||||||
<rss xmlns:sparkle="http://www.andymatuschak.org/xml-namespaces/sparkle" version="2.0">
|
<rss xmlns:sparkle="http://www.andymatuschak.org/xml-namespaces/sparkle" version="2.0">
|
||||||
<channel>
|
<channel>
|
||||||
<title>iKeyMon</title>
|
<title>iKeyMon</title>
|
||||||
|
<item>
|
||||||
|
<title>26.0.15</title>
|
||||||
|
<pubDate>Tue, 25 Nov 2025 18:11:17 +0100</pubDate>
|
||||||
|
<sparkle:version>35</sparkle:version>
|
||||||
|
<sparkle:shortVersionString>26.0.15</sparkle:shortVersionString>
|
||||||
|
<sparkle:minimumSystemVersion>15.2</sparkle:minimumSystemVersion>
|
||||||
|
<enclosure url="https://git.24unix.net/tracer/iKeyMon/releases/download/iKeyMon-26.0.15.zip" length="4801128" type="application/octet-stream" sparkle:edSignature="T16+tX44yN2UqIUsMJeZAxydOuLC6lcQQrlRElTkJlSWPheWLy9xPjP4T45mNSOcWTax0gRCnI50ab3geL9XAA=="/>
|
||||||
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<title>26.0.15</title>
|
<title>26.0.15</title>
|
||||||
<pubDate>Tue, 25 Nov 2025 17:42:56 +0100</pubDate>
|
<pubDate>Tue, 25 Nov 2025 17:42:56 +0100</pubDate>
|
||||||
|
|||||||
@@ -310,7 +310,7 @@
|
|||||||
CODE_SIGN_ENTITLEMENTS = iKeyMon.entitlements;
|
CODE_SIGN_ENTITLEMENTS = iKeyMon.entitlements;
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
COMBINE_HIDPI_IMAGES = YES;
|
COMBINE_HIDPI_IMAGES = YES;
|
||||||
CURRENT_PROJECT_VERSION = 34;
|
CURRENT_PROJECT_VERSION = 35;
|
||||||
DEVELOPMENT_ASSET_PATHS = "\"Preview Content\"";
|
DEVELOPMENT_ASSET_PATHS = "\"Preview Content\"";
|
||||||
DEVELOPMENT_TEAM = Q5486ZVAFT;
|
DEVELOPMENT_TEAM = Q5486ZVAFT;
|
||||||
ENABLE_HARDENED_RUNTIME = YES;
|
ENABLE_HARDENED_RUNTIME = YES;
|
||||||
@@ -341,7 +341,7 @@
|
|||||||
CODE_SIGN_ENTITLEMENTS = iKeyMon.entitlements;
|
CODE_SIGN_ENTITLEMENTS = iKeyMon.entitlements;
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
COMBINE_HIDPI_IMAGES = YES;
|
COMBINE_HIDPI_IMAGES = YES;
|
||||||
CURRENT_PROJECT_VERSION = 34;
|
CURRENT_PROJECT_VERSION = 35;
|
||||||
DEVELOPMENT_ASSET_PATHS = "\"Preview Content\"";
|
DEVELOPMENT_ASSET_PATHS = "\"Preview Content\"";
|
||||||
DEVELOPMENT_TEAM = Q5486ZVAFT;
|
DEVELOPMENT_TEAM = Q5486ZVAFT;
|
||||||
ENABLE_HARDENED_RUNTIME = YES;
|
ENABLE_HARDENED_RUNTIME = YES;
|
||||||
|
|||||||
@@ -63,11 +63,28 @@ if [[ -z "$release_id" || "$release_id" == "null" ]]; then
|
|||||||
exit 1
|
exit 1
|
||||||
fi
|
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() {
|
upload_asset() {
|
||||||
local file="$1"
|
local file="$1"
|
||||||
local filename
|
local filename
|
||||||
filename="$(basename "$file")"
|
filename="$(basename "$file")"
|
||||||
|
|
||||||
|
delete_existing_asset "$filename"
|
||||||
|
|
||||||
echo "⬆️ Uploading ${filename}"
|
echo "⬆️ Uploading ${filename}"
|
||||||
curl -sS \
|
curl -sS \
|
||||||
-H "Authorization: token ${GITEA_TOKEN}" \
|
-H "Authorization: token ${GITEA_TOKEN}" \
|
||||||
@@ -78,8 +95,4 @@ upload_asset() {
|
|||||||
upload_asset "$ZIP_PATH"
|
upload_asset "$ZIP_PATH"
|
||||||
upload_asset "$DMG_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."
|
echo "🎉 Release ${RELEASE_TAG} assets uploaded."
|
||||||
|
|||||||
Reference in New Issue
Block a user