Atomic Payload
Contributing

Releasing & publishing

Lockstep versioning across the workspace and npm publishing of every public package.

Every @pro-laico/* package shares one version (Payload-style lockstep) and ships together. Versioning happens locally with pnpm release; publishing happens in CI on the pushed tag with pnpm publish-packages.

Lockstep versioning

pnpm release reads the root package.json version as the source of truth, computes the next version from your chosen bump, and stamps that same version into the root plus every releasable workspace project: all packages/*, templates/*, and examples/*. Only the version line is rewritten, so Biome formatting is preserved. It then commits chore(release): vX.Y.Z and creates an annotated vX.Y.Z tag.

Internal workspace:* dependencies are left untouched: pnpm rewrites them to the concrete version automatically at publish time.

Always dry-run first. It prints the version table and writes nothing:

pnpm release --dry-run

To pass a bump type or other flags, invoke through the package filter so arguments forward cleanly:

pnpm --filter @tools/releaser release --bump minor                    # 0.2.0 -> 0.3.0
pnpm --filter @tools/releaser release --bump major                    # 0.2.0 -> 1.0.0
pnpm --filter @tools/releaser release --bump prerelease --preid beta  # 0.2.0 -> 0.2.1-beta.0

A bare pnpm release does a patch bump (e.g. 0.2.0 -> 0.2.1) and prompts for confirmation before writing.

Flags

FlagDefaultEffect
--bump <patch|minor|major|prerelease>patchWhich part of the version to bump.
--preid <id>betaPrerelease identifier (only used with --bump prerelease).
--dry-runfalsePrint the plan, write nothing, run no git commands.
--yesfalseSkip the interactive confirmation prompt.
--skip-gitfalseStamp the version files but do not commit or tag.

Publishing

pnpm publish-packages builds and publishes every non-private packages/* to npm. Templates, examples, and tools/* are never published. Each pnpm publish runs the package's prepack (swc/tsc build; the CLI also bundles its scaffolds), and pnpm rewrites workspace:* deps to the concrete shared version.

pnpm publish-packages --dry-run           # build + pack every package, no upload
pnpm publish-packages                      # publish at dist-tag "latest" (prompts)
pnpm publish-packages --tag beta           # publish under a different dist-tag
pnpm publish-packages --provenance --yes   # CI: signed provenance, no prompt

Versions already on the registry are skipped, so re-running after a partial failure is safe.

Flags

FlagDefaultEffect
--tag <name>latestnpm dist-tag to publish under.
--provenancefalseEmit npm provenance (requires CI OIDC, fails locally).
--dry-runfalseBuild + pack every package without uploading.
--yesfalseSkip the confirmation prompt.

The full flow

Bump and tag

Run the lockstep version bump. It stamps the version everywhere, then commits and tags.

pnpm release --bump <patch|minor|major|prerelease>

Push the tag

git push --follow-tags

CI publishes

Pushing a v* tag triggers .github/workflows/release.yml, which runs pnpm publish-packages --yes --provenance on the pushed tag, building and publishing every public package with npm provenance.

One-time setup for CI publishing: add an npm automation token as the NPM_TOKEN repo secret, and ensure the npm account/org can publish the @pro-laico scope.

To publish locally instead of through CI, run pnpm publish-packages yourself after pnpm release.

On this page