@htekdev/actions-debugger 1.0.43 → 1.0.45
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.
- package/errors/known-unsolved/environment-matrix-one-review-per-job.yml +100 -0
- package/errors/known-unsolved/known-unsolved-035.yml +97 -0
- package/errors/permissions-auth/attest-build-provenance-missing-attestations-write.yml +100 -0
- package/errors/runner-environment/runner-environment-100.yml +69 -0
- package/errors/runner-environment/runner-environment-101.yml +73 -0
- package/errors/runner-environment/runner-environment-102.yml +89 -0
- package/errors/runner-environment/setup-python-version-range-resolves-to-313-distutils-removed.yml +107 -0
- package/errors/silent-failures/github-output-heredoc-delimiter-collision.yml +83 -0
- package/package.json +1 -1
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
id: known-unsolved-034
|
|
2
|
+
title: 'environment deployment protection with required reviewers creates one review request per matrix job — no batch approval'
|
|
3
|
+
category: known-unsolved
|
|
4
|
+
severity: limitation
|
|
5
|
+
tags:
|
|
6
|
+
- environment
|
|
7
|
+
- matrix
|
|
8
|
+
- deployment
|
|
9
|
+
- required-reviewers
|
|
10
|
+
- approvals
|
|
11
|
+
- no-fix
|
|
12
|
+
patterns:
|
|
13
|
+
- regex: 'Waiting for.*review'
|
|
14
|
+
flags: 'i'
|
|
15
|
+
- regex: 'Review required before this job runs'
|
|
16
|
+
flags: 'i'
|
|
17
|
+
error_messages:
|
|
18
|
+
- 'Waiting for a reviewer'
|
|
19
|
+
- 'Review required before this job runs'
|
|
20
|
+
root_cause: |
|
|
21
|
+
GitHub Actions environments with required reviewers enforce approval at the
|
|
22
|
+
individual job level. When a job using environment: with required reviewers
|
|
23
|
+
also uses strategy: matrix, each matrix cell creates a separate deployment
|
|
24
|
+
instance requiring its own approval.
|
|
25
|
+
|
|
26
|
+
A 3x3 matrix (os x environment) produces 9 separate "Waiting for reviewer"
|
|
27
|
+
prompts in the GitHub Actions UI — one for each matrix combination. Each
|
|
28
|
+
must be approved individually; there is no "approve all" button for
|
|
29
|
+
matrix deployments.
|
|
30
|
+
|
|
31
|
+
This behavior stems from GitHub's deployment model: each job run creates a
|
|
32
|
+
discrete deployment record in the repository's deployment history. Matrix
|
|
33
|
+
jobs are independent job runs, so each creates its own deployment record
|
|
34
|
+
and independently triggers the environment protection review gate.
|
|
35
|
+
|
|
36
|
+
This is confirmed expected behavior per GitHub staff in community discussions.
|
|
37
|
+
There is no configuration option to batch or group matrix job deployment approvals.
|
|
38
|
+
fix: |
|
|
39
|
+
There is no supported way to batch-approve matrix jobs targeting a protected
|
|
40
|
+
environment. The workaround is architectural: separate the build/test matrix
|
|
41
|
+
from the deployment job, using a single non-matrix deploy job that depends
|
|
42
|
+
on all matrix results via needs:.
|
|
43
|
+
|
|
44
|
+
This "build in matrix, deploy once" pattern also aligns with security best
|
|
45
|
+
practice — production deployments should be a single auditable event.
|
|
46
|
+
fix_code:
|
|
47
|
+
- language: yaml
|
|
48
|
+
label: 'Anti-pattern — matrix job with protected environment (creates N review requests)'
|
|
49
|
+
code: |
|
|
50
|
+
jobs:
|
|
51
|
+
deploy:
|
|
52
|
+
strategy:
|
|
53
|
+
matrix:
|
|
54
|
+
region: [us-east-1, eu-west-1, ap-southeast-1]
|
|
55
|
+
environment: production # 3 separate review requests
|
|
56
|
+
runs-on: ubuntu-latest
|
|
57
|
+
steps:
|
|
58
|
+
- run: echo "deploying to ${{ matrix.region }}"
|
|
59
|
+
- language: yaml
|
|
60
|
+
label: 'Workaround — single non-matrix deploy job collects matrix artifacts and deploys once'
|
|
61
|
+
code: |
|
|
62
|
+
jobs:
|
|
63
|
+
build:
|
|
64
|
+
strategy:
|
|
65
|
+
matrix:
|
|
66
|
+
region: [us-east-1, eu-west-1, ap-southeast-1]
|
|
67
|
+
runs-on: ubuntu-latest
|
|
68
|
+
steps:
|
|
69
|
+
- uses: actions/checkout@v4
|
|
70
|
+
- name: Build for region
|
|
71
|
+
run: make build REGION=${{ matrix.region }}
|
|
72
|
+
- uses: actions/upload-artifact@v4
|
|
73
|
+
with:
|
|
74
|
+
name: build-${{ matrix.region }}
|
|
75
|
+
path: dist/
|
|
76
|
+
|
|
77
|
+
deploy:
|
|
78
|
+
needs: build
|
|
79
|
+
runs-on: ubuntu-latest
|
|
80
|
+
environment: production # Single review request for all regions
|
|
81
|
+
steps:
|
|
82
|
+
- uses: actions/download-artifact@v4
|
|
83
|
+
with:
|
|
84
|
+
pattern: build-*
|
|
85
|
+
merge-multiple: true
|
|
86
|
+
path: all-dist/
|
|
87
|
+
- name: Deploy all regions
|
|
88
|
+
run: make deploy-all ARTIFACTS_DIR=all-dist/
|
|
89
|
+
prevention:
|
|
90
|
+
- 'Design deployment workflows so the job with environment: protection is never a matrix job'
|
|
91
|
+
- 'Use build-in-matrix, deploy-once pattern: matrix for build/test, single serial job for protected deploy'
|
|
92
|
+
- 'If per-region deployments must be parallel and require environment protection, accept the N-approvals UX'
|
|
93
|
+
- 'Document this limitation in team runbooks before adopting matrix + environment patterns in production pipelines'
|
|
94
|
+
docs:
|
|
95
|
+
- url: 'https://docs.github.com/en/actions/managing-workflow-runs-and-deployments/managing-deployments/managing-environments-for-deployment'
|
|
96
|
+
label: 'GitHub Docs — Managing environments for deployment'
|
|
97
|
+
- url: 'https://github.com/orgs/community/discussions/15690'
|
|
98
|
+
label: 'GitHub Community — Matrix deployment creates multiple approval requests'
|
|
99
|
+
- url: 'https://docs.github.com/en/actions/writing-workflows/choosing-what-your-workflow-does/using-a-matrix-for-your-workflow'
|
|
100
|
+
label: 'GitHub Docs — Using a matrix for your workflow'
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
id: known-unsolved-035
|
|
2
|
+
title: "workflow_run trigger only fires for same-repo workflows — cross-repo chaining not supported"
|
|
3
|
+
category: known-unsolved
|
|
4
|
+
severity: limitation
|
|
5
|
+
tags:
|
|
6
|
+
- workflow_run
|
|
7
|
+
- cross-repo
|
|
8
|
+
- triggers
|
|
9
|
+
- repository-dispatch
|
|
10
|
+
- known-limitation
|
|
11
|
+
- event-chaining
|
|
12
|
+
patterns:
|
|
13
|
+
- regex: 'workflow_run.*never.*trigger|on.*workflow_run.*different.*repo'
|
|
14
|
+
flags: "i"
|
|
15
|
+
- regex: 'cross.repo.*workflow.run|workflow_run.*external.*repo'
|
|
16
|
+
flags: "i"
|
|
17
|
+
error_messages:
|
|
18
|
+
- "workflow_run trigger does not fire for workflows in a different repository"
|
|
19
|
+
root_cause: |
|
|
20
|
+
The on: workflow_run trigger only listens to workflow completion events in the same
|
|
21
|
+
repository. It cannot subscribe to events from workflows in external repositories,
|
|
22
|
+
even within the same organization or enterprise. Teams building cross-repository
|
|
23
|
+
CI/CD chains (e.g., "when repo-A build finishes, trigger repo-B deploy") discover
|
|
24
|
+
that the downstream workflow simply never starts — there is no error, just silence.
|
|
25
|
+
|
|
26
|
+
This is a platform design decision: workflow_run was built for intra-repo fan-out
|
|
27
|
+
(e.g., running security scans after CI passes) and not for cross-repo event routing.
|
|
28
|
+
|
|
29
|
+
Common scenarios where this limitation is hit:
|
|
30
|
+
- Platform team repo triggering deploy workflows in service repos
|
|
31
|
+
- Shared library repo signaling consumers after a release
|
|
32
|
+
- Monorepo-to-polyrepo migration preserving CI event chains
|
|
33
|
+
- Organization-wide rollout pipelines spanning multiple repositories
|
|
34
|
+
fix: |
|
|
35
|
+
Use repository_dispatch for cross-repo event chaining. The upstream workflow sends
|
|
36
|
+
a POST to the GitHub REST API to create a repository_dispatch event in the downstream
|
|
37
|
+
repo. The downstream workflow listens on on: repository_dispatch: types: [...].
|
|
38
|
+
|
|
39
|
+
This requires a PAT (classic) with repo scope, or a GitHub App token with contents:
|
|
40
|
+
write or actions: write on the downstream repository. The peter-evans/repository-dispatch
|
|
41
|
+
action is the most widely used wrapper.
|
|
42
|
+
fix_code:
|
|
43
|
+
- language: yaml
|
|
44
|
+
label: "Upstream (repo-A): dispatch event to repo-B on workflow completion"
|
|
45
|
+
code: |
|
|
46
|
+
# .github/workflows/build.yml in repo-A
|
|
47
|
+
on:
|
|
48
|
+
push:
|
|
49
|
+
branches: [main]
|
|
50
|
+
|
|
51
|
+
jobs:
|
|
52
|
+
build:
|
|
53
|
+
runs-on: ubuntu-latest
|
|
54
|
+
steps:
|
|
55
|
+
- name: Build
|
|
56
|
+
run: make build
|
|
57
|
+
|
|
58
|
+
- name: Trigger deployment in repo-B
|
|
59
|
+
uses: peter-evans/repository-dispatch@v3
|
|
60
|
+
with:
|
|
61
|
+
token: ${{ secrets.CROSS_REPO_PAT }}
|
|
62
|
+
repository: my-org/repo-B
|
|
63
|
+
event-type: repo-a-build-complete
|
|
64
|
+
client-payload: >-
|
|
65
|
+
{"sha": "${{ github.sha }}", "ref": "${{ github.ref }}",
|
|
66
|
+
"run_id": "${{ github.run_id }}"}
|
|
67
|
+
- language: yaml
|
|
68
|
+
label: "Downstream (repo-B): receive repository_dispatch from repo-A"
|
|
69
|
+
code: |
|
|
70
|
+
# .github/workflows/deploy.yml in repo-B
|
|
71
|
+
on:
|
|
72
|
+
repository_dispatch:
|
|
73
|
+
types: [repo-a-build-complete]
|
|
74
|
+
|
|
75
|
+
jobs:
|
|
76
|
+
deploy:
|
|
77
|
+
runs-on: ubuntu-latest
|
|
78
|
+
steps:
|
|
79
|
+
- name: Deploy
|
|
80
|
+
run: |
|
|
81
|
+
echo "Triggered by SHA: ${{ github.event.client_payload.sha }}"
|
|
82
|
+
echo "Source run: ${{ github.event.client_payload.run_id }}"
|
|
83
|
+
# deploy steps here
|
|
84
|
+
prevention:
|
|
85
|
+
- "Use repository_dispatch for cross-repository event chaining — workflow_run is same-repo only"
|
|
86
|
+
- "Document this limitation in workflow comments so future maintainers don't spend time debugging non-firing triggers"
|
|
87
|
+
- "Consider reusable workflows (workflow_call) for sharing logic within an org instead of cross-repo triggers"
|
|
88
|
+
- "For org-wide fan-out, a central platform repo dispatching to all downstream repos is a common pattern"
|
|
89
|
+
docs:
|
|
90
|
+
- url: "https://docs.github.com/en/actions/writing-workflows/choosing-when-your-workflow-runs/events-that-trigger-workflows#workflow_run"
|
|
91
|
+
label: "GitHub Docs: workflow_run trigger"
|
|
92
|
+
- url: "https://docs.github.com/en/rest/repos/repos#create-a-repository-dispatch-event"
|
|
93
|
+
label: "GitHub REST API: Create a repository dispatch event"
|
|
94
|
+
- url: "https://github.com/peter-evans/repository-dispatch"
|
|
95
|
+
label: "peter-evans/repository-dispatch action"
|
|
96
|
+
- url: "https://github.com/orgs/community/discussions/26323"
|
|
97
|
+
label: "GitHub Community #26323: workflow_run cross-repo limitation confirmed"
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
id: permissions-auth-035
|
|
2
|
+
title: 'actions/attest-build-provenance fails with 403 — missing attestations: write permission'
|
|
3
|
+
category: permissions-auth
|
|
4
|
+
severity: error
|
|
5
|
+
tags:
|
|
6
|
+
- attestations
|
|
7
|
+
- attest-build-provenance
|
|
8
|
+
- GITHUB_TOKEN
|
|
9
|
+
- permissions
|
|
10
|
+
- 403
|
|
11
|
+
- supply-chain
|
|
12
|
+
patterns:
|
|
13
|
+
- regex: 'HttpError.*403.*attestation'
|
|
14
|
+
flags: 'i'
|
|
15
|
+
- regex: 'Resource not accessible by integration'
|
|
16
|
+
flags: 'i'
|
|
17
|
+
- regex: 'Failed to create attestation'
|
|
18
|
+
flags: 'i'
|
|
19
|
+
error_messages:
|
|
20
|
+
- 'HttpError: 403 — Resource not accessible by integration'
|
|
21
|
+
- 'Failed to create attestation'
|
|
22
|
+
- 'Error: Resource not accessible by integration'
|
|
23
|
+
root_cause: |
|
|
24
|
+
actions/attest-build-provenance (introduced GitHub Changelog, May 2024) requires
|
|
25
|
+
the GITHUB_TOKEN to have the attestations: write scope. This permission did not
|
|
26
|
+
exist before the attestations feature was released and is NOT included in the
|
|
27
|
+
GitHub Actions default token permissions, nor in commonly used broad permission
|
|
28
|
+
sets like contents: write or id-token: write.
|
|
29
|
+
|
|
30
|
+
When the workflow omits attestations: write from its permissions block, the
|
|
31
|
+
action fails with a 403 "Resource not accessible by integration" error. The
|
|
32
|
+
error message does not explicitly mention "attestations: write" as the missing
|
|
33
|
+
scope, making the root cause difficult to identify.
|
|
34
|
+
|
|
35
|
+
Common mistake: developers copy the attest-build-provenance action from
|
|
36
|
+
documentation examples or third-party tutorials that may not include the full
|
|
37
|
+
permissions block, or they use a minimal permissions block that covers other
|
|
38
|
+
needs (contents: read, packages: write) without adding attestations: write.
|
|
39
|
+
|
|
40
|
+
Organization policy note: if the organization has disabled the attestations
|
|
41
|
+
feature, even a correctly-permissioned workflow will fail. Check org-level
|
|
42
|
+
Actions settings under Settings > Actions > General.
|
|
43
|
+
fix: |
|
|
44
|
+
Add attestations: write to the permissions block of the job (or workflow)
|
|
45
|
+
that runs actions/attest-build-provenance. If using OIDC for cloud auth,
|
|
46
|
+
id-token: write is also required for the attestation signature.
|
|
47
|
+
fix_code:
|
|
48
|
+
- language: yaml
|
|
49
|
+
label: 'Add attestations: write to job permissions'
|
|
50
|
+
code: |
|
|
51
|
+
jobs:
|
|
52
|
+
build:
|
|
53
|
+
runs-on: ubuntu-latest
|
|
54
|
+
permissions:
|
|
55
|
+
contents: read
|
|
56
|
+
attestations: write # Required for attest-build-provenance
|
|
57
|
+
id-token: write # Required for OIDC-based attestation signing
|
|
58
|
+
steps:
|
|
59
|
+
- uses: actions/checkout@v4
|
|
60
|
+
|
|
61
|
+
- name: Build artifact
|
|
62
|
+
run: make build
|
|
63
|
+
|
|
64
|
+
- uses: actions/attest-build-provenance@v2
|
|
65
|
+
with:
|
|
66
|
+
subject-path: dist/my-artifact
|
|
67
|
+
- language: yaml
|
|
68
|
+
label: 'Container registry publish with attestation'
|
|
69
|
+
code: |
|
|
70
|
+
jobs:
|
|
71
|
+
publish:
|
|
72
|
+
runs-on: ubuntu-latest
|
|
73
|
+
permissions:
|
|
74
|
+
contents: read
|
|
75
|
+
packages: write
|
|
76
|
+
attestations: write # Required
|
|
77
|
+
id-token: write # Required
|
|
78
|
+
steps:
|
|
79
|
+
- uses: actions/checkout@v4
|
|
80
|
+
- uses: docker/build-push-action@v6
|
|
81
|
+
id: push
|
|
82
|
+
with:
|
|
83
|
+
push: true
|
|
84
|
+
tags: ghcr.io/${{ github.repository }}:latest
|
|
85
|
+
- uses: actions/attest-build-provenance@v2
|
|
86
|
+
with:
|
|
87
|
+
subject-name: ghcr.io/${{ github.repository }}
|
|
88
|
+
subject-digest: ${{ steps.push.outputs.digest }}
|
|
89
|
+
prevention:
|
|
90
|
+
- 'Always include both attestations: write and id-token: write when using attest-build-provenance'
|
|
91
|
+
- 'Check action release notes when adding actions that use newer GitHub platform features'
|
|
92
|
+
- 'The missing scope is not always named in 403 error messages — cross-reference the action docs for required permissions'
|
|
93
|
+
- 'Enable required_workflows or org-level policies to verify attestation is permitted before deploying'
|
|
94
|
+
docs:
|
|
95
|
+
- url: 'https://docs.github.com/en/actions/security-for-github-actions/using-artifact-attestations/using-artifact-attestations-to-establish-provenance-for-builds'
|
|
96
|
+
label: 'GitHub Docs — Using artifact attestations to establish provenance'
|
|
97
|
+
- url: 'https://github.com/actions/attest-build-provenance'
|
|
98
|
+
label: 'actions/attest-build-provenance repository'
|
|
99
|
+
- url: 'https://docs.github.com/en/actions/writing-workflows/choosing-what-your-workflow-does/controlling-permissions-for-github_token'
|
|
100
|
+
label: 'GitHub Docs — Controlling permissions for GITHUB_TOKEN'
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
id: runner-environment-100
|
|
2
|
+
title: "ubuntu-24.04 libmysqlclient-dev renamed to default-libmysqlclient-dev — apt install fails"
|
|
3
|
+
category: runner-environment
|
|
4
|
+
severity: error
|
|
5
|
+
tags:
|
|
6
|
+
- ubuntu-24.04
|
|
7
|
+
- apt
|
|
8
|
+
- mysql
|
|
9
|
+
- libmysqlclient
|
|
10
|
+
- migration
|
|
11
|
+
- package-rename
|
|
12
|
+
patterns:
|
|
13
|
+
- regex: 'Package .libmysqlclient-dev. has no installation candidate'
|
|
14
|
+
flags: "i"
|
|
15
|
+
- regex: 'Unable to locate package openjdk-8|libmysqlclient-dev.*no installation'
|
|
16
|
+
flags: "i"
|
|
17
|
+
error_messages:
|
|
18
|
+
- "E: Package 'libmysqlclient-dev' has no installation candidate"
|
|
19
|
+
- "Package 'libmysqlclient-dev' has no installation candidate"
|
|
20
|
+
root_cause: |
|
|
21
|
+
In Ubuntu 24.04 (Noble Numbat), the libmysqlclient-dev package was removed from
|
|
22
|
+
the default apt repositories. MySQL 8.x development headers are now provided by
|
|
23
|
+
default-libmysqlclient-dev (a metapackage resolving to MySQL or MariaDB headers)
|
|
24
|
+
or the MariaDB-specific libmariadb-dev. Workflows migrating from ubuntu-22.04
|
|
25
|
+
(which carried libmysqlclient-dev) to ubuntu-24.04 fail at the apt-get install
|
|
26
|
+
step. This affects Django (mysqlclient), Ruby on Rails (mysql2 gem), PHP (mysqli
|
|
27
|
+
extension compile), and Go applications using CGO MySQL bindings.
|
|
28
|
+
fix: |
|
|
29
|
+
Replace libmysqlclient-dev with default-libmysqlclient-dev, which resolves to
|
|
30
|
+
the correct MySQL or MariaDB dev headers on Ubuntu 22.04 and 24.04. For projects
|
|
31
|
+
strictly requiring Oracle MySQL headers, add the official MySQL APT repository
|
|
32
|
+
before installing.
|
|
33
|
+
fix_code:
|
|
34
|
+
- language: yaml
|
|
35
|
+
label: "Replace libmysqlclient-dev with default-libmysqlclient-dev"
|
|
36
|
+
code: |
|
|
37
|
+
- name: Install MySQL development headers
|
|
38
|
+
run: |
|
|
39
|
+
sudo apt-get update
|
|
40
|
+
# libmysqlclient-dev removed in Ubuntu 24.04 — use default-libmysqlclient-dev
|
|
41
|
+
sudo apt-get install -y default-libmysqlclient-dev
|
|
42
|
+
- language: yaml
|
|
43
|
+
label: "Alternative: MariaDB headers explicitly"
|
|
44
|
+
code: |
|
|
45
|
+
- name: Install MariaDB development headers
|
|
46
|
+
run: |
|
|
47
|
+
sudo apt-get update
|
|
48
|
+
sudo apt-get install -y libmariadb-dev pkg-config
|
|
49
|
+
- language: yaml
|
|
50
|
+
label: "Alternative: Oracle MySQL APT repo for strict MySQL requirement"
|
|
51
|
+
code: |
|
|
52
|
+
- name: Add Oracle MySQL APT repository
|
|
53
|
+
run: |
|
|
54
|
+
wget https://dev.mysql.com/get/mysql-apt-config_0.8.33-1_all.deb
|
|
55
|
+
sudo dpkg -i mysql-apt-config_0.8.33-1_all.deb
|
|
56
|
+
sudo apt-get update
|
|
57
|
+
sudo apt-get install -y libmysqlclient-dev
|
|
58
|
+
prevention:
|
|
59
|
+
- "Grep workflow files for libmysqlclient-dev before migrating from ubuntu-22.04 to ubuntu-24.04"
|
|
60
|
+
- "Use default-libmysqlclient-dev in all new workflows — it works on both Ubuntu 22.04 and 24.04"
|
|
61
|
+
- "Pin MySQL client library versions in requirements.txt or Gemfile rather than relying on system headers"
|
|
62
|
+
- "Add an ubuntu-24.04 job to the matrix before retiring ubuntu-22.04 to catch apt package renames early"
|
|
63
|
+
docs:
|
|
64
|
+
- url: "https://packages.ubuntu.com/noble/default-libmysqlclient-dev"
|
|
65
|
+
label: "Ubuntu Noble: default-libmysqlclient-dev"
|
|
66
|
+
- url: "https://dev.mysql.com/doc/refman/8.0/en/linux-installation-apt-repo.html"
|
|
67
|
+
label: "MySQL APT Repository Guide"
|
|
68
|
+
- url: "https://github.com/actions/runner-images/issues/9932"
|
|
69
|
+
label: "runner-images #9932: Ubuntu 24.04 MySQL package rename"
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
id: runner-environment-101
|
|
2
|
+
title: "ubuntu-24.04 openjdk-8-jdk unavailable via apt — must use actions/setup-java"
|
|
3
|
+
category: runner-environment
|
|
4
|
+
severity: error
|
|
5
|
+
tags:
|
|
6
|
+
- ubuntu-24.04
|
|
7
|
+
- java
|
|
8
|
+
- openjdk
|
|
9
|
+
- apt
|
|
10
|
+
- migration
|
|
11
|
+
- jdk8
|
|
12
|
+
patterns:
|
|
13
|
+
- regex: 'Package .openjdk-8-(jdk|jre|jre-headless). has no installation candidate'
|
|
14
|
+
flags: "i"
|
|
15
|
+
- regex: 'Unable to locate package openjdk-8'
|
|
16
|
+
flags: "i"
|
|
17
|
+
error_messages:
|
|
18
|
+
- "E: Package 'openjdk-8-jdk' has no installation candidate"
|
|
19
|
+
- "E: Unable to locate package openjdk-8-jdk"
|
|
20
|
+
- "E: Package 'openjdk-8-jre-headless' has no installation candidate"
|
|
21
|
+
root_cause: |
|
|
22
|
+
Ubuntu 24.04 (Noble) dropped OpenJDK 8 from its official apt repositories because
|
|
23
|
+
OpenJDK 8 reached end-of-life upstream. Workflows that install Java via
|
|
24
|
+
apt-get install -y openjdk-8-jdk succeed on ubuntu-22.04 but fail immediately on
|
|
25
|
+
ubuntu-24.04 with "no installation candidate". Common affected scenarios include:
|
|
26
|
+
|
|
27
|
+
- Legacy Android builds requiring Java 8 compile target
|
|
28
|
+
- Apache Ant or Maven builds with a Java 8 minimum
|
|
29
|
+
- Older Spring Boot projects targeting Java 8
|
|
30
|
+
- Workflows that manually set JAVA_HOME after apt-get install
|
|
31
|
+
|
|
32
|
+
The actions/setup-java action with the temurin distribution still supports Java 8
|
|
33
|
+
and is the recommended cross-platform replacement.
|
|
34
|
+
fix: |
|
|
35
|
+
Replace apt-get install openjdk-8-jdk with actions/setup-java using the temurin
|
|
36
|
+
(Eclipse Adoptium, formerly AdoptOpenJDK) distribution. This resolves correctly
|
|
37
|
+
on ubuntu-22.04, ubuntu-24.04, macOS, and Windows runners. Migrate to Java 11 or
|
|
38
|
+
17 LTS if the project allows — Java 8 is past end-of-life.
|
|
39
|
+
fix_code:
|
|
40
|
+
- language: yaml
|
|
41
|
+
label: "Replace apt install with actions/setup-java for JDK 8"
|
|
42
|
+
code: |
|
|
43
|
+
- name: Set up Java 8
|
|
44
|
+
uses: actions/setup-java@v4
|
|
45
|
+
with:
|
|
46
|
+
distribution: temurin # Eclipse Adoptium (formerly AdoptOpenJDK)
|
|
47
|
+
java-version: '8'
|
|
48
|
+
# Prefer java-version: '17' or '21' where the project allows
|
|
49
|
+
- language: yaml
|
|
50
|
+
label: "Matrix: test multiple Java versions"
|
|
51
|
+
code: |
|
|
52
|
+
strategy:
|
|
53
|
+
matrix:
|
|
54
|
+
java: ['8', '11', '17', '21']
|
|
55
|
+
steps:
|
|
56
|
+
- uses: actions/setup-java@v4
|
|
57
|
+
with:
|
|
58
|
+
distribution: temurin
|
|
59
|
+
java-version: ${{ matrix.java }}
|
|
60
|
+
prevention:
|
|
61
|
+
- "Prefer actions/setup-java over apt-get for Java in all workflows — explicit version pinning works cross-platform"
|
|
62
|
+
- "Upgrade to Java 11 or 17 LTS where feasible — Java 8 is EOL"
|
|
63
|
+
- "Search workflow files for openjdk-8 before migrating the runner label to ubuntu-24.04"
|
|
64
|
+
- "Use distribution: zulu as an alternative Azul OpenJDK distribution if Temurin is not suitable"
|
|
65
|
+
docs:
|
|
66
|
+
- url: "https://github.com/actions/setup-java"
|
|
67
|
+
label: "actions/setup-java — supported distributions and versions"
|
|
68
|
+
- url: "https://adoptium.net/temurin/releases/?version=8"
|
|
69
|
+
label: "Eclipse Temurin Java 8 Releases"
|
|
70
|
+
- url: "https://packages.ubuntu.com/search?keywords=openjdk-8"
|
|
71
|
+
label: "Ubuntu Package Search: openjdk-8 availability"
|
|
72
|
+
- url: "https://github.com/actions/runner-images/issues/9848"
|
|
73
|
+
label: "runner-images #9848: openjdk-8 missing on Ubuntu 24.04"
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
id: runner-environment-102
|
|
2
|
+
title: "macOS 14+ xcrun altool removed — notarization workflows fail with 'unable to find utility'"
|
|
3
|
+
category: runner-environment
|
|
4
|
+
severity: error
|
|
5
|
+
tags:
|
|
6
|
+
- macos
|
|
7
|
+
- xcode
|
|
8
|
+
- notarization
|
|
9
|
+
- altool
|
|
10
|
+
- notarytool
|
|
11
|
+
- codesign
|
|
12
|
+
- migration
|
|
13
|
+
patterns:
|
|
14
|
+
- regex: 'xcrun: error: unable to find utility .altool.'
|
|
15
|
+
flags: "i"
|
|
16
|
+
- regex: 'altool.*has been deprecated and is no longer supported|unable to find utility .altool.'
|
|
17
|
+
flags: "i"
|
|
18
|
+
error_messages:
|
|
19
|
+
- "xcrun: error: unable to find utility \"altool\", not a developer tool or in PATH"
|
|
20
|
+
- "altool has been deprecated and is no longer supported"
|
|
21
|
+
root_cause: |
|
|
22
|
+
xcrun altool was Apple's original notarization CLI tool. Apple deprecated it in
|
|
23
|
+
Xcode 13 (WWDC 2021) and removed it entirely in Xcode 15 (September 2023).
|
|
24
|
+
GitHub's macOS 14, macOS 15, and macOS 26 runners ship Xcode 15 or later, so
|
|
25
|
+
altool is not present on these runners.
|
|
26
|
+
|
|
27
|
+
Workflows that use any of the following commands fail immediately on macos-14+:
|
|
28
|
+
xcrun altool --notarize-app ...
|
|
29
|
+
xcrun altool --notarization-info ...
|
|
30
|
+
xcrun altool --staple-archive ...
|
|
31
|
+
xcrun altool --notarization-history ...
|
|
32
|
+
|
|
33
|
+
This is a runner image migration break: workflows working on macos-12 or macos-13
|
|
34
|
+
(Xcode 14) silently stop working when the runner label switches to macos-14 or
|
|
35
|
+
macos-latest, which ships Xcode 15+. The failure is loud (non-zero exit from
|
|
36
|
+
xcrun) but easy to miss if teams assume the mac runner version did not change.
|
|
37
|
+
fix: |
|
|
38
|
+
Migrate to xcrun notarytool, the replacement for altool since Xcode 13. Notarytool
|
|
39
|
+
accepts the same Apple ID + app-specific password credentials or the more secure
|
|
40
|
+
App Store Connect API key (recommended for CI — avoids 2FA issues). Submissions
|
|
41
|
+
complete synchronously with --wait, replacing the polling loop previously required
|
|
42
|
+
by altool.
|
|
43
|
+
fix_code:
|
|
44
|
+
- language: yaml
|
|
45
|
+
label: "Migrate from altool to notarytool (Apple ID auth)"
|
|
46
|
+
code: |
|
|
47
|
+
- name: Notarize app
|
|
48
|
+
env:
|
|
49
|
+
APPLE_ID: ${{ secrets.APPLE_ID }}
|
|
50
|
+
APPLE_PASSWORD: ${{ secrets.APPLE_APP_SPECIFIC_PASSWORD }}
|
|
51
|
+
TEAM_ID: ${{ secrets.APPLE_TEAM_ID }}
|
|
52
|
+
run: |
|
|
53
|
+
xcrun notarytool submit MyApp.zip \
|
|
54
|
+
--apple-id "$APPLE_ID" \
|
|
55
|
+
--password "$APPLE_PASSWORD" \
|
|
56
|
+
--team-id "$TEAM_ID" \
|
|
57
|
+
--wait
|
|
58
|
+
|
|
59
|
+
- name: Staple notarization ticket
|
|
60
|
+
run: xcrun stapler staple MyApp.app
|
|
61
|
+
- language: yaml
|
|
62
|
+
label: "Preferred: App Store Connect API key auth (no 2FA issues)"
|
|
63
|
+
code: |
|
|
64
|
+
- name: Notarize with App Store Connect API key
|
|
65
|
+
env:
|
|
66
|
+
API_KEY_ID: ${{ secrets.AC_API_KEY_ID }}
|
|
67
|
+
API_KEY_ISSUER: ${{ secrets.AC_API_KEY_ISSUER }}
|
|
68
|
+
API_KEY_PATH: /tmp/AuthKey.p8
|
|
69
|
+
run: |
|
|
70
|
+
printf '%s' "${{ secrets.AC_API_KEY }}" > "$API_KEY_PATH"
|
|
71
|
+
xcrun notarytool submit MyApp.zip \
|
|
72
|
+
--key "$API_KEY_PATH" \
|
|
73
|
+
--key-id "$API_KEY_ID" \
|
|
74
|
+
--issuer "$API_KEY_ISSUER" \
|
|
75
|
+
--wait
|
|
76
|
+
prevention:
|
|
77
|
+
- "Migrate all xcrun altool commands to xcrun notarytool — altool is gone on any Xcode 15+ runner"
|
|
78
|
+
- "Prefer App Store Connect API key authentication in CI — avoids 2FA prompts and app-specific password rotation"
|
|
79
|
+
- "Search workflow files for altool before updating the macos runner label from macos-13 to macos-14 or macos-latest"
|
|
80
|
+
- "Test notarization on macos-14 alongside macos-13 before fully retiring the older runner label"
|
|
81
|
+
docs:
|
|
82
|
+
- url: "https://developer.apple.com/documentation/notaryapi"
|
|
83
|
+
label: "Apple: Notary API (notarytool)"
|
|
84
|
+
- url: "https://developer.apple.com/news/releases/xcode-15-release-notes/"
|
|
85
|
+
label: "Xcode 15 Release Notes — altool removal"
|
|
86
|
+
- url: "https://developer.apple.com/documentation/security/notarizing-macos-software-before-distribution/customizing-the-notarization-workflow"
|
|
87
|
+
label: "Apple: Customizing the notarization workflow"
|
|
88
|
+
- url: "https://github.com/actions/runner-images/discussions/7505"
|
|
89
|
+
label: "runner-images: macOS 14 Xcode 15 notarization migration"
|
package/errors/runner-environment/setup-python-version-range-resolves-to-313-distutils-removed.yml
ADDED
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
id: runner-environment-099
|
|
2
|
+
title: "setup-python python-version '3' resolves to Python 3.13 — distutils and other removed modules cause ImportError"
|
|
3
|
+
category: runner-environment
|
|
4
|
+
severity: error
|
|
5
|
+
tags:
|
|
6
|
+
- setup-python
|
|
7
|
+
- python-3-13
|
|
8
|
+
- distutils
|
|
9
|
+
- breaking-change
|
|
10
|
+
- version-pinning
|
|
11
|
+
patterns:
|
|
12
|
+
- regex: 'ModuleNotFoundError.*distutils'
|
|
13
|
+
flags: 'i'
|
|
14
|
+
- regex: 'No module named .distutils.'
|
|
15
|
+
flags: 'i'
|
|
16
|
+
- regex: 'ImportError.*distutils'
|
|
17
|
+
flags: 'i'
|
|
18
|
+
error_messages:
|
|
19
|
+
- "ModuleNotFoundError: No module named 'distutils'"
|
|
20
|
+
- "No module named 'distutils'"
|
|
21
|
+
- "error: can't find distutils"
|
|
22
|
+
root_cause: |
|
|
23
|
+
Python 3.12 moved distutils into setuptools (no longer stdlib), and Python 3.13
|
|
24
|
+
fully removed it from the standard library (PEP 632, deprecated since 3.10).
|
|
25
|
+
|
|
26
|
+
GitHub Actions workflows using a floating python-version constraint:
|
|
27
|
+
python-version: '3'
|
|
28
|
+
python-version: '3.x'
|
|
29
|
+
python-version: 'latest'
|
|
30
|
+
...resolved to Python 3.13 when it became the latest stable release (October 2024).
|
|
31
|
+
Runner images updated to include 3.13 as the available version for these constraints.
|
|
32
|
+
|
|
33
|
+
Any project that imports distutils directly (setup.py, older NumPy, Cython, some
|
|
34
|
+
SWIG bindings) or tools that internally import it will fail with:
|
|
35
|
+
ModuleNotFoundError: No module named 'distutils'
|
|
36
|
+
|
|
37
|
+
Additional modules removed in Python 3.12-3.13 that break CI:
|
|
38
|
+
- cgi, imghdr (removed 3.13)
|
|
39
|
+
- aifc, sunau, chunk, crypt (removed 3.13)
|
|
40
|
+
- imp module (removed 3.12)
|
|
41
|
+
- asynchat, asyncore (removed 3.12)
|
|
42
|
+
|
|
43
|
+
The failure is from the floating version constraint resolving higher than intended,
|
|
44
|
+
not from the runner image itself. Pinned workflows on 3.11 or 3.12 are unaffected.
|
|
45
|
+
fix: |
|
|
46
|
+
Pin python-version to a specific minor version instead of using a floating
|
|
47
|
+
constraint. If distutils is required, use the setuptools-provided shim.
|
|
48
|
+
|
|
49
|
+
Migration options for distutils usage:
|
|
50
|
+
- Replace distutils.core.setup with setuptools.setup
|
|
51
|
+
- Replace distutils.util.strtobool with a custom bool parser
|
|
52
|
+
- Replace distutils.version.LooseVersion with packaging.version.Version
|
|
53
|
+
- Install setuptools on Python 3.13 to restore the distutils shim
|
|
54
|
+
fix_code:
|
|
55
|
+
- language: yaml
|
|
56
|
+
label: 'Pin to specific minor version to avoid 3.13+ resolution'
|
|
57
|
+
code: |
|
|
58
|
+
- uses: actions/setup-python@v5
|
|
59
|
+
with:
|
|
60
|
+
python-version: '3.11' # Pinned — won't resolve to 3.13+
|
|
61
|
+
# OR: '3.12' (distutils still available via setuptools shim)
|
|
62
|
+
- language: yaml
|
|
63
|
+
label: 'Use setuptools shim on Python 3.13'
|
|
64
|
+
code: |
|
|
65
|
+
- uses: actions/setup-python@v5
|
|
66
|
+
with:
|
|
67
|
+
python-version: '3.13'
|
|
68
|
+
- name: Install setuptools for distutils compatibility
|
|
69
|
+
run: pip install setuptools # Restores distutils shim on 3.13+
|
|
70
|
+
- language: yaml
|
|
71
|
+
label: 'Pin version via .python-version file'
|
|
72
|
+
code: |
|
|
73
|
+
# .python-version file in repo root:
|
|
74
|
+
# 3.11.9
|
|
75
|
+
|
|
76
|
+
- uses: actions/setup-python@v5
|
|
77
|
+
with:
|
|
78
|
+
python-version-file: '.python-version' # Reads from repo file
|
|
79
|
+
- language: yaml
|
|
80
|
+
label: 'Matrix across versions to catch breakage early'
|
|
81
|
+
code: |
|
|
82
|
+
jobs:
|
|
83
|
+
test:
|
|
84
|
+
strategy:
|
|
85
|
+
matrix:
|
|
86
|
+
python-version: ['3.11', '3.12', '3.13']
|
|
87
|
+
steps:
|
|
88
|
+
- uses: actions/setup-python@v5
|
|
89
|
+
with:
|
|
90
|
+
python-version: ${{ matrix.python-version }}
|
|
91
|
+
- run: pip install setuptools # Shim for 3.13
|
|
92
|
+
- run: pip install -e .
|
|
93
|
+
- run: pytest
|
|
94
|
+
prevention:
|
|
95
|
+
- 'Never use python-version: 3 or python-version: 3.x in production workflows without testing each new minor release'
|
|
96
|
+
- 'Pin to a specific minor version (3.11, 3.12) or use a .python-version file in the repo'
|
|
97
|
+
- 'Run CI on a matrix of python versions to catch version-specific breakage early'
|
|
98
|
+
- 'Audit setup.py for direct distutils imports and replace with setuptools equivalents before upgrading to 3.13'
|
|
99
|
+
docs:
|
|
100
|
+
- url: 'https://docs.python.org/3/whatsnew/3.13.html#removed-modules'
|
|
101
|
+
label: 'Python 3.13 — Removed Modules'
|
|
102
|
+
- url: 'https://peps.python.org/pep-0632/'
|
|
103
|
+
label: 'PEP 632 — Deprecate distutils'
|
|
104
|
+
- url: 'https://github.com/actions/setup-python'
|
|
105
|
+
label: 'actions/setup-python repository'
|
|
106
|
+
- url: 'https://docs.github.com/en/actions/use-cases-and-examples/building-and-testing/building-and-testing-python'
|
|
107
|
+
label: 'GitHub Docs — Building and testing Python'
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
id: silent-failures-049
|
|
2
|
+
title: 'GITHUB_OUTPUT multiline heredoc value silently truncated when content contains the delimiter string'
|
|
3
|
+
category: silent-failures
|
|
4
|
+
severity: silent-failure
|
|
5
|
+
tags:
|
|
6
|
+
- GITHUB_OUTPUT
|
|
7
|
+
- multiline
|
|
8
|
+
- heredoc
|
|
9
|
+
- delimiter-collision
|
|
10
|
+
- environment-files
|
|
11
|
+
patterns:
|
|
12
|
+
- regex: 'echo\s+\"\w+<<EOF\"'
|
|
13
|
+
flags: 'i'
|
|
14
|
+
error_messages: []
|
|
15
|
+
root_cause: |
|
|
16
|
+
GitHub Actions environment files (GITHUB_OUTPUT, GITHUB_ENV, GITHUB_STEP_SUMMARY)
|
|
17
|
+
use a heredoc-style syntax for multiline values:
|
|
18
|
+
|
|
19
|
+
echo "BODY<<EOF" >> $GITHUB_OUTPUT
|
|
20
|
+
echo "first line" >> $GITHUB_OUTPUT
|
|
21
|
+
echo "second line" >> $GITHUB_OUTPUT
|
|
22
|
+
echo "EOF" >> $GITHUB_OUTPUT
|
|
23
|
+
|
|
24
|
+
If the multiline content itself contains the exact delimiter string ("EOF" in
|
|
25
|
+
the example above) on a line by itself, the runner stops reading at that point
|
|
26
|
+
and silently truncates the value. No error is raised and the step exits 0.
|
|
27
|
+
|
|
28
|
+
Common scenarios:
|
|
29
|
+
1. A release body or commit message that happens to contain "EOF" on its own line.
|
|
30
|
+
2. A generated file that includes shell script snippets (which often use EOF).
|
|
31
|
+
3. A changelog that uses EOF as a delimiter in a code example.
|
|
32
|
+
|
|
33
|
+
The delimiter collision causes the output variable to contain only the content
|
|
34
|
+
up to (but not including) the first occurrence of the delimiter string, with
|
|
35
|
+
no indication that truncation occurred.
|
|
36
|
+
fix: |
|
|
37
|
+
Use a randomly-generated or sufficiently unique delimiter that will not
|
|
38
|
+
appear in the content. Common approaches:
|
|
39
|
+
|
|
40
|
+
1. Generate a UUID or random hex string at runtime and use it as the delimiter.
|
|
41
|
+
2. Use a very long, unusual string that is unlikely to appear in content.
|
|
42
|
+
|
|
43
|
+
The GitHub documentation explicitly recommends a random delimiter to avoid
|
|
44
|
+
this collision:
|
|
45
|
+
https://docs.github.com/en/actions/writing-workflows/choosing-what-your-workflow-does/workflow-commands-for-github-actions#multiline-strings
|
|
46
|
+
fix_code:
|
|
47
|
+
- language: yaml
|
|
48
|
+
label: 'Unsafe — static delimiter may collide with content'
|
|
49
|
+
code: |
|
|
50
|
+
- name: Set multiline output (unsafe)
|
|
51
|
+
run: |
|
|
52
|
+
echo "BODY<<EOF" >> $GITHUB_OUTPUT
|
|
53
|
+
echo "${{ steps.notes.outputs.content }}" >> $GITHUB_OUTPUT
|
|
54
|
+
echo "EOF" >> $GITHUB_OUTPUT
|
|
55
|
+
- language: yaml
|
|
56
|
+
label: 'Safe — random delimiter prevents collision'
|
|
57
|
+
code: |
|
|
58
|
+
- name: Set multiline output (safe random delimiter)
|
|
59
|
+
run: |
|
|
60
|
+
DELIM="ghadelim_$(head -c 16 /dev/urandom | base64 | tr -dc 'a-zA-Z0-9' | head -c 16)"
|
|
61
|
+
echo "BODY<<${DELIM}" >> $GITHUB_OUTPUT
|
|
62
|
+
echo "${{ steps.notes.outputs.content }}" >> $GITHUB_OUTPUT
|
|
63
|
+
echo "${DELIM}" >> $GITHUB_OUTPUT
|
|
64
|
+
- language: yaml
|
|
65
|
+
label: 'Windows — PowerShell random delimiter'
|
|
66
|
+
code: |
|
|
67
|
+
- name: Set multiline output (PowerShell)
|
|
68
|
+
shell: pwsh
|
|
69
|
+
run: |
|
|
70
|
+
$delim = "ghadelim_$([System.Guid]::NewGuid().ToString('N').Substring(0, 16))"
|
|
71
|
+
"BODY<<$delim" | Out-File -FilePath $env:GITHUB_OUTPUT -Append -Encoding utf8
|
|
72
|
+
$releaseNotes | Out-File -FilePath $env:GITHUB_OUTPUT -Append -Encoding utf8
|
|
73
|
+
$delim | Out-File -FilePath $env:GITHUB_OUTPUT -Append -Encoding utf8
|
|
74
|
+
prevention:
|
|
75
|
+
- 'Never use a simple static delimiter like EOF, END, or DONE for multiline GITHUB_OUTPUT values'
|
|
76
|
+
- 'Always use a random or UUID-based delimiter when the content could be dynamic or user-provided'
|
|
77
|
+
- 'Test multiline output steps with content that deliberately contains common delimiter strings'
|
|
78
|
+
- 'GitHub docs recommend randomly generated delimiters for all multiline environment file writes'
|
|
79
|
+
docs:
|
|
80
|
+
- url: 'https://docs.github.com/en/actions/writing-workflows/choosing-what-your-workflow-does/workflow-commands-for-github-actions#multiline-strings'
|
|
81
|
+
label: 'GitHub Docs — Workflow commands: multiline strings'
|
|
82
|
+
- url: 'https://docs.github.com/en/actions/writing-workflows/choosing-what-your-workflow-does/store-information-in-variables'
|
|
83
|
+
label: 'GitHub Docs — Store information in variables'
|
package/package.json
CHANGED