Files
iris b0e83059a3 dev-updater: build an app on the machine, install it on the phone
A Rust backend that discovers Android projects under configured roots,
builds one on request, and serves the APK over pinned TLS on a WireGuard
interface; an Android client that lists what is buildable, watches a build,
and installs the result. Enrolment carries the token and the CA, so the
phone trusts exactly the machine that issued it and nothing else.

`AGENTS.md` is the working guide and `README.md` the configuration
reference. The shared tunnel-and-TLS code lives in `vendor/wg-app-link`,
which ai-app uses too.

History before this point was squashed away, and a stale `config.json` went
with it: nothing had read that file since the config moved to RON outside
the checkout, and what it still held was one machine's absolute paths and
the names of projects on it.
2026-08-31 20:31:08 -04:00

74 lines
2.9 KiB
Bash
Executable File

#!/bin/sh
# Builds both halves and gets the server service running again.
#
# ./start.sh
#
# The "put it back the way it should be" script: run it after a pull, or
# whenever the running server and the checkout have drifted apart. Every
# step is safe to repeat, so running it when nothing is wrong is a no-op
# that takes as long as a cached build.
#
# The service is reinstalled rather than only installed when missing. The
# unit file is generated from the service script, so a pull that changes
# how the service is defined leaves an installed unit that is out of date
# -- and that unit is what decides the working directory the server starts
# in, which is where it looks for its own checkout. Rewriting it every time
# is the only way running this actually guarantees the state it claims to.
#
# The service steps go through the freshly built binary's `--service`,
# which derives the name and the script from the same declaration the
# running server reads. So there is one definition of this service rather
# than a bootstrap copy of it here.
set -eu
cd "$(dirname "$0")"
# The binary decides how its own service is named and invoked, so nothing
# here has to. It is built by the step above, which is what makes asking it
# possible at all -- and it means this script cannot drift out of step with
# `service::driver` the way a second copy of the name and arguments would.
SERVICE="./server/target/release/dev-updater --service"
# This service used to be installed under its own name by a script of its
# own. Left in place, that unit would still start a second copy at boot,
# which then loses the race for the port -- so it goes before the new one
# arrives. Harmless once it is gone; this is a no-op on every later run.
LEGACY="${XDG_CONFIG_HOME:-$HOME/.config}/systemd/user/dev-updater.service"
LEGACY_OPENRC="${XDG_CONFIG_HOME:-$HOME/.config}/rc/init.d/dev-updater"
if [ -f "$LEGACY" ] || [ -f "$LEGACY_OPENRC" ]; then
echo "==> Removing the old dev-updater unit, which this service replaces"
if [ -f "$LEGACY" ]; then
systemctl --user disable --now dev-updater >/dev/null 2>&1 || true
rm -f "$LEGACY"
systemctl --user daemon-reload
fi
if [ -f "$LEGACY_OPENRC" ]; then
rc-service --user dev-updater stop >/dev/null 2>&1 || true
rc-update --user del dev-updater >/dev/null 2>&1 || true
rm -f "$LEGACY_OPENRC"
fi
fi
# Server first, then the APK: if the APK build fails, the phone keeps being
# offered the one it already had rather than half of a matched pair.
./build-self.sh
echo
echo "==> Installing the service"
$SERVICE install
# Told apart because restart on a service somebody stopped on purpose is a
# different thing from starting one that is merely down.
case "$($SERVICE status)" in
running)
echo "==> Restarting into the build just made"
$SERVICE restart
;;
*)
echo "==> Starting"
$SERVICE start
;;
esac
echo
echo "==> the service is $($SERVICE status)"