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.


  • 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

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.


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

Section titled “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

Section titled “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)

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.


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.


  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

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).

  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
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

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

“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.