@htekdev/actions-debugger 1.0.37 → 1.0.39
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/errors/caching-artifacts/cache-legacy-service-decommission-url-override-fail.yml +120 -0
- package/errors/runner-environment/container-job-rootless-user-workspace-eacces.yml +103 -0
- package/errors/runner-environment/macos-latest-macos-15-xcode16-sdk-mismatch.yml +84 -0
- package/errors/runner-environment/node16-actions-runtime-deprecated-disabled.yml +87 -0
- package/errors/runner-environment/self-hosted-runsvc-zero-bytes-auto-update.yml +112 -0
- package/errors/runner-environment/ubuntu-latest-ubuntu-24-python2-package-removal.yml +75 -0
- package/errors/silent-failures/fork-pr-secrets-empty-string-steps-silently-skipped.yml +97 -0
- package/errors/silent-failures/github-workspace-incorrect-inside-container-job.yml +123 -0
- package/package.json +1 -1
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
id: caching-artifacts-031
|
|
2
|
+
title: 'Cache failures from manually-overridden ACTIONS_CACHE_URL after legacy service decommission (April 2025)'
|
|
3
|
+
category: caching-artifacts
|
|
4
|
+
severity: error
|
|
5
|
+
tags:
|
|
6
|
+
- cache
|
|
7
|
+
- legacy-service
|
|
8
|
+
- ACTIONS_CACHE_URL
|
|
9
|
+
- service-migration
|
|
10
|
+
- brownout
|
|
11
|
+
- self-hosted
|
|
12
|
+
patterns:
|
|
13
|
+
- regex: 'ACTIONS_CACHE_URL.*403|ACTIONS_CACHE_URL.*503|ACTIONS_CACHE_URL.*Connection refused'
|
|
14
|
+
flags: 'i'
|
|
15
|
+
- regex: 'Cache service responded with (403|503|5\d\d)'
|
|
16
|
+
flags: 'i'
|
|
17
|
+
- regex: 'Failed to restore cache entry\. Exiting\.\.\.'
|
|
18
|
+
flags: 'i'
|
|
19
|
+
- regex: 'Unable to reserve cache with key.*ACTIONS_CACHE_URL'
|
|
20
|
+
flags: 'i'
|
|
21
|
+
error_messages:
|
|
22
|
+
- "Cache service responded with 503"
|
|
23
|
+
- "Cache service responded with 403"
|
|
24
|
+
- "Failed to restore cache entry. Exiting..."
|
|
25
|
+
- "Unable to reserve cache with key"
|
|
26
|
+
- "Error: ECONNREFUSED connecting to ACTIONS_CACHE_URL"
|
|
27
|
+
root_cause: |
|
|
28
|
+
GitHub migrated all customers to a new cache service backend in early 2025
|
|
29
|
+
and decommissioned the legacy service on April 15, 2025. Prior to decommission,
|
|
30
|
+
brownout windows were scheduled on April 1 and April 8 (each 4-8 hours).
|
|
31
|
+
|
|
32
|
+
Workflows that explicitly override ACTIONS_CACHE_URL, ACTIONS_RESULTS_URL, or
|
|
33
|
+
ACTIONS_RUNTIME_URL continue routing requests to the decommissioned endpoint,
|
|
34
|
+
causing 403 or 503 responses. The cache action reports "Failed to restore cache
|
|
35
|
+
entry" or "Unable to reserve cache" and either skips caching silently or fails
|
|
36
|
+
the step (depending on fail-on-cache-miss settings).
|
|
37
|
+
|
|
38
|
+
Common sources of stale overrides:
|
|
39
|
+
- Third-party self-hosted runner software (ARC add-ons, Buildkite agents, etc.)
|
|
40
|
+
that inject a corporate cache proxy URL into the runner environment
|
|
41
|
+
- Composite actions or reusable workflows with hardcoded env var overrides
|
|
42
|
+
copied from pre-migration documentation
|
|
43
|
+
- Container images with ENV ACTIONS_CACHE_URL set in their Dockerfile,
|
|
44
|
+
inherited by container jobs and overriding the runner-injected value
|
|
45
|
+
- Enterprise self-hosted runner configurations in on-premises GitHub instances
|
|
46
|
+
that still point to a proxy configured for the old cache service API
|
|
47
|
+
|
|
48
|
+
The runner agent always injects the correct new-service values at job startup.
|
|
49
|
+
Any explicit override — even one set a millisecond earlier — takes precedence
|
|
50
|
+
and silently routes to the wrong endpoint.
|
|
51
|
+
fix: |
|
|
52
|
+
Remove all explicit overrides of ACTIONS_CACHE_URL, ACTIONS_RESULTS_URL, and
|
|
53
|
+
ACTIONS_RUNTIME_URL from:
|
|
54
|
+
- Workflow env: blocks (top-level, job-level, and step-level)
|
|
55
|
+
- Composite action env blocks
|
|
56
|
+
- Reusable workflow env blocks
|
|
57
|
+
- Container image Dockerfiles (ENV directives)
|
|
58
|
+
- Self-hosted runner startup scripts and systemd unit files
|
|
59
|
+
- ARC runner controller configuration and any environment-injection middleware
|
|
60
|
+
|
|
61
|
+
Let the runner agent inject the correct values automatically at job startup.
|
|
62
|
+
These values are ephemeral per-job tokens — they cannot be cached or pre-set
|
|
63
|
+
and must come from the runner agent.
|
|
64
|
+
|
|
65
|
+
For self-hosted setups using a corporate cache proxy, update the proxy
|
|
66
|
+
to forward requests to the new service endpoint format, or decommission the
|
|
67
|
+
proxy if it is no longer required.
|
|
68
|
+
fix_code:
|
|
69
|
+
- language: yaml
|
|
70
|
+
label: 'Remove ACTIONS_CACHE_URL override from workflow — let runner inject correct value'
|
|
71
|
+
code: |
|
|
72
|
+
# WRONG: overriding cache service URL causes failures after April 2025
|
|
73
|
+
# env:
|
|
74
|
+
# ACTIONS_CACHE_URL: https://my-corp-proxy.example.com/_apis/artifactcache/
|
|
75
|
+
# ACTIONS_RESULTS_URL: https://my-corp-proxy.example.com/_apis/
|
|
76
|
+
# ACTIONS_RUNTIME_URL: https://my-corp-proxy.example.com/
|
|
77
|
+
|
|
78
|
+
# CORRECT: remove all overrides, let the runner inject the values
|
|
79
|
+
jobs:
|
|
80
|
+
build:
|
|
81
|
+
runs-on: [self-hosted, linux]
|
|
82
|
+
steps:
|
|
83
|
+
- uses: actions/checkout@v4
|
|
84
|
+
- name: Cache dependencies
|
|
85
|
+
uses: actions/cache@v4
|
|
86
|
+
with:
|
|
87
|
+
path: ~/.npm
|
|
88
|
+
key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
|
|
89
|
+
- name: Install
|
|
90
|
+
run: npm ci
|
|
91
|
+
- language: yaml
|
|
92
|
+
label: 'Audit container images for hardcoded ACTIONS_CACHE_URL'
|
|
93
|
+
code: |
|
|
94
|
+
# In your Dockerfile — remove any hardcoded cache service URL
|
|
95
|
+
# FROM ubuntu:22.04
|
|
96
|
+
# ENV ACTIONS_CACHE_URL=https://... ← REMOVE: causes failures after April 2025
|
|
97
|
+
|
|
98
|
+
# In your workflow — do not set cache URL env vars in container definitions
|
|
99
|
+
jobs:
|
|
100
|
+
build:
|
|
101
|
+
runs-on: ubuntu-latest
|
|
102
|
+
container:
|
|
103
|
+
image: myimage:latest
|
|
104
|
+
# Do not add env overrides for ACTIONS_CACHE_URL here
|
|
105
|
+
steps:
|
|
106
|
+
- uses: actions/cache@v4
|
|
107
|
+
with:
|
|
108
|
+
path: ~/.cache/pip
|
|
109
|
+
key: ${{ runner.os }}-pip-${{ hashFiles('**/requirements.txt') }}
|
|
110
|
+
prevention:
|
|
111
|
+
- 'Never hardcode ACTIONS_CACHE_URL, ACTIONS_RESULTS_URL, or ACTIONS_RUNTIME_URL in workflows, container images, or runner configs'
|
|
112
|
+
- 'Audit third-party composite actions and runner middleware for injected cache URL overrides after any GitHub cache service migration'
|
|
113
|
+
- 'Subscribe to the GitHub Changelog (github.blog/changelog) to receive advance notice of cache service migrations and brownout schedules'
|
|
114
|
+
- 'Upgrade to actions/cache@v4 or later — the v4 client was updated to use the new service API and is the supported path forward'
|
|
115
|
+
- 'Add a pre-flight check step on self-hosted runners that logs the injected ACTIONS_CACHE_URL to detect unexpected overrides'
|
|
116
|
+
docs:
|
|
117
|
+
- url: 'https://github.blog/changelog/2025-03-20-notification-of-upcoming-breaking-changes-in-github-actions/'
|
|
118
|
+
label: 'GitHub Changelog: Upcoming breaking changes — legacy cache service decommission (March 2025)'
|
|
119
|
+
- url: 'https://docs.github.com/en/actions/writing-workflows/choosing-what-your-workflow-does/caching-dependencies-to-speed-up-workflows'
|
|
120
|
+
label: 'Caching dependencies to speed up workflows — actions/cache@v4'
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
id: runner-environment-097
|
|
2
|
+
title: 'Container job with non-root Docker user fails with EACCES on workspace and command files'
|
|
3
|
+
category: runner-environment
|
|
4
|
+
severity: error
|
|
5
|
+
tags:
|
|
6
|
+
- container-jobs
|
|
7
|
+
- non-root
|
|
8
|
+
- rootless
|
|
9
|
+
- permissions
|
|
10
|
+
- EACCES
|
|
11
|
+
- docker
|
|
12
|
+
- workspace
|
|
13
|
+
patterns:
|
|
14
|
+
- regex: 'EACCES.*permission denied.*_runner_file_commands|permission denied.*_runner_file_commands'
|
|
15
|
+
flags: 'i'
|
|
16
|
+
- regex: 'permission denied.*GITHUB_ENV|permission denied.*GITHUB_OUTPUT|permission denied.*GITHUB_PATH|permission denied.*GITHUB_STEP_SUMMARY'
|
|
17
|
+
flags: 'i'
|
|
18
|
+
- regex: 'could not lock config file.*Permission denied'
|
|
19
|
+
flags: 'i'
|
|
20
|
+
- regex: 'EACCES.*permission denied.*__w|permission denied.*github/workspace'
|
|
21
|
+
flags: 'i'
|
|
22
|
+
error_messages:
|
|
23
|
+
- "Error: EACCES: permission denied, open '/home/runner/work/_temp/_runner_file_commands/set_env_'"
|
|
24
|
+
- "Error: EACCES: permission denied, open '/__w/_temp/_runner_file_commands/add_path_'"
|
|
25
|
+
- "error: could not lock config file /home/runner/work/repo/.git/config: Permission denied"
|
|
26
|
+
- "EACCES: permission denied, open '/github/workspace/_temp/_runner_file_commands/'"
|
|
27
|
+
root_cause: |
|
|
28
|
+
When a workflow uses a container job (jobs.<id>.container), the GitHub Actions
|
|
29
|
+
runner creates the workspace directories, .git directory, and all special command
|
|
30
|
+
files (GITHUB_ENV, GITHUB_OUTPUT, GITHUB_PATH, GITHUB_STEP_SUMMARY) as root UID
|
|
31
|
+
on the host before starting the container.
|
|
32
|
+
|
|
33
|
+
If the container image runs as a non-root user — via a USER directive in the
|
|
34
|
+
Dockerfile, docker run --user, or a Kubernetes securityContext.runAsUser setting —
|
|
35
|
+
that user has no write access to the root-owned files and directories. Every step
|
|
36
|
+
that writes to GITHUB_ENV, GITHUB_OUTPUT, GITHUB_PATH, or GITHUB_STEP_SUMMARY
|
|
37
|
+
fails with EACCES: permission denied. The checkout step also fails because git
|
|
38
|
+
cannot write the lock file for the config.
|
|
39
|
+
|
|
40
|
+
The runner does not automatically adjust ownership, set ACLs, or apply mount
|
|
41
|
+
options to make the workspace writable by non-root container users. This is a
|
|
42
|
+
known long-standing platform limitation tracked in runner#2411 (30 reactions)
|
|
43
|
+
with no built-in fix as of 2026. The issue also affects ARC (actions-runner-controller)
|
|
44
|
+
Kubernetes runners when the pod securityContext sets a non-root runAsUser.
|
|
45
|
+
fix: |
|
|
46
|
+
Option 1 — Add `options: --user root` to the container definition.
|
|
47
|
+
This overrides the container USER and runs job steps as root, granting
|
|
48
|
+
full access to all runner-created files.
|
|
49
|
+
|
|
50
|
+
Option 2 — Set fsGroup in Kubernetes/ARC pod spec so mounted directories
|
|
51
|
+
are group-writable and the container's supplemental group matches.
|
|
52
|
+
|
|
53
|
+
Option 3 — Use a privileged init step (--user 0) to chown the workspace
|
|
54
|
+
to the container's non-root UID before executing actual build steps.
|
|
55
|
+
|
|
56
|
+
Option 4 — Build the container image with UID 1001 (the runner UID on
|
|
57
|
+
GitHub-hosted runners) instead of a custom non-root UID, so ownership
|
|
58
|
+
matches automatically.
|
|
59
|
+
fix_code:
|
|
60
|
+
- language: yaml
|
|
61
|
+
label: 'Force container to run as root with options: --user root'
|
|
62
|
+
code: |
|
|
63
|
+
jobs:
|
|
64
|
+
build:
|
|
65
|
+
runs-on: ubuntu-latest
|
|
66
|
+
container:
|
|
67
|
+
image: myapp:latest # Has a non-root USER in its Dockerfile
|
|
68
|
+
options: --user root # Override: run job steps as root
|
|
69
|
+
steps:
|
|
70
|
+
- uses: actions/checkout@v4
|
|
71
|
+
- name: Build
|
|
72
|
+
run: make build
|
|
73
|
+
- language: yaml
|
|
74
|
+
label: 'Set fsGroup in ARC RunnerSet to make workspace group-writable'
|
|
75
|
+
code: |
|
|
76
|
+
apiVersion: actions.github.com/v1alpha1
|
|
77
|
+
kind: RunnerSet
|
|
78
|
+
metadata:
|
|
79
|
+
name: my-runners
|
|
80
|
+
spec:
|
|
81
|
+
template:
|
|
82
|
+
spec:
|
|
83
|
+
securityContext:
|
|
84
|
+
fsGroup: 1001 # Match runner UID so workspace is accessible
|
|
85
|
+
containers:
|
|
86
|
+
- name: runner
|
|
87
|
+
image: ghcr.io/actions/actions-runner:latest
|
|
88
|
+
securityContext:
|
|
89
|
+
runAsUser: 1001
|
|
90
|
+
runAsGroup: 1001
|
|
91
|
+
prevention:
|
|
92
|
+
- 'Prefer running container jobs as root or as UID 1001 to match the runner workspace ownership'
|
|
93
|
+
- 'Test container images locally with docker run --user <uid> to catch permission issues before CI'
|
|
94
|
+
- 'Document the --user root workaround in workflow templates that use custom container images'
|
|
95
|
+
- 'Consider using a job-level container for tool availability only, keeping privileged steps on the host runner'
|
|
96
|
+
- 'When building custom runner images, set USER to UID 1001 to match GitHub-hosted runner conventions'
|
|
97
|
+
docs:
|
|
98
|
+
- url: 'https://github.com/actions/runner/issues/2411'
|
|
99
|
+
label: 'runner#2411: Runner does not set proper permissions for mounted folders in rootless container jobs (30 reactions)'
|
|
100
|
+
- url: 'https://docs.github.com/en/actions/writing-workflows/choosing-where-your-workflow-runs/running-jobs-in-a-container'
|
|
101
|
+
label: 'Running jobs in a container — options field and container configuration'
|
|
102
|
+
- url: 'https://github.com/actions/runner/issues/3290'
|
|
103
|
+
label: 'runner#3290: Kubernetes container pods fail with EACCES when using a custom user'
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
id: runner-environment-095
|
|
2
|
+
title: macos-latest Points to macOS 15 — Xcode 16 Default Breaks Hardcoded SDK References
|
|
3
|
+
category: runner-environment
|
|
4
|
+
severity: error
|
|
5
|
+
tags:
|
|
6
|
+
- macos-latest
|
|
7
|
+
- macos-15
|
|
8
|
+
- xcode-16
|
|
9
|
+
- runner-migration
|
|
10
|
+
- apple-silicon
|
|
11
|
+
patterns:
|
|
12
|
+
- regex: 'SDK ''macosx14\.\d+'' cannot be located'
|
|
13
|
+
flags: i
|
|
14
|
+
- regex: 'SDKROOT.*macosx14'
|
|
15
|
+
flags: i
|
|
16
|
+
- regex: 'built for macOS 14.*linking for macOS 15'
|
|
17
|
+
flags: i
|
|
18
|
+
- regex: 'xcodebuild: error:.*SDK ''macosx14'
|
|
19
|
+
flags: i
|
|
20
|
+
error_messages:
|
|
21
|
+
- "error: SDK 'macosx14.5' cannot be located"
|
|
22
|
+
- "xcodebuild: error: The requested SDK 'macosx14.5' cannot be found."
|
|
23
|
+
- "ld: warning: ignoring file ...: built for macOS 14, but linking for macOS 15"
|
|
24
|
+
root_cause: |
|
|
25
|
+
GitHub updated macos-latest to point to macOS 15 (Sequoia) on Apple Silicon
|
|
26
|
+
(M1) runners in January 2025 (GitHub Changelog 2025-01-16). The macOS 15 runner
|
|
27
|
+
image ships with Xcode 16 as the default toolchain.
|
|
28
|
+
|
|
29
|
+
Workflows and Xcode project files that hardcode `SDKROOT=macosx14.5` or
|
|
30
|
+
`MACOSX_DEPLOYMENT_TARGET=14` fail because the macOS 14 SDK is not bundled
|
|
31
|
+
with Xcode 16 by default. Common failure modes:
|
|
32
|
+
|
|
33
|
+
- Hardcoded SDK version strings in .xcconfig files
|
|
34
|
+
- Xcode project targets specifying a minimum macOS deployment target of 14.x
|
|
35
|
+
that resolve against the now-absent SDK
|
|
36
|
+
- Homebrew formulae and pre-installed tool versions changed on macOS 15,
|
|
37
|
+
breaking workflows that assumed specific tool paths or versions
|
|
38
|
+
- The pre-installed Ruby version changed, breaking Fastlane and CocoaPods
|
|
39
|
+
workflows that did not pin a Ruby version
|
|
40
|
+
fix: |
|
|
41
|
+
Option 1: Pin the runner to `macos-14` explicitly to continue using Xcode 15
|
|
42
|
+
and the macOS 14 SDK until you are ready to migrate.
|
|
43
|
+
|
|
44
|
+
Option 2: Use the `maxim-lobanov/setup-xcode` action to pin a specific Xcode
|
|
45
|
+
version on macos-latest, keeping the runner current while controlling toolchain.
|
|
46
|
+
|
|
47
|
+
Option 3: Update Xcode project settings to remove hardcoded SDK version strings.
|
|
48
|
+
Use `$(SDKROOT)` relative targets and set `MACOSX_DEPLOYMENT_TARGET` to a value
|
|
49
|
+
supported by Xcode 16.
|
|
50
|
+
|
|
51
|
+
For Ruby-dependent workflows (Fastlane, CocoaPods), use `ruby/setup-ruby` with
|
|
52
|
+
an explicit version rather than relying on the system Ruby.
|
|
53
|
+
fix_code:
|
|
54
|
+
- language: yaml
|
|
55
|
+
label: Pin explicit macOS version to avoid macos-latest drift
|
|
56
|
+
code: |
|
|
57
|
+
jobs:
|
|
58
|
+
build:
|
|
59
|
+
runs-on: macos-14 # explicit; Xcode 15 + macOS 14 SDK
|
|
60
|
+
|
|
61
|
+
- language: yaml
|
|
62
|
+
label: Pin Xcode version on macos-latest
|
|
63
|
+
code: |
|
|
64
|
+
- uses: maxim-lobanov/setup-xcode@v1
|
|
65
|
+
with:
|
|
66
|
+
xcode-version: '15.4'
|
|
67
|
+
|
|
68
|
+
- language: yaml
|
|
69
|
+
label: Use ruby/setup-ruby for Fastlane and CocoaPods workflows
|
|
70
|
+
code: |
|
|
71
|
+
- uses: ruby/setup-ruby@v1
|
|
72
|
+
with:
|
|
73
|
+
ruby-version: '3.3'
|
|
74
|
+
bundler-cache: true
|
|
75
|
+
prevention:
|
|
76
|
+
- "Pin explicit runner OS versions (macos-14, macos-15) instead of macos-latest for stable CI builds"
|
|
77
|
+
- "Never hardcode SDK version strings (macosx14.x) in Xcode project .xcconfig files — use $(SDKROOT)"
|
|
78
|
+
- "Use ruby/setup-ruby, actions/setup-python, and similar version-pinning actions for all language runtimes"
|
|
79
|
+
- "Subscribe to GitHub Changelog and runner-images repository releases for macOS image update notices"
|
|
80
|
+
docs:
|
|
81
|
+
- url: https://github.blog/changelog/2025-01-16-github-actions-macos-15-is-now-the-latest-macos-runner-image/
|
|
82
|
+
label: "GitHub Changelog: macOS 15 becomes macos-latest (Jan 2025)"
|
|
83
|
+
- url: https://docs.github.com/en/actions/using-github-hosted-runners/using-github-hosted-runners/about-github-hosted-runners
|
|
84
|
+
label: "GitHub-hosted runner images documentation"
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
id: runner-environment-094
|
|
2
|
+
title: Node.js 16 Actions Runtime Deprecated and Disabled — Actions Using node16 Fail
|
|
3
|
+
category: runner-environment
|
|
4
|
+
severity: error
|
|
5
|
+
tags:
|
|
6
|
+
- node16
|
|
7
|
+
- node20
|
|
8
|
+
- action-runtime
|
|
9
|
+
- deprecation
|
|
10
|
+
- runs-using
|
|
11
|
+
patterns:
|
|
12
|
+
- regex: 'Node\.js 16 actions are deprecated'
|
|
13
|
+
flags: i
|
|
14
|
+
- regex: 'Please update the following actions to use Node\.js 20'
|
|
15
|
+
flags: i
|
|
16
|
+
- regex: 'uses a deprecated version of `actions/node`'
|
|
17
|
+
flags: i
|
|
18
|
+
error_messages:
|
|
19
|
+
- "Node.js 16 actions are deprecated. Please update the following actions to use Node.js 20: actions/checkout@v3"
|
|
20
|
+
- "Warning: Node.js 16 is End-of-Life. Upgrade to Node.js 20 or later."
|
|
21
|
+
- "Error: This request has been automatically failed because it uses a deprecated version of `actions/node`"
|
|
22
|
+
root_cause: |
|
|
23
|
+
Node.js 16 reached end-of-life on September 11, 2023. GitHub announced on
|
|
24
|
+
September 22, 2023 (GitHub Changelog) that it would deprecate the Node.js 16
|
|
25
|
+
runtime for GitHub Actions, with a hard enforcement cutoff on September 22, 2024.
|
|
26
|
+
|
|
27
|
+
Actions authored with `runs.using: node16` in their action.yml emit deprecation
|
|
28
|
+
warnings from late 2023 onward. From September 2024, these actions produce hard
|
|
29
|
+
errors and may not execute. Third-party actions pinned to older major versions
|
|
30
|
+
that internally use node16 are affected, including actions/checkout@v3,
|
|
31
|
+
actions/setup-node@v3, actions/cache@v3, and many community actions. Composite
|
|
32
|
+
actions that transitively call a node16-based action also fail.
|
|
33
|
+
fix: |
|
|
34
|
+
Update all action references in your workflows to major versions that use the
|
|
35
|
+
node20 (or node22) runtime. Common upgrades needed:
|
|
36
|
+
- actions/checkout@v3 → @v4
|
|
37
|
+
- actions/setup-node@v3 → @v4
|
|
38
|
+
- actions/cache@v3 → @v4
|
|
39
|
+
- actions/upload-artifact@v3 → @v4
|
|
40
|
+
- actions/download-artifact@v3 → @v4
|
|
41
|
+
|
|
42
|
+
For custom actions you own, update `runs.using` in action.yml from
|
|
43
|
+
`node16` to `node20`.
|
|
44
|
+
|
|
45
|
+
Use Dependabot or Renovate with the `github-actions` package ecosystem to
|
|
46
|
+
keep action versions current automatically.
|
|
47
|
+
fix_code:
|
|
48
|
+
- language: yaml
|
|
49
|
+
label: Update official actions from node16 to node20-based versions
|
|
50
|
+
code: |
|
|
51
|
+
- uses: actions/checkout@v4 # was @v3 (node16)
|
|
52
|
+
- uses: actions/setup-node@v4 # was @v3 (node16)
|
|
53
|
+
with:
|
|
54
|
+
node-version: '20'
|
|
55
|
+
- uses: actions/cache@v4 # was @v3 (node16)
|
|
56
|
+
with:
|
|
57
|
+
path: ~/.npm
|
|
58
|
+
key: ${{ runner.os }}-npm-${{ hashFiles('**/package-lock.json') }}
|
|
59
|
+
|
|
60
|
+
- language: yaml
|
|
61
|
+
label: Update custom action.yml to node20 runtime
|
|
62
|
+
code: |
|
|
63
|
+
# In your action's action.yml
|
|
64
|
+
runs:
|
|
65
|
+
using: node20
|
|
66
|
+
main: dist/index.js
|
|
67
|
+
|
|
68
|
+
- language: yaml
|
|
69
|
+
label: Enable Dependabot for github-actions ecosystem
|
|
70
|
+
code: |
|
|
71
|
+
# .github/dependabot.yml
|
|
72
|
+
version: 2
|
|
73
|
+
updates:
|
|
74
|
+
- package-ecosystem: github-actions
|
|
75
|
+
directory: /
|
|
76
|
+
schedule:
|
|
77
|
+
interval: weekly
|
|
78
|
+
prevention:
|
|
79
|
+
- "Enable Dependabot for the github-actions package ecosystem to receive automatic PRs for action version updates"
|
|
80
|
+
- "Audit all action.yml files in custom actions for runs.using: node16 before the hard cutoff"
|
|
81
|
+
- "Watch the actions/* repositories on GitHub for major version releases that upgrade the runtime"
|
|
82
|
+
- "Prefer Dependabot or Renovate over manually pinned major versions to stay ahead of deprecations"
|
|
83
|
+
docs:
|
|
84
|
+
- url: https://github.blog/changelog/2023-09-22-github-actions-transitioning-from-node-16-to-node-20/
|
|
85
|
+
label: "GitHub Changelog: Transitioning from Node.js 16 to Node.js 20 (Sep 2023)"
|
|
86
|
+
- url: https://docs.github.com/en/actions/creating-actions/metadata-syntax-for-github-actions#runs-for-javascript-actions
|
|
87
|
+
label: "Actions metadata syntax: runs.using"
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
id: runner-environment-096
|
|
2
|
+
title: 'Self-hosted runner runsvc.sh corrupted to 0 bytes after auto-update'
|
|
3
|
+
category: runner-environment
|
|
4
|
+
severity: error
|
|
5
|
+
tags:
|
|
6
|
+
- self-hosted
|
|
7
|
+
- auto-update
|
|
8
|
+
- runsvc
|
|
9
|
+
- systemd
|
|
10
|
+
- service-restart
|
|
11
|
+
patterns:
|
|
12
|
+
- regex: 'runsvc\.sh.*0 bytes|0 bytes.*runsvc\.sh'
|
|
13
|
+
flags: 'i'
|
|
14
|
+
- regex: 'code=exited.*status=203/EXEC|status=203/EXEC'
|
|
15
|
+
flags: 'i'
|
|
16
|
+
- regex: 'Failed to start GitHub Actions Runner'
|
|
17
|
+
flags: 'i'
|
|
18
|
+
- regex: 'bin/runsvc\.sh.*Syntax error.*end of file'
|
|
19
|
+
flags: 'i'
|
|
20
|
+
error_messages:
|
|
21
|
+
- "(code=exited, status=203/EXEC)"
|
|
22
|
+
- "Failed to start GitHub Actions Runner (svc.sh)"
|
|
23
|
+
- "bin/runsvc.sh: 1: Syntax error: Unexpected end of file"
|
|
24
|
+
- "bin.2.334.0/runsvc.sh: 0 bytes"
|
|
25
|
+
root_cause: |
|
|
26
|
+
When a self-hosted runner auto-updates from v2.328.0 to v2.334.0 (and some
|
|
27
|
+
adjacent version pairs), a race condition in the update file-extraction process
|
|
28
|
+
sometimes writes the new bin.{version}/runsvc.sh as 0 bytes instead of the
|
|
29
|
+
correct shell script content.
|
|
30
|
+
|
|
31
|
+
The currently-running listener operates from in-memory state and continues
|
|
32
|
+
accepting and completing jobs normally — so the runner appears healthy in
|
|
33
|
+
the GitHub Actions UI and the corruption is not immediately visible. The
|
|
34
|
+
bin/runsvc.sh symlink quietly points to the corrupted 0-byte file.
|
|
35
|
+
|
|
36
|
+
On the next service restart (host reboot, manual systemctl restart, OOM kill,
|
|
37
|
+
scheduled maintenance window), systemd attempts to execute the 0-byte runsvc.sh,
|
|
38
|
+
receives Status=203/EXEC (exec format error because the file is empty), and the
|
|
39
|
+
runner fails to start entirely — dropping all pending and future jobs.
|
|
40
|
+
|
|
41
|
+
The failure is especially hard to diagnose because the runner appears fully
|
|
42
|
+
online right up to the restart event. Runners in pools that restart infrequently
|
|
43
|
+
may run corrupted for days before the symptom appears.
|
|
44
|
+
fix: |
|
|
45
|
+
Immediate recovery:
|
|
46
|
+
1. Check if runsvc.sh is 0 bytes:
|
|
47
|
+
ls -lh /path/to/runner/bin/runsvc.sh
|
|
48
|
+
2. If 0 bytes, stop the service and re-download the runner package at the
|
|
49
|
+
same version, or manually copy runsvc.sh from a known-good runner
|
|
50
|
+
installation of the same version.
|
|
51
|
+
3. Restart the service and confirm it comes up cleanly before re-enabling
|
|
52
|
+
job acceptance.
|
|
53
|
+
|
|
54
|
+
Preventive measures:
|
|
55
|
+
- Disable auto-update (--no-auto-update flag during registration) and manage
|
|
56
|
+
runner version upgrades manually during maintenance windows.
|
|
57
|
+
- Add a startup health check (see fix_code) that verifies runsvc.sh is
|
|
58
|
+
non-zero before the service is considered ready.
|
|
59
|
+
- For ephemeral runners, use container restart policies that detect the
|
|
60
|
+
0-byte condition and re-register a fresh runner instead of recycling
|
|
61
|
+
a corrupted one.
|
|
62
|
+
fix_code:
|
|
63
|
+
- language: yaml
|
|
64
|
+
label: 'Detect corrupted runsvc.sh in a pre-job health check step'
|
|
65
|
+
code: |
|
|
66
|
+
jobs:
|
|
67
|
+
preflight:
|
|
68
|
+
runs-on: [self-hosted, linux]
|
|
69
|
+
steps:
|
|
70
|
+
- name: Verify runner service script integrity
|
|
71
|
+
shell: bash
|
|
72
|
+
run: |
|
|
73
|
+
RUNNER_SVC="$(dirname "$(realpath "$0")")/../bin/runsvc.sh"
|
|
74
|
+
if [ ! -s "$RUNNER_SVC" ]; then
|
|
75
|
+
echo "::error::runsvc.sh is 0 bytes — runner update corrupted the service script. Re-register this runner."
|
|
76
|
+
exit 1
|
|
77
|
+
fi
|
|
78
|
+
echo "runsvc.sh OK ($(wc -c < "$RUNNER_SVC") bytes)"
|
|
79
|
+
- language: yaml
|
|
80
|
+
label: 'Pin runner version and disable auto-update via ARC RunnerSet spec'
|
|
81
|
+
code: |
|
|
82
|
+
# actions-runner-controller RunnerSet — pin version, disable auto-update
|
|
83
|
+
apiVersion: actions.github.com/v1alpha1
|
|
84
|
+
kind: RunnerSet
|
|
85
|
+
metadata:
|
|
86
|
+
name: my-runners
|
|
87
|
+
spec:
|
|
88
|
+
githubConfigUrl: https://github.com/my-org/my-repo
|
|
89
|
+
githubConfigSecret: controller-manager
|
|
90
|
+
minRunners: 2
|
|
91
|
+
maxRunners: 10
|
|
92
|
+
template:
|
|
93
|
+
spec:
|
|
94
|
+
containers:
|
|
95
|
+
- name: runner
|
|
96
|
+
image: ghcr.io/actions/actions-runner:2.334.0 # pin version
|
|
97
|
+
env:
|
|
98
|
+
- name: DISABLE_RUNNER_UPDATE
|
|
99
|
+
value: '1'
|
|
100
|
+
prevention:
|
|
101
|
+
- 'Pin runner version with --no-auto-update and upgrade manually during maintenance windows'
|
|
102
|
+
- 'Monitor runner systemd units with alerting on failed states before jobs queue up'
|
|
103
|
+
- 'Use ephemeral runners (--ephemeral flag) so each job gets a freshly registered runner, avoiding accumulated update corruption'
|
|
104
|
+
- 'After any auto-update event, verify that bin/runsvc.sh is non-zero before accepting production jobs'
|
|
105
|
+
- 'Run a nightly canary workflow that exercises a restart-then-run cycle on self-hosted pools'
|
|
106
|
+
docs:
|
|
107
|
+
- url: 'https://github.com/actions/runner/issues/4421'
|
|
108
|
+
label: 'runner#4421: runsvc.sh sometimes 0 bytes after auto-update from 2.328.0 to 2.334.0 (May 2026)'
|
|
109
|
+
- url: 'https://docs.github.com/en/actions/hosting-your-own-runners/managing-self-hosted-runners/autoscaling-with-self-hosted-runners'
|
|
110
|
+
label: 'Autoscaling with self-hosted runners — runner lifecycle management'
|
|
111
|
+
- url: 'https://docs.github.com/en/actions/hosting-your-own-runners/managing-self-hosted-runners/about-self-hosted-runners#self-hosted-runner-version-updates'
|
|
112
|
+
label: 'Self-hosted runner version updates'
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
id: runner-environment-093
|
|
2
|
+
title: ubuntu-latest Now Points to Ubuntu 24.04 — Python 2 and Legacy Packages Removed
|
|
3
|
+
category: runner-environment
|
|
4
|
+
severity: error
|
|
5
|
+
tags:
|
|
6
|
+
- ubuntu-latest
|
|
7
|
+
- ubuntu-24-04
|
|
8
|
+
- python2
|
|
9
|
+
- apt-get
|
|
10
|
+
- runner-migration
|
|
11
|
+
patterns:
|
|
12
|
+
- regex: 'E: Package ''python'' has no installation candidate'
|
|
13
|
+
flags: i
|
|
14
|
+
- regex: 'python: command not found'
|
|
15
|
+
flags: i
|
|
16
|
+
- regex: 'Unable to locate package python2'
|
|
17
|
+
flags: i
|
|
18
|
+
- regex: 'E: Package ''libssl1\.1'' has no installation candidate'
|
|
19
|
+
flags: i
|
|
20
|
+
error_messages:
|
|
21
|
+
- "E: Package 'python' has no installation candidate"
|
|
22
|
+
- "python: command not found"
|
|
23
|
+
- "Unable to locate package python2"
|
|
24
|
+
- "E: Package 'libssl1.1' has no installation candidate"
|
|
25
|
+
root_cause: |
|
|
26
|
+
GitHub changed ubuntu-latest to point to Ubuntu 24.04 on November 7, 2024
|
|
27
|
+
(announced via GitHub Changelog on September 25, 2024). Ubuntu 24.04 (Noble
|
|
28
|
+
Numbat) removes several packages that were present on Ubuntu 20.04 and 22.04:
|
|
29
|
+
|
|
30
|
+
- The `python` package (Python 2.7) is entirely absent; only `python3` is available
|
|
31
|
+
- `python2` and `python-is-python2` are not installable via apt
|
|
32
|
+
- `libssl1.1` (OpenSSL 1.1.x) is removed; only OpenSSL 3.x ships with 24.04
|
|
33
|
+
- Various other legacy apt packages dropped in the 24.04 LTS release
|
|
34
|
+
|
|
35
|
+
Workflows that ran `sudo apt-get install python`, invoked `python script.py`
|
|
36
|
+
(instead of `python3`), or installed packages transitively depending on
|
|
37
|
+
libssl1.1 started failing immediately after the image switch.
|
|
38
|
+
fix: |
|
|
39
|
+
Option 1: Replace all `python` calls with `python3` and use `actions/setup-python`
|
|
40
|
+
to install a specific Python 3 version rather than relying on the system default.
|
|
41
|
+
|
|
42
|
+
Option 2: Pin the runner to `ubuntu-22.04` explicitly if Python 2 is genuinely
|
|
43
|
+
required or if you need time to migrate. Note that ubuntu-22.04 will eventually
|
|
44
|
+
be retired from the GitHub-hosted runner fleet.
|
|
45
|
+
|
|
46
|
+
Audit all `apt-get install` steps for packages removed in Ubuntu 24.04, including
|
|
47
|
+
libssl1.1, python2, python-is-python2, libffi7, and others listed in the Ubuntu
|
|
48
|
+
24.04 release notes.
|
|
49
|
+
fix_code:
|
|
50
|
+
- language: yaml
|
|
51
|
+
label: Use actions/setup-python and replace python with python3
|
|
52
|
+
code: |
|
|
53
|
+
- uses: actions/setup-python@v5
|
|
54
|
+
with:
|
|
55
|
+
python-version: '3.12'
|
|
56
|
+
|
|
57
|
+
- name: Run script
|
|
58
|
+
run: python3 script.py
|
|
59
|
+
|
|
60
|
+
- language: yaml
|
|
61
|
+
label: Pin explicit runner version to avoid ubuntu-latest drift
|
|
62
|
+
code: |
|
|
63
|
+
jobs:
|
|
64
|
+
build:
|
|
65
|
+
runs-on: ubuntu-22.04 # explicit version; do not rely on ubuntu-latest
|
|
66
|
+
prevention:
|
|
67
|
+
- "Pin explicit runner versions (ubuntu-22.04, ubuntu-24.04) instead of ubuntu-latest to prevent surprise image changes"
|
|
68
|
+
- "Use actions/setup-python for all Python installs rather than apt-get"
|
|
69
|
+
- "Replace python with python3 in all shell commands and scripts"
|
|
70
|
+
- "Subscribe to GitHub Changelog for runner image update announcements before they take effect"
|
|
71
|
+
docs:
|
|
72
|
+
- url: https://github.blog/changelog/2024-09-25-actions-new-images-and-ubuntu-latest-changes/
|
|
73
|
+
label: "GitHub Changelog: ubuntu-latest points to Ubuntu 24.04 (Sep 2024)"
|
|
74
|
+
- url: https://docs.github.com/en/actions/using-github-hosted-runners/using-github-hosted-runners/about-github-hosted-runners
|
|
75
|
+
label: "GitHub-hosted runner images documentation"
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
id: silent-failures-042
|
|
2
|
+
title: Fork pull_request Secrets Are Empty Strings — Secret-Gated Steps Silently Skip
|
|
3
|
+
category: silent-failures
|
|
4
|
+
severity: silent-failure
|
|
5
|
+
tags:
|
|
6
|
+
- fork
|
|
7
|
+
- pull-request
|
|
8
|
+
- secrets
|
|
9
|
+
- empty-string
|
|
10
|
+
- conditional-step
|
|
11
|
+
patterns:
|
|
12
|
+
- regex: 'secrets\.[A-Z_]+ != ''''.*if.*condition'
|
|
13
|
+
flags: i
|
|
14
|
+
- regex: 'npm ERR! code E401'
|
|
15
|
+
flags: ''
|
|
16
|
+
- regex: 'Error: HttpError: Resource not accessible by integration'
|
|
17
|
+
flags: i
|
|
18
|
+
error_messages:
|
|
19
|
+
- "npm ERR! code E401"
|
|
20
|
+
- "Error: HttpError: Resource not accessible by integration"
|
|
21
|
+
- "(No log output — the step shows 'skipped' status when secrets.MY_TOKEN != '' evaluates false on fork PRs)"
|
|
22
|
+
root_cause: |
|
|
23
|
+
When a pull_request event is triggered from a fork, GitHub Actions intentionally
|
|
24
|
+
provides empty strings ("") for all secrets in the `secrets` context — not null,
|
|
25
|
+
but empty string. This is a security measure to prevent secret exfiltration from
|
|
26
|
+
untrusted fork code running in the base repository's context.
|
|
27
|
+
|
|
28
|
+
The silent-failure pattern occurs when a workflow guards a step with a secrets
|
|
29
|
+
check:
|
|
30
|
+
|
|
31
|
+
- if: ${{ secrets.NPM_TOKEN != '' }}
|
|
32
|
+
run: npm publish
|
|
33
|
+
|
|
34
|
+
On fork PRs, `secrets.NPM_TOKEN` is `""`, so the condition evaluates to `false`
|
|
35
|
+
and the step is silently skipped with no error, no warning, and no indication
|
|
36
|
+
in normal logs. Developers expecting either a published artifact or a clear
|
|
37
|
+
failure instead see a green workflow with a quietly skipped deploy step.
|
|
38
|
+
|
|
39
|
+
A related failure mode: when the empty secret IS used directly (without a guard),
|
|
40
|
+
the downstream tool emits a generic auth error (E401, 403) that gives no indication
|
|
41
|
+
the root cause is an empty secret from a fork trigger.
|
|
42
|
+
fix: |
|
|
43
|
+
Separate concerns: run untrusted fork code in a `pull_request` workflow (no
|
|
44
|
+
secrets needed), then gate secret-requiring operations on a `workflow_run`
|
|
45
|
+
workflow that triggers after the pull_request workflow completes. The
|
|
46
|
+
workflow_run event runs in the base branch context and has full access to
|
|
47
|
+
repository secrets.
|
|
48
|
+
|
|
49
|
+
If you must use secrets in a `pull_request` workflow (e.g., to post PR comments
|
|
50
|
+
via GITHUB_TOKEN), rely on the automatically-provided GITHUB_TOKEN with
|
|
51
|
+
appropriate `permissions:` — do not depend on user-defined secrets in
|
|
52
|
+
pull_request context from forks.
|
|
53
|
+
|
|
54
|
+
Avoid the `if: ${{ secrets.MY_SECRET != '' }}` guard pattern entirely;
|
|
55
|
+
document the fork limitation explicitly in the workflow file instead.
|
|
56
|
+
fix_code:
|
|
57
|
+
- language: yaml
|
|
58
|
+
label: "Split pattern: pull_request for tests (no secrets), workflow_run for deploys"
|
|
59
|
+
code: |
|
|
60
|
+
# pr-tests.yml — runs untrusted fork code, no secrets needed
|
|
61
|
+
on: pull_request
|
|
62
|
+
jobs:
|
|
63
|
+
test:
|
|
64
|
+
runs-on: ubuntu-latest
|
|
65
|
+
steps:
|
|
66
|
+
- uses: actions/checkout@v4
|
|
67
|
+
- run: npm ci && npm test
|
|
68
|
+
|
|
69
|
+
- language: yaml
|
|
70
|
+
label: workflow_run continuation with secrets (runs in base branch context)
|
|
71
|
+
code: |
|
|
72
|
+
# pr-deploy.yml — triggers after pr-tests completes; has full secret access
|
|
73
|
+
on:
|
|
74
|
+
workflow_run:
|
|
75
|
+
workflows: [PR Tests]
|
|
76
|
+
types: [completed]
|
|
77
|
+
jobs:
|
|
78
|
+
publish:
|
|
79
|
+
if: ${{ github.event.workflow_run.conclusion == 'success' }}
|
|
80
|
+
runs-on: ubuntu-latest
|
|
81
|
+
steps:
|
|
82
|
+
- uses: actions/checkout@v4
|
|
83
|
+
- run: npm publish
|
|
84
|
+
env:
|
|
85
|
+
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
|
|
86
|
+
prevention:
|
|
87
|
+
- "Never write if: ${{ secrets.MY_SECRET != '' }} as a fork guard — this silently evaluates false on all fork PRs"
|
|
88
|
+
- "Use the pull_request + workflow_run split pattern for any workflow needing both fork code and repository secrets"
|
|
89
|
+
- "Add a comment in your workflow file explaining that secret-gated steps intentionally skip on fork PRs"
|
|
90
|
+
- "Use GITHUB_TOKEN with explicit permissions: blocks for operations that only require base repository access"
|
|
91
|
+
docs:
|
|
92
|
+
- url: https://docs.github.com/en/actions/security-for-github-actions/security-guides/security-hardening-for-github-actions#using-secrets
|
|
93
|
+
label: "GitHub Docs: Security hardening for GitHub Actions — using secrets"
|
|
94
|
+
- url: https://securitylab.github.com/resources/github-actions-preventing-pwn-requests/
|
|
95
|
+
label: "GitHub Security Lab: Preventing pwn requests (pull_request_target risks)"
|
|
96
|
+
- url: https://docs.github.com/en/actions/writing-workflows/choosing-when-your-workflow-runs/events-that-trigger-workflows#workflow_run
|
|
97
|
+
label: "GitHub Docs: workflow_run event"
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
id: silent-failures-043
|
|
2
|
+
title: 'github.workspace and runner.workspace return host paths, not container paths, inside container jobs'
|
|
3
|
+
category: silent-failures
|
|
4
|
+
severity: silent-failure
|
|
5
|
+
tags:
|
|
6
|
+
- container-jobs
|
|
7
|
+
- github-context
|
|
8
|
+
- workspace
|
|
9
|
+
- path-mismatch
|
|
10
|
+
- expressions
|
|
11
|
+
- silent
|
|
12
|
+
patterns:
|
|
13
|
+
- regex: '\$\{\{\s*github\.workspace\s*\}\}.*container|\$\{\{\s*runner\.workspace\s*\}\}.*container'
|
|
14
|
+
flags: 'i'
|
|
15
|
+
- regex: '/home/runner/work/[^/]+/[^/]+.*no such file|not found.*home/runner/work'
|
|
16
|
+
flags: 'i'
|
|
17
|
+
error_messages: []
|
|
18
|
+
root_cause: |
|
|
19
|
+
Inside container jobs, `${{ github.workspace }}` and `${{ runner.workspace }}`
|
|
20
|
+
resolve to the HOST-side path (e.g., /home/runner/work/repo/repo), not the
|
|
21
|
+
path that the container actually sees at runtime (e.g., /github/workspace or
|
|
22
|
+
/__w/repo/repo depending on the runner type).
|
|
23
|
+
|
|
24
|
+
The container mounts the workspace at a different path than the host. Any
|
|
25
|
+
expression using these context values to construct file paths, Docker build
|
|
26
|
+
contexts, artifact paths, or shell script arguments will silently resolve to
|
|
27
|
+
the wrong location inside the container — either a non-existent path or an
|
|
28
|
+
unexpected host directory leaked into the container mount namespace.
|
|
29
|
+
|
|
30
|
+
By contrast, the GITHUB_WORKSPACE and RUNNER_WORKSPACE environment variables
|
|
31
|
+
ARE injected with the correct container-visible paths. Only the expression
|
|
32
|
+
context values (${{ github.workspace }}) are wrong. This inconsistency is the
|
|
33
|
+
core trap: developers expect context and env var to be equivalent, but inside
|
|
34
|
+
containers they diverge.
|
|
35
|
+
|
|
36
|
+
No error is raised — wrong paths are silently accepted by shells and tools,
|
|
37
|
+
causing subtly incorrect behavior: files not found, wrong directory used for
|
|
38
|
+
builds, artifacts uploaded from wrong paths, or test results pointing to
|
|
39
|
+
non-existent locations.
|
|
40
|
+
|
|
41
|
+
Tracked in runner#2058 (81 reactions, 13 confused reactions) as a known bug
|
|
42
|
+
with no built-in fix as of 2026.
|
|
43
|
+
fix: |
|
|
44
|
+
Use the GITHUB_WORKSPACE environment variable instead of the
|
|
45
|
+
${{ github.workspace }} expression inside container job steps. The env var
|
|
46
|
+
is injected by the runner with the correct container-visible path.
|
|
47
|
+
|
|
48
|
+
Similarly, use RUNNER_WORKSPACE instead of ${{ runner.workspace }}.
|
|
49
|
+
|
|
50
|
+
For Docker build contexts and tool paths that require absolute paths, use
|
|
51
|
+
the container-visible path directly:
|
|
52
|
+
- GitHub-hosted runners: /github/workspace
|
|
53
|
+
- ARC/self-hosted: /__w/<repo-name>/<repo-name> (verify with pwd in first step)
|
|
54
|
+
|
|
55
|
+
Alternatively, use relative paths (.) wherever possible to avoid the
|
|
56
|
+
host/container path discrepancy entirely.
|
|
57
|
+
fix_code:
|
|
58
|
+
- language: yaml
|
|
59
|
+
label: 'Use GITHUB_WORKSPACE env var instead of ${{ github.workspace }} inside container steps'
|
|
60
|
+
code: |
|
|
61
|
+
jobs:
|
|
62
|
+
build:
|
|
63
|
+
runs-on: ubuntu-latest
|
|
64
|
+
container:
|
|
65
|
+
image: myapp-builder:latest
|
|
66
|
+
steps:
|
|
67
|
+
- uses: actions/checkout@v4
|
|
68
|
+
|
|
69
|
+
# WRONG: returns host path, not the container-visible mount path
|
|
70
|
+
# - name: Build
|
|
71
|
+
# run: cd "${{ github.workspace }}" && make build
|
|
72
|
+
|
|
73
|
+
# CORRECT: GITHUB_WORKSPACE is set to the container-visible path
|
|
74
|
+
- name: Build
|
|
75
|
+
run: |
|
|
76
|
+
echo "Container workspace: $GITHUB_WORKSPACE"
|
|
77
|
+
cd "$GITHUB_WORKSPACE" && make build
|
|
78
|
+
- language: yaml
|
|
79
|
+
label: 'Use relative paths for Docker build context inside container jobs'
|
|
80
|
+
code: |
|
|
81
|
+
jobs:
|
|
82
|
+
docker-in-docker:
|
|
83
|
+
runs-on: ubuntu-latest
|
|
84
|
+
container:
|
|
85
|
+
image: docker:24
|
|
86
|
+
steps:
|
|
87
|
+
- uses: actions/checkout@v4
|
|
88
|
+
- name: Build image
|
|
89
|
+
run: |
|
|
90
|
+
# Use . (current dir) not ${{ github.workspace }} for build context
|
|
91
|
+
docker build -t myimage:latest .
|
|
92
|
+
|
|
93
|
+
# If absolute path needed, use the env var:
|
|
94
|
+
docker build -t myimage:latest "$GITHUB_WORKSPACE"
|
|
95
|
+
- language: yaml
|
|
96
|
+
label: 'Debug step to reveal the actual container workspace path'
|
|
97
|
+
code: |
|
|
98
|
+
jobs:
|
|
99
|
+
debug:
|
|
100
|
+
runs-on: ubuntu-latest
|
|
101
|
+
container:
|
|
102
|
+
image: ubuntu:22.04
|
|
103
|
+
steps:
|
|
104
|
+
- name: Show path discrepancy
|
|
105
|
+
run: |
|
|
106
|
+
echo "Host path via context (WRONG inside container):"
|
|
107
|
+
echo " github.workspace = ${{ github.workspace }}"
|
|
108
|
+
echo ""
|
|
109
|
+
echo "Container-visible path via env var (CORRECT):"
|
|
110
|
+
echo " GITHUB_WORKSPACE = $GITHUB_WORKSPACE"
|
|
111
|
+
echo ""
|
|
112
|
+
echo "Actual current directory: $(pwd)"
|
|
113
|
+
prevention:
|
|
114
|
+
- 'Never use ${{ github.workspace }} or ${{ runner.workspace }} expressions inside container job steps — they return host paths'
|
|
115
|
+
- 'Use the GITHUB_WORKSPACE and RUNNER_WORKSPACE environment variables for all path references inside containers'
|
|
116
|
+
- 'Use relative paths wherever possible in container steps to avoid the host/container path mismatch entirely'
|
|
117
|
+
- 'Add a debug step printing both the context value and the env var when authoring new container workflows'
|
|
118
|
+
- 'Test container-based workflows locally with nektos/act to surface path resolution issues before CI'
|
|
119
|
+
docs:
|
|
120
|
+
- url: 'https://github.com/actions/runner/issues/2058'
|
|
121
|
+
label: 'runner#2058: github.workspace and runner.workspace are incorrect inside container jobs (81 reactions)'
|
|
122
|
+
- url: 'https://docs.github.com/en/actions/writing-workflows/choosing-where-your-workflow-runs/running-jobs-in-a-container'
|
|
123
|
+
label: 'Running jobs in a container — environment variables and context values'
|
package/package.json
CHANGED