commit 1ae5c82e191ecee7a1d8369cc87d2e9aee0e1304
parent 759dcec18659d9309519e13437e31ebb9aa98c7d
Author: Robin Bron <robin.bron@yourhosting.nl>
Date: Wed, 30 Sep 2026 02:03:05 +0200
Correct docs that predate the channel layout and the linkd rename
Diffstat:
3 files changed, 40 insertions(+), 30 deletions(-)
diff --git a/README.md b/README.md
@@ -6,27 +6,34 @@ that builds and signs them, and the CI pipeline that publishes them.
This repo produces a signed apk repository. It does not assemble a rootfs, an
image or an installer -- that is the `unos` repo, which consumes what is
-published here over HTTP. The `unosd` daemon's source lives in its own repo and
+published here over HTTP. The `linkd` daemon's source lives in its own repo and
arrives here as a tag-pinned tarball like any other dependency.
-Published to `https://repo.unos.finwo.net/<arch>`.
+Published to `https://repo.unos.finwo.net/apk/<channel>/<arch>`.
Layout
------
- packages/<name>/template build recipe (sourced by mk/build.sh)
- packages/<name>/files/ static files installed by the template
- packages/<name>/patches/ *.patch, applied in order to WRKSRC
+ channels/<layer>/channel.conf upstream= and publish=
+ channels/<layer>/packages/<name>/template build recipe (mk/build.sh)
+ channels/<layer>/packages/<name>/files/ static files
+ channels/<layer>/packages/<name>/patches/ *.patch, applied to WRKSRC
+ builder/ the CI image: Dockerfile + VERSION
mk/ the build driver and its tooling
.conductor.yml CI pipeline, GENERATED from the dep graph
+ crossed with the channel list
+
+Channels chain `base` -> `lts` -> `stable` -> `edge`, each layer replacing
+whole package directories from the one above. `base` holds every package and
+is never published; `lts` is empty, so it is base.
Building
--------
./mk/bootstrap-host.sh build pinned muon + apk into build/host/bin
- ./mk/build.sh <pkg> build one package
+ ./mk/build.sh <pkg> build one package (--channel, default lts)
./mk/build-all.sh build everything in dependency order
./mk/repo-index.sh (re)generate and sign APKINDEX.tar.gz
@@ -35,8 +42,8 @@ hostmakedepends, and it is built here rather than installed from a
distribution, so `mk/deps.sh check` reports it missing until bootstrap has
produced it.
-See `mk/README.md` for the full tooling reference and `packages/README.md` for
-the template format.
+See `mk/README.md` for the full tooling reference and
+`channels/base/packages/README.md` for the template format.
Where source comes from
@@ -51,7 +58,7 @@ a server nobody here controls, so the tarball is pinned by content.
`srcfiles=` is our own source, fetched by tag from `git.finwo.net`. It carries
no checksum: the tag is the pin and TLS is the transport, and a forge
regenerates tag archives, so they are not byte-stable and a sha256 would fail
-for reasons indistinguishable from tampering. Only `unosd` uses this today.
+for reasons indistinguishable from tampering. Only `linkd` uses this today.
Keeping them separate means "no checksum" can never silently apply to an
upstream tarball.
@@ -61,13 +68,6 @@ Cached source lives in `build/work/sources/`, and is only fetched when absent.
in the tag, so the bare basename is often just `v0.1.0.tar.gz` and two
first-party packages at the same version would otherwise share one entry.
-**While git.finwo.net does not yet serve tag archives**, seed the cache by
-hand and the fetch is skipped:
-
- git -C ../unosd archive --format=tar --prefix=unosd/ HEAD \
- | gzip -n > build/work/sources/unosd-v0.1.0.tar.gz
-
-
Signing
-------
@@ -81,10 +81,10 @@ resolved by `mk/sign-key.inc`, in order:
`mk/build.sh` names the signature record after the key that signed it
(`.SIGN.RSA.<keyname>.rsa.pub`), and the apk client verifies it against
-`/etc/apk/keys/<keyname>.rsa.pub`, shipped by `packages/unos-keys`.
+`/etc/apk/keys/<keyname>.rsa.pub`, shipped by the `unos-keys` package.
**Every CI worker has a distinct keypair**, so the signer is whichever worker
-the conductor scheduled the build on. `packages/unos-keys` therefore trusts all
+the conductor scheduled the build on. `unos-keys` therefore trusts all
four. Ship fewer and verification fails for an arbitrary subset of packages
that changes run to run -- a failure that looks like corruption rather than a
missing key. Adding a worker means publishing `unos-keys` *before* that worker
@@ -113,15 +113,26 @@ Tasks run in ephemeral containers with no mounts and no artifact sharing, so
each package seeds its sysroot from the published repo (`mk/sysroot.sh`) and
publishes its own result (`mk/publish.sh`). `needs` provides ordering only.
-The pipeline requires a worker advertising the **`unos-sign-key`** feature,
-which mounts the signing key and exports `UNOS_KEY_APK_RSA_PRI`,
-`UNOS_KEY_APK_RSA_PUB`, `UNOS_KEY_SUPERCOP_PRI` and `UNOS_KEY_SUPERCOP_PUB`.
-Feature names are global to the conductor, which hosts more than UNOS, hence
-the project prefix. A task requiring a feature no worker advertises is never
-scheduled -- it does not fail, it silently never runs.
+Every package task builds on the prebuilt `finwo/unos-builder` image, and the
+`builder` task rebuilds and pushes it when `builder/VERSION` moves. Each
+package task probes `mk/check-revision.sh` first and skips when that exact
+`pkgver-r` is already published, so a rerun rebuilds only what changed.
+
+Two worker features are required. **`unos-sign-key`** mounts the signing key
+and exports `UNOS_KEY_APK_RSA_PRI`, `UNOS_KEY_APK_RSA_PUB`,
+`UNOS_KEY_SUPERCOP_PRI` and `UNOS_KEY_SUPERCOP_PUB`. **`docker`** is needed by
+the `builder` task alone, which runs a docker-in-docker image rather than the
+builder it is producing. Feature names are global to the conductor, which
+hosts more than UNOS, hence the project prefix. A task requiring a feature no
+worker advertises is never scheduled -- it does not fail, it silently never
+runs.
S3 credentials arrive as `BUCKET_ACCESS_KEY`, `BUCKET_SECRET_KEY`,
-`BUCKET_NAME`, `BUCKET_ENDPOINT` (a URL) and `BUCKET_REGION` (a region name).
+`BUCKET_NAME`, `BUCKET_ENDPOINT` (a URL), `BUCKET_REGION` (a region name) and
+`BUCKET_PUBLIC_URL` (the bare public base, with no `apk/` segment -- the
+publish and sysroot steps append it). Pushing the builder image additionally
+needs `REGISTRY_USERNAME` and `REGISTRY_TOKEN`, plus `REGISTRY_HOST` for a
+registry other than Docker Hub.
Testing
diff --git a/channels/base/packages/linkd/template b/channels/base/packages/linkd/template
@@ -9,9 +9,7 @@ homepage="https://git.finwo.net/app/linkd"
depends="busybox iproute2"
hostmakedepends="dep"
# First-party source, pinned by tag rather than sha256: see srcfiles in
-# mk/build.sh. Until git.finwo.net serves tag archives, seed the cache by
-# dropping the tarball at build/work/sources/linkd-v0.1.0.tar.gz -- the fetch
-# is skipped whenever that file already exists.
+# mk/build.sh.
srcfiles="https://git.finwo.net/app/linkd/archives/tags/v${version}.tar.gz"
do_build() {
diff --git a/mk/build.sh b/mk/build.sh
@@ -1,10 +1,11 @@
#!/bin/sh
# mk/build.sh - UNOS package driver: template -> signed .apk (v2)
#
-# Usage: ./mk/build.sh <pkgname>
+# Usage: ./mk/build.sh [--channel <name>] <pkgname>
#
# Pipeline: source template -> fetch+verify -> extract -> patches ->
-# do_build/do_install into DESTDIR -> emit signed .apk into build/repo/
+# do_build/do_install into DESTDIR -> emit signed .apk into
+# build/repo/<channel>/<arch>/
#
# The whole of build/ is generated output (gitignored). Only mk/ is source.
set -eu