Skip to content

Commit 59e6240

Browse files
rubnogueiraclaude
andcommitted
ci: gate release on master ancestry; use docker for musl builds
- Add a `gate-release` job that runs after the matrix and only allows the `release` job to proceed if the tag commit is reachable from origin/master. Tags pushed from feature branches still run the build matrix (for verification) but the release is skipped, not failed. - Replace the `container: node:24-alpine` directive on musl jobs with an explicit `docker run` invocation. GitHub Actions JS actions can't run inside Alpine containers on ARM64 runners; running the build inside `docker run` on the host runner sidesteps that limitation and keeps the x64/arm64 musl paths identical. - Drop the obsolete `build-release` branch from the push trigger. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent 500d14c commit 59e6240

1 file changed

Lines changed: 61 additions & 15 deletions

File tree

.github/workflows/prebuild.yml

Lines changed: 61 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ name: prebuild
22

33
on:
44
push:
5-
branches: [master, main, build-release]
5+
branches: [master, main]
66
tags: ['v*']
77
pull_request:
88
workflow_dispatch:
@@ -34,34 +34,30 @@ jobs:
3434
runner: ubuntu-latest
3535
- id: linux-x64-musl
3636
runner: ubuntu-latest
37-
container: node:24-alpine
37+
musl: true
3838
- id: linux-arm64-glibc
3939
runner: ubuntu-24.04-arm
4040
- id: linux-arm64-musl
4141
runner: ubuntu-24.04-arm
42-
container: node:24-alpine
42+
musl: true
4343
- id: win32-x64
4444
runner: windows-latest
4545

46-
container: ${{ matrix.container }}
47-
4846
steps:
49-
- name: Install Alpine build deps
50-
if: matrix.container == 'node:24-alpine'
51-
run: apk add --no-cache bash python3 make g++ git tar
52-
5347
- uses: actions/checkout@v5
5448

55-
- name: Set up Node (non-container runners)
56-
if: matrix.container == ''
49+
- name: Set up Node (non-musl jobs)
50+
if: ${{ !matrix.musl }}
5751
uses: actions/setup-node@v5
5852
with:
5953
node-version: '24'
6054

61-
- name: Install npm deps (no scripts so install hook can't fire)
55+
- name: Install npm deps (non-musl)
56+
if: ${{ !matrix.musl }}
6257
run: npm ci --ignore-scripts
6358

64-
- name: Build prebuilds for all target ABIs
59+
- name: Build prebuilds for all target ABIs (non-musl)
60+
if: ${{ !matrix.musl }}
6561
shell: bash
6662
run: |
6763
set -euo pipefail
@@ -74,6 +70,29 @@ jobs:
7470
# consumer side.
7571
npx prebuild $args --strip --tag-libc
7672
73+
# Musl path runs inside docker rather than using `container:`, because
74+
# GitHub Actions JavaScript actions can't run in Alpine containers on
75+
# ARM64 runners. Doing the whole build inside `docker run` sidesteps
76+
# that limitation and keeps the x64/arm64 musl steps identical.
77+
- name: Build musl prebuilds via Alpine docker
78+
if: ${{ matrix.musl }}
79+
shell: bash
80+
run: |
81+
set -euo pipefail
82+
docker run --rm \
83+
-v "$PWD":/work -w /work \
84+
-e NODE_TARGETS="$NODE_TARGETS" \
85+
node:24-alpine sh -c '
86+
set -e
87+
apk add --no-cache python3 make g++ git tar
88+
npm ci --ignore-scripts
89+
args=""
90+
for v in $NODE_TARGETS; do
91+
args="$args -t $v"
92+
done
93+
npx prebuild $args --strip --tag-libc
94+
'
95+
7796
- name: Verify each tarball contains a .node binary
7897
shell: bash
7998
run: |
@@ -98,11 +117,38 @@ jobs:
98117
if-no-files-found: error
99118
retention-days: 30
100119

101-
release:
102-
name: attach prebuilds to GitHub Release
120+
# Gate the release on tag being reachable from master. If the tag was
121+
# pushed from a feature branch (or any non-master commit), this job
122+
# outputs on_master=false and the release job is skipped (not failed).
123+
gate-release:
124+
name: gate release on master ancestry
103125
needs: prebuild
104126
if: startsWith(github.ref, 'refs/tags/v')
105127
runs-on: ubuntu-latest
128+
outputs:
129+
on_master: ${{ steps.check.outputs.on_master }}
130+
steps:
131+
- uses: actions/checkout@v5
132+
with:
133+
fetch-depth: 0
134+
- id: check
135+
run: |
136+
set -euo pipefail
137+
git fetch origin master
138+
if git merge-base --is-ancestor "$GITHUB_SHA" origin/master; then
139+
echo "Tag $GITHUB_REF_NAME (commit $GITHUB_SHA) is on master — release will publish"
140+
echo "on_master=true" >> "$GITHUB_OUTPUT"
141+
else
142+
echo "Tag $GITHUB_REF_NAME (commit $GITHUB_SHA) is NOT on master — release will be skipped"
143+
echo "Merge your PR to master first, then re-tag the merge commit."
144+
echo "on_master=false" >> "$GITHUB_OUTPUT"
145+
fi
146+
147+
release:
148+
name: attach prebuilds to GitHub Release
149+
needs: [prebuild, gate-release]
150+
if: needs.gate-release.outputs.on_master == 'true'
151+
runs-on: ubuntu-latest
106152
permissions:
107153
contents: write
108154
steps:

0 commit comments

Comments
 (0)