@htekdev/actions-debugger 1.0.114 → 1.0.116
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/concurrency-timing/concurrency-timing-053.yml +83 -0
- package/errors/known-unsolved/known-unsolved-062.yml +87 -0
- package/errors/known-unsolved/runner-rest-api-busy-false-broker-state-desync.yml +102 -0
- package/errors/permissions-auth/upload-code-coverage-missing-code-quality-write-permission.yml +94 -0
- package/errors/runner-environment/arc-ephemeral-runner-oom-kill-session-conflict.yml +129 -0
- package/errors/runner-environment/macos-26-homebrew-python313-removed-stdlib-modules.yml +113 -0
- package/errors/runner-environment/macos-26-openssl3-legacy-cipher-p12-import-failure.yml +102 -0
- package/errors/runner-environment/runner-environment-199.yml +93 -0
- package/errors/runner-environment/runner-v2334-action-download-repeated-case-sensitivity.yml +100 -0
- package/errors/runner-environment/setup-python-macos-self-hosted-symlink-permission-denied.yml +94 -0
- package/errors/runner-environment/setup-python-windows-self-hosted-no-admin-install-fails.yml +101 -0
- package/errors/silent-failures/paths-filter-before-field-missing-workflow-run.yml +105 -0
- package/errors/silent-failures/windows-11-arm-bash-shell-intermittent-zero-output.yml +99 -0
- package/errors/triggers/triggers-069.yml +100 -0
- package/errors/yaml-syntax/continue-on-error-inputs-composite-action-unexpected-value.yml +110 -0
- package/package.json +1 -1
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
id: runner-environment-200
|
|
2
|
+
title: 'macOS 26 OpenSSL 3.x rejects legacy RC2 ciphers — p12 certificate import fails with inner_evp_generic_fetch unsupported'
|
|
3
|
+
category: runner-environment
|
|
4
|
+
severity: error
|
|
5
|
+
tags:
|
|
6
|
+
- macos
|
|
7
|
+
- macos-26
|
|
8
|
+
- openssl
|
|
9
|
+
- code-signing
|
|
10
|
+
- certificate
|
|
11
|
+
- ios
|
|
12
|
+
- legacy-cipher
|
|
13
|
+
patterns:
|
|
14
|
+
- regex: 'inner_evp_generic_fetch:unsupported'
|
|
15
|
+
flags: 'i'
|
|
16
|
+
- regex: 'Algorithm \(RC2-\d+-CBC.*\)'
|
|
17
|
+
flags: 'i'
|
|
18
|
+
- regex: 'Could not find certificate from.*stdin|Could not parse.*certificate'
|
|
19
|
+
flags: 'i'
|
|
20
|
+
- regex: 'openssl.*failed with return code:\s*1'
|
|
21
|
+
flags: 'i'
|
|
22
|
+
error_messages:
|
|
23
|
+
- '40CBBC50F87F0000:error:0308010C:digital envelope routines:inner_evp_generic_fetch:unsupported:crypto/evp/evp_fetch.c:355:Global default library context, Algorithm (RC2-40-CBC : 0), Properties ()'
|
|
24
|
+
- 'Could not find certificate from <stdin>'
|
|
25
|
+
- '##[error]Error: /usr/local/bin/openssl failed with return code: 1'
|
|
26
|
+
- '##[warning]Error parsing certificate. This might be caused by an unsupported algorithm. If you''re using old certificate with a new OpenSSL version try to set -legacy flag in opensslPkcsArgs input.'
|
|
27
|
+
root_cause: |
|
|
28
|
+
macOS 26 runner images ship OpenSSL 3.x (OpenSSL 3.6.x as of runner-images macOS 26
|
|
29
|
+
release notes). OpenSSL 3.x removed RC2-40-CBC, RC2-64-CBC, and RC2-128-CBC from
|
|
30
|
+
the default provider. These legacy ciphers were commonly used to encrypt PKCS#12
|
|
31
|
+
certificate bundles generated by macOS Keychain Access, Fastlane cert, older CI
|
|
32
|
+
pipelines, or Keychain import/export tools shipped before 2020.
|
|
33
|
+
|
|
34
|
+
When a workflow installs a p12 certificate using openssl pkcs12 (directly or via
|
|
35
|
+
apple-actions/import-codesign-certs@v1/v2), OpenSSL 3.x cannot decrypt the legacy
|
|
36
|
+
bundle and emits:
|
|
37
|
+
|
|
38
|
+
error:0308010C:digital envelope routines:inner_evp_generic_fetch:unsupported:
|
|
39
|
+
...Algorithm (RC2-40-CBC : 0), Properties ()
|
|
40
|
+
|
|
41
|
+
followed by "Could not find certificate from <stdin>" and openssl exit code 1.
|
|
42
|
+
|
|
43
|
+
The code-signing step silently skips certificate import, causing downstream
|
|
44
|
+
codesign, xcodebuild archive, or notarytool steps to fail with "no identity found"
|
|
45
|
+
or "identity not in keychain" errors.
|
|
46
|
+
|
|
47
|
+
Workflows that ran successfully on macos-14 (OpenSSL 1.1.x) or macos-15
|
|
48
|
+
(OpenSSL 3.3.x with legacy provider enabled) may start failing when the job
|
|
49
|
+
label is macos-26 or when macos-latest migrates to macOS 26.
|
|
50
|
+
fix: |
|
|
51
|
+
Option 1 (quickest) — Pass opensslPkcsArgs: -legacy to apple-actions/import-codesign-certs:
|
|
52
|
+
The -legacy flag activates OpenSSL's legacy provider which re-enables RC2 and
|
|
53
|
+
other deprecated algorithms. Supported in apple-actions/import-codesign-certs v2+.
|
|
54
|
+
|
|
55
|
+
Option 2 (permanent) — Re-encode the p12 with a modern cipher on your local machine
|
|
56
|
+
before uploading to GitHub Secrets:
|
|
57
|
+
openssl pkcs12 -in legacy.p12 -out certs.pem -nodes -passin pass:OLDPASSWORD
|
|
58
|
+
openssl pkcs12 -export -in certs.pem -out modern.p12 -passout pass:NEWPASSWORD \
|
|
59
|
+
-keypbe aes-256-cbc -certpbe aes-256-cbc -macalg sha256
|
|
60
|
+
base64 -w 0 modern.p12 > modern_b64.txt
|
|
61
|
+
# Upload content of modern_b64.txt as the new GitHub secret value
|
|
62
|
+
|
|
63
|
+
Option 3 — Regenerate certificates with modern tooling:
|
|
64
|
+
Use Fastlane match (>= 3.x) or Xcode 26 certificate export; both default to
|
|
65
|
+
AES-256-CBC which OpenSSL 3.x supports without -legacy.
|
|
66
|
+
fix_code:
|
|
67
|
+
- language: yaml
|
|
68
|
+
label: 'Fix: pass opensslPkcsArgs: -legacy (apple-actions/import-codesign-certs)'
|
|
69
|
+
code: |
|
|
70
|
+
- uses: apple-actions/import-codesign-certs@v3
|
|
71
|
+
with:
|
|
72
|
+
p12-file-base64: ${{ secrets.IOS_DISTRIBUTION_P12 }}
|
|
73
|
+
p12-password: ${{ secrets.IOS_DISTRIBUTION_P12_PASSWORD }}
|
|
74
|
+
opensslPkcsArgs: -legacy # required on macOS 26 / OpenSSL 3.x for RC2-encrypted p12
|
|
75
|
+
- language: yaml
|
|
76
|
+
label: 'Long-term fix: re-encode p12 with AES-256-CBC before updating the secret'
|
|
77
|
+
code: |
|
|
78
|
+
# Run these commands locally (not in CI) to produce a modern p12:
|
|
79
|
+
#
|
|
80
|
+
# openssl pkcs12 -in legacy.p12 -out certs.pem -nodes -passin pass:$OLD_PASS \
|
|
81
|
+
# -legacy # may need -legacy on your local OpenSSL 3.x too
|
|
82
|
+
# openssl pkcs12 -export \
|
|
83
|
+
# -in certs.pem -out modern.p12 \
|
|
84
|
+
# -passout pass:$NEW_PASS \
|
|
85
|
+
# -keypbe aes-256-cbc \
|
|
86
|
+
# -certpbe aes-256-cbc \
|
|
87
|
+
# -macalg sha256
|
|
88
|
+
# base64 -w 0 modern.p12 | pbcopy # paste into GitHub Secrets
|
|
89
|
+
#
|
|
90
|
+
# After updating the secret, remove the opensslPkcsArgs: -legacy workaround.
|
|
91
|
+
prevention:
|
|
92
|
+
- 'Re-encode all p12 certificate bundles with AES-256-CBC before migrating to macos-26'
|
|
93
|
+
- 'Audit p12 cipher with: openssl pkcs12 -in cert.p12 -info -noout -passin pass:X 2>&1 | grep -i cipher'
|
|
94
|
+
- 'Pin macos-15 temporarily as a fallback while re-encoding certificates'
|
|
95
|
+
- 'Test certificate import on macos-26 runners before macos-latest label migration completes'
|
|
96
|
+
docs:
|
|
97
|
+
- url: 'https://github.com/actions/runner-images/issues/10934'
|
|
98
|
+
label: 'GitHub runner-images #10934: Intermittent SSL issue loading iOS certificates on macOS 26'
|
|
99
|
+
- url: 'https://www.openssl.org/docs/man3.0/man7/OSSL_PROVIDER-legacy.html'
|
|
100
|
+
label: 'OpenSSL 3.x legacy provider documentation'
|
|
101
|
+
- url: 'https://github.com/apple-actions/import-codesign-certs'
|
|
102
|
+
label: 'apple-actions/import-codesign-certs: opensslPkcsArgs input'
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
id: runner-environment-199
|
|
2
|
+
title: 'Windows self-hosted runner V2 broker listener stops polling after first job (2.334.0)'
|
|
3
|
+
category: runner-environment
|
|
4
|
+
severity: error
|
|
5
|
+
tags:
|
|
6
|
+
- self-hosted
|
|
7
|
+
- windows
|
|
8
|
+
- runner-v2
|
|
9
|
+
- broker
|
|
10
|
+
- listener
|
|
11
|
+
- stuck
|
|
12
|
+
- message-queue
|
|
13
|
+
- v2-flow
|
|
14
|
+
patterns:
|
|
15
|
+
- regex: 'Get messages has been cancelled using local token source\. Continue to get messages with new status'
|
|
16
|
+
flags: 'i'
|
|
17
|
+
- regex: 'BrokerMessageListener.*cancel|cancel.*BrokerMessageListener'
|
|
18
|
+
flags: 'i'
|
|
19
|
+
error_messages:
|
|
20
|
+
- 'Get messages has been cancelled using local token source. Continue to get messages with new status.'
|
|
21
|
+
root_cause: |
|
|
22
|
+
On Windows self-hosted runners running v2.334.0 with the V2 broker flow enabled
|
|
23
|
+
(`useV2Flow: true`, connecting to `broker.actions.githubusercontent.com`), the
|
|
24
|
+
`BrokerMessageListener` stops issuing GET /message requests after the first job
|
|
25
|
+
completes and the runner transitions from Busy→Online (idle).
|
|
26
|
+
|
|
27
|
+
The root cause is a race condition in the V2 state machine reset path: when the
|
|
28
|
+
Busy→Online transition fires, the existing `localTokenSource` for the polling loop
|
|
29
|
+
is cancelled (logging "Get messages has been cancelled using local token source.
|
|
30
|
+
Continue to get messages with new status."), but the replacement polling loop fails
|
|
31
|
+
to start due to a missing null-check or async continuation bug on Windows. OAuth
|
|
32
|
+
token refreshes continue normally (masking the hang — credentials are not the issue),
|
|
33
|
+
but no new GET /message requests are dispatched.
|
|
34
|
+
|
|
35
|
+
The runner UI shows the runner as "Idle" indefinitely. Any jobs queued after the
|
|
36
|
+
first run sit in "Queued" status and never start until the runner service is manually
|
|
37
|
+
restarted. The issue is specific to Windows (the identical code path on Linux/macOS
|
|
38
|
+
appears unaffected) and requires a service start + exactly one job completion to
|
|
39
|
+
trigger. Reproduced reliably across multiple self-hosted Windows environments.
|
|
40
|
+
|
|
41
|
+
Reported against runner v2.334.0, commit f1995ede5d885c997d13d8eca5467c4ce97fe69c.
|
|
42
|
+
No fix available as of June 2026. Open at actions/runner#4444.
|
|
43
|
+
fix: |
|
|
44
|
+
Immediate workaround: restart the runner service after each job, or add an automated
|
|
45
|
+
watchdog that monitors the runner diagnostics log for the stale-listener pattern and
|
|
46
|
+
triggers a service restart.
|
|
47
|
+
|
|
48
|
+
Longer-term: downgrade to runner v2.333.x until actions/runner#4444 is resolved.
|
|
49
|
+
Check the runner release notes for a fix targeting the V2 BrokerMessageListener
|
|
50
|
+
state-reset path.
|
|
51
|
+
fix_code:
|
|
52
|
+
- language: yaml
|
|
53
|
+
label: 'PowerShell watchdog snippet to restart runner service on listener hang (add to a monitoring script)'
|
|
54
|
+
code: |
|
|
55
|
+
# Watchdog: detect stale BrokerMessageListener and restart runner service
|
|
56
|
+
# Run this as a scheduled task every 5 minutes on the runner host
|
|
57
|
+
|
|
58
|
+
$diagDir = "C:\actions-runner\_diag"
|
|
59
|
+
$logFile = Get-ChildItem $diagDir -Filter "Runner_*.log" | Sort-Object LastWriteTime -Descending | Select-Object -First 1
|
|
60
|
+
$lastMsg = (Get-Content $logFile.FullName -Tail 200 | Select-String "BrokerMessageListener") | Select-Object -Last 1
|
|
61
|
+
|
|
62
|
+
# If the last BrokerMessageListener log entry is the cancellation message
|
|
63
|
+
# and it's more than 10 minutes old, restart the service
|
|
64
|
+
if ($lastMsg -match "cancelled using local token source") {
|
|
65
|
+
$entryTime = [datetime]::Parse(($lastMsg -split " ")[0])
|
|
66
|
+
if ((Get-Date) - $entryTime -gt [TimeSpan]::FromMinutes(10)) {
|
|
67
|
+
Restart-Service actions.runner.*
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
- language: yaml
|
|
71
|
+
label: 'Pin runner version to 2.333.x in ARC or self-hosted runner config'
|
|
72
|
+
code: |
|
|
73
|
+
# For ARC (Actions Runner Controller) — pin runner version in values.yaml
|
|
74
|
+
githubConfigSecret: pre-defined-secret
|
|
75
|
+
template:
|
|
76
|
+
spec:
|
|
77
|
+
containers:
|
|
78
|
+
- name: runner
|
|
79
|
+
env:
|
|
80
|
+
- name: RUNNER_VERSION
|
|
81
|
+
value: "2.333.0" # Pin below 2.334.0 until #4444 is fixed
|
|
82
|
+
prevention:
|
|
83
|
+
- "Subscribe to the actions/runner release feed to catch regression fixes; downgrade immediately when a V2-flow listener regression is reported."
|
|
84
|
+
- "For Windows runner pools, add a service watchdog (Task Scheduler or Prometheus alert) that detects listener staleness via the _diag/Runner_*.log pattern."
|
|
85
|
+
- "Consider switching to ephemeral JIT runners on Windows — ephemeral runners cannot hit this bug because each runner handles exactly one job then exits."
|
|
86
|
+
- "Monitor runner queue depth in your autoscaler; an idle runner with > 0 queued jobs is a reliable signal the listener has stalled."
|
|
87
|
+
docs:
|
|
88
|
+
- url: 'https://github.com/actions/runner/issues/4444'
|
|
89
|
+
label: 'actions/runner#4444 — Listener stops polling broker after first job (2.334.0, Windows, V2 flow)'
|
|
90
|
+
- url: 'https://docs.github.com/en/actions/hosting-your-own-runners/managing-self-hosted-runners/about-self-hosted-runners'
|
|
91
|
+
label: 'About self-hosted runners'
|
|
92
|
+
- url: 'https://github.com/actions/runner/releases'
|
|
93
|
+
label: 'Actions Runner release notes'
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
id: runner-environment-202
|
|
2
|
+
title: 'Runner v2.334.0 "Download action repository" repeats for same action when references use different letter casing'
|
|
3
|
+
category: runner-environment
|
|
4
|
+
severity: warning
|
|
5
|
+
tags:
|
|
6
|
+
- runner
|
|
7
|
+
- action-resolution
|
|
8
|
+
- performance
|
|
9
|
+
- v2.334
|
|
10
|
+
- composite-actions
|
|
11
|
+
- case-sensitivity
|
|
12
|
+
patterns:
|
|
13
|
+
- regex: 'Download action repository.*already been downloaded'
|
|
14
|
+
flags: 'i'
|
|
15
|
+
- regex: 'Download action repository.*\d+\.\d+s.*Download action repository'
|
|
16
|
+
flags: 'i'
|
|
17
|
+
- regex: 'Resolving action.*batching.*dedup.*failed|action.*resolution.*duplicate.*case'
|
|
18
|
+
flags: 'i'
|
|
19
|
+
error_messages:
|
|
20
|
+
- 'Download action repository ''actions/checkout@v4'' (SHA:abc123...) 18.35s'
|
|
21
|
+
- 'Download action repository ''Actions/Checkout@v4'' (SHA:abc123...) 19.12s'
|
|
22
|
+
- 'Download action repository ''ACTIONS/CHECKOUT@v4'' (SHA:abc123...) 17.88s'
|
|
23
|
+
root_cause: |
|
|
24
|
+
Runner v2.334.0 introduced "batch and deduplicate action resolution across composite
|
|
25
|
+
depths" to speed up jobs with many actions. The deduplication logic uses a
|
|
26
|
+
case-sensitive equality check on the action reference string (owner/repo@ref). When
|
|
27
|
+
the same action is referenced with different capitalizations — for example,
|
|
28
|
+
actions/checkout@v4 in one workflow step and Actions/Checkout@v4 inside a composite
|
|
29
|
+
action — the deduplication logic treats them as distinct actions and downloads both.
|
|
30
|
+
|
|
31
|
+
This regression is tracked in actions/runner#3731. Each duplicate download takes
|
|
32
|
+
15-20 seconds, which multiplies across all case-variant references in a job. In
|
|
33
|
+
workflows with many composite actions or large action dependency trees, this can add
|
|
34
|
+
several minutes of silent overhead.
|
|
35
|
+
|
|
36
|
+
The issue does not cause a build failure — the downloads resolve to the same SHA
|
|
37
|
+
and the action runs once. The cost is purely in duplicate network traffic, API
|
|
38
|
+
calls, and elapsed time. Repeated downloads also count against GitHub API rate
|
|
39
|
+
limits for private runners or GHES installations.
|
|
40
|
+
|
|
41
|
+
Most commonly observed when:
|
|
42
|
+
- Composite actions use uppercase or title-case owners in their uses: fields
|
|
43
|
+
- Third-party actions internally call actions/core or actions/toolcache with
|
|
44
|
+
inconsistent casing
|
|
45
|
+
- Workflows mix community-contributed composite actions with differing conventions
|
|
46
|
+
fix: |
|
|
47
|
+
Canonicalize all action references to lowercase owner/repo throughout your
|
|
48
|
+
workflow files and composite action.yml files. GitHub API lookups are
|
|
49
|
+
case-insensitive, so actions/checkout and Actions/Checkout resolve identically,
|
|
50
|
+
but the v2.334.0 deduplication cache is case-sensitive.
|
|
51
|
+
|
|
52
|
+
After fixing, run the job again to confirm "Download action repository" appears
|
|
53
|
+
only once per unique action in the logs.
|
|
54
|
+
|
|
55
|
+
A fix for the runner-side deduplication (case-insensitive cache key) is tracked
|
|
56
|
+
in actions/runner#3731 and may be included in a future runner release.
|
|
57
|
+
fix_code:
|
|
58
|
+
- language: yaml
|
|
59
|
+
label: 'Bug: mixed-case action references cause repeated downloads'
|
|
60
|
+
code: |
|
|
61
|
+
# workflow.yml — uses lowercase
|
|
62
|
+
steps:
|
|
63
|
+
- uses: actions/checkout@v4
|
|
64
|
+
|
|
65
|
+
# internal/composite/action.yml — uses title-case (different casing)
|
|
66
|
+
runs:
|
|
67
|
+
using: composite
|
|
68
|
+
steps:
|
|
69
|
+
- uses: Actions/Checkout@v4 # triggers a second download in v2.334.0
|
|
70
|
+
- language: yaml
|
|
71
|
+
label: 'Fix: canonicalize to lowercase owner/repo in all workflow and composite action files'
|
|
72
|
+
code: |
|
|
73
|
+
# workflow.yml
|
|
74
|
+
steps:
|
|
75
|
+
- uses: actions/checkout@v4 # lowercase
|
|
76
|
+
|
|
77
|
+
# internal/composite/action.yml
|
|
78
|
+
runs:
|
|
79
|
+
using: composite
|
|
80
|
+
steps:
|
|
81
|
+
- uses: actions/checkout@v4 # lowercase matches — deduplicated correctly
|
|
82
|
+
- language: yaml
|
|
83
|
+
label: 'Diagnostic: detect duplicate downloads by searching job logs'
|
|
84
|
+
code: |
|
|
85
|
+
# In the Actions UI, open the job log and search for "Download action repository"
|
|
86
|
+
# If the same action appears more than once (even with different casing), you
|
|
87
|
+
# have duplicate downloads.
|
|
88
|
+
#
|
|
89
|
+
# CLI equivalent (with gh):
|
|
90
|
+
# gh run view <run-id> --log | grep "Download action repository" | sort | uniq -c
|
|
91
|
+
prevention:
|
|
92
|
+
- 'Use consistent lowercase owner/repo for all action references across workflow files and composite actions'
|
|
93
|
+
- 'Add an actionlint check to CI; it flags inconsistent action reference casing'
|
|
94
|
+
- 'Audit composite action.yml files for uppercase uses: references, as they are the most common source'
|
|
95
|
+
- 'Pin runner version to v2.333.0 as a temporary workaround while waiting for runner#3731 fix'
|
|
96
|
+
docs:
|
|
97
|
+
- url: 'https://github.com/actions/runner/issues/3731'
|
|
98
|
+
label: 'GitHub runner#3731: Download action repository called repeatedly for same action (case-sensitivity)'
|
|
99
|
+
- url: 'https://github.com/actions/runner/releases/tag/v2.334.0'
|
|
100
|
+
label: 'Runner v2.334.0 release notes: batch and deduplicate action resolution'
|
package/errors/runner-environment/setup-python-macos-self-hosted-symlink-permission-denied.yml
ADDED
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
id: runner-environment-198
|
|
2
|
+
title: 'setup-python fails on macOS self-hosted runner with "ln: python3XX: Permission denied" — symlink created without sudo after sudo install'
|
|
3
|
+
category: runner-environment
|
|
4
|
+
severity: error
|
|
5
|
+
tags:
|
|
6
|
+
- setup-python
|
|
7
|
+
- self-hosted
|
|
8
|
+
- macos
|
|
9
|
+
- symlink
|
|
10
|
+
- permissions
|
|
11
|
+
- sudo
|
|
12
|
+
patterns:
|
|
13
|
+
- regex: 'ln:.*python3\d+.*Permission denied'
|
|
14
|
+
flags: 'i'
|
|
15
|
+
- regex: 'Error:.*ln:.*python.*Permission denied'
|
|
16
|
+
flags: 'i'
|
|
17
|
+
error_messages:
|
|
18
|
+
- 'Error: ln: python314: Permission denied'
|
|
19
|
+
- 'Error: ln: python312: Permission denied'
|
|
20
|
+
- 'Error: ln: python313: Permission denied'
|
|
21
|
+
root_cause: |
|
|
22
|
+
The setup-python macOS installer script (setup.sh) uses sudo to install the Python
|
|
23
|
+
framework into /Library/Frameworks/ — a root-owned directory. However, the
|
|
24
|
+
subsequent step that creates symlinks inside that directory (e.g., linking
|
|
25
|
+
python3.14 → python3) runs WITHOUT sudo, causing a permission error when the
|
|
26
|
+
runner''s CI user is a standard (non-root) account even if sudo is available for
|
|
27
|
+
the install step.
|
|
28
|
+
|
|
29
|
+
The error appears as:
|
|
30
|
+
Error: ln: python314: Permission denied
|
|
31
|
+
|
|
32
|
+
This affects macOS self-hosted runners (EC2, bare-metal, VM) where the runner
|
|
33
|
+
service is configured as a non-admin user. GitHub-hosted macOS runners are
|
|
34
|
+
unaffected because they grant passwordless sudo to the runner user.
|
|
35
|
+
|
|
36
|
+
A fix was proposed in actions/python-versions PR #384 to use sudo for the symlink
|
|
37
|
+
creation step as well, but is not yet merged/released as of mid-2026.
|
|
38
|
+
fix: |
|
|
39
|
+
Short-term workaround: Grant the runner service user passwordless sudo on the
|
|
40
|
+
macOS runner machine, or run the runner as a user with write access to
|
|
41
|
+
/Library/Frameworks/ and /usr/local/bin.
|
|
42
|
+
|
|
43
|
+
Safer workaround: Pre-install Python on the macOS runner machine using the
|
|
44
|
+
official Python.org pkg installer (which creates symlinks correctly as root), then
|
|
45
|
+
rely on setup-python''s PATH-detection to use the pre-installed version without
|
|
46
|
+
invoking the installer.
|
|
47
|
+
|
|
48
|
+
Enterprise workaround: Use a custom RUNNER_TOOL_CACHE path that is owned by the
|
|
49
|
+
runner user and set python-version to a version already cached there, bypassing
|
|
50
|
+
the framework installer entirely.
|
|
51
|
+
fix_code:
|
|
52
|
+
- language: yaml
|
|
53
|
+
label: 'Workaround: use pre-installed Python to avoid the installer'
|
|
54
|
+
code: |
|
|
55
|
+
jobs:
|
|
56
|
+
build:
|
|
57
|
+
runs-on: [self-hosted, macos]
|
|
58
|
+
steps:
|
|
59
|
+
# If Python 3.14 is pre-installed system-wide (via pkg installer as root),
|
|
60
|
+
# setup-python finds it in PATH without invoking setup.sh
|
|
61
|
+
- uses: actions/setup-python@v5
|
|
62
|
+
with:
|
|
63
|
+
python-version: '3.14'
|
|
64
|
+
- run: python3 --version
|
|
65
|
+
- language: yaml
|
|
66
|
+
label: 'Workaround: grant passwordless sudo to runner user via /etc/sudoers (NOT recommended for production)'
|
|
67
|
+
code: |
|
|
68
|
+
# Add to /etc/sudoers on the macOS runner machine (use visudo):
|
|
69
|
+
# runner-user ALL=(ALL) NOPASSWD: ALL
|
|
70
|
+
#
|
|
71
|
+
# This allows setup-python's installer to use sudo for both the framework
|
|
72
|
+
# install and symlink creation steps.
|
|
73
|
+
#
|
|
74
|
+
# In your workflow, no changes are needed — setup-python works normally once
|
|
75
|
+
# the runner user has the required sudo permissions.
|
|
76
|
+
jobs:
|
|
77
|
+
build:
|
|
78
|
+
runs-on: [self-hosted, macos]
|
|
79
|
+
steps:
|
|
80
|
+
- uses: actions/setup-python@v5
|
|
81
|
+
with:
|
|
82
|
+
python-version: '3.14'
|
|
83
|
+
prevention:
|
|
84
|
+
- 'Use pre-installed Python on macOS self-hosted runners to avoid the setup.sh installer and its sudo/symlink requirements'
|
|
85
|
+
- 'When provisioning macOS self-hosted runners, ensure the runner user has passwordless sudo or pre-install all required Python versions'
|
|
86
|
+
- 'Track actions/python-versions#384 for an upstream fix that adds sudo to the symlink creation step'
|
|
87
|
+
- 'Test setup-python on macOS self-hosted runners in a staging environment before deploying to production'
|
|
88
|
+
docs:
|
|
89
|
+
- url: 'https://github.com/actions/setup-python/issues/1301'
|
|
90
|
+
label: 'actions/setup-python#1301: Permission denied when creating symlinks on macOS self-hosted runners (2026)'
|
|
91
|
+
- url: 'https://github.com/actions/python-versions/pull/384'
|
|
92
|
+
label: 'actions/python-versions PR #384: fix symlink creation to use sudo (pending)'
|
|
93
|
+
- url: 'https://docs.github.com/en/actions/hosting-your-own-runners/managing-self-hosted-runners/about-self-hosted-runners#self-hosted-runner-security'
|
|
94
|
+
label: 'GitHub Docs: Self-hosted runner security'
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
id: runner-environment-197
|
|
2
|
+
title: 'setup-python fails on Windows self-hosted runner without administrator permissions — InstallAllUsers=1 MSI installer requires admin'
|
|
3
|
+
category: runner-environment
|
|
4
|
+
severity: error
|
|
5
|
+
tags:
|
|
6
|
+
- setup-python
|
|
7
|
+
- self-hosted
|
|
8
|
+
- windows
|
|
9
|
+
- admin-permissions
|
|
10
|
+
- msi-installer
|
|
11
|
+
patterns:
|
|
12
|
+
- regex: 'Error happened during Python installation'
|
|
13
|
+
flags: 'i'
|
|
14
|
+
- regex: 'InstallAllUsers=1'
|
|
15
|
+
flags: 'i'
|
|
16
|
+
- regex: 'setup-python.*self.hosted.*windows.*fail'
|
|
17
|
+
flags: 'i'
|
|
18
|
+
error_messages:
|
|
19
|
+
- 'Error happened during Python installation'
|
|
20
|
+
root_cause: |
|
|
21
|
+
The setup-python action installs Python using the official MSI installer with the
|
|
22
|
+
flag InstallAllUsers=1. This flag installs Python into the shared runner tool cache
|
|
23
|
+
(RUNNER_TOOL_CACHE) using the DefaultAllUsersTargetDir argument, which requires
|
|
24
|
+
administrator privileges to write to the shared system-level installation path.
|
|
25
|
+
|
|
26
|
+
When the GitHub Actions runner service is running under a standard user account
|
|
27
|
+
without local administrator permissions, the Python MSI installer fails because it
|
|
28
|
+
cannot write to the required system paths, resulting in:
|
|
29
|
+
|
|
30
|
+
Error happened during Python installation
|
|
31
|
+
|
|
32
|
+
This affects Windows self-hosted runners configured as a Windows service under a
|
|
33
|
+
non-admin account. GitHub-hosted Windows runners are unaffected because they run
|
|
34
|
+
as SYSTEM (full admin). Linux and macOS self-hosted runners are unaffected.
|
|
35
|
+
|
|
36
|
+
Note: this is by design per the action maintainers — InstallAllUsers=1 is required
|
|
37
|
+
to correctly populate the shared RUNNER_TOOL_CACHE. A per-user install mode
|
|
38
|
+
(InstallAllUsers=0) is under consideration as a future enhancement.
|
|
39
|
+
fix: |
|
|
40
|
+
Primary fix: Configure the Windows runner service to run as a local administrator
|
|
41
|
+
account. In Windows Services (services.msc), change the "Log On" account for the
|
|
42
|
+
GitHub Actions Runner service to an account with local admin rights, or install the
|
|
43
|
+
runner using the .\config.cmd --runasservice flow with an admin account.
|
|
44
|
+
|
|
45
|
+
Workaround 1: Pre-install the required Python version system-wide on the runner
|
|
46
|
+
machine before workflows run. setup-python will use the pre-installed version from
|
|
47
|
+
PATH without invoking the MSI installer if the version matches.
|
|
48
|
+
|
|
49
|
+
Workaround 2: Ensure the runner is run interactively (not as a service) under an
|
|
50
|
+
account with admin rights during initial Python installation, then cache the tool.
|
|
51
|
+
|
|
52
|
+
Workaround 3: Use actions/setup-python''s uses: together with a self-hosted runner
|
|
53
|
+
image that already has Python pre-installed in RUNNER_TOOL_CACHE, bypassing the
|
|
54
|
+
MSI install step entirely.
|
|
55
|
+
fix_code:
|
|
56
|
+
- language: yaml
|
|
57
|
+
label: 'Workflow: no changes needed — fix is on the runner machine configuration'
|
|
58
|
+
code: |
|
|
59
|
+
# Fix requires reconfiguring the Windows runner service account:
|
|
60
|
+
# 1. Open Services (services.msc) on the runner machine
|
|
61
|
+
# 2. Find "GitHub Actions Runner (<name>)"
|
|
62
|
+
# 3. Right-click → Properties → Log On tab
|
|
63
|
+
# 4. Change to an account with local administrator privileges
|
|
64
|
+
# 5. Restart the service
|
|
65
|
+
#
|
|
66
|
+
# After reconfiguring, setup-python works normally:
|
|
67
|
+
jobs:
|
|
68
|
+
build:
|
|
69
|
+
runs-on: [self-hosted, windows]
|
|
70
|
+
steps:
|
|
71
|
+
- uses: actions/setup-python@v5
|
|
72
|
+
with:
|
|
73
|
+
python-version: '3.12'
|
|
74
|
+
- run: python --version
|
|
75
|
+
- language: yaml
|
|
76
|
+
label: 'Workaround: use pre-installed Python from PATH if runner has it installed system-wide'
|
|
77
|
+
code: |
|
|
78
|
+
jobs:
|
|
79
|
+
build:
|
|
80
|
+
runs-on: [self-hosted, windows]
|
|
81
|
+
steps:
|
|
82
|
+
# Skip setup-python entirely if Python is pre-installed system-wide
|
|
83
|
+
- name: Verify Python available
|
|
84
|
+
run: python --version
|
|
85
|
+
# OR use setup-python only to add to PATH, not install:
|
|
86
|
+
- uses: actions/setup-python@v5
|
|
87
|
+
with:
|
|
88
|
+
python-version: '3.12'
|
|
89
|
+
# If Python 3.12 is already in RUNNER_TOOL_CACHE, no install occurs
|
|
90
|
+
prevention:
|
|
91
|
+
- 'Always run Windows self-hosted runner services under a local administrator account — setup-python requires admin rights to install into the shared tool cache'
|
|
92
|
+
- 'Test setup-python on self-hosted runners with the same service account before deploying to production workloads'
|
|
93
|
+
- 'Use pre-installed Python on Windows self-hosted runners to avoid the MSI installer entirely when admin rights cannot be granted'
|
|
94
|
+
- 'Document the runner service account requirements in your team''s self-hosted runner setup guide'
|
|
95
|
+
docs:
|
|
96
|
+
- url: 'https://github.com/actions/setup-python/issues/1308'
|
|
97
|
+
label: 'actions/setup-python#1308: fails on self-hosted runners without admin permissions (2026)'
|
|
98
|
+
- url: 'https://github.com/actions/setup-python/blob/main/docs/advanced-usage.md#windows'
|
|
99
|
+
label: 'setup-python docs: Windows advanced usage and self-hosted runner configuration'
|
|
100
|
+
- url: 'https://docs.github.com/en/actions/hosting-your-own-runners/managing-self-hosted-runners/configuring-the-self-hosted-runner-application-as-a-service'
|
|
101
|
+
label: 'GitHub Docs: Configuring the self-hosted runner as a service'
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
id: silent-failures-107
|
|
2
|
+
title: "dorny/paths-filter Reports All Files Changed When 'before' Field Missing on workflow_run"
|
|
3
|
+
category: silent-failures
|
|
4
|
+
severity: silent-failure
|
|
5
|
+
tags:
|
|
6
|
+
- paths-filter
|
|
7
|
+
- workflow_run
|
|
8
|
+
- before-field
|
|
9
|
+
- silent-failure
|
|
10
|
+
- fork-pr
|
|
11
|
+
- changed-files
|
|
12
|
+
- wrong-output
|
|
13
|
+
patterns:
|
|
14
|
+
- regex: '''before'' field is missing in event payload'
|
|
15
|
+
flags: 'i'
|
|
16
|
+
- regex: 'changes will be detected from last commit'
|
|
17
|
+
flags: 'i'
|
|
18
|
+
- regex: 'paths-filter.*workflow.run'
|
|
19
|
+
flags: 'i'
|
|
20
|
+
error_messages:
|
|
21
|
+
- "Warning: 'before' field is missing in event payload - changes will be detected from last commit"
|
|
22
|
+
root_cause: |
|
|
23
|
+
`dorny/paths-filter` (v3 and earlier) contains an internal code path that requires a
|
|
24
|
+
`before` SHA field from the GitHub event payload to compute the diff base. When used in
|
|
25
|
+
a `workflow_run`-triggered workflow, the event payload does not contain a `before` field
|
|
26
|
+
(it only has `head_sha`, `head_branch`, etc.) — so the action falls into a fallback path
|
|
27
|
+
that calls `getChangesInLastCommit()` instead of performing a proper merge-base diff.
|
|
28
|
+
|
|
29
|
+
The result: **every file in the repository is reported as "changed"**, defeating any
|
|
30
|
+
attempt to use paths-filter as a change detection gate in `workflow_run` workflows.
|
|
31
|
+
|
|
32
|
+
Root cause in source code (paths-filter v3):
|
|
33
|
+
The action's `getChangedFilesFromGit()` logic normalizes both `base` and `head` to short
|
|
34
|
+
branch names. On `workflow_run`, `github.context.ref` resolves to the same ref as the
|
|
35
|
+
user-supplied `base:` (e.g. both become "main"). The `isBaseSameAsHead` check triggers
|
|
36
|
+
the fallback: if `base === head` AND `beforeSha` is null, the action emits the warning
|
|
37
|
+
and returns only the last commit's changes — which in a merge-queue or PR workflow is
|
|
38
|
+
completely wrong.
|
|
39
|
+
|
|
40
|
+
The same bug occurs when:
|
|
41
|
+
- Using paths-filter in a `workflow_run` workflow without explicitly passing `ref:` as a SHA.
|
|
42
|
+
- Running from a forked PR where the `before` field is absent from the push payload.
|
|
43
|
+
- Any workflow_run where `github.context.ref` resolves to the same branch name as the
|
|
44
|
+
`base:` input after short-name normalization.
|
|
45
|
+
fix: |
|
|
46
|
+
Pass `ref:` explicitly as the HEAD SHA of the triggering workflow run. Using a full SHA
|
|
47
|
+
prevents the `isBaseSameAsHead` short-circuit because a SHA never equals a branch name
|
|
48
|
+
after normalization:
|
|
49
|
+
|
|
50
|
+
- uses: dorny/paths-filter@v3
|
|
51
|
+
with:
|
|
52
|
+
base: 'main'
|
|
53
|
+
ref: ${{ github.event.workflow_run.head_sha }}
|
|
54
|
+
filters: |
|
|
55
|
+
backend:
|
|
56
|
+
- 'src/**'
|
|
57
|
+
|
|
58
|
+
Also ensure the prior `actions/checkout` step uses `fetch-depth: 0` so the action has
|
|
59
|
+
both `base` and `ref` locally available for `getChangesSinceMergeBase`.
|
|
60
|
+
|
|
61
|
+
For fork PRs: use `ref: ${{ github.event.workflow_run.head_sha }}` and
|
|
62
|
+
`base: ${{ github.event.workflow_run.base_branch }}`.
|
|
63
|
+
|
|
64
|
+
Alternative: upgrade to dorny/paths-filter v4.0.1+ which adds native `merge_group`
|
|
65
|
+
support and has improved ref handling (check release notes for workflow_run fixes).
|
|
66
|
+
fix_code:
|
|
67
|
+
- language: yaml
|
|
68
|
+
label: 'Pass ref as SHA to avoid isBaseSameAsHead false-positive on workflow_run'
|
|
69
|
+
code: |
|
|
70
|
+
on:
|
|
71
|
+
workflow_run:
|
|
72
|
+
workflows: ["CI"]
|
|
73
|
+
types: [completed]
|
|
74
|
+
|
|
75
|
+
jobs:
|
|
76
|
+
check-changes:
|
|
77
|
+
runs-on: ubuntu-latest
|
|
78
|
+
outputs:
|
|
79
|
+
backend: ${{ steps.filter.outputs.backend }}
|
|
80
|
+
steps:
|
|
81
|
+
- uses: actions/checkout@v4
|
|
82
|
+
with:
|
|
83
|
+
ref: ${{ github.event.workflow_run.head_sha }}
|
|
84
|
+
fetch-depth: 0
|
|
85
|
+
|
|
86
|
+
- uses: dorny/paths-filter@v3
|
|
87
|
+
id: filter
|
|
88
|
+
with:
|
|
89
|
+
base: ${{ github.event.workflow_run.base_branch }}
|
|
90
|
+
# REQUIRED: pass ref as SHA, not branch name
|
|
91
|
+
# Without this, base == head after normalization → all files reported as changed
|
|
92
|
+
ref: ${{ github.event.workflow_run.head_sha }}
|
|
93
|
+
filters: |
|
|
94
|
+
backend:
|
|
95
|
+
- 'src/**'
|
|
96
|
+
prevention:
|
|
97
|
+
- 'Always pass ref: ${{ github.event.workflow_run.head_sha }} when using paths-filter in workflow_run contexts.'
|
|
98
|
+
- 'Never rely on implicit ref resolution in workflow_run workflows — the context.ref is the default branch, not the PR head.'
|
|
99
|
+
- 'After fixing, add a smoke-test PR that changes only an unmonitored path and verify paths-filter returns false for the guarded path.'
|
|
100
|
+
- 'Consider tj-actions/changed-files as an alternative; check its workflow_run documentation before switching.'
|
|
101
|
+
docs:
|
|
102
|
+
- url: 'https://github.com/dorny/paths-filter/issues/261'
|
|
103
|
+
label: "Bug: 'before' field is missing when it should not even be used (11 reactions, open)"
|
|
104
|
+
- url: 'https://github.com/dorny/paths-filter'
|
|
105
|
+
label: 'dorny/paths-filter — conditionally run actions based on modified files'
|