fix: ci check installs shellcheck where the image lacks it; default runner labels gain ubuntu-latest-full (#144)
This commit is contained in:
parent
9cb81c9f6b
commit
ba3097491a
4 changed files with 80 additions and 7 deletions
10
.github/workflows/ci.yml
vendored
10
.github/workflows/ci.yml
vendored
|
|
@ -15,6 +15,16 @@ jobs:
|
|||
# a skip (a guard that can quietly stop guarding is the failure
|
||||
# shape these checks exist to refuse).
|
||||
fetch-depth: 0
|
||||
- name: install shellcheck where the image lacks it
|
||||
# GitHub's ubuntu-latest preinstalls shellcheck; the slim act image
|
||||
# rig's Forgejo runners map `ubuntu-latest` to does not (#144), and
|
||||
# the full image (54.5 GB on disk) is not a price every ci-box can
|
||||
# pay. The `command -v` short-circuit means GitHub pays nothing; on
|
||||
# the act image the job runs as uid 0 and sudo is a no-op — it is
|
||||
# load-bearing only on GitHub, where the job runs as `runner` with
|
||||
# passwordless sudo. Both forges get jammy's 0.8.0, the same version
|
||||
# the full image ships, so no lint result differs between them.
|
||||
run: command -v shellcheck >/dev/null || { sudo apt-get update && sudo apt-get install -y shellcheck; }
|
||||
- name: shellcheck
|
||||
# -x follows the `source=SCRIPTDIR/...` directives into commands/lib/.
|
||||
# globstar so a script in a new subdirectory is linted without anyone
|
||||
|
|
|
|||
8
changelog.d/144.md
Normal file
8
changelog.d/144.md
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
### Added
|
||||
|
||||
- `ubuntu-latest-full` runner label — opt-in GitHub-parity image, pulls nothing until a job matches it (#144)
|
||||
|
||||
### Fixed
|
||||
|
||||
- CI's `check` job installs shellcheck where the runner image lacks it — rig's own CI passes on rig-installed Forgejo runners (#144)
|
||||
- `forgejo-runner install` warns on a plain converge when a runner was registered with a retired default label set (#144)
|
||||
|
|
@ -27,11 +27,22 @@ die() { printf 'rig-forgejo-runner: ERROR: %s\n' "$1" >&2; exit "${2:-1}"; }
|
|||
# editing to migrate; catthehacker's image is the act/Forgejo ecosystem's
|
||||
# stand-in for GitHub's runner image. `docker` is the lean second option.
|
||||
#
|
||||
# `ubuntu-latest` maps to the SLIM act image, not the full one — measured
|
||||
# 2026-08-01 (ghcr manifests, amd64): act-22.04 is 0.55 GB on the wire and
|
||||
# ~2 GB on disk; full-22.04 is 18.67 GB on the wire and 54.52 GB on disk,
|
||||
# which does not fit a box-class ci-box at all. The slim image carries no
|
||||
# copy of shellcheck (streamed every layer: zero entries), so a workflow must
|
||||
# assume GitHub's tool surface — it installs what it uses, as rig's own
|
||||
# ci.yml does for shellcheck (#144). `ubuntu-latest-full` is the opt-in
|
||||
# parity label: inert until a job matches it, so it costs nothing to boxes
|
||||
# that never ask, and an operator who needs GitHub's full tool surface
|
||||
# writes `runs-on: ubuntu-latest-full` and pays the 54.5 GB deliberately.
|
||||
#
|
||||
# Both are `docker://` — jobs run in CONTAINERS on the box's own dockerd, not
|
||||
# on the box itself. No docker-in-docker: the guide this came from stacks a
|
||||
# privileged dind sidecar with a plaintext tcp://…:2375 daemon to isolate jobs
|
||||
# from a shared CI server, and inside a box that boundary is already paid for.
|
||||
DEFAULT_LABELS='ubuntu-latest:docker://ghcr.io/catthehacker/ubuntu:act-22.04,docker:docker://node:22-bookworm'
|
||||
DEFAULT_LABELS='ubuntu-latest:docker://ghcr.io/catthehacker/ubuntu:act-22.04,ubuntu-latest-full:docker://ghcr.io/catthehacker/ubuntu:full-22.04,docker:docker://node:22-bookworm'
|
||||
|
||||
# fetch_and_verify_sha256 <asset-url> <file> <sumfile> <label>
|
||||
#
|
||||
|
|
@ -93,7 +104,8 @@ usage: rig forgejo-runner install --instance <url> [options]
|
|||
time). Pin it for a deterministic, auditable install.
|
||||
--name <name> runner name (default: this host's hostname)
|
||||
--labels <csv> runner labels; replaces the default. The default maps
|
||||
ubuntu-latest and docker onto container images, so a
|
||||
ubuntu-latest (slim), ubuntu-latest-full (GitHub
|
||||
parity, opt-in) and docker onto container images, so a
|
||||
workflow written for GitHub runs unchanged.
|
||||
--user <name> unprivileged service user (default: the tenant user
|
||||
`ci` when it exists, else forgejo-runner; created if
|
||||
|
|
@ -410,12 +422,25 @@ if [ -e "$RUNNER_DIR/.runner" ]; then
|
|||
# Registration was skipped, so the labels on the instance are the ones it was
|
||||
# registered with — NOT whatever this invocation was passed. Say so when the
|
||||
# operator explicitly asked for different ones, rather than letting the
|
||||
# request evaporate. Only when EXPLICIT: comparing the default against a
|
||||
# runner registered with custom labels would warn on every plain converge.
|
||||
if [ "$LABELS_EXPLICIT" -eq 1 ] && [ -r "$RUNNER_DIR/.rig-labels" ]; then
|
||||
# request evaporate. When nothing was asked for, warn only when the recorded
|
||||
# labels are a KNOWN retired rig default — comparing a plain converge against
|
||||
# the current default would warn on every run for runners registered with
|
||||
# custom --labels, which is noise (the LABELS_EXPLICIT comment below).
|
||||
if [ -r "$RUNNER_DIR/.rig-labels" ]; then
|
||||
RECORDED="$(cat "$RUNNER_DIR/.rig-labels")"
|
||||
if [ "$RECORDED" != "$LABELS" ]; then
|
||||
warn "--labels was not applied: this runner is already registered, and Forgejo owns its labels from registration time. It still has: ${RECORDED}. Labels are what 'runs-on' matches, so changing them means re-registering: 'rig forgejo-runner remove' then install again with the labels you want."
|
||||
if [ "$LABELS_EXPLICIT" -eq 1 ]; then
|
||||
if [ "$RECORDED" != "$LABELS" ]; then
|
||||
warn "--labels was not applied: this runner is already registered, and Forgejo owns its labels from registration time. It still has: ${RECORDED}. Labels are what 'runs-on' matches, so changing them means re-registering: 'rig forgejo-runner remove' then install again with the labels you want."
|
||||
fi
|
||||
else
|
||||
# Retired defaults, one pattern per past DEFAULT_LABELS value. The
|
||||
# message must not imply anything is broken: a retired default still
|
||||
# runs everything it ran before (#144's fix lands in ci.yml, not here);
|
||||
# re-registering only picks up labels the old set never had.
|
||||
case "$RECORDED" in
|
||||
'ubuntu-latest:docker://ghcr.io/catthehacker/ubuntu:act-22.04,docker:docker://node:22-bookworm')
|
||||
warn "this runner was registered with an older rig default label set. The current default adds ubuntu-latest-full (the GitHub-parity image). Labels are fixed at registration, so picking it up means re-registering: 'rig forgejo-runner remove' then install again. Nothing you run today is affected — re-register only if you want the new label." ;;
|
||||
esac
|
||||
fi
|
||||
fi
|
||||
else
|
||||
|
|
|
|||
30
test/cli.sh
30
test/cli.sh
|
|
@ -3413,6 +3413,36 @@ check "forgejo-runner: …and the install creates it, owned by the runner user"
|
|||
check "forgejo-runner: ProtectHome stays read-only (the cache is not an excuse to widen it)" 0 "" \
|
||||
grep -qF 'ProtectHome=read-only' "$FRI"
|
||||
|
||||
# #144: the default label map, pinned WITH its reason. ubuntu-latest maps to
|
||||
# the SLIM act image — the full one is 18.67 GB on the wire / 54.52 GB on
|
||||
# disk and does not fit a box-class ci-box, so workflows install the tools
|
||||
# they use (ci.yml's shellcheck step, pinned below) and the parity image is
|
||||
# an opt-in label that pulls nothing until a job matches it.
|
||||
check "forgejo-runner: the default map keeps ubuntu-latest on the slim act image" 0 "" \
|
||||
grep -qF "DEFAULT_LABELS='ubuntu-latest:docker://ghcr.io/catthehacker/ubuntu:act-22.04," "$FRI"
|
||||
check "forgejo-runner: …and adds ubuntu-latest-full as the opt-in parity label" 0 "" \
|
||||
grep -qF 'ubuntu-latest-full:docker://ghcr.io/catthehacker/ubuntu:full-22.04' "$FRI"
|
||||
check "forgejo-runner: the default map still carries the lean docker label" 0 "" \
|
||||
grep -qF "docker:docker://node:22-bookworm'" "$FRI"
|
||||
# The retired-default warn: fires on a plain converge ONLY for a recorded
|
||||
# label set that matches a known retired default — never for custom --labels,
|
||||
# and never claiming anything is broken (the fix lives in ci.yml, so the old
|
||||
# set still runs everything it ran before).
|
||||
check "forgejo-runner: a plain converge names the retired default label set" 0 "" \
|
||||
grep -qF "registered with an older rig default label set" "$FRI"
|
||||
check "forgejo-runner: …matching the exact retired default, not any differing labels" 0 "" \
|
||||
grep -qF "'ubuntu-latest:docker://ghcr.io/catthehacker/ubuntu:act-22.04,docker:docker://node:22-bookworm')" "$FRI"
|
||||
check "forgejo-runner: …and says re-registering is only for the new label" 0 "" \
|
||||
grep -qF "re-register only if you want the new label" "$FRI"
|
||||
# The other half of #144: ci.yml's check job installs shellcheck only when
|
||||
# the image lacks it — the conditional is the pin, so a rewrite that makes
|
||||
# GitHub pay for apt on every run fails here.
|
||||
check "ci.yml: check installs shellcheck only where the image lacks it" 0 "" \
|
||||
grep -qF 'command -v shellcheck >/dev/null ||' "$ROOT/.github/workflows/ci.yml"
|
||||
# shellcheck disable=SC2016 # $1 is the bash -c positional, intentionally single-quoted
|
||||
check "ci.yml: …and the install step runs before the shellcheck step" 0 "" \
|
||||
bash -c 'grep -n "name: install shellcheck\|name: shellcheck$" "$1" | head -2 | tail -1 | grep -q "name: shellcheck"' _ "$ROOT/.github/workflows/ci.yml"
|
||||
|
||||
check "forgejo-runner: status --help exits 0" 0 "usage:" "$ROOT/commands/forgejo-runner-status.sh" --help
|
||||
check "forgejo-runner: remove --help exits 0" 0 "usage:" "$ROOT/commands/forgejo-runner-remove.sh" --help
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue