@htekdev/actions-debugger 1.0.44 → 1.0.46
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/caching-artifacts/caching-artifacts-034.yml +70 -0
- package/errors/known-unsolved/known-unsolved-035.yml +97 -0
- package/errors/known-unsolved/known-unsolved-036.yml +87 -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/silent-failures/silent-failures-050.yml +93 -0
- package/errors/triggers/triggers-033.yml +100 -0
- package/package.json +1 -1
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
id: caching-artifacts-034
|
|
2
|
+
title: "Cache entries created in a PR branch are not accessible from other PR branches or the default branch"
|
|
3
|
+
category: caching-artifacts
|
|
4
|
+
severity: limitation
|
|
5
|
+
tags:
|
|
6
|
+
- cache
|
|
7
|
+
- branch-scope
|
|
8
|
+
- pull-request
|
|
9
|
+
- isolation
|
|
10
|
+
- cache-miss
|
|
11
|
+
- known-limitation
|
|
12
|
+
patterns:
|
|
13
|
+
- regex: 'cache.*miss.*pull.request|cache.*not.*found.*branch|cache.*not.*accessible.*pr'
|
|
14
|
+
flags: "i"
|
|
15
|
+
- regex: 'cache.*scope.*branch|branch.specific.*cache.*miss|pr.*branch.*no.*cache'
|
|
16
|
+
flags: "i"
|
|
17
|
+
error_messages:
|
|
18
|
+
- "Cache not found for input keys"
|
|
19
|
+
root_cause: |
|
|
20
|
+
GitHub Actions cache entries are strictly scoped to the branch that created them. The
|
|
21
|
+
cache lookup order during a restore operation is:
|
|
22
|
+
|
|
23
|
+
1. Exact key match on the CURRENT branch
|
|
24
|
+
2. restore-keys prefix match on the CURRENT branch
|
|
25
|
+
3. restore-keys prefix match on the BASE branch (for PRs) or the DEFAULT branch
|
|
26
|
+
|
|
27
|
+
Consequences of this scoping:
|
|
28
|
+
- A cache saved on PR branch A is NOT readable from PR branch B
|
|
29
|
+
- A cache saved on a PR branch is NOT readable from the default branch's push workflow
|
|
30
|
+
- Each new PR starts with a cold cache until it produces its own branch-scoped entry
|
|
31
|
+
- The base branch cache is only available as a fallback during a PR workflow restore
|
|
32
|
+
|
|
33
|
+
This is an intentional security isolation boundary — one PR cannot read potentially
|
|
34
|
+
sensitive build artifacts cached by another PR. There is no configuration option to
|
|
35
|
+
enable cross-PR cache sharing.
|
|
36
|
+
|
|
37
|
+
Teams migrating from shared CI caches (Jenkins, GitLab with shared runner caches) are
|
|
38
|
+
frequently surprised by persistent cache misses across parallel PRs on active repos.
|
|
39
|
+
fix: |
|
|
40
|
+
Structure cache keys and restore-keys to maximize fallback hits from the default branch.
|
|
41
|
+
The strategy: save a well-keyed cache on the default branch after each merge (readable
|
|
42
|
+
by all PRs as a fallback), and include base-branch and OS-only restore-key prefixes so
|
|
43
|
+
new PR runs warm up quickly via partial matches.
|
|
44
|
+
|
|
45
|
+
For dependency caches, a lockfile-hash-keyed entry on main ensures new PRs get a
|
|
46
|
+
near-hit on first run via restore-keys, rather than a completely cold cache.
|
|
47
|
+
fix_code:
|
|
48
|
+
- language: yaml
|
|
49
|
+
label: "Cache key strategy that maximizes default-branch fallback for all PRs"
|
|
50
|
+
code: |
|
|
51
|
+
- name: Cache dependencies
|
|
52
|
+
uses: actions/cache@v4
|
|
53
|
+
with:
|
|
54
|
+
path: ~/.npm
|
|
55
|
+
# Primary: exact branch + lockfile hash (hit on repeat runs of same PR)
|
|
56
|
+
key: ${{ runner.os }}-npm-${{ github.ref_name }}-${{ hashFiles('**/package-lock.json') }}
|
|
57
|
+
# Fallbacks: base branch (for PRs) → default branch → OS-only
|
|
58
|
+
restore-keys: |
|
|
59
|
+
${{ runner.os }}-npm-${{ github.base_ref }}-
|
|
60
|
+
${{ runner.os }}-npm-
|
|
61
|
+
prevention:
|
|
62
|
+
- "Add restore-keys with base branch and OS-only prefixes so PRs fall back to main's cache"
|
|
63
|
+
- "Ensure the default branch workflow saves a fresh cache after each merge so PRs have a warm fallback"
|
|
64
|
+
- "Be aware that parallel PRs each maintain their own independent branch-scoped cache"
|
|
65
|
+
- "For monorepos, include the workspace or package path in the cache key to prevent cross-PR key collisions"
|
|
66
|
+
docs:
|
|
67
|
+
- url: "https://docs.github.com/en/actions/writing-workflows/choosing-what-your-workflow-does/caching-dependencies-to-speed-up-workflows#restrictions-for-accessing-a-cache"
|
|
68
|
+
label: "GitHub Docs: Cache access restrictions by branch"
|
|
69
|
+
- url: "https://github.com/orgs/community/discussions/10539"
|
|
70
|
+
label: "GitHub Community: Cache access is restricted to the same branch and base branches"
|
|
@@ -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,87 @@
|
|
|
1
|
+
id: known-unsolved-036
|
|
2
|
+
title: "Scheduled workflows auto-disabled after 60 days of repository inactivity"
|
|
3
|
+
category: known-unsolved
|
|
4
|
+
severity: limitation
|
|
5
|
+
tags:
|
|
6
|
+
- schedule
|
|
7
|
+
- cron
|
|
8
|
+
- inactivity
|
|
9
|
+
- disabled
|
|
10
|
+
- known-limitation
|
|
11
|
+
- maintenance
|
|
12
|
+
patterns:
|
|
13
|
+
- regex: 'This scheduled workflow is disabled|scheduled workflow.*disabled.*no.*activity'
|
|
14
|
+
flags: "i"
|
|
15
|
+
- regex: 'schedule.*60.day.*inactiv|60.day.*no.*activity.*workflow'
|
|
16
|
+
flags: "i"
|
|
17
|
+
error_messages:
|
|
18
|
+
- "This scheduled workflow is disabled because there has been no repository activity in the past 60 days"
|
|
19
|
+
root_cause: |
|
|
20
|
+
GitHub automatically disables on: schedule workflows in repositories that have had no
|
|
21
|
+
activity (pushes, pull requests, merges) for 60 days. This is a platform resource
|
|
22
|
+
management decision to reduce compute on dormant repositories.
|
|
23
|
+
|
|
24
|
+
When triggered, the Actions tab displays a banner:
|
|
25
|
+
"This scheduled workflow is disabled because there has been no repository activity
|
|
26
|
+
in the past 60 days."
|
|
27
|
+
|
|
28
|
+
GitHub sends a notification email before disabling, but many maintainers miss it.
|
|
29
|
+
|
|
30
|
+
Common affected scenarios:
|
|
31
|
+
- Maintenance repos (dependency update jobs, reporting pipelines) with infrequent code changes
|
|
32
|
+
- Scheduled audit or monitoring workflows in stable, rarely-pushed codebases
|
|
33
|
+
- Open source repos that go quiet between releases
|
|
34
|
+
- Returning after extended leave to find weeks or months of scheduled runs silently missed
|
|
35
|
+
|
|
36
|
+
There is no workflow-level setting to prevent automatic disabling. The only remedies
|
|
37
|
+
are to manually re-enable via the GitHub UI or maintain repository activity artificially.
|
|
38
|
+
fix: |
|
|
39
|
+
To re-enable a disabled scheduled workflow:
|
|
40
|
+
1. Navigate to the repository Actions tab
|
|
41
|
+
2. Select the disabled workflow in the left sidebar
|
|
42
|
+
3. Click the "Enable workflow" button shown in the banner
|
|
43
|
+
|
|
44
|
+
To prevent future auto-disabling, add a keep-alive workflow that creates an empty
|
|
45
|
+
commit on a schedule shorter than 60 days. Using stefanzweifel/git-auto-commit-action
|
|
46
|
+
with --allow-empty avoids modifying tracked files while still generating commit activity
|
|
47
|
+
that resets the 60-day counter.
|
|
48
|
+
|
|
49
|
+
There is no REST API endpoint to re-enable disabled scheduled workflows — it must be
|
|
50
|
+
done via the GitHub UI or by pushing a new commit to the repository.
|
|
51
|
+
fix_code:
|
|
52
|
+
- language: yaml
|
|
53
|
+
label: "Keep-alive workflow — runs monthly to prevent schedule auto-disable"
|
|
54
|
+
code: |
|
|
55
|
+
# .github/workflows/keep-alive.yml
|
|
56
|
+
name: Keep Alive
|
|
57
|
+
|
|
58
|
+
on:
|
|
59
|
+
schedule:
|
|
60
|
+
- cron: '0 0 1 * *' # First of each month — well within 60-day window
|
|
61
|
+
workflow_dispatch:
|
|
62
|
+
|
|
63
|
+
jobs:
|
|
64
|
+
keep-alive:
|
|
65
|
+
runs-on: ubuntu-latest
|
|
66
|
+
permissions:
|
|
67
|
+
contents: write
|
|
68
|
+
steps:
|
|
69
|
+
- uses: actions/checkout@v4
|
|
70
|
+
|
|
71
|
+
- name: Maintain repository activity
|
|
72
|
+
uses: stefanzweifel/git-auto-commit-action@v5
|
|
73
|
+
with:
|
|
74
|
+
commit_message: 'chore: keep-alive [skip ci]'
|
|
75
|
+
commit_options: '--allow-empty'
|
|
76
|
+
prevention:
|
|
77
|
+
- "Monitor the Actions tab for the 60-day inactivity warning banner"
|
|
78
|
+
- "Add a keep-alive workflow to all repos with important scheduled jobs but infrequent commits"
|
|
79
|
+
- "Subscribe to GitHub notification emails so the pre-disable warning is not missed"
|
|
80
|
+
- "Document this limitation in the repo CONTRIBUTING guide for future maintainers"
|
|
81
|
+
docs:
|
|
82
|
+
- url: "https://docs.github.com/en/actions/writing-workflows/choosing-when-your-workflow-runs/events-that-trigger-workflows#schedule"
|
|
83
|
+
label: "GitHub Docs: schedule trigger"
|
|
84
|
+
- url: "https://github.com/orgs/community/discussions/5614"
|
|
85
|
+
label: "GitHub Community #5614: Scheduled workflow disabled after 60 days of inactivity"
|
|
86
|
+
- url: "https://github.com/stefanzweifel/git-auto-commit-action"
|
|
87
|
+
label: "stefanzweifel/git-auto-commit-action — keep-alive commit pattern"
|
|
@@ -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"
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
id: silent-failures-050
|
|
2
|
+
title: "continue-on-error: true on a failing step silently prevents if: failure() downstream steps from running"
|
|
3
|
+
category: silent-failures
|
|
4
|
+
severity: silent-failure
|
|
5
|
+
tags:
|
|
6
|
+
- continue-on-error
|
|
7
|
+
- if-condition
|
|
8
|
+
- failure-check
|
|
9
|
+
- step-outcome
|
|
10
|
+
- silent-skip
|
|
11
|
+
- cleanup
|
|
12
|
+
patterns:
|
|
13
|
+
- regex: 'continue.on.error.*if.*failure|if.*failure.*not.*running.*continue.on.error'
|
|
14
|
+
flags: "i"
|
|
15
|
+
- regex: 'cleanup.*step.*skipped.*continue.on.error|failure.*handler.*not.*triggered'
|
|
16
|
+
flags: "i"
|
|
17
|
+
error_messages:
|
|
18
|
+
- "Downstream step with if: failure() silently skipped when preceding step uses continue-on-error: true"
|
|
19
|
+
root_cause: |
|
|
20
|
+
When a step fails AND has continue-on-error: true, GitHub Actions marks that step's
|
|
21
|
+
conclusion as success (the error was absorbed) while preserving its outcome as failure.
|
|
22
|
+
Because the step conclusion is success, the job's overall result remains success.
|
|
23
|
+
|
|
24
|
+
Any downstream step or job conditioned on if: failure() evaluates the job's overall
|
|
25
|
+
status, not individual step outcomes. Since the job is still succeeding (the failure was
|
|
26
|
+
continued past), if: failure() evaluates to false — and those downstream steps are
|
|
27
|
+
silently skipped with no error or warning.
|
|
28
|
+
|
|
29
|
+
The pattern developers expect to work (but doesn't):
|
|
30
|
+
|
|
31
|
+
steps:
|
|
32
|
+
- name: Run tests
|
|
33
|
+
run: npm test
|
|
34
|
+
continue-on-error: true
|
|
35
|
+
- name: Upload failure report # NEVER runs — job outcome is still 'success'
|
|
36
|
+
if: failure()
|
|
37
|
+
|
|
38
|
+
Silently broken patterns:
|
|
39
|
+
- Failure notification steps after continue-on-error test or lint steps
|
|
40
|
+
- Cleanup steps conditioned on job failure after a continued-on-error build
|
|
41
|
+
- Report upload or artifact save steps expected to fire when tests fail
|
|
42
|
+
- Alerting steps (Slack, PagerDuty) conditioned on failure() after a tolerated failure
|
|
43
|
+
fix: |
|
|
44
|
+
Reference the specific failing step's outcome directly using steps.<id>.outcome
|
|
45
|
+
instead of the job-level failure() function. Give the step-with-continue-on-error an
|
|
46
|
+
explicit id: field, then condition the downstream step on
|
|
47
|
+
steps.<step-id>.outcome == 'failure'.
|
|
48
|
+
|
|
49
|
+
This correctly captures the step-level failure even when the job overall is succeeding.
|
|
50
|
+
fix_code:
|
|
51
|
+
- language: yaml
|
|
52
|
+
label: "Wrong: if: failure() silently never fires after a continue-on-error step"
|
|
53
|
+
code: |
|
|
54
|
+
steps:
|
|
55
|
+
- name: Run tests
|
|
56
|
+
run: npm test
|
|
57
|
+
continue-on-error: true
|
|
58
|
+
# Job outcome stays 'success' — if: failure() below never executes
|
|
59
|
+
|
|
60
|
+
- name: Upload test failure report
|
|
61
|
+
if: failure()
|
|
62
|
+
uses: actions/upload-artifact@v4
|
|
63
|
+
with:
|
|
64
|
+
name: test-report
|
|
65
|
+
path: test-results/
|
|
66
|
+
- language: yaml
|
|
67
|
+
label: "Correct: check the specific step outcome to catch the continued failure"
|
|
68
|
+
code: |
|
|
69
|
+
steps:
|
|
70
|
+
- name: Run tests
|
|
71
|
+
id: run-tests # Explicit ID required to reference outcome below
|
|
72
|
+
run: npm test
|
|
73
|
+
continue-on-error: true
|
|
74
|
+
|
|
75
|
+
- name: Upload test failure report
|
|
76
|
+
# Fires when tests failed — works correctly even though the job is still 'success'
|
|
77
|
+
if: steps.run-tests.outcome == 'failure'
|
|
78
|
+
uses: actions/upload-artifact@v4
|
|
79
|
+
with:
|
|
80
|
+
name: test-report
|
|
81
|
+
path: test-results/
|
|
82
|
+
prevention:
|
|
83
|
+
- "Never rely on if: failure() to detect failures from steps that use continue-on-error: true"
|
|
84
|
+
- "Assign explicit id: to any step with continue-on-error that needs downstream conditional checks"
|
|
85
|
+
- "Use steps.<id>.outcome == 'failure' to condition steps on a specific earlier step's result"
|
|
86
|
+
- "Test failure-handler steps explicitly by temporarily forcing the upstream step to fail without continue-on-error"
|
|
87
|
+
docs:
|
|
88
|
+
- url: "https://docs.github.com/en/actions/writing-workflows/choosing-what-your-workflow-does/using-conditions-to-control-job-execution"
|
|
89
|
+
label: "GitHub Docs: Using conditions to control job execution"
|
|
90
|
+
- url: "https://docs.github.com/en/actions/writing-workflows/choosing-what-your-workflow-does/accessing-contextual-information-about-workflow-runs#steps-context"
|
|
91
|
+
label: "GitHub Docs: steps context — outcome vs conclusion"
|
|
92
|
+
- url: "https://github.com/orgs/community/discussions/25420"
|
|
93
|
+
label: "GitHub Community: continue-on-error and if: failure() interaction explained"
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
id: triggers-033
|
|
2
|
+
title: "Commits, PRs, and releases created using GITHUB_TOKEN do not trigger new workflow runs"
|
|
3
|
+
category: triggers
|
|
4
|
+
severity: limitation
|
|
5
|
+
tags:
|
|
6
|
+
- GITHUB_TOKEN
|
|
7
|
+
- loopback-prevention
|
|
8
|
+
- push-event
|
|
9
|
+
- pull-request
|
|
10
|
+
- no-trigger
|
|
11
|
+
- known-limitation
|
|
12
|
+
patterns:
|
|
13
|
+
- regex: 'GITHUB_TOKEN.*push.*not.*trigger|workflow.*not.*triggered.*after.*commit'
|
|
14
|
+
flags: "i"
|
|
15
|
+
- regex: 'auto.commit.*no.*workflow|push.*token.*not.*firing.*CI'
|
|
16
|
+
flags: "i"
|
|
17
|
+
error_messages:
|
|
18
|
+
- "Workflow not triggered after automated push using GITHUB_TOKEN"
|
|
19
|
+
root_cause: |
|
|
20
|
+
GitHub Actions intentionally prevents new workflow runs from being triggered by events
|
|
21
|
+
performed with the built-in GITHUB_TOKEN. This loopback prevention exists to stop
|
|
22
|
+
accidental or malicious infinite workflow loops — for example, a push workflow that
|
|
23
|
+
commits back to the repo and re-triggers itself in perpetuity.
|
|
24
|
+
|
|
25
|
+
Affected operations when performed with GITHUB_TOKEN:
|
|
26
|
+
- Pushing a commit to a branch (no push event fired; CI does not run on the new SHA)
|
|
27
|
+
- Creating a pull request via REST API (no pull_request event fired; PR checks do not start)
|
|
28
|
+
- Publishing a release (no release event fired)
|
|
29
|
+
- Merging a PR programmatically (no push or pull_request closed event fired)
|
|
30
|
+
|
|
31
|
+
Common surprise scenarios:
|
|
32
|
+
- Auto-version-bump workflows that commit package.json and expect CI to run on the result
|
|
33
|
+
- Automated changelog commits that should trigger a docs publish pipeline
|
|
34
|
+
- Bots that open PRs using GITHUB_TOKEN expecting branch protection checks to start
|
|
35
|
+
- Tag-from-workflow jobs expecting the resulting tag push to start a release pipeline
|
|
36
|
+
fix: |
|
|
37
|
+
To trigger new workflow runs from operations performed inside a workflow, use a Personal
|
|
38
|
+
Access Token (PAT) or a GitHub App installation token instead of GITHUB_TOKEN. Events
|
|
39
|
+
created with these tokens are not subject to the loopback prevention rule.
|
|
40
|
+
|
|
41
|
+
For organizational workflows, GitHub App tokens are the recommended approach — they
|
|
42
|
+
do not rely on a personal user's credentials and can be scoped to minimum permissions.
|
|
43
|
+
|
|
44
|
+
If triggering new runs is NOT needed, add [skip ci] to the commit message to make the
|
|
45
|
+
intent explicit and prevent accidental CI consumption if a PAT is used later.
|
|
46
|
+
fix_code:
|
|
47
|
+
- language: yaml
|
|
48
|
+
label: "PAT-based checkout so the resulting push triggers downstream CI"
|
|
49
|
+
code: |
|
|
50
|
+
jobs:
|
|
51
|
+
version-bump:
|
|
52
|
+
runs-on: ubuntu-latest
|
|
53
|
+
steps:
|
|
54
|
+
# Check out with PAT — any subsequent push WILL trigger a new push workflow run
|
|
55
|
+
- uses: actions/checkout@v4
|
|
56
|
+
with:
|
|
57
|
+
token: ${{ secrets.MY_PAT }}
|
|
58
|
+
|
|
59
|
+
- name: Bump version
|
|
60
|
+
run: npm version patch --no-git-tag-version
|
|
61
|
+
|
|
62
|
+
- name: Commit and push version bump
|
|
63
|
+
uses: stefanzweifel/git-auto-commit-action@v5
|
|
64
|
+
with:
|
|
65
|
+
commit_message: 'chore: bump version'
|
|
66
|
+
- language: yaml
|
|
67
|
+
label: "GitHub App token so an auto-created PR triggers branch protection checks"
|
|
68
|
+
code: |
|
|
69
|
+
jobs:
|
|
70
|
+
create-pr:
|
|
71
|
+
runs-on: ubuntu-latest
|
|
72
|
+
steps:
|
|
73
|
+
- name: Get GitHub App token
|
|
74
|
+
id: app-token
|
|
75
|
+
uses: actions/create-github-app-token@v1
|
|
76
|
+
with:
|
|
77
|
+
app-id: ${{ secrets.APP_ID }}
|
|
78
|
+
private-key: ${{ secrets.APP_PRIVATE_KEY }}
|
|
79
|
+
|
|
80
|
+
- uses: actions/checkout@v4
|
|
81
|
+
with:
|
|
82
|
+
token: ${{ steps.app-token.outputs.token }}
|
|
83
|
+
|
|
84
|
+
- name: Create PR — App token causes PR checks to be triggered
|
|
85
|
+
uses: peter-evans/create-pull-request@v6
|
|
86
|
+
with:
|
|
87
|
+
token: ${{ steps.app-token.outputs.token }}
|
|
88
|
+
title: 'chore: automated update'
|
|
89
|
+
prevention:
|
|
90
|
+
- "Use a PAT or GitHub App token when downstream workflow runs must be triggered by a commit or PR"
|
|
91
|
+
- "Add [skip ci] to auto-commit messages when downstream CI triggering is explicitly NOT needed"
|
|
92
|
+
- "Document in workflow comments why PAT or App token is used instead of GITHUB_TOKEN"
|
|
93
|
+
- "When debugging missing CI runs after automated commits, check whether GITHUB_TOKEN loopback prevention applies"
|
|
94
|
+
docs:
|
|
95
|
+
- url: "https://docs.github.com/en/actions/security-for-github-actions/security-guides/automatic-token-authentication#using-the-github_token-in-a-workflow"
|
|
96
|
+
label: "GitHub Docs: Automatic token authentication — events triggered by GITHUB_TOKEN"
|
|
97
|
+
- url: "https://github.com/orgs/community/discussions/27072"
|
|
98
|
+
label: "GitHub Community: Push with GITHUB_TOKEN does not trigger new workflow runs"
|
|
99
|
+
- url: "https://docs.github.com/en/apps/creating-github-apps/authenticating-with-a-github-app/making-authenticated-api-requests-with-a-github-app-in-a-github-actions-workflow"
|
|
100
|
+
label: "GitHub Docs: Using a GitHub App token in Actions workflows"
|
package/package.json
CHANGED