Update build procedures and documentation

This commit is contained in:
NeilClack
2026-08-13 18:57:11 -05:00
parent c53abede6a
commit 7c74198d4f
5 changed files with 93 additions and 17 deletions
+34 -5
View File
@@ -1,9 +1,11 @@
name: build
on:
push:
branches: [dev, main]
pull_request:
# Manual only for now. Select the branch to build when dispatching:
# main -> APP_VERSION is the current git tag
# dev -> APP_VERSION is the current commit hash
# Both branches bake the portal API key from secrets.
workflow_dispatch:
jobs:
nix-build:
@@ -11,11 +13,13 @@ jobs:
steps:
# actions/checkout@v4 is unreliable on host-mode runners (its files are
# copied into the workspace instead of the repo), so clone explicitly.
# A full clone (no --depth) is required so `git describe --tags` on main
# resolves the real nearest tag instead of falling back to a hash.
- name: Checkout
run: |
rm -rf ./* ./.[!.]* 2>/dev/null || true
git config --global http.extraheader "Authorization: token ${{ github.token }}"
git clone --depth 1 --branch "${{ gitea.ref_name }}" \
git clone --branch "${{ gitea.ref_name }}" \
"${{ gitea.server_url }}/${{ gitea.repository }}.git" .
test -f flake.nix
git log --oneline -1
@@ -26,12 +30,37 @@ jobs:
ls -la
git rev-parse --show-toplevel 2>&1 || true
git remote -v 2>&1 || true
git describe --tags --always 2>&1 || true
test -f flake.nix && echo "flake.nix present" || echo "NO flake.nix"
# Compute the version string baked into the binary's Home footer:
# main reports the git tag, dev reports the commit hash fingerprint.
# The key stays in the build step's environment (never echoed).
- name: Compute version
id: version
run: |
if [ "${{ gitea.ref_name }}" = "main" ]; then
APP_VERSION="$(git describe --tags --always)"
else
APP_VERSION="$(git rev-parse --short HEAD)"
fi
echo "APP_VERSION=$APP_VERSION" >> "$GITHUB_ENV"
echo "Branch: ${{ gitea.ref_name }} -> APP_VERSION=$APP_VERSION"
if [ -n "${{ secrets.RWT_API_KEY }}" ]; then
echo "API key: provided via secret RWT_API_KEY"
else
echo "API key: NOT set (build proceeds without an Authorization header)"
fi
# checks is keyed per-system (checks.<system>.default); nix build's
# #attr shorthand can't resolve it, so resolve the current system inline.
# --impure lets the flake read APP_VERSION/API_KEY via builtins.getEnv
# (pure evals always get the package defaults). The offline test suite
# runs in the package's checkPhase.
- name: Build + offline test suite
run: nix build -L ".#checks.$(nix eval --impure --raw --expr 'builtins.currentSystem').default"
env:
API_KEY: ${{ secrets.RWT_API_KEY }}
run: nix build -L ".#checks.$(nix eval --impure --raw --expr 'builtins.currentSystem').default" --impure
- name: Live portal tests
if: ${{ secrets.RWT_LIVE_API_KEY != '' }}
+13 -7
View File
@@ -30,8 +30,9 @@ the project version, or pass your own at configure time:
cmake -S . -B build -G Ninja -DCMAKE_BUILD_TYPE=Debug -DAPP_VERSION="1.2.3"
```
The Nix package bakes `-DAPP_VERSION=<pkg version>` via `cmakeFlags` (version is
hardcoded `0.1.0` in `nix/package.nix`, not read from the flake). `nix develop`
The Nix package bakes `-DAPP_VERSION=<pkg version>` via `cmakeFlags` (`version`
defaults to `0.1.0` in `nix/package.nix`; the flake overrides it from the
`APP_VERSION` env var on impure evals). `nix develop`
sets `APP_VERSION=dev` and exports `API_KEY` from the ambient environment
(falling back to `RWT_LIVE_API_KEY`). CMake seeds a *fresh* configure from the
`APP_VERSION` / `API_KEY` env vars; `-D` wins on reconfigure.
@@ -230,11 +231,16 @@ cached.
- Do not modify files in `archive/` — reference only.
- Build needs SDL3 + SDL3_ttf/image/mixer/net + GTest installed; CI uses
Gitea Actions on a self-hosted host runner (`build-server`, no docker).
The workflow lives in `.gitea/workflows/build.yml` and runs on both `dev`
and `main`. It runs `nix build -L .#checks.<system>.default` (build + the
offline test suite; `checks` is keyed per-system, so the workflow resolves
the current system via `nix eval --impure --expr 'builtins.currentSystem'`);
when the `RWT_LIVE_API_KEY` secret is set it also runs
The workflow lives in `.gitea/workflows/build.yml` and is **manual-only**
(`workflow_dispatch`); pick the branch when dispatching. It runs
`nix build -L .#checks.<system>.default` (build + the offline test suite;
`checks` is keyed per-system, so the workflow resolves the current system
via `nix eval --impure --expr 'builtins.currentSystem'`). The build bakes
in a per-branch `APP_VERSION` — the current git tag on `main`, the current
commit hash on `dev` — plus the portal API key from the `RWT_API_KEY`
secret. The flake reads `APP_VERSION`/`API_KEY` from the environment via
`builtins.getEnv`, so the build must pass `--impure` (pure evals get the
package defaults). When the `RWT_LIVE_API_KEY` secret is set it also runs
`test_api_client` / `test_license_service` against the portal via
`nix develop` (outside the sandbox, like a dev machine). Those live tests
also need `RWT_LIVE_ACCOUNT_EMAIL`, `RWT_LIVE_LICENSE_EMAIL`, and
+26 -3
View File
@@ -133,7 +133,12 @@ cmake --build build
If `APP_VERSION` is left unset the footer falls back to the project version
from `CMakeLists.txt` (`project(... VERSION ...)`); a build that defines no
version at all shows `unknown`. The Nix build sets `APP_VERSION` automatically
to the flake package version, so `nix build` needs no extra flags.
to the flake package version, so a plain `nix build` needs no extra flags.
With `--impure` the flake instead reads the `APP_VERSION` / `API_KEY`
environment variables — this is how CI injects the version and portal key
(see the CI note under *Common Pitfalls*). Pure evals always get the package
defaults, because `builtins.getEnv` cannot see the environment in pure
evaluation mode.
#### Portal API key
@@ -151,7 +156,8 @@ cmake --build build
Rotate the key by building with a new value and shipping the new binary. The
Nix package accepts the same value via `callPackage ./nix/package.nix {
apiKey = "…"; }`; the flake itself never embeds one.
apiKey = "…"; }`, or via the `API_KEY` environment variable with
`nix build --impure`; the flake itself never embeds one.
#### Version + API key in one configure
@@ -179,6 +185,17 @@ nix build .#packages.x86_64-linux.default # needs a Linux machine/builders
nix build .#packages.aarch64-linux.default
```
To bake in a custom version and/or portal key, build impurely — the flake
reads `APP_VERSION` and `API_KEY` from the environment on impure evals:
```sh
APP_VERSION="1.2.3" API_KEY="$PORTAL_API_KEY" nix build --impure .#default
```
A pure `nix build` always uses the package defaults (`0.1.0`, no auth header)
even if those variables are set in your shell, because pure evaluation cannot
see the environment. CI uses `--impure` to inject them.
`nix build` runs the full offline test suite in its `checkPhase`; the
live-portal test binaries (`test_api_client`, `test_license_service`) are
excluded. `nix flake check` builds the package and therefore also runs the
@@ -610,6 +627,12 @@ status to decide which page to show.
- `build/` is gitignored. Do not commit build artifacts.
- Use the Nix dev shell or ensure SDL3 is installed for building.
- CI uses Gitea Actions on a self-hosted host runner (`build-server`); the
workflow is `.gitea/workflows/build.yml`.
workflow is `.gitea/workflows/build.yml`. It is **manual-only**
(`workflow_dispatch`) — pick the branch when dispatching. `main` builds bake
the current git tag as `APP_VERSION`; `dev` builds bake the current commit
hash. Both pass the portal key from the `RWT_API_KEY` secret and build with
`nix build --impure` (which lets the flake's env injection work). The
offline test suite runs in the package's `checkPhase`; the live portal tests
run from `nix develop` when the `RWT_LIVE_*` secrets are set.
- Asset tests (`test_assets`) must pass before committing -- they catch missing
fonts and images that would break the app at runtime.
+15 -1
View File
@@ -34,7 +34,20 @@
};
in
{
packages.default = pkgs.callPackage ./nix/package.nix { };
# Version and API key are injected from the ambient environment on
# impure evals (CI sets APP_VERSION/API_KEY from the git ref and a
# secret). Pure evals (`nix flake check`, local `nix build`) can't
# see the environment, so builtins.getEnv returns "" and the
# package falls back to its 0.1.0 default / no auth header.
packages.default =
let
envVersion = builtins.getEnv "APP_VERSION";
envApiKey = builtins.getEnv "API_KEY";
packageArgs =
{ apiKey = envApiKey; }
// (nixpkgs.lib.optionalAttrs (envVersion != "") { version = envVersion; });
in
pkgs.callPackage ./nix/package.nix packageArgs;
devShells.default = pkgs.mkShell {
inputsFrom = [ self.packages.${system}.default ];
@@ -55,6 +68,7 @@
echo "RadiantWave dev shell (APP_VERSION=dev, API_KEY=$([[ -n "$API_KEY" ]] && echo set || echo unset))"
echo " Configure: cmake -S . -B build -G Ninja -DCMAKE_BUILD_TYPE=Debug"
echo " Bake version+key: cmake -S . -B build -G Ninja -DCMAKE_BUILD_TYPE=Debug -DAPP_VERSION=\"1.2.3\" -DAPI_KEY=\"<key>\""
echo " Nix build (env version+key, impure): APP_VERSION=... API_KEY=... nix build --impure .#default"
echo " Build: cmake --build build"
echo " Run: ./build/radiantwave"
echo " Tests: ./build/test_assets && ./build/test_<name>"
+5 -1
View File
@@ -18,11 +18,15 @@
# Portal API key baked into the binary. Keep it out of the flake; pass it
# when calling callPackage from CI/your own config (see README "App version").
apiKey ? "",
# App version baked into the Home footer's Version row. CI overrides this
# per branch (git tag on main, commit hash on dev); local/pure builds keep
# the 0.1.0 default.
version ? "0.1.0",
}:
stdenv.mkDerivation (finalAttrs: {
pname = "radiantwave";
version = "0.1.0";
inherit version;
src = lib.cleanSourceWith {
filter =