feat(infra): add ci-runners.sh wrapper for the runner stack #81

Merged
julien merged 1 commits from feat/infra/ci-runners-sh-wrapper into main 2026-05-10 06:37:08 +02:00
Owner

Summary

Mirrors the convenience-script pattern we adopted for infra/local/dev.sh: typing docker compose -f infra/ci-runners.compose.yml ... for routine ops gets old fast, the pre-pull of the catthehacker job images is documented but easy to forget, and the "rotation of one runner at a time" tip in infra/README.md is a sequence the contributor was supposed to hand-roll every time.

infra/ci-runners.sh exposes the everyday verbs and automates the rolling-restart pattern.

What lands

Command Effect
./ci-runners.sh up Bring the three runner containers up
./ci-runners.sh up --prepull Pre-pull the job images (act-22.04 + :full-22.04) on the host first
./ci-runners.sh down Stop and remove the containers (preserves data/runner-N/.runner credentials)
./ci-runners.sh restart <runner> Restart one runner
./ci-runners.sh rotate Rolling restart of every runner with a 15 s pause between each — keeps at least N-1 runners online through a config refresh
./ci-runners.sh status docker compose ps for the runner services
./ci-runners.sh logs [runner] Follow logs (one runner or all of them)
./ci-runners.sh pull-images Pre-pull / refresh the job images (idempotent)
./ci-runners.sh <other> Pass-through to docker compose -f ci-runners.compose.yml ...

The destructive down -v (wipes data/, forces re-registration with a fresh Gitea token) is intentionally not exposed as a verb — invoke docker compose -f ci-runners.compose.yml down -v directly so the path is explicit at the typing level.

Doc updates (infra/README.md)

  • Inventory table at the top picks up the script.
  • "First-time registration" walkthrough swaps the explicit docker pull / docker compose up steps for ./ci-runners.sh up --prepull.
  • New "Convenience script — ci-runners.sh" subsection with the cheat-sheet table.
  • "Operational tips" rephrased to point at the script's rotate / restart / logs verbs as the canonical commands; the raw-docker-compose form is kept in parentheses as the underlying mechanism.
  • "Adding a fourth runner" tip now reminds to update the RUNNERS=() array at the top of the script.

Trade-off

The 15 s pause in rotate is a conservative approximation — act_runner doesn't expose a Compose healthcheck, so we can't poll for ready. Adjust the constant at the top of the script if reality argues for a different value.

Test plan

  • CI green on this PR.
  • On the runner host: ./infra/ci-runners.sh status shows the three runners running.
  • ./infra/ci-runners.sh logs runner-1 tails runner-1's stdout.
  • ./infra/ci-runners.sh rotate cycles through runner-1 → runner-2 → runner-3 with the 15 s pauses; status between rotations shows N-1 runners online at any moment (with a brief gap for the one currently restarting).
  • ./infra/ci-runners.sh restart runner-99 errors out with the "unknown runner" message.
## Summary Mirrors the convenience-script pattern we adopted for `infra/local/dev.sh`: typing `docker compose -f infra/ci-runners.compose.yml ...` for routine ops gets old fast, the pre-pull of the catthehacker job images is documented but easy to forget, and the "rotation of one runner at a time" tip in `infra/README.md` is a sequence the contributor was supposed to hand-roll every time. `infra/ci-runners.sh` exposes the everyday verbs and automates the rolling-restart pattern. ## What lands | Command | Effect | | --------------------------------------------- | --------------------------------------------------------------------------------- | | `./ci-runners.sh up` | Bring the three runner containers up | | `./ci-runners.sh up --prepull` | Pre-pull the job images (`act-22.04` + `:full-22.04`) on the host first | | `./ci-runners.sh down` | Stop and remove the containers (**preserves** `data/runner-N/.runner` credentials) | | `./ci-runners.sh restart <runner>` | Restart one runner | | `./ci-runners.sh rotate` | Rolling restart of every runner with a 15 s pause between each — keeps at least N-1 runners online through a config refresh | | `./ci-runners.sh status` | `docker compose ps` for the runner services | | `./ci-runners.sh logs [runner]` | Follow logs (one runner or all of them) | | `./ci-runners.sh pull-images` | Pre-pull / refresh the job images (idempotent) | | `./ci-runners.sh <other>` | Pass-through to `docker compose -f ci-runners.compose.yml ...` | The destructive `down -v` (wipes `data/`, forces re-registration with a fresh Gitea token) is intentionally **not** exposed as a verb — invoke `docker compose -f ci-runners.compose.yml down -v` directly so the path is explicit at the typing level. ## Doc updates (`infra/README.md`) - Inventory table at the top picks up the script. - "First-time registration" walkthrough swaps the explicit `docker pull` / `docker compose up` steps for `./ci-runners.sh up --prepull`. - New "Convenience script — `ci-runners.sh`" subsection with the cheat-sheet table. - "Operational tips" rephrased to point at the script's `rotate` / `restart` / `logs` verbs as the canonical commands; the raw-docker-compose form is kept in parentheses as the underlying mechanism. - "Adding a fourth runner" tip now reminds to update the `RUNNERS=()` array at the top of the script. ## Trade-off The 15 s pause in `rotate` is a conservative approximation — `act_runner` doesn't expose a Compose healthcheck, so we can't poll for ready. Adjust the constant at the top of the script if reality argues for a different value. ## Test plan - [ ] CI green on this PR. - [ ] On the runner host: `./infra/ci-runners.sh status` shows the three runners running. - [ ] `./infra/ci-runners.sh logs runner-1` tails runner-1's stdout. - [ ] `./infra/ci-runners.sh rotate` cycles through runner-1 → runner-2 → runner-3 with the 15 s pauses; `status` between rotations shows N-1 runners online at any moment (with a brief gap for the one currently restarting). - [ ] `./infra/ci-runners.sh restart runner-99` errors out with the "unknown runner" message.
julien added 1 commit 2026-05-10 06:35:30 +02:00
feat(infra): add ci-runners.sh wrapper for the runner stack
CI / commits (pull_request) Successful in 1m36s
CI / scan (pull_request) Successful in 1m38s
CI / check (pull_request) Successful in 1m43s
CI / a11y (pull_request) Successful in 1m36s
CI / perf (pull_request) Successful in 3m18s
308f505f38
Mirrors the convenience-script pattern we adopted for
infra/local/dev.sh: typing
`docker compose -f infra/ci-runners.compose.yml ...` for routine
ops (status, restart, log tail) gets old fast, the pre-pull of
the catthehacker job images is documented but easy to forget,
and the "rotation of one runner at a time" tip in
infra/README.md is a sequence the contributor was supposed to
hand-roll every time.

`infra/ci-runners.sh` exposes:

  ./ci-runners.sh up                  # bring up runner-1..3
  ./ci-runners.sh up --prepull        # pre-pull job images first
  ./ci-runners.sh down                # stop + remove (preserves
                                       data/runner-N/.runner creds)
  ./ci-runners.sh restart <runner>    # restart one runner
  ./ci-runners.sh rotate              # rolling restart with a 15 s
                                       pause between each — keeps
                                       at least N-1 runners online
                                       through a config refresh
  ./ci-runners.sh status              # docker compose ps
  ./ci-runners.sh logs [runner]       # follow logs
  ./ci-runners.sh pull-images         # idempotent image refresh

Anything else is passed through to
`docker compose -f ci-runners.compose.yml ...`. The destructive
`down -v` (wipes data/, forces re-registration with a fresh
Gitea token) is intentionally NOT exposed as a verb — invoke
docker compose directly so the path is explicit at the typing
level.

`infra/README.md` updated:

- Inventory table at the top picks up the script.
- "First-time registration" walkthrough swaps the explicit
  docker pull / docker compose up steps for `./ci-runners.sh
  up --prepull`.
- New "Convenience script — ci-runners.sh" subsection with the
  cheat-sheet table.
- "Operational tips" rephrased to point at the script's `rotate`
  / `restart` / `logs` verbs as the canonical commands; the
  raw-docker-compose form is kept in parentheses as the
  underlying mechanism.
- "Adding a fourth runner" tip now reminds to update the
  RUNNERS=() array at the top of the script.

The 15 s pause in `rotate` is a conservative approximation —
act_runner doesn't expose a Compose healthcheck, so we can't
poll for ready. Adjust the constant if reality argues for a
different value.

Smoke-tested help + arg-validation paths on the host.
julien merged commit 2d676cc279 into main 2026-05-10 06:37:08 +02:00
julien deleted branch feat/infra/ci-runners-sh-wrapper 2026-05-10 06:37:09 +02:00
Sign in to join this conversation.
No Reviewers
No Label
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: julien/apf_portal#81