1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
name: Publish Node Package
# Publishes the napi-rs addon as the standard layout: a thin root package
# `mq-bridge` plus one binary package per platform
# (`mq-bridge-darwin-arm64`, `mq-bridge-linux-x64-gnu`, ...). The root lists the
# platform packages as optionalDependencies, so each consumer downloads only its
# own ~20MB binary; the napi loader (native.js) requires the matching one.
#
# Linux is built inside a Debian 11 (glibc 2.31) container so the binaries run on
# RHEL 9 (glibc 2.34), Debian 11/12 and Ubuntu 20.04+ — covering the priority
# server targets. macOS/Windows build natively.
#
# Auth: token-or-OIDC. If the `NPM_TOKEN` secret is set it is used (needed for the
# one-time bootstrap that creates the 5 platform packages, since npm has no
# pending-publisher concept). Once all six packages exist and trusted publishing
# is configured for them, remove the secret and publishing continues via OIDC
# (id-token) with provenance — no token.
on:
release:
types:
- published
workflow_dispatch:
env:
CARGO_TERM_COLOR: always
jobs:
build-linux:
name: Build ${{ matrix.target }}
runs-on: ${{ matrix.runner }}
permissions:
contents: read
container:
# Debian 11 bullseye => glibc 2.31 baseline (runs on RHEL 9 / Debian 11+ /
# Ubuntu 20.04+). Pulled natively per arch on the matching runner.
image: node:20-bullseye
strategy:
fail-fast: false
matrix:
include:
- runner: ubuntu-22.04
target: x86_64-unknown-linux-gnu
- runner: ubuntu-22.04-arm
target: aarch64-unknown-linux-gnu
steps:
- uses: actions/checkout@v4
# rdkafka builds librdkafka from source (cc/make) and aws-lc-sys needs
# cmake; the slim node image lacks these.
- name: Install build toolchain
run: |
apt-get update -qq
apt-get install -y --no-install-recommends build-essential cmake perl pkg-config
- name: Install Rust toolchain
run: |
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --profile minimal
echo "$HOME/.cargo/bin" >> "$GITHUB_PATH"
- name: Install Node dependencies
working-directory: node/mq-bridge-node
run: npm ci
- name: Build native addon (full)
working-directory: node/mq-bridge-node
env:
CARGO_NET_RETRY: "5"
CARGO_NET_GIT_FETCH_WITH_CLI: "true"
run: >-
npx napi build --platform --release --strip
--target ${{ matrix.target }}
--js native.js --dts native.d.ts
- name: Upload addon
uses: actions/upload-artifact@v4
with:
name: bindings-${{ matrix.target }}
path: node/mq-bridge-node/*.node
if-no-files-found: error
# The root package ships the generated loader; upload it once.
- name: Upload loader
if: matrix.target == 'x86_64-unknown-linux-gnu'
uses: actions/upload-artifact@v4
with:
name: loader
path: |
node/mq-bridge-node/native.js
node/mq-bridge-node/native.d.ts
if-no-files-found: error
build-native:
name: Build ${{ matrix.target }}
runs-on: ${{ matrix.runner }}
permissions:
contents: read
strategy:
fail-fast: false
matrix:
include:
- runner: macos-15-intel
target: x86_64-apple-darwin
- runner: macos-latest
target: aarch64-apple-darwin
- runner: windows-latest
target: x86_64-pc-windows-msvc
steps:
- uses: actions/checkout@v4
- name: Set up Node
uses: actions/setup-node@v4
with:
node-version: "20"
cache: npm
cache-dependency-path: node/mq-bridge-node/package-lock.json
- name: Install Rust toolchain
uses: dtolnay/rust-toolchain@29eef336d9b2848a0b548edc03f92a220660cdb8 # stable
with:
targets: ${{ matrix.target }}
- name: Install Node dependencies
working-directory: node/mq-bridge-node
run: npm ci
- name: Build native addon (full)
working-directory: node/mq-bridge-node
env:
CARGO_NET_RETRY: "5"
CARGO_NET_GIT_FETCH_WITH_CLI: "true"
run: >-
npx napi build --platform --release --strip
--target ${{ matrix.target }}
--js native.js --dts native.d.ts
- name: Upload addon
uses: actions/upload-artifact@v4
with:
name: bindings-${{ matrix.target }}
path: node/mq-bridge-node/*.node
if-no-files-found: error
publish:
name: Publish to npm
runs-on: ubuntu-latest
needs:
permissions:
contents: read
id-token: write # OIDC trusted publishing + provenance
steps:
- uses: actions/checkout@v4
- name: Set up Node
uses: actions/setup-node@v4
with:
node-version: "20"
registry-url: "https://registry.npmjs.org"
cache: npm
cache-dependency-path: node/mq-bridge-node/package-lock.json
# Trusted publishing (OIDC) requires npm >= 11.5.1.
- name: Update npm
run: npm install -g npm@11.5.1
- name: Install Node dependencies
working-directory: node/mq-bridge-node
run: npm ci
- name: Sync version from Cargo workspace
working-directory: node/mq-bridge-node
run: npm run sync-version
- name: Download loader into package root
uses: actions/download-artifact@v4
with:
name: loader
path: node/mq-bridge-node
- name: Download platform addons
uses: actions/download-artifact@v4
with:
pattern: bindings-*
path: node/mq-bridge-node/artifacts
- name: Create per-platform npm dirs
working-directory: node/mq-bridge-node
run: npx napi create-npm-dirs
- name: Distribute addons into npm dirs
working-directory: node/mq-bridge-node
run: npx napi artifacts -d artifacts
- name: List npm dirs
working-directory: node/mq-bridge-node
run: ls -R npm
- name: Publish platform packages and root
working-directory: node/mq-bridge-node
env:
# Empty when the secret is unset -> npm falls back to OIDC.
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
NPM_CONFIG_PROVENANCE: "true"
run: |
set -e
for dir in npm/*/; do
echo "Publishing $dir"
npm publish "$dir" --access public
done
echo "Publishing root package"
npm publish --access public