Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
809882b333 | ||
|
|
0124e1c67b | ||
|
|
476202f8e2 |
@@ -10,6 +10,149 @@ and manages WiFi/provisioning on a headless Linux kiosk.
|
||||
**Audio:** SDL3_mixer
|
||||
**Target:** Linux kiosk (Wayland); developed on macOS
|
||||
|
||||
---
|
||||
## Version Deployment
|
||||
> How to release a new version of RadiantWave, and what happens on the kiosks when you do.
|
||||
|
||||
### Two channels, two update paths
|
||||
|
||||
| Channel | App input | Attic cache | Manifest |
|
||||
|---|---|---|---|
|
||||
| `dev` | `radiantwave-dev` (`?ref=dev`) | `attic.../radiantwave-dev` | `files.../radiantwave-dev/manifest.json` |
|
||||
| `main` | `radiantwave` (`?ref=refs/tags/1.8`) | `attic.../radiantwave` | `files.../radiantwave/manifest.json` |
|
||||
|
||||
A kiosk gets RadiantWave by two independent paths:
|
||||
|
||||
- **Live app update** -- CI publishes a manifest; the kiosk's
|
||||
`radiantwave-updater.timer` fetches the closure from Attic and swaps
|
||||
`/var/lib/radiantwave/current`. Takes effect in ~2 min, no rebuild.
|
||||
- **NixOS rebuild** -- `system.autoUpgrade` runs every 10 min against the
|
||||
`KioskConfig` repo with `--refresh` and rebuilds the whole system closure.
|
||||
|
||||
`KioskConfig` enables `services.radiantwaveUpdater` on all four configs on
|
||||
**both** branches, so the live path is always available.
|
||||
|
||||
**An app-only feature only needs the live app update path. You do not commit,
|
||||
push, or rebuild `../KioskConfig`.** Its `flake.lock` pin of `radiantwave-dev`
|
||||
only determines the closure baked into the ISO; the updater overwrites that
|
||||
pointer as soon as it sees a newer manifest.
|
||||
|
||||
### Test a feature on the dev kiosk -- manual steps
|
||||
|
||||
**1. Build and test locally.**
|
||||
|
||||
```sh
|
||||
nix develop --command bash -c '
|
||||
cmake -S . -B build -G Ninja -DCMAKE_BUILD_TYPE=Debug
|
||||
cmake --build build
|
||||
./build/test_assets
|
||||
'
|
||||
```
|
||||
|
||||
Run each `./build/test_<name>` binary you touched -- there is no ctest
|
||||
integration and no aggregate target. If you added a test file, register it as
|
||||
a new `add_executable` in `CMakeLists.txt` first.
|
||||
|
||||
**2. Land it on `dev`.**
|
||||
|
||||
```sh
|
||||
git switch dev && git pull
|
||||
git switch -c feature/<name>
|
||||
# ... commit your work ...
|
||||
git push -u origin feature/<name>
|
||||
```
|
||||
|
||||
Open a PR against `dev` and merge. The kiosk only ever builds `dev`.
|
||||
|
||||
**3. Dispatch the build workflow** on the RadiantWave repo in Gitea Actions.
|
||||
|
||||
**4. Verify.**
|
||||
|
||||
The Home footer's Version row shows the new short commit hash, and:
|
||||
|
||||
```sh
|
||||
ssh kiosk@<dev-kiosk> 'readlink /var/lib/radiantwave/current'
|
||||
curl -fsSL https://files.radiantwavetech.com/radiantwave-dev/manifest.json | jq .storePath
|
||||
```
|
||||
|
||||
Both must match.
|
||||
|
||||
### Test a feature on the dev kiosk -- automated by CI
|
||||
|
||||
> Everything between dispatching `build.yml` and the kiosk running the new
|
||||
> binary. No human step is required for any of it.
|
||||
>
|
||||
> **Trigger.** `workflow_dispatch` force-clones the `dev` branch
|
||||
> (`REF=dev`, hardcoded -- you cannot pick a branch). A tag push clones the tag.
|
||||
> Either way `APP_VERSION` becomes the short commit hash on dispatch, or
|
||||
> `git describe --tags --always` on a tag.
|
||||
>
|
||||
> **Build.** Native `x86_64-linux` package, then the offline suite via
|
||||
> `checks.<system>.default`, then the live portal tests from `nix develop`
|
||||
> (`RWT_LIVE_*` secrets), then the `aarch64-linux` package and checks. The
|
||||
> aarch64 build is emulated via binfmt/qemu-user and is the long pole.
|
||||
>
|
||||
> **Publish.** `attic push radiantwave:radiantwave-dev` with both
|
||||
> `result-pkg` and `result-pkg-aarch64`, using `ATTIC_TOKEN_DEV`. Then it
|
||||
> writes `{"version","storePath"}` from `readlink -f` of each result into
|
||||
> `manifest.json` (x86) and `aarch64-manifest.json` (arm), and `scp`s both to
|
||||
> `157.245.124.103:/mnt/infrastructure_data/files/radiantwave-dev/`, which is
|
||||
> served as `https://files.radiantwavetech.com/radiantwave-dev/`.
|
||||
>
|
||||
> **Kiosk side.** `radiantwave-updater.timer` (`OnBootSec=2min`,
|
||||
> `OnUnitActiveSec=2min`, `Persistent`) runs the oneshot
|
||||
> `radiantwave-updater.service`, which curls the manifest, `jq`s `.storePath`,
|
||||
> and compares it against `readlink /var/lib/radiantwave/current`. On a new
|
||||
> path it fetches the closure, never building:
|
||||
>
|
||||
> ```sh
|
||||
> nix-store -r "$NEW_PATH" \
|
||||
> --add-root /var/lib/radiantwave/.current-root \
|
||||
> --option extra-substituters "<atticUrl> https://cache.nixos.org"
|
||||
> ```
|
||||
>
|
||||
> Then it swaps atomically with `ln -sfn` plus `mv -T`. Both Attic caches and
|
||||
> their public keys are already trusted in `configuration.nix`, so the kiosk
|
||||
> needs no credentials.
|
||||
>
|
||||
> **Failure mode.** The Attic push and manifest publish are ordinary steps, not
|
||||
> `always()`, so **any failing test blocks publication** and the kiosk keeps
|
||||
> running the previous build. Check the run's log before assuming a deploy
|
||||
> landed.
|
||||
|
||||
### Gotchas
|
||||
|
||||
- **Dispatch hardcodes `dev`.** `build.yml` sets `REF=dev` on
|
||||
`workflow_dispatch`; you cannot select a branch.
|
||||
- **Push before you dispatch.** CI clones `dev` at dispatch time, so dispatching
|
||||
first publishes the previous commit and the feature appears not to deploy.
|
||||
- **Reboot briefly reverts the app.** `radiantwave-updater.nix` seeds the
|
||||
pointer with tmpfiles type `L`, which re-points `current` at the ISO's baked
|
||||
baseline on every boot. The 2-minute timer restores the live build shortly
|
||||
after, so the window is brief but real.
|
||||
- **A reboot does not lose kiosk data.** `radiantwave-backup.service` rsyncs
|
||||
`~/.local/radiantwave` (minus `audio/`) before every upgrade attempt.
|
||||
- **Don't bump `channel.appVersion` for an app-only deploy.** It only labels
|
||||
the baked ISO baseline. Bump it when rebuilding a dev ISO so it advertises
|
||||
the new fingerprint.
|
||||
- **No local Linux builder on macOS.** `extra-platforms = x86_64-darwin` only,
|
||||
so `nix build .#packages.x86_64-linux.default` and
|
||||
`nixos-rebuild switch --target-host` are not available from a Mac. The
|
||||
`orion-lxc` runner is the only `x86_64-linux` builder.
|
||||
|
||||
### Releasing to production
|
||||
|
||||
1. Merge `dev` -> `main` in `radiantwave`.
|
||||
2. Tag and push: `git tag 1.9 && git push origin 1.9`. The tag push triggers
|
||||
`build.yml`, which publishes to the `radiantwave` Attic cache and
|
||||
`radiantwave/manifest.json` using `ATTIC_TOKEN_PROD`.
|
||||
3. In `KioskConfig`, on `main`: set `radiantwave.url` to
|
||||
`?ref=refs/tags/1.9`, set `channel.appVersion = "1.9"`, and run
|
||||
`nix flake update radiantwave`. Commit both -- the lock and the channel
|
||||
block must agree.
|
||||
4. Its CI fails fast unless the baked baseline exactly matches the published
|
||||
manifest, so this step cannot drift silently.
|
||||
|
||||
---
|
||||
|
||||
## Project Layout
|
||||
@@ -564,34 +707,6 @@ status to decide which page to show.
|
||||
|
||||
---
|
||||
|
||||
## Rebuild Progress
|
||||
|
||||
| Component | Status |
|
||||
| ----------- | -------- |
|
||||
| Entry / Event Loop | Done |
|
||||
| Window + Renderer | Done |
|
||||
| Page System | Done |
|
||||
| PageManager (stack) | Done |
|
||||
| KeybindManager | Done |
|
||||
| Home Page | Done |
|
||||
| Settings Page | Done |
|
||||
| Provisioning FSM | — |
|
||||
| Pages (11 types) | — |
|
||||
| OpenGL Context | — |
|
||||
| Virtual Framebuffer | — |
|
||||
| Shader Manager | — |
|
||||
| Font Manager | — |
|
||||
| Line Patterns | — |
|
||||
| Color Patterns | — |
|
||||
| Mixer | — |
|
||||
| Network / WiFi | — |
|
||||
| Database (SQLite) | — |
|
||||
| HTTP Client | — |
|
||||
| Logging | — |
|
||||
| Config / App State | — |
|
||||
|
||||
---
|
||||
|
||||
## Common Pitfalls
|
||||
|
||||
- Do not commit audio assets (`.wav` files) -- downloaded at runtime.
|
||||
|
||||
Reference in New Issue
Block a user