Skip to content

Publishing to npm

This guide covers how to publish a new version of the astropress package. Releases use Changesets for versioning and CHANGELOG management, and the CI pipeline handles the actual publish step via changeset publish --provenance.


Prerequisites

  • Maintainer access to the GitHub repository
  • NPM_TOKEN secret configured in repository Settings → Secrets → Actions (automation token with publish permission on the astropress npm package)
  • All CI checks green on main

Pre-flight checks

Run these locally before starting the release process:

Terminal window
# 1. All Vitest tests must pass
bun run --filter astropress test
# 2. All Rust CLI tests must pass
cargo test --manifest-path crates/astropress-cli/Cargo.toml
# 3. Architectural invariants must pass (TS and Rust)
bun run audit:arch && bun run audit:arch:rust
# 4. BDD scenarios must all pass
bun run bdd:test
# 5. API reference must be up to date
bun run docs:api:check
# 6. Dependency audit must be clean
bun run audit:deps && bun run audit:security
# 7. No uncommitted changes
git status --short

If any check fails, fix it before proceeding.


Step 1 — Create a changeset

A changeset describes what changed and bumps the version type (major/minor/patch).

Terminal window
bun run changeset add

Follow the interactive prompts:

  1. Select astropress (space to toggle, enter to confirm)
  2. Choose bump type: patch for bug fixes, minor for new features, major for breaking changes
  3. Write a short summary (this becomes the CHANGELOG entry)

Commit the generated changeset file:

Terminal window
git add .changeset/
git commit -m "chore: add changeset for <description>"

Step 2 — Push and let CI create the Version PR

Terminal window
git push origin main

The release.yml workflow (powered by changesets/action) automatically opens a “Version Packages” pull request on GitHub. This PR:

  • Bumps packages/astropress/package.json to the new version
  • Updates packages/astropress/CHANGELOG.md
  • Squashes any pending changesets

Step 3 — Review and merge the Version PR

  1. Open the pull request labeled Version Packages on GitHub
  2. Review the CHANGELOG.md diff — verify the bump type is correct and the entry accurately describes the change
  3. Merge the PR (squash merge is fine)

Step 4 — CI publishes automatically

After the Version PR merges, release.yml runs the publish job:

publish: bun run release -- --provenance

This calls changeset publish --provenance, which:

  1. Runs prepublishOnly (bun run build && bun run audit:arch) to emit the compiled .js output into dist/
  2. Publishes packages/astropress to the npm registry
  3. Attaches a SLSA Build L1 provenance attestation
  4. Creates a git tag (astropress@<version>) and pushes it

No manual npm publish step is required.


Step 5 — Verify the release

Terminal window
# Confirm the new version is visible on npm
npm show astropress version
# Smoke-test the published package
mkdir /tmp/ap-smoke && cd /tmp/ap-smoke
bun add astropress@latest
cat > smoke.mjs << 'EOF'
import * as ap from 'astropress';
console.log('ok', Object.keys(ap).slice(0, 10));
EOF
node smoke.mjs

Check the provenance badge on the npm package page — it should show “Published with provenance” linking to the exact CI run that built it.


Step 6 — Create a GitHub Release

  1. Go to Releases → Draft a new release on GitHub
  2. Select the tag that was auto-created (e.g. astropress@0.1.0)
  3. Copy the relevant section from packages/astropress/CHANGELOG.md into the release notes
  4. Publish the release

CLI distribution

The Astropress CLI is a Rust binary distributed separately from the npm package. It is not bundled in the astropress npm package.

ChannelCommand for usersAudience
crates.iocargo install astropress-cliRust users; builds from source
GitHub ReleasesDownload pre-built binaryUsers without a Rust toolchain

A full CLI release publishes to both channels from a single git tag matching cli-v* (e.g. cli-v0.2.0).

Per-release workflow

  1. Bump the version in crates/astropress-cli/Cargo.toml
  2. Run pre-flight checks locally:
    Terminal window
    cargo test --manifest-path crates/Cargo.toml
    bun run audit:arch:rust
    cargo clippy --manifest-path crates/Cargo.toml --all-targets -- -D warnings
    cargo publish --manifest-path crates/astropress-cli/Cargo.toml --dry-run
  3. Commit and tag:
    Terminal window
    git commit -am "chore: release astropress-cli v0.2.0"
    git tag cli-v0.2.0
    git push origin main --tags
  4. Wait for binary-release CI. The cli-v* tag triggers cli-release.yml, which builds for x86_64-linux-gnu, aarch64-linux-gnu, x86_64-apple-darwin, aarch64-apple-darwin, and x86_64-windows-msvc.
  5. Publish to crates.io from the tagged commit:
    Terminal window
    git checkout cli-v0.2.0
    cargo publish --manifest-path crates/astropress-cli/Cargo.toml

Verify the CLI release

Terminal window
cargo search astropress-cli | head -1
cargo install astropress-cli --version 0.2.0 --locked
astropress-cli --version
gh release view cli-v0.2.0

Required secrets

SecretPurpose
NPM_TOKENnpm automation token with publish access to the astropress package
CARGO_REGISTRY_TOKENcrates.io API token scoped to publish-update on astropress-cli

Troubleshooting

“Version Packages” PR does not appear after push → Check that .changeset/config.json lists astropress in the packages and that the changeset file was committed correctly (bun run changeset status).

Publish step fails with 403 → The NPM_TOKEN secret may be expired or have insufficient permissions. Regenerate an automation token on npmjs.com and update the repository secret.

prepublishOnly failsprepublishOnly runs bun run build then audit:arch. If audit:arch fails with no-js-in-src, a stray .js file crept into packages/astropress/src/ — delete it.

cargo publish fails with “crate already exists”Cargo.toml version was not bumped. Update it, commit, re-tag.