Skip to content

npm-publish

npm-publish #9

Workflow file for this run

name: npm-publish
on:
release:
types: [published]
workflow_dispatch:
inputs:
dry_run:
description: "Dry run (skip actual publish)"
required: false
default: "false"
type: boolean
permissions:
contents: read
id-token: write
jobs:
build:
strategy:
fail-fast: false
matrix:
include:
- platform: darwin-arm64
target: aarch64-apple-darwin
runner: macos-14
method: native
- platform: darwin-x64
target: x86_64-apple-darwin
runner: macos-14
method: cross
- platform: linux-x64-gnu
target: x86_64-unknown-linux-gnu
runner: ubuntu-latest
method: native
- platform: linux-arm64-gnu
target: aarch64-unknown-linux-gnu
runner: ubuntu-latest
method: zigbuild
- platform: win32-x64-msvc
target: x86_64-pc-windows-msvc
runner: windows-latest
method: native
- platform: win32-arm64-msvc
target: aarch64-pc-windows-msvc
runner: windows-latest
method: cross
runs-on: ${{ matrix.runner }}
name: build (${{ matrix.platform }})
steps:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@stable
with:
targets: ${{ matrix.target }}
- name: Install zigbuild (Linux ARM64)
if: matrix.method == 'zigbuild'
run: |
pip3 install ziglang
cargo install cargo-zigbuild
- name: Build (native)
if: matrix.method == 'native'
run: cargo build --release --locked --target ${{ matrix.target }}
- name: Build (zigbuild)
if: matrix.method == 'zigbuild'
run: cargo zigbuild --release --locked --target ${{ matrix.target }}.2.17
- name: Build (cross-compile)
if: matrix.method == 'cross'
run: cargo build --release --locked --target ${{ matrix.target }}
- name: Upload binary (unix)
if: runner.os != 'Windows'
uses: actions/upload-artifact@v4
with:
name: binary-${{ matrix.platform }}
path: target/${{ matrix.target }}/release/tsq
- name: Upload binary (windows)
if: runner.os == 'Windows'
uses: actions/upload-artifact@v4
with:
name: binary-${{ matrix.platform }}
path: target/${{ matrix.target }}/release/tsq.exe
publish:
needs: build
runs-on: ubuntu-latest
name: publish
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: "20"
registry-url: "https://registry.npmjs.org"
- name: Download all artifacts
uses: actions/download-artifact@v4
with:
path: raw-artifacts
- name: Reorganize artifacts
run: |
mkdir -p artifacts
for dir in raw-artifacts/binary-*/; do
platform=$(basename "$dir" | sed 's/^binary-//')
case "$platform" in
darwin-arm64) target="aarch64-apple-darwin" ;;
darwin-x64) target="x86_64-apple-darwin" ;;
linux-x64-gnu) target="x86_64-unknown-linux-gnu" ;;
linux-arm64-gnu) target="aarch64-unknown-linux-gnu" ;;
win32-x64-msvc) target="x86_64-pc-windows-msvc" ;;
win32-arm64-msvc) target="aarch64-pc-windows-msvc" ;;
esac
mkdir -p "artifacts/$target"
cp "$dir"* "artifacts/$target/"
done
- name: Build npm packages
run: bash scripts/build-npm.sh
- name: Validate platform package binaries
if: ${{ !inputs.dry_run }}
run: |
set -euo pipefail
declare -A EXPECTED_BINARIES=(
["darwin-arm64"]="tsq"
["darwin-x64"]="tsq"
["linux-x64-gnu"]="tsq"
["linux-arm64-gnu"]="tsq"
["win32-x64-msvc"]="tsq.exe"
["win32-arm64-msvc"]="tsq.exe"
)
missing=0
for platform in "${!EXPECTED_BINARIES[@]}"; do
dir="npm/platforms/$platform"
bin="$dir/${EXPECTED_BINARIES[$platform]}"
if [[ ! -s "$bin" ]]; then
echo "::error::Missing expected binary for $platform: $bin"
ls -la "$dir" || true
missing=1
fi
done
if [[ "$missing" -ne 0 ]]; then
echo "Pre-publish validation failed."
exit 1
fi
echo "Pre-publish validation passed."
- name: Publish platform packages
if: ${{ !inputs.dry_run }}
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
run: |
VERSION=$(node -e "console.log(require('./npm/package.json').version)")
for dir in npm/platforms/*/; do
PKG_NAME=$(node -e "console.log(require('./${dir}package.json').name)")
EXISTING=$(npm view "${PKG_NAME}@${VERSION}" version 2>/dev/null || echo "")
if [ -n "$EXISTING" ]; then
echo "Skipping $PKG_NAME@$VERSION (already published)"
else
echo "Publishing $PKG_NAME@$VERSION"
npm publish "$dir" --provenance --access public
fi
done
- name: Publish root package
if: ${{ !inputs.dry_run }}
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
run: |
VERSION=$(node -e "console.log(require('./npm/package.json').version)")
PKG_NAME="@bumpyclock/tasque"
EXISTING=$(npm view "${PKG_NAME}@${VERSION}" version 2>/dev/null || echo "")
if [ -n "$EXISTING" ]; then
echo "Skipping $PKG_NAME@$VERSION (already published)"
else
echo "Publishing $PKG_NAME@$VERSION"
npm publish npm/ --provenance --access public
fi
- name: Dry run summary
if: ${{ inputs.dry_run }}
run: |
echo "=== Dry Run ==="
echo "Would publish the following packages:"
for dir in npm/platforms/*/; do
PKG=$(node -e "const p=require('./${dir}package.json'); console.log(p.name + '@' + p.version)")
echo " $PKG"
ls -la "$dir"
done
ROOT=$(node -e "const p=require('./npm/package.json'); console.log(p.name + '@' + p.version)")
echo " $ROOT"