Give each component build modes and a settings sheet
A component now declares its ways of being built in one list -- `modes: ["release", "debug"]`, the first the default -- and every command it runs is handed the mode as its last argument, so a project whose script takes `release` or `debug` names that script once. A field may instead be written per mode, which is the escape hatch for the commands that cannot take the word: cargo takes `--release` or nothing, and its profile for the unoptimised build is called `dev` while the directory it writes is called `debug`, so no single word serves as both the flag and the path. A command written per mode is not handed the word as well; it already is the answer, and a stray argument to a service binary is a process that will not start. One list rather than gathering names from whichever fields happened to mention them is what makes a mode missing from one part unsayable: every per-mode map is checked against it, so a gap is named rather than resolved to some other mode's command. Which mode to build in and whether to strip are the build machine's -- there is one checkout and one set of outputs, so a per-device mode would have two phones rebuilding over each other silently. Which of the finished builds a phone installs stays that phone's. Neither choice is part of the acceptance gate, so both have to be carried across the components list being rewritten, by acceptance and by the self entry's startup reconciliation alike; without the second a mode chosen for this server's own component would not survive the restart that applies it. A mode switch moves no commit, so `builtMode` is recorded beside `builtFrom`. Without it a component built in debug and switched to release reads as current and serves the debug build for ever -- and for an APK nothing else notices, because the "never built at all" check finds any variant under the component's directory. Each component card gains a settings sheet behind a gear at the row's right-hand end, holding the mode, which build to install, strip, and an Enrol button. The variant picker moved into it: on the card the two read as one choice, both saying debug and release, and they are not. The row's text is now bounded and truncates, so a long status can no longer push the log and settings buttons off the edge. `enroll:` is a declared command whose one line of stdout is a URL for the phone to open after installing -- generic on purpose, run per press since such a link is one-shot and carries a credential, and in the acceptance gate because it runs on the build machine. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
1 parent
0b7164bb30
commit
17d873ab7c
16 files changed
+2225
-220
No files matched your search
+33
-2
@@ -28,19 +28,50 @@ components: [
|
||||
// started anywhere else this server finds no checkout of its own,
|
||||
// and its card silently loses the branch line, its commit count
|
||||
// and the Pull button.
|
||||
build: "cargo build --release --manifest-path server/Cargo.toml",
|
||||
// The ways this component can be built, declared in one place.
|
||||
// Release first, because the first is the default: what this
|
||||
// server serves to a phone should be the optimised build unless
|
||||
// somebody says otherwise, and debug is here for the times when
|
||||
// a stack trace matters more than the speed.
|
||||
modes: ["release", "debug"],
|
||||
// Written per mode rather than handed the mode as an argument,
|
||||
// which is the escape hatch and this is what it is for: cargo
|
||||
// takes `--release` or nothing, and its *profile* for the
|
||||
// unoptimised build is called `dev` while the directory it
|
||||
// writes is called `debug`. So no single word can serve as both
|
||||
// the flag and the path, and a project that wants one would have
|
||||
// to carry a wrapper script to translate.
|
||||
build: {
|
||||
"release": "cargo build --release --manifest-path server/Cargo.toml",
|
||||
"debug": "cargo build --manifest-path server/Cargo.toml",
|
||||
},
|
||||
// Managed, like anything else that just wants its binary kept
|
||||
// running. Nothing about restarting *this* server lives in the
|
||||
// script -- that is `restart.rs`, which defers the hand-over past
|
||||
// the reply and spawns it detached. So there was nothing left for
|
||||
// a script of its own to say.
|
||||
service: Managed("server/target/release/dev-updater"),
|
||||
// And the same for the binary, which is the pairing that makes
|
||||
// per-mode worth having at all: built with `--release` and
|
||||
// started from `target/debug/`, this server would go on running
|
||||
// last week's build with nothing anywhere saying so.
|
||||
service: Managed({
|
||||
"release": "server/target/release/dev-updater",
|
||||
"debug": "server/target/debug/dev-updater",
|
||||
}),
|
||||
),
|
||||
Apk(
|
||||
name: "app",
|
||||
// The command resolves against the project root and `cwd` says
|
||||
// where to run it -- two different things, which is why this is
|
||||
// not `./build-apk.sh`.
|
||||
//
|
||||
// Deliberately one mode. A release build of *this* app would be
|
||||
// signed with a different key from the debug one, and Android
|
||||
// refuses to install a differently-signed APK over an installed
|
||||
// package -- which for this app means the copy on the phone can
|
||||
// no longer be updated through the server it updates itself
|
||||
// from. Every other project can switch freely; this is the one
|
||||
// that cannot, because it is the way back.
|
||||
build: "app/build-apk.sh",
|
||||
cwd: "app",
|
||||
),
|
||||
|
||||
Reference in new issue
Block a user