@htekdev/actions-debugger 1.0.88 → 1.0.89

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,93 @@
1
+ id: silent-failures-082
2
+ title: "pull_request_target checkout defaults to base branch, not PR head"
3
+ category: silent-failures
4
+ severity: silent-failure
5
+ tags:
6
+ - pull_request_target
7
+ - checkout
8
+ - security
9
+ - fork
10
+ - base-branch
11
+ patterns:
12
+ - regex: 'on:\s*\n\s+pull_request_target'
13
+ flags: 'im'
14
+ - regex: 'pull_request_target'
15
+ flags: 'i'
16
+ error_messages:
17
+ - "Workflow runs on base branch code instead of PR contributor changes"
18
+ - "Tests pass on base but fail on PR code with no visible error in logs"
19
+ root_cause: |
20
+ When a workflow is triggered by `pull_request_target`, GitHub Actions runs the workflow
21
+ from the TARGET repository's base branch — not the contributor's PR head. This is
22
+ intentional: `pull_request_target` provides write-level token access (for labeling,
23
+ commenting, posting status checks), so GitHub protects secrets by refusing to run
24
+ untrusted fork code with elevated permissions.
25
+
26
+ As a result, `actions/checkout` checks out `github.sha`, which resolves to the merge
27
+ base commit on the target branch. Any tests, linting, or code analysis in this
28
+ workflow validate the base branch, not the contributor's changes. The workflow
29
+ succeeds silently while testing the wrong code.
30
+ fix: |
31
+ Option 1 (recommended — safe): Use `pull_request` (not `pull_request_target`) for
32
+ running PR code. `pull_request` triggers run with read-only tokens and check out the
33
+ PR head by default. Use `pull_request_target` only for privileged actions like posting
34
+ comments or labels.
35
+
36
+ Option 2 (explicit checkout — use with caution): Explicitly check out the PR head
37
+ using `github.event.pull_request.head.sha`. Only do this if you fully trust all
38
+ contributors and understand that fork code will execute with the repository write token.
39
+ fix_code:
40
+ - language: yaml
41
+ label: "Recommended: use pull_request for code execution, pull_request_target for privileged writes"
42
+ code: |
43
+ # Workflow 1: run tests on PR code (read-only, safe for forks)
44
+ on:
45
+ pull_request:
46
+ branches: [main]
47
+
48
+ jobs:
49
+ test:
50
+ runs-on: ubuntu-latest
51
+ steps:
52
+ - uses: actions/checkout@v4
53
+ # Checks out PR head automatically — no ref: override needed
54
+ - run: npm test
55
+
56
+ ---
57
+ # Workflow 2: post labels (write access via pull_request_target)
58
+ on:
59
+ pull_request_target:
60
+ types: [opened]
61
+
62
+ jobs:
63
+ label:
64
+ runs-on: ubuntu-latest
65
+ permissions:
66
+ pull-requests: write
67
+ steps:
68
+ - uses: actions/labeler@v5
69
+ # Never runs contributor code here — only labels the PR
70
+ - language: yaml
71
+ label: "If you must run PR code under pull_request_target (risky)"
72
+ code: |
73
+ on:
74
+ pull_request_target:
75
+ branches: [main]
76
+
77
+ jobs:
78
+ test:
79
+ runs-on: ubuntu-latest
80
+ steps:
81
+ - uses: actions/checkout@v4
82
+ with:
83
+ ref: ${{ github.event.pull_request.head.sha }}
84
+ # WARNING: executes untrusted fork code with write-level token
85
+ prevention:
86
+ - "Use pull_request (not pull_request_target) for workflows that run code — pull_request tokens are read-only and checkout the PR head correctly by default"
87
+ - "Reserve pull_request_target for privileged write-only actions: posting comments, applying labels, updating statuses — never checkout and execute untrusted PR code in these workflows"
88
+ - "If CI consistently passes but reviewers find bugs tests should catch, verify which commit your checkout step is using by printing github.sha vs github.event.pull_request.head.sha"
89
+ docs:
90
+ - url: "https://docs.github.com/en/actions/writing-workflows/choosing-when-your-workflow-runs/events-that-trigger-workflows#pull_request_target"
91
+ label: "pull_request_target event — security considerations"
92
+ - url: "https://securitylab.github.com/research/github-actions-preventing-pwn-requests/"
93
+ label: "GitHub Security Lab: Preventing pwn requests (pull_request_target risks)"
@@ -0,0 +1,64 @@
1
+ id: silent-failures-083
2
+ title: "matrix strategy fail-fast true by default silently cancels all remaining jobs on first failure"
3
+ category: silent-failures
4
+ severity: silent-failure
5
+ tags:
6
+ - matrix
7
+ - fail-fast
8
+ - cancellation
9
+ - strategy
10
+ - parallel-jobs
11
+ patterns:
12
+ - regex: 'strategy:\s*\n\s+matrix:'
13
+ flags: 'im'
14
+ - regex: 'Some jobs were not executed because a previous required job failed'
15
+ flags: 'i'
16
+ error_messages:
17
+ - "Some jobs were not executed because a previous required job failed"
18
+ - "Skipping this step because a previous step failed or the workflow was cancelled"
19
+ - "This job was cancelled because another job in the workflow failed"
20
+ root_cause: |
21
+ GitHub Actions matrix strategy has `fail-fast: true` as the default. When any single
22
+ matrix job fails, GitHub immediately cancels all remaining in-progress and queued
23
+ matrix jobs from the same workflow run.
24
+
25
+ This means:
26
+ - You only see the failure from the first (or earliest) failing matrix combination
27
+ - All other combinations — whether they would pass or fail — are cancelled immediately
28
+ - The workflow summary shows cancelled jobs with no diagnostic information
29
+ - Developers may spend time fixing the first failure only to discover a second unrelated
30
+ failure in a different matrix combination afterward
31
+
32
+ Many developers set up matrix builds specifically to validate across multiple
33
+ OS/language version combinations and expect every combination to run to completion.
34
+ fix: |
35
+ Explicitly set `fail-fast: false` in your matrix strategy to allow all matrix jobs to
36
+ run to completion regardless of individual failures. This provides a complete picture
37
+ of which matrix combinations are broken.
38
+ fix_code:
39
+ - language: yaml
40
+ label: "Set fail-fast: false to run all matrix combinations to completion"
41
+ code: |
42
+ jobs:
43
+ test:
44
+ strategy:
45
+ fail-fast: false # default is true — set false for full matrix visibility
46
+ matrix:
47
+ os: [ubuntu-latest, windows-latest, macos-latest]
48
+ node: [18, 20, 22]
49
+ runs-on: ${{ matrix.os }}
50
+ steps:
51
+ - uses: actions/checkout@v4
52
+ - uses: actions/setup-node@v4
53
+ with:
54
+ node-version: ${{ matrix.node }}
55
+ - run: npm test
56
+ prevention:
57
+ - "Always explicitly set fail-fast: false when you want all matrix combinations to run — for example when building cross-platform or cross-version compatibility matrices"
58
+ - "The default fail-fast: true is intentional for workflows where you only care about any single failure (saves CI minutes), but must be changed when you need full failure visibility"
59
+ - "If matrix jobs are silently cancelled and show no error output, check whether fail-fast: true (or its absence — the default) is the cause"
60
+ docs:
61
+ - url: "https://docs.github.com/en/actions/writing-workflows/workflow-syntax-for-github-actions#jobsjob_idstrategyfail-fast"
62
+ label: "jobs.<job_id>.strategy.fail-fast documentation"
63
+ - url: "https://docs.github.com/en/actions/writing-workflows/workflow-syntax-for-github-actions#jobsjob_idstrategymatrix"
64
+ label: "Matrix strategy documentation"
@@ -0,0 +1,96 @@
1
+ id: silent-failures-084
2
+ title: "github.sha on pull_request event is the ephemeral merge commit SHA, not the PR head commit"
3
+ category: silent-failures
4
+ severity: silent-failure
5
+ tags:
6
+ - github-sha
7
+ - pull_request
8
+ - merge-commit
9
+ - docker
10
+ - tagging
11
+ - status-checks
12
+ patterns:
13
+ - regex: '\$\{\{\s*github\.sha\s*\}\}'
14
+ flags: 'i'
15
+ - regex: 'github\.sha'
16
+ flags: 'i'
17
+ error_messages:
18
+ - "Docker image tagged with SHA not found in git history"
19
+ - "Deployment status does not appear on the PR commit"
20
+ - "Commit status check not visible on pull request"
21
+ root_cause: |
22
+ On `pull_request` events, `github.sha` is NOT the PR branch's head commit SHA. It is
23
+ the SHA of a temporary merge commit that GitHub creates automatically to simulate
24
+ "what would happen if this PR were merged right now." This ephemeral merge commit:
25
+
26
+ - Does NOT appear in the repository's git history
27
+ - Changes every time the base branch advances, even with no new PR commits
28
+ - Is not accessible via normal git operations outside the workflow run
29
+
30
+ Consequences developers hit in the wild:
31
+ - Docker images tagged with `github.sha` have tags that don't correspond to any real
32
+ commit, making rollbacks and tracing impossible
33
+ - Commit status checks or deployment markers posted to `github.sha` don't appear on
34
+ any commit in the PR and are effectively invisible to reviewers
35
+ - Scripts that fetch the commit from the API using github.sha return 404
36
+
37
+ The actual PR head commit SHA is available via `github.event.pull_request.head.sha`.
38
+ fix: |
39
+ Use `github.event.pull_request.head.sha` to get the actual PR head commit on
40
+ pull_request events. For workflows triggered by both push and pull_request, use a
41
+ conditional to select the correct SHA per event type.
42
+ fix_code:
43
+ - language: yaml
44
+ label: "Get the correct SHA for both push and pull_request events"
45
+ code: |
46
+ jobs:
47
+ build:
48
+ runs-on: ubuntu-latest
49
+ steps:
50
+ - uses: actions/checkout@v4
51
+
52
+ - name: Resolve commit SHA
53
+ id: sha
54
+ run: |
55
+ if [ "${{ github.event_name }}" = "pull_request" ]; then
56
+ echo "value=${{ github.event.pull_request.head.sha }}" >> $GITHUB_OUTPUT
57
+ else
58
+ echo "value=${{ github.sha }}" >> $GITHUB_OUTPUT
59
+ fi
60
+
61
+ - name: Tag Docker image with correct SHA
62
+ run: |
63
+ docker build -t myapp:${{ steps.sha.outputs.value }} .
64
+ docker push myapp:${{ steps.sha.outputs.value }}
65
+ - language: yaml
66
+ label: "Post commit status to the correct PR head SHA"
67
+ code: |
68
+ on:
69
+ pull_request:
70
+
71
+ jobs:
72
+ status:
73
+ runs-on: ubuntu-latest
74
+ steps:
75
+ - name: Post status to actual PR commit
76
+ uses: actions/github-script@v7
77
+ with:
78
+ script: |
79
+ // Use PR head SHA, not github.sha (merge commit)
80
+ await github.rest.repos.createCommitStatus({
81
+ owner: context.repo.owner,
82
+ repo: context.repo.repo,
83
+ sha: context.payload.pull_request.head.sha,
84
+ state: 'success',
85
+ description: 'Build passed',
86
+ context: 'ci/build'
87
+ });
88
+ prevention:
89
+ - "Never tag Docker images or create commit statuses using github.sha on pull_request events — use github.event.pull_request.head.sha for the real PR head"
90
+ - "If deployment statuses or commit checks are missing from PR commits, verify you are not posting them to github.sha (the merge commit)"
91
+ - "The merge commit SHA changes every time the base branch gets new commits, even without new PR activity — this makes github.sha unstable for artifact tagging on PRs"
92
+ docs:
93
+ - url: "https://docs.github.com/en/actions/writing-workflows/choosing-when-your-workflow-runs/events-that-trigger-workflows#pull_request"
94
+ label: "pull_request event — note on github.sha merge commit"
95
+ - url: "https://docs.github.com/en/actions/writing-workflows/choosing-what-your-workflow-does/accessing-contextual-information-about-workflow-runs#github-context"
96
+ label: "GitHub context — sha property"
@@ -0,0 +1,87 @@
1
+ id: yaml-syntax-056
2
+ title: "env context unavailable inside with: inputs of uses: steps"
3
+ category: yaml-syntax
4
+ severity: error
5
+ tags:
6
+ - env-context
7
+ - with-inputs
8
+ - uses
9
+ - expression-context
10
+ - action-inputs
11
+ patterns:
12
+ - regex: "Unrecognized named-value: 'env'"
13
+ flags: 'i'
14
+ - regex: 'Invalid workflow file.*Unrecognized named-value'
15
+ flags: 'i'
16
+ error_messages:
17
+ - "Unrecognized named-value: 'env'. Located at position 1 within expression: env.MY_VAR"
18
+ - "Invalid workflow file: .github/workflows/ci.yml (Line 14, Col 15): Unrecognized named-value: 'env'"
19
+ - "The workflow is not valid. .github/workflows/build.yml: Unrecognized named-value: 'env'"
20
+ root_cause: |
21
+ The `env` context is NOT available inside the `with:` input block of a `uses:` step.
22
+ GitHub Actions evaluates `uses:` step inputs using a restricted set of contexts, and
23
+ `env` is explicitly excluded because env var values may depend on previous step
24
+ outputs (which are also unavailable at `with:` evaluation time).
25
+
26
+ Contexts available in `with:` inputs: `github`, `needs`, `strategy`, `matrix`,
27
+ `secrets`, `inputs`, `vars`, and `steps` (but only from previously completed steps).
28
+ The `env` context, `runner` context, and job-level env vars are all unavailable.
29
+
30
+ This catches developers who define env vars at the workflow or job level and then try
31
+ to pass them as action inputs, which fails with "Unrecognized named-value: 'env'".
32
+ fix: |
33
+ Three options:
34
+ 1. Reference the value directly (hardcoded or via a different supported context)
35
+ 2. Use `vars` context (repository/org variables) — available in `with:` blocks
36
+ 3. Capture the env value in a prior step's GITHUB_OUTPUT and reference it via
37
+ `steps.<id>.outputs.<name>` in the subsequent `uses:` step
38
+ fix_code:
39
+ - language: yaml
40
+ label: "Wrong: env context in with: inputs (causes parse error)"
41
+ code: |
42
+ env:
43
+ API_URL: https://api.example.com
44
+
45
+ jobs:
46
+ deploy:
47
+ runs-on: ubuntu-latest
48
+ steps:
49
+ - uses: my-org/deploy-action@v1
50
+ with:
51
+ url: ${{ env.API_URL }} # ERROR: Unrecognized named-value: 'env'
52
+ - language: yaml
53
+ label: "Fix option A: use vars context (repository variable)"
54
+ code: |
55
+ # Set API_URL as a repository variable in Settings > Secrets and variables > Variables
56
+ jobs:
57
+ deploy:
58
+ runs-on: ubuntu-latest
59
+ steps:
60
+ - uses: my-org/deploy-action@v1
61
+ with:
62
+ url: ${{ vars.API_URL }} # vars context IS available in with:
63
+ - language: yaml
64
+ label: "Fix option B: capture in prior step output, reference via steps context"
65
+ code: |
66
+ env:
67
+ API_URL: https://api.example.com
68
+
69
+ jobs:
70
+ deploy:
71
+ runs-on: ubuntu-latest
72
+ steps:
73
+ - id: config
74
+ run: echo "api_url=$API_URL" >> $GITHUB_OUTPUT
75
+
76
+ - uses: my-org/deploy-action@v1
77
+ with:
78
+ url: ${{ steps.config.outputs.api_url }} # steps context IS available
79
+ prevention:
80
+ - "In with: inputs, only use: github, needs, strategy, matrix, secrets, inputs, vars, and steps (from prior completed steps) — never env or runner"
81
+ - "For static configuration values, prefer repository variables (vars context) over env — vars are available everywhere env is not"
82
+ - "If you need a dynamically computed value (from a script or env var) in a with: block, capture it to GITHUB_OUTPUT in a prior step and reference via steps.<id>.outputs"
83
+ docs:
84
+ - url: "https://docs.github.com/en/actions/writing-workflows/choosing-what-your-workflow-does/accessing-contextual-information-about-workflow-runs#context-availability"
85
+ label: "Context availability table — which contexts are valid per syntax location"
86
+ - url: "https://docs.github.com/en/actions/writing-workflows/workflow-syntax-for-github-actions#jobsjob_idstepswith"
87
+ label: "jobs.<job_id>.steps[*].with syntax documentation"
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@htekdev/actions-debugger",
3
- "version": "1.0.88",
3
+ "version": "1.0.89",
4
4
  "description": "65+ real GitHub Actions errors, queryable by agents. CLI + MCP server + Copilot skills + error database.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",