Skip to content

Publish npm package to npm registry #92

Publish npm package to npm registry

Publish npm package to npm registry #92

# Copyright © SixtyFPS GmbH <info@slint.dev>
# SPDX-License-Identifier: GPL-3.0-only OR LicenseRef-Slint-Royalty-free-2.0 OR LicenseRef-Slint-Software-3.0
name: Publish npm package to npm registry
on:
workflow_dispatch:
inputs:
private:
type: boolean
default: true
required: false
description: "Private build? True means artifacts are only built. False means the package will be published to the NPM registry"
release:
type: boolean
default: false
required: false
description: "Release? Enable options for building binaries for a release (i.e. apply a nightly tag, nightly version)"
schedule:
- cron: "0 5 * * *"
permissions:
id-token: write # Required for OIDC
contents: read
env:
# Use fat LTO for the published npm native binaries: smaller size and better runtime perf.
# Workspace [profile.release] uses cargo defaults to keep dev release builds fast.
CARGO_PROFILE_RELEASE_LTO: "fat"
CARGO_PROFILE_RELEASE_CODEGEN_UNITS: "1"
jobs:
determine_version:
runs-on: ubuntu-latest
outputs:
PKG_VERSION: ${{ steps.mkversion.outputs.PKG_VERSION }}
steps:
- uses: actions/checkout@v6
- uses: pnpm/action-setup@v6.0.8
with:
version: 10.29.3
- uses: actions/setup-node@v6
with:
package-manager-cache: false
- name: Determine version
id: mkversion
env:
RELEASE_INPUT: ${{ github.event.inputs.release }}
working-directory: api/node
run: |
version=`pnpm pkg get version | jq -r`
if [ "$RELEASE_INPUT" != "true" ]; then
nightly_version_suffix=`git log -1 --format=%cd --date="format:%Y%m%d%H"`
version="$version-nightly.$nightly_version_suffix"
fi
echo $version
echo "PKG_VERSION=$version" >> $GITHUB_OUTPUT
build_binaries:
env:
PKG_VERSION: ${{ needs.determine_version.outputs.PKG_VERSION }}
RELEASE_INPUT: ${{ github.event.inputs.release }}
MACOSX_DEPLOYMENT_TARGET: "11.0"
strategy:
matrix:
include:
- os: ubuntu-22.04
rust-target: x86_64-unknown-linux-gnu
napi-rs-target: linux-x64-gnu
- os: ubuntu-22.04-arm
rust-target: aarch64-unknown-linux-gnu
napi-rs-target: linux-arm64-gnu
- os: macos-26
rust-target: aarch64-apple-darwin
napi-rs-target: darwin-arm64
- os: windows-2022
rust-target: x86_64-pc-windows-msvc
napi-rs-target: win32-x64-msvc
msvc-arch: x64
- os: windows-11-arm
rust-target: aarch64-pc-windows-msvc
napi-rs-target: win32-arm64-msvc
msvc-arch: arm64
needs: determine_version
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v6
- uses: ./.github/actions/install-linux-dependencies
- uses: ./.github/actions/install-skia-dependencies
- uses: ilammy/msvc-dev-cmd@v1
if: runner.os == 'Windows'
with:
arch: ${{ matrix.msvc-arch }}
- uses: ./.github/actions/setup-rust
with:
target: ${{ matrix.rust-target }}
- uses: pnpm/action-setup@v6.0.8
with:
version: 10.29.3
# Setup .npmrc file to publish to npm
- uses: actions/setup-node@v6
with:
node-version: "24"
registry-url: "https://registry.npmjs.org"
package-manager-cache: false
- uses: pnpm/action-setup@v6.0.8
with:
version: 10.29.3
- name: Set version
working-directory: api/node
shell: bash
run: |
if [ "$RELEASE_INPUT" != "true" ]; then
pnpm version $PKG_VERSION
fi
- name: Build binary
shell: bash
working-directory: api/node
run: |
pnpm install --ignore-scripts
pnpm run build --target ${{ matrix.rust-target }}
# Build the "dev" binary with the additional system-testing and
# mcp features. It is published as a separate optional binary
# package (distributed via the slint-ui-dev package) and loaded
# conditionally at runtime (see binding.cjs).
pnpm run build:dev --target ${{ matrix.rust-target }}
- name: Create package
shell: bash
working-directory: api/node
run: |
PACKED="$PWD/packed"
PKG="$GITHUB_WORKSPACE/api/node/scripts/packaging.mts"
node "$PKG" pack-binary binaries.json ${{ matrix.napi-rs-target }} slint-ui "$PACKED"
node "$PKG" pack-binary binaries-dev.json ${{ matrix.napi-rs-target }} slint-ui-dev "$PACKED"
- name: Upload artifact
uses: actions/upload-artifact@v7
with:
name: binaries-${{ matrix.rust-target }}
path: "api/node/packed/*.tgz"
build_and_publish_npm_package:
runs-on: ubuntu-22.04
needs: [determine_version, build_binaries]
env:
PKG_VERSION: ${{ needs.determine_version.outputs.PKG_VERSION }}
RELEASE_INPUT: ${{ github.event.inputs.release }}
steps:
- uses: actions/checkout@v6
- uses: ./.github/actions/install-linux-dependencies
- uses: ./.github/actions/setup-rust
- uses: pnpm/action-setup@v6.0.8
with:
version: 10.29.3
# Setup .npmrc file to publish to npm
- uses: actions/setup-node@v6
with:
node-version: "24"
registry-url: "https://registry.npmjs.org"
package-manager-cache: false
- name: Update npm as Node 20.x might not have an new enough npm for trusted publishing
run: npm install -g npm@latest
- name: Set version
working-directory: api/node
run: |
if [ "$RELEASE_INPUT" != "true" ]; then
pnpm version $PKG_VERSION
fi
- name: Select git revision
if: github.event.inputs.release != 'true'
run: |
echo "PKG_EXTRA_ARGS=--sha1=$GITHUB_SHA" >> $GITHUB_ENV
# dist-tag value (empty for a release → published as `latest`).
echo "PUBLISH_DIST_TAG=nightly" >> $GITHUB_ENV
- name: Compile index.js and index.d.ts
working-directory: api/node
run: |
pnpm install
pnpm run build
# Generate the "dev" loader (rust-module-dev.cjs); it is shipped in the
# separate slint-ui-dev package (see below), which binding.cjs loads by
# name when present. It is intentionally kept out of the main package
# (see .npmignore) so `npm i slint-ui` stays lean for production.
pnpm run build:dev
pnpm run compile
- name: Prepare binary packages
working-directory: api/node
run: |
npx napi create-npm-dirs --npm-dir . -c ./binaries.json
- name: Download artifacts
uses: actions/download-artifact@v8
with:
name: binaries-x86_64-unknown-linux-gnu
path: api/node/
- name: Download artifacts
uses: actions/download-artifact@v8
with:
name: binaries-aarch64-unknown-linux-gnu
path: api/node/
- name: Download artifacts
uses: actions/download-artifact@v8
with:
name: binaries-aarch64-apple-darwin
path: api/node/
- name: Download artifacts
uses: actions/download-artifact@v8
with:
name: binaries-x86_64-pc-windows-msvc
path: api/node/
- name: Download artifacts
uses: actions/download-artifact@v8
with:
name: binaries-aarch64-pc-windows-msvc
path: api/node/
- name: Add binary dependencies
working-directory: api/node
run: |
node "$GITHUB_WORKSPACE/api/node/scripts/packaging.mts" set-main-deps "$PKG_VERSION"
- name: Build slint-ui-dev package
working-directory: api/node
run: |
node "$GITHUB_WORKSPACE/api/node/scripts/packaging.mts" pack-dev-meta "$PKG_VERSION" "$GITHUB_WORKSPACE/api/node"
- name: Build package
run: |
cargo xtask node_package $PKG_EXTRA_ARGS
- name: "Upload npm package Artifact"
uses: actions/upload-artifact@v7
with:
name: slint-ui-node-package
path: |
api/node/slint-ui-${{ env.PKG_VERSION }}.tgz
- name: End-to-end test against a local registry
# Gate that always runs (including dry-run builds where `private=true`):
# publish the real, all-platform tarballs to a throwaway Verdaccio
# registry with the same `publishAll` routine used for the real publish
# below, then install them as a consumer (npm + pnpm) and verify the
# distribution. Blocks the real publish on failure.
working-directory: api/node
env:
SLINT_E2E_TGZ_DIR: ${{ github.workspace }}/api/node
SLINT_E2E_VERSION: ${{ env.PKG_VERSION }}
SLINT_E2E_TAG: ${{ env.PUBLISH_DIST_TAG }}
run: node --test __test__/registry/e2e.test.mts
- name: Build and publish packages
if: ${{ github.event.inputs.private != 'true' && (github.ref == 'refs/heads/master' || github.event.inputs.release == 'true') }}
run: |
node "$GITHUB_WORKSPACE/api/node/scripts/packaging.mts" publish-all "$GITHUB_WORKSPACE/api/node" https://registry.npmjs.org/ "$PUBLISH_DIST_TAG"