diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 6cc20987..53b52c4b 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -15,13 +15,13 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 - - uses: pnpm/action-setup@v4 + - uses: pnpm/action-setup@v5 - - uses: actions/setup-node@v4 + - uses: actions/setup-node@v5 with: - node-version: 20 + node-version: 24 cache: pnpm - run: pnpm install --frozen-lockfile @@ -33,3 +33,6 @@ jobs: - run: pnpm lint - run: pnpm test + + - name: Verify installed package + run: bash scripts/smoke-package.sh diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index af68ff03..781ee611 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -3,6 +3,7 @@ name: Release on: push: branches: [main] + workflow_dispatch: concurrency: group: ${{ github.workflow }}-${{ github.ref }} @@ -11,6 +12,7 @@ concurrency: jobs: release: name: Version or publish + if: github.ref == 'refs/heads/main' runs-on: ubuntu-latest permissions: contents: write @@ -18,21 +20,31 @@ jobs: id-token: write steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v5 with: fetch-depth: 0 - - uses: pnpm/action-setup@v4 + - uses: pnpm/action-setup@v5 - - uses: actions/setup-node@v4 + - uses: actions/setup-node@v5 with: - node-version: 20 + node-version: 24 cache: pnpm registry-url: https://registry.npmjs.org - run: pnpm install --frozen-lockfile - - run: pnpm build + - name: Typecheck package + run: pnpm --filter @web-kits/audio typecheck + + - name: Test package + run: pnpm --filter @web-kits/audio test + + - name: Build package + run: pnpm --filter @web-kits/audio build + + - name: Verify installed package + run: bash scripts/smoke-package.sh - name: Create Release PR or publish uses: changesets/action@v1 @@ -44,4 +56,5 @@ jobs: env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} NPM_TOKEN: ${{ secrets.NPM_TOKEN }} + NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} NPM_CONFIG_PROVENANCE: "true" diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index bdaf93f3..7ae61849 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -59,6 +59,32 @@ pnpm changeset Follow the prompts to describe what changed and the semver bump type. This creates a markdown file in `.changeset/` that gets consumed during release. +## Publishing + +The Release workflow on `main` versions packages with Changesets, or publishes +unpublished package versions when no changesets remain. It typechecks, tests, and +builds `@web-kits/audio` independently of the private website and marketing apps. +It also installs a packed tarball in a temporary project and checks the library +import and executable CLI. Run this check locally after building: + +```bash +bash scripts/smoke-package.sh +``` + +Configure the repository's `NPM_TOKEN` Actions secret with permission to publish +`@web-kits/audio`. The workflow passes this secret as both `NPM_TOKEN` for +Changesets and `NODE_AUTH_TOKEN` for the npm configuration created by setup-node. + +If publishing fails after a version bump, fix the underlying error and rerun the +Release workflow from Actions on `main` using **Run workflow**. Keep the existing +package version when it has not yet been published; a new changeset is not needed +for a release workflow repair. Verify the result with: + +```bash +npm view @web-kits/audio version +npm view @web-kits/audio@0.2.0 version +``` + ## Commit convention Commits must follow [Conventional Commits](https://www.conventionalcommits.org/). A `commitlint` hook enforces this automatically. diff --git a/packages/audio/CHANGELOG.md b/packages/audio/CHANGELOG.md index 912b0933..361193c0 100644 --- a/packages/audio/CHANGELOG.md +++ b/packages/audio/CHANGELOG.md @@ -2,6 +2,10 @@ ## 0.2.0 +### Patch Changes + +- Restore the Node.js interpreter header so the installed `audio` CLI runs correctly. + ### Minor Changes - ec45185: Add a `jitter` option to `PlayOptions` for per-voice random variation. Pick any combination of `detune` (cents), `volume` (fraction), and `playbackRate` (fraction) to humanize repeated triggers — so buttons pressed in quick succession no longer sound identical. diff --git a/packages/audio/src/bin.ts b/packages/audio/src/bin.ts index b5a858c2..1f338637 100644 --- a/packages/audio/src/bin.ts +++ b/packages/audio/src/bin.ts @@ -1,3 +1,4 @@ +#!/usr/bin/env node import { run } from "./commands/index.js"; run(); diff --git a/scripts/smoke-package.sh b/scripts/smoke-package.sh new file mode 100644 index 00000000..53197115 --- /dev/null +++ b/scripts/smoke-package.sh @@ -0,0 +1,28 @@ +#!/usr/bin/env bash +set -euo pipefail + +repo_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" +smoke_dir="$(mktemp -d)" +trap 'rm -rf "$smoke_dir"' EXIT + +cd "$repo_dir/packages/audio" +expected_version="$(node -p 'require("./package.json").version')" +npm pack --pack-destination "$smoke_dir" --json > "$smoke_dir/pack.json" +tarball="$(node -p 'JSON.parse(require("node:fs").readFileSync(process.argv[1], "utf8"))[0].filename' "$smoke_dir/pack.json")" + +npm install --prefix "$smoke_dir/consumer" "$smoke_dir/$tarball" \ + --ignore-scripts --no-audit --no-fund + +cd "$smoke_dir/consumer" +node --input-type=module -e ' + import { defineSound } from "@web-kits/audio"; + if (typeof defineSound !== "function") throw new Error("Missing defineSound export"); +' + +actual_version="$(./node_modules/.bin/audio --version)" +if [[ "$actual_version" != "$expected_version" ]]; then + echo "Expected CLI version $expected_version, got $actual_version" >&2 + exit 1 +fi +./node_modules/.bin/audio --help +echo "Packed @web-kits/audio@$expected_version passed installation and CLI checks."