@htekdev/actions-debugger 1.0.105 → 1.0.106
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-save-restore-path-mismatch-silent-miss.yml +93 -0
- package/errors/caching-artifacts/setup-java-gradle-windows-lock-files-device-busy.yml +81 -0
- package/errors/runner-environment/checkout-lfs-double-authorization-header-non-github-host.yml +70 -0
- package/package.json +1 -1
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
id: caching-artifacts-062
|
|
2
|
+
title: "actions/cache save and restore Separate Actions Silently Miss When Paths Differ"
|
|
3
|
+
category: caching-artifacts
|
|
4
|
+
severity: silent-failure
|
|
5
|
+
tags:
|
|
6
|
+
- cache
|
|
7
|
+
- cache-save
|
|
8
|
+
- cache-restore
|
|
9
|
+
- path-mismatch
|
|
10
|
+
- cache-miss
|
|
11
|
+
- silent
|
|
12
|
+
patterns:
|
|
13
|
+
- regex: 'Cache not found for input keys'
|
|
14
|
+
flags: i
|
|
15
|
+
error_messages:
|
|
16
|
+
- "Cache not found for input keys: my-cache-key"
|
|
17
|
+
root_cause: |
|
|
18
|
+
When using actions/cache/save and actions/cache/restore as separate actions (split across
|
|
19
|
+
different jobs), the cache archive is indexed by BOTH the cache key AND the path provided
|
|
20
|
+
to the save action. The restore action must specify the EXACT same path as the save action
|
|
21
|
+
or no cache will be found, even when the key matches perfectly.
|
|
22
|
+
|
|
23
|
+
This is undocumented behaviour: the path is part of the cache version hash used to locate
|
|
24
|
+
the archive, not just the key. Using a relative vs absolute path, a trailing slash, or any
|
|
25
|
+
variation in path formatting between save and restore results in "Cache not found for input
|
|
26
|
+
keys" with no hint that path mismatch is the cause.
|
|
27
|
+
|
|
28
|
+
This differs from using the combined actions/cache action in a single job, where the path
|
|
29
|
+
is always consistent between save and restore. Reported in actions/cache#1444.
|
|
30
|
+
fix: |
|
|
31
|
+
Ensure the path: value in actions/cache/restore exactly matches the path: value used in
|
|
32
|
+
actions/cache/save — including the same relative-vs-absolute format and no trailing slash
|
|
33
|
+
differences.
|
|
34
|
+
|
|
35
|
+
Best practice: extract the path into a shared env variable or workflow-level output, or
|
|
36
|
+
document the exact path string in both jobs.
|
|
37
|
+
fix_code:
|
|
38
|
+
- language: yaml
|
|
39
|
+
label: "Wrong: different paths between save and restore jobs"
|
|
40
|
+
code: |
|
|
41
|
+
jobs:
|
|
42
|
+
build:
|
|
43
|
+
runs-on: ubuntu-latest
|
|
44
|
+
steps:
|
|
45
|
+
- name: Create files
|
|
46
|
+
run: mkdir my-files && echo "data" > my-files/data.txt
|
|
47
|
+
- uses: actions/cache/save@v4
|
|
48
|
+
with:
|
|
49
|
+
path: my-files # saved with relative path
|
|
50
|
+
key: my-cache-${{ github.run_id }}
|
|
51
|
+
|
|
52
|
+
deploy:
|
|
53
|
+
needs: build
|
|
54
|
+
runs-on: ubuntu-latest
|
|
55
|
+
steps:
|
|
56
|
+
- uses: actions/cache/restore@v4
|
|
57
|
+
with:
|
|
58
|
+
path: ./my-files # WRONG: './my-files' != 'my-files' -- cache not found
|
|
59
|
+
key: my-cache-${{ github.run_id }}
|
|
60
|
+
- language: yaml
|
|
61
|
+
label: "Correct: identical path strings in save and restore"
|
|
62
|
+
code: |
|
|
63
|
+
jobs:
|
|
64
|
+
build:
|
|
65
|
+
runs-on: ubuntu-latest
|
|
66
|
+
steps:
|
|
67
|
+
- name: Create files
|
|
68
|
+
run: mkdir my-files && echo "data" > my-files/data.txt
|
|
69
|
+
- uses: actions/cache/save@v4
|
|
70
|
+
with:
|
|
71
|
+
path: my-files # use identical path
|
|
72
|
+
key: my-cache-${{ github.run_id }}
|
|
73
|
+
|
|
74
|
+
deploy:
|
|
75
|
+
needs: build
|
|
76
|
+
runs-on: ubuntu-latest
|
|
77
|
+
steps:
|
|
78
|
+
- uses: actions/cache/restore@v4
|
|
79
|
+
with:
|
|
80
|
+
path: my-files # exact match — cache found
|
|
81
|
+
key: my-cache-${{ github.run_id }}
|
|
82
|
+
prevention:
|
|
83
|
+
- "Copy the exact path: string from your save step into your restore step — do not retype it"
|
|
84
|
+
- "Avoid mixing relative (my-dir) and absolute (${{ github.workspace }}/my-dir) paths across jobs"
|
|
85
|
+
- "If in doubt, use the combined actions/cache@v4 action in a single job instead of split save/restore"
|
|
86
|
+
- "Print the cache key and path in both jobs to make debugging easier"
|
|
87
|
+
docs:
|
|
88
|
+
- url: "https://github.com/actions/cache/issues/1444"
|
|
89
|
+
label: "actions/cache#1444 — Restore reports cache not found when path differs from save path"
|
|
90
|
+
- url: "https://github.com/actions/cache/tree/main/save"
|
|
91
|
+
label: "actions/cache/save — Split save/restore documentation"
|
|
92
|
+
- url: "https://github.com/actions/cache/tree/main/restore"
|
|
93
|
+
label: "actions/cache/restore — Split save/restore documentation"
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
id: caching-artifacts-061
|
|
2
|
+
title: "setup-java cache: 'gradle' Silently Corrupts Cache on Windows — Gradle Lock Files Device or Resource Busy"
|
|
3
|
+
category: caching-artifacts
|
|
4
|
+
severity: silent-failure
|
|
5
|
+
tags:
|
|
6
|
+
- setup-java
|
|
7
|
+
- gradle
|
|
8
|
+
- windows
|
|
9
|
+
- cache
|
|
10
|
+
- lock-files
|
|
11
|
+
- device-busy
|
|
12
|
+
patterns:
|
|
13
|
+
- regex: '\.lock.*Read error.*Device or resource busy'
|
|
14
|
+
flags: i
|
|
15
|
+
- regex: 'fileContent\.lock.*Device or resource busy'
|
|
16
|
+
flags: i
|
|
17
|
+
- regex: '\.gradle/caches.*Read error.*byte 0'
|
|
18
|
+
flags: i
|
|
19
|
+
error_messages:
|
|
20
|
+
- "/usr/bin/tar: C\\:/Users/runneradmin/.gradle/caches/8.7/fileContent/fileContent.lock: Read error at byte 0, while reading 38 bytes: Device or resource busy"
|
|
21
|
+
- "/usr/bin/tar: Exiting with failure status due to previous errors"
|
|
22
|
+
- "Warning: Failed to save: ... failed with exit code 2"
|
|
23
|
+
root_cause: |
|
|
24
|
+
On Windows runners, actions/setup-java with cache: 'gradle' triggers a cache save in its
|
|
25
|
+
post-job step. At that point, the Gradle daemon process started during the build step may
|
|
26
|
+
still be running and holding open file locks on these cache directories:
|
|
27
|
+
- .gradle/caches/*/fileContent.lock
|
|
28
|
+
- .gradle/caches/*/fileHashes.lock
|
|
29
|
+
- .gradle/caches/*/generated-gradle-jars.lock
|
|
30
|
+
- .gradle/caches/*/javaCompile.lock
|
|
31
|
+
- .gradle/caches/journal-1/journal-1.lock
|
|
32
|
+
- .gradle/caches/modules-*/modules-*.lock
|
|
33
|
+
|
|
34
|
+
The GNU tar bundled with Git for Windows (used by the GitHub Actions runner) cannot read
|
|
35
|
+
Windows-locked files and exits with code 2. Despite this failure, setup-java logs
|
|
36
|
+
"Cache saved with the key: ..." because the cache service accepted a partial archive.
|
|
37
|
+
|
|
38
|
+
The silent failure: subsequent runs restore the partial cache, missing the locked files.
|
|
39
|
+
Gradle then redownloads dependencies on every run, and the cache save repeats the same
|
|
40
|
+
error. Cache size appears normal in the UI but the archive contents are incomplete.
|
|
41
|
+
Reported in actions/setup-java#633.
|
|
42
|
+
fix: |
|
|
43
|
+
Stop the Gradle daemon explicitly before the post-job step fires. The setup-java
|
|
44
|
+
post-step runs after all workflow steps complete, so stopping the daemon in the last
|
|
45
|
+
step ensures no lock files are held when the post-step archives the cache:
|
|
46
|
+
fix_code:
|
|
47
|
+
- language: yaml
|
|
48
|
+
label: "Fix: stop Gradle daemon before post-step cache save"
|
|
49
|
+
code: |
|
|
50
|
+
jobs:
|
|
51
|
+
build:
|
|
52
|
+
runs-on: windows-latest
|
|
53
|
+
steps:
|
|
54
|
+
- uses: actions/checkout@v4
|
|
55
|
+
- uses: actions/setup-java@v4
|
|
56
|
+
with:
|
|
57
|
+
java-version: '21'
|
|
58
|
+
distribution: 'temurin'
|
|
59
|
+
cache: 'gradle'
|
|
60
|
+
- name: Build with Gradle
|
|
61
|
+
run: ./gradlew build
|
|
62
|
+
- name: Stop Gradle daemon before cache save
|
|
63
|
+
if: always()
|
|
64
|
+
run: ./gradlew --stop
|
|
65
|
+
- language: yaml
|
|
66
|
+
label: "Alternative: build with --no-daemon (no daemon started, no lock files)"
|
|
67
|
+
code: |
|
|
68
|
+
- name: Build with Gradle (no daemon)
|
|
69
|
+
run: ./gradlew build --no-daemon
|
|
70
|
+
prevention:
|
|
71
|
+
- "Always add a './gradlew --stop' step (with if: always()) after your build step on Windows runners"
|
|
72
|
+
- "Use --no-daemon for Gradle builds in CI to avoid daemon lock file issues entirely"
|
|
73
|
+
- "Verify cache usefulness by checking whether Gradle redownloads dependencies on runs after cache save"
|
|
74
|
+
- "Consider using the official gradle/actions/setup-gradle action which handles daemon lifecycle better"
|
|
75
|
+
docs:
|
|
76
|
+
- url: "https://github.com/actions/setup-java/issues/633"
|
|
77
|
+
label: "actions/setup-java#633 — Gradle caching post-task fails on Windows with 'device or resource busy'"
|
|
78
|
+
- url: "https://docs.gradle.org/current/userguide/gradle_daemon.html"
|
|
79
|
+
label: "Gradle Daemon documentation — stopping and disabling"
|
|
80
|
+
- url: "https://github.com/gradle/actions/blob/main/docs/setup-gradle.md"
|
|
81
|
+
label: "gradle/actions — recommended Gradle CI caching action"
|
package/errors/runner-environment/checkout-lfs-double-authorization-header-non-github-host.yml
ADDED
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
id: runner-environment-175
|
|
2
|
+
title: "checkout@v4 LFS with Non-GitHub Host Sends Double Authorization Header -- 400 Bad Request"
|
|
3
|
+
category: runner-environment
|
|
4
|
+
severity: error
|
|
5
|
+
tags:
|
|
6
|
+
- checkout
|
|
7
|
+
- lfs
|
|
8
|
+
- git-lfs
|
|
9
|
+
- non-github-host
|
|
10
|
+
- authorization-header
|
|
11
|
+
- submodule
|
|
12
|
+
patterns:
|
|
13
|
+
- regex: 'Authorization.*Authorization'
|
|
14
|
+
flags: i
|
|
15
|
+
- regex: 'HTTP.*400.*lfs'
|
|
16
|
+
flags: i
|
|
17
|
+
error_messages:
|
|
18
|
+
- "trace git-lfs: HTTP: 400"
|
|
19
|
+
- "batch request failed with status 400"
|
|
20
|
+
root_cause: |
|
|
21
|
+
When actions/checkout is used with lfs: true and the repository contains submodules
|
|
22
|
+
pointing to a non-GitHub host (Gitea, Bitbucket, self-hosted GitLab, etc.), the checkout
|
|
23
|
+
action writes an HTTP Authorization header into .git/config via http.<url>.extraheader.
|
|
24
|
+
For GitHub.com remotes this works correctly. However, for submodule remotes on other hosts,
|
|
25
|
+
the git-lfs client then sends BOTH this injected header AND its own credential-helper-derived
|
|
26
|
+
Authorization header in the same LFS batch request.
|
|
27
|
+
|
|
28
|
+
Most non-GitHub servers reject duplicate Authorization headers with HTTP 400 Bad Request,
|
|
29
|
+
as the HTTP spec treats repeated Authorization headers as ambiguous. GitHub.com silently
|
|
30
|
+
deduplicates them, hiding the problem. Only non-GitHub hosts expose this bug.
|
|
31
|
+
|
|
32
|
+
Diagnosed by enabling GIT_CURL_VERBOSE: 1 and GIT_TRACE: 1 in the workflow environment,
|
|
33
|
+
which reveals two Authorization: Basic lines in the same LFS request headers.
|
|
34
|
+
Reported in actions/checkout#1830 (15 reactions).
|
|
35
|
+
fix: |
|
|
36
|
+
Use SSH key authentication for the non-GitHub submodule remote — no HTTP Authorization
|
|
37
|
+
header is injected for SSH remotes, eliminating the conflict:
|
|
38
|
+
fix_code:
|
|
39
|
+
- language: yaml
|
|
40
|
+
label: "Recommended: use ssh-key for non-GitHub submodule host"
|
|
41
|
+
code: |
|
|
42
|
+
- uses: actions/checkout@v4
|
|
43
|
+
with:
|
|
44
|
+
submodules: recursive
|
|
45
|
+
lfs: true
|
|
46
|
+
ssh-key: ${{ secrets.SUBMODULE_SSH_KEY }}
|
|
47
|
+
- language: yaml
|
|
48
|
+
label: "Alternative: disable lfs on checkout and pull LFS per-host manually"
|
|
49
|
+
code: |
|
|
50
|
+
steps:
|
|
51
|
+
- uses: actions/checkout@v4
|
|
52
|
+
with:
|
|
53
|
+
submodules: recursive
|
|
54
|
+
lfs: false # prevents checkout from injecting LFS auth header
|
|
55
|
+
- name: Clear injected extraheader and pull LFS for non-GitHub host
|
|
56
|
+
env:
|
|
57
|
+
GIT_CURL_VERBOSE: "1"
|
|
58
|
+
run: |
|
|
59
|
+
cd path/to/non-github-submodule
|
|
60
|
+
git config --unset http.https://your-host.example.com/.extraheader || true
|
|
61
|
+
git lfs pull
|
|
62
|
+
prevention:
|
|
63
|
+
- "Use SSH keys for non-GitHub submodule remotes to avoid HTTP credential injection conflicts"
|
|
64
|
+
- "Enable GIT_CURL_VERBOSE=1 to diagnose duplicate Authorization headers in LFS requests"
|
|
65
|
+
- "Test LFS workflows after upgrading checkout to a new major version"
|
|
66
|
+
docs:
|
|
67
|
+
- url: "https://github.com/actions/checkout/issues/1830"
|
|
68
|
+
label: "actions/checkout#1830 -- LFS fails with double auth header on non-GitHub host"
|
|
69
|
+
- url: "https://github.com/actions/checkout#readme"
|
|
70
|
+
label: "actions/checkout -- lfs and submodules input documentation"
|
package/package.json
CHANGED