Skip to content
21 changes: 16 additions & 5 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,10 @@ Canonical files:
- The live R10 witness is a composing box's `check` bed; the candy's own `check:`
steps assert `config.sh` + `run.sh` presence, `config.sh --version` (proving the
`.NET` deps resolved), `skopeo`/`buildah`/`cosign`/`go` versions, the aarch64
qemu interpreter, rootless nested `podman`, the runner running as uid 1000, and
the `newuidmap` capability.
qemu interpreter, rootless nested `podman`, the runner running as uid 1000, the
`newuidmap` capability, one `package:` check per tool in the job tool surface,
and behavioural checks for `hostname` and the UTF-8 locale (a check that passes
either way proves nothing — assert what the change actually alters).
- The merge gate is the **org-wide** `charly/pr-validator` (required check
`validate / validate`, defined in `opencharly/.github`); this repo has **no**
per-repo candy gate. Its only workflow file is
Expand All @@ -48,9 +50,18 @@ Canonical files:
- Edit the `github-runner:` candy entity in `charly.yml`; the `skill:` entity in
the same file is the owning skill's source — a candy change and its skill change
land together.
- The runner version pin is the `RUNNER_VERSION` var; the registration logic is
the token-guarded `post_enable` / `pre_remove` hooks. Keep them token-guarded —
an empty `RUNNER_TOKEN` must stay a clean no-op for token-less beds.
- `RUNNER_VERSION` **seeds** the initial runner download; it does **not** pin the
version that runs. The runner self-updates, and the `state` volume carries that
update across image rebuilds — measured on the live fleet, `bin` symlinks to
`bin.2.337.0` under an image declaring `2.334.0`. Do not describe it as a pin,
and do not add `--disableupdate` without also deciding who owns the version
bumps that then become necessary.
- The registration logic is the token-guarded `post_enable` / `pre_remove` hooks.
Keep them token-guarded — an empty `RUNNER_TOKEN` must stay a clean no-op for
token-less beds.
- The job tool surface is load-bearing and org-wide, because the pool serves
every repo. Add a tool only with a matching `check:` in the `plan:` — a declared
package with no check is a claim, not a proof.
- `podman`/`buildah`/`skopeo`/`crun`/`fuse-overlayfs` come from
`layer-container-nesting`; do not redeclare them here (R3).
- The `skill:` entity is the source for `/charly-distros:github-runner`; never
Expand Down
28 changes: 19 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,21 +6,31 @@ CI jobs rootless inside a disposable box.

## What it provides

Installs the pinned `actions/runner` release (default `2.334.0`) under
`${HOME}/actions-runner` (`config.sh` + `run.sh`, run as uid 1000) plus the CI
toolchain — `jq`/`git`/`go`/`cosign`, `qemu-user-static` for aarch64 binfmt
cross-builds, and the rootless nested container stack (`podman`/`buildah`/`skopeo`
via `container-nesting`). The `.NET` runtime deps (`icu`/`krb5`/`openssl`/
`libunwind`/`lttng-ust`) are declared explicitly because the runner's
`installdependencies.sh` has no Arch branch.
Installs the `actions/runner` release seeded by `RUNNER_VERSION` (default
`2.334.0`) under `${HOME}/actions-runner` (`config.sh` + `run.sh`, run as uid
1000), plus the CI job tool surface the org's own workflows actually call:
`jq`/`git`/`go`/`cosign`, `hostname` (from `inetutils`), `unzip`/`zip`/`7zip`/
`wget`/`rsync`, `tree`, `shellcheck`/`shfmt`/`actionlint`/`golangci-lint`,
`nodejs`/`npm`, `python-pip`/`uv`, `cmake`, `yq`/`ripgrep`/`moreutils`/`bc`/`less`,
and the `lsof`/`strace`/`nc`/`dig` diagnostics — plus `qemu-user-static` for
aarch64 binfmt cross-builds and the rootless nested container stack
(`podman`/`buildah`/`skopeo` via `container-nesting`). The `.NET` runtime deps
(`icu`/`krb5`/`openssl`/`libunwind`/`lttng-ust`) are declared explicitly because
the runner's `installdependencies.sh` has no Arch branch. **Every** package
carries its own `check:` in the candy's `plan:`, so a tool that is declared but
not installed fails the image build rather than a job at 02:00.

`RUNNER_VERSION` **seeds** that install — it is not a pin. The runner
self-updates, and the `state` volume makes that update outlive the image, so
rebuilding does not change the runner version.

| Property | Value |
|---|---|
| Service | `github-runner` (`~/actions-runner/run.sh`, `restart: always`, uid 1000) |
| Requires | `layer-supervisord`, `layer-container-nesting` |
| Volume | `state` at `~/actions-runner` |
| Env | `RUNNER_WORK_DIR=~/actions-runner/_work`, `RUNNER_GROUP=Default` |
| env_accept | `RUNNER_ORG` — the org/user to register with |
| Env | `RUNNER_WORK_DIR=~/actions-runner/_work`, `LANG=C.UTF-8`, `TZ=UTC` |
| env_accept | `RUNNER_ORG` — the org/user to register with; `RUNNER_LABELS` — the labels a job's `runs-on:` selects on (defaults to `opencharly`) |
| secret_accept | `RUNNER_TOKEN` — the registration token (credential-store backed) |

## Registration
Expand Down
Loading
Loading