zuka
zuka/.zuka.toml

worklyn / zukapublic

Agent-first git hosting. One Rust binary: git over HTTP and SSH, a REST API, MCP, CI, and multi-tenant isolation.

Get a copy: git clone https://zuka.worklyn.com/worklyn/zuka.git
zuka/.zuka.toml
TOML.zuka.toml3.7 KBDownload
1# zuka builds and deploys itself.
2#
3# This runs on the build instance — a second zuka on the same host, separate from the
4# control plane. That separation is not tidiness: the last step restarts the control
5# plane, and a build running inside the thing it restarts would kill itself half way
6# through its own deploy.
7
8[run]
9# A cold Rust build plus the live suite on two cores. The default 600s is not close
10# to enough, and a timeout that trips on a clean build teaches everyone to ignore red.
11timeout_secs = 2400
12
13steps = [
14 # Cheapest first: formatting and lints fail in seconds, so a badly formatted commit
15 # does not occupy the host for twenty minutes before saying so.
16 "cargo fmt --check",
17
18 # CARGO_TARGET_DIR on every cargo step, because each run gets a fresh workspace and
19 # a target directory inside it would be thrown away — making every build a cold
20 # twenty-five minute one. Cargo locks this directory, so concurrent runs queue
21 # rather than corrupt each other.
22 "CARGO_TARGET_DIR=/var/lib/zuka-build/target cargo clippy --all-targets -- -D warnings",
23 "CARGO_TARGET_DIR=/var/lib/zuka-build/target cargo test",
24
25 # musl, statically linked. The host runs glibc 2.39 and the tenant containers 2.36,
26 # so a glibc build made here will not start in a container. One static binary runs
27 # in both places, which is what lets the control plane and its tenants be the same
28 # build.
29 "CARGO_TARGET_DIR=/var/lib/zuka-build/target cargo build --release --target x86_64-unknown-linux-musl",
30
31 # The live suite is where the wire protocol and the REST contract are actually
32 # proven. It self-skips without ZUKA_LIVE_TEST, which the task sets, and a proof
33 # that never runs is not one.
34 #
35 # Pointed at the musl binary built above, because that is the exact file the deploy
36 # step ships. Exercising a separate glibc build and then shipping this one would
37 # prove nothing about what actually runs.
38 "ZUKA_TEST_BINARY=/var/lib/zuka-build/target/x86_64-unknown-linux-musl/release/zuka deno task test:live",
39
40 # Hand the binary to root and ask for a deploy, but only from main.
41 #
42 # The guard and the deploy are one step on purpose: `exit 0` only ends its own
43 # step, so a guard in a step of its own would skip nothing and every branch would
44 # deploy.
45 #
46 # CI holds no privilege and cannot deploy by itself. It writes the binary and a
47 # request file; a root systemd.path unit notices the request and runs the deploy,
48 # which restarts the service, checks that the new build is the one answering, and
49 # puts the old binary back if it is not. The result comes back through a file so a
50 # failed deploy still turns this run red — a build that goes green while the deploy
51 # quietly failed is worse than not deploying at all.
52 '''
53 set -eu
54 BIN=/var/lib/zuka-build/target/x86_64-unknown-linux-musl/release/zuka
55 BUILD=$("$BIN" version | awk '{print $NF}')
56
57 if [ "$ZUKA_REF" != refs/heads/main ]; then
58 echo "$ZUKA_REF is not main - built and tested $BUILD, not deploying"
59 exit 0
60 fi
61
62 S=/var/lib/zuka-build/staging
63 mkdir -p "$S"
64 # Clear the previous run's answer first, or a stale OK would be read as this
65 # deploy succeeding before root has even started.
66 rm -f "$S/deploy.result"
67 cp "$BIN" "$S/zuka"
68 echo "$BUILD" > "$S/deploy.request"
69 echo "requested deploy of $BUILD"
70
71 n=0
72 while [ "$n" -lt 180 ]; do
73 if [ -f "$S/deploy.result" ]; then
74 R=$(cat "$S/deploy.result")
75 echo "$R"
76 case "$R" in
77 "OK $BUILD"*) exit 0 ;;
78 OK*) echo "a different build was deployed; expected $BUILD"; exit 1 ;;
79 *) exit 1 ;;
80 esac
81 fi
82 sleep 2
83 n=$((n + 2))
84 done
85 echo "no deploy result after 180s"
86 exit 1
87 ''',
88]