@@ -107,7 +107,7 @@ jobs:
107107 done
108108
109109 cd "$platform_dir"
110- zip -r "../../release-artifacts/slim-bindings-${platform_name}.zip" *
110+ zip -r "../../release-artifacts/slim-bindings-${platform_name}.zip" .
111111 cd - > /dev/null
112112
113113 echo "✅ Created slim-bindings-${platform_name}.zip"
@@ -186,7 +186,346 @@ jobs:
186186 nuget-api-token : ${{ secrets.NUGET_API_TOKEN }}
187187
188188 # ==========================================================================
189- # Job 6: Release Kotlin bindings to GitHub Packages
189+ # Job 6: Generate Node bindings once (x86_64 Linux) for use by all pack jobs.
190+ # uniffi-bindgen-node must load the .so on the host; we only have native lib for
191+ # the runner, so we generate once then pack per target with each target's lib.
192+ # ==========================================================================
193+ generate-node-bindings-once :
194+ name : Generate Node bindings (once)
195+ runs-on : ubuntu-latest
196+ needs :
197+ - build-and-test-bindings
198+ steps :
199+ - name : Checkout code
200+ uses : actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
201+ with :
202+ persist-credentials : false
203+
204+ - name : Setup Rust
205+ uses : ./.github/actions/setup-rust
206+ with :
207+ workspace : ./data-plane
208+
209+ - name : Setup Node
210+ uses : actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
211+ with :
212+ node-version : ' 20'
213+ # Release workflow: disable GHA npm cache (zizmor cache-poisoning / trusted tag builds only).
214+ package-manager-cache : false
215+
216+ - name : Setup Task
217+ uses : ./.github/actions/setup-task
218+
219+ - name : Download library artifact (x86_64 Linux)
220+ uses : actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
221+ with :
222+ name : bindings-x86_64-unknown-linux-gnu
223+ path : .
224+
225+ - name : Place library for Node generate
226+ run : |
227+ RELEASE_DIR="data-plane/target/x86_64-unknown-linux-gnu/release"
228+ mkdir -p "$RELEASE_DIR"
229+ if [ -n "$(find "$RELEASE_DIR" -mindepth 1 -print -quit 2>/dev/null)" ]; then
230+ echo "Library files (from artifact path):"
231+ find "$RELEASE_DIR" -maxdepth 1 ! -path "$RELEASE_DIR" -ls
232+ exit 0
233+ fi
234+ find . -name '*slim_bindings*' -type f -exec cp -v {} "$RELEASE_DIR/" \; 2>/dev/null
235+ [ -n "$(find "$RELEASE_DIR" -mindepth 1 -print -quit 2>/dev/null)" ] || { echo "No library files found."; find . -maxdepth 4 -ls 2>/dev/null | head -80; exit 1; }
236+ echo "Library files (copied):"
237+ find "$RELEASE_DIR" -maxdepth 1 ! -path "$RELEASE_DIR" -ls
238+
239+ - name : Generate Node bindings
240+ working-directory : ./data-plane/bindings/node
241+ run : |
242+ npm install
243+ task generate TARGET=x86_64-unknown-linux-gnu
244+
245+ - name : Upload generated bindings
246+ uses : actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
247+ with :
248+ name : node-generated-bindings
249+ path : ./data-plane/bindings/node/generated/
250+
251+ # ==========================================================================
252+ # Job 7: Build Node platform packages (matrix: one per target with .so/.dylib/.dll).
253+ # Uses pre-generated bindings + each target's library (no uniffi-bindgen-node on non-native libs).
254+ # musl excluded: Rust build produces only static .a for musl, no .so.
255+ # ==========================================================================
256+ build-node-packages :
257+ name : Node ${{ matrix.target }}
258+ runs-on : ubuntu-latest
259+ needs :
260+ - build-and-test-bindings
261+ - generate-node-bindings-once
262+ strategy :
263+ fail-fast : false
264+ matrix :
265+ target :
266+ - x86_64-unknown-linux-gnu
267+ - aarch64-apple-darwin
268+ - x86_64-apple-darwin
269+ - x86_64-pc-windows-msvc
270+ - aarch64-unknown-linux-gnu
271+ - aarch64-pc-windows-msvc
272+ steps :
273+ - name : Checkout code
274+ uses : actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
275+ with :
276+ persist-credentials : false
277+
278+ - name : Get bindings version
279+ id : version
280+ run : echo "version=$(bash .github/scripts/get-binding-version.sh)" >> "$GITHUB_OUTPUT"
281+
282+ - name : Setup Node
283+ uses : actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
284+ with :
285+ node-version : ' 20'
286+ package-manager-cache : false
287+
288+ - name : Setup Task
289+ uses : ./.github/actions/setup-task
290+
291+ - name : Download generated bindings
292+ uses : actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
293+ with :
294+ name : node-generated-bindings
295+ path : ./data-plane/bindings/node/generated/
296+
297+ - name : Download library artifact
298+ uses : actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
299+ with :
300+ name : bindings-${{ matrix.target }}
301+ path : .
302+
303+ - name : Place library for Node pack
304+ run : |
305+ RELEASE_DIR="data-plane/target/${{ matrix.target }}/release"
306+ mkdir -p "$RELEASE_DIR"
307+ if [ -n "$(find "$RELEASE_DIR" -mindepth 1 -print -quit 2>/dev/null)" ]; then
308+ echo "Library files (from artifact path):"
309+ find "$RELEASE_DIR" -maxdepth 1 ! -path "$RELEASE_DIR" -ls
310+ exit 0
311+ fi
312+ find . -name '*slim_bindings*' -type f -exec cp -v {} "$RELEASE_DIR/" \; 2>/dev/null
313+ if [ -n "$(find "$RELEASE_DIR" -mindepth 1 -print -quit 2>/dev/null)" ]; then
314+ echo "Library files (copied):"
315+ find "$RELEASE_DIR" -maxdepth 1 ! -path "$RELEASE_DIR" -ls
316+ exit 0
317+ fi
318+ echo "No library files found after download."
319+ find . -maxdepth 4 -ls 2>/dev/null | head -80
320+ exit 1
321+
322+ - name : Pack Node platform package
323+ working-directory : ./data-plane/bindings/node
324+ run : |
325+ npm install
326+ task pack:platform:from-artifacts TARGET=${{ matrix.target }} VERSION=${{ steps.version.outputs.version }}
327+
328+ - name : Upload Node platform package
329+ uses : actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
330+ with :
331+ name : node-platform-${{ matrix.target }}
332+ path : ./data-plane/bindings/node/dist/node-*.tgz
333+
334+ # ==========================================================================
335+ # Job 8: Publish Node platform packages to npm
336+ # ==========================================================================
337+ publish-node-platform-packages :
338+ name : Publish Node platform packages
339+ runs-on : ubuntu-latest
340+ needs : build-node-packages
341+ permissions :
342+ contents : read
343+ steps :
344+ - name : Download all Node platform artifacts
345+ uses : actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
346+ with :
347+ path : ./node-packages
348+ pattern : node-platform-*
349+
350+ - name : Configure npm auth
351+ run : echo "//registry.npmjs.org/:_authToken=${NODE_AUTH_TOKEN}" >> .npmrc
352+ env :
353+ NODE_AUTH_TOKEN : ${{ secrets.NPM_TOKEN }}
354+
355+ - name : Publish to npm
356+ run : |
357+ for tgz in ./node-packages/node-platform-*/*.tgz; do
358+ [ -f "$tgz" ] || continue
359+ echo "Publishing $tgz..."
360+ npm publish "$tgz" --access public
361+ done
362+ env :
363+ NODE_AUTH_TOKEN : ${{ secrets.NPM_TOKEN }}
364+
365+ # ==========================================================================
366+ # Job 9: Publish Node main package to npm
367+ # Uses pre-generated bindings from generate-node-bindings-once; only emits types and publishes.
368+ # ==========================================================================
369+ publish-node-main :
370+ name : Publish Node main package
371+ runs-on : ubuntu-latest
372+ needs :
373+ - publish-node-platform-packages
374+ - generate-node-bindings-once
375+ permissions :
376+ contents : read
377+ steps :
378+ - name : Checkout code
379+ uses : actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
380+ with :
381+ persist-credentials : false
382+
383+ - name : Get bindings version
384+ id : version
385+ run : echo "version=$(bash .github/scripts/get-binding-version.sh)" >> "$GITHUB_OUTPUT"
386+
387+ - name : Setup Node
388+ uses : actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
389+ with :
390+ node-version : ' 20'
391+ package-manager-cache : false
392+
393+ - name : Setup Task
394+ uses : ./.github/actions/setup-task
395+
396+ - name : Download generated bindings
397+ uses : actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
398+ with :
399+ name : node-generated-bindings
400+ path : ./data-plane/bindings/node/generated/
401+
402+ - name : Emit types and prepare package
403+ working-directory : ./data-plane/bindings/node
404+ run : |
405+ npm install
406+ task emit-types
407+
408+ - name : Set version in package.json
409+ working-directory : ./data-plane/bindings/node
410+ env :
411+ BINDINGS_VERSION : ${{ steps.version.outputs.version }}
412+ run : |
413+ npm pkg set version="${BINDINGS_VERSION}"
414+ node -e "
415+ const pkg = require('./package.json');
416+ const v = process.env.BINDINGS_VERSION;
417+ const opt = pkg.optionalDependencies || {};
418+ for (const k of Object.keys(opt)) opt[k] = v;
419+ pkg.optionalDependencies = opt;
420+ require('fs').writeFileSync('package.json', JSON.stringify(pkg, null, 2));
421+ "
422+
423+ - name : Configure npm auth
424+ working-directory : ./data-plane/bindings/node
425+ run : echo "//registry.npmjs.org/:_authToken=${NODE_AUTH_TOKEN}" >> .npmrc
426+ env :
427+ NODE_AUTH_TOKEN : ${{ secrets.NPM_TOKEN }}
428+
429+ - name : Publish main package to npm
430+ working-directory : ./data-plane/bindings/node
431+ run : npm publish --access public
432+ env :
433+ NODE_AUTH_TOKEN : ${{ secrets.NPM_TOKEN }}
434+
435+ # ==========================================================================
436+ # Job 10: Build and publish React Native bindings to npm
437+ # Runs on mac to build iOS static lib; requires NPM_TOKEN.
438+ # ==========================================================================
439+ publish-react-native :
440+ name : Publish React Native to npm
441+ runs-on : macos-15
442+ needs :
443+ - build-and-test-bindings
444+ permissions :
445+ contents : read
446+ steps :
447+ - name : Checkout code
448+ uses : actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
449+ with :
450+ persist-credentials : false
451+
452+ - name : Get bindings version
453+ id : version
454+ run : echo "version=$(bash .github/scripts/get-binding-version.sh)" >> "$GITHUB_OUTPUT"
455+
456+ - name : Setup Rust
457+ uses : ./.github/actions/setup-rust
458+ with :
459+ workspace : ./data-plane
460+
461+ - name : Setup Task
462+ uses : ./.github/actions/setup-task
463+
464+ - name : Setup Node
465+ uses : actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
466+ with :
467+ node-version : ' 20'
468+ registry-url : ' https://registry.npmjs.org'
469+ package-manager-cache : false
470+
471+ - name : Build iOS static libs (device + simulator)
472+ id : build-ios
473+ working-directory : ./data-plane/bindings/react-native
474+ env :
475+ # Required for ___chkstk_darwin: aws-lc-sys and linker need iOS 13.4+
476+ IPHONEOS_DEPLOYMENT_TARGET : " 13.4"
477+ # Force linker wrapper via absolute path (Task's TASKFILE_DIR can differ on CI)
478+ CARGO_TARGET_AARCH64_APPLE_IOS_LINKER : " ${{ github.workspace }}/data-plane/.cargo/clang-ios-linker-wrapper.sh"
479+ CARGO_TARGET_AARCH64_APPLE_IOS_SIM_LINKER : " ${{ github.workspace }}/data-plane/.cargo/clang-ios-linker-wrapper.sh"
480+ run : |
481+ chmod +x "${{ github.workspace }}/data-plane/.cargo/clang-ios-linker-wrapper.sh"
482+ rm -f /tmp/linker-args.log
483+ _sim_sdk="$(xcrun --sdk iphonesimulator --show-sdk-path)"
484+ BINDGEN_EXTRA_CLANG_ARGS="-isysroot ${_sim_sdk} -target arm64-apple-ios15.0-simulator"
485+ export BINDGEN_EXTRA_CLANG_ARGS
486+ task adapter:bindings:build:all TARGET=aarch64-apple-ios-sim PROFILE=release
487+ _ios_sdk="$(xcrun --sdk iphoneos --show-sdk-path)"
488+ BINDGEN_EXTRA_CLANG_ARGS="-isysroot ${_ios_sdk} -target arm64-apple-ios15.0"
489+ export BINDGEN_EXTRA_CLANG_ARGS
490+ task adapter:bindings:build:all TARGET=aarch64-apple-ios PROFILE=release
491+
492+ - name : Vendor iOS libs and create XCFramework
493+ working-directory : ./data-plane/bindings/react-native
494+ run : |
495+ task vendor:ios
496+ task xcframework:ios
497+
498+ - name : Generate bindings
499+ working-directory : ./data-plane/bindings/react-native
500+ env :
501+ CARGO_TARGET_AARCH64_APPLE_IOS_SIM_LINKER : " ${{ github.workspace }}/data-plane/.cargo/clang-ios-linker-wrapper.sh"
502+ IPHONEOS_DEPLOYMENT_TARGET : " 13.4"
503+ run : |
504+ _sim_sdk="$(xcrun --sdk iphonesimulator --show-sdk-path)"
505+ BINDGEN_EXTRA_CLANG_ARGS="-isysroot ${_sim_sdk} -target arm64-apple-ios15.0-simulator"
506+ export BINDGEN_EXTRA_CLANG_ARGS
507+ task generate TARGET=aarch64-apple-ios-sim
508+
509+ - name : Set version in package.json
510+ working-directory : ./data-plane/bindings/react-native
511+ env :
512+ BINDINGS_VERSION : ${{ steps.version.outputs.version }}
513+ run : npm pkg set version="${BINDINGS_VERSION}"
514+
515+ - name : Configure npm auth
516+ working-directory : ./data-plane/bindings/react-native
517+ run : echo "//registry.npmjs.org/:_authToken=${NODE_AUTH_TOKEN}" >> .npmrc
518+ env :
519+ NODE_AUTH_TOKEN : ${{ secrets.NPM_TOKEN }}
520+
521+ - name : Publish to npm
522+ working-directory : ./data-plane/bindings/react-native
523+ run : npm publish --access public
524+ env :
525+ NODE_AUTH_TOKEN : ${{ secrets.NPM_TOKEN }}
526+
527+ # ==========================================================================
528+ # Job 6b: Release Kotlin bindings to GitHub Packages
190529 # ==========================================================================
191530 release-kotlin-bindings :
192531 name : " Release Kotlin Bindings"
0 commit comments