@htekdev/actions-debugger 1.0.55 → 1.0.56

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,124 @@
1
+ id: known-unsolved-037
2
+ title: "Skipped jobs show as 'skipped' — branch protection required status checks block PR merge"
3
+ category: known-unsolved
4
+ severity: limitation
5
+ tags:
6
+ - required-status-checks
7
+ - branch-protection
8
+ - skipped
9
+ - conditional-job
10
+ - merge-blocked
11
+ - known-limitation
12
+ patterns:
13
+ - regex: 'if:\s+github\.event_name\s+!=\s+'
14
+ flags: i
15
+ - regex: 'if:\s+\$\{\{\s*github\.event_name\s*!=\s*'
16
+ flags: i
17
+ error_messages:
18
+ - "Required status check 'ci/test' was not successful — status: skipped"
19
+ - "Branch protection rule requires passing status checks before merging"
20
+ root_cause: |
21
+ When a job's if: condition evaluates to false, GitHub Actions marks that job as
22
+ "Skipped" in the Checks API. Branch protection rules that require a specific check
23
+ to pass only accept a conclusion of "success" — not "skipped", "cancelled", or
24
+ "neutral".
25
+
26
+ This creates a practical trap: a team sets up a required check for a job like
27
+ ci/test, then later adds an if: condition to skip that job on certain events
28
+ (for example, to avoid running tests on tag pushes or documentation-only changes).
29
+ The conditional logic is correct for workflow execution, but the skipped conclusion
30
+ permanently blocks all PRs where that condition evaluates to false.
31
+
32
+ GitHub has documented this as intentional: a skipped job is not a successful job.
33
+ There is no configuration option to treat "skipped" as equivalent to "success" for
34
+ branch protection purposes as of 2026. The workaround requires a structural change
35
+ to the workflow.
36
+ fix: |
37
+ This is a known limitation with no direct fix. The recommended workarounds are:
38
+
39
+ 1. ALWAYS-PASS WRAPPER JOB: Create a wrapper job that always runs and reports
40
+ the real outcome. The wrapper job becomes the required status check instead of
41
+ the real CI job. If CI was skipped (e.g., docs-only change), the wrapper passes.
42
+ If CI ran and failed, the wrapper fails.
43
+
44
+ 2. MOVE THE CONDITION INSIDE THE JOB: Instead of using if: at the job level, keep
45
+ the job always running and use if: at the step level. An empty job always
46
+ succeeds, so the required status check passes.
47
+
48
+ 3. PATHS FILTER PATTERN (dorny/paths-filter): Use a separate filtering job and
49
+ pass its output as a condition parameter to downstream jobs while keeping a
50
+ pass-through job for status check reporting.
51
+
52
+ 4. RE-EVALUATE THE REQUIRED CHECK: If the check is truly optional for some events,
53
+ consider removing it from required status checks and instead enforce it only at
54
+ the merge queue level.
55
+ fix_code:
56
+ - language: yaml
57
+ label: "Problem: conditional job is skipped, blocking required status check"
58
+ code: |
59
+ on: [push, pull_request]
60
+
61
+ jobs:
62
+ test:
63
+ runs-on: ubuntu-latest
64
+ # This job is required in branch protection, but gets skipped on push to main
65
+ if: github.event_name == 'pull_request'
66
+ steps:
67
+ - run: npm test
68
+ # On push events, this job is SKIPPED, blocking required status check
69
+ - language: yaml
70
+ label: "Fix: always-pass wrapper job becomes the required status check"
71
+ code: |
72
+ on: [push, pull_request]
73
+
74
+ jobs:
75
+ test:
76
+ runs-on: ubuntu-latest
77
+ if: github.event_name == 'pull_request'
78
+ steps:
79
+ - uses: actions/checkout@v4
80
+ - run: npm test
81
+
82
+ # Set THIS job as the required status check in branch protection
83
+ ci-status:
84
+ runs-on: ubuntu-latest
85
+ needs: [test]
86
+ if: always()
87
+ steps:
88
+ - name: Report CI result
89
+ run: |
90
+ result="${{ needs.test.result }}"
91
+ if [[ "$result" == "success" || "$result" == "skipped" ]]; then
92
+ echo "CI passed or was intentionally skipped — OK to merge"
93
+ else
94
+ echo "CI failed (result: $result)"
95
+ exit 1
96
+ fi
97
+ - language: yaml
98
+ label: "Alternative: move condition inside job so job always runs and passes when empty"
99
+ code: |
100
+ on: [push, pull_request]
101
+
102
+ jobs:
103
+ test:
104
+ runs-on: ubuntu-latest
105
+ # No if: at job level — job always runs and always produces a conclusion
106
+ steps:
107
+ - uses: actions/checkout@v4
108
+
109
+ - name: Run tests (pull_request only)
110
+ if: github.event_name == 'pull_request'
111
+ run: npm test
112
+ # If step is skipped, job still succeeds — required check passes
113
+ prevention:
114
+ - "Never add an if: condition to a job that is a required status check — use a wrapper job instead"
115
+ - "Use the always-pass wrapper pattern from the start when adding new required status checks"
116
+ - "Test required check behavior by creating a draft PR that intentionally triggers the skip condition"
117
+ - "Document which jobs are required status checks in a comment at the top of the workflow file"
118
+ docs:
119
+ - url: "https://docs.github.com/en/repositories/configuring-branches-and-merges-in-your-repository/managing-protected-branches/troubleshooting-required-status-checks"
120
+ label: "GitHub Docs: Troubleshooting required status checks"
121
+ - url: "https://docs.github.com/en/actions/writing-workflows/workflow-syntax-for-github-actions#jobsjob_idif"
122
+ label: "GitHub Docs: Job-level if conditions"
123
+ - url: "https://github.com/dorny/paths-filter"
124
+ label: "dorny/paths-filter: Conditional execution with status reporting"
@@ -0,0 +1,142 @@
1
+ id: permissions-auth-040
2
+ title: "GITHUB_TOKEN is read-only by default in new repositories — write operations fail with 403"
3
+ category: permissions-auth
4
+ severity: error
5
+ tags:
6
+ - GITHUB_TOKEN
7
+ - read-only
8
+ - permissions
9
+ - 403
10
+ - new-repo
11
+ - workflow-permissions
12
+ patterns:
13
+ - regex: 'remote:\s*Permission to .* denied to github-actions\[bot\]'
14
+ flags: i
15
+ - regex: 'Error:\s*Resource not accessible by integration'
16
+ flags: i
17
+ - regex: 'HttpError:\s*Resource not accessible by integration'
18
+ flags: i
19
+ - regex: '403.*github-actions\[bot\]'
20
+ flags: i
21
+ error_messages:
22
+ - "remote: Permission to org/repo.git denied to github-actions[bot]"
23
+ - "Error: Resource not accessible by integration"
24
+ - "HttpError: Resource not accessible by integration"
25
+ - "fatal: unable to access 'https://github.com/org/repo/': The requested URL returned error: 403"
26
+ - "GitHub Actions is not permitted to create or approve pull requests"
27
+ root_cause: |
28
+ In February 2023 (GitHub Changelog), GitHub changed the default GITHUB_TOKEN
29
+ permissions for all new repositories and new organizations from read-write to
30
+ read-only. Repositories created before this change retain their original default
31
+ (read-write) unless an administrator explicitly changes the org-level setting.
32
+
33
+ This creates two failure scenarios:
34
+
35
+ 1. COPIED WORKFLOWS: A developer copies a workflow from an older repo or a public
36
+ template that relies on the default read-write GITHUB_TOKEN (for example, to push
37
+ a build artifact, create a release, comment on a PR, or open a pull request). In a
38
+ new repo, that same workflow fails with 403 or "Resource not accessible by
39
+ integration" because the token only has read permissions.
40
+
41
+ 2. ORG POLICY CHANGE: An organization administrator enables the read-only default
42
+ at the organization level (Settings > Actions > General > Workflow permissions).
43
+ All repos in the org immediately start failing any workflow that performs write
44
+ operations without an explicit permissions block.
45
+
46
+ The failure message is typically cryptic and does not mention that the root cause is
47
+ the workflow permissions default — it only says the token was denied.
48
+ fix: |
49
+ Add explicit permissions blocks to workflows or jobs that perform write operations.
50
+ GitHub recommends the principle of least privilege: grant only the specific write
51
+ permission needed, not blanket read-write access.
52
+
53
+ At the workflow level, a top-level permissions: block sets defaults for all jobs.
54
+ At the job level, a permissions: block overrides the workflow-level default for that
55
+ job only. Job-level is preferred — it minimises the blast radius if a job is
56
+ compromised.
57
+
58
+ Common permissions needed:
59
+ - contents: write — push commits, create releases, upload release assets
60
+ - pull-requests: write — create/comment on pull requests
61
+ - issues: write — create/comment on issues
62
+ - packages: write — publish to GitHub Packages
63
+ - pages: write — deploy to GitHub Pages (also needs id-token: write for OIDC)
64
+
65
+ Alternatively, change the default at repo level: Settings > Actions > General >
66
+ Workflow permissions > Read and write permissions. Not recommended for security-
67
+ conscious teams.
68
+ fix_code:
69
+ - language: yaml
70
+ label: "Problem: workflow relies on default write token, fails in new repos"
71
+ code: |
72
+ # No permissions block — relies on default, which is READ-ONLY in new repos
73
+ on: push
74
+
75
+ jobs:
76
+ release:
77
+ runs-on: ubuntu-latest
78
+ steps:
79
+ - uses: actions/checkout@v4
80
+ - name: Build
81
+ run: npm run build
82
+ - name: Create GitHub Release
83
+ uses: softprops/action-gh-release@v2
84
+ with:
85
+ files: dist/**
86
+ # Fails with 403 in new repos — needs contents:write
87
+ - language: yaml
88
+ label: "Fix: explicit job-level permissions (least privilege)"
89
+ code: |
90
+ on: push
91
+
92
+ jobs:
93
+ release:
94
+ runs-on: ubuntu-latest
95
+ permissions:
96
+ contents: write # Required to create releases and upload assets
97
+ steps:
98
+ - uses: actions/checkout@v4
99
+ - name: Build
100
+ run: npm run build
101
+ - name: Create GitHub Release
102
+ uses: softprops/action-gh-release@v2
103
+ with:
104
+ files: dist/**
105
+ - language: yaml
106
+ label: "Workflow-level permissions (when multiple jobs all need write access)"
107
+ code: |
108
+ on: push
109
+
110
+ # Set workflow-level default — overridden per job as needed
111
+ permissions:
112
+ contents: write
113
+ pull-requests: write
114
+
115
+ jobs:
116
+ build-and-release:
117
+ runs-on: ubuntu-latest
118
+ # Inherits workflow-level permissions
119
+ steps:
120
+ - uses: actions/checkout@v4
121
+ - run: npm run build
122
+
123
+ comment-on-pr:
124
+ runs-on: ubuntu-latest
125
+ permissions:
126
+ pull-requests: write # Job-level — more restrictive than workflow default
127
+ contents: read
128
+ steps:
129
+ - uses: actions/checkout@v4
130
+ prevention:
131
+ - "Always declare explicit permissions blocks in workflows that push, create releases, comment, or deploy — never rely on defaults"
132
+ - "Run 'actionlint' locally — it warns when a workflow uses write-requiring actions without corresponding permissions"
133
+ - "Use the minimum permissions required: grant 'contents: write' only on jobs that need it, not at workflow level"
134
+ - "When copying a workflow from another repo, check whether it has a permissions block — add one if missing"
135
+ - "Review the GitHub Actions audit log when a workflow fails with 403 to confirm the token permissions in use"
136
+ docs:
137
+ - url: "https://docs.github.com/en/actions/security-for-github-actions/security-guides/automatic-token-authentication#permissions-for-the-github_token"
138
+ label: "GitHub Docs: GITHUB_TOKEN permissions"
139
+ - url: "https://docs.github.com/en/repositories/managing-your-repositorys-settings-and-features/enabling-features-for-your-repository/managing-github-actions-settings-for-a-repository#setting-the-permissions-of-the-github_token-for-your-repository"
140
+ label: "GitHub Docs: Setting default workflow permissions"
141
+ - url: "https://github.blog/changelog/2023-02-02-github-actions-updating-the-default-github_token-permissions-to-read-only/"
142
+ label: "GitHub Changelog: Default GITHUB_TOKEN permissions changed to read-only (Feb 2023)"
@@ -0,0 +1,105 @@
1
+ id: silent-failures-056
2
+ title: "'continue-on-error: true' makes a failed job report success in required status checks"
3
+ category: silent-failures
4
+ severity: silent-failure
5
+ tags:
6
+ - continue-on-error
7
+ - required-status-checks
8
+ - branch-protection
9
+ - checks-api
10
+ - silent
11
+ - branch-protection-bypass
12
+ patterns:
13
+ - regex: 'continue-on-error:\s*true'
14
+ flags: i
15
+ error_messages:
16
+ - "Job succeeded (continue-on-error)"
17
+ - "Required status check passed (job actually failed but continue-on-error: true)"
18
+ root_cause: |
19
+ When a job has continue-on-error: true set, GitHub Actions converts the job's conclusion
20
+ from failure to success before writing the result to the Checks API. The branch
21
+ protection system only sees the API-level conclusion — which is "success" — and allows
22
+ the pull request to merge.
23
+
24
+ The job timeline in the GitHub UI shows a yellow icon with "(Cancelled)" or similar
25
+ wording, but the Checks API and branch protection treat it as passed. Developers
26
+ relying on required status checks to enforce quality gates unknowingly lose that
27
+ protection for any job marked continue-on-error: true.
28
+
29
+ This is particularly dangerous on jobs that run security scans, license checks, or
30
+ integration tests where the team deliberately added them as required checks to block
31
+ broken or risky changes from merging.
32
+ fix: |
33
+ Avoid using continue-on-error: true on jobs that are configured as required status
34
+ checks in branch protection rules. Instead, handle acceptable failure conditions
35
+ explicitly inside the job using if: steps.*.outcome == 'failure' logic.
36
+
37
+ If you need to always continue a workflow past a flaky or optional step but still
38
+ surface failures in status checks, use a separate sentinel job that:
39
+ 1. Depends on the real job with needs:
40
+ 2. Runs with if: always()
41
+ 3. Fails explicitly if the upstream job failed
42
+
43
+ This pattern separates "keep the workflow running" from "record the real outcome".
44
+ fix_code:
45
+ - language: yaml
46
+ label: "Problem: continue-on-error silently hides failures from status checks"
47
+ code: |
48
+ jobs:
49
+ security-scan:
50
+ runs-on: ubuntu-latest
51
+ continue-on-error: true # DANGER: required status check will PASS even if scan fails
52
+ steps:
53
+ - name: Run security scan
54
+ run: ./run-scan.sh
55
+ - language: yaml
56
+ label: "Fix: use a sentinel job to preserve the real outcome"
57
+ code: |
58
+ jobs:
59
+ security-scan:
60
+ runs-on: ubuntu-latest
61
+ # No continue-on-error here
62
+ steps:
63
+ - name: Run security scan
64
+ run: ./run-scan.sh
65
+
66
+ # This is the job to set as the required status check
67
+ security-gate:
68
+ runs-on: ubuntu-latest
69
+ needs: [security-scan]
70
+ if: always()
71
+ steps:
72
+ - name: Check security scan result
73
+ if: needs.security-scan.result != 'success'
74
+ run: |
75
+ echo "Security scan did not pass (result: ${{ needs.security-scan.result }})"
76
+ exit 1
77
+ - language: yaml
78
+ label: "Alternative: handle acceptable failures inside the step, not the job"
79
+ code: |
80
+ jobs:
81
+ test:
82
+ runs-on: ubuntu-latest
83
+ steps:
84
+ - name: Run optional extended tests
85
+ id: extended
86
+ run: ./run-extended-tests.sh
87
+ continue-on-error: true # Step-level is safer than job-level
88
+
89
+ - name: Fail job if extended tests failed unexpectedly
90
+ if: steps.extended.outcome == 'failure'
91
+ run: |
92
+ echo "Extended tests failed — blocking merge"
93
+ exit 1
94
+ prevention:
95
+ - "Never set continue-on-error: true at the job level for jobs that are required status checks"
96
+ - "Use continue-on-error: true at the step level instead — it does not affect the Checks API job conclusion"
97
+ - "Audit your branch protection required checks against all jobs that have continue-on-error: true"
98
+ - "Use the sentinel job pattern to separate workflow continuation from status reporting"
99
+ docs:
100
+ - url: "https://docs.github.com/en/actions/writing-workflows/workflow-syntax-for-github-actions#jobsjob_idcontinue-on-error"
101
+ label: "GitHub Docs: continue-on-error syntax"
102
+ - url: "https://docs.github.com/en/repositories/configuring-branches-and-merges-in-your-repository/managing-protected-branches/about-protected-branches#require-status-checks-before-merging"
103
+ label: "GitHub Docs: Required status checks before merging"
104
+ - url: "https://docs.github.com/en/rest/checks/runs"
105
+ label: "GitHub REST API: Checks runs"
@@ -0,0 +1,104 @@
1
+ id: triggers-040
2
+ title: "Missing 'on: merge_group' trigger — required status checks fail in merge queue"
3
+ category: triggers
4
+ severity: error
5
+ tags:
6
+ - merge-queue
7
+ - merge_group
8
+ - required-status-checks
9
+ - branch-protection
10
+ - ci-failure
11
+ - triggers
12
+ patterns:
13
+ - regex: 'merge_group'
14
+ flags: i
15
+ - regex: 'Required status checks were not passing.*merge.queue'
16
+ flags: i
17
+ error_messages:
18
+ - "Required status check 'ci/test' was not reported — PR ejected from merge queue"
19
+ - "This branch requires linear history. The merge queue could not merge this pull request."
20
+ root_cause: |
21
+ GitHub's merge queue (available since May 2023 GA) uses a dedicated event called
22
+ merge_group to trigger workflows. This is distinct from the pull_request event.
23
+
24
+ When a pull request enters the merge queue, GitHub creates a temporary merge branch
25
+ and fires the merge_group event. Workflows that only declare on: pull_request (or
26
+ other events) do not trigger on merge_group and therefore never create any status
27
+ check runs for the queued PR.
28
+
29
+ Branch protection rules that require specific status checks see no check result for
30
+ the merge group run and treat the absence as failure, ejecting the PR from the queue
31
+ with a message that the required checks were not passing.
32
+
33
+ The merge queue was added to GitHub Actions in May 2023 (GitHub Changelog). Existing
34
+ workflows created before that date have no merge_group trigger and must be updated
35
+ manually. Projects that enable merge queue on an existing repo will silently find
36
+ that all PRs are blocked from being merged via the queue.
37
+ fix: |
38
+ Add merge_group: to the on: trigger block alongside pull_request (and push, if used).
39
+ The merge_group event accepts no filter options — it fires whenever any PR enters
40
+ the merge queue for a protected branch.
41
+
42
+ If your workflow uses branch filters under on.pull_request.branches, those filters
43
+ do NOT apply to merge_group — the event always fires regardless of branch name.
44
+ This is intentional: the merge queue uses temporary synthetic branches.
45
+ fix_code:
46
+ - language: yaml
47
+ label: "Problem: workflow only triggers on pull_request, not in merge queue"
48
+ code: |
49
+ # BEFORE: only runs on pull_request — never fires in merge queue
50
+ on:
51
+ pull_request:
52
+ branches: [main]
53
+
54
+ jobs:
55
+ test:
56
+ runs-on: ubuntu-latest
57
+ steps:
58
+ - uses: actions/checkout@v4
59
+ - run: npm test
60
+ - language: yaml
61
+ label: "Fix: add merge_group trigger so CI runs in the merge queue"
62
+ code: |
63
+ # AFTER: runs on both pull_request and when entering the merge queue
64
+ on:
65
+ pull_request:
66
+ branches: [main]
67
+ merge_group: # Required for merge queue — no filter options available
68
+
69
+ jobs:
70
+ test:
71
+ runs-on: ubuntu-latest
72
+ steps:
73
+ - uses: actions/checkout@v4
74
+ - run: npm test
75
+ - language: yaml
76
+ label: "With push trigger (common three-trigger pattern)"
77
+ code: |
78
+ on:
79
+ push:
80
+ branches: [main]
81
+ pull_request:
82
+ branches: [main]
83
+ merge_group: # Always needed if merge queue is enabled on the repo
84
+
85
+ jobs:
86
+ ci:
87
+ runs-on: ubuntu-latest
88
+ steps:
89
+ - uses: actions/checkout@v4
90
+ - run: npm ci
91
+ - run: npm test
92
+ - run: npm run lint
93
+ prevention:
94
+ - "Any time you enable merge queue on a branch, audit all required-check workflows and add 'merge_group:' to each"
95
+ - "The merge_group event accepts no filter keys — do not try to add 'branches:' or 'types:' under it"
96
+ - "Test merge queue behavior by adding a PR to the queue and checking the Actions tab for the merge group run"
97
+ - "Add a comment near the merge_group trigger explaining its purpose for teammates unfamiliar with merge queues"
98
+ docs:
99
+ - url: "https://docs.github.com/en/actions/writing-workflows/choosing-when-your-workflow-runs/events-that-trigger-workflows#merge_group"
100
+ label: "GitHub Docs: merge_group event"
101
+ - url: "https://docs.github.com/en/repositories/configuring-branches-and-merges-in-your-repository/configuring-pull-request-merges/managing-a-merge-queue"
102
+ label: "GitHub Docs: Managing a merge queue"
103
+ - url: "https://github.blog/changelog/2023-05-12-github-actions-merge-queue-is-generally-available/"
104
+ label: "GitHub Changelog: Merge queue GA (May 2023)"
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@htekdev/actions-debugger",
3
- "version": "1.0.55",
3
+ "version": "1.0.56",
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",