blob: ab1f75029fd3423fc3bd0dacf9e93dfc0ef9008a [file]
name: release-npm
# Cross-compiles doriscli for every supported platform, assembles the npm
# packages, and publishes them. Triggered by pushing a v* tag (whose number must
# match the version in Cargo.toml) or run manually.
#
# Prerequisite: add an npm automation token as the repo secret `NPM_TOKEN`
# (npmjs.com → Access Tokens → Generate → "Automation").
on:
workflow_dispatch:
inputs:
dry_run:
description: "Validate build + packaging without publishing (npm publish --dry-run)"
type: boolean
default: true
push:
tags: ["v*.*.*"]
permissions:
contents: read
jobs:
build:
strategy:
fail-fast: false
matrix:
include:
- { runner: macos-14, key: darwin-arm64, target: aarch64-apple-darwin }
- { runner: ubuntu-latest, key: linux-x64, target: x86_64-unknown-linux-gnu }
# If arm64 Linux runners aren't available to this repo, swap to the
# `cross` tool or houseabsolute/actions-rust-cross for this entry.
- { runner: ubuntu-24.04-arm, key: linux-arm64, target: aarch64-unknown-linux-gnu }
runs-on: ${{ matrix.runner }}
steps:
# checkout must run first: the step below uses a local composite action
# (referenced by in-repo relative path) that lives in this repository.
# The apache org action allowlist blocks third-party actions such as
# dtolnay/rust-toolchain, so it is reimplemented under .github/actions
# and used via ./.github/actions/<name>.
- uses: actions/checkout@v4
- uses: ./.github/actions/setup-rust-toolchain
with:
targets: ${{ matrix.target }}
- uses: actions/setup-node@v4
with:
node-version: 20
- run: cargo build --release --target ${{ matrix.target }}
- name: Assemble platform package
shell: bash
run: |
BIN="target/${{ matrix.target }}/release/doriscli"
node npm/build-packages.cjs platform ${{ matrix.key }} "$BIN"
- uses: actions/upload-artifact@v4
with:
name: pkg-${{ matrix.key }}
path: npm/dist/doriscli-${{ matrix.key }}
if-no-files-found: error
publish:
needs: build
runs-on: ubuntu-latest
env:
# Manual runs default to a dry run (validate without publishing); a v* tag
# push does a real publish. --dry-run needs no token, so you can validate
# the whole pipeline before NPM_TOKEN is even set.
DRYRUN: ${{ (github.event_name == 'workflow_dispatch' && inputs.dry_run) && '--dry-run' || '' }}
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 20
registry-url: https://registry.npmjs.org
- uses: actions/download-artifact@v4
with:
path: npm/dist
pattern: pkg-*
- name: Arrange dist dirs
shell: bash
run: |
set -e
cd npm/dist
# download-artifact nests each artifact under its name (pkg-<key>); the
# generator + main package expect doriscli-<key>.
for d in pkg-*/; do
dest="doriscli-${d#pkg-}"
rm -rf "${dest%/}"
mv "$d" "${dest%/}"
done
# actions/upload-artifact strips the Unix executable bit, so each
# prebuilt binary arrives as 0644 and npm would publish a
# non-executable file (the launcher spawns it directly, and platform
# packages declare no `bin` entry for npm to chmod on install).
# Restore it before the packages are packed.
chmod 0755 doriscli-*/bin/*
ls -la
- name: Assemble main package
run: node npm/build-packages.cjs main
- name: Publish platform packages
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
run: |
set -e
echo "DRYRUN='${DRYRUN}' (empty = real publish)"
for d in npm/dist/doriscli-*/; do
npm publish "$d" --access public $DRYRUN
done
- name: Publish main package
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
# Published last so the optionalDependencies already exist on the registry.
run: npm publish npm/dist/doriscli --access public $DRYRUN