feat(packaging): the unsigned macOS .dmg built in CI, and the docs for steps 3 and 4 (P11a step 6, macOS half)

cargo-packager's dmg format (it makes the .app first) from
deploy/packaging/packager-macos.toml, an Info.plist merged into the
generated one, build-macos.sh in portable shell (BSD sed) and a
package-macos recipe; the release workflow gets a macos job on
macos-latest that uploads the .dmg as a run artifact and attaches it on a
tag. Unsigned and not notarized: that is step 5 (the owner's Developer ID,
Q-4). The config was parsed under cargo-packager 0.11.8's strict schema on
Linux; the build itself needs the CI run. No new dependency.
docs/packaging.md (macOS rows, finding 7 resolved, the staged update),
architecture.md and testing.md describe steps 3 and 4.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HS8WZziDnyxunC23MUxrLp
This commit is contained in:
swaitsandClaude Fable 5.1 committed 2026-10-29 16:25:34 -06:00
1 parent 6e7deb15c7
commit bc9aa57380
8 files changed
+221 -22

No files matched your search

+12
View File
@@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<!-- Merged by cargo-packager into the Info.plist it generates for the
.app (P11a step 6): the keys the generated one lacks. -->
<plist version="1.0">
<dict>
<key>LSMultipleInstancesProhibited</key>
<true/>
<key>NSSupportsAutomaticGraphicsSwitching</key>
<true/>
</dict>
</plist>
+33
View File
@@ -0,0 +1,33 @@
#!/usr/bin/env bash
# The macOS bundle (P11a step 6), UNSIGNED, from the release program
# already built at target/release/wanderbooks (`cargo build --release -p
# ledger-cli`). Run on a Mac from the repository root:
#
# build-macos.sh [VERSION]
#
# Puts Wanderbooks_VERSION_<arch>.dmg into target/packages/VERSION/. It
# is not signed or notarized (step 5): Gatekeeper refuses it on a Mac
# that downloaded it, and the owner opens it with right-click > Open.
# Portable shell: macOS has BSD sed and no GNU mktemp options.
set -euo pipefail
own=$(sed -n 's/^version = "\(.*\)"/\1/p' crates/ledger-cli/Cargo.toml | head -n1)
version=${1:-$own}
out="target/packages/$version"
program=${WB_PROGRAM:-target/release/wanderbooks}
test -x "$program" || { echo "build the release program first: cargo build --release -p ledger-cli" >&2; exit 1; }
rm -rf "$out"; mkdir -p "$out"
stage="target/packages/.stage-$version"
rm -rf "$stage"; mkdir -p "$stage"
cp "$program" "$stage/wanderbooks"
config="$stage/packager.toml"
# cargo-packager reads paths relative to the config file, which is in the
# stage folder here, so they are made absolute.
sed -e "s/^version = \".*\"/version = \"$version\"/" \
-e "s#^out-dir = .*#out-dir = \"$PWD/$out\"#" \
-e "s#\"target/release\"#\"$PWD/$stage\"#" \
-e "s#\"deploy/packaging/#\"$PWD/deploy/packaging/#" \
-e "s#\"LICENSE-MIT\"#\"$PWD/LICENSE-MIT\"#" \
deploy/packaging/packager-macos.toml >"$config"
cargo packager --config "$config" --formats dmg --release
rm -rf "$stage"
ls -l "$out"
+36
View File
@@ -0,0 +1,36 @@
# cargo-packager's description of the macOS bundle (P11a step 6; D-24,
# D-25): the .app and its .dmg, UNSIGNED. `deploy/packaging/build-macos.sh`
# runs it on a Mac (CI: the `macos` job of .github/workflows/release.yml).
# Developer ID signing and notarization are step 5 (the owner's Apple
# certificate, Q-4): they add `signing-identity` under [macos] and the
# certificate and notarization credentials as CI secrets.
# Paths are relative to this file's copy that build-macos.sh writes.
name = "wanderbooks"
product-name = "Wanderbooks"
version = "0.1.0"
identifier = "ai.wanderbooks.app"
description = "Double-entry bookkeeping your agent keeps and you can read."
homepage = "https://wanderbooks.ai"
authors = ["Stephen Waits"]
license-file = "LICENSE-MIT"
category = "Finance"
binaries-dir = "target/release"
out-dir = "target/packages"
# A png is made into the .icns (cargo-packager does it); the 512 px
# placeholder is the owner's to replace.
icons = ["deploy/packaging/icons/512x512.png"]
formats = ["dmg"]
binaries = [{ path = "wanderbooks", main = true }]
[macos]
# The oldest macOS Rust's tier-1 aarch64-apple-darwin and x86-64 targets
# run on; eframe's wgpu/Metal path needs 10.15 at least.
minimum-system-version = "11.0"
# Keys merged into the generated Info.plist: one viewer at a time, and the
# discrete GPU is not woken for a ledger.
info-plist-path = "deploy/packaging/Info.plist"
[dmg]
window-size = { width = 540, height = 380 }
app-position = { x = 140, y = 180 }
application-folder-position = { x = 400, y = 180 }