#!/usr/bin/env bash # Builds the client, `knotless`, `git-remote-knotless` and `knotless-mcp`, # and the accounts that work for a repository, `knotless-run` (its runner), # `knotless-triage` (its labeller) and `knotless-agent` (its reviewer, with # the `knotless-claude-review` script it runs), for every target the install script fetches, as one archive per target: # # deploy/build-client.sh [...] # # leaves /knotless--.tar.gz, each holding a # directory of that name with the binaries, README and licences. The # version is the workspace's, in Cargo.toml. With no target named, it # empties and builds them all; with some, it builds only those, # replacing their archives and leaving the rest, so a workflow can build # each in a step of its own, each within the runner's step timeout. # # On a Mac, both macOS targets build natively; every other target builds # with cargo-zigbuild (`brew install zig`, `cargo install cargo-zigbuild`), # on Linux all four, macOS included: the client links no macOS framework. # TOOLCHAIN is rustup's toolchain to build with (stable; empty for the # default, as in a rust image), and CARGO the cargo to run (its). set -euo pipefail cd "$(dirname "$0")/.." OUT="${1:?usage: deploy/build-client.sh [...]}" shift TOOLCHAIN="${TOOLCHAIN-stable}" CARGO="${CARGO:-${TOOLCHAIN:+rustup run $TOOLCHAIN }cargo}" VERSION="$(sed -n 's/^version = "\(.*\)"/\1/p' Cargo.toml | head -1)" ALL=(aarch64-apple-darwin x86_64-apple-darwin x86_64-unknown-linux-musl aarch64-unknown-linux-musl) if [ $# -gt 0 ]; then TARGETS=("$@") for target in "${TARGETS[@]}"; do [[ " ${ALL[*]} " == *" $target "* ]] || { echo "not a target the install script fetches: $target" >&2; exit 2; } done else TARGETS=("${ALL[@]}") rm -rf "$OUT" fi $CARGO zigbuild --help >/dev/null 2>&1 \ || { echo "needs cargo-zigbuild: cargo install cargo-zigbuild, and zig" >&2; exit 1; } rustup target add ${TOOLCHAIN:+--toolchain "$TOOLCHAIN"} "${TARGETS[@]}" >/dev/null mkdir -p "$OUT" for target in "${TARGETS[@]}"; do echo "→ building $VERSION for $target" case "$(uname -s) $target" in "Darwin "*-apple-darwin) build=build ;; *) build=zigbuild ;; esac $CARGO $build --release --locked --target "$target" -p knotless -p knotless-mcp -p knotless-run -p knotless-triage -p knotless-agent name="knotless-$VERSION-$target" rm -rf "$OUT/$name" "$OUT/$name.tar.gz" mkdir "$OUT/$name" for bin in knotless git-remote-knotless knotless-mcp knotless-run knotless-triage knotless-agent; do cp "target/$target/release/$bin" "$OUT/$name/" done install -m 755 crates/knotless-agent/claude-review "$OUT/$name/knotless-claude-review" cp README.md LICENSE-MIT LICENSE-APACHE "$OUT/$name/" tar -czf "$OUT/$name.tar.gz" -C "$OUT" "$name" rm -r "$OUT/$name" done