1+ name : Publish to npm
2+
3+ on :
4+ push :
5+ tags :
6+ - ' [0-9]+.[0-9]+.[0-9]+'
7+
8+ env :
9+ CARGO_TERM_COLOR : always
10+ RUST_BACKTRACE : 1
11+ DEBUG : napi:*
12+
13+ permissions :
14+ id-token : write
15+ contents : read
16+
17+ jobs :
18+ build-native :
19+ name : Build native (${{ matrix.target }})
20+ runs-on : ${{ matrix.runner }}
21+ strategy :
22+ fail-fast : false
23+ matrix :
24+ include :
25+ - target : x86_64-unknown-linux-gnu
26+ runner : ubuntu-latest
27+ toolchain : stable
28+ features : x86_set
29+ - target : aarch64-unknown-linux-gnu
30+ runner : ubuntu-24.04-arm
31+ toolchain : nightly
32+ features : aarch64_set
33+ - target : aarch64-apple-darwin
34+ runner : macos-14
35+ toolchain : nightly
36+ features : aarch64_set
37+ - target : x86_64-pc-windows-msvc
38+ runner : windows-latest
39+ toolchain : stable
40+ features : x86_set
41+
42+ steps :
43+ - uses : actions/checkout@v6
44+
45+ - uses : dtolnay/rust-toolchain@stable
46+ with :
47+ targets : ${{ matrix.target }}
48+ toolchain : ${{ matrix.toolchain }}
49+
50+ - uses : actions/setup-node@v6
51+ with :
52+ node-version : ' 22'
53+
54+ - name : Install @napi-rs/cli
55+ run : npm install -g @napi-rs/cli
56+
57+ - name : Install cross-compilation tools (Linux aarch64)
58+ if : matrix.target == 'aarch64-unknown-linux-gnu'
59+ run : |
60+ sudo apt-get update
61+ sudo apt-get install -y \
62+ gcc-aarch64-linux-gnu \
63+ g++-aarch64-linux-gnu \
64+ binutils-aarch64-linux-gnu
65+
66+ - name : Cache vcpkg MD
67+ if : matrix.runner == 'windows-latest'
68+ uses : actions/cache@v4
69+ with :
70+ path : C:\vcpkg\installed
71+ key : vcpkg-x64-windows-static-md-${{ hashFiles('**/Cargo.lock') }}
72+ restore-keys : vcpkg-x64-windows-static-md-
73+
74+ - name : Install dependencies (Windows)
75+ if : matrix.runner == 'windows-latest'
76+ shell : powershell
77+ run : |
78+ vcpkg integrate install
79+ vcpkg install `
80+ libheif:x64-windows-static-md `
81+ libjpeg-turbo:x64-windows-static-md `
82+ libpng:x64-windows-static-md `
83+ zlib:x64-windows-static-md `
84+ aom:x64-windows-static-md `
85+ dav1d:x64-windows-static-md `
86+ libde265:x64-windows-static-md `
87+ x265:x64-windows-static-md
88+
89+ - name : Cache Cargo registry + build
90+ uses : actions/cache@v4
91+ if : matrix.runner == 'windows-latest'
92+ with :
93+ path : |
94+ ~/.cargo/registry/index
95+ ~/.cargo/registry/cache
96+ ~/.cargo/git/db
97+ target/
98+ key : cargo-${{ matrix.target }}-${{ matrix.toolchain }}-${{ hashFiles('**/Cargo.lock') }}
99+ restore-keys : |
100+ cargo-${{ matrix.target }}-${{ matrix.toolchain }}-
101+ cargo-${{ matrix.target }}-
102+
103+ - name : Build native addon
104+ working-directory : pic-scale-js
105+ env :
106+ VCPKG_ROOT : ${{ matrix.runner == 'windows-latest' && 'C:\vcpkg' || '' }}
107+ VCPKG_TARGET_TRIPLET : ${{ matrix.runner == 'windows-latest' && 'x64-windows-static' || '' }}
108+ run : |
109+ napi build --release --target ${{ matrix.target }} --features "napi,${{ matrix.features }}" --output-dir dist/
110+
111+ - uses : actions/upload-artifact@v6
112+ with :
113+ name : native-${{ matrix.target }}
114+ path : pic-scale-js/dist/*.node
115+ retention-days : 1
116+
117+ build-wasm :
118+ name : Build WASM
119+ runs-on : ubuntu-latest
120+ steps :
121+ - uses : actions/checkout@v6
122+
123+ - uses : dtolnay/rust-toolchain@stable
124+ with :
125+ targets : wasm32-unknown-unknown
126+
127+ - name : Install wasm-pack
128+ run : curl https://rustwasm.github.io/wasm-pack/installer/init.sh -sSf | sh
129+
130+ - name : Build (bundler)
131+ working-directory : pic-scale-js
132+ run : |
133+ RUSTFLAGS="-C target-feature=+simd128" \
134+ wasm-pack build --release --target bundler \
135+ --out-dir wasm-pkg/bundler \
136+ --features wasm
137+
138+ - name : Build (web)
139+ working-directory : pic-scale-js
140+ run : |
141+ RUSTFLAGS="-C target-feature=+simd128" \
142+ wasm-pack build --release --target web \
143+ --out-dir wasm-pkg/web \
144+ --features wasm
145+
146+ - name : Build (nodejs)
147+ working-directory : pic-scale-js
148+ run : |
149+ RUSTFLAGS="-C target-feature=+simd128" \
150+ wasm-pack build --release --target nodejs \
151+ --out-dir wasm-pkg/nodejs \
152+ --features wasm
153+
154+ - uses : actions/upload-artifact@v6
155+ with :
156+ name : wasm-pkg
157+ path : pic-scale-js/wasm-pkg/
158+ retention-days : 1
159+
160+ publish :
161+ name : Publish to npm
162+ needs : [ build-native, build-wasm ]
163+ runs-on : ubuntu-latest
164+ if : ${{ startsWith(github.ref, 'refs/tags/') || github.event_name == 'workflow_dispatch' }}
165+ environment : Cargo
166+ permissions :
167+ contents : read
168+ id-token : write
169+
170+ steps :
171+ - uses : actions/checkout@v6
172+
173+ - uses : actions/setup-node@v6
174+ with :
175+ node-version : ' 22'
176+ registry-url : ' https://registry.npmjs.org'
177+
178+ # Required for OIDC trusted publishing
179+ - name : Install dependencies
180+ run : npm install && npm ci
181+
182+ - name : Download all artifacts
183+ uses : actions/download-artifact@v6
184+ with :
185+ path : artifacts/
186+
187+ - name : Extract version from Cargo.toml
188+ id : version
189+ run : |
190+ VERSION=$(grep '^version' Cargo.toml | head -1 | sed 's/version = "\(.*\)"/\1/')
191+ echo "version=$VERSION" >> $GITHUB_OUTPUT
192+
193+ - name : Assemble dist/
194+ run : |
195+ VERSION="${{ steps.version.outputs.version }}"
196+ mkdir -p dist/wasm
197+
198+ # ── native .node files ──────────────────────────────────────────────
199+ # napi-rs CLI generates index.js / index.d.ts / index.mjs that load
200+ # the right platform binary at runtime. Copy everything it produced.
201+ cp artifacts/native-*/*.node dist/
202+
203+ # ── WASM bundle ─────────────────────────────────────────────────────
204+ # Use the bundler build as the default WASM target (vite/webpack).
205+ rsync -a --exclude='package.json' --exclude='.gitignore' \
206+ artifacts/wasm-pkg/bundler/ dist/wasm/bundler/
207+ rsync -a --exclude='package.json' --exclude='.gitignore' \
208+ artifacts/wasm-pkg/web/ dist/wasm/web/
209+ rsync -a --exclude='package.json' --exclude='.gitignore' \
210+ artifacts/wasm-pkg/nodejs/ dist/wasm/nodejs/
211+
212+ if [ -f dist/wasm/nodejs/pic_scale_node.js ]; then
213+ mv dist/wasm/nodejs/pic_scale_node.js dist/wasm/nodejs/pic_scale_node.cjs
214+ mv dist/wasm/nodejs/pic_scale_node_bg.js dist/wasm/nodejs/pic_scale_node_bg.cjs
215+ sed -i "s|require('./pic_scale_node_bg.js')|require('./pic_scale_node_bg.cjs')|g" \
216+ dist/wasm/nodejs/pic_scale_node.cjs
217+ fi
218+
219+ # ── loader files (generated by napi build) ──────────────────────────
220+ # napi build --output-dir dist/ already wrote index.js/mjs/d.ts there.
221+ # If not present, generate them now.
222+ if [ ! -f dist/index.js ]; then
223+ npx @napi-rs/cli artifacts --dist dist/
224+ fi
225+
226+ cp pic-scale-js/README.md dist/README.md
227+
228+ # Stamp version into package.json
229+ sed "s/\"version\": \"[^\"]*\"/\"version\": \"$VERSION\"/" \
230+ package.json > dist/package.json
231+ jq 'del(.devDependencies)' dist/package.json \
232+ > dist/package.tmp && mv dist/package.tmp dist/package.json
233+
234+ - name : Publish dist/
235+ run : npm publish dist/ --provenance --access public
0 commit comments