-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathrelease-macos.sh
More file actions
164 lines (149 loc) · 7.93 KB
/
Copy pathrelease-macos.sh
File metadata and controls
164 lines (149 loc) · 7.93 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
#!/usr/bin/env bash
# Build self-contained macOS artifacts for the Catalyst Code, per arch
# (arm64 + x86_64):
#
# 1. A standalone executable — the TUI with the Rust core embedded via go:embed
# (-tags embed_core). One file per arch; run it from any CWD and it extracts
# its bundled core to ~/Library/Caches/catalyst-code on first run — no
# separate catcode-core, no install.
#
# 2. A catcode .dmg installer wrapping that standalone executable. The .dmg
# contains `catcode` (the standalone) + a double-clickable "Install
# catcode.command" that copies it onto your PATH, + a README. Mounts on macOS
# and installs with one click.
#
# Run on Linux. Needs: cargo + the aarch64-apple-darwin / x86_64-apple-darwin
# rustup targets, Go 1.21+, zig (0.13+) on PATH, cargo-zigbuild, and (to build
# the .dmg) xorriso. Building the .dmg ON a Mac instead uses hdiutil (real UDIF).
#
# rustup target add aarch64-apple-darwin x86_64-apple-darwin
# cargo install cargo-zigbuild # and put zig on PATH
#
# ./release-macos.sh [version] # version defaults to the git commit (short SHA)
# CATCODE_MACOS_ARCH=arm64 ./release-macos.sh # build one arch (CI fan-out)
set -euo pipefail
cd "$(dirname "$0")"
VERSION="${1:-$(git rev-parse --short HEAD 2>/dev/null || grep -m1 '^version' core/Cargo.toml | sed -E 's/.*"([^"]+)".*/\1/')}"
EMBED_FILE="tui/embed/catcode-core"
MACOS_ARCH="${CATCODE_MACOS_ARCH:-all}"
case "$MACOS_ARCH" in
all|arm64|x86_64) ;;
*) echo "error: CATCODE_MACOS_ARCH must be all, arm64, or x86_64" >&2; exit 1 ;;
esac
require() { command -v "$1" >/dev/null 2>&1 || { echo "error: '$1' not found — $2" >&2; exit 1; }; }
require cargo "install rustup/rust"
require go "https://go.dev/dl/"
require zig "install zig 0.13+ from https://ziglang.org/download/ and put it on PATH"
require cargo-zigbuild "cargo install cargo-zigbuild"
# The .dmg needs hdiutil (macOS) or xorriso (Linux). Fail fast with a clear
# message if neither is present so the user isn't told after a long build.
if ! command -v hdiutil >/dev/null 2>&1 && ! command -v xorriso >/dev/null 2>&1; then
echo "error: need hdiutil (on macOS) or xorriso (on Linux) to build the .dmg" >&2
echo " install xorriso (e.g. apt install xorriso / brew install xorriso)" >&2
exit 1
fi
mkdir -p dist tui/embed
# Always remove a stale injected core on exit so it never leaks into the tree.
trap 'rm -f "$EMBED_FILE"' EXIT
echo "==> building catalyst-code ${VERSION} for macOS (standalone + .dmg, core embedded)"
# make_dmg <standalone_path> <tag> -> dist/catcode-<ver>-macos-<tag>.dmg
make_dmg() {
local standalone="$1" tag="$2"
local volname="catcode-${VERSION}-macos-${tag}"
local out="dist/catcode-${VERSION}-macos-${tag}.dmg"
local stage; stage="$(mktemp -d)"
# Layout: catcode (the standalone, renamed) + one-click installer + README.
cp "$standalone" "$stage/catcode"
cp packaging/macos/install.command "$stage/Install catcode.command"
sed "s/<VERSION>/${VERSION}/g; s/<ARCH>/${tag}/g" \
packaging/macos/README.txt > "$stage/README.txt"
chmod +x "$stage/catcode" "$stage/Install catcode.command"
if command -v hdiutil >/dev/null 2>&1; then
# Real UDIF compressed DMG (build host is macOS).
hdiutil create -srcfolder "$stage" -volname "$volname" \
-fs HFS+ -format UDZO -ov "$out" >/dev/null
elif command -v xorriso >/dev/null 2>&1; then
# HFS+ hybrid image (build host is Linux; mounts on macOS via
# DiskImageMounter). The ISO9660 volid-compliance warning, if any,
# is cosmetic — the HFS+ volume name is what macOS displays.
xorriso -as mkisofs -V "$volname" -hfsplus -rock -no-pad \
-o "$out" "$stage" >/dev/null 2>&1 || \
xorriso -as mkisofs -V "$volname" -hfsplus -rock -no-pad -o "$out" "$stage"
else
echo "error: need hdiutil (macOS) or xorriso (Linux) to build the .dmg" >&2
echo " (the standalone was still built; only the .dgm was skipped)" >&2
rm -rf "$stage"; return 1
fi
rm -rf "$stage"
echo " -> ${out} ($(du -h "$out" | cut -f1))"
}
build_arch() {
local rust_target="$1" goarch="$2" tag="$3"
echo "[1/3] core -> ${rust_target} (cargo zigbuild --release, no microsandbox)..."
# Build the macOS core WITHOUT the `microsandbox` default feature. The
# Microsandbox SDK (msb_krun_utils) references `kvm_bindings` (Linux KVM)
# unconditionally and does not compile for the darwin target at all — so a
# feature-on darwin build dies at `error[E0433]: cannot find crate
# kvm_bindings`. With the feature off the core uses its fail-closed
# `UnsupportedSandboxBackend` (manager.rs): default config is sandbox=none
# (runs on the host, fully usable); an explicit --sandbox microsandbox on
# macOS returns a structured SetupRequired error instead of running on the
# host. Linux/Windows releases still build microsandbox-enabled.
cargo zigbuild --release --target "$rust_target" --no-default-features --manifest-path core/Cargo.toml
# cargo-zigbuild writes to the standard target/<triple>/release path; the
# [[bin]] name in core/Cargo.toml is "core" (no suffix on macOS).
local corebin="core/target/${rust_target}/release/core"
[[ -f "$corebin" ]] || { echo "error: expected core binary at $corebin" >&2; exit 1; }
cp "$corebin" "$EMBED_FILE"
echo "[2/3] tui -> darwin/${goarch} (go build -tags embed_core, core embedded)..."
local out="dist/catcode-${VERSION}-macos-${tag}"
( cd tui && CGO_ENABLED=0 GOOS=darwin GOARCH="$goarch" \
go build -trimpath -tags embed_core \
-ldflags "-s -w -X main.coreVersion=${VERSION}" \
-o "../${out}" . )
chmod +x "${out}"
rm -f "$EMBED_FILE"
echo " -> ${out} ($(du -h "${out}" | cut -f1))"
# Separate core binary (no embed) for the web service's CATCODE_CORE.
# Built from the SAME cargo-zigbuild artifact as the embedded core.
local core_art="dist/catcode-core-${VERSION}-macos-${tag}"
cp "$corebin" "$core_art"; chmod +x "$core_art"
echo " -> ${core_art} ($(du -h "$core_art" | cut -f1))"
echo "[3/3] dmg -> dist/catcode-${VERSION}-macos-${tag}.dmg..."
make_dmg "${out}" "${tag}" || echo " (warning: .dmg for ${tag} skipped — see message above)"
}
if [[ "$MACOS_ARCH" == all || "$MACOS_ARCH" == arm64 ]]; then
build_arch aarch64-apple-darwin arm64 arm64
fi
if [[ "$MACOS_ARCH" == all || "$MACOS_ARCH" == x86_64 ]]; then
build_arch x86_64-apple-darwin amd64 x86_64
fi
echo "[done] checksums..."
( cd dist
for f in catcode-${VERSION}-macos-arm64 catcode-${VERSION}-macos-x86_64 \
catcode-core-${VERSION}-macos-arm64 catcode-core-${VERSION}-macos-x86_64 \
catcode-${VERSION}-macos-arm64.dmg catcode-${VERSION}-macos-x86_64.dmg; do
if [[ -f "$f" ]]; then
sha256sum "$f" > "$f.sha256"
fi
done )
# P1-23: for distribution, codesign + notarize each artifact with an Apple
# Developer ID in CI (not done here — no signing identity available):
# codesign --force --options runtime --sign "Developer ID Application: ..." "$f"
# ditto -c -k --keepParent "$f" "${f}.zip"
# xcrun notarytool submit "${f}.zip" --apple-id ... --team-id ... --password ... --wait
# xcrun stapler staple "$f"
# Without this, Gatekeeper blocks the unsigned artifacts for most users.
echo "==> dist/catcode-${VERSION}-macos-arm64 (standalone, Apple Silicon)"
echo "==> dist/catcode-${VERSION}-macos-x86_64 (standalone, Intel)"
echo "==> dist/catcode-core-${VERSION}-macos-arm64 (core binary; web service CATCODE_CORE)"
echo "==> dist/catcode-core-${VERSION}-macos-x86_64 (core binary; web service CATCODE_CORE)"
echo "==> dist/catcode-${VERSION}-macos-arm64.dmg (installer, Apple Silicon)"
echo "==> dist/catcode-${VERSION}-macos-x86_64.dmg (installer, Intel)"
echo
echo "Download + run the standalone from any directory:"
echo " chmod +x catcode-${VERSION}-macos-arm64"
echo " ./catcode-${VERSION}-macos-arm64 # launches in the current directory"
echo "Or install via the .dmg: open catcode-${VERSION}-macos-arm64.dmg -> double-click 'Install catcode.command'"
echo "Then run from any terminal: catcode"
echo "First run: /login then /model, then type a prompt."