@htekdev/actions-debugger 1.0.71 → 1.0.73
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/runner-environment/arm64-runner-binary-exec-format-error.yml +100 -0
- package/errors/runner-environment/ubuntu-24-no-swap-oom-exit-137.yml +124 -0
- package/errors/runner-environment/ubuntu-24-openjdk11-no-installation-candidate.yml +99 -0
- package/errors/runner-environment/windows-2025-dotnet6-sdk-removed.yml +96 -0
- package/errors/silent-failures/github-ref-name-pr-merge-ref-not-branch.yml +102 -0
- package/errors/silent-failures/reusable-workflow-caller-env-not-forwarded.yml +93 -0
- package/errors/triggers/issue-comment-pr-review-thread-not-triggered.yml +105 -0
- package/errors/yaml-syntax/branches-and-branches-ignore-combined-same-event.yml +99 -0
- package/package.json +1 -1
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
id: runner-environment-133
|
|
2
|
+
title: 'ARM64 runners: downloaded x86_64 binary fails with "Exec format error" — wrong architecture'
|
|
3
|
+
category: runner-environment
|
|
4
|
+
severity: error
|
|
5
|
+
tags:
|
|
6
|
+
- arm64
|
|
7
|
+
- aarch64
|
|
8
|
+
- binary
|
|
9
|
+
- exec-format-error
|
|
10
|
+
- ubuntu-arm
|
|
11
|
+
- architecture
|
|
12
|
+
patterns:
|
|
13
|
+
- regex: 'cannot execute binary file: Exec format error'
|
|
14
|
+
flags: 'i'
|
|
15
|
+
- regex: 'Exec format error'
|
|
16
|
+
flags: 'i'
|
|
17
|
+
- regex: 'exec.*format error'
|
|
18
|
+
flags: 'i'
|
|
19
|
+
error_messages:
|
|
20
|
+
- './my-tool: cannot execute binary file: Exec format error'
|
|
21
|
+
- '/usr/local/bin/kubectl: cannot execute binary file: Exec format error'
|
|
22
|
+
- 'bash: ./tool: cannot execute binary file: Exec format error'
|
|
23
|
+
root_cause: |
|
|
24
|
+
GitHub-hosted ubuntu-24.04-arm and ubuntu-22.04-arm runners use ARM64 (aarch64) CPUs.
|
|
25
|
+
The RUNNER_ARCH environment variable returns ARM64 on these runners, not X64.
|
|
26
|
+
|
|
27
|
+
Workflows that download pre-built binaries using hardcoded architecture suffixes like
|
|
28
|
+
linux-amd64, linux-x86_64, or linux-x64 download x86_64 binaries that cannot execute on
|
|
29
|
+
ARM64 hardware. The Linux kernel rejects the binary with "Exec format error" (ENOEXEC)
|
|
30
|
+
because the ELF architecture header in the binary does not match the host CPU.
|
|
31
|
+
|
|
32
|
+
Common patterns that break:
|
|
33
|
+
- Hardcoded URL: https://example.com/tool-linux-amd64.tar.gz
|
|
34
|
+
- Shell variable set once: ARCH="amd64" without checking RUNNER_ARCH
|
|
35
|
+
- Workflow matrix that includes ubuntu-24.04-arm without updating download URLs
|
|
36
|
+
- Third-party scripts that assume x86_64 without ARM64 support
|
|
37
|
+
|
|
38
|
+
This is a silent-ish failure — the binary downloads successfully (HTTP 200), extracts
|
|
39
|
+
without error, but fails only when executed.
|
|
40
|
+
fix: |
|
|
41
|
+
Use the RUNNER_ARCH environment variable or uname -m to detect architecture and select
|
|
42
|
+
the correct binary:
|
|
43
|
+
|
|
44
|
+
- RUNNER_ARCH is X64 on x86_64 runners, ARM64 on ARM64 runners
|
|
45
|
+
- uname -m returns x86_64 on x86_64, aarch64 on ARM64
|
|
46
|
+
|
|
47
|
+
Normalize to the convention used by the tool's release naming (amd64/arm64 or x86_64/aarch64).
|
|
48
|
+
Where possible, prefer using setup-* actions that handle multi-architecture automatically.
|
|
49
|
+
fix_code:
|
|
50
|
+
- language: yaml
|
|
51
|
+
label: 'Detect architecture and download correct binary'
|
|
52
|
+
code: |
|
|
53
|
+
jobs:
|
|
54
|
+
install-tool:
|
|
55
|
+
runs-on: ${{ matrix.runner }}
|
|
56
|
+
strategy:
|
|
57
|
+
matrix:
|
|
58
|
+
runner: [ubuntu-24.04, ubuntu-24.04-arm]
|
|
59
|
+
steps:
|
|
60
|
+
- name: Detect architecture and download tool
|
|
61
|
+
run: |
|
|
62
|
+
ARCH=$(uname -m)
|
|
63
|
+
case "$ARCH" in
|
|
64
|
+
x86_64) DL_ARCH="amd64" ;;
|
|
65
|
+
aarch64) DL_ARCH="arm64" ;;
|
|
66
|
+
*) echo "Unsupported arch: $ARCH"; exit 1 ;;
|
|
67
|
+
esac
|
|
68
|
+
curl -sSL "https://example.com/tool-linux-${DL_ARCH}.tar.gz" | tar xz
|
|
69
|
+
sudo mv tool /usr/local/bin/
|
|
70
|
+
|
|
71
|
+
- language: yaml
|
|
72
|
+
label: 'Use RUNNER_ARCH environment variable (GitHub-native)'
|
|
73
|
+
code: |
|
|
74
|
+
jobs:
|
|
75
|
+
install-tool:
|
|
76
|
+
runs-on: ubuntu-24.04-arm
|
|
77
|
+
steps:
|
|
78
|
+
- name: Install tool using RUNNER_ARCH
|
|
79
|
+
run: |
|
|
80
|
+
# RUNNER_ARCH is X64 or ARM64 (uppercase)
|
|
81
|
+
if [ "$RUNNER_ARCH" = "ARM64" ]; then
|
|
82
|
+
DL_ARCH="arm64"
|
|
83
|
+
else
|
|
84
|
+
DL_ARCH="amd64"
|
|
85
|
+
fi
|
|
86
|
+
curl -sSL "https://releases.example.com/tool-linux-${DL_ARCH}" -o /usr/local/bin/tool
|
|
87
|
+
chmod +x /usr/local/bin/tool
|
|
88
|
+
prevention:
|
|
89
|
+
- 'Never hardcode linux-amd64 or linux-x86_64 in binary download URLs — always parameterize by architecture'
|
|
90
|
+
- 'Prefer setup-* GitHub Actions (setup-node, setup-go, setup-java) over manual binary downloads — they handle ARM64 automatically'
|
|
91
|
+
- 'Add ubuntu-24.04-arm to your test matrix to catch architecture issues before they affect users'
|
|
92
|
+
- 'Check tool release pages for ARM64 availability before migrating to ARM64 runners — not all tools provide arm64 builds'
|
|
93
|
+
- 'Use RUNNER_ARCH (GitHub variable) or uname -m (portable) to detect architecture in shell scripts'
|
|
94
|
+
docs:
|
|
95
|
+
- url: 'https://docs.github.com/en/actions/using-github-hosted-runners/about-github-hosted-runners/about-github-hosted-runners#supported-runners-and-hardware-resources'
|
|
96
|
+
label: 'GitHub-hosted runners — supported runner types including ARM64'
|
|
97
|
+
- url: 'https://docs.github.com/en/actions/writing-workflows/choosing-what-your-workflow-does/store-information-in-variables#default-environment-variables'
|
|
98
|
+
label: 'Default environment variables — RUNNER_ARCH values'
|
|
99
|
+
- url: 'https://github.com/actions/runner-images/blob/main/images/ubuntu/Ubuntu2404-ARM64-Readme.md'
|
|
100
|
+
label: 'ubuntu-24.04-arm runner software report'
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
id: runner-environment-135
|
|
2
|
+
title: 'ubuntu-24.04: no swap memory — memory-intensive builds killed with exit code 137 (OOM)'
|
|
3
|
+
category: runner-environment
|
|
4
|
+
severity: error
|
|
5
|
+
tags:
|
|
6
|
+
- oom
|
|
7
|
+
- memory
|
|
8
|
+
- swap
|
|
9
|
+
- ubuntu-24
|
|
10
|
+
- exit-137
|
|
11
|
+
- killed
|
|
12
|
+
patterns:
|
|
13
|
+
- regex: 'Error 137'
|
|
14
|
+
flags: 'i'
|
|
15
|
+
- regex: 'exit code 137'
|
|
16
|
+
flags: 'i'
|
|
17
|
+
- regex: '^Killed\s*$'
|
|
18
|
+
flags: 'm'
|
|
19
|
+
- regex: 'out of memory|OOM|oom.killer'
|
|
20
|
+
flags: 'i'
|
|
21
|
+
error_messages:
|
|
22
|
+
- 'make: *** [Makefile:42: build] Error 137'
|
|
23
|
+
- 'Killed'
|
|
24
|
+
- 'Process exited with code 137'
|
|
25
|
+
- 'error Command failed with exit code 137'
|
|
26
|
+
- 'npm ERR! code 137'
|
|
27
|
+
root_cause: |
|
|
28
|
+
GitHub-hosted ubuntu-24.04 runners provide approximately 29GB RAM but have no swap space.
|
|
29
|
+
Ubuntu 22.04 runners provided about 6GB of swap as overflow capacity. When a job exhausts
|
|
30
|
+
physical RAM, the Linux OOM killer terminates the offending process with SIGKILL (signal 9),
|
|
31
|
+
producing exit code 137 (128 + 9).
|
|
32
|
+
|
|
33
|
+
The killed process may be:
|
|
34
|
+
- Node.js during webpack/esbuild/rollup bundle generation for large frontend projects
|
|
35
|
+
- Gradle during Android AAB/APK build or large multi-module Java projects
|
|
36
|
+
- Electron Forge/Builder packaging step
|
|
37
|
+
- C/C++ linker (ld) linking large binaries with many object files
|
|
38
|
+
- Cargo (Rust) compiling with high parallelism or many dependencies
|
|
39
|
+
|
|
40
|
+
The failure is often hard to diagnose because:
|
|
41
|
+
- No explicit "Out of Memory" message appears in the workflow log
|
|
42
|
+
- The step log simply shows "Killed" and exit code 137
|
|
43
|
+
- The runner does not report memory usage in the workflow summary
|
|
44
|
+
|
|
45
|
+
If the same workflow runs on ubuntu-22.04 without issues, missing swap is the likely cause.
|
|
46
|
+
fix: |
|
|
47
|
+
Option A — Add a swap file manually before the memory-intensive step. This adds ~30 seconds
|
|
48
|
+
to job setup but provides 8GB of overflow capacity:
|
|
49
|
+
|
|
50
|
+
Option B — Reduce peak memory usage:
|
|
51
|
+
- Node.js: pass --max-old-space-size=N (MB) to node or set NODE_OPTIONS env var
|
|
52
|
+
- Gradle: reduce org.gradle.jvmargs heap in gradle.properties
|
|
53
|
+
- Cargo: set CARGO_BUILD_JOBS=2 to reduce parallel compilation
|
|
54
|
+
- webpack: use --parallel false or reduce splitChunks settings
|
|
55
|
+
|
|
56
|
+
Option C — Use a larger GitHub-hosted runner with more RAM (requires paid plan):
|
|
57
|
+
ubuntu-24.04 with 64GB RAM is available as a larger runner.
|
|
58
|
+
fix_code:
|
|
59
|
+
- language: yaml
|
|
60
|
+
label: 'Add 8GB swap file before memory-intensive build step'
|
|
61
|
+
code: |
|
|
62
|
+
jobs:
|
|
63
|
+
build:
|
|
64
|
+
runs-on: ubuntu-24.04
|
|
65
|
+
steps:
|
|
66
|
+
- uses: actions/checkout@v4
|
|
67
|
+
|
|
68
|
+
- name: Add swap space
|
|
69
|
+
run: |
|
|
70
|
+
sudo fallocate -l 8G /swapfile
|
|
71
|
+
sudo chmod 600 /swapfile
|
|
72
|
+
sudo mkswap /swapfile
|
|
73
|
+
sudo swapon /swapfile
|
|
74
|
+
swapon --show
|
|
75
|
+
free -h
|
|
76
|
+
|
|
77
|
+
- name: Build (memory-intensive)
|
|
78
|
+
run: npm run build
|
|
79
|
+
|
|
80
|
+
- language: yaml
|
|
81
|
+
label: 'Reduce Node.js memory usage with --max-old-space-size'
|
|
82
|
+
code: |
|
|
83
|
+
jobs:
|
|
84
|
+
build:
|
|
85
|
+
runs-on: ubuntu-24.04
|
|
86
|
+
env:
|
|
87
|
+
NODE_OPTIONS: '--max-old-space-size=6144'
|
|
88
|
+
steps:
|
|
89
|
+
- uses: actions/checkout@v4
|
|
90
|
+
- uses: actions/setup-node@v4
|
|
91
|
+
with:
|
|
92
|
+
node-version: '20'
|
|
93
|
+
- run: npm ci
|
|
94
|
+
- run: npm run build
|
|
95
|
+
|
|
96
|
+
- language: yaml
|
|
97
|
+
label: 'Reduce Gradle heap for Android/Java builds'
|
|
98
|
+
code: |
|
|
99
|
+
jobs:
|
|
100
|
+
build:
|
|
101
|
+
runs-on: ubuntu-24.04
|
|
102
|
+
steps:
|
|
103
|
+
- uses: actions/checkout@v4
|
|
104
|
+
|
|
105
|
+
- name: Set Gradle memory limits
|
|
106
|
+
run: |
|
|
107
|
+
mkdir -p ~/.gradle
|
|
108
|
+
echo 'org.gradle.jvmargs=-Xmx4g -XX:MaxMetaspaceSize=512m' >> ~/.gradle/gradle.properties
|
|
109
|
+
|
|
110
|
+
- name: Build APK
|
|
111
|
+
run: ./gradlew assembleRelease
|
|
112
|
+
prevention:
|
|
113
|
+
- 'Test builds on ubuntu-24.04 explicitly — do not assume ubuntu-22.04 memory behavior transfers'
|
|
114
|
+
- 'Add a swap file as a build step when migrating large builds to ubuntu-24.04'
|
|
115
|
+
- 'Set NODE_OPTIONS=--max-old-space-size as a job-level env var for Node.js heavy workflows'
|
|
116
|
+
- 'Monitor build memory usage locally: /usr/bin/time -v npm run build shows peak RSS'
|
|
117
|
+
- 'Exit code 137 with no explicit error is the canonical indicator of OOM kill — add this as a diagnostic check'
|
|
118
|
+
docs:
|
|
119
|
+
- url: 'https://docs.github.com/en/actions/using-github-hosted-runners/about-github-hosted-runners/about-github-hosted-runners#supported-runners-and-hardware-resources'
|
|
120
|
+
label: 'GitHub-hosted runner hardware specs — RAM and storage per runner type'
|
|
121
|
+
- url: 'https://github.com/actions/runner-images/issues'
|
|
122
|
+
label: 'runner-images issues — search "OOM" or "exit 137" for community reports'
|
|
123
|
+
- url: 'https://nodejs.org/api/cli.html#--max-old-space-sizesize-in-megabytes'
|
|
124
|
+
label: 'Node.js CLI docs — --max-old-space-size option'
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
id: runner-environment-134
|
|
2
|
+
title: 'ubuntu-24.04: openjdk-11-jdk has no installation candidate — Java 11 removed from Ubuntu 24 repos'
|
|
3
|
+
category: runner-environment
|
|
4
|
+
severity: error
|
|
5
|
+
tags:
|
|
6
|
+
- java
|
|
7
|
+
- openjdk
|
|
8
|
+
- ubuntu-24
|
|
9
|
+
- apt
|
|
10
|
+
- java-11
|
|
11
|
+
- noble
|
|
12
|
+
patterns:
|
|
13
|
+
- regex: 'Package .openjdk-11.*has no installation candidate'
|
|
14
|
+
flags: 'i'
|
|
15
|
+
- regex: 'openjdk-11-jdk.*no installation candidate'
|
|
16
|
+
flags: 'i'
|
|
17
|
+
- regex: 'E: Package .openjdk-11'
|
|
18
|
+
flags: 'i'
|
|
19
|
+
error_messages:
|
|
20
|
+
- 'E: Package ''openjdk-11-jdk'' has no installation candidate'
|
|
21
|
+
- 'E: Package ''openjdk-11-jre'' has no installation candidate'
|
|
22
|
+
- 'E: Unable to locate package openjdk-11-jdk'
|
|
23
|
+
root_cause: |
|
|
24
|
+
Ubuntu 24.04 LTS (Noble Numbat) dropped OpenJDK 11 from its official package repositories.
|
|
25
|
+
The minimum available Java version via apt on Ubuntu 24.04 is OpenJDK 17 (openjdk-17-jdk)
|
|
26
|
+
along with OpenJDK 21 (openjdk-21-jdk). OpenJDK 11 packages that existed in Ubuntu 22.04
|
|
27
|
+
(Jammy) are not present in Ubuntu 24.04 (Noble) main or universe repos.
|
|
28
|
+
|
|
29
|
+
Workflows that install Java via apt-get will fail:
|
|
30
|
+
sudo apt-get install -y openjdk-11-jdk # Fails on ubuntu-24.04
|
|
31
|
+
sudo apt-get install -y openjdk-11-jre # Fails on ubuntu-24.04
|
|
32
|
+
|
|
33
|
+
This affects workflows that:
|
|
34
|
+
- Directly install OpenJDK via apt without using actions/setup-java
|
|
35
|
+
- Use Docker images based on ubuntu:24.04 inside workflow steps
|
|
36
|
+
- Run scripts that call apt-get install openjdk-11* expecting Ubuntu 22 behavior
|
|
37
|
+
|
|
38
|
+
Note: Java 11 is still supported under long-term support plans but must be obtained from
|
|
39
|
+
third-party sources (Adoptium/Temurin, Amazon Corretto, Azul Zulu) rather than Ubuntu repos.
|
|
40
|
+
fix: |
|
|
41
|
+
Use actions/setup-java to install any Java version including 11. The action downloads from
|
|
42
|
+
a distribution vendor (Temurin, Corretto, Zulu, etc.) rather than Ubuntu packages, making
|
|
43
|
+
it distribution-independent and supporting Java 11 on ubuntu-24.04.
|
|
44
|
+
|
|
45
|
+
Never use apt-get to install Java on GitHub-hosted runners — always use actions/setup-java
|
|
46
|
+
which handles version discovery, caching, JAVA_HOME configuration, and multi-platform support.
|
|
47
|
+
fix_code:
|
|
48
|
+
- language: yaml
|
|
49
|
+
label: 'Use actions/setup-java to install Java 11 (works on ubuntu-24.04)'
|
|
50
|
+
code: |
|
|
51
|
+
jobs:
|
|
52
|
+
build:
|
|
53
|
+
runs-on: ubuntu-24.04
|
|
54
|
+
steps:
|
|
55
|
+
- uses: actions/checkout@v4
|
|
56
|
+
|
|
57
|
+
- uses: actions/setup-java@v4
|
|
58
|
+
with:
|
|
59
|
+
java-version: '11'
|
|
60
|
+
distribution: 'temurin'
|
|
61
|
+
cache: 'maven'
|
|
62
|
+
|
|
63
|
+
- name: Build with Maven
|
|
64
|
+
run: mvn -B package --file pom.xml
|
|
65
|
+
|
|
66
|
+
- language: yaml
|
|
67
|
+
label: 'Multi-version Java matrix — test across Java 11, 17, 21'
|
|
68
|
+
code: |
|
|
69
|
+
jobs:
|
|
70
|
+
test:
|
|
71
|
+
runs-on: ubuntu-24.04
|
|
72
|
+
strategy:
|
|
73
|
+
matrix:
|
|
74
|
+
java-version: ['11', '17', '21']
|
|
75
|
+
steps:
|
|
76
|
+
- uses: actions/checkout@v4
|
|
77
|
+
|
|
78
|
+
- uses: actions/setup-java@v4
|
|
79
|
+
with:
|
|
80
|
+
java-version: ${{ matrix.java-version }}
|
|
81
|
+
distribution: 'temurin'
|
|
82
|
+
|
|
83
|
+
- name: Run tests
|
|
84
|
+
run: mvn test
|
|
85
|
+
prevention:
|
|
86
|
+
- 'Always use actions/setup-java to install Java on GitHub-hosted runners — never rely on apt-get for Java'
|
|
87
|
+
- 'Pin the Java distribution explicitly (temurin, corretto, zulu) to avoid resolution differences across Ubuntu versions'
|
|
88
|
+
- 'Test workflows on ubuntu-24.04 explicitly when migrating from ubuntu-22.04 or ubuntu-20.04'
|
|
89
|
+
- 'Check Ubuntu package availability with https://packages.ubuntu.com before relying on apt for any tool installation'
|
|
90
|
+
- 'Validate Java availability in your workflow with: java -version && javac -version as an early smoke check'
|
|
91
|
+
docs:
|
|
92
|
+
- url: 'https://github.com/actions/setup-java'
|
|
93
|
+
label: 'actions/setup-java — install Java on any GitHub-hosted runner'
|
|
94
|
+
- url: 'https://packages.ubuntu.com/noble/'
|
|
95
|
+
label: 'Ubuntu 24.04 (Noble) package search — verify available package versions'
|
|
96
|
+
- url: 'https://adoptium.net/temurin/releases/?version=11'
|
|
97
|
+
label: 'Eclipse Temurin — Java 11 LTS builds for all platforms'
|
|
98
|
+
- url: 'https://github.com/actions/runner-images/blob/main/images/ubuntu/Ubuntu2404-Readme.md'
|
|
99
|
+
label: 'ubuntu-24.04 runner software report — pre-installed Java versions'
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
id: runner-environment-132
|
|
2
|
+
title: 'windows-2025 runner: .NET 6 SDK removed — NETSDK1045 when targeting net6.0'
|
|
3
|
+
category: runner-environment
|
|
4
|
+
severity: error
|
|
5
|
+
tags:
|
|
6
|
+
- dotnet
|
|
7
|
+
- windows-2025
|
|
8
|
+
- net6
|
|
9
|
+
- sdk
|
|
10
|
+
- netsdk1045
|
|
11
|
+
- eol
|
|
12
|
+
patterns:
|
|
13
|
+
- regex: 'NETSDK1045.*\.NET 6\.0'
|
|
14
|
+
flags: 'i'
|
|
15
|
+
- regex: 'does not support targeting.*\.NET 6'
|
|
16
|
+
flags: 'i'
|
|
17
|
+
- regex: 'error NETSDK1045'
|
|
18
|
+
flags: 'i'
|
|
19
|
+
error_messages:
|
|
20
|
+
- 'error NETSDK1045: The current .NET SDK does not support targeting .NET 6.0.'
|
|
21
|
+
- 'error NETSDK1045: The current .NET SDK does not support targeting .NET 6.0. Either target .NET 8.0 or higher, or use a .NET SDK that supports .NET 6.0.'
|
|
22
|
+
root_cause: |
|
|
23
|
+
.NET 6 reached end-of-life on November 12, 2024. The windows-2025 runner image does not
|
|
24
|
+
include the .NET 6 SDK or runtime. Pre-installed .NET SDKs on windows-2025 are .NET 8
|
|
25
|
+
and .NET 9 only.
|
|
26
|
+
|
|
27
|
+
Workflows using dotnet build, dotnet test, or dotnet publish that target net6.0 TFM fail
|
|
28
|
+
with NETSDK1045 because no installed SDK can build or run .NET 6 targets. This affects:
|
|
29
|
+
- Projects with <TargetFramework>net6.0</TargetFramework> in their .csproj
|
|
30
|
+
- Multi-target projects including net6.0 in <TargetFrameworks>
|
|
31
|
+
- Workflows that run dotnet run with a net6.0 project
|
|
32
|
+
|
|
33
|
+
The windows-2022 runner still includes .NET 6 for legacy compatibility, so workflows using
|
|
34
|
+
runs-on: windows-2022 are unaffected. The breakage appears when migrating to windows-2025
|
|
35
|
+
or when windows-latest switches to windows-2025.
|
|
36
|
+
fix: |
|
|
37
|
+
Option A (recommended): Upgrade the project's TargetFramework to net8.0 or net9.0. .NET 8
|
|
38
|
+
is the current LTS release and is pre-installed on windows-2025.
|
|
39
|
+
|
|
40
|
+
Option B (legacy support): Use actions/setup-dotnet to explicitly install the .NET 6 SDK.
|
|
41
|
+
Note: .NET 6 is EOL and receives no security patches — this option is not recommended for
|
|
42
|
+
production workloads.
|
|
43
|
+
|
|
44
|
+
Option C (short-term): Pin to windows-2022 runner temporarily while upgrading.
|
|
45
|
+
fix_code:
|
|
46
|
+
- language: yaml
|
|
47
|
+
label: 'Option A — upgrade target framework to .NET 8 LTS (recommended)'
|
|
48
|
+
code: |
|
|
49
|
+
# In your .csproj, update:
|
|
50
|
+
# <TargetFramework>net8.0</TargetFramework>
|
|
51
|
+
# Then in your workflow:
|
|
52
|
+
jobs:
|
|
53
|
+
build:
|
|
54
|
+
runs-on: windows-2025
|
|
55
|
+
steps:
|
|
56
|
+
- uses: actions/checkout@v4
|
|
57
|
+
|
|
58
|
+
- uses: actions/setup-dotnet@v4
|
|
59
|
+
with:
|
|
60
|
+
dotnet-version: '8.0.x'
|
|
61
|
+
|
|
62
|
+
- name: Build
|
|
63
|
+
run: dotnet build --configuration Release
|
|
64
|
+
|
|
65
|
+
- language: yaml
|
|
66
|
+
label: 'Option B — explicitly install .NET 6 SDK (EOL, not recommended for production)'
|
|
67
|
+
code: |
|
|
68
|
+
jobs:
|
|
69
|
+
build:
|
|
70
|
+
runs-on: windows-2025
|
|
71
|
+
steps:
|
|
72
|
+
- uses: actions/checkout@v4
|
|
73
|
+
|
|
74
|
+
- uses: actions/setup-dotnet@v4
|
|
75
|
+
with:
|
|
76
|
+
dotnet-version: |
|
|
77
|
+
6.0.x
|
|
78
|
+
8.0.x
|
|
79
|
+
|
|
80
|
+
- name: Build
|
|
81
|
+
run: dotnet build --framework net6.0
|
|
82
|
+
prevention:
|
|
83
|
+
- 'Audit all TargetFramework and TargetFrameworks values before migrating to windows-2025'
|
|
84
|
+
- 'Monitor the .NET release lifecycle at https://dotnet.microsoft.com/platform/support/policy for upcoming EOL dates'
|
|
85
|
+
- 'Use Dependabot or Renovate to track .NET SDK versions referenced in global.json or setup-dotnet steps'
|
|
86
|
+
- 'Check the windows-2025 runner software report (runner-images/Windows2025-Readme.md) before migration to see pre-installed SDKs'
|
|
87
|
+
- 'Set up a CI matrix that tests both windows-2022 and windows-2025 during migration periods'
|
|
88
|
+
docs:
|
|
89
|
+
- url: 'https://github.com/actions/runner-images/blob/main/images/windows/Windows2025-Readme.md'
|
|
90
|
+
label: 'windows-2025 runner software report — pre-installed SDK versions'
|
|
91
|
+
- url: 'https://dotnet.microsoft.com/platform/support/policy/dotnet-core'
|
|
92
|
+
label: '.NET release lifecycle and EOL schedule'
|
|
93
|
+
- url: 'https://github.com/actions/setup-dotnet'
|
|
94
|
+
label: 'actions/setup-dotnet — install specific .NET SDK versions'
|
|
95
|
+
- url: 'https://github.com/actions/runner-images/discussions'
|
|
96
|
+
label: 'GitHub runner-images discussions — windows-2025 migration issues'
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
id: silent-failures-070
|
|
2
|
+
title: 'github.ref_name returns N/merge on pull_request events, not the head branch name'
|
|
3
|
+
category: silent-failures
|
|
4
|
+
severity: silent-failure
|
|
5
|
+
tags:
|
|
6
|
+
- github-ref-name
|
|
7
|
+
- github-head-ref
|
|
8
|
+
- pull-request
|
|
9
|
+
- merge-ref
|
|
10
|
+
- branch-name
|
|
11
|
+
- context
|
|
12
|
+
patterns:
|
|
13
|
+
- regex: 'github\.ref_name'
|
|
14
|
+
flags: 'i'
|
|
15
|
+
- regex: '\d+/merge'
|
|
16
|
+
flags: ''
|
|
17
|
+
error_messages:
|
|
18
|
+
- "branch name is '15/merge' instead of 'feature/my-branch'"
|
|
19
|
+
- "invalid branch: 45/merge"
|
|
20
|
+
- "ref_name evaluates to 23/merge on pull_request trigger"
|
|
21
|
+
root_cause: |
|
|
22
|
+
On pull_request events, GitHub creates a synthetic merge commit ref at refs/pull/N/merge
|
|
23
|
+
representing the result of merging the head branch into the base branch. This is the ref
|
|
24
|
+
that the runner checks out by default.
|
|
25
|
+
|
|
26
|
+
github.ref resolves to 'refs/pull/N/merge' and github.ref_name resolves to 'N/merge'
|
|
27
|
+
(e.g., '15/merge') — not the human-readable head branch name.
|
|
28
|
+
|
|
29
|
+
Developers who use github.ref_name expecting the PR head branch name receive the synthetic
|
|
30
|
+
merge ref slug instead, which breaks:
|
|
31
|
+
- Branch-based deployment logic
|
|
32
|
+
- Conditional workflow steps that check the branch name
|
|
33
|
+
- Tag/release workflows incorrectly applied to PR builds
|
|
34
|
+
- Docker image tags derived from the branch name
|
|
35
|
+
|
|
36
|
+
To get the actual PR head branch name on pull_request events, use github.head_ref.
|
|
37
|
+
To get the base branch name, use github.base_ref.
|
|
38
|
+
|
|
39
|
+
Note: On push events, github.ref_name correctly returns the branch name (e.g., 'main').
|
|
40
|
+
The discrepancy only affects pull_request (and pull_request_target) events.
|
|
41
|
+
fix: |
|
|
42
|
+
Use github.head_ref instead of github.ref_name when you need the PR head branch name.
|
|
43
|
+
|
|
44
|
+
For robust multi-event workflows, use a conditional expression:
|
|
45
|
+
- On pull_request: github.head_ref contains the branch name
|
|
46
|
+
- On push: github.ref_name contains the branch name
|
|
47
|
+
|
|
48
|
+
Or use a ternary-style expression to normalize:
|
|
49
|
+
${{ github.event_name == 'pull_request' && github.head_ref || github.ref_name }}
|
|
50
|
+
fix_code:
|
|
51
|
+
- language: yaml
|
|
52
|
+
label: 'Use github.head_ref for PR branch name, github.ref_name for push'
|
|
53
|
+
code: |
|
|
54
|
+
jobs:
|
|
55
|
+
build:
|
|
56
|
+
runs-on: ubuntu-latest
|
|
57
|
+
steps:
|
|
58
|
+
- name: Get branch name
|
|
59
|
+
run: |
|
|
60
|
+
if [ "${{ github.event_name }}" = "pull_request" ]; then
|
|
61
|
+
BRANCH="${{ github.head_ref }}"
|
|
62
|
+
else
|
|
63
|
+
BRANCH="${{ github.ref_name }}"
|
|
64
|
+
fi
|
|
65
|
+
echo "Branch: $BRANCH"
|
|
66
|
+
echo "BRANCH=$BRANCH" >> $GITHUB_ENV
|
|
67
|
+
|
|
68
|
+
- language: yaml
|
|
69
|
+
label: 'Normalize branch name in Docker image tag (works for push and PR)'
|
|
70
|
+
code: |
|
|
71
|
+
on:
|
|
72
|
+
push:
|
|
73
|
+
branches: [main, develop]
|
|
74
|
+
pull_request:
|
|
75
|
+
|
|
76
|
+
jobs:
|
|
77
|
+
docker:
|
|
78
|
+
runs-on: ubuntu-latest
|
|
79
|
+
steps:
|
|
80
|
+
- name: Set branch slug
|
|
81
|
+
id: branch
|
|
82
|
+
run: |
|
|
83
|
+
# Use head_ref for PRs, ref_name for push events
|
|
84
|
+
BRANCH="${{ github.event_name == 'pull_request' && github.head_ref || github.ref_name }}"
|
|
85
|
+
# Slugify: replace / with - for Docker tag compatibility
|
|
86
|
+
SLUG=$(echo "$BRANCH" | tr '/' '-' | tr '[:upper:]' '[:lower:]')
|
|
87
|
+
echo "slug=$SLUG" >> $GITHUB_OUTPUT
|
|
88
|
+
|
|
89
|
+
- name: Build Docker image
|
|
90
|
+
run: docker build -t myapp:${{ steps.branch.outputs.slug }} .
|
|
91
|
+
prevention:
|
|
92
|
+
- 'On pull_request events, always use github.head_ref for the PR head branch and github.base_ref for the target base branch'
|
|
93
|
+
- 'github.ref_name is only reliable as a branch name on push events — never use it unconditionally'
|
|
94
|
+
- 'When writing multi-event workflows (push + pull_request), add an event-conditional expression to normalize the branch name'
|
|
95
|
+
- 'Test workflows triggered by both push and pull_request events to catch context differences early'
|
|
96
|
+
docs:
|
|
97
|
+
- url: 'https://docs.github.com/en/actions/writing-workflows/choosing-what-your-workflow-does/accessing-contextual-information-about-workflow-runs#github-context'
|
|
98
|
+
label: 'GitHub context — github.ref_name, github.head_ref, github.base_ref'
|
|
99
|
+
- url: 'https://docs.github.com/en/actions/writing-workflows/choosing-when-your-workflow-runs/events-that-trigger-workflows#pull_request'
|
|
100
|
+
label: 'pull_request event context and merge ref behavior'
|
|
101
|
+
- url: 'https://github.com/orgs/community/discussions/25722'
|
|
102
|
+
label: 'GitHub Community: github.ref_name returns N/merge on pull_request'
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
id: silent-failures-069
|
|
2
|
+
title: 'workflow_call: caller env vars not forwarded to reusable workflow — silently unavailable'
|
|
3
|
+
category: silent-failures
|
|
4
|
+
severity: silent-failure
|
|
5
|
+
tags:
|
|
6
|
+
- reusable-workflow
|
|
7
|
+
- workflow_call
|
|
8
|
+
- env-context
|
|
9
|
+
- caller-env
|
|
10
|
+
- inputs
|
|
11
|
+
- environment-variables
|
|
12
|
+
patterns:
|
|
13
|
+
- regex: 'env\.\w+ is not defined'
|
|
14
|
+
flags: 'i'
|
|
15
|
+
- regex: '\$\{\{\s*env\.\w+\s*\}\}\s*$'
|
|
16
|
+
flags: 'im'
|
|
17
|
+
error_messages:
|
|
18
|
+
- "env.API_URL is not defined"
|
|
19
|
+
- "The template is not valid. .github/workflows/deploy.yml: env.BASE_URL is not defined"
|
|
20
|
+
root_cause: |
|
|
21
|
+
GitHub Actions reusable workflows (on.workflow_call) run in a completely isolated environment.
|
|
22
|
+
The caller workflow's env: context — whether defined at the top-level workflow scope or at the
|
|
23
|
+
calling job scope — is NOT automatically forwarded to the called reusable workflow.
|
|
24
|
+
|
|
25
|
+
Only two mechanisms exist for passing data into a reusable workflow:
|
|
26
|
+
- inputs: (on.workflow_call.inputs) for plain values
|
|
27
|
+
- secrets: (on.workflow_call.secrets) for sensitive values
|
|
28
|
+
|
|
29
|
+
A common mistake is defining env: vars at the caller workflow level and assuming they will be
|
|
30
|
+
visible inside the reusable workflow. They are not. The called workflow has its own empty env:
|
|
31
|
+
context (unless vars.* or env: is set within the reusable workflow itself).
|
|
32
|
+
|
|
33
|
+
Example that breaks silently:
|
|
34
|
+
- Caller sets: env: { API_URL: 'https://api.example.com' }
|
|
35
|
+
- Caller calls: uses: ./.github/workflows/deploy.yml
|
|
36
|
+
- Inside deploy.yml: run: curl ${{ env.API_URL }} # evaluates to empty string, no error
|
|
37
|
+
fix: |
|
|
38
|
+
Pass values explicitly via the inputs: mechanism on the reusable workflow call.
|
|
39
|
+
Define the input on on.workflow_call.inputs and reference it as inputs.<name> inside the
|
|
40
|
+
called workflow.
|
|
41
|
+
|
|
42
|
+
If many env vars need forwarding, consider using a JSON-encoded input and fromJSON() inside
|
|
43
|
+
the called workflow, or use repository variables (vars.*) which are available in all workflows.
|
|
44
|
+
fix_code:
|
|
45
|
+
- language: yaml
|
|
46
|
+
label: 'Pass caller env var as explicit input to reusable workflow'
|
|
47
|
+
code: |
|
|
48
|
+
# Caller workflow
|
|
49
|
+
jobs:
|
|
50
|
+
deploy:
|
|
51
|
+
uses: ./.github/workflows/deploy.yml
|
|
52
|
+
with:
|
|
53
|
+
api_url: ${{ vars.API_URL }} # or hardcoded value
|
|
54
|
+
secrets: inherit
|
|
55
|
+
|
|
56
|
+
# Reusable workflow: .github/workflows/deploy.yml
|
|
57
|
+
on:
|
|
58
|
+
workflow_call:
|
|
59
|
+
inputs:
|
|
60
|
+
api_url:
|
|
61
|
+
required: true
|
|
62
|
+
type: string
|
|
63
|
+
|
|
64
|
+
jobs:
|
|
65
|
+
run:
|
|
66
|
+
runs-on: ubuntu-latest
|
|
67
|
+
steps:
|
|
68
|
+
- name: Deploy
|
|
69
|
+
run: curl ${{ inputs.api_url }}
|
|
70
|
+
|
|
71
|
+
- language: yaml
|
|
72
|
+
label: 'Use repository variables (vars.*) accessible in all workflows'
|
|
73
|
+
code: |
|
|
74
|
+
# Set API_URL as a repository variable in Settings → Secrets and variables → Actions → Variables
|
|
75
|
+
# Then reference it in the reusable workflow directly:
|
|
76
|
+
jobs:
|
|
77
|
+
run:
|
|
78
|
+
runs-on: ubuntu-latest
|
|
79
|
+
steps:
|
|
80
|
+
- name: Deploy
|
|
81
|
+
run: curl ${{ vars.API_URL }}
|
|
82
|
+
prevention:
|
|
83
|
+
- 'Never rely on env: vars defined in a caller workflow being available inside a reusable workflow — they are not forwarded'
|
|
84
|
+
- 'Declare all cross-workflow values as on.workflow_call.inputs or on.workflow_call.secrets'
|
|
85
|
+
- 'Use repository/org-level variables (vars.*) for configuration that many workflows need without explicit passing'
|
|
86
|
+
- 'Run actionlint on caller and callee separately — it will flag undefined env references in reusable workflows'
|
|
87
|
+
docs:
|
|
88
|
+
- url: 'https://docs.github.com/en/actions/sharing-automations/reusing-workflows#passing-inputs-and-secrets-to-a-reusable-workflow'
|
|
89
|
+
label: 'Passing inputs and secrets to a reusable workflow'
|
|
90
|
+
- url: 'https://docs.github.com/en/actions/writing-workflows/choosing-what-your-workflow-does/store-information-in-variables#using-the-vars-context-to-access-configuration-variable-values'
|
|
91
|
+
label: 'Using repository variables with the vars context'
|
|
92
|
+
- url: 'https://github.com/orgs/community/discussions/26671'
|
|
93
|
+
label: 'GitHub Community: env vars not accessible in reusable workflows'
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
id: triggers-050
|
|
2
|
+
title: 'on.issue_comment does not fire for PR review thread comments — requires pull_request_review_comment'
|
|
3
|
+
category: triggers
|
|
4
|
+
severity: silent-failure
|
|
5
|
+
tags:
|
|
6
|
+
- issue_comment
|
|
7
|
+
- pull_request_review_comment
|
|
8
|
+
- pr-review
|
|
9
|
+
- comment-event
|
|
10
|
+
- trigger
|
|
11
|
+
- chatops
|
|
12
|
+
patterns:
|
|
13
|
+
- regex: 'on:\s*\n\s+issue_comment'
|
|
14
|
+
flags: 'im'
|
|
15
|
+
- regex: 'github\.event_name\s*==\s*[''"]issue_comment[''"]'
|
|
16
|
+
flags: 'i'
|
|
17
|
+
error_messages:
|
|
18
|
+
- "workflow never triggered when commenting on a PR review thread"
|
|
19
|
+
- "issue_comment workflow fires on issue comments but not PR inline review comments"
|
|
20
|
+
root_cause: |
|
|
21
|
+
GitHub Actions has two distinct comment event types that developers frequently confuse:
|
|
22
|
+
|
|
23
|
+
1. issue_comment — fires when a comment is posted on:
|
|
24
|
+
- The main conversation thread of an issue
|
|
25
|
+
- The main conversation thread of a pull request (PR-as-issue comments)
|
|
26
|
+
It does NOT fire for inline PR code review comments or review summary comments.
|
|
27
|
+
|
|
28
|
+
2. pull_request_review_comment — fires when a comment is posted on:
|
|
29
|
+
- A specific line of code in a PR diff (inline review comment)
|
|
30
|
+
It does NOT fire for comments on the main PR conversation thread.
|
|
31
|
+
|
|
32
|
+
3. pull_request_review — fires when:
|
|
33
|
+
- A complete PR review is submitted (including review body, approval, or request-changes)
|
|
34
|
+
|
|
35
|
+
Chatops bots and automation that listen to issue_comment expecting to catch all PR comment
|
|
36
|
+
activity will silently miss all PR code review thread comments. There is no error — the
|
|
37
|
+
workflow simply never fires for that comment type.
|
|
38
|
+
|
|
39
|
+
Similarly, on.pull_request_review_comment will miss all main thread comments on the same PR.
|
|
40
|
+
fix: |
|
|
41
|
+
Choose the correct trigger based on what type of comment you want to react to:
|
|
42
|
+
|
|
43
|
+
- For commands in PR main conversation (/deploy, /approve, etc.): use issue_comment
|
|
44
|
+
- For reactions to inline code review comments: use pull_request_review_comment
|
|
45
|
+
- For reactions to full review submissions (approve, request changes): use pull_request_review
|
|
46
|
+
- For all PR comment activity: use both issue_comment AND pull_request_review_comment
|
|
47
|
+
|
|
48
|
+
Note: on.issue_comment has access to github.event.issue.number for the PR number,
|
|
49
|
+
while on.pull_request_review_comment has access to github.event.pull_request.number.
|
|
50
|
+
fix_code:
|
|
51
|
+
- language: yaml
|
|
52
|
+
label: 'Listen to all PR comment types (main thread + review thread)'
|
|
53
|
+
code: |
|
|
54
|
+
on:
|
|
55
|
+
issue_comment:
|
|
56
|
+
types: [created]
|
|
57
|
+
pull_request_review_comment:
|
|
58
|
+
types: [created]
|
|
59
|
+
pull_request_review:
|
|
60
|
+
types: [submitted]
|
|
61
|
+
|
|
62
|
+
jobs:
|
|
63
|
+
handle-comment:
|
|
64
|
+
runs-on: ubuntu-latest
|
|
65
|
+
steps:
|
|
66
|
+
- name: Handle comment
|
|
67
|
+
run: |
|
|
68
|
+
if [ "${{ github.event_name }}" = "issue_comment" ]; then
|
|
69
|
+
echo "Main thread comment: ${{ github.event.comment.body }}"
|
|
70
|
+
echo "PR number: ${{ github.event.issue.number }}"
|
|
71
|
+
elif [ "${{ github.event_name }}" = "pull_request_review_comment" ]; then
|
|
72
|
+
echo "Review thread comment: ${{ github.event.comment.body }}"
|
|
73
|
+
echo "PR number: ${{ github.event.pull_request.number }}"
|
|
74
|
+
fi
|
|
75
|
+
|
|
76
|
+
- language: yaml
|
|
77
|
+
label: 'Chatops bot — listen for slash commands on main PR thread only'
|
|
78
|
+
code: |
|
|
79
|
+
on:
|
|
80
|
+
issue_comment:
|
|
81
|
+
types: [created]
|
|
82
|
+
|
|
83
|
+
jobs:
|
|
84
|
+
chatops:
|
|
85
|
+
# Only run for PR comments (issue_comment also fires on plain issues)
|
|
86
|
+
if: github.event.issue.pull_request != null
|
|
87
|
+
runs-on: ubuntu-latest
|
|
88
|
+
steps:
|
|
89
|
+
- name: Check for slash command
|
|
90
|
+
run: |
|
|
91
|
+
echo "Comment body: ${{ github.event.comment.body }}"
|
|
92
|
+
prevention:
|
|
93
|
+
- 'Distinguish issue_comment (main PR thread) from pull_request_review_comment (inline code review thread) — they never overlap'
|
|
94
|
+
- 'If building a PR chatops bot, filter to PR-only comments by checking github.event.issue.pull_request != null'
|
|
95
|
+
- 'Use pull_request_review for reactions to full review submissions (approve/reject), not pull_request_review_comment'
|
|
96
|
+
- 'Test your trigger by posting comments in BOTH places (main conversation and code review thread) to verify expected behavior'
|
|
97
|
+
docs:
|
|
98
|
+
- url: 'https://docs.github.com/en/actions/writing-workflows/choosing-when-your-workflow-runs/events-that-trigger-workflows#issue_comment'
|
|
99
|
+
label: 'GitHub Docs — issue_comment event'
|
|
100
|
+
- url: 'https://docs.github.com/en/actions/writing-workflows/choosing-when-your-workflow-runs/events-that-trigger-workflows#pull_request_review_comment'
|
|
101
|
+
label: 'GitHub Docs — pull_request_review_comment event'
|
|
102
|
+
- url: 'https://docs.github.com/en/actions/writing-workflows/choosing-when-your-workflow-runs/events-that-trigger-workflows#pull_request_review'
|
|
103
|
+
label: 'GitHub Docs — pull_request_review event'
|
|
104
|
+
- url: 'https://github.com/orgs/community/discussions/21929'
|
|
105
|
+
label: 'GitHub Community: issue_comment vs pull_request_review_comment confusion'
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
id: yaml-syntax-047
|
|
2
|
+
title: '"You can''t use both ''branches'' and ''branches-ignore''" — combined on same event trigger'
|
|
3
|
+
category: yaml-syntax
|
|
4
|
+
severity: error
|
|
5
|
+
tags:
|
|
6
|
+
- branches
|
|
7
|
+
- branches-ignore
|
|
8
|
+
- trigger-filter
|
|
9
|
+
- validation-error
|
|
10
|
+
- actionlint
|
|
11
|
+
- on-push
|
|
12
|
+
patterns:
|
|
13
|
+
- regex: 'You can''t use both ''branches'' and ''branches-ignore'''
|
|
14
|
+
flags: 'i'
|
|
15
|
+
- regex: "You can't use both 'branches' and 'branches-ignore'"
|
|
16
|
+
flags: 'i'
|
|
17
|
+
- regex: 'branches.*branches-ignore|branches-ignore.*branches'
|
|
18
|
+
flags: 'is'
|
|
19
|
+
error_messages:
|
|
20
|
+
- "You can't use both 'branches' and 'branches-ignore' for the same event."
|
|
21
|
+
- "Invalid workflow file: .github/workflows/ci.yml: You can't use both 'branches' and 'branches-ignore' for the same event."
|
|
22
|
+
root_cause: |
|
|
23
|
+
GitHub Actions validates that branches and branches-ignore are mutually exclusive filters
|
|
24
|
+
on the same trigger event. Using both simultaneously causes a workflow parse error because
|
|
25
|
+
the semantics are contradictory — branches is an allowlist while branches-ignore is a
|
|
26
|
+
denylist, and combining them on the same trigger is undefined behavior.
|
|
27
|
+
|
|
28
|
+
This restriction applies to all events that support branch filtering, including:
|
|
29
|
+
- on.push
|
|
30
|
+
- on.pull_request
|
|
31
|
+
- on.pull_request_target
|
|
32
|
+
|
|
33
|
+
The same restriction applies to paths vs paths-ignore and tags vs tags-ignore.
|
|
34
|
+
|
|
35
|
+
Common mistake patterns:
|
|
36
|
+
- Developer adds branches-ignore: [main] to prevent duplicate runs, forgetting branches is set
|
|
37
|
+
- Developer copies a snippet with branches and adds branches-ignore without removing the original
|
|
38
|
+
- Workflow generated from a template that includes both filters from different sections
|
|
39
|
+
|
|
40
|
+
Note: branches and paths can coexist on the same trigger (both act as allowlists that AND together).
|
|
41
|
+
It is only branches + branches-ignore (or paths + paths-ignore) that conflict.
|
|
42
|
+
fix: |
|
|
43
|
+
Choose one approach and remove the other:
|
|
44
|
+
|
|
45
|
+
Option A — Use branches (allowlist): explicitly list which branches should trigger the workflow.
|
|
46
|
+
Option B — Use branches-ignore (denylist): list which branches should NOT trigger the workflow.
|
|
47
|
+
|
|
48
|
+
To achieve "run on all branches except main and release/*", use branches-ignore.
|
|
49
|
+
To achieve "only run on main and feature/*", use branches.
|
|
50
|
+
|
|
51
|
+
For complex patterns (e.g., "feature/* except feature/skip"), use branches with negation
|
|
52
|
+
via the ! prefix:
|
|
53
|
+
branches:
|
|
54
|
+
- 'feature/**'
|
|
55
|
+
- '!feature/skip-*'
|
|
56
|
+
fix_code:
|
|
57
|
+
- language: yaml
|
|
58
|
+
label: 'Broken — branches and branches-ignore on same event (causes validation error)'
|
|
59
|
+
code: |
|
|
60
|
+
# BROKEN — do not use both on the same event
|
|
61
|
+
on:
|
|
62
|
+
push:
|
|
63
|
+
branches:
|
|
64
|
+
- main
|
|
65
|
+
- 'feature/**'
|
|
66
|
+
branches-ignore: # ERROR: cannot combine with branches
|
|
67
|
+
- 'feature/wip-*'
|
|
68
|
+
|
|
69
|
+
- language: yaml
|
|
70
|
+
label: 'Fixed — use branches with ! negation patterns'
|
|
71
|
+
code: |
|
|
72
|
+
on:
|
|
73
|
+
push:
|
|
74
|
+
branches:
|
|
75
|
+
- main
|
|
76
|
+
- 'feature/**'
|
|
77
|
+
- '!feature/wip-*' # negate specific sub-pattern
|
|
78
|
+
|
|
79
|
+
- language: yaml
|
|
80
|
+
label: 'Fixed — use branches-ignore (denylist) alone'
|
|
81
|
+
code: |
|
|
82
|
+
on:
|
|
83
|
+
push:
|
|
84
|
+
branches-ignore:
|
|
85
|
+
- 'feature/wip-*'
|
|
86
|
+
- 'dependabot/**'
|
|
87
|
+
prevention:
|
|
88
|
+
- 'Never combine branches and branches-ignore on the same trigger event — pick one approach'
|
|
89
|
+
- 'Use branches (allowlist) when only a few branches should trigger; use branches-ignore (denylist) when most branches should trigger'
|
|
90
|
+
- 'To exclude specific patterns from an allowlist, use ! negation prefix inside the branches list'
|
|
91
|
+
- 'Run actionlint in CI to catch this validation error before pushing (actionlint reports it immediately)'
|
|
92
|
+
- 'The same mutual-exclusion rule applies to paths/paths-ignore and tags/tags-ignore'
|
|
93
|
+
docs:
|
|
94
|
+
- url: 'https://docs.github.com/en/actions/writing-workflows/choosing-when-your-workflow-runs/triggering-a-workflow#using-filters'
|
|
95
|
+
label: 'Using filters — branches, branches-ignore, and negation patterns'
|
|
96
|
+
- url: 'https://docs.github.com/en/actions/writing-workflows/workflow-syntax-for-github-actions#onpushbranchestagsbranches-ignoretags-ignore'
|
|
97
|
+
label: 'Workflow syntax — on.push branches and branches-ignore'
|
|
98
|
+
- url: 'https://rhysd.github.io/actionlint/'
|
|
99
|
+
label: 'actionlint — static checker that catches this error instantly'
|
package/package.json
CHANGED