Skip to content

Update version to 0.27.5. #44

Update version to 0.27.5.

Update version to 0.27.5. #44

Workflow file for this run

name: Release NPM
# Publishes the napi binding `@net-mesh/core` to npm. The
# pure-TypeScript SDK `@net-mesh/sdk` ships via
# `release-npm-sdk.yml`.
#
# Tag schema: `node-v<semver>`.
#
# Required repository secret: `NPM_TOKEN`
# `Automation` token type so 2FA doesn't block CI publishes.
on:
push:
tags:
- "node-v*"
workflow_dispatch:
env:
CARGO_TERM_COLOR: always
jobs:
build:
strategy:
fail-fast: false
matrix:
include:
- os: ubuntu-latest
target: x86_64-unknown-linux-gnu
- os: ubuntu-latest
target: x86_64-unknown-linux-musl
- os: ubuntu-latest
target: aarch64-unknown-linux-gnu
- os: ubuntu-latest
target: aarch64-unknown-linux-musl
- os: macos-latest
target: x86_64-apple-darwin
- os: macos-latest
target: aarch64-apple-darwin
- os: windows-latest
target: x86_64-pc-windows-msvc
- os: windows-latest
target: aarch64-pc-windows-msvc
runs-on: ${{ matrix.os }}
defaults:
run:
working-directory: net/crates/net/bindings/node
steps:
- uses: actions/checkout@v6
- name: Setup Node.js
uses: actions/setup-node@v6
with:
node-version: "24"
registry-url: "https://registry.npmjs.org"
- name: Install Rust
uses: dtolnay/rust-toolchain@stable
with:
targets: ${{ matrix.target }}
# `crates/net/rust-toolchain.toml` pins the cargo invocation
# to 1.95.0 with profile=minimal. The `dtolnay/rust-toolchain`
# step above installed stable + this target on stable, but
# cargo auto-switches to 1.95.0 once it enters `crates/net/`
# and that pinned toolchain doesn't carry the cross-compile
# target — `rustc` then errors with "can't find crate for
# core". Adding the target inside the pinned-toolchain dir
# forwards rustup's target-add to the pinned channel.
- name: Add target to pinned toolchain
working-directory: net/crates/net
run: rustup target add ${{ matrix.target }}
- name: Install cross-compilation tools (aarch64-linux-gnu)
if: matrix.target == 'aarch64-unknown-linux-gnu'
run: |
sudo apt-get update
sudo apt-get install -y gcc-aarch64-linux-gnu
# Pin the linker via BOTH `.cargo/config.toml` AND
# `CARGO_TARGET_*_LINKER`. Rust 1.95 defaults to a
# `gnu-cc` linker flavor that drives `cc -fuse-ld=lld`
# and pulls the HOST x86_64 sysroot's `gcc-ld` —
# producing "elf64-x86-64 incompatible with elf64-aarch64"
# errors. The env-var-only attempt didn't override that
# path (rust 1.95's flavor selection ignores it for some
# cross targets); the on-disk `[target.X] linker = ...`
# config.toml entry does.
mkdir -p "$HOME/.cargo"
cat >> "$HOME/.cargo/config.toml" <<'EOF'
[target.aarch64-unknown-linux-gnu]
linker = "aarch64-linux-gnu-gcc"
EOF
echo "CARGO_TARGET_AARCH64_UNKNOWN_LINUX_GNU_LINKER=aarch64-linux-gnu-gcc" >> "$GITHUB_ENV"
# Cross-compile to musl via Zig. Zig ships a fully-functional
# C cross-compiler with built-in support for every musl target
# (`zig cc -target <arch>-linux-musl`), so we don't need a
# prebuilt `<arch>-linux-musl-gcc` binary on PATH. cc-rs and
# cargo's linker can only point at a single binary (no args),
# so we write a tiny wrapper script that exec's zig with the
# right `-target` flag, then point the cross-build env vars
# at it. This is the same pattern `cargo-zigbuild` uses
# under the hood — without bringing the extra crate in.
- name: Install zig (musl cross compiler)
if: contains(matrix.target, 'musl')
uses: goto-bus-stop/setup-zig@v2
- name: Wrap zig as the musl cross-compiler
if: contains(matrix.target, 'musl')
shell: bash
run: |
case "${{ matrix.target }}" in
x86_64-unknown-linux-musl)
ZIG_TARGET=x86_64-linux-musl
ENV_TGT=x86_64_unknown_linux_musl
;;
aarch64-unknown-linux-musl)
ZIG_TARGET=aarch64-linux-musl
ENV_TGT=aarch64_unknown_linux_musl
;;
*)
echo "Unexpected musl target: ${{ matrix.target }}" >&2
exit 1
;;
esac
WRAPPER="$HOME/zig-cc-${ZIG_TARGET}.sh"
# cc-rs appends `--target=<rustc-triple>` (with the
# `unknown` vendor tag) to every C/asm compile invocation.
# Zig's `cc` parses `--target=` as a clang-style target
# query and rejects `x86_64-unknown-linux-musl` because
# `unknown-linux-musl` isn't a valid OS+abi pair in
# zig's parser. Strip it — our own `-target` flag below
# already pins the cross target in zig's native format.
cat > "$WRAPPER" <<EOF
#!/bin/bash
args=()
for arg in "\$@"; do
case "\$arg" in
--target=*) ;;
*) args+=("\$arg") ;;
esac
done
exec zig cc -target ${ZIG_TARGET} "\${args[@]}"
EOF
chmod +x "$WRAPPER"
UPPER=$(echo "$ENV_TGT" | tr '[:lower:]' '[:upper:]')
{
echo "CC_${ENV_TGT}=$WRAPPER"
echo "CXX_${ENV_TGT}=$WRAPPER"
echo "CARGO_TARGET_${UPPER}_LINKER=$WRAPPER"
} >> "$GITHUB_ENV"
- name: Install npm dependencies
run: npm i
- name: Build native module
# `--features` is baked into the `build` script in
# package.json (redis,net,cortex,compute,groups). Don't pass
# it again here — `@napi-rs/cli` 3.x forwards the second
# `--features <name>` to cargo as a positional, and cargo
# rejects it with "unexpected argument 'name' found".
run: npm run build -- --target ${{ matrix.target }}
- name: Upload artifact
uses: actions/upload-artifact@v7
with:
name: bindings-${{ matrix.target }}
path: net/crates/net/bindings/node/*.node
if-no-files-found: error
publish:
needs: build
runs-on: ubuntu-latest
defaults:
run:
working-directory: net/crates/net/bindings/node
steps:
- uses: actions/checkout@v6
- name: Setup Node.js
uses: actions/setup-node@v6
with:
node-version: "24"
registry-url: "https://registry.npmjs.org"
- name: Install Rust
uses: dtolnay/rust-toolchain@stable
- name: Install dependencies
run: npm i
# Generate the napi JS loader (`index.js`) + type defs
# (`index.d.ts`). Both are gitignored — produced by `napi
# build` from the `#[napi]` macro expansion, so a fresh
# checkout here lacks them. napi has no types-only mode, so we
# run the (faster) debug build purely for the generated
# `index.{js,d.ts}`: they are byte-identical to the release
# build's, and the throwaway host `.node` is removed below so
# it can't shadow the release binaries downloaded from the
# build matrix. Without this the published tarball is missing
# its declared `main`/`types` entry (`index.js`) and `build:ts`
# cannot resolve `./index`.
- name: Generate JS loader + type defs
run: npm run build:debug
- name: Drop throwaway debug binary
shell: bash
run: rm -f net.*.node
- name: Download all artifacts
uses: actions/download-artifact@v8
with:
path: net/crates/net/bindings/node/artifacts
# `napi artifacts` writes each `*.node` into `npm/<platform>/`,
# but expects those subdirectories to already exist. They're
# normally created once by `napi create-npm-dirs` and committed
# to the repo; whenever a new target lands in
# `package.json`'s `napi.targets`, the corresponding sub-dir
# is missing. Run create-npm-dirs in CI so the per-platform
# scaffolding is always in lockstep with `napi.targets`.
- name: Create per-platform npm dirs
run: npx napi create-npm-dirs
- name: Move artifacts
run: npm run artifacts
- name: List packages
run: ls -la npm/
- name: Publish to npm
shell: bash
run: |
VERSION="$(node -p "require('./package.json').version")"
case "$VERSION" in
*-*) DIST_TAG="$(printf '%s' "${VERSION#*-}" | cut -d. -f1)" ;;
*) DIST_TAG="latest" ;;
esac
echo "Publishing $VERSION with npm dist-tag: $DIST_TAG"
# `npm_config_tag` is npm's env form of `--tag`. It is inherited by the
# per-platform `npm publish` calls that `napi prepublish` (invoked from
# this package's prepublishOnly) shells out to and which take no flag of
# their own. npm refuses to publish a prerelease under the default
# `latest` tag, so a beta/rc must set this on every publish.
export npm_config_tag="$DIST_TAG"
npm publish --access public --tag "$DIST_TAG"
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}