fix: fall back to musl binary when gnu prebuild fails to load #18
Workflow file for this run
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: CI | |
| on: | |
| pull_request: | |
| workflow_call: | |
| permissions: | |
| contents: read | |
| concurrency: | |
| group: ${{ github.workflow }}-${{ github.ref }} | |
| cancel-in-progress: true | |
| env: | |
| CARGO_TERM_COLOR: always | |
| jobs: | |
| test: | |
| name: ${{ matrix.os }} | |
| runs-on: ${{ matrix.os }} | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| os: [ubuntu-latest, macos-latest, windows-latest] | |
| steps: | |
| - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 | |
| with: | |
| persist-credentials: false | |
| - uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0 | |
| with: | |
| node-version-file: .nvmrc | |
| cache: yarn | |
| # Rust (stable + clippy) is preinstalled on the hosted runner images. | |
| - uses: Swatinem/rust-cache@c19371144df3bb44fab255c43d04cbc2ab54d1c4 # v2.9.1 | |
| - run: yarn install --immutable | |
| - run: yarn build | |
| - run: yarn test | |
| - run: cargo test --release | |
| - run: cargo clippy --release -- -D warnings | |
| audit: | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 | |
| with: | |
| persist-credentials: false | |
| - uses: rustsec/audit-check@69366f33c96575abad1ee0dba8212993eecbe998 # v2.0.0 | |
| with: | |
| token: ${{ secrets.GITHUB_TOKEN }} | |
| # Build every prebuild target the released package ships. Running this on | |
| # PRs (not just on main) means a broken target is caught before merge; the | |
| # Release workflow reuses these same jobs (via workflow_call) and publishes | |
| # the artifacts they upload. | |
| build: | |
| name: ${{ matrix.name }} | |
| runs-on: ${{ matrix.os }} | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| include: | |
| # ── macOS: build both arches, lipo to universal ─────────────────── | |
| - name: darwin-universal | |
| os: macos-latest | |
| build: | | |
| rustup target add x86_64-apple-darwin | |
| yarn napi build --platform --release --esm --output-dir . --target aarch64-apple-darwin --js binding.js --dts binding.d.ts | |
| yarn napi build --platform --release --esm --output-dir . --target x86_64-apple-darwin --js binding.js --dts binding.d.ts | |
| yarn napi universalize --output-dir . | |
| artifact: index.darwin-universal.node | |
| # ── Windows ─────────────────────────────────────────────────────── | |
| - name: win32-x64 | |
| os: windows-latest | |
| build: yarn napi build --platform --release --esm --output-dir . --target x86_64-pc-windows-msvc --js binding.js --dts binding.d.ts | |
| artifact: index.win32-x64-msvc.node | |
| - name: win32-arm64 | |
| os: windows-latest | |
| build: | | |
| rustup target add aarch64-pc-windows-msvc | |
| yarn napi build --platform --release --esm --output-dir . --target aarch64-pc-windows-msvc --js binding.js --dts binding.d.ts | |
| artifact: index.win32-arm64-msvc.node | |
| # ── Linux glibc (native runners for each arch) ──────────────────── | |
| - name: linux-x64-gnu | |
| os: ubuntu-latest | |
| build: yarn napi build --platform --release --esm --output-dir . --target x86_64-unknown-linux-gnu --js binding.js --dts binding.d.ts | |
| artifact: index.linux-x64-gnu.node | |
| - name: linux-arm64-gnu | |
| os: ubuntu-24.04-arm | |
| build: yarn napi build --platform --release --esm --output-dir . --target aarch64-unknown-linux-gnu --js binding.js --dts binding.d.ts | |
| artifact: index.linux-arm64-gnu.node | |
| # ── Linux musl (Alpine via docker run on native-arch runners) ───── | |
| # Job containers can't be used here: the runner refuses to exec JS | |
| # actions (checkout, upload-artifact, ...) inside Alpine containers | |
| # on arm64 hosts (actions/runner#801), so the "Build (docker)" step | |
| # runs the whole alpine build via `docker run` instead. Rust comes | |
| # from a version-pinned, checksum-verified rustup-init. | |
| - name: linux-x64-musl | |
| os: ubuntu-latest | |
| docker: node:22-alpine@sha256:968df39aedcea65eeb078fb336ed7191baf48f972b4479711397108be0966920 | |
| rustup_url: https://static.rust-lang.org/rustup/archive/1.29.0/x86_64-unknown-linux-musl/rustup-init | |
| rustup_sha256: 9cd3fda5fd293890e36ab271af6a786ee22084b5f6c2b83fd8323cec6f0992c1 | |
| build: | | |
| rustup target add x86_64-unknown-linux-musl | |
| yarn napi build --platform --release --esm --output-dir . --target x86_64-unknown-linux-musl --js binding.js --dts binding.d.ts | |
| artifact: index.linux-x64-musl.node | |
| - name: linux-arm64-musl | |
| os: ubuntu-24.04-arm | |
| docker: node:22-alpine@sha256:968df39aedcea65eeb078fb336ed7191baf48f972b4479711397108be0966920 | |
| rustup_url: https://static.rust-lang.org/rustup/archive/1.29.0/aarch64-unknown-linux-musl/rustup-init | |
| rustup_sha256: 88761caacddb92cd79b0b1f939f3990ba1997d701a38b3e8dd6746a562f2a759 | |
| build: | | |
| # napi assumes aarch64-musl is cross-compiled and would default the | |
| # linker to aarch64-linux-musl-gcc; here gcc IS the native musl gcc. | |
| export CARGO_TARGET_AARCH64_UNKNOWN_LINUX_MUSL_LINKER=gcc | |
| rustup target add aarch64-unknown-linux-musl | |
| yarn napi build --platform --release --esm --output-dir . --target aarch64-unknown-linux-musl --js binding.js --dts binding.d.ts | |
| artifact: index.linux-arm64-musl.node | |
| # ── Linux 32-bit (cross-compiled) ───────────────────────────────── | |
| # Old release lines (e.g. Electron's armv7l / linux-ia32 builds) still | |
| # install this package, so keep shipping 32-bit prebuilds. There are no | |
| # native 32-bit runners, so these are cross-compiled and flagged | |
| # `cross: true` to skip the smoke test below (the host's 64-bit node | |
| # can't load a 32-bit .node). | |
| - name: linux-ia32-gnu | |
| os: ubuntu-latest | |
| cross: true | |
| # i686 isn't in @napi-rs/cross-toolchain, but an x86_64 host can target | |
| # it directly with gcc-multilib (gcc -m32), which also builds zlib-ng. | |
| build: | | |
| sudo apt-get update | |
| sudo apt-get install -y gcc-multilib g++-multilib | |
| rustup target add i686-unknown-linux-gnu | |
| yarn napi build --platform --release --esm --output-dir . --target i686-unknown-linux-gnu --js binding.js --dts binding.d.ts | |
| artifact: index.linux-ia32-gnu.node | |
| - name: linux-arm-gnueabihf | |
| os: ubuntu-latest | |
| cross: true | |
| # --use-napi-cross pulls @napi-rs/cross-toolchain and wires up the | |
| # armv7 linker / CC / sysroot (used to cross-compile zlib-ng too). | |
| build: | | |
| rustup target add armv7-unknown-linux-gnueabihf | |
| yarn napi build --platform --release --esm --output-dir . --target armv7-unknown-linux-gnueabihf --use-napi-cross --js binding.js --dts binding.d.ts | |
| artifact: index.linux-arm-gnueabihf.node | |
| steps: | |
| - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 | |
| with: | |
| persist-credentials: false | |
| - uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0 | |
| with: | |
| node-version-file: .nvmrc | |
| cache: yarn | |
| package-manager-cache: ${{ github.ref != 'refs/heads/main' }} | |
| # Rust (stable) is preinstalled on the hosted runner images; the alpine | |
| # docker builds install their own pinned rustup in "Build (docker)". | |
| - uses: Swatinem/rust-cache@c19371144df3bb44fab255c43d04cbc2ab54d1c4 # v2.9.1 | |
| with: | |
| key: ${{ matrix.name }} | |
| - run: yarn install --immutable | |
| - name: Build | |
| if: ${{ !matrix.docker }} | |
| shell: bash | |
| run: ${{ matrix.build }} | |
| # Everything that the other entries do across separate steps — alpine | |
| # deps, Rust, yarn install, build, strip, smoke test — has to happen | |
| # inside the container here, since the host can't run musl binaries. | |
| - name: Build (docker) | |
| if: matrix.docker | |
| run: | | |
| docker run --rm -v "$PWD:/build" -w /build "${{ matrix.docker }}" sh -ec ' | |
| apk add --no-cache bash curl build-base cmake python3 git | |
| curl --proto "=https" --tlsv1.2 -fsSL -o /tmp/rustup-init "${{ matrix.rustup_url }}" | |
| echo "${{ matrix.rustup_sha256 }} /tmp/rustup-init" | sha256sum -c - | |
| chmod +x /tmp/rustup-init | |
| /tmp/rustup-init -y --profile minimal --default-toolchain stable | |
| export PATH="$HOME/.cargo/bin:$PATH" | |
| yarn install --immutable | |
| ${{ matrix.build }} | |
| node scripts/strip-binding-fallbacks.js | |
| yarn test | |
| ' | |
| sudo chown -R "$(id -u):$(id -g)" . | |
| - name: Strip binding.js package fallbacks | |
| run: node scripts/strip-binding-fallbacks.js | |
| - name: Smoke test (native targets only) | |
| if: ${{ !matrix.docker && !matrix.cross && (!contains(matrix.name, 'arm64') || contains(matrix.os, 'arm') || matrix.os == 'macos-latest') }} | |
| run: yarn test | |
| - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 | |
| with: | |
| name: ${{ matrix.name }} | |
| path: ${{ matrix.artifact }} | |
| if-no-files-found: error | |
| # binding.js / binding.d.ts are gitignored; ship one canonical copy from | |
| # this job for the release step to pick up. | |
| - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 | |
| if: matrix.name == 'linux-x64-gnu' | |
| with: | |
| name: binding | |
| path: | | |
| binding.js | |
| binding.d.ts | |
| if-no-files-found: error |