@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.
@@ -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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@htekdev/actions-debugger",
3
- "version": "1.0.2",
3
+ "version": "1.0.4",
4
4
  "description": "65+ real GitHub Actions errors, queryable by agents. MCP server + Copilot skills + error database.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",