@htekdev/actions-debugger 1.0.111 → 1.0.112
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/buildkit-gha-cache-legacy-api-v1-self-hosted.yml +123 -0
- package/errors/concurrency-timing/merge-group-pr-number-concurrency-null-collapse.yml +85 -0
- package/errors/concurrency-timing/push-schedule-shared-concurrency-silent-cancel.yml +84 -0
- package/errors/known-unsolved/vars-context-reusable-workflow-reflects-caller-repo.yml +91 -0
- package/errors/permissions-auth/security-events-write-required-for-sarif-upload.yml +104 -0
- package/errors/runner-environment/runner-environment-180.yml +132 -0
- package/errors/runner-environment/runner-environment-181.yml +114 -0
- package/errors/runner-environment/setup-java-sudo-strips-java-home-env-reset.yml +111 -0
- package/errors/runner-environment/setup-python-free-threaded-arm64-broken-symlink.yml +98 -0
- package/errors/runner-environment/sparse-checkout-cone-mode-not-honored-git-pre-237.yml +121 -0
- package/errors/silent-failures/silent-failures-099.yml +104 -0
- package/errors/silent-failures/sparse-checkout-non-cone-gitignore-depth-extra-paths.yml +96 -0
- package/errors/silent-failures/upload-download-artifact-silent-failure-windows-heap-corruption.yml +90 -0
- package/package.json +1 -1
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
id: runner-environment-181
|
|
2
|
+
title: 'Self-hosted Windows runner steps stuck "Waiting for a runner to pick up this job..." mid-job after v2.321.0 auto-update'
|
|
3
|
+
category: runner-environment
|
|
4
|
+
severity: error
|
|
5
|
+
tags:
|
|
6
|
+
- self-hosted
|
|
7
|
+
- windows
|
|
8
|
+
- runner-update
|
|
9
|
+
- stuck
|
|
10
|
+
- queued
|
|
11
|
+
- multi-step
|
|
12
|
+
- message-queue
|
|
13
|
+
patterns:
|
|
14
|
+
- regex: 'Waiting for a runner to pick up this job'
|
|
15
|
+
flags: 'i'
|
|
16
|
+
- regex: 'Current runner version.*2\.32[1-9]|v2\.32[1-9]\.'
|
|
17
|
+
flags: 'i'
|
|
18
|
+
error_messages:
|
|
19
|
+
- "Waiting for a runner to pick up this job..."
|
|
20
|
+
root_cause: |
|
|
21
|
+
After the GitHub Actions runner auto-updated to v2.321.0 (released November 2024),
|
|
22
|
+
Windows self-hosted runners began exhibiting a specific failure mode in multi-step
|
|
23
|
+
jobs: the first step of a job executes successfully, but subsequent steps hang
|
|
24
|
+
indefinitely in a queued state showing "Waiting for a runner to pick up this job..."
|
|
25
|
+
|
|
26
|
+
Root cause: The v2.321.0 update introduced a regression in the Windows runner's
|
|
27
|
+
inter-step message queue session management. After completing a step, the runner
|
|
28
|
+
sends a completion signal to the GitHub broker but fails to maintain the job session
|
|
29
|
+
channel open for the next step. GitHub's broker interprets the broken session as
|
|
30
|
+
the job needing a fresh runner allocation — hence the "waiting for runner" message
|
|
31
|
+
for a job that is technically already in-flight.
|
|
32
|
+
|
|
33
|
+
The runner service itself remains running and reports "idle" to GitHub, but the job
|
|
34
|
+
session token has already been invalidated or the queue socket closed. Restarting
|
|
35
|
+
the runner service re-establishes the connection and any subsequent cancel+rerun
|
|
36
|
+
immediately picks up because the session management is freshly initialized.
|
|
37
|
+
|
|
38
|
+
Characteristics:
|
|
39
|
+
- Specific to Windows self-hosted runners (not Ubuntu/macOS hosted runners)
|
|
40
|
+
- Only occurs in jobs with 2 or more steps
|
|
41
|
+
- Step 1 always completes; step 2+ hangs without timeout
|
|
42
|
+
- Cancel + rerun of the stuck job resolves it immediately
|
|
43
|
+
- Runner service restart also resolves it
|
|
44
|
+
- Began appearing after Nov 27, 2024 auto-update on Windows machines
|
|
45
|
+
- Still open as of May 2026 with 90+ reactions (actions/runner#3609)
|
|
46
|
+
|
|
47
|
+
Note: This is distinct from runner-environment-082 (runner stuck between JOBS in
|
|
48
|
+
the same workflow) — this failure occurs between STEPS within a single job.
|
|
49
|
+
fix: |
|
|
50
|
+
Immediate mitigation:
|
|
51
|
+
1. Cancel the stuck run in the GitHub Actions UI and re-run it — the job typically
|
|
52
|
+
completes correctly on rerun because the session is re-initialized.
|
|
53
|
+
2. Restart the GitHub Actions runner service on the Windows host between runs:
|
|
54
|
+
Restart-Service -Name "actions.runner.*"
|
|
55
|
+
(replace wildcard with the actual runner service name from services.msc)
|
|
56
|
+
|
|
57
|
+
Permanent mitigation:
|
|
58
|
+
3. Upgrade the runner to the latest version (v2.334.0+) which includes session
|
|
59
|
+
management improvements. Check https://github.com/actions/runner/releases for
|
|
60
|
+
the latest stable version.
|
|
61
|
+
4. Disable auto-update and pin to a known-good runner version by setting
|
|
62
|
+
`RUNNER_ALLOW_RUNASROOT=false` and specifying the version in your runner
|
|
63
|
+
configuration script.
|
|
64
|
+
5. If operating ARC (Actions Runner Controller), upgrade the controller to use a
|
|
65
|
+
runner image version 2.334.0+ to pick up the fix.
|
|
66
|
+
fix_code:
|
|
67
|
+
- language: yaml
|
|
68
|
+
label: 'Workflow with restart-runner step for self-hosted Windows runners (workaround)'
|
|
69
|
+
code: |
|
|
70
|
+
# Workaround: add a pre-step that verifies the runner session is healthy.
|
|
71
|
+
# This forces a new session token for each major step block.
|
|
72
|
+
jobs:
|
|
73
|
+
build:
|
|
74
|
+
runs-on: [self-hosted, windows]
|
|
75
|
+
steps:
|
|
76
|
+
- name: Verify runner session (workaround for runner#3609)
|
|
77
|
+
run: Write-Host "Runner session active — version $env:RUNNER_VERSION"
|
|
78
|
+
shell: pwsh
|
|
79
|
+
|
|
80
|
+
- uses: actions/checkout@v4
|
|
81
|
+
|
|
82
|
+
- name: Build
|
|
83
|
+
run: dotnet build
|
|
84
|
+
shell: pwsh
|
|
85
|
+
- language: yaml
|
|
86
|
+
label: 'Script to upgrade self-hosted runner to latest version on Windows'
|
|
87
|
+
code: |
|
|
88
|
+
# Run on each Windows runner host to upgrade to the latest runner version.
|
|
89
|
+
# Execute from PowerShell as Administrator.
|
|
90
|
+
|
|
91
|
+
# Stop the runner service
|
|
92
|
+
Stop-Service -Name "actions.runner.*" -Force
|
|
93
|
+
|
|
94
|
+
# Download and replace the runner binary
|
|
95
|
+
$version = (Invoke-RestMethod "https://api.github.com/repos/actions/runner/releases/latest").tag_name.TrimStart('v')
|
|
96
|
+
Invoke-WebRequest "https://github.com/actions/runner/releases/download/v$version/actions-runner-win-x64-$version.zip" -OutFile runner.zip
|
|
97
|
+
Expand-Archive runner.zip -DestinationPath . -Force
|
|
98
|
+
|
|
99
|
+
# Restart the service
|
|
100
|
+
Start-Service -Name "actions.runner.*"
|
|
101
|
+
Write-Host "Runner upgraded to v$version"
|
|
102
|
+
prevention:
|
|
103
|
+
- 'Keep self-hosted runners updated to the latest runner version — regression fixes are frequent'
|
|
104
|
+
- 'Monitor runner logs at _diag/Runner_*.log for session/message-queue errors between steps'
|
|
105
|
+
- 'Set up automatic runner version checks in your infrastructure pipeline'
|
|
106
|
+
- 'For critical pipelines, disable auto-update and pin to a tested runner version then upgrade on schedule'
|
|
107
|
+
- 'On Windows hosts, ensure the runner service account has rights to re-establish named pipe connections between steps'
|
|
108
|
+
docs:
|
|
109
|
+
- url: 'https://github.com/actions/runner/issues/3609'
|
|
110
|
+
label: 'actions/runner#3609: Self-hosted runner stuck "Waiting for runner" in multi-step jobs (90 reactions, open Dec 2024)'
|
|
111
|
+
- url: 'https://github.com/actions/runner/releases'
|
|
112
|
+
label: 'GitHub Actions Runner releases — check for v2.321.0 regression fixes'
|
|
113
|
+
- url: 'https://docs.github.com/en/actions/hosting-your-own-runners/managing-self-hosted-runners/about-self-hosted-runners'
|
|
114
|
+
label: 'GitHub Docs: About self-hosted runners'
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
id: runner-environment-183
|
|
2
|
+
title: "setup-java JAVA_HOME stripped by sudo env_reset on Ubuntu — wrong JDK used silently"
|
|
3
|
+
category: runner-environment
|
|
4
|
+
severity: silent-failure
|
|
5
|
+
tags:
|
|
6
|
+
- setup-java
|
|
7
|
+
- sudo
|
|
8
|
+
- java
|
|
9
|
+
- ubuntu
|
|
10
|
+
- env-reset
|
|
11
|
+
- sudoers
|
|
12
|
+
- java-home
|
|
13
|
+
patterns:
|
|
14
|
+
- regex: 'error: invalid target release: \d+'
|
|
15
|
+
flags: 'i'
|
|
16
|
+
- regex: '(bad source file|class file has wrong version).*\d+\.\d+'
|
|
17
|
+
flags: 'i'
|
|
18
|
+
error_messages:
|
|
19
|
+
- "error: invalid target release: 25"
|
|
20
|
+
- "error: invalid target release: 21"
|
|
21
|
+
- "error: invalid target release: 23"
|
|
22
|
+
- "class file has wrong version"
|
|
23
|
+
root_cause: |
|
|
24
|
+
Ubuntu's sudoers policy includes `env_reset` and `secure_path` by default. When a
|
|
25
|
+
workflow step runs any command via `sudo` (e.g., `sudo apt-get install ...`,
|
|
26
|
+
`sudo ant build`, `sudo mvn package`), the environment is completely reset: PATH
|
|
27
|
+
reverts to the sudoers secure_path and JAVA_HOME is cleared.
|
|
28
|
+
|
|
29
|
+
Because the runner image has JDK 17 registered as the system default via
|
|
30
|
+
`update-alternatives`, any subsequent Java invocation under sudo — including
|
|
31
|
+
tool-wrapped invocations via Debian-packaged `ant` (which uses `java-wrappers.sh`
|
|
32
|
+
to detect Java through system alternatives) — silently uses JDK 17 regardless of
|
|
33
|
+
what `actions/setup-java` configured.
|
|
34
|
+
|
|
35
|
+
This causes silent failures when the build silently compiles against JDK 17 and
|
|
36
|
+
produces wrong artifacts, and explicit errors when the requested JDK is newer
|
|
37
|
+
than 17 and javac refuses with "error: invalid target release: N".
|
|
38
|
+
|
|
39
|
+
The root cause is not a bug in setup-java — it correctly sets JAVA_HOME and PATH
|
|
40
|
+
via $GITHUB_ENV / $GITHUB_PATH, which only apply to non-sudo process contexts.
|
|
41
|
+
Ubuntu's sudoers env_reset is OS-level behaviour that strips those env variables.
|
|
42
|
+
fix: |
|
|
43
|
+
1. Pass JAVACMD explicitly to sudo: `sudo JAVACMD=$JAVA_HOME/bin/java ant ...`
|
|
44
|
+
(Debian-packaged ant reads JAVACMD before system alternatives)
|
|
45
|
+
2. Register the setup-java JDK as the system default before any sudo steps:
|
|
46
|
+
sudo update-alternatives --install /usr/bin/java java "$JAVA_HOME/bin/java" 2000
|
|
47
|
+
sudo update-alternatives --set java "$JAVA_HOME/bin/java"
|
|
48
|
+
3. Avoid running Java build tools via sudo entirely — install build dependencies
|
|
49
|
+
first, then run the build as the runner user (without sudo).
|
|
50
|
+
4. Use `sudo -E` to preserve the current environment (requires sudoers NOPASSWD
|
|
51
|
+
with env_keep or SETENV; not available by default on GitHub-hosted runners).
|
|
52
|
+
fix_code:
|
|
53
|
+
- language: yaml
|
|
54
|
+
label: "Workaround: pass JAVACMD explicitly to sudo ant/maven"
|
|
55
|
+
code: |
|
|
56
|
+
- name: Setup Java
|
|
57
|
+
uses: actions/setup-java@v4
|
|
58
|
+
with:
|
|
59
|
+
java-version: '25'
|
|
60
|
+
distribution: temurin
|
|
61
|
+
|
|
62
|
+
# Debian ant uses java-wrappers which ignores JAVA_HOME — pass JAVACMD directly
|
|
63
|
+
- name: Build with ant (sudo)
|
|
64
|
+
run: sudo JAVACMD=$JAVA_HOME/bin/java ant build
|
|
65
|
+
|
|
66
|
+
- language: yaml
|
|
67
|
+
label: "Workaround: register JDK as system default before sudo steps"
|
|
68
|
+
code: |
|
|
69
|
+
- name: Setup Java
|
|
70
|
+
uses: actions/setup-java@v4
|
|
71
|
+
with:
|
|
72
|
+
java-version: '25'
|
|
73
|
+
distribution: temurin
|
|
74
|
+
|
|
75
|
+
- name: Register JDK as system default (for sudo)
|
|
76
|
+
run: |
|
|
77
|
+
sudo update-alternatives --install /usr/bin/java java "$JAVA_HOME/bin/java" 2000
|
|
78
|
+
sudo update-alternatives --set java "$JAVA_HOME/bin/java"
|
|
79
|
+
sudo update-alternatives --install /usr/bin/javac javac "$JAVA_HOME/bin/javac" 2000
|
|
80
|
+
sudo update-alternatives --set javac "$JAVA_HOME/bin/javac"
|
|
81
|
+
|
|
82
|
+
- name: Build (sudo now uses correct JDK)
|
|
83
|
+
run: sudo ant build
|
|
84
|
+
|
|
85
|
+
- language: yaml
|
|
86
|
+
label: "Best practice: separate install from build to avoid sudo"
|
|
87
|
+
code: |
|
|
88
|
+
- name: Install build dependencies
|
|
89
|
+
run: sudo apt-get install -y build-essential
|
|
90
|
+
|
|
91
|
+
- name: Setup Java
|
|
92
|
+
uses: actions/setup-java@v4
|
|
93
|
+
with:
|
|
94
|
+
java-version: '25'
|
|
95
|
+
distribution: temurin
|
|
96
|
+
|
|
97
|
+
# No sudo here — JAVA_HOME is intact
|
|
98
|
+
- name: Build
|
|
99
|
+
run: ant build
|
|
100
|
+
prevention:
|
|
101
|
+
- "Avoid running Java build tools (ant, mvn, gradle) via sudo — install OS dependencies before setup-java, build without sudo"
|
|
102
|
+
- "After setup-java, verify sudo sees the correct JDK: sudo java -version"
|
|
103
|
+
- "For Debian-packaged tools (apt install ant), always pass JAVACMD=$JAVA_HOME/bin/java when invoking via sudo"
|
|
104
|
+
- "If sudo is unavoidable, register the JDK via update-alternatives immediately after setup-java"
|
|
105
|
+
docs:
|
|
106
|
+
- url: "https://github.com/actions/setup-java/issues/997"
|
|
107
|
+
label: "ubuntu-latest uses wrong JDK version under sudo (setup-java#997)"
|
|
108
|
+
- url: "https://github.com/actions/setup-java/pull/1013"
|
|
109
|
+
label: "Update README for Ubuntu sudo JAVA_HOME behavior (setup-java PR#1013)"
|
|
110
|
+
- url: "https://manpages.ubuntu.com/manpages/noble/en/man5/sudoers.5.html"
|
|
111
|
+
label: "sudoers(5) — env_reset and secure_path"
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
id: runner-environment-184
|
|
2
|
+
title: "setup-python free-threaded Python (3.13t/3.14t) on windows-11-arm64 installs broken 0-byte python.exe symlink"
|
|
3
|
+
category: runner-environment
|
|
4
|
+
severity: error
|
|
5
|
+
tags:
|
|
6
|
+
- setup-python
|
|
7
|
+
- free-threaded
|
|
8
|
+
- python
|
|
9
|
+
- windows-11-arm64
|
|
10
|
+
- symlink
|
|
11
|
+
- arm64
|
|
12
|
+
- reparse-point
|
|
13
|
+
patterns:
|
|
14
|
+
- regex: 'Fatal Python error: Failed to import encodings module'
|
|
15
|
+
flags: 'i'
|
|
16
|
+
- regex: 'ModuleNotFoundError: No module named .encodings.'
|
|
17
|
+
flags: 'i'
|
|
18
|
+
- regex: 'Remove-Item.*python\.exe.*does not exist'
|
|
19
|
+
flags: 'i'
|
|
20
|
+
error_messages:
|
|
21
|
+
- "Fatal Python error: Failed to import encodings module"
|
|
22
|
+
- "ModuleNotFoundError: No module named 'encodings'"
|
|
23
|
+
- "Remove-Item : Cannot find path '...\\arm64-freethreaded\\python.exe' because it does not exist."
|
|
24
|
+
- "Error happened during pip installation / upgrade"
|
|
25
|
+
root_cause: |
|
|
26
|
+
The `win32-arm64-freethreaded` distribution zip for Python 3.13t and 3.14t packages
|
|
27
|
+
`python.exe` and `python3.exe` as Windows reparse points (symlinks) pointing to
|
|
28
|
+
`python3.13t.exe` / `python3.14t.exe`.
|
|
29
|
+
|
|
30
|
+
When actions/setup-python extracts and copies the zip contents to the tool cache on
|
|
31
|
+
`windows-11-arm64`, the symlink target is not found at the expected relative path —
|
|
32
|
+
the copy operation leaves a dangling 0-byte reparse point (`-a---l 0 python.exe`)
|
|
33
|
+
instead of a real executable.
|
|
34
|
+
|
|
35
|
+
`setup.ps1:131` then fails to Remove-Item the dangling reparse point (PowerShell
|
|
36
|
+
cannot delete it because the path resolves as non-existent), and the tool cache
|
|
37
|
+
entry has no working Python interpreter. When the action invokes the installed
|
|
38
|
+
python, it immediately crashes with "Fatal Python error: Failed to import encodings
|
|
39
|
+
module" because the 0-byte stub cannot locate its stdlib.
|
|
40
|
+
|
|
41
|
+
Non-free-threaded arm64 builds (3.11, 3.12, 3.13, 3.14) are not affected — only
|
|
42
|
+
the `*t` (free-threaded / GIL-free) variants hit this issue on windows-11-arm64.
|
|
43
|
+
fix: |
|
|
44
|
+
1. Workaround: Use the non-free-threaded variant (3.13 instead of 3.13t) unless
|
|
45
|
+
the GIL-free runtime is explicitly required.
|
|
46
|
+
2. Workaround for arm64 only: Install free-threaded Python from NuGet, which
|
|
47
|
+
ships real executables instead of symlinks. Gate on runner.arch == 'ARM64'.
|
|
48
|
+
3. Wait for actions/setup-python to land a fix that correctly resolves Windows
|
|
49
|
+
reparse points in free-threaded zip distributions (tracked in setup-python#1307).
|
|
50
|
+
fix_code:
|
|
51
|
+
- language: yaml
|
|
52
|
+
label: "Workaround: use non-free-threaded Python on windows-11-arm64"
|
|
53
|
+
code: |
|
|
54
|
+
- uses: actions/setup-python@v5
|
|
55
|
+
with:
|
|
56
|
+
# Avoid '3.13t' / '3.14t' on windows-11-arm64 — use standard variant
|
|
57
|
+
python-version: '3.13'
|
|
58
|
+
|
|
59
|
+
- language: yaml
|
|
60
|
+
label: "Workaround: install free-threaded Python via NuGet on ARM64"
|
|
61
|
+
code: |
|
|
62
|
+
- name: Setup Python (non-ARM64)
|
|
63
|
+
if: runner.arch != 'ARM64'
|
|
64
|
+
uses: actions/setup-python@v5
|
|
65
|
+
with:
|
|
66
|
+
python-version: '3.13t'
|
|
67
|
+
|
|
68
|
+
- name: Install free-threaded Python via NuGet (windows-11-arm64 workaround)
|
|
69
|
+
if: runner.os == 'Windows' && runner.arch == 'ARM64'
|
|
70
|
+
run: |
|
|
71
|
+
nuget install python -Version 3.13.3t -OutputDirectory "$env:RUNNER_TEMP\nuget" -NonInteractive
|
|
72
|
+
$pythonDir = Get-ChildItem "$env:RUNNER_TEMP\nuget" -Filter "python.3*" | Select-Object -First 1
|
|
73
|
+
Add-Content $env:GITHUB_PATH "$($pythonDir.FullName)\tools"
|
|
74
|
+
Add-Content $env:GITHUB_PATH "$($pythonDir.FullName)\tools\Scripts"
|
|
75
|
+
|
|
76
|
+
- language: yaml
|
|
77
|
+
label: "Verification step: confirm Python works after setup"
|
|
78
|
+
code: |
|
|
79
|
+
- uses: actions/setup-python@v5
|
|
80
|
+
with:
|
|
81
|
+
python-version: '3.13t'
|
|
82
|
+
|
|
83
|
+
- name: Verify Python installation
|
|
84
|
+
run: |
|
|
85
|
+
python --version
|
|
86
|
+
python -c "import sys; print(sys.version, sys._is_gil_enabled())"
|
|
87
|
+
prevention:
|
|
88
|
+
- "Do not use free-threaded Python variants (3.13t, 3.14t) on windows-11-arm64 until setup-python#1307 is resolved"
|
|
89
|
+
- "Gate free-threaded Python tests: run on ubuntu-latest or windows-latest (x64), avoid windows-11-arm64 for *t variants"
|
|
90
|
+
- "Add a verification step (python -c 'import sys') after setup-python to catch broken installs before test steps"
|
|
91
|
+
- "Follow setup-python#1307 for the official fix — upgrade as soon as a patched version is released"
|
|
92
|
+
docs:
|
|
93
|
+
- url: "https://github.com/actions/setup-python/issues/1307"
|
|
94
|
+
label: "setup-python fails for free-threaded Python (3.13t/3.14t) on windows-11-arm64 (setup-python#1307)"
|
|
95
|
+
- url: "https://github.com/onnx/onnx/pull/7869"
|
|
96
|
+
label: "Install free-threaded Python from NuGet on windows-11-arm (workaround reference)"
|
|
97
|
+
- url: "https://docs.python.org/3.13/whatsnew/3.13.html#free-threaded-cpython"
|
|
98
|
+
label: "Python 3.13 — Free-threaded CPython documentation"
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
id: 'runner-environment-182'
|
|
2
|
+
title: 'actions/checkout sparse-checkout-cone-mode: true not honored when container git < 2.37'
|
|
3
|
+
category: 'runner-environment'
|
|
4
|
+
severity: 'error'
|
|
5
|
+
tags:
|
|
6
|
+
- sparse-checkout
|
|
7
|
+
- cone-mode
|
|
8
|
+
- git-version
|
|
9
|
+
- container
|
|
10
|
+
- checkout
|
|
11
|
+
- self-hosted
|
|
12
|
+
patterns:
|
|
13
|
+
- regex: 'sparse-checkout-cone-mode.*true.*container'
|
|
14
|
+
flags: 'i'
|
|
15
|
+
- regex: 'git.*2\.[12][0-9]\.'
|
|
16
|
+
flags: 'i'
|
|
17
|
+
- regex: 'core\.sparseCheckoutConeMode.*not set'
|
|
18
|
+
flags: 'i'
|
|
19
|
+
error_messages:
|
|
20
|
+
- "Expected full checkout but only subdirectory present"
|
|
21
|
+
- "Sibling files missing from sparse checkout cone"
|
|
22
|
+
- "core.sparseCheckoutConeMode"
|
|
23
|
+
root_cause: |
|
|
24
|
+
`actions/checkout` enables sparse-checkout cone mode by setting
|
|
25
|
+
`core.sparseCheckoutConeMode = true` in the git config. However, the
|
|
26
|
+
`git sparse-checkout set` command requires the explicit `--cone` flag to
|
|
27
|
+
activate cone mode in Git versions **before 2.37.0**.
|
|
28
|
+
|
|
29
|
+
Starting with Git 2.37.0, cone mode became the default for `git sparse-checkout`.
|
|
30
|
+
In earlier Git versions, cone mode must be opted into with `--cone`. The
|
|
31
|
+
`actions/checkout` action does NOT pass `--cone` explicitly, so when running
|
|
32
|
+
inside a container image with Git < 2.37 (e.g., `ubuntu:22.04` ships with
|
|
33
|
+
Git 2.34.1), setting `sparse-checkout-cone-mode: true` has no effect.
|
|
34
|
+
|
|
35
|
+
The result is that cone mode is silently ignored. The checkout runs in non-cone
|
|
36
|
+
(gitignore pattern) mode instead, which means:
|
|
37
|
+
- Root-level sibling files that should be included in cone mode are absent
|
|
38
|
+
- Only the exact subdirectory specified is checked out, without the expected
|
|
39
|
+
parent-level files
|
|
40
|
+
- Subsequent steps that depend on root-level files (e.g., package.json, .env,
|
|
41
|
+
Makefile) fail with "file not found" errors that appear unrelated to checkout
|
|
42
|
+
|
|
43
|
+
Reported in actions/checkout#1868 (Aug 2024).
|
|
44
|
+
fix: |
|
|
45
|
+
Option 1 (recommended): Upgrade Git in the container to 2.37.0 or later.
|
|
46
|
+
For containers based on Ubuntu 22.04, install a newer Git via PPA:
|
|
47
|
+
add-apt-repository ppa:git-core/ppa && apt-get install git
|
|
48
|
+
|
|
49
|
+
Option 2: Add an explicit `git sparse-checkout init --cone` step AFTER checkout
|
|
50
|
+
to force cone mode activation retroactively. This is a workaround for containers
|
|
51
|
+
where upgrading Git is not possible.
|
|
52
|
+
|
|
53
|
+
Option 3: Use GitHub-hosted runners (ubuntu-latest, ubuntu-24.04) which ship
|
|
54
|
+
with Git >= 2.43, where cone mode works correctly by default.
|
|
55
|
+
|
|
56
|
+
Option 4: If specific file patterns are required (not just directories), use
|
|
57
|
+
`sparse-checkout-cone-mode: false` with root-anchored `/pattern` patterns
|
|
58
|
+
instead of relying on cone mode.
|
|
59
|
+
fix_code:
|
|
60
|
+
- language: yaml
|
|
61
|
+
label: 'Upgrade git in container before checkout (Ubuntu 22.04 example)'
|
|
62
|
+
code: |
|
|
63
|
+
jobs:
|
|
64
|
+
build:
|
|
65
|
+
runs-on: ubuntu-latest
|
|
66
|
+
container:
|
|
67
|
+
image: ubuntu:22.04
|
|
68
|
+
steps:
|
|
69
|
+
- name: Upgrade git to 2.37+ for sparse-checkout cone mode support
|
|
70
|
+
run: |
|
|
71
|
+
apt-get update -qq
|
|
72
|
+
apt-get install -y software-properties-common
|
|
73
|
+
add-apt-repository -y ppa:git-core/ppa
|
|
74
|
+
apt-get update -qq
|
|
75
|
+
apt-get install -y git
|
|
76
|
+
git --version # Verify >= 2.37
|
|
77
|
+
|
|
78
|
+
- uses: actions/checkout@v4
|
|
79
|
+
with:
|
|
80
|
+
sparse-checkout: |
|
|
81
|
+
src
|
|
82
|
+
config
|
|
83
|
+
sparse-checkout-cone-mode: true # Now honored after Git 2.37+ installed
|
|
84
|
+
- language: yaml
|
|
85
|
+
label: 'Workaround: force --cone after checkout on old Git'
|
|
86
|
+
code: |
|
|
87
|
+
- uses: actions/checkout@v4
|
|
88
|
+
with:
|
|
89
|
+
sparse-checkout: src
|
|
90
|
+
sparse-checkout-cone-mode: true
|
|
91
|
+
|
|
92
|
+
# Explicitly enable cone mode on Git < 2.37 (workaround for actions/checkout#1868)
|
|
93
|
+
- name: Force cone mode on old git
|
|
94
|
+
run: |
|
|
95
|
+
git sparse-checkout init --cone
|
|
96
|
+
git sparse-checkout set src
|
|
97
|
+
- language: yaml
|
|
98
|
+
label: 'Use GitHub-hosted runner to avoid old git versions'
|
|
99
|
+
code: |
|
|
100
|
+
jobs:
|
|
101
|
+
build:
|
|
102
|
+
runs-on: ubuntu-latest # Ships with Git 2.43+ — cone mode works correctly
|
|
103
|
+
steps:
|
|
104
|
+
- uses: actions/checkout@v4
|
|
105
|
+
with:
|
|
106
|
+
sparse-checkout: |
|
|
107
|
+
src
|
|
108
|
+
config
|
|
109
|
+
# sparse-checkout-cone-mode: true # Default, works on ubuntu-latest
|
|
110
|
+
prevention:
|
|
111
|
+
- "Check the git version in container images before relying on sparse-checkout cone mode: run 'git --version' in a workflow step."
|
|
112
|
+
- "Upgrade container base images to Ubuntu 24.04 or Debian 12 which ship with Git >= 2.39."
|
|
113
|
+
- "Pin to GitHub-hosted runners (ubuntu-latest, ubuntu-24.04) for consistent Git versions that support cone mode."
|
|
114
|
+
- "After setting up sparse checkout, add a debug step printing 'git config core.sparseCheckoutConeMode' to verify cone mode is active."
|
|
115
|
+
docs:
|
|
116
|
+
- url: 'https://github.com/actions/checkout/issues/1868'
|
|
117
|
+
label: 'actions/checkout#1868 — sparse-checkout-cone-mode not honored on git < 2.37'
|
|
118
|
+
- url: 'https://git-scm.com/docs/git-sparse-checkout/2.37.0'
|
|
119
|
+
label: 'Git 2.37 release notes — cone mode becomes the default for sparse-checkout'
|
|
120
|
+
- url: 'https://github.com/actions/checkout?tab=readme-ov-file'
|
|
121
|
+
label: 'actions/checkout — sparse-checkout inputs documentation'
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
id: silent-failures-099
|
|
2
|
+
title: 'setup-node registry-url auto-sets NODE_AUTH_TOKEN which blocks npm OIDC provenance publish'
|
|
3
|
+
category: silent-failures
|
|
4
|
+
severity: silent-failure
|
|
5
|
+
tags:
|
|
6
|
+
- setup-node
|
|
7
|
+
- npm
|
|
8
|
+
- oidc
|
|
9
|
+
- provenance
|
|
10
|
+
- NODE_AUTH_TOKEN
|
|
11
|
+
- registry-url
|
|
12
|
+
- publish
|
|
13
|
+
patterns:
|
|
14
|
+
- regex: 'npm publish.*--provenance'
|
|
15
|
+
flags: 'i'
|
|
16
|
+
- regex: 'npm (ERR!|error) code E401'
|
|
17
|
+
flags: 'i'
|
|
18
|
+
- regex: 'NODE_AUTH_TOKEN.*publish|npm.*oidc.*token'
|
|
19
|
+
flags: 'i'
|
|
20
|
+
error_messages:
|
|
21
|
+
- "npm error code E401"
|
|
22
|
+
- "npm error 401 Unauthorized - PUT https://registry.npmjs.org/"
|
|
23
|
+
- "npm publish --provenance"
|
|
24
|
+
root_cause: |
|
|
25
|
+
When actions/setup-node is used with `registry-url`, it automatically generates a
|
|
26
|
+
`.npmrc` file containing `//registry.npmjs.org/:_authToken=${NODE_AUTH_TOKEN}`. This
|
|
27
|
+
binds npm authentication to the NODE_AUTH_TOKEN environment variable at publish time.
|
|
28
|
+
|
|
29
|
+
For npm OIDC publishing (`npm publish --provenance`), npm requires that no
|
|
30
|
+
`_authToken` is set (or that it is empty string), so that npm can use the GitHub
|
|
31
|
+
Actions OIDC token to authenticate and attach a sigstore provenance attestation.
|
|
32
|
+
|
|
33
|
+
However, if NODE_AUTH_TOKEN is present in the environment — even set by setup-node's
|
|
34
|
+
own post-install logic (authutil.ts sets a default value when registry-url is
|
|
35
|
+
provided) — npm uses that token for auth instead of OIDC. This silently bypasses the
|
|
36
|
+
OIDC flow in one of two ways:
|
|
37
|
+
1. NODE_AUTH_TOKEN is set to a valid npm publish token → publish succeeds but
|
|
38
|
+
WITHOUT provenance attestation (silent failure, no error thrown).
|
|
39
|
+
2. NODE_AUTH_TOKEN is set to a wrong/expired value (e.g., GitHub token) → npm
|
|
40
|
+
rejects with E401 Unauthorized, making it seem like a credential problem.
|
|
41
|
+
|
|
42
|
+
Both cases confuse developers who believe setup-node + --provenance "just works".
|
|
43
|
+
The root: setup-node's auto-set NODE_AUTH_TOKEN takes precedence over OIDC.
|
|
44
|
+
|
|
45
|
+
Source: actions/setup-node#1440 (23 reactions, closed May 2026 — setup-node v5+ adds
|
|
46
|
+
a new behavior where OIDC is respected, but pre-v5 or misconfigured workflows still
|
|
47
|
+
hit this).
|
|
48
|
+
fix: |
|
|
49
|
+
Option 1 (recommended — explicit unset in publish step):
|
|
50
|
+
Unset NODE_AUTH_TOKEN in the npm publish step's `env:` block so that OIDC can take
|
|
51
|
+
over. An empty string `""` causes npm to ignore the .npmrc token reference.
|
|
52
|
+
|
|
53
|
+
Option 2: Remove `registry-url` from setup-node if you don't need .npmrc written
|
|
54
|
+
(e.g., when publishing to npmjs.org with OIDC only). setup-node only writes .npmrc
|
|
55
|
+
when registry-url is explicitly set.
|
|
56
|
+
|
|
57
|
+
Option 3: Upgrade to actions/setup-node@v5+ which fixed the default NODE_AUTH_TOKEN
|
|
58
|
+
behavior to not override OIDC when the token is unset.
|
|
59
|
+
|
|
60
|
+
Option 4: Set `auth-token: ""` in the setup-node step (setup-node v5.5.0+).
|
|
61
|
+
fix_code:
|
|
62
|
+
- language: yaml
|
|
63
|
+
label: 'Unset NODE_AUTH_TOKEN in the npm publish step to allow OIDC'
|
|
64
|
+
code: |
|
|
65
|
+
- uses: actions/setup-node@v4
|
|
66
|
+
with:
|
|
67
|
+
node-version: '20'
|
|
68
|
+
registry-url: 'https://registry.npmjs.org'
|
|
69
|
+
|
|
70
|
+
- name: Publish with provenance
|
|
71
|
+
run: npm publish --provenance --access public
|
|
72
|
+
env:
|
|
73
|
+
NODE_AUTH_TOKEN: '' # Explicitly empty so npm uses OIDC instead of token auth
|
|
74
|
+
- language: yaml
|
|
75
|
+
label: 'Correct OIDC provenance publish permissions'
|
|
76
|
+
code: |
|
|
77
|
+
permissions:
|
|
78
|
+
contents: read
|
|
79
|
+
id-token: write # Required for OIDC token — without this npm --provenance fails
|
|
80
|
+
|
|
81
|
+
steps:
|
|
82
|
+
- uses: actions/setup-node@v4
|
|
83
|
+
with:
|
|
84
|
+
node-version: '20'
|
|
85
|
+
registry-url: 'https://registry.npmjs.org'
|
|
86
|
+
|
|
87
|
+
- run: npm publish --provenance --access public
|
|
88
|
+
env:
|
|
89
|
+
NODE_AUTH_TOKEN: ''
|
|
90
|
+
prevention:
|
|
91
|
+
- 'Always set `id-token: write` permission when using npm --provenance OIDC publishing'
|
|
92
|
+
- 'Set `NODE_AUTH_TOKEN: ""` explicitly in the env of the npm publish step when using OIDC'
|
|
93
|
+
- 'Upgrade to actions/setup-node v5+ which corrected the default NODE_AUTH_TOKEN behavior'
|
|
94
|
+
- 'Verify provenance attestation was created: check the package page on npmjs.org for the attestations badge'
|
|
95
|
+
- 'Avoid setting registry-url in setup-node if only using OIDC and no npm install caching is needed'
|
|
96
|
+
docs:
|
|
97
|
+
- url: 'https://github.com/actions/setup-node/issues/1440'
|
|
98
|
+
label: 'actions/setup-node#1440: Don''t default NPM_AUTH_TOKEN to support NPM OIDC (23 reactions, closed May 2026)'
|
|
99
|
+
- url: 'https://docs.npmjs.com/generating-provenance-statements'
|
|
100
|
+
label: 'npm Docs: Generating provenance statements'
|
|
101
|
+
- url: 'https://docs.github.com/en/actions/security-for-github-actions/using-artifact-attestations/using-artifact-attestations-to-establish-provenance-for-builds'
|
|
102
|
+
label: 'GitHub Docs: Artifact attestations for build provenance'
|
|
103
|
+
- url: 'https://github.com/actions/setup-node/blob/main/docs/advanced-usage.md#publish-to-npmjs-and-gpr-with-npm'
|
|
104
|
+
label: 'setup-node advanced usage: publishing to npm'
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
id: 'silent-failures-100'
|
|
2
|
+
title: 'sparse-checkout-cone-mode: false matches file patterns at any depth, checking out unintended paths'
|
|
3
|
+
category: 'silent-failures'
|
|
4
|
+
severity: 'silent-failure'
|
|
5
|
+
tags:
|
|
6
|
+
- sparse-checkout
|
|
7
|
+
- cone-mode
|
|
8
|
+
- gitignore-patterns
|
|
9
|
+
- checkout
|
|
10
|
+
- extra-files
|
|
11
|
+
patterns:
|
|
12
|
+
- regex: 'sparse-checkout-cone-mode:\s*false'
|
|
13
|
+
flags: 'i'
|
|
14
|
+
- regex: 'sparse.checkout.*cone.mode.*false'
|
|
15
|
+
flags: 'i'
|
|
16
|
+
- regex: 'non.cone mode.*sparse'
|
|
17
|
+
flags: 'i'
|
|
18
|
+
error_messages:
|
|
19
|
+
- "Run actions/checkout@v4"
|
|
20
|
+
- "sparse-checkout-cone-mode: false"
|
|
21
|
+
- "Unexpected files present in workspace"
|
|
22
|
+
root_cause: |
|
|
23
|
+
When `sparse-checkout-cone-mode: false` is set, `actions/checkout` uses
|
|
24
|
+
gitignore-style pattern matching for sparse checkout. In this non-cone mode,
|
|
25
|
+
a pattern like `myfile.yaml` (without a leading `/`) is interpreted as a
|
|
26
|
+
gitignore glob that matches `myfile.yaml` at ANY depth in the repository tree,
|
|
27
|
+
not just at the root. This causes `folderA/myfile.yaml`,
|
|
28
|
+
`folderB/subdir/myfile.yaml`, and all other path-depth occurrences of the
|
|
29
|
+
filename to be checked out alongside the intended root-level `myfile.yaml`.
|
|
30
|
+
|
|
31
|
+
Similarly, a pattern like `scripts` matches not just the top-level `scripts/`
|
|
32
|
+
directory but any directory or file named `scripts` at any depth.
|
|
33
|
+
|
|
34
|
+
The checkout step reports success with no error — the silent failure is that
|
|
35
|
+
the workspace contains more files than the developer expected, which can:
|
|
36
|
+
- Cause unintended files to be processed by downstream steps
|
|
37
|
+
- Inflate workspace size beyond what sparse checkout was intended to achieve
|
|
38
|
+
- Cause cache keys computed from workspace contents to be incorrect
|
|
39
|
+
- Introduce security risks if sensitive files at unexpected paths are included
|
|
40
|
+
|
|
41
|
+
Reported in actions/checkout#1628 (Feb 2024, multiple reproductions).
|
|
42
|
+
Non-cone mode is also deprecated by the Git project for these and other reasons.
|
|
43
|
+
fix: |
|
|
44
|
+
Option 1 (recommended): Switch to cone mode (the default).
|
|
45
|
+
Cone mode only accepts directory names, not patterns. It always includes root-level
|
|
46
|
+
files and all files under the specified directories. It is faster and predictable.
|
|
47
|
+
|
|
48
|
+
Option 2: Anchor non-cone patterns to the root with a leading `/`.
|
|
49
|
+
In gitignore syntax, a leading `/` anchors the pattern to the root of the tree,
|
|
50
|
+
so `/myfile.yaml` matches only the root-level file, not `/subfolder/myfile.yaml`.
|
|
51
|
+
|
|
52
|
+
Option 3: Use `filter: blob:none` (partial clone) instead of sparse-checkout
|
|
53
|
+
when you need to avoid downloading specific large binary assets rather than
|
|
54
|
+
limiting which files are checked out.
|
|
55
|
+
fix_code:
|
|
56
|
+
- language: yaml
|
|
57
|
+
label: 'Switch from non-cone to cone mode (recommended)'
|
|
58
|
+
code: |
|
|
59
|
+
# BEFORE (non-cone mode — patterns match at any depth)
|
|
60
|
+
# - uses: actions/checkout@v4
|
|
61
|
+
# with:
|
|
62
|
+
# sparse-checkout-cone-mode: false
|
|
63
|
+
# sparse-checkout: |
|
|
64
|
+
# myfile.yaml
|
|
65
|
+
# scripts
|
|
66
|
+
|
|
67
|
+
# AFTER (cone mode — specify directory names; root files always included)
|
|
68
|
+
- uses: actions/checkout@v4
|
|
69
|
+
with:
|
|
70
|
+
# sparse-checkout-cone-mode: true # This is the default — safe to omit
|
|
71
|
+
sparse-checkout: |
|
|
72
|
+
scripts
|
|
73
|
+
# Root-level files are always included in cone mode automatically
|
|
74
|
+
- language: yaml
|
|
75
|
+
label: 'Anchor non-cone patterns to root with leading / if you must use non-cone mode'
|
|
76
|
+
code: |
|
|
77
|
+
- uses: actions/checkout@v4
|
|
78
|
+
with:
|
|
79
|
+
sparse-checkout-cone-mode: false
|
|
80
|
+
sparse-checkout: |
|
|
81
|
+
/myfile.yaml # Leading / anchors to repo root only
|
|
82
|
+
/scripts # Only the top-level scripts/ directory
|
|
83
|
+
# WITHOUT leading /, 'scripts' would match any 'scripts' dir at any depth
|
|
84
|
+
prevention:
|
|
85
|
+
- "Avoid sparse-checkout-cone-mode: false unless you specifically need gitignore-style pattern matching."
|
|
86
|
+
- "When using non-cone mode, always prefix patterns with / to anchor them to the repository root."
|
|
87
|
+
- "After a sparse checkout, validate workspace contents by printing ls -R or find . to spot unexpected files."
|
|
88
|
+
- "Prefer cone mode (the default) — it is faster, predictable, and not deprecated."
|
|
89
|
+
- "For excluding large binary files rather than limiting directory scope, use partial clone with filter: blob:none."
|
|
90
|
+
docs:
|
|
91
|
+
- url: 'https://github.com/actions/checkout/issues/1628'
|
|
92
|
+
label: 'actions/checkout#1628 — sparse-checkout checks out undefined paths in non-cone mode'
|
|
93
|
+
- url: 'https://git-scm.com/docs/git-sparse-checkout#_non_cone_problems'
|
|
94
|
+
label: 'Git docs — Non-cone mode problems and deprecation notice'
|
|
95
|
+
- url: 'https://github.com/actions/checkout?tab=readme-ov-file#fetch-only-a-single-file'
|
|
96
|
+
label: 'actions/checkout — Sparse-checkout usage and cone-mode default'
|