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_TOKENsecret configured in repository Settings → Secrets → Actions (automation token with publish permission on theastropressnpm package)- All CI checks green on
main
Pre-flight checks
Run these locally before starting the release process:
# 1. All Vitest tests must passbun run --filter astropress test
# 2. All Rust CLI tests must passcargo 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 passbun run bdd:test
# 5. API reference must be up to datebun run docs:api:check
# 6. Dependency audit must be cleanbun run audit:deps && bun run audit:security
# 7. No uncommitted changesgit status --shortIf 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).
bun run changeset addFollow the interactive prompts:
- Select
astropress(space to toggle, enter to confirm) - Choose bump type:
patchfor bug fixes,minorfor new features,majorfor breaking changes - Write a short summary (this becomes the CHANGELOG entry)
Commit the generated changeset file:
git add .changeset/git commit -m "chore: add changeset for <description>"Step 2 — Push and let CI create the Version PR
git push origin mainThe release.yml workflow (powered by changesets/action) automatically
opens a “Version Packages” pull request on GitHub. This PR:
- Bumps
packages/astropress/package.jsonto the new version - Updates
packages/astropress/CHANGELOG.md - Squashes any pending changesets
Step 3 — Review and merge the Version PR
- Open the pull request labeled Version Packages on GitHub
- Review the CHANGELOG.md diff — verify the bump type is correct and the entry accurately describes the change
- 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 -- --provenanceThis calls changeset publish --provenance, which:
- Runs
prepublishOnly(bun run build && bun run audit:arch) to emit the compiled.jsoutput intodist/ - Publishes
packages/astropressto the npm registry - Attaches a SLSA Build L1 provenance attestation
- Creates a git tag (
astropress@<version>) and pushes it
No manual npm publish step is required.
Step 5 — Verify the release
# Confirm the new version is visible on npmnpm show astropress version
# Smoke-test the published packagemkdir /tmp/ap-smoke && cd /tmp/ap-smokebun add astropress@latestcat > smoke.mjs << 'EOF'import * as ap from 'astropress';console.log('ok', Object.keys(ap).slice(0, 10));EOFnode smoke.mjsCheck 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
- Go to Releases → Draft a new release on GitHub
- Select the tag that was auto-created (e.g.
astropress@0.1.0) - Copy the relevant section from
packages/astropress/CHANGELOG.mdinto the release notes - 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.
| Channel | Command for users | Audience |
|---|---|---|
| crates.io | cargo install astropress-cli | Rust users; builds from source |
| GitHub Releases | Download pre-built binary | Users 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
- Bump the version in
crates/astropress-cli/Cargo.toml - Run pre-flight checks locally:
Terminal window cargo test --manifest-path crates/Cargo.tomlbun run audit:arch:rustcargo clippy --manifest-path crates/Cargo.toml --all-targets -- -D warningscargo publish --manifest-path crates/astropress-cli/Cargo.toml --dry-run - Commit and tag:
Terminal window git commit -am "chore: release astropress-cli v0.2.0"git tag cli-v0.2.0git push origin main --tags - Wait for binary-release CI. The
cli-v*tag triggerscli-release.yml, which builds forx86_64-linux-gnu,aarch64-linux-gnu,x86_64-apple-darwin,aarch64-apple-darwin, andx86_64-windows-msvc. - Publish to crates.io from the tagged commit:
Terminal window git checkout cli-v0.2.0cargo publish --manifest-path crates/astropress-cli/Cargo.toml
Verify the CLI release
cargo search astropress-cli | head -1cargo install astropress-cli --version 0.2.0 --lockedastropress-cli --versiongh release view cli-v0.2.0Required secrets
| Secret | Purpose |
|---|---|
NPM_TOKEN | npm automation token with publish access to the astropress package |
CARGO_REGISTRY_TOKEN | crates.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 fails
→ prepublishOnly 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.