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.
This commit is contained in:
commit
b0e83059a3
82 files changed
+20372
No files matched your search
@@ -0,0 +1,38 @@
|
||||
// A test project for Dev Updater, not a real app. See ../README.md.
|
||||
//
|
||||
// The two-component case: a server on the build machine beside an APK for
|
||||
// the phone. That pairing is what Dev Updater itself is, so it is the shape
|
||||
// most worth having a second of -- a project where breaking something
|
||||
// cannot take the updater down with it.
|
||||
//
|
||||
// What it exercises that a one-component project cannot: two builds running
|
||||
// at once with a bar and a timing each, the project area at the bottom
|
||||
// holding only what belongs to the whole project, and the whole service
|
||||
// contract -- install, start, stop, status, restart, and a runtime log that
|
||||
// is not this server's own.
|
||||
label: "Test: Service + App",
|
||||
|
||||
// Declared, so the Uninstall dialog has real paths to show and its data and
|
||||
// config toggles are enabled. `hello-app` deliberately declares nothing,
|
||||
// which is the other half of that test.
|
||||
resources: Ron("resources.ron"),
|
||||
|
||||
components: [
|
||||
Server(
|
||||
name: "daemon",
|
||||
build: "./build-daemon.sh",
|
||||
// Managed, so Dev Updater's own service script drives it and this
|
||||
// project needs no systemd or OpenRC knowledge of its own. The
|
||||
// unit is named `<key>-daemon` after the key this project is added
|
||||
// under.
|
||||
//
|
||||
// The leading `./` is load-bearing: service-default.sh resolves a
|
||||
// program containing a slash against the working directory and
|
||||
// looks anything else up on PATH.
|
||||
service: Managed("./serve.sh"),
|
||||
),
|
||||
Apk(
|
||||
name: "app",
|
||||
build: ["../lib/build-apk.sh", "--package", "com.example.dutest.service", "--label", "Test Service"],
|
||||
),
|
||||
],
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
#!/bin/sh
|
||||
# "Builds" this project's daemon, which is a shell script and so needs no
|
||||
# building at all. What it actually does is take a few seconds and report
|
||||
# progress, because that is the thing worth having: a component slow enough
|
||||
# to watch a bar move on, next to an APK component that finishes in two
|
||||
# seconds. A card with one instant component and one slow one is how you see
|
||||
# whether the per-component timings and the concurrent build really are per
|
||||
# component.
|
||||
set -eu
|
||||
|
||||
STEPS=8
|
||||
i=0
|
||||
while [ "$i" -lt "$STEPS" ]; do
|
||||
i=$((i + 1))
|
||||
echo "@@progress $i/$STEPS"
|
||||
echo "==> Pretending to compile part $i of $STEPS"
|
||||
sleep 1
|
||||
done
|
||||
|
||||
chmod +x ./serve.sh
|
||||
echo "==> Daemon ready"
|
||||
@@ -0,0 +1,10 @@
|
||||
// Where this test project keeps its state, in the shape Dev Updater reads
|
||||
// (`ResourceFacts` in server/src/config.rs) -- the body of the struct, no
|
||||
// outer parentheses, which is the house rule for every RON file here.
|
||||
//
|
||||
// Only `name` is given, so the data and config directories follow from it:
|
||||
// $XDG_DATA_HOME/dutest-service and $XDG_CONFIG_HOME/dutest-service. That
|
||||
// is the ordinary case, and it keeps both paths under the XDG directories,
|
||||
// which matters because Uninstall removes a path wherever it points and the
|
||||
// dialog showing it is the only guard.
|
||||
name: "dutest-service",
|
||||
Executable
+24
@@ -0,0 +1,24 @@
|
||||
#!/bin/sh
|
||||
# The long-running half of this test project: a service that does nothing
|
||||
# except say so, once every ten seconds, forever.
|
||||
#
|
||||
# It writes into its own data directory -- the one resources.ron names -- so
|
||||
# that Uninstall's "remove data" toggle has something real to remove, and so
|
||||
# that the directory exists to be shown in the dialog. Its *log* is not
|
||||
# written here: a managed service's output is captured by Dev Updater's
|
||||
# service script, which is what the runtime log tab reads.
|
||||
set -eu
|
||||
|
||||
DATA="${XDG_DATA_HOME:-$HOME/.local/share}/dutest-service"
|
||||
mkdir -p "$DATA"
|
||||
|
||||
echo "started at $(date -Is), writing to $DATA"
|
||||
count=0
|
||||
while true; do
|
||||
count=$((count + 1))
|
||||
echo "$(date -Is) tick $count" >>"$DATA/ticks.log"
|
||||
# Colour, so the runtime log tab has escapes to render too -- the same
|
||||
# reason breakable/build.sh writes them.
|
||||
printf 'tick \033[1;32m%s\033[0m -- still here\n' "$count"
|
||||
sleep 10
|
||||
done
|
||||
Reference in new issue
Block a user