@htekdev/actions-debugger 1.0.2 → 1.0.4
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/artifact-download-no-artifacts-found.yml +118 -0
- package/errors/concurrency-timing/job-stuck-waiting-for-runner.yml +105 -0
- package/errors/concurrency-timing/matrix-fail-fast-sibling-cancellation.yml +113 -0
- package/errors/concurrency-timing/timeout-minutes-job-killed.yml +107 -0
- package/errors/known-unsolved/github-step-summary-size-limit.yml +112 -0
- package/errors/known-unsolved/job-maximum-execution-time.yml +127 -0
- package/errors/runner-environment/macos-14-sonoma-eol.yml +89 -0
- package/errors/runner-environment/macos-latest-to-macos-26.yml +127 -0
- package/errors/runner-environment/powershell-74-to-76-upgrade.yml +112 -0
- package/errors/runner-environment/service-container-unhealthy.yml +126 -0
- package/errors/runner-environment/windows-latest-vs2026-migration.yml +131 -0
- package/errors/silent-failures/hashfiles-empty-string-cache-collision.yml +96 -0
- package/errors/triggers/environment-protection-rules-silent-block.yml +105 -0
- package/errors/yaml-syntax/env-context-unavailable-job-level.yml +109 -0
- package/package.json +1 -1
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
id: runner-environment-020
|
|
2
|
+
title: "windows-latest Now Uses Visual Studio 2026 — VS 2022 Components Removed"
|
|
3
|
+
category: runner-environment
|
|
4
|
+
severity: error
|
|
5
|
+
tags:
|
|
6
|
+
- windows
|
|
7
|
+
- visual-studio
|
|
8
|
+
- runner-image
|
|
9
|
+
- breaking-change
|
|
10
|
+
- msbuild
|
|
11
|
+
- dotnet
|
|
12
|
+
patterns:
|
|
13
|
+
- regex: "MSB[0-9]+.*Visual Studio 2022|The tools version.*15\\.0.*is not available"
|
|
14
|
+
flags: "i"
|
|
15
|
+
- regex: "Dotfuscator.*not found|dotfuscator.*missing"
|
|
16
|
+
flags: "i"
|
|
17
|
+
- regex: "Component.*Azure.ServiceFabric.Tools.*not installed"
|
|
18
|
+
flags: "i"
|
|
19
|
+
- regex: "VC\\.Tools\\.ARM.*not found|Microsoft\\.VisualStudio\\.Component\\.VC\\.Tools\\.ARM"
|
|
20
|
+
flags: "i"
|
|
21
|
+
- regex: "error.*NETSDK1045.*The current .NET SDK does not support targeting .NET (5|6|7)"
|
|
22
|
+
flags: "i"
|
|
23
|
+
- regex: "Visual Studio.*version 17\\.[0-9]+.*not found|MSBuild.*17\\.[0-9]+.*not available"
|
|
24
|
+
flags: "i"
|
|
25
|
+
error_messages:
|
|
26
|
+
- "MSB4019: The imported project 'Microsoft.CppBuild.targets' was not found."
|
|
27
|
+
- "Error: Dotfuscator is not installed. Please install Dotfuscator Community."
|
|
28
|
+
- "The component 'Microsoft.VisualStudio.Component.Azure.ServiceFabric.Tools' is not installed."
|
|
29
|
+
- "MSBUILD : error MSB1009: Project file does not exist. Switch: /version:17"
|
|
30
|
+
- "The current .NET SDK does not support targeting .NET 7.0."
|
|
31
|
+
root_cause: |
|
|
32
|
+
The `windows-latest` and `windows-2025` labels in GitHub Actions were migrated to use
|
|
33
|
+
**Windows Server 2025 with Visual Studio 2026** beginning June 8, 2026 (completing
|
|
34
|
+
June 15, 2026). Previously these labels ran Visual Studio 2022 (version 17.x).
|
|
35
|
+
|
|
36
|
+
Visual Studio 2026 (version 18.x) ships with MSBuild 18 and removes several VS 2022
|
|
37
|
+
components that workflows may depend on:
|
|
38
|
+
|
|
39
|
+
**Removed VS components:**
|
|
40
|
+
- `Component.Dotfuscator` — .NET obfuscation tool
|
|
41
|
+
- `Microsoft.VisualStudio.Component.Azure.ServiceFabric.Tools`
|
|
42
|
+
- `Microsoft.VisualStudio.Component.TestTools.CodedUITest`
|
|
43
|
+
- `Microsoft.VisualStudio.Component.TestTools.WebLoadTest`
|
|
44
|
+
- `Microsoft.VisualStudio.Component.VC.Tools.ARM` — ARM cross-compilation toolchain
|
|
45
|
+
- `Microsoft.VisualStudio.Component.VC.Modules.x86.x64`
|
|
46
|
+
- `Microsoft.VisualStudio.Component.VC.Runtimes.ARM.Spectre`
|
|
47
|
+
- `Microsoft.VisualStudio.Component.VC.MFC.ARM` and `.ARM.Spectre`
|
|
48
|
+
- `Microsoft.VisualStudio.Component.VC.ATL.ARM` and `.ARM.Spectre`
|
|
49
|
+
- `Microsoft.VisualStudio.ComponentGroup.Azure.CloudServices`
|
|
50
|
+
- `Microsoft.VisualStudio.ComponentGroup.Azure.ResourceManager.Tools`
|
|
51
|
+
|
|
52
|
+
**Other changes:**
|
|
53
|
+
- CMake updated from 3.31.6 → 4.3.2 (adds VS 18 2026 generator, deprecates some older generators)
|
|
54
|
+
- Android Command Line Tools updated from 16.0 → 19.0
|
|
55
|
+
- MSVC v143 toolset is added as a compatibility shim for projects requiring it
|
|
56
|
+
fix: |
|
|
57
|
+
**Immediate rollback:** Pin to `windows-2022` to keep Visual Studio 2022:
|
|
58
|
+
```yaml
|
|
59
|
+
runs-on: windows-2022
|
|
60
|
+
```
|
|
61
|
+
Note: `windows-2022` continues to run VS 2022 (version 17.x) and will remain supported.
|
|
62
|
+
|
|
63
|
+
**For removed components:**
|
|
64
|
+
- **Dotfuscator**: Remove from build pipeline, or install manually via the Dotfuscator
|
|
65
|
+
Community installer in a workflow step. Consider alternatives like ConfuserEx.
|
|
66
|
+
- **ARM VC toolchain** (`VC.Tools.ARM`): Use the separate `windows-11-arm64` runner label
|
|
67
|
+
for native ARM64 builds, or cross-compile via MSVC v143 shim that ships with VS 2026.
|
|
68
|
+
- **Azure Service Fabric Tools**: Install the Service Fabric SDK directly via PowerShell
|
|
69
|
+
if your workflow requires it.
|
|
70
|
+
- **CMake generator**: Update your CMake invocation from `-G "Visual Studio 17 2022"` to
|
|
71
|
+
`-G "Visual Studio 18 2026"`.
|
|
72
|
+
fix_code:
|
|
73
|
+
- language: yaml
|
|
74
|
+
label: "Pin to windows-2022 for immediate rollback (VS 2022)"
|
|
75
|
+
code: |
|
|
76
|
+
jobs:
|
|
77
|
+
build:
|
|
78
|
+
# Temporarily pin to VS 2022 while migrating
|
|
79
|
+
runs-on: windows-2022
|
|
80
|
+
steps:
|
|
81
|
+
- uses: actions/checkout@v4
|
|
82
|
+
- name: Build
|
|
83
|
+
run: msbuild MyProject.sln /p:Configuration=Release
|
|
84
|
+
- language: yaml
|
|
85
|
+
label: "Migrate to VS 2026 — update CMake generator and toolset"
|
|
86
|
+
code: |
|
|
87
|
+
jobs:
|
|
88
|
+
build:
|
|
89
|
+
runs-on: windows-latest # now VS 2026
|
|
90
|
+
steps:
|
|
91
|
+
- uses: actions/checkout@v4
|
|
92
|
+
|
|
93
|
+
- name: Configure CMake (VS 2026 generator)
|
|
94
|
+
run: |
|
|
95
|
+
cmake -B build -G "Visual Studio 18 2026" -A x64 `
|
|
96
|
+
-DCMAKE_BUILD_TYPE=Release
|
|
97
|
+
|
|
98
|
+
- name: Build
|
|
99
|
+
run: cmake --build build --config Release
|
|
100
|
+
|
|
101
|
+
# If you need MSVC v143 (VS 2022 toolset) compatibility:
|
|
102
|
+
# cmake -B build -G "Visual Studio 18 2026" -A x64 -T v143
|
|
103
|
+
- language: yaml
|
|
104
|
+
label: "Test against both VS 2022 and VS 2026 during migration"
|
|
105
|
+
code: |
|
|
106
|
+
jobs:
|
|
107
|
+
build:
|
|
108
|
+
strategy:
|
|
109
|
+
matrix:
|
|
110
|
+
os: [windows-2022, windows-latest]
|
|
111
|
+
runs-on: ${{ matrix.os }}
|
|
112
|
+
steps:
|
|
113
|
+
- uses: actions/checkout@v4
|
|
114
|
+
- name: Build and test
|
|
115
|
+
run: msbuild MyProject.sln /p:Configuration=Release /t:Build,Test
|
|
116
|
+
prevention:
|
|
117
|
+
- "Avoid depending on specific Visual Studio components that are not part of the core VS 2022/2026 workloads — install them explicitly in your workflow if needed."
|
|
118
|
+
- "Subscribe to actions/runner-images announcements to receive advance notice of `windows-latest` migrations."
|
|
119
|
+
- "Test your Windows workflows against `windows-2025-vs2026` before the `windows-latest` migration completes."
|
|
120
|
+
- "Use MSBuild's `-T v143` toolset flag to target the VS 2022 compiler toolchain from within VS 2026 if full migration is not yet feasible."
|
|
121
|
+
- "Search your workflows for CMake generator strings like 'Visual Studio 17 2022' and update them proactively."
|
|
122
|
+
docs:
|
|
123
|
+
- url: "https://github.com/actions/runner-images/issues/14017"
|
|
124
|
+
label: "GitHub Announcement: windows-latest migrates to Visual Studio 2026"
|
|
125
|
+
- url: "https://github.com/actions/runner-images/issues/14016"
|
|
126
|
+
label: "GitHub Announcement: Windows Server 2025 with VS 2026 now GA"
|
|
127
|
+
- url: "https://docs.github.com/en/actions/using-github-hosted-runners/using-github-hosted-runners/about-github-hosted-runners"
|
|
128
|
+
label: "About GitHub-hosted runners"
|
|
129
|
+
source:
|
|
130
|
+
article: "https://htek.dev/articles/github-actions-debugging-guide"
|
|
131
|
+
section: "Windows runner Visual Studio migrations"
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
id: silent-failures-009
|
|
2
|
+
title: "hashFiles() Returns Empty String When No Files Match — Silent Cache Key Collision"
|
|
3
|
+
category: silent-failures
|
|
4
|
+
severity: silent-failure
|
|
5
|
+
tags:
|
|
6
|
+
- cache
|
|
7
|
+
- hashFiles
|
|
8
|
+
- cache-key
|
|
9
|
+
- collision
|
|
10
|
+
- glob
|
|
11
|
+
- silent-failure
|
|
12
|
+
patterns:
|
|
13
|
+
- regex: "key: [A-Za-z0-9_-]+-$"
|
|
14
|
+
flags: "m"
|
|
15
|
+
- regex: "Cache restored from key: [A-Za-z0-9_-]+(?!-[0-9a-f]{64})"
|
|
16
|
+
flags: "i"
|
|
17
|
+
error_messages:
|
|
18
|
+
- "Cache restored from key: Linux-node-"
|
|
19
|
+
- "Cache restored from key: Linux-pip-"
|
|
20
|
+
- "No error shown — workflow succeeds but wrong cache is restored"
|
|
21
|
+
root_cause: |
|
|
22
|
+
The `hashFiles()` expression function returns an empty string (not an error)
|
|
23
|
+
when the supplied glob pattern matches no files in the workspace. This silently
|
|
24
|
+
truncates the cache key, turning a key like:
|
|
25
|
+
|
|
26
|
+
${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
|
|
27
|
+
|
|
28
|
+
into:
|
|
29
|
+
|
|
30
|
+
Linux-node-
|
|
31
|
+
|
|
32
|
+
when no package-lock.json exists. This short, predictable key collides across
|
|
33
|
+
branches and runs, causing stale or wrong cache content to be restored without
|
|
34
|
+
any warning. The workflow log shows the cache as restored successfully.
|
|
35
|
+
|
|
36
|
+
Documented in actions/runner issue #894. Commonly triggered by:
|
|
37
|
+
- Lockfile not yet committed (new project setup)
|
|
38
|
+
- Wrong glob path (e.g., `**/package-lock.json` but lockfile is at root)
|
|
39
|
+
- Wrong working directory at cache step execution time
|
|
40
|
+
- Matrix jobs where not all matrix values have a matching lockfile
|
|
41
|
+
fix: |
|
|
42
|
+
Add a fallback value to the hashFiles() expression using the `||` operator so
|
|
43
|
+
the key is always deterministic even when no files match:
|
|
44
|
+
|
|
45
|
+
key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') || 'no-lockfile' }}
|
|
46
|
+
|
|
47
|
+
Also verify that the glob actually matches the file by running
|
|
48
|
+
`find . -name "package-lock.json"` in a debug step before the cache step.
|
|
49
|
+
|
|
50
|
+
For matrix workflows, include the matrix value in the key to prevent
|
|
51
|
+
cross-matrix collisions even when hash is empty:
|
|
52
|
+
|
|
53
|
+
key: ${{ runner.os }}-node-${{ matrix.node-version }}-${{ hashFiles('**/package-lock.json') || 'no-lockfile' }}
|
|
54
|
+
fix_code:
|
|
55
|
+
- language: yaml
|
|
56
|
+
label: "WRONG — hashFiles with no fallback (silently short key on miss)"
|
|
57
|
+
code: |
|
|
58
|
+
- uses: actions/cache@v4
|
|
59
|
+
with:
|
|
60
|
+
path: ~/.npm
|
|
61
|
+
key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
|
|
62
|
+
# ❌ If no package-lock.json found, key becomes "Linux-node-"
|
|
63
|
+
# All runs share the same truncated key → wrong cache restored silently
|
|
64
|
+
- language: yaml
|
|
65
|
+
label: "RIGHT — hashFiles with explicit fallback"
|
|
66
|
+
code: |
|
|
67
|
+
- uses: actions/cache@v4
|
|
68
|
+
with:
|
|
69
|
+
path: ~/.npm
|
|
70
|
+
key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') || 'no-lockfile' }}
|
|
71
|
+
# ✅ If no lockfile, key becomes "Linux-node-no-lockfile" — deterministic and unique
|
|
72
|
+
restore-keys: |
|
|
73
|
+
${{ runner.os }}-node-
|
|
74
|
+
- language: yaml
|
|
75
|
+
label: "DEBUG — verify glob matches before caching"
|
|
76
|
+
code: |
|
|
77
|
+
- name: Debug — check lockfile exists
|
|
78
|
+
run: find . -name "package-lock.json" | head -5
|
|
79
|
+
# If empty output: fix the glob or ensure lockfile is committed
|
|
80
|
+
|
|
81
|
+
- uses: actions/cache@v4
|
|
82
|
+
with:
|
|
83
|
+
path: ~/.npm
|
|
84
|
+
key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') || 'no-lockfile' }}
|
|
85
|
+
prevention:
|
|
86
|
+
- "Always provide a `|| 'fallback-value'` after any hashFiles() call to prevent empty-string cache key truncation."
|
|
87
|
+
- "Test your hashFiles() glob locally: run `find . -name 'your-lockfile'` from the repo root to confirm it matches."
|
|
88
|
+
- "Include stable discriminators (runner.os, matrix values, Node version) in cache keys to reduce collision risk."
|
|
89
|
+
- "Review restored cache key in workflow logs — a key ending in just a short prefix without a 64-char hash is a sign of an empty hashFiles()."
|
|
90
|
+
docs:
|
|
91
|
+
- url: "https://docs.github.com/en/actions/writing-workflows/choosing-what-your-workflow-does/evaluate-expressions-in-workflows-and-actions#hashfiles"
|
|
92
|
+
label: "hashFiles() function documentation"
|
|
93
|
+
- url: "https://github.com/actions/runner/issues/894"
|
|
94
|
+
label: "actions/runner #894 — hashFiles returns empty string instead of hash"
|
|
95
|
+
- url: "https://docs.github.com/en/actions/using-workflows/caching-dependencies-to-speed-up-workflows"
|
|
96
|
+
label: "Caching dependencies to speed up workflows"
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
id: triggers-006
|
|
2
|
+
title: "Job Blocked Silently by Environment Protection Rules — No Clear Log Message"
|
|
3
|
+
category: triggers
|
|
4
|
+
severity: warning
|
|
5
|
+
tags:
|
|
6
|
+
- environment
|
|
7
|
+
- protection-rules
|
|
8
|
+
- deployment
|
|
9
|
+
- approval
|
|
10
|
+
- branch-restriction
|
|
11
|
+
- silent-wait
|
|
12
|
+
patterns:
|
|
13
|
+
- regex: "Waiting for.*environment.*approval"
|
|
14
|
+
flags: "i"
|
|
15
|
+
- regex: "Branch '.*' is not allowed to deploy to .* due to environment protection rules"
|
|
16
|
+
flags: "i"
|
|
17
|
+
- regex: "Expected.*Waiting for status to be reported"
|
|
18
|
+
flags: "i"
|
|
19
|
+
error_messages:
|
|
20
|
+
- "Branch 'feature/my-branch' is not allowed to deploy to production due to environment protection rules."
|
|
21
|
+
- "Waiting for approval — This workflow run requires approval from the environment's configured reviewers."
|
|
22
|
+
- "Expected — Waiting for status to be reported"
|
|
23
|
+
root_cause: |
|
|
24
|
+
GitHub Environments can have protection rules that gate job execution:
|
|
25
|
+
- **Required reviewers**: A human must approve the deployment before the job runs.
|
|
26
|
+
- **Branch/tag restrictions**: Only specific branches or tags are allowed to
|
|
27
|
+
deploy to the environment (e.g., only `main` can deploy to `production`).
|
|
28
|
+
- **Required status checks**: External status checks must pass first.
|
|
29
|
+
- **Wait timers**: A mandatory delay before the job can proceed.
|
|
30
|
+
|
|
31
|
+
When a job targets an environment with unsatisfied protection rules, it enters
|
|
32
|
+
a waiting state in the GitHub UI. The **workflow log may not show a clear
|
|
33
|
+
failure message** — the job simply appears as pending or "Expected — Waiting
|
|
34
|
+
for status to be reported." This is a common source of confusion for teams
|
|
35
|
+
that enable environment protection rules for the first time, especially in
|
|
36
|
+
forks or feature-branch workflows where the branch is not in the allowed list.
|
|
37
|
+
|
|
38
|
+
Documented in GitHub Community discussions #39054 and #26698.
|
|
39
|
+
fix: |
|
|
40
|
+
1. **Check environment settings**: Repository Settings → Environments → select
|
|
41
|
+
the environment → review protection rules (required reviewers, deployment
|
|
42
|
+
branches, required checks, wait timers).
|
|
43
|
+
|
|
44
|
+
2. **For branch restriction failures**: Add the branch that the workflow runs
|
|
45
|
+
on to the environment's "Deployment branches and tags" list, or change the
|
|
46
|
+
policy to "No restriction" for non-production environments.
|
|
47
|
+
|
|
48
|
+
3. **For pending approval**: A configured reviewer must approve the deployment
|
|
49
|
+
in the GitHub UI (Actions tab → select the run → click "Review deployments").
|
|
50
|
+
|
|
51
|
+
4. **For automated CI**: Use a separate environment with no protection rules
|
|
52
|
+
for automated test deployments, and reserve protected environments for
|
|
53
|
+
production deployments that require human approval.
|
|
54
|
+
|
|
55
|
+
5. **For fork PRs**: Environments with protection rules can silently block
|
|
56
|
+
fork PRs since the fork branch is not in the allowed branch list — use a
|
|
57
|
+
separate no-protection environment for fork PR validation jobs.
|
|
58
|
+
fix_code:
|
|
59
|
+
- language: yaml
|
|
60
|
+
label: "Use separate environments for CI vs production"
|
|
61
|
+
code: |
|
|
62
|
+
jobs:
|
|
63
|
+
deploy-staging:
|
|
64
|
+
runs-on: ubuntu-latest
|
|
65
|
+
environment: staging # ✅ no protection rules — runs immediately
|
|
66
|
+
steps:
|
|
67
|
+
- run: ./deploy.sh staging
|
|
68
|
+
|
|
69
|
+
deploy-production:
|
|
70
|
+
needs: deploy-staging
|
|
71
|
+
runs-on: ubuntu-latest
|
|
72
|
+
environment: production # 🔒 has required reviewers — waits for approval
|
|
73
|
+
if: github.ref == 'refs/heads/main' # ✅ only main is in allowed branch list
|
|
74
|
+
steps:
|
|
75
|
+
- run: ./deploy.sh production
|
|
76
|
+
- language: yaml
|
|
77
|
+
label: "Check branch restriction: ensure workflow branch is in allowed list"
|
|
78
|
+
code: |
|
|
79
|
+
# In GitHub UI: Settings → Environments → production → Deployment branches
|
|
80
|
+
# Add "main" or change policy to match your workflow's ref.
|
|
81
|
+
#
|
|
82
|
+
# In workflow: use github.ref_name to verify before targeting environment
|
|
83
|
+
jobs:
|
|
84
|
+
deploy:
|
|
85
|
+
runs-on: ubuntu-latest
|
|
86
|
+
# Only run on main — matches production environment's branch restriction
|
|
87
|
+
if: github.ref == 'refs/heads/main'
|
|
88
|
+
environment: production
|
|
89
|
+
steps:
|
|
90
|
+
- run: ./deploy.sh
|
|
91
|
+
prevention:
|
|
92
|
+
- "Document environment protection rules in your repository's CONTRIBUTING.md so all developers know which branches can deploy where."
|
|
93
|
+
- "Test protection rules in a staging environment before applying them to production — the silent-wait behavior is surprising on first encounter."
|
|
94
|
+
- "For automated CI workflows that run on feature branches, use environments without branch restrictions or required reviewers."
|
|
95
|
+
- "After enabling environment protection rules, verify the workflow can actually trigger by running a test deployment from an allowed branch."
|
|
96
|
+
- "Monitor for stuck jobs in the Actions tab — a job sitting in 'waiting' or 'Expected' state usually means an environment protection rule is blocking it."
|
|
97
|
+
docs:
|
|
98
|
+
- url: "https://docs.github.com/en/actions/deployment/targeting-different-environments/using-environments-for-deployment"
|
|
99
|
+
label: "Using environments for deployment — protection rules"
|
|
100
|
+
- url: "https://github.com/orgs/community/discussions/39054"
|
|
101
|
+
label: "GitHub Community #39054 — Branch not allowed to deploy due to environment protection rules"
|
|
102
|
+
- url: "https://github.com/orgs/community/discussions/26698"
|
|
103
|
+
label: "GitHub Community #26698 — Job stuck in Expected / Waiting for status to be reported"
|
|
104
|
+
- url: "https://stackoverflow.com/questions/72109150/github-action-avoid-approval-on-same-environment-rule-within-same-workflow"
|
|
105
|
+
label: "Stack Overflow — Avoiding approval in same environment within same workflow"
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
id: yaml-syntax-014
|
|
2
|
+
title: "env Context Not Available at Job-Level if or Reusable Workflow Positions"
|
|
3
|
+
category: yaml-syntax
|
|
4
|
+
severity: error
|
|
5
|
+
tags:
|
|
6
|
+
- env
|
|
7
|
+
- context
|
|
8
|
+
- job-if
|
|
9
|
+
- reusable-workflow
|
|
10
|
+
- expression
|
|
11
|
+
- context-availability
|
|
12
|
+
patterns:
|
|
13
|
+
- regex: "Unrecognized named-value: 'env'"
|
|
14
|
+
flags: "i"
|
|
15
|
+
- regex: "The workflow is not valid.*Unrecognized named-value: 'env'"
|
|
16
|
+
flags: "i"
|
|
17
|
+
- regex: "Located at position \\d+ within expression.*env\\."
|
|
18
|
+
flags: "i"
|
|
19
|
+
error_messages:
|
|
20
|
+
- "The workflow is not valid. .github/workflows/<workflow>.yml (Line: X, Col: Y): Unrecognized named-value: 'env'. Located at position Z within expression: <expression>"
|
|
21
|
+
- "Unrecognized named-value: 'env'. Located at position 1 within expression"
|
|
22
|
+
root_cause: |
|
|
23
|
+
GitHub Actions evaluates job-level expressions (jobs.<job_id>.if, certain
|
|
24
|
+
jobs.<job_id>.with: inputs for reusable workflows) before any steps run and
|
|
25
|
+
before step-level env values are available. Because the `env` context is
|
|
26
|
+
only populated at step execution time, using `env.MY_VAR` inside a job-level
|
|
27
|
+
`if:` condition or inside a reusable workflow's `jobs:` block triggers a
|
|
28
|
+
validation error at parse time rather than a runtime failure.
|
|
29
|
+
|
|
30
|
+
This affects:
|
|
31
|
+
- `jobs.<job_id>.if: ${{ env.MY_VAR == 'foo' }}`
|
|
32
|
+
- `jobs.<job_id>.with:` fields referencing `env.*` in a reusable workflow call
|
|
33
|
+
- Any top-level workflow expression that attempts to read `env` context
|
|
34
|
+
|
|
35
|
+
Documented in actions/runner issues #1189, #1661, and #2372.
|
|
36
|
+
fix: |
|
|
37
|
+
Replace env context references in job-level positions with contexts that are
|
|
38
|
+
available at job evaluation time:
|
|
39
|
+
- Use `vars.*` (repository/environment variables) for static configuration values
|
|
40
|
+
- Use `github.*` context for event-driven values
|
|
41
|
+
- Use `inputs.*` for values passed into reusable workflows
|
|
42
|
+
- Use job outputs (`needs.<job_id>.outputs.<name>`) to pass dynamic values
|
|
43
|
+
computed in earlier steps to downstream job `if:` conditions
|
|
44
|
+
|
|
45
|
+
If the value is truly dynamic and set in a previous step, emit it as a step
|
|
46
|
+
output → job output → needs output chain so downstream jobs can reference it.
|
|
47
|
+
fix_code:
|
|
48
|
+
- language: yaml
|
|
49
|
+
label: "WRONG — env context in job-level if (fails validation)"
|
|
50
|
+
code: |
|
|
51
|
+
jobs:
|
|
52
|
+
deploy:
|
|
53
|
+
if: ${{ env.DEPLOY_ENV == 'production' }} # ❌ env not available here
|
|
54
|
+
runs-on: ubuntu-latest
|
|
55
|
+
steps:
|
|
56
|
+
- run: echo "Deploying"
|
|
57
|
+
- language: yaml
|
|
58
|
+
label: "RIGHT — use vars context or job outputs instead"
|
|
59
|
+
code: |
|
|
60
|
+
# Option 1: use vars (repository/environment variables) for static config
|
|
61
|
+
jobs:
|
|
62
|
+
deploy:
|
|
63
|
+
if: ${{ vars.DEPLOY_ENV == 'production' }} # ✅ vars available at job level
|
|
64
|
+
runs-on: ubuntu-latest
|
|
65
|
+
steps:
|
|
66
|
+
- run: echo "Deploying"
|
|
67
|
+
|
|
68
|
+
# Option 2: compute in a preceding job, emit as output
|
|
69
|
+
jobs:
|
|
70
|
+
compute-env:
|
|
71
|
+
runs-on: ubuntu-latest
|
|
72
|
+
outputs:
|
|
73
|
+
deploy_env: ${{ steps.set-env.outputs.deploy_env }}
|
|
74
|
+
steps:
|
|
75
|
+
- id: set-env
|
|
76
|
+
run: echo "deploy_env=production" >> $GITHUB_OUTPUT
|
|
77
|
+
|
|
78
|
+
deploy:
|
|
79
|
+
needs: compute-env
|
|
80
|
+
if: ${{ needs.compute-env.outputs.deploy_env == 'production' }}
|
|
81
|
+
runs-on: ubuntu-latest
|
|
82
|
+
steps:
|
|
83
|
+
- run: echo "Deploying"
|
|
84
|
+
- language: yaml
|
|
85
|
+
label: "RIGHT — reusable workflow: pass value via inputs not env"
|
|
86
|
+
code: |
|
|
87
|
+
# Caller workflow
|
|
88
|
+
jobs:
|
|
89
|
+
call-deploy:
|
|
90
|
+
uses: ./.github/workflows/deploy.yml
|
|
91
|
+
with:
|
|
92
|
+
environment: production # ✅ pass via inputs, not env
|
|
93
|
+
secrets: inherit
|
|
94
|
+
prevention:
|
|
95
|
+
- "Consult the GitHub docs context availability table before writing expressions — not all contexts are available at every YAML key position."
|
|
96
|
+
- "For job-level if conditions, use `vars.*`, `github.*`, or `needs.<job>.outputs.*` — never `env.*`."
|
|
97
|
+
- "For reusable workflow inputs, pass values explicitly through `with:` inputs rather than relying on caller env context."
|
|
98
|
+
- "Use `vars` (repository/environment variables) as a replacement for env-based feature flags that need to be available at job evaluation time."
|
|
99
|
+
docs:
|
|
100
|
+
- url: "https://docs.github.com/en/actions/writing-workflows/choosing-what-your-workflow-does/accessing-contextual-information-about-workflow-runs#context-availability"
|
|
101
|
+
label: "Context availability — which contexts are available at each YAML key"
|
|
102
|
+
- url: "https://github.com/actions/runner/issues/1189"
|
|
103
|
+
label: "actions/runner #1189 — Unrecognized named-value: 'env' for job conditional"
|
|
104
|
+
- url: "https://github.com/actions/runner/issues/1661"
|
|
105
|
+
label: "actions/runner #1661 — env unrecognised in job-level if when calling reusable workflow"
|
|
106
|
+
- url: "https://github.com/actions/runner/issues/2372"
|
|
107
|
+
label: "actions/runner #2372 — Unrecognized named-value: 'env' in reusable workflow jobs"
|
|
108
|
+
- url: "https://stackoverflow.com/questions/76471787/why-is-env-context-not-available-in-github-action-job-level-if-statement"
|
|
109
|
+
label: "Stack Overflow — Why is env context not available in job level if statement?"
|
package/package.json
CHANGED