@htekdev/actions-debugger 1.0.1 → 1.0.3
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/artifact-download-no-artifacts-found.yml +118 -0
- package/errors/known-unsolved/workflow-rerun-limit.yml +101 -0
- package/errors/permissions-auth/gcp-oidc-workload-identity-misconfigured.yml +130 -0
- package/errors/runner-environment/macos-14-sonoma-eol.yml +89 -0
- package/errors/runner-environment/macos-latest-to-macos-26.yml +127 -0
- package/errors/runner-environment/node20-to-node24-migration.yml +118 -0
- package/errors/runner-environment/powershell-74-to-76-upgrade.yml +112 -0
- package/errors/runner-environment/service-container-unhealthy.yml +126 -0
- package/errors/runner-environment/windows-latest-vs2026-migration.yml +131 -0
- package/errors/silent-failures/hashfiles-empty-string-cache-collision.yml +96 -0
- package/errors/silent-failures/sparse-checkout-sticky-cone-mode.yml +120 -0
- package/errors/triggers/environment-protection-rules-silent-block.yml +105 -0
- package/errors/yaml-syntax/env-context-unavailable-job-level.yml +109 -0
- package/errors/yaml-syntax/reusable-workflow-missing-output-declaration.yml +140 -0
- package/package.json +1 -1
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
id: caching-artifacts-010
|
|
2
|
+
title: "Artifact Download Fails — Unable to Find Any Artifacts for Run"
|
|
3
|
+
category: caching-artifacts
|
|
4
|
+
severity: error
|
|
5
|
+
tags:
|
|
6
|
+
- artifact
|
|
7
|
+
- download
|
|
8
|
+
- run-id
|
|
9
|
+
- cross-workflow
|
|
10
|
+
- upload-artifact
|
|
11
|
+
- download-artifact
|
|
12
|
+
patterns:
|
|
13
|
+
- regex: "Unable to find any artifacts for the associated workflow"
|
|
14
|
+
flags: "i"
|
|
15
|
+
- regex: "No artifacts found for run"
|
|
16
|
+
flags: "i"
|
|
17
|
+
- regex: "Error: Unable to find any artifacts"
|
|
18
|
+
flags: "i"
|
|
19
|
+
error_messages:
|
|
20
|
+
- "Unable to find any artifacts for the associated workflow"
|
|
21
|
+
- "Error: Unable to find any artifacts for the associated workflow"
|
|
22
|
+
- "No artifacts were found with the provided name and filters."
|
|
23
|
+
root_cause: |
|
|
24
|
+
GitHub Actions artifacts are scoped to a specific workflow run. The
|
|
25
|
+
`actions/download-artifact@v4` action (and v3 with `run-id:`) will fail with
|
|
26
|
+
"Unable to find any artifacts" when:
|
|
27
|
+
|
|
28
|
+
1. **Wrong or stale run-id** — The run ID is hard-coded or fetched from a
|
|
29
|
+
prior run that no longer has the expected artifact (artifacts expire after
|
|
30
|
+
the configured retention period, default 90 days).
|
|
31
|
+
|
|
32
|
+
2. **Upload step never ran** — The producing workflow job was cancelled, the
|
|
33
|
+
upload step was skipped due to a failed prior step, or the `if:` condition
|
|
34
|
+
on the upload step evaluated to false.
|
|
35
|
+
|
|
36
|
+
3. **Name mismatch** — The `name:` specified in `download-artifact` doesn't
|
|
37
|
+
exactly match the name used in `upload-artifact` (case-sensitive).
|
|
38
|
+
|
|
39
|
+
4. **Cross-workflow download without explicit run-id** — In v4, downloading
|
|
40
|
+
artifacts from a different workflow run requires an explicit `run-id:`.
|
|
41
|
+
Omitting it defaults to the current run, which may not have those artifacts.
|
|
42
|
+
|
|
43
|
+
Documented in GitHub Community discussion #109905.
|
|
44
|
+
fix: |
|
|
45
|
+
For cross-workflow artifact sharing:
|
|
46
|
+
1. Capture the producing workflow's run-id dynamically using the GitHub REST
|
|
47
|
+
API or by passing it as a workflow_dispatch input or repository_dispatch payload.
|
|
48
|
+
2. Verify the upload step ran successfully in the producer workflow before
|
|
49
|
+
downloading in a consumer workflow.
|
|
50
|
+
3. Ensure `name:` matches exactly (case-sensitive) between upload and download.
|
|
51
|
+
4. For same-workflow jobs, omit `run-id:` — download-artifact v4 defaults to
|
|
52
|
+
the current run automatically.
|
|
53
|
+
fix_code:
|
|
54
|
+
- language: yaml
|
|
55
|
+
label: "WRONG — hard-coded run-id that may be stale"
|
|
56
|
+
code: |
|
|
57
|
+
- uses: actions/download-artifact@v4
|
|
58
|
+
with:
|
|
59
|
+
name: build-output
|
|
60
|
+
run-id: 12345678 # ❌ hard-coded run ID — stale if re-run or wrong workflow
|
|
61
|
+
- language: yaml
|
|
62
|
+
label: "RIGHT — same-workflow, no run-id needed"
|
|
63
|
+
code: |
|
|
64
|
+
# Job A (producer)
|
|
65
|
+
jobs:
|
|
66
|
+
build:
|
|
67
|
+
runs-on: ubuntu-latest
|
|
68
|
+
steps:
|
|
69
|
+
- run: make build
|
|
70
|
+
- uses: actions/upload-artifact@v4
|
|
71
|
+
with:
|
|
72
|
+
name: build-output # ✅ exact name matters
|
|
73
|
+
path: dist/
|
|
74
|
+
|
|
75
|
+
test:
|
|
76
|
+
needs: build
|
|
77
|
+
runs-on: ubuntu-latest
|
|
78
|
+
steps:
|
|
79
|
+
- uses: actions/download-artifact@v4
|
|
80
|
+
with:
|
|
81
|
+
name: build-output # ✅ same name, no run-id needed for current run
|
|
82
|
+
- language: yaml
|
|
83
|
+
label: "RIGHT — cross-workflow download, run-id from API"
|
|
84
|
+
code: |
|
|
85
|
+
- name: Get latest successful run ID
|
|
86
|
+
id: get-run
|
|
87
|
+
env:
|
|
88
|
+
GH_TOKEN: ${{ github.token }}
|
|
89
|
+
run: |
|
|
90
|
+
RUN_ID=$(gh run list \
|
|
91
|
+
--workflow=build.yml \
|
|
92
|
+
--branch=main \
|
|
93
|
+
--status=success \
|
|
94
|
+
--limit=1 \
|
|
95
|
+
--json databaseId \
|
|
96
|
+
--jq '.[0].databaseId')
|
|
97
|
+
echo "run_id=$RUN_ID" >> $GITHUB_OUTPUT
|
|
98
|
+
|
|
99
|
+
- uses: actions/download-artifact@v4
|
|
100
|
+
with:
|
|
101
|
+
name: build-output
|
|
102
|
+
run-id: ${{ steps.get-run.outputs.run_id }} # ✅ dynamic run ID
|
|
103
|
+
github-token: ${{ github.token }}
|
|
104
|
+
prevention:
|
|
105
|
+
- "Never hard-code run-id values — always fetch them dynamically via the GitHub API or pass them as workflow inputs."
|
|
106
|
+
- "Always verify artifact upload completed successfully before writing a consuming workflow that depends on it."
|
|
107
|
+
- "Use exact case-matching artifact names — `build-output` and `Build-Output` are different artifacts."
|
|
108
|
+
- "For same-workflow artifact sharing between jobs, omit `run-id:` entirely — it defaults to the current run."
|
|
109
|
+
- "Check artifact retention settings — artifacts expire after 90 days (public) or 400 days (private) by default."
|
|
110
|
+
docs:
|
|
111
|
+
- url: "https://docs.github.com/en/actions/writing-workflows/choosing-what-your-workflow-does/storing-and-sharing-data-from-a-workflow"
|
|
112
|
+
label: "Storing and sharing data from a workflow"
|
|
113
|
+
- url: "https://github.com/actions/download-artifact"
|
|
114
|
+
label: "actions/download-artifact — README and cross-run download docs"
|
|
115
|
+
- url: "https://github.com/orgs/community/discussions/109905"
|
|
116
|
+
label: "GitHub Community #109905 — Unable to find any artifacts troubleshooting"
|
|
117
|
+
- url: "https://stackoverflow.com/questions/78238187/unable-to-find-any-artifacts-for-the-associated-workflow-github-actions"
|
|
118
|
+
label: "Stack Overflow — Unable to find any artifacts for the associated workflow"
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
id: known-unsolved-007
|
|
2
|
+
title: "Workflow Rerun Limit: 50 Reruns Maximum Per Workflow Run"
|
|
3
|
+
category: known-unsolved
|
|
4
|
+
severity: limitation
|
|
5
|
+
tags:
|
|
6
|
+
- rerun
|
|
7
|
+
- retry
|
|
8
|
+
- automation
|
|
9
|
+
- limits
|
|
10
|
+
- check-suite
|
|
11
|
+
patterns:
|
|
12
|
+
- regex: "exceeded.*maximum.*rerun.*limit"
|
|
13
|
+
flags: "i"
|
|
14
|
+
- regex: "rerun limit.*50"
|
|
15
|
+
flags: "i"
|
|
16
|
+
- regex: "This workflow has been rerun too many times"
|
|
17
|
+
flags: "i"
|
|
18
|
+
- regex: "maximum rerun limit.*exceeded"
|
|
19
|
+
flags: "i"
|
|
20
|
+
error_messages:
|
|
21
|
+
- "This workflow has exceeded the maximum rerun limit of 50."
|
|
22
|
+
- "You have exceeded the maximum rerun limit for this workflow run."
|
|
23
|
+
- "Failed check suite: exceeded maximum rerun limit."
|
|
24
|
+
root_cause: |
|
|
25
|
+
In April 2026 GitHub introduced a hard cap of 50 reruns per workflow run (combining
|
|
26
|
+
full re-runs and partial job re-runs). When the limit is hit, any subsequent rerun
|
|
27
|
+
attempt results in a failed check suite with an annotation — no partial or full rerun
|
|
28
|
+
is permitted on that run ever again.
|
|
29
|
+
|
|
30
|
+
The limit was introduced because some automation scripts were issuing hundreds of retry
|
|
31
|
+
attempts on a single workflow run, adding significant load to GitHub's infrastructure.
|
|
32
|
+
|
|
33
|
+
Common triggers of this limit:
|
|
34
|
+
- Automated retry bots (e.g. flaky-test detection scripts) that loop on `gh run rerun`
|
|
35
|
+
- CI platforms that aggressively requeue failed runs
|
|
36
|
+
- Scheduled maintenance pipelines that retry indefinitely on runner-level transient failures
|
|
37
|
+
- GitHub Apps polling and re-triggering stale check suites on long-lived PRs
|
|
38
|
+
fix: |
|
|
39
|
+
There is no way to raise the 50-rerun cap — it is a hard platform limit with no bypass.
|
|
40
|
+
|
|
41
|
+
Recommended approaches:
|
|
42
|
+
1. **Fix the root cause instead of retrying** — identify and address flaky tests, network
|
|
43
|
+
timeouts, or runner instability rather than masking them with reruns.
|
|
44
|
+
2. **Create a new workflow run instead of rerunning** — close and reopen the PR, push a
|
|
45
|
+
no-op commit, or trigger `workflow_dispatch` to start a fresh run with its own 50-run
|
|
46
|
+
budget.
|
|
47
|
+
3. **Implement retry logic inside the step** — use a step-level retry loop (`for i in 1 2 3`)
|
|
48
|
+
rather than whole-workflow reruns so flakiness is contained within a single run.
|
|
49
|
+
4. **Limit automation rerun budgets** — if you operate a retry bot, add a counter check
|
|
50
|
+
(`gh run view --json runAttempt`) and stop retrying once `runAttempt >= 40` to leave
|
|
51
|
+
headroom before the limit hits.
|
|
52
|
+
fix_code:
|
|
53
|
+
- language: yaml
|
|
54
|
+
label: "Step-level retry instead of whole-workflow rerun"
|
|
55
|
+
code: |
|
|
56
|
+
steps:
|
|
57
|
+
- name: Run flaky integration test (with built-in retry)
|
|
58
|
+
shell: bash
|
|
59
|
+
run: |
|
|
60
|
+
for attempt in 1 2 3; do
|
|
61
|
+
echo "Attempt $attempt of 3"
|
|
62
|
+
if npm run test:integration; then
|
|
63
|
+
echo "Tests passed on attempt $attempt"
|
|
64
|
+
exit 0
|
|
65
|
+
fi
|
|
66
|
+
echo "Attempt $attempt failed, retrying..."
|
|
67
|
+
sleep 10
|
|
68
|
+
done
|
|
69
|
+
echo "All 3 attempts failed"
|
|
70
|
+
exit 1
|
|
71
|
+
- language: yaml
|
|
72
|
+
label: "Check rerun count before auto-retrying in a workflow automation"
|
|
73
|
+
code: |
|
|
74
|
+
steps:
|
|
75
|
+
- name: Guard against rerun limit
|
|
76
|
+
shell: bash
|
|
77
|
+
run: |
|
|
78
|
+
RUN_ATTEMPT="${{ github.run_attempt }}"
|
|
79
|
+
if [ "$RUN_ATTEMPT" -ge 40 ]; then
|
|
80
|
+
echo "::error::Run attempt $RUN_ATTEMPT is near the 50-rerun limit. Stopping auto-retry."
|
|
81
|
+
exit 1
|
|
82
|
+
fi
|
|
83
|
+
echo "Run attempt $RUN_ATTEMPT — within safe retry budget"
|
|
84
|
+
- language: yaml
|
|
85
|
+
label: "Trigger a fresh run instead of rerunning (workflow_dispatch)"
|
|
86
|
+
code: |
|
|
87
|
+
# Instead of gh run rerun <run-id>, dispatch a fresh run:
|
|
88
|
+
# gh workflow run my-workflow.yml --ref main
|
|
89
|
+
# This creates a new run ID with its own 50-rerun budget.
|
|
90
|
+
prevention:
|
|
91
|
+
- "Build retry logic inside steps using shell loops rather than whole-workflow reruns."
|
|
92
|
+
- "Monitor `github.run_attempt` context value; alert or stop automation at 40+ attempts."
|
|
93
|
+
- "Fix flaky tests rather than relying on reruns as the primary reliability mechanism."
|
|
94
|
+
- "If a run regularly hits >10 reruns, treat it as a reliability incident, not a normal CI pattern."
|
|
95
|
+
docs:
|
|
96
|
+
- url: "https://github.blog/changelog/2026-04-10-actions-workflows-are-limited-to-50-reruns/"
|
|
97
|
+
label: "GitHub Changelog: Actions workflows are limited to 50 reruns"
|
|
98
|
+
- url: "https://docs.github.com/en/actions/managing-workflow-runs-and-deployments/managing-workflow-runs/re-running-workflows-and-jobs"
|
|
99
|
+
label: "Re-running workflows and jobs"
|
|
100
|
+
- url: "https://docs.github.com/en/actions/writing-workflows/choosing-what-your-workflow-does/workflow-commands-for-github-actions"
|
|
101
|
+
label: "Workflow commands for GitHub Actions"
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
id: permissions-auth-008
|
|
2
|
+
title: "GCP OIDC Workload Identity: Pool Path vs Provider Path / Project ID vs Number"
|
|
3
|
+
category: permissions-auth
|
|
4
|
+
severity: error
|
|
5
|
+
tags:
|
|
6
|
+
- oidc
|
|
7
|
+
- gcp
|
|
8
|
+
- google-cloud
|
|
9
|
+
- workload-identity
|
|
10
|
+
- auth
|
|
11
|
+
patterns:
|
|
12
|
+
- regex: "Invalid value for [\"']?audience[\"']?"
|
|
13
|
+
flags: "i"
|
|
14
|
+
- regex: "Error code invalid_request.*Invalid value for.*audience"
|
|
15
|
+
flags: "i"
|
|
16
|
+
- regex: "workloadIdentityPools.*not.*providers"
|
|
17
|
+
flags: "i"
|
|
18
|
+
- regex: "project.*number.*not.*project.*id"
|
|
19
|
+
flags: "i"
|
|
20
|
+
- regex: "OAuthError.*Invalid value for.*audience"
|
|
21
|
+
flags: "i"
|
|
22
|
+
- regex: "Error parsing credentials.*workload_identity_provider"
|
|
23
|
+
flags: "i"
|
|
24
|
+
error_messages:
|
|
25
|
+
- "ERROR: gcloud crashed (OAuthError): Error code invalid_request: Invalid value for \"audience\"."
|
|
26
|
+
- "Error: google-github-actions/auth failed with: Error code invalid_request: Invalid value for \"audience\"."
|
|
27
|
+
- "The workload_identity_provider must be the full provider resource name, not the pool resource name."
|
|
28
|
+
root_cause: |
|
|
29
|
+
`google-github-actions/auth` OIDC authentication fails with "Invalid value for audience"
|
|
30
|
+
when either of two common misconfiguration patterns is present:
|
|
31
|
+
|
|
32
|
+
**Mistake 1 — Pool path instead of Provider path**
|
|
33
|
+
The `workload_identity_provider` input requires the full *Provider* resource name:
|
|
34
|
+
`projects/PROJECT_NUMBER/locations/global/workloadIdentityPools/POOL_ID/providers/PROVIDER_ID`
|
|
35
|
+
|
|
36
|
+
Many developers mistakenly supply only the *Pool* path (omitting `/providers/PROVIDER_ID`):
|
|
37
|
+
`projects/PROJECT_NUMBER/locations/global/workloadIdentityPools/POOL_ID`
|
|
38
|
+
|
|
39
|
+
GCP's STS token endpoint rejects the audience because it expects the provider URI, not the pool URI.
|
|
40
|
+
|
|
41
|
+
**Mistake 2 — Project ID (string) instead of Project Number (integer)**
|
|
42
|
+
The path requires the numeric GCP project number (e.g. `123456789012`), NOT the human-readable
|
|
43
|
+
project ID (e.g. `my-gcp-project`). Workload Identity Federation does not accept project IDs.
|
|
44
|
+
Using a project ID causes the STS endpoint to return "Invalid value for audience" because the
|
|
45
|
+
resource path does not resolve to a valid identity provider.
|
|
46
|
+
|
|
47
|
+
**Mistake 3 — Missing `id-token: write` permission**
|
|
48
|
+
If `permissions.id-token` is not explicitly set to `write` at the job or workflow level,
|
|
49
|
+
GitHub will not mint an OIDC token and the auth step fails with a permissions error rather
|
|
50
|
+
than a token exchange error.
|
|
51
|
+
fix: |
|
|
52
|
+
Verify the `workload_identity_provider` value against the exact format required:
|
|
53
|
+
`projects/PROJECT_NUMBER/locations/global/workloadIdentityPools/POOL/providers/PROVIDER`
|
|
54
|
+
|
|
55
|
+
Retrieve the correct value:
|
|
56
|
+
gcloud iam workload-identity-pools providers describe PROVIDER_ID \
|
|
57
|
+
--project=PROJECT_ID \
|
|
58
|
+
--location=global \
|
|
59
|
+
--workload-identity-pool=POOL_ID \
|
|
60
|
+
--format='value(name)'
|
|
61
|
+
|
|
62
|
+
Ensure `id-token: write` is set in the job permissions block.
|
|
63
|
+
|
|
64
|
+
Wait at least 5 minutes after changes to Workload Identity Pool / Provider / IAM bindings
|
|
65
|
+
before testing — these resources are eventually consistent.
|
|
66
|
+
fix_code:
|
|
67
|
+
- language: yaml
|
|
68
|
+
label: "Correct workload_identity_provider format (provider path + project number)"
|
|
69
|
+
code: |
|
|
70
|
+
jobs:
|
|
71
|
+
deploy:
|
|
72
|
+
runs-on: ubuntu-latest
|
|
73
|
+
permissions:
|
|
74
|
+
id-token: write # REQUIRED — grants GitHub the right to mint an OIDC token
|
|
75
|
+
contents: read
|
|
76
|
+
|
|
77
|
+
steps:
|
|
78
|
+
- uses: actions/checkout@v4
|
|
79
|
+
|
|
80
|
+
- id: auth
|
|
81
|
+
uses: google-github-actions/auth@v2
|
|
82
|
+
with:
|
|
83
|
+
# CORRECT: full provider path with numeric project number
|
|
84
|
+
workload_identity_provider: >-
|
|
85
|
+
projects/123456789012/locations/global/workloadIdentityPools/my-pool/providers/my-provider
|
|
86
|
+
service_account: my-service-account@my-project.iam.gserviceaccount.com
|
|
87
|
+
- language: yaml
|
|
88
|
+
label: "Common mistake — pool path (missing /providers/...) causes audience error"
|
|
89
|
+
code: |
|
|
90
|
+
# WRONG: pool path only — gcloud crashes with "Invalid value for audience"
|
|
91
|
+
# workload_identity_provider: >-
|
|
92
|
+
# projects/123456789012/locations/global/workloadIdentityPools/my-pool
|
|
93
|
+
|
|
94
|
+
# ALSO WRONG: project ID string instead of project number
|
|
95
|
+
# workload_identity_provider: >-
|
|
96
|
+
# projects/my-gcp-project/locations/global/workloadIdentityPools/my-pool/providers/my-provider
|
|
97
|
+
|
|
98
|
+
# CORRECT:
|
|
99
|
+
# workload_identity_provider: >-
|
|
100
|
+
# projects/123456789012/locations/global/workloadIdentityPools/my-pool/providers/my-provider
|
|
101
|
+
- language: yaml
|
|
102
|
+
label: "Store provider path in a repository variable to avoid typos"
|
|
103
|
+
code: |
|
|
104
|
+
jobs:
|
|
105
|
+
deploy:
|
|
106
|
+
runs-on: ubuntu-latest
|
|
107
|
+
permissions:
|
|
108
|
+
id-token: write
|
|
109
|
+
contents: read
|
|
110
|
+
steps:
|
|
111
|
+
- uses: google-github-actions/auth@v2
|
|
112
|
+
with:
|
|
113
|
+
# Store full provider path as a repository variable to avoid typos
|
|
114
|
+
workload_identity_provider: ${{ vars.GCP_WIF_PROVIDER }}
|
|
115
|
+
service_account: ${{ vars.GCP_SERVICE_ACCOUNT }}
|
|
116
|
+
prevention:
|
|
117
|
+
- "Always use `gcloud iam workload-identity-pools providers describe` to copy the exact provider path."
|
|
118
|
+
- "Store the full provider path in a GitHub Actions variable (`vars.GCP_WIF_PROVIDER`) to prevent manual typos."
|
|
119
|
+
- "Use numeric project number — retrieve it with `gcloud projects describe PROJECT_ID --format='value(projectNumber)'`."
|
|
120
|
+
- "After changing Workload Identity Pool config, wait 5 minutes before testing (eventual consistency)."
|
|
121
|
+
- "Confirm `id-token: write` permission is present at job (not just workflow) level."
|
|
122
|
+
docs:
|
|
123
|
+
- url: "https://github.com/google-github-actions/auth#setup"
|
|
124
|
+
label: "google-github-actions/auth: Setup and configuration"
|
|
125
|
+
- url: "https://github.com/google-github-actions/auth/blob/main/docs/TROUBLESHOOTING.md"
|
|
126
|
+
label: "google-github-actions/auth: Troubleshooting guide"
|
|
127
|
+
- url: "https://docs.github.com/en/actions/security-for-github-actions/security-hardening-your-deployments/configuring-openid-connect-in-google-cloud-platform"
|
|
128
|
+
label: "Configuring OIDC in Google Cloud Platform"
|
|
129
|
+
- url: "https://cloud.google.com/iam/docs/workload-identity-federation-with-deployment-pipelines"
|
|
130
|
+
label: "GCP: Workload Identity Federation with deployment pipelines"
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
id: runner-environment-018
|
|
2
|
+
title: "macOS 14 Sonoma Runner Deprecation — EOL November 2026"
|
|
3
|
+
category: runner-environment
|
|
4
|
+
severity: warning
|
|
5
|
+
tags:
|
|
6
|
+
- macos
|
|
7
|
+
- deprecation
|
|
8
|
+
- runner-image
|
|
9
|
+
- eol
|
|
10
|
+
- migration
|
|
11
|
+
patterns:
|
|
12
|
+
- regex: "##\\[error\\]This request was rejected because.*macos-14"
|
|
13
|
+
flags: "i"
|
|
14
|
+
- regex: "Image.*macos-14.*deprecated|macos-14.*no longer supported"
|
|
15
|
+
flags: "i"
|
|
16
|
+
- regex: "The requested image.*macos-14.*not available"
|
|
17
|
+
flags: "i"
|
|
18
|
+
error_messages:
|
|
19
|
+
- "##[error]This request was rejected because the runner label 'macos-14' is no longer supported."
|
|
20
|
+
- "The macOS 14 image has been retired. Please update to macos-15 or macos-latest."
|
|
21
|
+
root_cause: |
|
|
22
|
+
GitHub announced the deprecation of `macOS 14 Sonoma` runner images on the following schedule:
|
|
23
|
+
- **Deprecation begins**: July 6, 2026 — longer queue times during peak hours, brownout periods
|
|
24
|
+
- **Full retirement**: November 2, 2026 — jobs using `macos-14` will fail permanently
|
|
25
|
+
|
|
26
|
+
GitHub maintains only the latest two stable macOS major versions. Since macOS 26 Tahoe is now
|
|
27
|
+
GA on GitHub Actions, macOS 14 is the oldest and must retire.
|
|
28
|
+
|
|
29
|
+
**Brownout schedule** (jobs deliberately failed during these windows to force migration):
|
|
30
|
+
- October 5, 14:00 UTC – October 6, 00:00 UTC
|
|
31
|
+
- October 12, 14:00 UTC – October 13, 00:00 UTC
|
|
32
|
+
- October 16–30, 14:00 UTC – next day 00:00 UTC (escalating weekly)
|
|
33
|
+
|
|
34
|
+
Affected labels: `macos-14`, `macos-14-large`, `macos-14-xlarge`.
|
|
35
|
+
fix: |
|
|
36
|
+
Update your workflow's `runs-on` label to a supported macOS version:
|
|
37
|
+
|
|
38
|
+
| Old label | Replace with |
|
|
39
|
+
|-----------|--------------|
|
|
40
|
+
| `macos-14` | `macos-latest` or `macos-15` or `macos-26` |
|
|
41
|
+
| `macos-14-large` | `macos-latest-large` or `macos-15-large` |
|
|
42
|
+
| `macos-14-xlarge` | `macos-latest-xlarge` or `macos-15-xlarge` or `macos-26-xlarge` |
|
|
43
|
+
|
|
44
|
+
If your workflow depends on macOS 14-specific software versions (e.g., Xcode 15, older
|
|
45
|
+
Python/Ruby), test carefully against macOS 15 before switching `macos-latest`.
|
|
46
|
+
See runner-environment-017 for macOS 15 → 26 migration notes if moving to `macos-latest`.
|
|
47
|
+
fix_code:
|
|
48
|
+
- language: yaml
|
|
49
|
+
label: "Migrate from macos-14 to macos-15 (conservative) or macos-latest"
|
|
50
|
+
code: |
|
|
51
|
+
jobs:
|
|
52
|
+
build:
|
|
53
|
+
# Before:
|
|
54
|
+
# runs-on: macos-14
|
|
55
|
+
|
|
56
|
+
# Conservative: macos-15 (similar software stack, no OpenSSL jump)
|
|
57
|
+
runs-on: macos-15
|
|
58
|
+
|
|
59
|
+
# OR accept latest (currently macos-26 after June 15 2026):
|
|
60
|
+
# runs-on: macos-latest
|
|
61
|
+
|
|
62
|
+
steps:
|
|
63
|
+
- uses: actions/checkout@v4
|
|
64
|
+
- language: yaml
|
|
65
|
+
label: "Strategy matrix: test across multiple macOS versions during migration"
|
|
66
|
+
code: |
|
|
67
|
+
jobs:
|
|
68
|
+
build:
|
|
69
|
+
strategy:
|
|
70
|
+
matrix:
|
|
71
|
+
os: [macos-15, macos-26]
|
|
72
|
+
runs-on: ${{ matrix.os }}
|
|
73
|
+
steps:
|
|
74
|
+
- uses: actions/checkout@v4
|
|
75
|
+
- name: Build and test
|
|
76
|
+
run: make test
|
|
77
|
+
prevention:
|
|
78
|
+
- "Subscribe to actions/runner-images GitHub Issues announcements label to receive deprecation notices well in advance."
|
|
79
|
+
- "Avoid pinning to specific macOS point versions (`macos-14`, `macos-15`) in long-lived workflows — use `macos-latest` and test proactively against the next version."
|
|
80
|
+
- "Run a matrix strategy against `macos-latest` and your pinned version to detect incompatibilities before they cause production failures."
|
|
81
|
+
- "Search your organization's workflows periodically for deprecated runner labels using: `gh search code 'runs-on: macos-14' --owner YOUR_ORG`."
|
|
82
|
+
docs:
|
|
83
|
+
- url: "https://github.com/actions/runner-images/issues/13518"
|
|
84
|
+
label: "GitHub Announcement: macOS 14 Sonoma deprecation timeline"
|
|
85
|
+
- url: "https://docs.github.com/en/actions/using-github-hosted-runners/using-github-hosted-runners/about-github-hosted-runners#supported-runners-and-hardware-resources"
|
|
86
|
+
label: "Supported GitHub-hosted runner labels"
|
|
87
|
+
source:
|
|
88
|
+
article: "https://htek.dev/articles/github-actions-debugging-guide"
|
|
89
|
+
section: "Runner deprecation and EOL"
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
id: runner-environment-017
|
|
2
|
+
title: "macos-latest Label Now Points to macOS 26 Tahoe"
|
|
3
|
+
category: runner-environment
|
|
4
|
+
severity: error
|
|
5
|
+
tags:
|
|
6
|
+
- macos
|
|
7
|
+
- runner-image
|
|
8
|
+
- breaking-change
|
|
9
|
+
- openssl
|
|
10
|
+
- xcode
|
|
11
|
+
- migration
|
|
12
|
+
patterns:
|
|
13
|
+
- regex: "Error opening configuration file.*openssl"
|
|
14
|
+
flags: "i"
|
|
15
|
+
- regex: "SSL_CTX_new.*failed|SSL_connect.*SYSCALL error"
|
|
16
|
+
flags: "i"
|
|
17
|
+
- regex: "Could not find Xcode.*version.*16\\.\\d"
|
|
18
|
+
flags: "i"
|
|
19
|
+
- regex: "ruby.*requires.*Ruby (2|3\\.0|3\\.1|3\\.2|3\\.3)"
|
|
20
|
+
flags: "i"
|
|
21
|
+
- regex: "dyld.*Library not loaded.*libssl\\.1\\.1"
|
|
22
|
+
flags: "i"
|
|
23
|
+
error_messages:
|
|
24
|
+
- "dyld[]: Library not loaded: /usr/local/opt/openssl@1.1/lib/libssl.1.1.dylib"
|
|
25
|
+
- "Could not find Xcode version '16.4'"
|
|
26
|
+
- "SSL_connect returned=1 errno=0 state=error: certificate verify failed"
|
|
27
|
+
- "Your Ruby version is 3.3.x, but your Gemfile specified ~> 3.3"
|
|
28
|
+
- "npm warn old lockfile"
|
|
29
|
+
root_cause: |
|
|
30
|
+
The `macos-latest` label in GitHub Actions was migrated to point to macOS 26 Tahoe
|
|
31
|
+
beginning June 15, 2026 (completing by July 15, 2026). Previously it pointed to macOS 15
|
|
32
|
+
Sequoia. This migration includes several major software version changes that silently break
|
|
33
|
+
workflows:
|
|
34
|
+
|
|
35
|
+
- **OpenSSL**: 1.1.1w → 3.6.2 — The biggest breaking change. Many C/C++ projects,
|
|
36
|
+
Ruby gems (openssl), and Python packages that link against the system OpenSSL dynamically
|
|
37
|
+
will fail at runtime because libssl.1.1.dylib no longer ships with macOS 26.
|
|
38
|
+
- **Xcode**: Default changes from 16.4 to 26.4.1 (Xcode 26 series). Workflows pinning
|
|
39
|
+
`xcode-version: '16.4'` or relying on Clang 17 will break — Clang/LLVM jumps from 17 → 21.
|
|
40
|
+
- **Ruby**: 3.3.x → 3.4.x — Minor version bump can cause Gemfile constraint failures and
|
|
41
|
+
gem native extension compilation issues.
|
|
42
|
+
- **Node.js**: Default moves from 22 → 24 (though both images include Node 24 in cached tools).
|
|
43
|
+
- **npm**: 10.x → 11.x — Major npm version. Package-lock.json format changes possible.
|
|
44
|
+
- **Homebrew LLVM**: 18 → 20 (major version jump for workflows using `llvm@18` explicitly).
|
|
45
|
+
fix: |
|
|
46
|
+
**Immediate mitigation:** Pin to `macos-15` to restore previous behavior while you migrate:
|
|
47
|
+
|
|
48
|
+
```yaml
|
|
49
|
+
runs-on: macos-15
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
**Proper fix** — address each breaking dependency:
|
|
53
|
+
|
|
54
|
+
1. **OpenSSL**: Brew-install a pinned OpenSSL version and set library paths:
|
|
55
|
+
```bash
|
|
56
|
+
brew install openssl@1.1
|
|
57
|
+
export LDFLAGS="-L$(brew --prefix openssl@1.1)/lib"
|
|
58
|
+
export CPPFLAGS="-I$(brew --prefix openssl@1.1)/include"
|
|
59
|
+
```
|
|
60
|
+
Or migrate to OpenSSL 3.x compatible code.
|
|
61
|
+
|
|
62
|
+
2. **Xcode**: Pin the Xcode version explicitly using `maxim-lobanov/setup-xcode`:
|
|
63
|
+
```yaml
|
|
64
|
+
- uses: maxim-lobanov/setup-xcode@v1
|
|
65
|
+
with:
|
|
66
|
+
xcode-version: '16.4'
|
|
67
|
+
```
|
|
68
|
+
Or migrate your project to Xcode 26.
|
|
69
|
+
|
|
70
|
+
3. **Ruby**: Update your Gemfile to accept 3.4.x (`~> 3.4`) or use `ruby/setup-ruby` to
|
|
71
|
+
pin a specific version:
|
|
72
|
+
```yaml
|
|
73
|
+
- uses: ruby/setup-ruby@v1
|
|
74
|
+
with:
|
|
75
|
+
ruby-version: '3.3'
|
|
76
|
+
```
|
|
77
|
+
fix_code:
|
|
78
|
+
- language: yaml
|
|
79
|
+
label: "Pin to macos-15 for immediate rollback"
|
|
80
|
+
code: |
|
|
81
|
+
jobs:
|
|
82
|
+
build:
|
|
83
|
+
runs-on: macos-15 # pinned until macos-26 migration complete
|
|
84
|
+
steps:
|
|
85
|
+
- uses: actions/checkout@v4
|
|
86
|
+
- language: yaml
|
|
87
|
+
label: "Full macos-26 compatible workflow — pin Xcode, Ruby, and OpenSSL"
|
|
88
|
+
code: |
|
|
89
|
+
jobs:
|
|
90
|
+
build:
|
|
91
|
+
runs-on: macos-latest # now macos-26
|
|
92
|
+
steps:
|
|
93
|
+
- uses: actions/checkout@v4
|
|
94
|
+
|
|
95
|
+
# Pin Xcode version explicitly
|
|
96
|
+
- uses: maxim-lobanov/setup-xcode@v1
|
|
97
|
+
with:
|
|
98
|
+
xcode-version: '26.4'
|
|
99
|
+
|
|
100
|
+
# Pin Ruby if needed
|
|
101
|
+
- uses: ruby/setup-ruby@v1
|
|
102
|
+
with:
|
|
103
|
+
ruby-version: '3.3'
|
|
104
|
+
bundler-cache: true
|
|
105
|
+
|
|
106
|
+
# If OpenSSL 1.1 is needed, install and export paths
|
|
107
|
+
- name: Install OpenSSL 1.1
|
|
108
|
+
run: |
|
|
109
|
+
brew install openssl@1.1
|
|
110
|
+
echo "LDFLAGS=-L$(brew --prefix openssl@1.1)/lib" >> $GITHUB_ENV
|
|
111
|
+
echo "CPPFLAGS=-I$(brew --prefix openssl@1.1)/include" >> $GITHUB_ENV
|
|
112
|
+
prevention:
|
|
113
|
+
- "Avoid relying on `macos-latest` for builds that depend on specific system library versions (OpenSSL, LLVM). Pin to a concrete label like `macos-15`."
|
|
114
|
+
- "Subscribe to the actions/runner-images repository announcements to get advance notice of `macos-latest` label migrations."
|
|
115
|
+
- "Use `ruby/setup-ruby`, `actions/setup-node`, and `actions/setup-python` to pin language runtimes instead of relying on runner image defaults."
|
|
116
|
+
- "Test your macOS workflows against the new image early by substituting `macos-26` before the `macos-latest` migration completes."
|
|
117
|
+
- "Audit all dylib/framework dependencies — anything linking to libssl.1.1 must be migrated to OpenSSL 3.x or brew-pinned."
|
|
118
|
+
docs:
|
|
119
|
+
- url: "https://github.com/actions/runner-images/issues/14167"
|
|
120
|
+
label: "GitHub Announcement: macos-latest will use macos-26 in June 2026"
|
|
121
|
+
- url: "https://github.com/actions/runner-images/blob/main/images/macos/macos-26-arm64-Readme.md"
|
|
122
|
+
label: "macOS 26 arm64 image README — full software list"
|
|
123
|
+
- url: "https://docs.github.com/en/actions/using-github-hosted-runners/using-github-hosted-runners/about-github-hosted-runners"
|
|
124
|
+
label: "About GitHub-hosted runners — supported runner labels"
|
|
125
|
+
source:
|
|
126
|
+
article: "https://htek.dev/articles/github-actions-debugging-guide"
|
|
127
|
+
section: "Runner image migrations"
|