From faf1bd44c281af044d6fa328767ff439d355e776 Mon Sep 17 00:00:00 2001 From: Lawrence Chen <54008264+lawrencecchen@users.noreply.github.com> Date: Sat, 14 Feb 2026 03:26:42 -0800 Subject: [PATCH] release: fix Sparkle upgrade path for 1.27.0 users --- .github/workflows/release.yml | 2 ++ CHANGELOG.md | 6 ++++++ GhosttyTabs.xcodeproj/project.pbxproj | 24 ++++++++++++------------ PROJECTS.md | 1 + docs-site/content/docs/changelog.mdx | 6 ++++++ scripts/bump-version.sh | 21 +++++++++++++++++++-- 6 files changed, 46 insertions(+), 14 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index a9ffe109..f6a76e05 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -86,6 +86,8 @@ jobs: - name: Inject Sparkle keys into Info.plist run: | APP_PLIST="build/Build/Products/Release/cmux.app/Contents/Info.plist" + /usr/libexec/PlistBuddy -c "Delete :SUPublicEDKey" "$APP_PLIST" >/dev/null 2>&1 || true + /usr/libexec/PlistBuddy -c "Delete :SUFeedURL" "$APP_PLIST" >/dev/null 2>&1 || true echo "Adding SUPublicEDKey to Info.plist..." /usr/libexec/PlistBuddy -c "Add :SUPublicEDKey string ${SPARKLE_PUBLIC_KEY}" "$APP_PLIST" echo "Adding SUFeedURL to Info.plist..." diff --git a/CHANGELOG.md b/CHANGELOG.md index 6d051e8c..f8ecb39d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,12 @@ All notable changes to cmux are documented here. +## [1.28.2] - 2026-02-14 + +### Fixed +- Sparkle updates from `1.27.0` could fail to detect newer releases because release build numbers were behind the latest published appcast build number +- Release GitHub Action failed on repeat runs when `SUPublicEDKey` / `SUFeedURL` already existed in `Info.plist` + ## [1.28.1] - 2026-02-14 ### Fixed diff --git a/GhosttyTabs.xcodeproj/project.pbxproj b/GhosttyTabs.xcodeproj/project.pbxproj index 6d347e11..342dd560 100644 --- a/GhosttyTabs.xcodeproj/project.pbxproj +++ b/GhosttyTabs.xcodeproj/project.pbxproj @@ -670,7 +670,7 @@ CODE_SIGN_ENTITLEMENTS = ""; CODE_SIGN_STYLE = Automatic; COMBINE_HIDPI_IMAGES = YES; - CURRENT_PROJECT_VERSION = 25; + CURRENT_PROJECT_VERSION = 39; DEVELOPMENT_TEAM = ""; ENABLE_HARDENED_RUNTIME = NO; GENERATE_INFOPLIST_FILE = NO; @@ -679,7 +679,7 @@ "$(inherited)", "@executable_path/../Frameworks", ); - MARKETING_VERSION = 1.28.1; + MARKETING_VERSION = 1.28.2; OTHER_LDFLAGS = ( "-lc++", "-framework", @@ -708,7 +708,7 @@ CODE_SIGN_ENTITLEMENTS = ""; CODE_SIGN_STYLE = Automatic; COMBINE_HIDPI_IMAGES = YES; - CURRENT_PROJECT_VERSION = 25; + CURRENT_PROJECT_VERSION = 39; DEVELOPMENT_TEAM = ""; ENABLE_HARDENED_RUNTIME = NO; GENERATE_INFOPLIST_FILE = NO; @@ -717,7 +717,7 @@ "$(inherited)", "@executable_path/../Frameworks", ); - MARKETING_VERSION = 1.28.1; + MARKETING_VERSION = 1.28.2; OTHER_LDFLAGS = ( "-lc++", "-framework", @@ -770,10 +770,10 @@ isa = XCBuildConfiguration; buildSettings = { CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 25; + CURRENT_PROJECT_VERSION = 39; GENERATE_INFOPLIST_FILE = YES; MACOSX_DEPLOYMENT_TARGET = 14.0; - MARKETING_VERSION = 1.28.1; + MARKETING_VERSION = 1.28.2; ONLY_ACTIVE_ARCH = YES; PRODUCT_BUNDLE_IDENTIFIER = com.cmuxterm.appuitests; PRODUCT_NAME = "$(TARGET_NAME)"; @@ -787,10 +787,10 @@ isa = XCBuildConfiguration; buildSettings = { CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 25; + CURRENT_PROJECT_VERSION = 39; GENERATE_INFOPLIST_FILE = YES; MACOSX_DEPLOYMENT_TARGET = 14.0; - MARKETING_VERSION = 1.28.1; + MARKETING_VERSION = 1.28.2; ONLY_ACTIVE_ARCH = YES; PRODUCT_BUNDLE_IDENTIFIER = com.cmuxterm.appuitests; PRODUCT_NAME = "$(TARGET_NAME)"; @@ -804,10 +804,10 @@ buildSettings = { BUNDLE_LOADER = "$(TEST_HOST)"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 25; + CURRENT_PROJECT_VERSION = 39; GENERATE_INFOPLIST_FILE = YES; MACOSX_DEPLOYMENT_TARGET = 14.0; - MARKETING_VERSION = 1.28.1; + MARKETING_VERSION = 1.28.2; ONLY_ACTIVE_ARCH = YES; PRODUCT_BUNDLE_IDENTIFIER = com.cmuxterm.apptests; PRODUCT_NAME = "$(TARGET_NAME)"; @@ -823,10 +823,10 @@ buildSettings = { BUNDLE_LOADER = "$(TEST_HOST)"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 25; + CURRENT_PROJECT_VERSION = 39; GENERATE_INFOPLIST_FILE = YES; MACOSX_DEPLOYMENT_TARGET = 14.0; - MARKETING_VERSION = 1.28.1; + MARKETING_VERSION = 1.28.2; ONLY_ACTIVE_ARCH = YES; PRODUCT_BUNDLE_IDENTIFIER = com.cmuxterm.apptests; PRODUCT_NAME = "$(TARGET_NAME)"; diff --git a/PROJECTS.md b/PROJECTS.md index 6037b3d4..3d0e0cc7 100644 --- a/PROJECTS.md +++ b/PROJECTS.md @@ -3,6 +3,7 @@ Cross-project tracking (features, bugs, backlog) for cmux. ## Done +- 2026-02-14: Fixed updater release regression path: made `.github/workflows/release.yml` Sparkle Info.plist key injection idempotent (re-running tags no longer fails with "Entry Already Exists"), and hardened `scripts/bump-version.sh` to keep `CURRENT_PROJECT_VERSION` above the latest published Sparkle appcast build number so upgrades from `1.27.0` can be detected. - 2026-02-14: Relicensed the repository to strong copyleft (`AGPL-3.0-or-later`), added canonical `LICENSE` text, and updated project/package metadata to advertise AGPL consistently. - 2026-02-14: Added an opt-in nightly update channel in Settings (`Receive nightly builds`) that routes Sparkle feed selection between stable and nightly appcasts, plus a scheduled GitHub Actions nightly pipeline (`.github/workflows/nightly.yml`) that only rebuilds when `main` has new commits since `nightly` (or when manually forced). - 2026-02-13: Added `demos/wkwebview-ssh-proxy-cookie-demo/` with a standalone macOS Swift app (two WKWebViews), two Docker backends (`:8080`) running behind separate SSH SOCKS tunnels, and scripts/docs to demonstrate same URL (`shared.test:8080`) routing to different backends plus app-level cookie sync between separate proxy-scoped data stores. diff --git a/docs-site/content/docs/changelog.mdx b/docs-site/content/docs/changelog.mdx index 7da68ec9..3d2f2311 100644 --- a/docs-site/content/docs/changelog.mdx +++ b/docs-site/content/docs/changelog.mdx @@ -5,6 +5,12 @@ description: Release notes and version history for cmux All notable changes to cmux are documented here. +## [1.28.2] - 2026-02-14 + +### Fixed +- Sparkle updates from `1.27.0` could fail to detect newer releases because release build numbers were behind the latest published appcast build number +- Release GitHub Action failed on repeat runs when `SUPublicEDKey` / `SUFeedURL` already existed in `Info.plist` + ## [1.28.1] - 2026-02-14 ### Fixed diff --git a/scripts/bump-version.sh b/scripts/bump-version.sh index d5a7b04e..27c93862 100755 --- a/scripts/bump-version.sh +++ b/scripts/bump-version.sh @@ -18,9 +18,26 @@ fi # Get current versions CURRENT_MARKETING=$(grep -m1 'MARKETING_VERSION = ' "$PROJECT_FILE" | sed 's/.*= \(.*\);/\1/') CURRENT_BUILD=$(grep -m1 'CURRENT_PROJECT_VERSION = ' "$PROJECT_FILE" | sed 's/.*= \(.*\);/\1/') +MIN_BUILD="$CURRENT_BUILD" echo "Current: MARKETING_VERSION=$CURRENT_MARKETING, CURRENT_PROJECT_VERSION=$CURRENT_BUILD" +# Keep Sparkle build numbers monotonic with the latest published stable appcast. +# If local build numbers have fallen behind due merges/rebases, auto-correct upward. +LATEST_RELEASE_BUILD="$( + curl -fsSL --max-time 8 https://github.com/manaflow-ai/cmux/releases/latest/download/appcast.xml 2>/dev/null \ + | sed -n 's#.*\([0-9][0-9]*\).*#\1#p' \ + | head -n1 +)" +if [[ "$LATEST_RELEASE_BUILD" =~ ^[0-9]+$ ]]; then + if (( LATEST_RELEASE_BUILD > MIN_BUILD )); then + MIN_BUILD="$LATEST_RELEASE_BUILD" + fi + echo "Latest release appcast build: $LATEST_RELEASE_BUILD" +else + echo "Latest release appcast build: unavailable (continuing with local build baseline)" +fi + # Parse current marketing version IFS='.' read -r MAJOR MINOR PATCH <<< "$CURRENT_MARKETING" @@ -42,8 +59,8 @@ else exit 1 fi -# Always increment build number -NEW_BUILD=$((CURRENT_BUILD + 1)) +# Always increment build number, and never go backwards relative to published releases. +NEW_BUILD=$((MIN_BUILD + 1)) echo "New: MARKETING_VERSION=$NEW_MARKETING, CURRENT_PROJECT_VERSION=$NEW_BUILD"