@htekdev/actions-debugger 1.0.22 → 1.0.24

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.
Files changed (61) hide show
  1. package/errors/caching-artifacts/artifact-minimum-retention-one-day.yml +153 -0
  2. package/errors/caching-artifacts/cache-api-propagation-delay-post-save.yml +128 -0
  3. package/errors/caching-artifacts/cache-backend-internal-error-skipped.yml +75 -0
  4. package/errors/caching-artifacts/cache-hit-step-id-case-sensitive-mismatch.yml +95 -0
  5. package/errors/caching-artifacts/cache-save-post-step-skipped-on-failure.yml +114 -0
  6. package/errors/concurrency-timing/deploy-pages-in-progress-deployment-wedged.yml +70 -0
  7. package/errors/concurrency-timing/deployment-review-timeout-expired.yml +88 -0
  8. package/errors/concurrency-timing/job-concurrency-scope-per-run-not-global.yml +81 -0
  9. package/errors/concurrency-timing/merge-queue-concurrency-cancel-blocks-all.yml +86 -0
  10. package/errors/concurrency-timing/reusable-workflow-github-workflow-context-cancel.yml +124 -0
  11. package/errors/concurrency-timing/runner-scale-set-jobs-never-start.yml +123 -0
  12. package/errors/concurrency-timing/runner-temp-dir-race-concurrent-workers.yml +90 -0
  13. package/errors/known-unsolved/artifact-download-url-unauthenticated-404.yml +98 -0
  14. package/errors/known-unsolved/checkout-v6-credentials-docker-run-manual.yml +105 -0
  15. package/errors/known-unsolved/concurrency-groups-repo-scoped-only.yml +138 -0
  16. package/errors/known-unsolved/matrix-256-job-limit.yml +142 -0
  17. package/errors/known-unsolved/merge-group-paths-filter-not-supported.yml +137 -0
  18. package/errors/known-unsolved/no-job-allow-failure.yml +73 -0
  19. package/errors/known-unsolved/reusable-secrets-inherit-not-deep-forwarded.yml +113 -0
  20. package/errors/known-unsolved/schedule-cron-hours-long-queue-drift.yml +101 -0
  21. package/errors/permissions-auth/checkout-persist-credentials-token-write.yml +90 -0
  22. package/errors/permissions-auth/create-github-app-token-cross-job-token-revoked.yml +95 -0
  23. package/errors/permissions-auth/github-token-contents-write-missing-git-push.yml +117 -0
  24. package/errors/permissions-auth/org-actions-policy-blocks-unapproved-action.yml +106 -0
  25. package/errors/runner-environment/codeql-action-v2-deprecated.yml +110 -0
  26. package/errors/runner-environment/macos-26-openssl-3-system-library-breaking.yml +114 -0
  27. package/errors/runner-environment/macos-26-ruby-34-default-upgrade.yml +114 -0
  28. package/errors/runner-environment/macos-26-xcode-default-265-pin-required.yml +99 -0
  29. package/errors/runner-environment/macos-latest-label-switches-to-macos26.yml +127 -0
  30. package/errors/runner-environment/node20-removed-toolcache-default-node22.yml +104 -0
  31. package/errors/runner-environment/org-runner-group-dispatch-null.yml +102 -0
  32. package/errors/runner-environment/powershell-74-76-threadjob-module-rename.yml +124 -0
  33. package/errors/runner-environment/self-hosted-runner-not-found.yml +134 -0
  34. package/errors/runner-environment/self-hosted-runner-selinux-service-exec-failure.yml +116 -0
  35. package/errors/runner-environment/service-container-no-healthcheck.yml +158 -0
  36. package/errors/runner-environment/setup-node-v5-corepack-pnpm-not-found.yml +101 -0
  37. package/errors/runner-environment/setup-node-yarn-not-installed-self-hosted.yml +76 -0
  38. package/errors/runner-environment/setup-python-externally-managed-env-error.yml +95 -0
  39. package/errors/runner-environment/windows-2019-runner-retired-june2025.yml +118 -0
  40. package/errors/runner-environment/windows-2022-docker-daemon-not-started.yml +108 -0
  41. package/errors/silent-failures/cache-hit-output-string-not-boolean.yml +96 -0
  42. package/errors/silent-failures/checkout-lfs-pointer-not-content.yml +105 -0
  43. package/errors/silent-failures/reusable-workflow-output-skipped-contains-secret.yml +115 -0
  44. package/errors/silent-failures/setup-node-silent-download-exit-zero.yml +105 -0
  45. package/errors/silent-failures/setup-python-truncated-manifest-silent-exit.yml +111 -0
  46. package/errors/silent-failures/undefined-env-expression-empty-string-silent.yml +115 -0
  47. package/errors/silent-failures/windows-powershell-github-output-bash-syntax.yml +118 -0
  48. package/errors/triggers/fork-pr-first-time-contributor-approval-required.yml +142 -0
  49. package/errors/triggers/on-push-branches-glob-star-no-slash-match.yml +78 -0
  50. package/errors/triggers/pull-request-target-env-protection-default-branch-eval.yml +117 -0
  51. package/errors/triggers/required-status-check-renamed-never-passes.yml +87 -0
  52. package/errors/triggers/schedule-cron-self-hosted-runner-not-triggered.yml +107 -0
  53. package/errors/triggers/workflow-run-checkout-uses-default-branch.yml +114 -0
  54. package/errors/yaml-syntax/composite-action-run-shell-missing.yml +90 -0
  55. package/errors/yaml-syntax/composite-action-secrets-context-unavailable.yml +99 -0
  56. package/errors/yaml-syntax/github-script-octokit-renamed-to-github.yml +130 -0
  57. package/errors/yaml-syntax/labeler-v5-config-format-breaking.yml +67 -0
  58. package/errors/yaml-syntax/reusable-workflow-nesting-depth-exceeded.yml +113 -0
  59. package/errors/yaml-syntax/runs-on-expression-array-syntax-error.yml +121 -0
  60. package/errors/yaml-syntax/setup-go-matrix-version-float-coercion.yml +69 -0
  61. package/package.json +1 -1
@@ -0,0 +1,118 @@
1
+ id: silent-failures-034
2
+ title: "Windows PowerShell GITHUB_OUTPUT and GITHUB_ENV Require $env: Prefix, Not Bash-Style $VARIABLE Syntax"
3
+ category: silent-failures
4
+ severity: silent-failure
5
+ tags:
6
+ - windows
7
+ - powershell
8
+ - GITHUB_OUTPUT
9
+ - GITHUB_ENV
10
+ - environment-variables
11
+ - shell-syntax
12
+ patterns:
13
+ - regex: "echo\\s+[\"']?[A-Z_]+=.*>>\\s+\\$GITHUB_OUTPUT"
14
+ flags: "i"
15
+ - regex: "echo\\s+[\"']?[A-Z_]+=.*>>\\s+\\$GITHUB_ENV"
16
+ flags: "i"
17
+ - regex: "shell:\\s*(pwsh|powershell)"
18
+ flags: "i"
19
+ error_messages:
20
+ - "echo \"KEY=value\" >> $GITHUB_OUTPUT"
21
+ - "echo \"KEY=value\" >> $GITHUB_ENV"
22
+ - "Val1: "
23
+ - "Val2: "
24
+ root_cause: |
25
+ When a workflow step uses shell: pwsh (PowerShell Core, the default on Windows
26
+ runners) or shell: powershell (legacy Windows PowerShell), the bash-style
27
+ variable syntax $GITHUB_OUTPUT and $GITHUB_ENV does NOT work.
28
+
29
+ In PowerShell, $GITHUB_OUTPUT is treated as a PowerShell variable (undefined
30
+ and therefore null). The >> append operator writes nothing to a null path.
31
+ The step exits 0 (success) with no error or warning. All downstream jobs
32
+ that reference step outputs or environment variables receive empty strings.
33
+
34
+ The correct PowerShell syntax uses $env:GITHUB_OUTPUT to access the OS
35
+ environment variable, not $GITHUB_OUTPUT (a PS variable).
36
+
37
+ Shell-specific syntax comparison:
38
+ - bash / sh: echo "KEY=val" >> $GITHUB_OUTPUT
39
+ - pwsh (PS 7+): "KEY=val" >> $env:GITHUB_OUTPUT
40
+ - powershell: "KEY=val" | Out-File -FilePath $env:GITHUB_OUTPUT -Encoding utf8 -Append
41
+ - cmd: echo KEY=val >> %GITHUB_OUTPUT%
42
+
43
+ This is a common mistake when:
44
+ - Migrating workflows from Linux to Windows runners
45
+ - Copying bash examples from documentation into PowerShell steps
46
+ - Writing cross-platform workflows without specifying shell: per step
47
+ fix: |
48
+ Replace $GITHUB_OUTPUT with $env:GITHUB_OUTPUT and $GITHUB_ENV with
49
+ $env:GITHUB_ENV in all PowerShell steps.
50
+
51
+ Alternatively, add shell: bash to every run: step that uses bash-style
52
+ syntax — Git Bash is available on all Windows GitHub-hosted runners and
53
+ supports the standard $GITHUB_OUTPUT syntax.
54
+
55
+ For old Windows PowerShell (shell: powershell), use Out-File with
56
+ explicit UTF-8 encoding to avoid BOM issues.
57
+ fix_code:
58
+ - language: yaml
59
+ label: "Broken — bash syntax in PowerShell step silently produces no output"
60
+ code: |
61
+ - name: Set output (broken on PowerShell)
62
+ shell: pwsh
63
+ run: |
64
+ # WRONG: $GITHUB_OUTPUT is a null PS variable — no output is set
65
+ echo "BUILD_VERSION=1.2.3" >> $GITHUB_OUTPUT
66
+
67
+ - language: yaml
68
+ label: "Fixed — correct $env: prefix for PowerShell Core (pwsh)"
69
+ code: |
70
+ - name: Set output (PowerShell Core)
71
+ id: version
72
+ shell: pwsh
73
+ run: |
74
+ # CORRECT: $env:GITHUB_OUTPUT accesses the OS environment variable
75
+ "BUILD_VERSION=1.2.3" >> $env:GITHUB_OUTPUT
76
+
77
+ - name: Use output
78
+ run: echo "Version is ${{ steps.version.outputs.BUILD_VERSION }}"
79
+ shell: pwsh
80
+
81
+ - language: yaml
82
+ label: "Old Windows PowerShell (shell: powershell) — explicit UTF-8 required"
83
+ code: |
84
+ - name: Set output (legacy Windows PowerShell)
85
+ shell: powershell
86
+ run: |
87
+ "BUILD_VERSION=1.2.3" | Out-File -FilePath $env:GITHUB_OUTPUT -Encoding utf8 -Append
88
+
89
+ - language: yaml
90
+ label: "Cross-platform — use shell: bash to keep bash-style syntax on Windows"
91
+ code: |
92
+ - name: Set output (bash on Windows runner)
93
+ shell: bash
94
+ run: |
95
+ # shell: bash uses Git Bash on Windows — $GITHUB_OUTPUT works fine
96
+ echo "BUILD_VERSION=1.2.3" >> $GITHUB_OUTPUT
97
+
98
+ - language: yaml
99
+ label: "CMD shell syntax"
100
+ code: |
101
+ - name: Set output (CMD)
102
+ shell: cmd
103
+ run: echo BUILD_VERSION=1.2.3 >> %GITHUB_OUTPUT%
104
+ prevention:
105
+ - "Use shell: bash for all run: steps that use bash-style $GITHUB_OUTPUT or $GITHUB_ENV syntax, even on Windows runners."
106
+ - "In team workflow templates, document the shell-specific syntax for GITHUB_OUTPUT and GITHUB_ENV."
107
+ - "Add actionlint to CI — it can detect shell/syntax mismatches in workflow files."
108
+ - "Add an explicit post-step validation that reads back expected outputs to confirm they were written correctly."
109
+ - "Prefer shell: bash globally (via defaults: run: shell: bash) when your workflows target cross-platform and use bash syntax."
110
+ docs:
111
+ - url: "https://stackoverflow.com/questions/74443940/value-not-set-using-github-output"
112
+ label: "Stack Overflow: Value not set using $GITHUB_OUTPUT on Windows PowerShell (Score: 22, 17K views)"
113
+ - url: "https://stackoverflow.com/questions/66733076/github-actions-set-environment-variable-for-windows-build-with-powershell"
114
+ label: "Stack Overflow: Set environment variable for Windows build with PowerShell (Score: 16, 11K views)"
115
+ - url: "https://docs.github.com/en/actions/using-workflows/workflow-commands-for-github-actions#setting-an-output-parameter"
116
+ label: "GitHub Docs: Setting an output parameter (includes PowerShell examples)"
117
+ - url: "https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#defaultsrun"
118
+ label: "GitHub Docs: defaults.run.shell — set default shell for all run steps"
@@ -0,0 +1,142 @@
1
+ id: triggers-022
2
+ title: "Fork PR Workflows Paused — First-Time Contributor Requires Approval"
3
+ category: triggers
4
+ severity: warning
5
+ tags:
6
+ - fork
7
+ - pull_request
8
+ - first-time-contributor
9
+ - approval
10
+ - secrets
11
+ - outside-collaborator
12
+ patterns:
13
+ - regex: "This run (?:was triggered by a (?:first-time contributor|new GitHub user)|requires approval)"
14
+ flags: "i"
15
+ - regex: "Workflow run requires approval"
16
+ flags: "i"
17
+ - regex: "requires approval from a maintainer"
18
+ flags: "i"
19
+ - regex: "waiting for approval"
20
+ flags: "i"
21
+ error_messages:
22
+ - "This run was triggered by a first-time contributor and requires approval from a maintainer with write access."
23
+ - "Workflow run requires approval"
24
+ - "This run requires approval from a maintainer with write access."
25
+ root_cause: |
26
+ GitHub requires manual approval before running workflows triggered by pull
27
+ requests from forked repositories when the contributor meets certain criteria.
28
+ This is a security measure to prevent untrusted code from accessing repository
29
+ secrets or running CI at the organization's expense.
30
+
31
+ GitHub's fork PR approval policy (configurable per repo, org, or enterprise)
32
+ determines when approval is required. The default for public repos is:
33
+ "Require approval for first-time contributors who are new to GitHub" — meaning
34
+ contributors who have never contributed to any public GitHub repo need approval
35
+ on their first PR. For private repos, the default is to require approval from
36
+ all outside collaborators.
37
+
38
+ When approval is required, the workflow run is shown in the Actions tab with
39
+ a yellow banner reading "This run was triggered by a first-time contributor
40
+ and requires approval from a maintainer with write access." The workflow does
41
+ not start until a maintainer with write access clicks "Approve and run."
42
+
43
+ Workflows awaiting approval for more than 30 days are automatically deleted.
44
+ Importantly, if no maintainer approves the run, CI results will never appear
45
+ on the pull request — blocking any required status checks from passing and
46
+ preventing the PR from being merged.
47
+
48
+ Three root causes are commonly conflated:
49
+ 1. First-time contributor to GitHub (no prior public repo contributions).
50
+ 2. First-time contributor to this specific repository (even if experienced on GitHub).
51
+ 3. Outside collaborator (not a member of the org that owns the repo).
52
+
53
+ The approval gate is per-workflow-run, not per-PR. If a contributor pushes
54
+ additional commits to an already-approved PR, each new push triggers a new
55
+ run that must be re-approved.
56
+ fix: |
57
+ Option 1 — Approve manually (per-run action):
58
+ Go to the repository's Actions tab → find the pending workflow run with the
59
+ yellow approval banner → click "Approve and run". Repeat for each new commit
60
+ push by the same contributor.
61
+
62
+ Option 2 — Change the approval policy (repo setting):
63
+ Go to Settings → Actions → General → Fork pull request workflows.
64
+ Change from "Require approval for first-time contributors who are new to GitHub"
65
+ to "Require approval for first-time contributors" (blocks all new contributors
66
+ to THIS repo, not all of GitHub) or "Not required" (disables the gate entirely).
67
+ Note: "Not required" means secrets are accessible to fork PR workflows —
68
+ only use this for private repos or repos with no sensitive secrets.
69
+
70
+ Option 3 — Use pull_request_target for secret-free PR workflows:
71
+ If you only need access to repository secrets in a separate, controlled job,
72
+ use pull_request_target instead of pull_request. The pull_request_target
73
+ event runs in the context of the base repo and has access to secrets, but
74
+ you should NEVER check out the PR's code and run it — only read PR metadata.
75
+
76
+ Option 4 — Approve all runs for a contributor via REST API:
77
+ POST /repos/{owner}/{repo}/actions/runs/{run_id}/approve
78
+ Use this to batch-approve pending runs from a trusted contributor programmatically.
79
+ fix_code:
80
+ - language: yaml
81
+ label: "Change approval policy — require approval for first-time contributors to THIS repo only"
82
+ code: |
83
+ # In GitHub UI: Settings → Actions → General → Fork pull request workflows
84
+ # Select: "Require approval for first-time contributors"
85
+ # This is the balanced option — trusts repeat contributors, gates new ones.
86
+
87
+ # For automation workflows that need to run on all fork PRs without approval,
88
+ # use pull_request_target (read-only PR metadata only — NEVER run PR code):
89
+ on:
90
+ pull_request_target:
91
+ types: [opened, synchronize]
92
+
93
+ jobs:
94
+ label:
95
+ runs-on: ubuntu-latest
96
+ permissions:
97
+ pull-requests: write
98
+ steps:
99
+ - name: Label first-time contributor
100
+ uses: actions/github-script@v7
101
+ with:
102
+ script: |
103
+ const pr = context.payload.pull_request;
104
+ if (pr.author_association === 'FIRST_TIME_CONTRIBUTOR') {
105
+ await github.rest.issues.addLabels({
106
+ owner: context.repo.owner,
107
+ repo: context.repo.repo,
108
+ issue_number: pr.number,
109
+ labels: ['first-time-contributor']
110
+ });
111
+ }
112
+ - language: yaml
113
+ label: "Separate workflow — gate secrets behind explicit approval check"
114
+ code: |
115
+ # Use pull_request for the CI job (no secrets, runs on fork code safely)
116
+ # Use pull_request_target with environment protection for secret-requiring jobs
117
+ on:
118
+ pull_request:
119
+ branches: [main]
120
+
121
+ jobs:
122
+ test:
123
+ runs-on: ubuntu-latest
124
+ steps:
125
+ - uses: actions/checkout@v4
126
+ - run: npm test
127
+ # No secrets needed — runs without approval gate
128
+ prevention:
129
+ - "Document in CONTRIBUTING.md that first-time contributors' CI runs require maintainer approval before they start — set expectations early."
130
+ - "Set the approval policy to 'Require approval for first-time contributors' (not 'new to GitHub') to minimize repeated approvals for experienced contributors who are new to your repo."
131
+ - "Use separate workflow files for CI (no secrets, runs on pull_request) and deployment/release (needs secrets, runs on merge to main) — this reduces how often the approval gate is hit."
132
+ - "For open-source projects with many external PRs, consider a bot that auto-approves workflow runs from contributors who have already passed a one-time review (e.g., using the approve-run REST API after manually approving the first PR)."
133
+ - "Never use pull_request_target to run code from the fork — only use it for read-only operations on PR metadata. Mixing it with code execution from the fork is a security vulnerability."
134
+ docs:
135
+ - url: "https://docs.github.com/en/actions/how-tos/manage-workflow-runs/approve-runs-from-forks"
136
+ label: "GitHub Docs: Approving workflow runs from forks"
137
+ - 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#configuring-required-approval-for-workflows-from-public-forks"
138
+ label: "GitHub Docs: Configuring required approval for workflows from public forks"
139
+ - url: "https://github.blog/changelog/2022-11-14-github-actions-require-approval-for-running-workflows-from-private-forks/"
140
+ label: "GitHub Changelog: Require approval for workflows from private forks (Nov 2022)"
141
+ - url: "https://github.com/orgs/community/discussions/14334"
142
+ label: "GitHub Community Discussion #14334: Fork PR approval pain points"
@@ -0,0 +1,78 @@
1
+ id: "triggers-023"
2
+ title: "Single-star branch filter does not match branch names containing slashes"
3
+ category: "triggers"
4
+ severity: "silent-failure"
5
+ tags:
6
+ - "branches-filter"
7
+ - "glob"
8
+ - "on-push"
9
+ - "slash"
10
+ - "feature-branch"
11
+ - "workflow-not-triggering"
12
+ patterns:
13
+ - regex: "branches:\\s*\\n\\s+-\\s+'\\*'\\s*$"
14
+ flags: "im"
15
+ - regex: "branches:\\s*\\[\\s*['\"]\\*['\"]\\s*\\]"
16
+ flags: "i"
17
+ error_messages:
18
+ - "Workflow does not trigger on feature/my-branch despite branches: ['*']"
19
+ root_cause: |
20
+ GitHub Actions uses Unix glob patterns for branch and tag filters. The single `*`
21
+ wildcard matches any character EXCEPT the forward slash `/`. This means:
22
+
23
+ branches: ['*'] matches: main, develop, hotfix-123
24
+ branches: ['*'] does NOT match: feature/my-feature, release/v1.2.0
25
+
26
+ To match any branch name including those with slashes, you must use `**` (double
27
+ star), which matches any character including `/`.
28
+
29
+ No error is thrown when the filter excludes a branch — the workflow simply does not
30
+ appear in the Actions tab for pushes to `feature/*`-style branches. Developers who
31
+ expect `*` to mean "all branches" (as in many other CI systems) are silently surprised
32
+ when feature branch pushes produce no workflow runs.
33
+
34
+ This follows the same glob semantics documented in GitHub's filter pattern cheat sheet
35
+ but is one of the most common "workflow not triggering" reports in GitHub Community.
36
+ fix: |
37
+ Replace single `*` with `**` in your branches filter to match all branch names
38
+ including those containing slashes. For selective matching, use prefix patterns
39
+ like 'feature/**' or 'release/**'.
40
+ fix_code:
41
+ - language: yaml
42
+ label: "Before: single star silently excludes feature/* branches"
43
+ code: |
44
+ on:
45
+ push:
46
+ branches:
47
+ - '*' # ❌ does NOT match feature/my-feature or release/v1.0.0
48
+
49
+ - language: yaml
50
+ label: "After: double star matches all branches including those with slashes"
51
+ code: |
52
+ on:
53
+ push:
54
+ branches:
55
+ - '**' # ✅ matches any branch name including feature/my-feature
56
+
57
+ - language: yaml
58
+ label: "Practical example: main plus all feature and release branches"
59
+ code: |
60
+ on:
61
+ push:
62
+ branches:
63
+ - main
64
+ - 'feature/**' # ✅ feature/foo, feature/bar/baz, etc.
65
+ - 'release/**' # ✅ release/v1.0, release/v1.0.1, etc.
66
+ - 'hotfix/**' # ✅ hotfix/critical-fix, etc.
67
+ prevention:
68
+ - "Use '**' when you mean 'any branch' and reserve '*' for single-segment names only."
69
+ - "Test your branch filter by pushing to a feature/test branch in a non-production context and verifying a workflow run appears."
70
+ - "Consult the GitHub filter pattern cheat sheet before using glob characters in branches, tags, or paths filters."
71
+ - "Use 'branches-ignore' with an empty list and 'branches: [**]' to explicitly document intent to run on all branches."
72
+ docs:
73
+ - url: "https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#filter-pattern-cheat-sheet"
74
+ label: "GitHub Docs — Filter pattern cheat sheet"
75
+ - url: "https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#onpushbranchesbranchesignore"
76
+ label: "GitHub Docs — on.push.branches filter"
77
+ - url: "https://github.com/orgs/community/discussions/147369"
78
+ label: "GitHub Community #147369 — Workflow not triggering on expected branches"
@@ -0,0 +1,117 @@
1
+ id: triggers-021
2
+ title: "pull_request_target Environment Branch Protection Now Evaluates Against Default Branch (Nov 2025 Breaking Change)"
3
+ category: triggers
4
+ severity: error
5
+ tags:
6
+ - pull_request_target
7
+ - environment
8
+ - branch-protection
9
+ - deployment
10
+ - breaking-change
11
+ - default-branch
12
+ - evaluation-ref
13
+ patterns:
14
+ - regex: "Branch 'refs/pull/\\d+/merge' is not allowed to deploy to .+ due to environment protection rules"
15
+ flags: "i"
16
+ - regex: "pull_request_target.*environment.*protection"
17
+ flags: "im"
18
+ - regex: "is not allowed to deploy to .+ due to environment protection rules"
19
+ flags: "i"
20
+ error_messages:
21
+ - "Branch 'refs/pull/904/merge' is not allowed to deploy to prod due to environment protection rules."
22
+ - "Branch 'refs/pull/123/merge' is not allowed to deploy to staging due to environment protection rules."
23
+ root_cause: |
24
+ In November 2025, GitHub changed how environment branch protection rules are evaluated
25
+ for `pull_request_target` workflows. Before the change:
26
+ - The evaluation ref could be the PR head SHA or the merge ref, depending on
27
+ how the workflow was written.
28
+ After the change (effective ~December 2025):
29
+ - `pull_request_target` workflows ALWAYS run from the **default branch** as the
30
+ workflow source reference (`GITHUB_REF`/`GITHUB_SHA`).
31
+ - Environment branch protection rules are now evaluated against the **execution
32
+ reference** (the default branch) rather than the PR head.
33
+
34
+ **Who is affected:**
35
+ Workflows using `pull_request_target` with environment deployments that have
36
+ branch protection rules configured to allow only specific branch patterns.
37
+
38
+ For example, if an environment's branch restriction allows `main` only, a
39
+ `pull_request_target` workflow that previously passed (because it matched some
40
+ derived ref) may now fail if GitHub evaluates a different ref. Conversely,
41
+ workflows that previously respected PR-branch restrictions may now bypass them
42
+ because the default branch is used instead.
43
+
44
+ This change was made for security: it ensures `pull_request_target` cannot be
45
+ used to circumvent branch-based deployment restrictions via crafted PR refs.
46
+
47
+ The `environment-protection-rules-silent-block` entry (triggers-006) covers the
48
+ general case of environment rules blocking deployment. This entry specifically
49
+ documents the November 2025 behavioral change and its migration path.
50
+ fix: |
51
+ Update your environment branch protection rules to match the execution reference
52
+ used after the behavioral change:
53
+
54
+ 1. **If deployments are now incorrectly blocked:** Add the default branch (e.g.,
55
+ `main`) to the environment's allowed branch patterns, since `pull_request_target`
56
+ now executes in the default branch context.
57
+
58
+ 2. **If PR-based branch restrictions are no longer enforced:** Switch from
59
+ `pull_request_target` to `pull_request` (if the elevated-permissions use case
60
+ can be removed), which uses the PR head ref and respects branch-filter rules
61
+ as expected.
62
+
63
+ 3. **For cross-repo PR deployments that legitimately need `pull_request_target`:**
64
+ Use required reviewers on the environment to gate deployments instead of
65
+ (or in addition to) branch restrictions — required reviewers are not affected
66
+ by this ref-evaluation change.
67
+ fix_code:
68
+ - language: yaml
69
+ label: "Use pull_request instead of pull_request_target when elevated secrets not needed"
70
+ code: |
71
+ # Before (uses pull_request_target — broad access, affected by Nov 2025 change):
72
+ # on:
73
+ # pull_request_target:
74
+ # types: [opened, synchronize]
75
+
76
+ # After (use pull_request — runs in PR head context, branch filters work as expected):
77
+ on:
78
+ pull_request:
79
+ types: [opened, synchronize]
80
+ branches:
81
+ - main
82
+
83
+ jobs:
84
+ deploy-preview:
85
+ runs-on: ubuntu-latest
86
+ environment: staging
87
+ steps:
88
+ - uses: actions/checkout@v4
89
+ - run: echo "Deploy preview for ${{ github.head_ref }}"
90
+ - language: yaml
91
+ label: "Add required reviewers to the environment instead of relying on branch filters alone"
92
+ code: |
93
+ # In GitHub repo Settings → Environments → staging → Protection rules:
94
+ # ✅ Required reviewers: add team "platform-team"
95
+ # (branch restrictions can be kept or relaxed — human approval is the gate)
96
+
97
+ jobs:
98
+ deploy:
99
+ runs-on: ubuntu-latest
100
+ environment: staging # requires approval from platform-team
101
+ steps:
102
+ - uses: actions/checkout@v4
103
+ - run: ./deploy.sh
104
+ prevention:
105
+ - "Prefer `pull_request` over `pull_request_target` unless your workflow specifically needs write permissions or secrets from the base repo for fork PR handling."
106
+ - "Use required reviewers in environments rather than relying solely on branch name patterns for deployment gating."
107
+ - "After enabling `pull_request_target`, validate that environment protection rules still behave as expected by reviewing which ref GitHub uses as the evaluation context."
108
+ - "Monitor the GitHub Actions changelog for behavioral changes to security-sensitive event types like `pull_request_target`."
109
+ docs:
110
+ - url: "https://github.blog/changelog/2025-11-07-actions-pull_request_target-and-environment-branch-protections-changes/"
111
+ label: "GitHub Changelog: pull_request_target and environment branch protections changes (Nov 2025)"
112
+ - url: "https://docs.github.com/en/actions/writing-workflows/choosing-when-your-workflow-runs/events-that-trigger-workflows#pull_request_target"
113
+ label: "GitHub Docs: pull_request_target event"
114
+ - url: "https://docs.github.com/en/actions/managing-workflow-runs-and-deployments/managing-deployments/managing-environments-for-deployment"
115
+ label: "GitHub Docs: Managing environments for deployment"
116
+ - url: "https://github.com/orgs/community/discussions/181616"
117
+ label: "Community Discussion: pull_request_target environment branch protection evaluation"
@@ -0,0 +1,87 @@
1
+ id: triggers-020
2
+ title: "Renamed Workflow or Job Leaves Stale Required Status Check Permanently Blocking Merges"
3
+ category: triggers
4
+ severity: error
5
+ tags:
6
+ - branch-protection
7
+ - required-status-checks
8
+ - workflow-rename
9
+ - merge-blocked
10
+ - repository-settings
11
+ patterns:
12
+ - regex: "Expected.*Waiting for status to be reported"
13
+ flags: "i"
14
+ - regex: "Required status check.*has not passed"
15
+ flags: "i"
16
+ error_messages:
17
+ - "Required status checks have not passed for this pull request"
18
+ - "Expected — Waiting for status to be reported"
19
+ - "Required status check has not passed"
20
+ root_cause: |
21
+ GitHub branch protection rules reference required status checks by their EXACT string
22
+ name: `<Workflow Name> / <job-id>` (e.g., `CI / build`). When a workflow file's
23
+ `name:` field is changed, a job ID is renamed, or a third-party check context string
24
+ changes, the new check runs and passes — but the branch protection rule still
25
+ references the old string.
26
+
27
+ The old check name is stuck at "Expected — Waiting for status to be reported"
28
+ permanently because no workflow run ever reports that exact string again. Every PR
29
+ targeting the protected branch is blocked from merging regardless of CI status.
30
+
31
+ Common triggers:
32
+ - Renaming the top-level `name:` of a workflow file
33
+ - Renaming a job ID (`jobs.<id>`)
34
+ - Migrating from one CI system to another
35
+ - Using a third-party action that changed its check context string
36
+ - Refactoring a monorepo with multiple workflow files that share a check name
37
+
38
+ This affects all open PRs immediately when the workflow is renamed — there is no
39
+ grace period or deprecation.
40
+ fix: |
41
+ 1. Go to Settings → Branches → Branch protection rules → Edit for the affected branch.
42
+ 2. Under "Require status checks to pass before merging", remove the stale check name.
43
+ 3. Start typing the NEW check name and select it from the autocomplete dropdown.
44
+ The format is: "Workflow Name / job-id" (exactly as shown in the PR checks UI).
45
+ 4. Save the branch protection rule.
46
+
47
+ To find the exact new check name without guessing:
48
+ gh api repos/{owner}/{repo}/commits/{ref}/check-runs --jq '.check_runs[].name'
49
+
50
+ If multiple branches are protected with the same stale rule, repeat for each.
51
+ fix_code:
52
+ - language: yaml
53
+ label: "Find current check names via GitHub CLI"
54
+ code: |
55
+ # List all check names currently reported for the default branch
56
+ gh api "repos/{owner}/{repo}/commits/main/check-runs" \
57
+ --jq '.check_runs[] | "\(.name) — \(.status)/\(.conclusion)"'
58
+
59
+ # Or for a specific open PR's head SHA:
60
+ gh api "repos/{owner}/{repo}/commits/{sha}/check-runs" \
61
+ --jq '.check_runs[].name'
62
+ - language: yaml
63
+ label: "Prevention: document required check names in workflow comments"
64
+ code: |
65
+ # Branch protection references this check as: "CI / build"
66
+ # If you rename this workflow or job, update Settings > Branches > Protection rules
67
+ name: CI # <-- changing this breaks the required check "CI / build"
68
+ on: [push, pull_request]
69
+
70
+ jobs:
71
+ build: # <-- changing this ID also breaks "CI / build"
72
+ runs-on: ubuntu-latest
73
+ steps:
74
+ - run: make build
75
+ prevention:
76
+ - "Before renaming a workflow or job, check Settings → Branches to see if any protection rules reference the current check name."
77
+ - "Add a comment in the workflow file listing the exact required status check string so renames are noticed."
78
+ - "After any workflow rename, immediately update branch protection rules and verify with an open PR."
79
+ - "Use the GitHub CLI command above to audit current check names after any CI refactor."
80
+ - "In monorepos, standardize workflow names and job IDs to minimize rename frequency."
81
+ docs:
82
+ - 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"
83
+ label: "GitHub Docs: Required status checks"
84
+ - url: "https://docs.github.com/en/rest/checks/runs#list-check-runs-for-a-git-reference"
85
+ label: "REST API: List check runs for a git reference"
86
+ - url: "https://docs.github.com/en/actions/writing-workflows/workflow-syntax-for-github-actions#name"
87
+ label: "Workflow syntax: name field"
@@ -0,0 +1,107 @@
1
+ id: triggers-024
2
+ title: "Scheduled Cron Workflow Does Not Trigger on Self-Hosted Runner"
3
+ category: triggers
4
+ severity: error
5
+ tags:
6
+ - cron
7
+ - schedule
8
+ - self-hosted-runner
9
+ - trigger
10
+ - offline
11
+ patterns:
12
+ - regex: "cron.*self.hosted"
13
+ flags: "i"
14
+ - regex: "schedule.*self.hosted"
15
+ flags: "i"
16
+ error_messages:
17
+ - "No trigger for scheduled cron task in Github actions on a self-hosted runner"
18
+ root_cause: |
19
+ Scheduled (on: schedule) workflows are queued by GitHub hosted-runner dispatch
20
+ infrastructure. When the job targets a self-hosted runner (runs-on: [self-hosted, ...]),
21
+ the schedule dispatcher attempts to assign the job to a registered self-hosted runner.
22
+
23
+ The workflow silently never runs when:
24
+ 1. The self-hosted runner is offline or disconnected at the moment the schedule fires.
25
+ 2. The runner is busy with another job and no other runner with the required label is idle.
26
+ 3. The runner binary is outdated or the registration token has expired, causing the runner
27
+ to appear registered but fail to accept new jobs.
28
+ 4. The repository has been inactive for 60+ days (GitHub disables scheduled workflows
29
+ on inactive repositories automatically).
30
+
31
+ Unlike GitHub-hosted runners, where a fresh VM is provisioned on demand for every job,
32
+ self-hosted runners must be online and idle at exactly the moment the schedule fires.
33
+ If no eligible runner is available, the queued job is eventually abandoned with no retry
34
+ and no error visible in the Actions UI. The run simply does not appear.
35
+ Reported in actions/runner#4210 (21 reactions, open since Jan 2026).
36
+ fix: |
37
+ Option 1 (recommended): Run the scheduled trigger on a GitHub-hosted runner.
38
+ Use ubuntu-latest for the schedule job and dispatch the real work to self-hosted
39
+ via workflow_dispatch or a separate triggered workflow.
40
+
41
+ Option 2: Use an external scheduler with workflow_dispatch.
42
+ Remove the on: schedule trigger. Use an external cron (cron job, cloud function, GitHub App)
43
+ to call the GitHub REST API dispatches endpoint on a schedule. The workflow is triggered
44
+ by workflow_dispatch instead, which does not require the runner to be available at a
45
+ fixed clock time.
46
+
47
+ Option 3: Ensure runner availability with a persistent service.
48
+ Run the self-hosted runner as a systemd service with Restart=always so it is online
49
+ when schedules fire. This reduces but does not eliminate the risk.
50
+ fix_code:
51
+ - language: yaml
52
+ label: "Option 1: Schedule on GitHub-hosted, dispatch to self-hosted"
53
+ code: |
54
+ on:
55
+ schedule:
56
+ - cron: '0 2 * * *'
57
+ workflow_dispatch: {}
58
+
59
+ jobs:
60
+ # Lightweight orchestrator runs on GitHub-hosted (always available at schedule time)
61
+ trigger:
62
+ runs-on: ubuntu-latest
63
+ steps:
64
+ - name: Trigger self-hosted workflow
65
+ uses: actions/github-script@v7
66
+ with:
67
+ script: |
68
+ await github.rest.actions.createWorkflowDispatch({
69
+ owner: context.repo.owner,
70
+ repo: context.repo.repo,
71
+ workflow_id: 'heavy-work.yml',
72
+ ref: 'main'
73
+ });
74
+ - language: yaml
75
+ label: "Option 2: Receive dispatch from external cron scheduler"
76
+ code: |
77
+ # External scheduler calls:
78
+ # curl -X POST \
79
+ # -H "Authorization: Bearer $GH_TOKEN" \
80
+ # https://api.github.com/repos/OWNER/REPO/actions/workflows/nightly.yml/dispatches \
81
+ # -d '{"ref":"main"}'
82
+ #
83
+ # Your workflow:
84
+ on:
85
+ workflow_dispatch: {} # Triggered externally; no GitHub-side scheduling dependency
86
+
87
+ jobs:
88
+ nightly:
89
+ runs-on: [self-hosted, linux, x64]
90
+ steps:
91
+ - uses: actions/checkout@v4
92
+ - run: ./scripts/nightly.sh
93
+ prevention:
94
+ - "Run self-hosted runners as a persistent systemd service (Restart=always, RestartSec=10) to minimize offline windows."
95
+ - "Add workflow_dispatch: alongside schedule: so missed runs can be manually re-triggered from the Actions UI."
96
+ - "Monitor runner registration status via GET /repos/{owner}/{repo}/actions/runners and alert on offline runners."
97
+ - "Keep repositories active with at least one push or workflow run to prevent scheduled workflow disablement after 60 days of inactivity."
98
+ - "Consider using ephemeral runners with autoscaling (ARC) so runners are always provisioned on demand."
99
+ docs:
100
+ - url: "https://github.com/actions/runner/issues/4210"
101
+ label: "actions/runner#4210 — Cron not triggering on self-hosted runner (Jan 2026)"
102
+ - url: "https://github.com/orgs/community/discussions/185024"
103
+ label: "Community discussion: self-hosted runner not triggering scheduled cron"
104
+ - url: "https://docs.github.com/en/actions/writing-workflows/choosing-when-your-workflow-runs/events-that-trigger-workflows#schedule"
105
+ label: "schedule event documentation"
106
+ - url: "https://docs.github.com/en/actions/managing-workflow-runs-and-deployments/managing-workflow-runs/disabling-and-enabling-a-workflow"
107
+ label: "Workflow disabled after 60 days of repo inactivity"