From bf13958b9177ee5eb4731e36a98b2f4949df30cf Mon Sep 17 00:00:00 2001 From: Pawan Sedara Date: Sun, 26 Jul 2026 22:53:03 +1000 Subject: [PATCH] fix: target macOS 11 in menu app --- README.md | 10 +++++----- docs/LAUNCH.md | 4 ++-- docs/RELEASE.md | 14 +++++++------- docs/releases/v0.1.0-preview.5.md | 24 ++++++++++++++++++++++++ scripts/build-macos-app.sh | 4 +++- scripts/test-macos-app.sh | 15 +++++++++++++++ tests/macos_app_bundle.rs | 4 ++++ 7 files changed, 60 insertions(+), 15 deletions(-) create mode 100644 docs/releases/v0.1.0-preview.5.md diff --git a/README.md b/README.md index 6801282..8c5afcc 100644 --- a/README.md +++ b/README.md @@ -16,11 +16,11 @@ PlainLink watches the clipboard and removes known tracking parameters before you PlainLink accepts links with or without `https://` and keeps the original form. -## Install Preview 4 +## Install Preview 5 -Preview 4 is for technical testers with an Apple silicon Mac. It is ad-hoc signed but not notarized, so macOS may incorrectly say the app is damaged. A normal drag-and-drop install will not bypass that warning. +Preview 5 is for technical testers with an Apple silicon Mac running macOS 11 or later. It is ad-hoc signed but not notarized, so macOS may incorrectly say the app is damaged. A normal drag-and-drop install will not bypass that warning. -1. Download `PlainLink-0.1.0-preview.4-macos-arm64.zip` from [GitHub Releases](https://github.com/HexCodeYT/PlainLink/releases). +1. Download `PlainLink-0.1.0-preview.5-macos-arm64.zip` from [GitHub Releases](https://github.com/HexCodeYT/PlainLink/releases). 2. Unzip it and drag `PlainLink.app` into `/Applications`. 3. Run these commands in Terminal: @@ -68,10 +68,10 @@ open dist/PlainLink.app The smoke test builds the Rust CLI and native Swift/AppKit menu bar app, verifies the app bundle and its embedded binaries, and writes `dist/PlainLink.app`. -To package a local Preview 4 ZIP: +To package a local Preview 5 ZIP: ```sh -PLAINLINK_RELEASE_VERSION=v0.1.0-preview.4 scripts/package-macos-app.sh +PLAINLINK_RELEASE_VERSION=v0.1.0-preview.5 scripts/package-macos-app.sh ``` ## Use the CLI diff --git a/docs/LAUNCH.md b/docs/LAUNCH.md index 723d86c..60395e9 100644 --- a/docs/LAUNCH.md +++ b/docs/LAUNCH.md @@ -29,7 +29,7 @@ Secondary angles by audience: - [ ] Enable GitHub Discussions for rule requests, testing reports, ideas, and show-and-tell posts. - [x] Confirm the issue templates cover missing rules, false positives, app bugs, and feature requests. -Preview 3 established the public download path. Preview 4 replaces it for launch because it refreshes an older installed watcher automatically. +Preview 5 is the launch build. It includes Preview 4's automatic watcher refresh and explicitly targets macOS 11 in both bundled Mach-O executables. ## Landing page requirements @@ -127,7 +127,7 @@ Ask for broken URLs and false positives. Do not ask for stars. Title: ```text -Show HN: PlainLink - a local-first URL cleaner with a Rust core and native Mac app +Show HN: PlainLink - a native Mac app that strips tracking from copied URLs ``` Submit this repository URL, not a storefront or checkout page: diff --git a/docs/RELEASE.md b/docs/RELEASE.md index 922fbcf..f947f9e 100644 --- a/docs/RELEASE.md +++ b/docs/RELEASE.md @@ -11,7 +11,7 @@ Current status: release automation exists, but this repository does not currentl Use this for technical testers: ```sh -PLAINLINK_RELEASE_VERSION=v0.1.0-preview.4 scripts/package-macos-app.sh +PLAINLINK_RELEASE_VERSION=v0.1.0-preview.5 scripts/package-macos-app.sh ``` This produces an ad-hoc-signed zip and checksum in `dist/packages/`. macOS Gatekeeper will warn users because the app is not signed with a Developer ID certificate and is not notarized. @@ -19,8 +19,8 @@ This produces an ad-hoc-signed zip and checksum in `dist/packages/`. macOS Gatek Preview artifacts include the preview suffix in the filename, for example: ```text -dist/packages/PlainLink-0.1.0-preview.4-macos-arm64.zip -dist/packages/PlainLink-0.1.0-preview.4-macos-arm64.zip.sha256 +dist/packages/PlainLink-0.1.0-preview.5-macos-arm64.zip +dist/packages/PlainLink-0.1.0-preview.5-macos-arm64.zip.sha256 ``` ### Signed regular-user release @@ -99,10 +99,10 @@ scripts/publish-github-release.sh v0.1.0 For preview releases, the publish script expects preview-named artifacts and falls back to the base version notes if preview-specific notes do not exist: ```sh -PLAINLINK_RELEASE_VERSION=v0.1.0-preview.4 scripts/package-macos-app.sh -git tag -a v0.1.0-preview.4 -m "PlainLink v0.1.0 Preview 4" -git push origin v0.1.0-preview.4 -scripts/publish-github-release.sh v0.1.0-preview.4 +PLAINLINK_RELEASE_VERSION=v0.1.0-preview.5 scripts/package-macos-app.sh +git tag -a v0.1.0-preview.5 -m "PlainLink v0.1.0 Preview 5" +git push origin v0.1.0-preview.5 +scripts/publish-github-release.sh v0.1.0-preview.5 ``` The publish script creates a draft GitHub Release with: diff --git a/docs/releases/v0.1.0-preview.5.md b/docs/releases/v0.1.0-preview.5.md new file mode 100644 index 0000000..af88494 --- /dev/null +++ b/docs/releases/v0.1.0-preview.5.md @@ -0,0 +1,24 @@ +# PlainLink v0.1.0 Preview 5 + +PlainLink v0.1.0 Preview 5 is an ad-hoc-signed, unnotarized technical preview for Apple silicon Macs running macOS 11 or later. + +## Fixes + +- Corrects the Swift menu-bar executable's Mach-O minimum deployment target from macOS 27.0 to macOS 11.0. +- Adds a packaging check that verifies both bundled executables match `LSMinimumSystemVersion` before an artifact is created. +- Retains Preview 4's automatic watcher refresh, schemeless-link cleaning, and pause-state behavior. + +## Installation + +Because this preview is not Developer ID-signed or notarized, macOS may incorrectly report that the downloaded app is damaged. Follow the exact quarantine-removal instructions in the repository README. + +Expected artifact names: + +```text +PlainLink-0.1.0-preview.5-macos-arm64.zip +PlainLink-0.1.0-preview.5-macos-arm64.zip.sha256 +``` + +## Tester Ask + +If you are running macOS 11 through macOS 26, please confirm that the menu-bar app launches and starts cleaning after installation. diff --git a/scripts/build-macos-app.sh b/scripts/build-macos-app.sh index fb886c6..55ba933 100755 --- a/scripts/build-macos-app.sh +++ b/scripts/build-macos-app.sh @@ -11,6 +11,8 @@ SWIFT_SOURCE="$ROOT_DIR/app/macos/PlainLinkMenu/Sources/PlainLinkMenu.swift" INFO_PLIST="$ROOT_DIR/packaging/macos/PlainLink.app/Contents/Info.plist" SWIFT_MODULE_CACHE="$ROOT_DIR/target/swift-module-cache" ICON_FILE="$RESOURCES_DIR/PlainLink.icns" +MIN_MACOS_VERSION="11.0" +SWIFT_TARGET="$(uname -m)-apple-macosx$MIN_MACOS_VERSION" if [ "$(uname -s)" != "Darwin" ]; then echo "PlainLink.app can only be built on macOS." >&2 @@ -39,7 +41,7 @@ mkdir -p "$MACOS_DIR" "$RESOURCES_DIR" "$SWIFT_MODULE_CACHE" cp "$INFO_PLIST" "$CONTENTS_DIR/Info.plist" "$ROOT_DIR/scripts/generate-macos-icon.sh" "$ICON_FILE" -swiftc -O -framework AppKit -module-cache-path "$SWIFT_MODULE_CACHE" "$SWIFT_SOURCE" -o "$MACOS_DIR/PlainLinkMenu" +swiftc -O -target "$SWIFT_TARGET" -framework AppKit -module-cache-path "$SWIFT_MODULE_CACHE" "$SWIFT_SOURCE" -o "$MACOS_DIR/PlainLinkMenu" cp "$ROOT_DIR/target/release/plainlink" "$MACOS_DIR/plainlink" chmod 755 "$MACOS_DIR/PlainLinkMenu" "$MACOS_DIR/plainlink" diff --git a/scripts/test-macos-app.sh b/scripts/test-macos-app.sh index 4402d5a..9c3276e 100755 --- a/scripts/test-macos-app.sh +++ b/scripts/test-macos-app.sh @@ -9,6 +9,10 @@ INFO_PLIST="$APP_DIR/Contents/Info.plist" ICON_FILE="$APP_DIR/Contents/Resources/PlainLink.icns" ICON_CHECK_DIR="$ROOT_DIR/target/macos-icon-check.iconset" +minimum_macos_version() { + xcrun vtool -show-build "$1" | awk '$1 == "minos" { print $2; exit }' +} + "$ROOT_DIR/scripts/build-macos-app.sh" test -d "$APP_DIR" @@ -19,6 +23,17 @@ test -s "$ICON_FILE" plutil -lint "$INFO_PLIST" >/dev/null codesign --verify --deep --strict --verbose=2 "$APP_DIR" +PLIST_MIN_OS=$(/usr/libexec/PlistBuddy -c "Print :LSMinimumSystemVersion" "$INFO_PLIST") +MENU_MIN_OS=$(minimum_macos_version "$MENU_BIN") +CLI_MIN_OS=$(minimum_macos_version "$CLI_BIN") +test "$MENU_MIN_OS" = "$PLIST_MIN_OS" || { + echo "PlainLinkMenu minimum macOS version is $MENU_MIN_OS; expected $PLIST_MIN_OS" >&2 + exit 1 +} +test "$CLI_MIN_OS" = "$PLIST_MIN_OS" || { + echo "plainlink minimum macOS version is $CLI_MIN_OS; expected $PLIST_MIN_OS" >&2 + exit 1 +} rm -rf "$ICON_CHECK_DIR" iconutil -c iconset -o "$ICON_CHECK_DIR" "$ICON_FILE" test -s "$ICON_CHECK_DIR/icon_512x512.png" diff --git a/tests/macos_app_bundle.rs b/tests/macos_app_bundle.rs index 601296f..e8e94b8 100644 --- a/tests/macos_app_bundle.rs +++ b/tests/macos_app_bundle.rs @@ -57,10 +57,14 @@ fn macos_menu_app_assets_are_wired() { assert!(build_script.contains("cargo build --release")); assert!(build_script.contains("scripts/generate-macos-icon.sh")); assert!(build_script.contains("swiftc")); + assert!(build_script.contains("MIN_MACOS_VERSION=\"11.0\"")); + assert!(build_script.contains("-target \"$SWIFT_TARGET\"")); assert!(build_script.contains("-module-cache-path")); assert!(build_script.contains("codesign --force --sign -")); assert!(test_script.contains("--smoke-test")); assert!(test_script.contains("plutil -lint")); + assert!(test_script.contains("vtool -show-build")); + assert!(test_script.contains("LSMinimumSystemVersion")); assert!(test_script.contains("PlainLink.icns")); assert!(test_script.contains("codesign --verify --deep --strict")); assert!(test_script.contains("icon_512x512.png"));