@htekdev/actions-debugger 1.0.67 → 1.0.68

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,69 @@
1
+ id: caching-artifacts-043
2
+ title: "upload-artifact retention-days silently capped at organization maximum — artifact expires earlier than configured"
3
+ category: caching-artifacts
4
+ severity: silent-failure
5
+ tags:
6
+ - upload-artifact
7
+ - retention-days
8
+ - artifacts
9
+ - organization-policy
10
+ - expiry
11
+ patterns:
12
+ - regex: 'Artifact will be retained for \d+ days'
13
+ flags: "i"
14
+ error_messages:
15
+ - "Artifact will be retained for"
16
+ root_cause: |
17
+ When actions/upload-artifact is configured with a retention-days value that exceeds the
18
+ organization's or repository's maximum artifact retention setting, GitHub silently caps
19
+ the retention period to the configured maximum without emitting any error or warning.
20
+ The upload step completes successfully, the workflow shows green, and the artifact is
21
+ created — but it expires sooner than the workflow author intended.
22
+
23
+ This is particularly dangerous for:
24
+ - Compliance workflows that retain build artifacts for audits
25
+ - Release workflows where binaries must survive for customer download periods
26
+ - Security scanning workflows that need artifacts for post-incident review
27
+
28
+ The only way to discover the cap is to inspect the artifact's expiration date in the
29
+ repository's Actions UI after upload, or query the REST API. Developers who set
30
+ retention-days: 365 expecting one-year retention will find artifacts disappearing after
31
+ 90 days (the default org maximum) with no log evidence of the cap.
32
+ fix: |
33
+ Check your organization's artifact retention maximum under Organization Settings → Actions
34
+ → General → Artifact and log retention, and ensure retention-days in upload-artifact is
35
+ set to a value at or below this limit. If you need retention beyond the org maximum
36
+ (e.g., for compliance), use GitHub Releases for tagged builds, or an external artifact
37
+ store (S3, Azure Blob, GCS). You can also query the artifact API to assert the actual
38
+ expiry date and fail the workflow if it doesn't match expectations.
39
+ fix_code:
40
+ - language: yaml
41
+ label: "Cap retention-days to org maximum and use GitHub Releases for long-term storage"
42
+ code: |
43
+ - name: Upload build artifact
44
+ uses: actions/upload-artifact@v4
45
+ with:
46
+ name: build-output-${{ github.sha }}
47
+ path: dist/
48
+ # Must be <= your org's maximum retention setting
49
+ # Check: Org Settings → Actions → General → Artifact and log retention
50
+ retention-days: 30
51
+
52
+ # For artifacts requiring retention beyond the org maximum (e.g., release binaries),
53
+ # attach them to a GitHub Release instead:
54
+ - name: Create GitHub Release with artifact
55
+ uses: softprops/action-gh-release@v2
56
+ if: startsWith(github.ref, 'refs/tags/')
57
+ with:
58
+ files: dist/**
59
+ # Release assets are NOT subject to the artifact retention policy
60
+ prevention:
61
+ - "Check your organization's artifact retention maximum before setting retention-days in upload-artifact"
62
+ - "For artifacts requiring long-term storage, use GitHub Releases or an external object store (S3, GCS, Azure Blob)"
63
+ - "Add a workflow step that queries the artifact expiry via the REST API and fails if it doesn't match the intended retention"
64
+ - "Document the org retention limit in a comment next to retention-days to alert future editors"
65
+ docs:
66
+ - url: "https://docs.github.com/en/actions/writing-workflows/choosing-what-your-workflow-does/storing-workflow-data-as-artifacts"
67
+ label: "Storing workflow data as artifacts — GitHub Docs"
68
+ - url: "https://docs.github.com/en/organizations/managing-organization-settings/configuring-the-retention-period-for-github-actions-artifacts-and-logs-in-your-organization"
69
+ label: "Configuring artifact retention period for your organization — GitHub Docs"
@@ -0,0 +1,76 @@
1
+ id: concurrency-timing-036
2
+ title: "cancel-in-progress: true cancels pending deployment environment reviews — deployment never completes"
3
+ category: concurrency-timing
4
+ severity: silent-failure
5
+ tags:
6
+ - concurrency
7
+ - deployment
8
+ - environment
9
+ - cancel-in-progress
10
+ - required-reviewers
11
+ patterns:
12
+ - regex: 'waiting for a required environment'
13
+ flags: "i"
14
+ - regex: 'Deployment to .+ was cancelled'
15
+ flags: "i"
16
+ error_messages:
17
+ - "This workflow run is waiting for a required environment"
18
+ - "Deployment to production was cancelled"
19
+ root_cause: |
20
+ When a deployment job targets an environment with required reviewers (protection rules)
21
+ and cancel-in-progress: true is set on the concurrency group, every new push cancels the
22
+ pending workflow run — including the one awaiting reviewer approval. The reviewer is
23
+ notified, starts the review process, but before they approve a new commit arrives and
24
+ cancels the run. The cycle repeats indefinitely: deployments queue, reviewers are
25
+ interrupted, and nothing ever reaches production. No diagnostic error is surfaced; the
26
+ workflow simply shows "Cancelled" with no indication that a required-reviewer gate was
27
+ involved.
28
+ fix: |
29
+ Remove cancel-in-progress: true from the concurrency group used by the deployment job.
30
+ Use cancel-in-progress: false (the default) so pending approval runs survive new commits.
31
+ To still get fast feedback on CI, split the workflow into two separate files: a fast CI
32
+ workflow with cancel-in-progress: true, and a deployment workflow (triggered on CI success)
33
+ with cancel-in-progress: false so approval gates are preserved.
34
+ fix_code:
35
+ - language: yaml
36
+ label: "Split CI and deploy workflows with separate concurrency policies"
37
+ code: |
38
+ # .github/workflows/ci.yml — cancel old CI runs freely
39
+ on: [push, pull_request]
40
+ concurrency:
41
+ group: ci-${{ github.ref }}
42
+ cancel-in-progress: true
43
+ jobs:
44
+ test:
45
+ runs-on: ubuntu-latest
46
+ steps:
47
+ - uses: actions/checkout@v4
48
+ - run: npm test
49
+
50
+ # .github/workflows/deploy.yml — preserve pending deployment approvals
51
+ on:
52
+ workflow_run:
53
+ workflows: [CI]
54
+ types: [completed]
55
+ branches: [main]
56
+ concurrency:
57
+ group: deploy-${{ github.ref }}
58
+ cancel-in-progress: false # preserves pending required-reviewer approval
59
+ jobs:
60
+ deploy:
61
+ if: ${{ github.event.workflow_run.conclusion == 'success' }}
62
+ environment: production # has required reviewers
63
+ runs-on: ubuntu-latest
64
+ steps:
65
+ - uses: actions/checkout@v4
66
+ - run: echo "Deploying..."
67
+ prevention:
68
+ - "Never combine cancel-in-progress: true with deployment jobs that have required-reviewer environment protection rules"
69
+ - "Use separate workflow files for CI and deployment to apply different concurrency policies"
70
+ - "Set cancel-in-progress: false (or omit it) on any concurrency group that wraps a deployment environment job"
71
+ - "Test the deployment approval flow explicitly after adding or changing concurrency settings"
72
+ docs:
73
+ - url: "https://docs.github.com/en/actions/writing-workflows/choosing-what-your-workflow-does/using-concurrency"
74
+ label: "Using concurrency — GitHub Docs"
75
+ - url: "https://docs.github.com/en/actions/managing-workflow-runs-and-deployments/managing-deployments/reviewing-deployments"
76
+ label: "Reviewing deployments — GitHub Docs"
@@ -0,0 +1,62 @@
1
+ id: concurrency-timing-037
2
+ title: "Concurrency group key missing github.ref accidentally cancels runs on other branches"
3
+ category: concurrency-timing
4
+ severity: silent-failure
5
+ tags:
6
+ - concurrency
7
+ - cancel-in-progress
8
+ - github-ref
9
+ - branches
10
+ - cross-branch
11
+ patterns:
12
+ - regex: 'cancelled because a more recent run with the same concurrency'
13
+ flags: "i"
14
+ - regex: 'This run was cancelled'
15
+ flags: "i"
16
+ error_messages:
17
+ - "This run was cancelled because a more recent run with the same concurrency key is in progress"
18
+ root_cause: |
19
+ When the concurrency group key is set to a static string or uses only github.workflow
20
+ without including github.ref, all branches share the same concurrency slot. A push to
21
+ any feature branch will cancel an in-progress run on main — or vice versa. With
22
+ cancel-in-progress: true, a developer's feature branch push can silently abort a
23
+ production branch deployment or a release CI run. The cancellation message ("This run
24
+ was cancelled because a more recent run with the same concurrency key is in progress")
25
+ gives no indication that the runs are on completely different branches. This is among the
26
+ most common misconfiguration in copy-pasted concurrency examples that omit github.ref.
27
+ fix: |
28
+ Always include github.ref (or github.head_ref for pull_request events) in the concurrency
29
+ group key so each branch maintains its own independent concurrency slot. For pull requests,
30
+ use github.event.pull_request.number to prevent conflicts between simultaneously open PRs
31
+ targeting the same branch. For scheduled or manual workflows where github.ref is always
32
+ the same, use github.run_id to allow parallel runs.
33
+ fix_code:
34
+ - language: yaml
35
+ label: "Include github.ref in the concurrency key to isolate each branch"
36
+ code: |
37
+ # WRONG — all branches share one concurrency slot, pushes to any branch
38
+ # cancel runs on all other branches
39
+ # concurrency:
40
+ # group: ${{ github.workflow }}
41
+ # cancel-in-progress: true
42
+
43
+ # CORRECT — each branch has its own independent concurrency slot
44
+ concurrency:
45
+ group: ${{ github.workflow }}-${{ github.ref }}
46
+ cancel-in-progress: true
47
+
48
+ # For pull_request events, scope to the PR number for extra precision
49
+ # (prevents PR-A and PR-B from cancelling each other when both target main)
50
+ concurrency:
51
+ group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
52
+ cancel-in-progress: true
53
+ prevention:
54
+ - "Always include github.ref or github.head_ref in the concurrency group key"
55
+ - "For pull_request workflows, use github.event.pull_request.number || github.ref to scope to individual PRs"
56
+ - "Audit all workflow concurrency keys whenever enabling cancel-in-progress: true"
57
+ - "Use a unique prefix per workflow type (ci-, deploy-, lint-) to prevent cross-workflow collisions even when github.ref is included"
58
+ docs:
59
+ - url: "https://docs.github.com/en/actions/writing-workflows/choosing-what-your-workflow-does/using-concurrency"
60
+ label: "Using concurrency — GitHub Docs"
61
+ - url: "https://docs.github.com/en/actions/writing-workflows/workflow-syntax-for-github-actions#concurrency"
62
+ label: "Concurrency syntax — GitHub Docs"
@@ -0,0 +1,76 @@
1
+ id: yaml-syntax-044
2
+ title: "run: > (folded block scalar) collapses newlines to spaces — multi-line shell scripts break silently"
3
+ category: yaml-syntax
4
+ severity: error
5
+ tags:
6
+ - yaml
7
+ - run
8
+ - block-scalar
9
+ - multiline
10
+ - shell
11
+ - folded
12
+ patterns:
13
+ - regex: 'syntax error near unexpected token'
14
+ flags: "i"
15
+ - regex: 'command not found'
16
+ flags: "i"
17
+ - regex: 'unexpected EOF while looking for matching'
18
+ flags: "i"
19
+ error_messages:
20
+ - "syntax error near unexpected token"
21
+ - "command not found"
22
+ - "unexpected EOF while looking for matching `\"'"
23
+ root_cause: |
24
+ YAML has two block scalar indicators: | (literal) preserves newlines exactly, while >
25
+ (folded) collapses newlines between non-empty lines into a single space. When a GitHub
26
+ Actions run: block uses > instead of |, every line break in the shell script becomes a
27
+ space. Multi-line scripts are silently concatenated into a single command that the shell
28
+ cannot parse, producing confusing errors like "syntax error near unexpected token" or
29
+ "command not found" pointing to the wrong line.
30
+
31
+ This is especially common when:
32
+ - Developers copy YAML examples from documentation that use > for prose (not scripts)
33
+ - IDEs or formatters suggest > to reduce visual indentation
34
+ - Developers confuse > (folded) and | (literal) because both produce multi-line blocks
35
+
36
+ Example: a three-line script becomes one run-together line:
37
+ # With run: > becomes: echo "start" VAR=hello echo "$VAR"
38
+ # With run: | becomes: echo "start" \n VAR=hello \n echo "$VAR" (correct)
39
+ fix: |
40
+ Always use | (pipe / literal block scalar) for run: steps that contain shell scripts.
41
+ The | indicator preserves newlines exactly as written. The > indicator should only be
42
+ used for prose strings (e.g., long error messages or descriptions) where newline
43
+ collapsing is intentional.
44
+ fix_code:
45
+ - language: yaml
46
+ label: "Use | (literal) not > (folded) for run: shell scripts"
47
+ code: |
48
+ jobs:
49
+ build:
50
+ runs-on: ubuntu-latest
51
+ steps:
52
+ # WRONG — > folds newlines into spaces, script becomes one broken command
53
+ # - name: Build
54
+ # run: >
55
+ # echo "Starting build"
56
+ # npm install
57
+ # npm run build
58
+
59
+ # CORRECT — | preserves newlines, each command runs on its own line
60
+ - name: Build
61
+ run: |
62
+ echo "Starting build"
63
+ npm install
64
+ npm run build
65
+ prevention:
66
+ - "Always use | (literal block scalar) for run: blocks containing shell scripts"
67
+ - "Reserve > (folded block scalar) for non-executable prose strings only"
68
+ - "Enable a YAML linter (e.g., actionlint, yamllint) in pre-commit hooks to catch > in run: blocks"
69
+ - "When in doubt: | keeps lines as lines; > joins lines with spaces"
70
+ docs:
71
+ - url: "https://yaml.org/spec/1.2.2/#chapter-8-block-style-productions"
72
+ label: "YAML block scalar styles — YAML spec"
73
+ - url: "https://docs.github.com/en/actions/writing-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun"
74
+ label: "jobs.<id>.steps[*].run — GitHub Docs"
75
+ - url: "https://rhysd.github.io/actionlint/"
76
+ label: "actionlint — static checker for GitHub Actions workflow files"
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@htekdev/actions-debugger",
3
- "version": "1.0.67",
3
+ "version": "1.0.68",
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",