From 0c4142b2f4368832e7d5e5065c5c0e7cd5d0e64f Mon Sep 17 00:00:00 2001 From: "claude[bot]" <41898282+claude[bot]@users.noreply.github.com> Date: Mon, 13 Jul 2026 19:22:00 +0000 Subject: [PATCH] runners/arc: bake CI-capability into register-repo.sh provisioning MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Make every scale set registered via register-repo.sh come up CI-capable from one provisioning change (issue #251): - Default RUNNER_IMAGE to the FuzeInfra CI-capable image (ghcr.io/izzywdev/fuzeinfra-arc-runner) which ships docker compose-v2 + buildx plugins, jq/curl, warm Python/Node toolcache, and now Playwright browser OS deps — instead of the stock actions-runner image that lacks compose (the "unknown shorthand flag: 'f'" failure). - Add --runner-image and --container-mode flags so onboarding stays a single invocation while remaining overridable (dind stays the default). - Dockerfile: bake Playwright browser system deps via `playwright install-deps` so e2e/visual jobs only run `npx playwright install ` (no apt/root at job time). - ONBOARD-REPO.md: docker compose now works by default; document the publish-PUBLIC prerequisite for the runner image. Prerequisite (human/PAT — Claude App cannot touch .github/workflows): publish the image PUBLIC via build-runner-image.yml before onboarding. Co-authored-by: Israel Weinberg <99821070+izzywdev@users.noreply.github.com> --- runners/arc/Dockerfile | 18 ++++++++++++++++++ runners/arc/ONBOARD-REPO.md | 21 ++++++++++++++------ runners/arc/register-repo.sh | 37 +++++++++++++++++++++++++++++++----- 3 files changed, 65 insertions(+), 11 deletions(-) diff --git a/runners/arc/Dockerfile b/runners/arc/Dockerfile index 514404e4..6b865c60 100644 --- a/runners/arc/Dockerfile +++ b/runners/arc/Dockerfile @@ -17,6 +17,10 @@ # local cache instead of hitting api.github.com / objects.githubusercontent.com # from a cold pod (setup-python was timing out fetching the version manifest). # +# It further bakes in `jq`/`curl` and Playwright's browser OS dependencies so +# e2e/visual jobs only run `npx playwright install ` (no apt/root at +# job time). This is the CI-capable runner image register-repo.sh defaults to. +# # Build + push: runners/arc/build-and-push-runner-image.sh # Consumed by: runners/arc/runner-scale-set-values.yaml (template.spec image) # runners/arc/register-repo.sh (--runner-image / RUNNER_IMAGE) @@ -70,4 +74,18 @@ COPY warm-python-toolcache.sh /usr/local/bin/warm-python-toolcache.sh RUN chmod +x /usr/local/bin/warm-python-toolcache.sh; \ /usr/local/bin/warm-python-toolcache.sh 3.10 3.11 +# --- Playwright browser system dependencies ---------------------------------- +# e2e / visual-regression jobs run Playwright. The heavy, root-requiring part is +# the OS-level libraries the browsers need (libnss3, libatk, fonts, …); baking +# those in via Playwright's own `install-deps` resolver means consumer jobs only +# need `npx playwright install ` — which downloads the browser binary +# into the (unprivileged) runner cache and needs neither apt nor root at job +# time. Uses the warmed Node from the toolcache. Pin PLAYWRIGHT_VERSION to the +# consumers' Playwright major so the dep list matches. +ARG PLAYWRIGHT_VERSION=1.49.1 +RUN set -eux; \ + export PATH="/opt/hostedtoolcache/node/${NODE_VERSION}/x64/bin:$PATH"; \ + npx --yes "playwright@${PLAYWRIGHT_VERSION}" install-deps; \ + rm -rf /var/lib/apt/lists/* /root/.npm + USER runner diff --git a/runners/arc/ONBOARD-REPO.md b/runners/arc/ONBOARD-REPO.md index b581355b..31920c9c 100644 --- a/runners/arc/ONBOARD-REPO.md +++ b/runners/arc/ONBOARD-REPO.md @@ -103,12 +103,21 @@ means these work out of the box on `runs-on: ` — no separate - `docker build` / `docker buildx build --push` (GHCR image builds) ✅ - `docker run` / `docker ps` (daemon reachable via `DOCKER_HOST`) ✅ -**`docker compose` needs one extra step.** The stock `ghcr.io/actions/actions-runner` -image ships the docker CLI + buildx but **not** the compose-v2 plugin, so -`docker compose -f …` fails with `unknown shorthand flag: 'f' in -f`. To enable it, -publish `runners/arc/Dockerfile` (bakes the compose plugin) and point the scale set -at it via `RUNNER_IMAGE` / the `image:` field, then re-register (below). DinD alone -does **not** add compose. +**`docker compose` works by default now.** `register-repo.sh` defaults the runner +image to the **FuzeInfra CI-capable image** (`ghcr.io/izzywdev/fuzeinfra-arc-runner`, +built from `runners/arc/Dockerfile`), which bakes in the **compose-v2 & buildx CLI +plugins**, `jq`/`curl`, a warm Python/Node toolcache, and **Playwright browser OS +deps**. So `docker compose -f …`, `docker buildx …`, and `npx playwright install +` all work on `runs-on: ` out of the box. + +> **Prerequisite:** that image must be **published + PUBLIC** on GHCR (or an +> `imagePullSecret` wired into `arc-runners`) or runner pods `ImagePullBackOff`. +> Publish it once via the `build-runner-image` workflow +> (`runners/arc/workflows-to-install/build-runner-image.yml` → move into +> `.github/workflows/`) or `runners/arc/build-and-push-runner-image.sh`. + +To fall back to the stock image (no compose), pass `--runner-image +ghcr.io/actions/actions-runner:latest`. DinD alone does **not** add compose. **Re-register existing scale sets to pick up DinD.** The dind sidecar only appears on pods created *after* the Helm values change. Any scale set registered before DinD diff --git a/runners/arc/register-repo.sh b/runners/arc/register-repo.sh index ab6cb340..cf7bc5b4 100644 --- a/runners/arc/register-repo.sh +++ b/runners/arc/register-repo.sh @@ -25,6 +25,15 @@ # --name fuzefront \ # --secret arc-runner-github-app # existing secret in arc-runners # +# # override the CI runner image or container mode (both have CI-capable +# # defaults — the FuzeInfra runner image + dind — so onboarding stays a +# # single invocation): +# ./runners/arc/register-repo.sh \ +# --repo-url https://github.com/izzywdev/FuzeFront \ +# --name fuzefront --secret arc-runner-github-app \ +# --runner-image ghcr.io/izzywdev/fuzeinfra-arc-runner:2026-07-13 \ +# --container-mode dind +# # # uninstall a repo's scale set # ./runners/arc/register-repo.sh --name fuzefront --uninstall # @@ -48,10 +57,24 @@ ARC_VERSION="0.14.2" # the node; raise per-repo with --max-runners once the CI pool is scaled out. MAX_RUNNERS=3 MIN_RUNNERS=0 -# Runner image. Stock actions-runner ships the docker CLI + buildx but NOT the -# compose-v2 plugin. To get `docker compose`, publish runners/arc/Dockerfile and -# point RUNNER_IMAGE at it (e.g. ghcr.io/izzywdev/fuzeinfra-arc-runner:). -RUNNER_IMAGE="${RUNNER_IMAGE:-ghcr.io/actions/actions-runner:latest}" +# Runner image. Defaults to the FuzeInfra CI-capable image (runners/arc/Dockerfile: +# stock actions-runner + docker compose-v2 & buildx plugins + jq/curl + warm +# Python/Node toolcache + Playwright browser deps) so every scale set comes up +# CI-capable from this one provisioning change. Override with --runner-image or +# RUNNER_IMAGE (e.g. the stock ghcr.io/actions/actions-runner:latest — but that +# lacks `docker compose`, so gate-* / build-test jobs will fail on it). +# +# PREREQUISITE: the default image must be published + PUBLIC (or an imagePullSecret +# wired into arc-runners) or runner pods ImagePullBackOff. Publish it via the +# build-runner-image workflow (runners/arc/workflows-to-install/build-runner-image.yml) +# or runners/arc/build-and-push-runner-image.sh before onboarding new repos. +RUNNER_IMAGE="${RUNNER_IMAGE:-ghcr.io/izzywdev/fuzeinfra-arc-runner:latest}" + +# Container mode for the runner pods. "dind" (default) injects a privileged +# docker:dind sidecar + init-dind-externals initContainer and wires DOCKER_HOST, +# giving docker / docker compose / docker buildx / docker run self-hosted. Kept +# parameterizable (--container-mode) but dind is the CI-capable default. +CONTAINER_MODE="dind" REPO_URL="" SCALE_SET_NAME="" @@ -76,6 +99,8 @@ while [[ $# -gt 0 ]]; do --app-install-id) APP_INSTALL_ID="$2"; shift 2 ;; --app-private-key) APP_PRIVATE_KEY_FILE="$2"; shift 2 ;; --max-runners) MAX_RUNNERS="$2"; shift 2 ;; + --runner-image) RUNNER_IMAGE="$2"; shift 2 ;; + --container-mode) CONTAINER_MODE="$2"; shift 2 ;; --uninstall) UNINSTALL=true; shift ;; --help|-h) usage ;; *) echo "Unknown option: $1"; usage ;; @@ -180,7 +205,7 @@ template: # FuzeInfra arc-reinstall-scaleset.yml for the staging set) to pick this up -- # the dind sidecar only appears on pods created after this Helm values change. containerMode: - type: dind + type: ${CONTAINER_MODE} controllerServiceAccount: namespace: ${CONTROLLER_NS} @@ -200,6 +225,8 @@ EOF # ---- Helm install/upgrade --------------------------------------------------- echo "==> Registering scale set '$SCALE_SET_NAME' for $REPO_URL …" +echo " runner image : $RUNNER_IMAGE" +echo " containerMode: $CONTAINER_MODE" echo "$VALUES" | helm upgrade --install "$SCALE_SET_NAME" \ "$ARC_RUNNER_CHART" \ --version "$ARC_VERSION" \