Repository navigation
CI and Releases
CI is .github/workflows/ci.yml. It runs the same commands as the devenv
scripts, written out directly, because running jobs through devenv shell
was too slow. Keep the two in step by hand.
Nix is installed by .github/actions/setup-nix, which writes substituters to
/etc/nix/nix.conf before the daemon starts. (NIX_CONFIG is ignored for
untrusted clients, and the build silently compiles from source.)
- clippy and rustfmt (rustfmt checked on pull requests only)
- Rust tests for both crates
- flake evaluation
- package builds
- installer ISO: built on every push, then booted under OVMF and SeaBIOS by
tests/iso-boot.py. A boot passes when the installer sends a DNS query forgithub.com. On timeout, the job uploads a screenshot. - the Nextcloud image: weekly and on request only
-
losos-registrarfor the dev machine: a static musl build pushed to GHCR on every push to main and every tag, served by the proxy (below)
Push a v* tag, or draft a release with a new v* tag in the web UI. The
release job:
- builds the installer ISO and the demo QCOW2,
- attaches the ISO and its
.sha256to the GitHub release, - pushes both to GHCR (the QCOW2 is over GitHub's 2 GiB asset limit).
Your release notes are kept. The download section goes between two marker comments, and a re-run replaces only that section.
CI publishes signed Nix store paths as OCI artifacts at
ghcr.io/dasmatus/losos/nix-cache. They are served by a separate deployment
of the LosOS Desktop proxy
with GHCR_REPOSITORY=dasmatus/losos.
Setup:
nix key generate-secret --key-name losos-1- Store the secret key as repository secret
NIX_CACHE_SIGNING_KEY. - Store the public key (
nix key convert-secret-to-public) as repository variableNIX_CACHE_PUBLIC_KEY. - Store the proxy's HTTPS URL as repository variable
LOSOS_PROXY_URL. That is the domain attached to thelosos-cache-proxyVercel project,https://proxy.losos.dasmat.us, and nothing else (the earlier name,losos-proxy.dasmat.us, now 307-redirects there): a hostname that merely resolves to Vercel answersDEPLOYMENT_NOT_FOUND, nix printswarning: '<url>' does not appear to be a binary cachein every job and builds from source, and the run stays green.setup-nixnow checks<url>/nix-cache-infoand annotates the run when that happens. - Make the
losos/nix-cachepackage public, andlosos/images(below) once the first push to main has created it. GitHub creates a package private; the proxy then answers502 token: 403for everything in it. - Keep
losos.cache.substitutersandlosos.cache.trustedPublicKeysinmodules/options.nixat the same URL and key. Their defaults arehttps://proxy.losos.dasmat.usand thelosos-1public key, so a stock appliance and installer medium already pull from the cache;tests/invariants.nixfails if either default is dropped. Rotating the signing key means changing the variable and the default together.
Every job reports what it actually got from the cache. setup-nix puts a
nix shim on PATH that counts nix's own copying path '…' from '<url>'
and building '…' lines per invocation and writes a Nix binary cache
use table to the job's step summary (one row per nix command that copied
or built anything: paths from the LosOS cache, from cache.nixos.org, from
elsewhere, and built on the runner), plus one LosOS cache: … line in the
job log right after the command. A row with the LosOS column at 0 and a
non-zero "built here" means this project's own paths were compiled although
an earlier run should have pushed them; a job that only evaluates adds no
row. The shim changes neither nix's output nor its exit status.
Check <proxy-url>/nix-cache-info and nix copy --from <proxy-url> <store-path> before relying on it. An unreachable cache is not fatal: the
appliance waits 5 s and falls back to cache.nixos.org and building. Never
put the secret key in the flake or on an appliance.
The key ceremony (Master Proxy → Official edges)
runs losos-registrar provision on the operator's own computer, which has
no Nix store, so .#losos-registrar-static is the same crate linked
statically against musl. The registrar-and-ui job builds it and the
publish-tool job pushes it to GHCR as the OCI artifact
ghcr.io/dasmatus/losos/images:<channel>-x86_64, one layer per file:
losos-registrar and SHA256SUMS. That is the shape the proxy's
/updates/<channel>/<arch>/<file> route serves: it picks the layer whose
title is the file name and redirects to GHCR's storage (SHA256SUMS it
serves inline), the same route LosOS Desktop's sysupdate reads. The channel
is main for a push to main, the tag for a release (which also moves
stable), and a cleaned-up branch name for a manual run elsewhere; pull
requests never publish.
curl -fsSLO "https://proxy.losos.dasmat.us/updates/main/x86_64/{losos-registrar,SHA256SUMS}" && sha256sum -c --ignore-missing SHA256SUMS && chmod +x losos-registrarThe job's step summary carries the artifact reference, the URL and the sum.
oras pull ghcr.io/dasmatus/losos/images:main-x86_64 fetches the same files
without the proxy.