fix(macos): package the app as SolidCraft (#347) (#354)

This commit is contained in:
Nathan Dane authored and GitHub committed 2026-10-12 14:37:35 -04:00
1 parent 882ef0e9c6
commit 4eaadf3099
8 files changed
+73 -21

No files matched your search

+9 -3
View File
@@ -13,7 +13,7 @@ SolidCraft project Pages URLs; old-name Pages addresses are not permanent aliase
**Which file?**
- **Windows:** `SolveCraft-{version}-windows-x64.exe` runs as is. Or install the `.msi`, or unzip the
`-portable.zip` (x64, x86 and arm64).
- **macOS 11+** (Apple silicon and Intel): open the `.dmg` and drag `SolveCraft.app` onto Applications.
- **macOS 11+** (Apple silicon and Intel): open the `.dmg` and drag `SolidCraft.app` onto Applications.
The CLI is in `solvecraft-cli-{version}-macos-universal.zip`.
- **Linux** (x86_64 and aarch64, glibc 2.35+): the `.AppImage` (`chmod +x`, then run it), the
`.deb` or `.rpm`, the `.flatpak` (`flatpak install --user <file>`), or the `.tar.gz`.
@@ -21,6 +21,12 @@ SolidCraft project Pages URLs; old-name Pages addresses are not permanent aliase
- **Web:** `solvecraft-web-{version}.zip` is a static site to host yourself.
- `SHA256SUMS.txt`: `sha256sum -c SHA256SUMS.txt --ignore-missing`.
**Updating macOS from SolveCraft.app:** quit the app, rename the existing app in
Applications to `SolidCraft.app`, then drag the new app from the DMG onto Applications
and choose **Replace**. If both names are already installed, move the old `SolveCraft.app`
to the Trash. Remove any Dock shortcut with the old name and pin the new app. Designs,
settings and the bundle identifier are unchanged. The DMG includes these instructions.
For Flatpak feed installation and updates, add Flathub for the required runtime before
installing SolidCraft; keep both remotes in the same user installation:
@@ -34,8 +40,8 @@ flatpak run ai.storyteller.solvecraft
Single-file `.flatpak` bundles include the runtime repository address; missing runtimes
still need an internet connection. [Linux installation details](https://bherbruck.github.io/solidcraft/guide/getting-started.html#linux-flatpak).
The builds aren't signed yet. On macOS, right-click `SolveCraft.app` in Applications and choose
**Open** the first time (or run `xattr -dr com.apple.quarantine /Applications/SolveCraft.app`).
The builds aren't signed yet. On macOS, right-click `SolidCraft.app` in Applications and choose
**Open** the first time (or run `xattr -dr com.apple.quarantine /Applications/SolidCraft.app`).
On Windows, SmartScreen may say "Windows protected your PC": **More info**, then **Run anyway**.
Licences are built in (Help ▸ About ▸ Licences, `solvecraft-cli licences`); the packages also
install `THIRD-PARTY-LICENSES.txt`. Known limitations:
+3
View File
@@ -33,6 +33,9 @@ Cargo package names, settings/recovery locations and package IDs keep their exis
Published 0.2.0 and 0.2.1 packages and demo recordings retain their original SolveCraft branding
and filenames.
On macOS, the DMG contains `SolidCraft.app`. To replace an older `SolveCraft.app`
without installing a second copy, follow the [macOS upgrade instructions](https://bherbruck.github.io/solidcraft/guide/getting-started.html#macos).
Use the SolidCraft documentation and web-app URLs above. GitHub redirects links to the
renamed repository; old-name Pages and Flatpak URLs are not maintained as permanent aliases.
+11
View File
@@ -19,6 +19,17 @@ cargo run --release -p solvecraft -- --sample # opens with a sample part
`solvecraft design.solvecraft` opens a saved design. Windows builds cross-compile from Linux with
`cargo xwin build --release --target x86_64-pc-windows-msvc -p solvecraft`.
### macOS
Open the release `.dmg` and drag `SolidCraft.app` onto Applications.
When updating from an older `SolveCraft.app`, quit the app and rename the existing
app in Applications to `SolidCraft.app` first. Then drag the new app onto Applications
and choose **Replace**. If you already have both names installed, move the old
`SolveCraft.app` to the Trash. The DMG does not remove old installations automatically.
Remove any Dock shortcut with the old name, open the new app from Applications, and
choose **Options > Keep in Dock**. Designs, settings and the bundle ID are unchanged.
### Linux Flatpak
Install Flatpak using your distribution's package manager. For an installation that receives
+1 -1
View File
@@ -37,7 +37,7 @@ solidcraft --sample
On Linux, this installs the SolidCraft desktop entry, MIME definition and generated icon
sizes alongside the commands. On macOS the package contains the binaries only; for a bundled
`SolveCraft.app`, use the release `.dmg`. NixOS/Home Manager can instead put the flake's
`SolidCraft.app`, use the release `.dmg`. NixOS/Home Manager can instead put the flake's
`packages.${system}.solidcraft` in `environment.systemPackages`/`home.packages`.
If a non-NixOS desktop does not discover profile-installed launchers, ensure that
its session includes `~/.nix-profile/share` in `XDG_DATA_DIRS`, then log out and
+6 -2
View File
@@ -9,8 +9,12 @@ version bump and no patch release for every merge.
## Compatibility names and deployment
SolidCraft is the product display name. Keep existing release asset filenames, including
`SolveCraft-{version}-windows-x64.exe`, `SolveCraft.app` and `solvecraft-cli` archives, together
with installed package IDs and settings paths. Do not rewrite published 0.2.0 or 0.2.1 assets,
`SolveCraft-{version}-windows-x64.exe` and `solvecraft-cli` archives, together
with installed package IDs and settings paths. The macOS DMG now contains `SolidCraft.app`
with a `SolidCraft` bundle executable and icon; its bundle ID remains
`ai.storyteller.solvecraft`. Include the one-time macOS upgrade instructions from
`.github/release-notes.md` so users replace an existing `SolveCraft.app` rather than
installing a second copy. Do not rewrite published 0.2.0 or 0.2.1 assets,
checksums, tags or historical release notes.
Project Pages publishes the documentation, browser app and published-release Flatpak
+2 -2
View File
@@ -11,7 +11,7 @@
<key>CFBundleName</key>
<string>SolidCraft</string>
<key>CFBundleExecutable</key>
<string>SolveCraft</string>
<string>SolidCraft</string>
<key>CFBundleIdentifier</key>
<string>ai.storyteller.solvecraft</string>
<key>CFBundleInfoDictionaryVersion</key>
@@ -27,7 +27,7 @@
<key>SolveCraftVersion</key>
<string>@VERSION@</string>
<key>CFBundleIconFile</key>
<string>SolveCraft</string>
<string>SolidCraft</string>
<key>LSApplicationCategoryType</key>
<string>public.app-category.graphics-design</string>
<!-- Must match MACOSX_DEPLOYMENT_TARGET in package.sh. -->
+17
View File
@@ -0,0 +1,17 @@
Install SolidCraft
Drag SolidCraft.app onto Applications.
Updating an older SolveCraft.app installation
1. Quit the app.
2. In Applications, rename the existing SolveCraft.app to SolidCraft.app.
3. Drag SolidCraft.app from this disk image onto Applications and choose Replace.
If both names are already present, keep SolidCraft.app and move the old
SolveCraft.app to the Trash. The disk image does not remove old installations.
If your Dock shortcut still uses the old name, remove it from the Dock, then
open SolidCraft.app from Applications and choose Options > Keep in Dock.
Your designs and settings keep their existing locations. The bundle identifier
remains ai.storyteller.solvecraft; saved designs still use .solvecraft.
+24 -13
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env bash
# Build and package SolidCraft for macOS:
#
# $DIST/solvecraft-<version>-macos-<arch>.dmg SolveCraft.app on a drag-to-Applications DMG
# $DIST/solvecraft-<version>-macos-<arch>.dmg SolidCraft.app on a drag-to-Applications DMG
# $DIST/solvecraft-cli-<version>-macos-<arch>.zip the headless CLI with the licence files
#
# Usage: packaging/macos/package.sh [--arch universal|aarch64|x86_64] [--skip-build]
@@ -34,7 +34,7 @@ esac
export MACOSX_DEPLOYMENT_TARGET=11.0
SHORT_VERSION="${VERSION%%-*}"
WORK="$CARGO_TARGET_DIR/macos-package"
APP="$WORK/SolveCraft.app"
APP="$WORK/SolidCraft.app"
DMG="$DIST/solvecraft-$VERSION-macos-$ARCH.dmg"
CLI_ZIP="$DIST/solvecraft-cli-$VERSION-macos-$ARCH.zip"
@@ -54,18 +54,18 @@ for bin in solvecraft solvecraft-cli; do
lipo -info "$WORK/bin/$bin"
done
# ---- SolveCraft.app ----------------------------------------------------------------------------
# ---- SolidCraft.app ----------------------------------------------------------------------------
echo "==> assembling $APP"
mkdir -p "$APP/Contents/MacOS" "$APP/Contents/Resources"
cp "$WORK/bin/solvecraft" "$APP/Contents/MacOS/SolveCraft"
cp "$WORK/bin/solvecraft" "$APP/Contents/MacOS/SolidCraft"
# The icon, drawn by the CLI (no image files are committed).
SET="$WORK/SolveCraft.iconset"
SET="$WORK/SolidCraft.iconset"
mkdir -p "$SET"
for s in 16 32 128 256 512; do
"$WORK/bin/solvecraft-cli" icon --size "$s" --out "$SET/icon_${s}x${s}.png" >/dev/null
"$WORK/bin/solvecraft-cli" icon --size $((s * 2)) --out "$SET/icon_${s}x${s}@2x.png" >/dev/null
done
iconutil -c icns -o "$APP/Contents/Resources/SolveCraft.icns" "$SET"
iconutil -c icns -o "$APP/Contents/Resources/SolidCraft.icns" "$SET"
mkdir -p "$APP/Contents/Resources/Licenses"
copy_docs "$APP/Contents/Resources/Licenses"
sed -e "s/@VERSION@/$VERSION/g" -e "s/@SHORT_VERSION@/$SHORT_VERSION/g" "$HERE/Info.plist.in" >"$APP/Contents/Info.plist"
@@ -79,8 +79,9 @@ codesign --verify --strict --deep --verbose=2 "$APP"
echo "==> building $DMG"
STAGE="$WORK/dmg"
mkdir -p "$STAGE"
ditto "$APP" "$STAGE/SolveCraft.app"
ditto "$APP" "$STAGE/SolidCraft.app"
ln -s /Applications "$STAGE/Applications"
cp "$HERE/README.txt" "$STAGE/README.txt"
rm -f "$DMG" "$WORK/raw.dmg"
# makehybrid + convert builds the image without attaching a device, unlike `create -srcfolder`,
# which is flaky on CI runners ("Resource busy").
@@ -91,15 +92,25 @@ rm -f "$WORK/raw.dmg"
# Check the image as a user gets it: mount it and look inside.
MNT="$(mktemp -d)"
hdiutil attach -readonly -nobrowse -mountpoint "$MNT" "$DMG"
ls -la "$MNT" "$MNT/SolveCraft.app/Contents" "$MNT/SolveCraft.app/Contents/MacOS" "$MNT/SolveCraft.app/Contents/Resources"
ls -la "$MNT" "$MNT/SolidCraft.app/Contents" "$MNT/SolidCraft.app/Contents/MacOS" "$MNT/SolidCraft.app/Contents/Resources"
test -L "$MNT/Applications" && test "$(readlink "$MNT/Applications")" = /Applications
plutil -lint "$MNT/SolveCraft.app/Contents/Info.plist"
plutil -lint "$MNT/SolidCraft.app/Contents/Info.plist"
# Check the names Finder/LaunchServices actually use, as well as compatibility identity.
for key in CFBundleName CFBundleDisplayName CFBundleExecutable CFBundleIconFile; do
test "$(/usr/libexec/PlistBuddy -c "Print :$key" "$MNT/SolidCraft.app/Contents/Info.plist")" = SolidCraft
done
test "$(/usr/libexec/PlistBuddy -c 'Print :CFBundleIdentifier' "$MNT/SolidCraft.app/Contents/Info.plist")" = "$APP_ID"
test ! -e "$MNT/SolveCraft.app"
test -s "$MNT/SolidCraft.app/Contents/Resources/SolidCraft.icns"
cmp "$HERE/README.txt" "$MNT/README.txt"
case "$ARCH" in universal) WANT=(arm64 x86_64) ;; aarch64) WANT=(arm64) ;; *) WANT=(x86_64) ;; esac
lipo "$MNT/SolveCraft.app/Contents/MacOS/SolveCraft" -verify_arch "${WANT[@]}"
test -s "$MNT/SolveCraft.app/Contents/Resources/Licenses/THIRD-PARTY-LICENSES.txt"
for arch in "${WANT[@]}"; do
lipo "$MNT/SolidCraft.app/Contents/MacOS/SolidCraft" -verify_arch "$arch"
done
test -s "$MNT/SolidCraft.app/Contents/Resources/Licenses/THIRD-PARTY-LICENSES.txt"
# Not --strict: the mounted HFS volume adds Finder info, which strict verification rejects.
codesign --verify --deep --verbose=2 "$MNT/SolveCraft.app"
"$MNT/SolveCraft.app/Contents/MacOS/SolveCraft" --version
codesign --verify --deep --verbose=2 "$MNT/SolidCraft.app"
"$MNT/SolidCraft.app/Contents/MacOS/SolidCraft" --version
hdiutil detach "$MNT"
# ---- CLI ---------------------------------------------------------------------------------------