Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 11 additions & 8 deletions docker/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand All @@ -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}" \
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -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",
Expand Down
24 changes: 20 additions & 4 deletions tests/dockerfile.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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);
});
});