From f66f85176a81132b4488c109a7968865976df449 Mon Sep 17 00:00:00 2001 From: Ben Williams Date: Thu, 20 Aug 2026 21:49:15 -0700 Subject: [PATCH 1/2] Fix runner Node and Git parity --- docker/Dockerfile | 19 +++++++++++-------- tests/dockerfile.test.ts | 24 ++++++++++++++++++++---- 2 files changed, 31 insertions(+), 12 deletions(-) diff --git a/docker/Dockerfile b/docker/Dockerfile index c20b8e3..b9b5bd1 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -19,13 +19,14 @@ RUN git apply /tmp/actions-runner-results-proxy.patch \ && cd src \ && ./dev.sh layout Release -# GitHub.com now executes JavaScript actions with Node 24. This runner cannot -# execute Docker container actions, so the Node copies used only inside Alpine -# container steps are unreachable. Prune them in the builder stage so they are -# absent from the final image layer instead of hidden behind whiteouts. -RUN test -x /opt/actions-runner-source/_layout/externals/node24/bin/node \ +# The runner invokes node20 to evaluate workflow expressions (for example, +# hashFiles()) and can still execute Node 20 actions during GitHub's temporary +# Node 24 opt-out. This runner cannot execute Docker container actions, so only +# the Node copies used inside Alpine container steps are unreachable. Prune +# those in the builder stage so they are absent from the final image layer. +RUN test -x /opt/actions-runner-source/_layout/externals/node20/bin/node \ + && test -x /opt/actions-runner-source/_layout/externals/node24/bin/node \ && rm -rf \ - /opt/actions-runner-source/_layout/externals/node20 \ /opt/actions-runner-source/_layout/externals/node20_alpine \ /opt/actions-runner-source/_layout/externals/node24_alpine @@ -51,20 +52,22 @@ RUN apt-get update \ ca-certificates \ cmake \ curl \ - git \ - git-lfs \ jq \ ninja-build \ openssh-client \ pkg-config \ python3 \ rsync \ + software-properties-common \ tini \ unzip \ wget \ xz-utils \ zip \ zstd \ + && add-apt-repository --yes ppa:git-core/ppa \ + && apt-get update \ + && apt-get install --yes --no-install-recommends git git-lfs \ && useradd --create-home --shell /bin/bash runner \ && mkdir --parents /home/runner/actions-runner \ && mkdir --parents "${RUNNER_TOOL_CACHE}/node/${NODE_VERSION}" \ diff --git a/tests/dockerfile.test.ts b/tests/dockerfile.test.ts index 65dc0bc..a298fd2 100644 --- a/tests/dockerfile.test.ts +++ b/tests/dockerfile.test.ts @@ -3,20 +3,36 @@ import { readFile } from "node:fs/promises"; import { describe, expect, it } from "vite-plus/test"; describe("runner image", () => { - it("keeps obsolete action runtimes out of the final image", async () => { + it("keeps supported action runtimes while pruning Alpine-only copies", async () => { const dockerfile = await readFile("docker/Dockerfile", "utf8"); const finalImage = dockerfile.lastIndexOf("FROM ubuntu:24.04"); - const prune = dockerfile.indexOf("/opt/actions-runner-source/_layout/externals/node20"); + const prune = dockerfile.indexOf("/opt/actions-runner-source/_layout/externals/node20_alpine"); + const runtimeCheck = dockerfile.indexOf("test -x /opt/actions-runner-source/_layout/externals/node20/bin/node"); + const pruneBlock = dockerfile.slice(runtimeCheck, dockerfile.indexOf("\n\n", runtimeCheck)); expect(finalImage).toBeGreaterThan(0); expect(prune).toBeGreaterThan(0); expect(prune).toBeLessThan(finalImage); - expect(dockerfile).toContain("/opt/actions-runner-source/_layout/externals/node20_alpine"); - expect(dockerfile).toContain("/opt/actions-runner-source/_layout/externals/node24_alpine"); + expect(runtimeCheck).toBeGreaterThan(0); + expect(pruneBlock).toContain("/opt/actions-runner-source/_layout/externals/node20_alpine"); + expect(pruneBlock).toContain("/opt/actions-runner-source/_layout/externals/node24_alpine"); + expect(pruneBlock).not.toMatch(/\/externals\/node20\s*(?:\\|\r?\n)/); expect(dockerfile).toContain("FORCE_JAVASCRIPT_ACTIONS_TO_NODE24=true"); + expect(dockerfile).toContain("test -x /opt/actions-runner-source/_layout/externals/node20/bin/node"); expect(dockerfile).toContain("test -x /opt/actions-runner-source/_layout/externals/node24/bin/node"); + expect(dockerfile).not.toContain("ln --symbolic node24 /home/runner/actions-runner/externals/node20"); expect(dockerfile).toContain("chown runner:runner /home/runner/actions-runner"); expect(dockerfile).toContain('chown --recursive runner:runner "${RUNNER_TOOL_CACHE}"'); expect(dockerfile).not.toContain('chown --recursive runner:runner /home/runner "${RUNNER_TOOL_CACHE}"'); }); + + it("installs Git from git-core for GitHub-hosted runner parity", async () => { + const dockerfile = await readFile("docker/Dockerfile", "utf8"); + + const repository = dockerfile.indexOf("add-apt-repository --yes ppa:git-core/ppa"); + const gitInstall = dockerfile.indexOf("apt-get install --yes --no-install-recommends git git-lfs", repository); + + expect(repository).toBeGreaterThan(0); + expect(gitInstall).toBeGreaterThan(repository); + }); }); From e5514afe8951abcff9e6babfdeae92b012503ae8 Mon Sep 17 00:00:00 2001 From: Ben Williams Date: Thu, 20 Aug 2026 21:53:58 -0700 Subject: [PATCH 2/2] Bump package version to 1.0.8 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 3a29fcf..ca54117 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "cloudflare-github-actions-runner", - "version": "1.0.7", + "version": "1.0.8", "description": "Run GitHub Actions jobs as disposable Cloudflare Containers.", "keywords": [ "ci",