name: Test & Release env: DEBUG: 'napi:*' RUST_BACKTRACE: 1 CARGO_TARGET_AARCH64_UNKNOWN_LINUX_MUSL_LINKER: aarch64-linux-gnu-gcc concurrency: group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true permissions: contents: write id-token: write on: push: branches: - main pull_request: jobs: lint: name: Lint SourceCode runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: Setup node uses: actions/setup-node@v4 with: node-version: 20 cache: 'yarn' - name: Install uses: dtolnay/rust-toolchain@stable with: toolchain: stable components: rustfmt, clippy - name: Cache cargo uses: actions/cache@v4 with: path: | ~/.cargo/registry ~/.cargo/git key: lint-cargo-cache - name: 'Install dependencies' run: yarn install --immutable --mode=skip-build - name: 'Lint JS/TS' run: yarn lint - name: Cargo fmt run: cargo fmt -- --check - name: Clippy run: cargo clippy build_and_test: strategy: fail-fast: false matrix: node: ['18', '20'] settings: - host: ubuntu-latest target: x86_64-unknown-linux-gnu build: yarn build:test test: | yarn test:cli yarn test --verbose yarn tsc -p examples/napi/tsconfig.json --noEmit --skipLibCheck yarn test:macro toolchain: stable - host: ubuntu-latest target: x86_64-unknown-linux-gnu build: yarn build:test test: | yarn test:cli yarn test --verbose yarn tsc -p examples/napi/tsconfig.json --noEmit --skipLibCheck yarn test:macro toolchain: 1.65.0 - host: macos-14 target: x86_64-apple-darwin build: yarn build:test test: | yarn test:cli yarn test --verbose yarn tsc -p examples/napi/tsconfig.json --noEmit --skipLibCheck yarn test:macro toolchain: stable - host: windows-latest target: x86_64-pc-windows-msvc build: yarn build:test test: | yarn test:cli yarn test --verbose yarn tsc -p examples/napi/tsconfig.json --noEmit --skipLibCheck yarn test:macro toolchain: stable - host: windows-latest target: i686-pc-windows-msvc build: | yarn workspace @examples/napi build --target i686-pc-windows-msvc --release yarn workspace @examples/compat-mode build --target i686-pc-windows-msvc --release test: | yarn test --verbose node ./node_modules/electron/install.js yarn test:electron toolchain: stable exclude: - settings: toolchain: 1.65.0 node: 18 - settings: toolchain: 1.65.0 node: 20 - settings: target: i686-pc-windows-msvc node: 18 name: ${{ matrix.settings.host }} - node@${{ matrix.node }} - toolchain@ ${{ matrix.settings.toolchain }} runs-on: ${{ matrix.settings.host }} steps: - uses: actions/checkout@v4 - name: Setup node uses: actions/setup-node@v4 with: node-version: ${{ matrix.node }} cache: 'yarn' - name: Install uses: dtolnay/rust-toolchain@stable with: toolchain: ${{ matrix.settings.toolchain }} targets: ${{ matrix.settings.target }} - name: Cache cargo uses: actions/cache@v4 with: path: | ~/.cargo/registry ~/.cargo/git target key: ${{ matrix.settings.host }}-${{ matrix.settings.toolchain }}-${{ matrix.settings.target }}-cargo-cache - name: 'Install dependencies' shell: bash run: yarn install --mode=skip-build --immutable - name: Check build run: cargo check --target ${{ matrix.settings.target }} --all --bins --examples --tests -vvv - name: Build tests if: matrix.settings.build run: ${{ matrix.settings.build }} - name: Setup node uses: actions/setup-node@v4 if: matrix.settings.target == 'i686-pc-windows-msvc' with: node-version: 20 architecture: 'x86' - name: Unit tests if: matrix.settings.test run: ${{ matrix.settings.test }} - name: Electron tests if: matrix.settings.target == 'x86_64-apple-darwin' || matrix.settings.target == 'x86_64-pc-windows-msvc' run: | node ./node_modules/electron/install.js yarn test:electron - name: Electron tests if: matrix.settings.target == 'x86_64-unknown-linux-gnu' run: | node ./node_modules/electron/install.js xvfb-run --auto-servernum yarn test:electron - name: Test build with profile run: yarn workspace @examples/napi build --profile napi-rs-custom build_only: name: Build only test - ${{ matrix.settings.target }} runs-on: ${{ matrix.settings.host }} strategy: fail-fast: false matrix: settings: - host: ubuntu-latest target: aarch64-linux-android - host: ubuntu-latest target: armv7-linux-androideabi - host: ubuntu-latest target: riscv64gc-unknown-linux-gnu setup: | sudo apt-get update sudo apt-get install -y gcc-riscv64-linux-gnu - host: windows-latest target: aarch64-pc-windows-msvc steps: - uses: actions/checkout@v4 - name: Setup node uses: actions/setup-node@v4 with: node-version: 20 cache: 'yarn' - name: Install uses: dtolnay/rust-toolchain@stable with: toolchain: stable targets: ${{ matrix.settings.target }} - name: Cache cargo uses: actions/cache@v4 with: path: | ~/.cargo/registry ~/.cargo/git target key: stable-${{ matrix.settings.host }}-${{ matrix.settings.target }}-cargo-cache - name: Setup toolchain if: matrix.settings.setup run: ${{ matrix.settings.setup }} - name: Install dependencies run: yarn install --immutable --mode=skip-build - name: Cross build native tests run: yarn build:test -- --target ${{ matrix.settings.target }} --release shell: bash build_for_test_in_docker: name: build - ${{ matrix.settings.target }} runs-on: ubuntu-latest strategy: fail-fast: false matrix: settings: - target: powerpc64le-unknown-linux-gnu setup: | sudo apt-get update sudo apt-get install -y gcc-powerpc64le-linux-gnu - target: s390x-unknown-linux-gnu setup: | sudo apt-get update sudo apt-get install -y gcc-s390x-linux-gnu steps: - uses: actions/checkout@v4 - name: Setup node uses: actions/setup-node@v4 with: node-version: 20 cache: 'yarn' - name: Install uses: dtolnay/rust-toolchain@stable with: toolchain: stable targets: ${{ matrix.settings.target }} - name: Cache cargo uses: actions/cache@v4 with: path: | ~/.cargo/registry ~/.cargo/git target key: stable-ubuntu-latest-${{ matrix.settings.target }}-cargo-cache - name: Setup toolchain run: ${{ matrix.settings.setup }} - name: Install dependencies run: yarn install --immutable --mode=skip-build - name: Cross build native tests run: yarn build:test -- --target ${{ matrix.settings.target }} --release shell: bash - uses: actions/upload-artifact@v4 with: name: ${{ matrix.settings.target }}-example path: examples/napi/*.node - uses: actions/upload-artifact@v4 with: name: ${{ matrix.settings.target }}-example-compat path: examples/napi-compat-mode/index.node build_in_docker: name: build - ${{ matrix.settings.target }} runs-on: ubuntu-latest strategy: fail-fast: false matrix: settings: - image: ghcr.io/napi-rs/napi-rs/nodejs-rust:lts-alpine target: x86_64-unknown-linux-musl libc: 'musl' arch: 'x64' - image: ghcr.io/napi-rs/napi-rs/nodejs-rust:lts-alpine target: aarch64-unknown-linux-musl - image: ghcr.io/napi-rs/napi-rs/nodejs-rust:lts-debian-aarch64 target: aarch64-unknown-linux-gnu arch: 'arm64' libc: 'gnu' - image: ghcr.io/napi-rs/napi-rs/nodejs-rust:lts-debian target: x86_64-unknown-linux-gnu steps: - uses: actions/checkout@v4 - name: Setup node uses: actions/setup-node@v4 with: node-version: 20 cache: 'yarn' - name: Install dependencies run: | yarn config set supportedArchitectures.cpu --json '["x64", "arm64"]' yarn config set supportedArchitectures.libc --json '["musl", "glibc"]' yarn install --immutable --mode=skip-build - name: Cache cargo uses: actions/cache@v4 with: path: | .cargo-cache/registry .cargo-cache/git target key: stable-${{ matrix.settings.target }}-cargo-cache - name: Cross build native tests uses: addnab/docker-run-action@v3 with: image: ${{ matrix.settings.image }} options: -v ${{ github.workspace }}/.cargo-cache/registry:/usr/local/cargo/registry -v ${{ github.workspace }}/.cargo-cache/git:/usr/local/cargo/git -v ${{ github.workspace }}:/napi-rs -w /napi-rs run: | yarn build:test -- --target ${{ matrix.settings.target }} chmod 777 -R .cargo-cache chmod 777 -R target - uses: actions/upload-artifact@v4 with: name: ${{ matrix.settings.target }}-example path: examples/napi/*.node - uses: actions/upload-artifact@v4 with: name: ${{ matrix.settings.target }}-example-compat path: examples/napi-compat-mode/index.node test_in_docker: name: Test - ${{ matrix.settings.target }} - ${{ matrix.node }} runs-on: ubuntu-latest needs: - build_in_docker - build_for_test_in_docker strategy: fail-fast: false matrix: node: [18, 20] settings: - image: 'node:{:version}-slim' target: x86_64-unknown-linux-gnu args: '' arch: 'x64' libc: 'gnu' - image: 'node:{:version}-slim' target: aarch64-unknown-linux-gnu args: '--platform linux/arm64' arch: 'arm64' libc: 'gnu' - image: 'node:{:version}-slim' target: powerpc64le-unknown-linux-gnu args: '--platform linux/ppc64le' arch: 'ppc64' libc: 'gnu' without-lerna: true - image: 'node:{:version}-slim' target: s390x-unknown-linux-gnu args: '--platform linux/s390x' arch: 's390x' libc: 'gnu' without-lerna: true - image: 'node:{:version}-alpine' target: x86_64-unknown-linux-musl args: '' arch: 'x64' libc: 'musl' - image: 'node:{:version}-alpine' target: aarch64-unknown-linux-musl args: '--platform linux/arm64' arch: 'arm64' libc: 'musl' steps: - uses: actions/checkout@v4 - name: Setup node uses: actions/setup-node@v4 with: node-version: 20 cache: 'yarn' - uses: actions/download-artifact@v4 with: name: ${{ matrix.settings.target }}-example path: examples/napi/ - uses: actions/download-artifact@v4 with: name: ${{ matrix.settings.target }}-example-compat path: examples/napi-compat-mode/index.node - name: Install dependencies run: | yarn config set --json supportedArchitectures.cpu '["current", "${{ matrix.settings.arch }}"]' yarn config set --json supportedArchitectures.libc '["current", "${{ matrix.settings.libc }}"]' yarn install --immutable --mode=skip-build - name: Set up QEMU uses: docker/setup-qemu-action@v3 with: platforms: all - run: docker run --rm --privileged multiarch/qemu-user-static --reset -p yes - name: Setup image name id: image-name run: | node -e "console.info('docker-image=${{ matrix.settings.image }}'.replace('{:version}', ${{ matrix.node }}))" >> "$GITHUB_OUTPUT" - name: Setup and run tests uses: addnab/docker-run-action@v3 with: image: ${{ steps.image-name.outputs.docker-image }} options: ${{ matrix.settings.args }} -v ${{ github.workspace }}/cores:/cores -v ${{ github.workspace }}:/build -w /build run: >- ${{ matrix.settings.without-lerna && 'yarn test:without-lerna' || 'yarn test' }} - name: List files run: | ls -la . ls -la ./cores build-and-test-linux-armv7: name: stable - armv7-unknown-linux-gnueabihf - node@20 runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: Setup node uses: actions/setup-node@v4 with: node-version: 20 cache: 'yarn' - name: Install uses: dtolnay/rust-toolchain@stable with: toolchain: stable targets: armv7-unknown-linux-gnueabihf - name: Cache cargo uses: actions/cache@v4 with: path: | ~/.cargo/registry ~/.cargo/git target key: stable-linux-armv7-gnueabihf-node@20-cargo-cache - name: Install dependencies run: | yarn config set --json supportedArchitectures.cpu '["arm", "current"]' yarn install --immutable --mode=skip-build - name: Cross build native tests run: yarn build:test -- --target armv7-unknown-linux-gnueabihf --use-napi-cross - run: docker run --rm --privileged multiarch/qemu-user-static --reset -p yes - name: Setup and run tests uses: addnab/docker-run-action@v3 with: image: node:lts-slim options: --platform linux/arm/v7 -v ${{ github.workspace }}:/build -w /build run: yarn test build_binary_crate: runs-on: ubuntu-latest name: Test cli build binary steps: - uses: actions/checkout@v4 - name: Setup node uses: actions/setup-node@v4 with: node-version: 20 cache: 'yarn' - name: Install uses: dtolnay/rust-toolchain@stable with: toolchain: stable - name: Cache cargo uses: actions/cache@v4 with: path: | ~/.cargo/registry ~/.cargo/git target key: stable-cargo-cache-build-binary - name: 'Install dependencies' run: yarn install --mode=skip-build --immutable - name: Build and run binary run: | yarn workspace binary build ./examples/binary/napi-examples-binary yarn workspace binary build --profile napi-rs-custom check-all-features: strategy: fail-fast: false matrix: settings: - features: 'napi1,napi2,napi3,napi4,napi5,napi6,napi7,napi8,experimental,async,chrono_date,latin1,full' package: 'napi' - features: 'compat-mode,strict,type-def,noop,full,default' package: 'napi-derive' name: stable - ubuntu-latest runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: Install uses: dtolnay/rust-toolchain@stable with: toolchain: stable - name: Check build run: cargo check -p ${{ matrix.settings.package }} -F ${{ matrix.settings.features }} test-node-wasi: runs-on: macos-14 name: Test node wasi target timeout-minutes: 10 steps: - uses: actions/checkout@v4 - name: Setup node uses: actions/setup-node@v4 with: node-version: 20 cache: 'yarn' - name: Install uses: dtolnay/rust-toolchain@stable with: toolchain: stable targets: wasm32-wasi-preview1-threads - name: Cache cargo uses: actions/cache@v4 with: path: | ~/.cargo/registry ~/.cargo/git target key: stable-wasm32-wasi-preview1-threads-node@20-cargo-cache - name: Install dependencies run: yarn install --immutable --mode=skip-build - name: Build run: | yarn build yarn workspace @examples/napi build --target wasm32-wasi-preview1-threads --release - name: Test run: yarn workspace @examples/napi test -s env: WASI_TEST: 'true' NODE_OPTIONS: '--max-old-space-size=8192' - name: Browser test run: yarn workspace @examples/napi vitest test-latest-bun: runs-on: ubuntu-latest name: Test latest bun timeout-minutes: 10 steps: - uses: actions/checkout@v4 - uses: oven-sh/setup-bun@v1 with: bun-version: latest - name: Setup node uses: actions/setup-node@v4 with: node-version: 20 cache: 'yarn' - name: Install uses: dtolnay/rust-toolchain@stable with: toolchain: stable targets: x86_64-unknown-linux-gnu - name: Cache cargo uses: actions/cache@v4 with: path: | ~/.cargo/registry ~/.cargo/git target key: stable-x86_64-unknown-linux-gnu-node@18-cargo-cache - name: Install dependencies run: yarn install --immutable --mode=skip-build - name: Build run: | bun run build yarn workspace @examples/napi build --features dyn-symbols - name: Test continue-on-error: true run: bun run test:bun release-npm: runs-on: ubuntu-latest needs: - lint - build_binary_crate if: "startsWith(github.event.head_commit.message, 'chore(release): publish')" steps: - uses: actions/checkout@v4 - uses: actions/setup-node@v4 with: node-version: 20 cache: 'yarn' - name: Publish run: | yarn install --mode=skip-build yarn build npm config set provenance true echo "//registry.npmjs.org/:_authToken=$NPM_TOKEN" >> ~/.npmrc yarn lerna publish from-package --pre-dist-tag canary --yes env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} NPM_TOKEN: ${{ secrets.NPM_TOKEN }}