Ship prepares the release; CI publishes it. This chapter covers the one-time setup of a package and what runs after the tag push.
The CI half of a release
sequenceDiagram
participant Dev as Developer
participant Ship as ship-it
participant Git as Git remote
participant CI as Tag-triggered CI
participant Reg as npm registry
Dev->>Ship: ship-it minor
Ship->>Git: verify remote branch equals HEAD
Ship->>Reg: is package@target published?
Ship->>Ship: run verify commands
Ship->>Git: commit, tag, atomic push
Git-->>CI: push of tag vX.Y.Z
CI->>CI: ship-it validate, tests, pack check
CI->>Reg: npm publish via OIDC
Dev->>Ship: ship-it check --wait 120
Ship->>Reg: is package@X.Y.Z published?
The setup wizard
For a single npm package in a GitHub repository, run the wizard once after installing Ship:
npm exec -- ship-it init
# or with Bun:
bun run ship-it init
It asks you to confirm the package manager, its exact CI version, the release branch, the workflow filename and the verification commands. Commands are suggested from existing check, test, prepack or build scripts; enter a JSON array to change them.
Then it can:
Set the pub, pub-check and pub-validate scripts, ship.verify, a matching GitHub repository URL and public publish settings.
Prepare the changelog and a tag-triggered workflow with locked installs, tag validation, your verify commands, package inspection and OIDC publishing.
Verify and inspect the package, then offer a commit and push of only the displayed setup files and lockfiles.
Offer the first publish when the current version is not on npm.
Create or reuse the npm Trusted Publisher for the workflow.
Every step that writes files, commits, publishes or changes npm trust asks first. Declining a step keeps the local setup, and running init again resumes. A replaced workflow is kept as a .ship-backup file.
Requirements: a Git repository with a GitHub remote and at least one commit, Ship installed, a committed lockfile for your package manager (npm, Bun, pnpm or Yarn Classic), npm CLI 11.15.0 or newer for Trusted Publisher management, and an account that may publish the package. Unrelated uncommitted changes or a non-empty staging area stop the commit step so you can review them.
The generated workflow
The workflow runs on pushes of tags matching <tagPrefix>* and has two permissions: contents: read and id-token: write. Its steps:
Check out the tag without persisting credentials.
Set up Node 24 and an exact npm version that supports Trusted Publishing.
Install the chosen package manager at its exact version, then install locked dependencies.
Run pub-validate (that is, ship-it validate) so the tag, version and changelog agree.
Run your ship.verify commands.
Run npm pack --dry-run --ignore-scripts.
Run npm publish --access public --ignore-scripts.
No npm token secret is needed; npm authenticates the job through OIDC.
First publish and Trusted Publishing
A new package must exist on npm before its Trusted Publisher can be configured, so the first publish is interactive.
flowchart TD
Prepare["Set metadata, license, first release notes"] --> Test["Test and inspect the package"]
Test --> Login["npm login with publish rights"]
Login --> First["npm publish --access public"]
First --> Workflow["Push the tag-triggered workflow"]
Workflow --> Trust["Configure the Trusted Publisher"]
Trust --> Next["Use ship-it for later versions"]
The first publish uses the version already in package.json; do not use ship-it for it, because Ship always increments the version. Prepare a stamped changelog entry for that version, then:
npm test
npm pack --dry-run --ignore-scripts
npm login
npm publish --access public
On npmjs.com, under the package's Settings → Trusted publishing, add a GitHub Actions publisher:
npm field
Value
Organization or user
The GitHub owner, for example acme
Repository
The repository name, for example widget
Workflow filename
The filename only, for example publish.yml
Environment name
Empty, unless the workflow uses a GitHub environment
Allowed actions
Direct npm publish enabled
Trusted Publishing needs npm 11.5.1+ and Node 22.14.0+. npm generates provenance automatically only for public repositories; the workflow does not force --provenance.
Setup and CI
Ship prepares the release; CI publishes it. This chapter covers the one-time setup of a package and what runs after the tag push.
The CI half of a release
The setup wizard
For a single npm package in a GitHub repository, run the wizard once after installing Ship:
npm exec -- ship-it init # or with Bun: bun run ship-it initIt asks you to confirm the package manager, its exact CI version, the release branch, the workflow filename and the verification commands. Commands are suggested from existing
check,test,prepackorbuildscripts; enter a JSON array to change them.Then it can:
pub,pub-checkandpub-validatescripts,ship.verify, a matching GitHubrepositoryURL and public publish settings.Every step that writes files, commits, publishes or changes npm trust asks first. Declining a step keeps the local setup, and running
initagain resumes. A replaced workflow is kept as a.ship-backupfile.Requirements: a Git repository with a GitHub remote and at least one commit, Ship installed, a committed lockfile for your package manager (npm, Bun, pnpm or Yarn Classic), npm CLI 11.15.0 or newer for Trusted Publisher management, and an account that may publish the package. Unrelated uncommitted changes or a non-empty staging area stop the commit step so you can review them.
The generated workflow
The workflow runs on pushes of tags matching
<tagPrefix>*and has two permissions:contents: readandid-token: write. Its steps:pub-validate(that is,ship-it validate) so the tag, version and changelog agree.ship.verifycommands.npm pack --dry-run --ignore-scripts.npm publish --access public --ignore-scripts.No npm token secret is needed; npm authenticates the job through OIDC.
First publish and Trusted Publishing
A new package must exist on npm before its Trusted Publisher can be configured, so the first publish is interactive.
The first publish uses the version already in
package.json; do not useship-itfor it, because Ship always increments the version. Prepare a stamped changelog entry for that version, then:npm test npm pack --dry-run --ignore-scripts npm login npm publish --access publicOn npmjs.com, under the package's Settings → Trusted publishing, add a GitHub Actions publisher:
acmewidgetpublish.ymlnpm publishenabledTrusted Publishing needs npm 11.5.1+ and Node 22.14.0+. npm generates provenance automatically only for public repositories; the workflow does not force
--provenance.