Repository navigation
feat: raise the macOS minimum to 26 - #27
Conversation
LSMinimumSystemVersion goes to 26.0 and the packaged binary links with MACOSX_DEPLOYMENT_TARGET=26.0 — the Mach-O min version is what older systems actually enforce, so plist and binary must agree. CI drops the macos-15 leg (the app no longer supports that system) and runs on macos-26 only; fmt moves with it. README/BUILDING state the 26+ requirement. Verified locally on macOS 27: the arm64 slice's LC_BUILD_VERSION shows minos 26.0, and all 196 tests pass with the target set.
There was a problem hiding this comment.
Pi code review
The PR consistently raises the macOS floor to 26.0 across CI (matrix + fmt gate), the packaging script (MACOSX_DEPLOYMENT_TARGET + LSMinimumSystemVersion), README, and BUILDING.md; the changes agree with each other and with the stated intent. I checked the workflow matrix/gating for dangling references to macos-15 (none remain), the plist/script/doc consistency, whether the env var actually reaches both slices of the universal build (it is exported before the single dual-target cargo build, so it does), and the release/docs claims. No correctness or security regressions found; two low-severity maintainability/reliability nits in the packaging script are filed below.
ℹ️ 2 Low
Reviewed e26de1c with Pi 0.85.1 using zai/glm-5.3:high.
| <key>CFBundleShortVersionString</key><string>${VERSION}</string> | ||
| <key>CFBundleInfoDictionaryVersion</key><string>6.0</string> | ||
| <key>LSMinimumSystemVersion</key><string>13.0</string> | ||
| <key>LSMinimumSystemVersion</key><string>26.0</string> |
There was a problem hiding this comment.
Low: The minimum version is now hardcoded in two places in this script: MACOSX_DEPLOYMENT_TARGET=26.0 (line 28) and the LSMinimumSystemVersion value here. If a future bump edits one and not the other, the plist and the Mach-O LC_BUILD_VERSION silently disagree — exactly the mismatch this PR was written to fix. Since the heredoc delimiter is unquoted (it already expands ${BUNDLE_ID} and ${VERSION}), define MIN_MACOS=26.0 once and use it in both the export and <key>LSMinimumSystemVersion</key><string>${MIN_MACOS}</string>.
| # Minimum supported macOS: both slices link with a 26.0 floor, matching | ||
| # LSMinimumSystemVersion below (Gatekeeper/LaunchServices enforce the | ||
| # plist; the Mach-O min version is what older systems actually read). | ||
| export MACOSX_DEPLOYMENT_TARGET=26.0 |
There was a problem hiding this comment.
Low: The script never verifies that the 26.0 floor actually landed in the produced binary. MACOSX_DEPLOYMENT_TARGET is not part of cargo's fingerprinting, so an incremental local build can reuse previously linked slices (e.g. from before this change, minos 11.0/13.0) and lipo/codesign/ditto will happily package them while the plist claims 26.0 — shipped artifact then lies about its floor. The author verified minos 26.0 manually once; make it a build gate instead: in the existing ==> Verifying section add something like vtool -arch arm64 -show-build -output ... | grep -q 'Platform: MacOS\|MinOS: 26.0' (or otool -l ... | grep -A2 LC_BUILD_VERSION) for both slices and fail the script on mismatch.
What
The supported macOS floor moves from 13.0 to 26.0:
LSMinimumSystemVersionin the packaged app: 26.0MACOSX_DEPLOYMENT_TARGET=26.0— the Mach-OLC_BUILD_VERSIONmin is what older systems actually enforce, so the plist and the binary now agree.macos-15leg (that system is below the new floor) and runs onmacos-26only; the fmt check moves with it.Verification
Locally on macOS 27 / Xcode 27: the arm64 release slice's
LC_BUILD_VERSIONshowsminos 26.0, and all 196 tests pass with the deployment target set. Intel is unaffected as a target — the universal build keeps its x86_64 slice, and macOS 26 (Tahoe) is the final Intel release, so Intel users on 26 remain supported.Anyone on macOS 13–25 will need to stay on the 0.8.0 release (built against the older floor), which remains downloadable.