Publishing to npm
This guide will help you publish the lambda-toolkit package to npm.
Prerequisites
-
All tests passing locally and in CI:
pnpm test -
An npm account with publish rights to the
@leighton-digital/*scope.npm login -
Access to the repo’s
NPM_TOKENsecret (must be an Automation token if org requires 2FA). -
package.jsonincludes:{
"name": "@leighton-digital/<your-package>",
"version": "0.0.0-development",
"private": false,
"packageManager": "pnpm@9",
"publishConfig": { "access": "public" }
}versionis managed by semantic-release at publish time. For scoped public packages,publishConfig.accessmust be"public".
Build
Build locally exactly as CI does:
pnpm install --frozen-lockfile
pnpm build
Your build should output distributable files (e.g., dist/) referenced by package.json fields like main, module, types, exports, etc.
Versioning & Changelog (Automated)
We use Conventional Commits + semantic-release:
feat: …→ minorfix: …→ patchperf:/refactor:may map to patch (configurable)BREAKING CHANGE:in the commit footer (orfeat!:/fix!:) → major- Changelog is generated automatically into
CHANGELOG.md.
Commit examples
feat(parser): add YAML support
fix(cli): handle empty config without crashing
feat(api)!: remove deprecated v1 endpoints
BREAKING CHANGE: The v1 /users endpoint was removed in favor of /v2/users.
How Publishing Works (GitHub Actions)
Releases are created automatically on pushes to main that include qualifying Conventional Commits.
1) Workflow file
The release is automatically performed through the GitHub Release Workflow
2) semantic-release config
The releaserc.json provides the release configuration.
3) Dependencies
The following packages have been installed to release the package:
semantic-release @semantic-release/{npm,git,github,changelog,commit-analyzer,release-notes-generator}
Tip: To validate locally without publishing, run:
pnpm dlx semantic-release --dry-run
Triggering a Release
- Merge/push Conventional Commit(s) to
main. - The workflow computes the next version, updates
CHANGELOG.md, creates a Git tag & GitHub Release, and publishes to npm.
You don’t manually bump versions or run
pnpm publish. CI handles it.
Manual/Emergency Publishing (avoid if possible)
If CI is unavailable and you must publish:
-
Ensure working tree is clean and built:
pnpm install --frozen-lockfile
pnpm build -
Strongly preferred: run a local dry run first:
pnpm dlx semantic-release --dry-run -
If absolutely necessary to publish without semantic-release, you can:
pnpm version patch|minor|major
pnpm publishCaveat: This bypasses automation and will desync the next SR calculation. Afterward, reset
versionto0.0.0-developmentand push a corrective commit. Use only as a last resort.
Biome & Lefthook Integration
To ensure code quality and consistency, Biome and Lefthook run locally and in CI.
Local (via Lefthook)
-
pre-commit
biome format --writeon staged filesbiome linton staged files
-
pre-push
pnpm typecheckandpnpm test
-
commit-msg
non-empty: run: test -s {1} || (echo "✖ Commit message is empty" && exit 1)commitlint: run: pnpm commitlint --edit {1}
CI (via GitHub Actions)
Every PR and push to main should run:
pnpm format:check # biome check --formatter
pnpm lint # biome check --linter
pnpm typecheck
pnpm build
pnpm test
The release job runs these before publishing.
Troubleshooting
“No release published”
- Cause: No Conventional Commits since last release (no
feat,fix, orBREAKING CHANGE). - Fix: Use proper commit types; push again.
“Semantic-release can’t find previous tag”
- Cause: Shallow clone.
- Fix: Ensure
actions/checkoutusesfetch-depth: 0.
403 from npm / publish failed
- Cause: Token lacks permission or isn’t an Automation token (when 2FA enforced).
- Fix: Regenerate
NPM_TOKENwith Automation type; confirm org permissions.
“Package is private”
- Cause: Missing public access for scoped package.
- Fix: Ensure
publishConfig.access: "public"inpackage.json.
Wrong branch
- Cause: Releasing from a non-configured branch.
- Fix: Update
.releaserc.json#branchesor usemain.
Changelog not updated
- Cause: Missing
@semantic-release/changelogor@semantic-release/git. - Fix: Ensure both plugins are present in config and installed.
Checking Published Packages
View the package on npm:
npm view @leighton-digital/api-gateway-cloudfront-distribution
Check available versions:
npm view @leighton-digital/api-gateway-cloudfront-distribution versions
Best Practices
-
Before opening a PR:
pnpm format:check
pnpm lint
pnpm typecheck
pnpm test -
Use
npm packlocally to preview the publish contents:pnpm pack -
Prefer CI-driven releases. Avoid manual
pnpm publishexcept in emergencies. -
Adopt Conventional Commits consistently across all changes.