Publishing & Releasing
This document describes the automated publishing and release process for SolvaPay SDK packages.
Overview
The SolvaPay SDK uses an automated publishing workflow that:
- Publishes seven packages:
@solvapay/core,@solvapay/react,@solvapay/react-supabase,@solvapay/server,@solvapay/auth,@solvapay/next, andcreate-solvapay-app - Uses fixed versioning - all packages share the same version number
- Auto-increments the patch version on every push to
mainbranch - Generates changelogs using conventional commits
- Publishes to npm automatically via GitHub Actions
Branching Strategy
dev- Main development branch where all work happensmain- Production branch that triggers automated publishing
Workflow
- Develop features and fixes in the
devbranch - When ready to publish, merge
devintomain(via PR with squash merge) - Trigger the publish workflow manually via GitHub Actions UI
- A new patch version is automatically created and published to npm
- Version is tracked via git tag (not committed to git)
Versioning
Version Bump Strategy
Important: Version bumps are NOT committed back to git. Versions are tracked via git tags only. This prevents:
- Branch divergence between
devandmain - Version conflicts when merging
dev→main - Lockfile conflicts from version changes
- Complex merge cycles
How it works:
- When publishing, the workflow reads the current version from
package.json - Strips preview suffix if present (e.g.,
1.0.0-preview.18→1.0.0) - Bumps the version (patch increment for stable, preview increment for preview)
- Publishes with the new version
- Creates a git tag (e.g.,
v1.0.1) - Does NOT commit version changes back to git
This means package.json versions in git may not match published versions, but versions are accurately tracked via git tags and npm.
Syncing package.json Versions
Since version bumps are not committed back to git, package.json versions can become out of sync with published versions. This is generally fine - the version in package.json is mainly used during development, and the published version on npm is what matters.
However, if you want to sync package.json versions to match the latest published version, you can use:
# Sync to latest stable tag
pnpm version:sync
# Sync to latest preview tag
pnpm version:sync:preview
# Sync to a specific tag
pnpm version:sync --tag v1.0.1
# Sync and commit the changes
pnpm version:sync --commit
When to sync:
- Before major releases or documentation updates
- When you want
package.jsonto reflect the current published state - After publishing multiple versions without syncing
When NOT to sync:
- Right before publishing (the workflow handles this automatically)
- During active development (versions will be updated during publish)
- If you're working on
devbranch (sync onmainonly)
Note: The actual documentation is generated by a separate docs repo that uses this SDK as a git submodule. Version syncing in this repo is only needed if you want package.json files to match published versions for consistency.
Manual Version Bumps
For minor or major version changes, run the appropriate command locally before pushing to main:
# Bump minor version (0.1.x → 0.2.0)
pnpm version:bump:minor
# Bump major version (0.x.x → 1.0.0)
pnpm version:bump:major
These commands will:
- Update all seven package.json files with the new version
- Generate changelog based on conventional commits
- Show you the next steps (commit and push)
Then commit and push to main to publish:
git add .
git commit -m "chore: bump version to 0.2.0"
git push origin main
Conventional Commits
The SDK uses Conventional Commits for automatic changelog generation.
Commit Format
<type>(<scope>): <subject>
<body>
<footer>
Types
- feat: A new feature (triggers minor version in semantic versioning)
- fix: A bug fix (triggers patch version)
- docs: Documentation only changes
- style: Code style changes (formatting, missing semi-colons, etc.)
- refactor: Code changes that neither fix bugs nor add features
- perf: Performance improvements
- test: Adding or updating tests
- build: Build system or external dependencies
- ci: CI/CD changes
- chore: Other changes that don't modify src or test files
Examples
feat(server): add webhook signature verification
fix(react): resolve payment form validation issue
docs: update installation instructions
refactor(core): simplify schema validation logic
Breaking Changes
For breaking changes, add BREAKING CHANGE: in the commit body or footer:
feat(server)!: redesign payable API
BREAKING CHANGE: The payable() method now requires an options object
instead of individual parameters.
GitHub Actions Workflows
The SDK uses three automated workflows:
1. Stable Release Workflow (.github/workflows/publish.yml)
Runs manually via GitHub Actions UI (or on push to main if enabled):
- Checks out the repository with full git history
- Installs dependencies using pnpm
- Runs tests to ensure quality
- Bumps version and generates changelog (patch increment)
- Strips preview suffix if present (e.g.,
1.0.0-preview.18→1.0.0) - Increments patch version (e.g.,
1.0.0→1.0.1)
- Strips preview suffix if present (e.g.,
- Builds all packages
- Publishes to npm registry (default
latesttag) - Creates git tag (e.g.,
v1.0.1) - Pushes git tag (version changes are NOT committed back to git)
Important: Version changes are tracked via git tags only, not commits. This prevents branch divergence and version conflicts when merging dev → main.
2. Preview Release Workflow (.github/workflows/publish-preview.yml)
Runs manually via GitHub Actions UI (or on push to dev if enabled):
- Checks out the repository with full git history
- Installs dependencies using pnpm
- Runs tests to ensure quality
- Bumps preview version (e.g.,
0.1.0-preview.1→0.1.0-preview.2) - Builds all packages
- Publishes to npm registry with
previewtag - Creates git tag (e.g.,
v0.1.0-preview.2) - Pushes git tag (version changes are NOT committed back to git)
Important: Version changes are tracked via git tags only, not commits. This prevents branch divergence and version conflicts when merging dev → main.
3. Tag as Latest Workflow (.github/workflows/tag-as-latest.yml)
Manual workflow triggered via GitHub Actions UI:
- Validates the version format
- Checks which packages exist on npm at that version
- Tags all published @solvapay packages as "latest"
- Verifies the tags were applied correctly
This workflow is useful for promoting preview versions to latest without republishing. It includes an optional dry run mode to preview changes before applying them.
Required Secrets
All workflows require the following GitHub secret:
NPM_TOKEN- NPM access token with publish permissions
To set up:
- Go to GitHub repository → Settings → Secrets and variables → Actions
- Add
NPM_TOKENwith your npm access token
Authentication Strategy
The workflows use the modern setup-node@v4 action with registry-url which automatically handles npm authentication via the NODE_AUTH_TOKEN environment variable (set from NPM_TOKEN secret). This is the recommended approach for CI/CD.
Local Publishing (Manual)
For testing or emergency publishing, you can publish manually:
Prerequisites
Authenticate with npm CLI (one-time setup):
npm login
Or set your npm token directly:
npm config set //registry.npmjs.org/:_authToken YOUR_NPM_TOKEN
This stores your credentials in ~/.npmrc globally, so you don't need to authenticate again.
Steps
- Bump version (if needed):
pnpm version:bump # patch
pnpm version:bump:minor # minor
pnpm version:bump:major # major
- Build packages:
pnpm build:packages
- Publish:
pnpm publish:packages
- Commit and push:
git add .
git commit -m "chore: bump version to X.X.X"
git tag "vX.X.X"
git push origin main --tags
Package Access
All packages are published with public access:
@solvapay/core@solvapay/react@solvapay/react-supabase@solvapay/server@solvapay/auth@solvapay/nextcreate-solvapay-app
Authentication Best Practices
The SDK uses a clean dual-authentication strategy:
Local Development (npm CLI)
- Use
npm loginto authenticate once - Credentials stored in
~/.npmrcglobally - No environment variables needed
- Simple and secure
CI/CD (GitHub Actions)
- Use
NPM_TOKENas a GitHub secret setup-nodeaction handles authentication automatically- Uses
NODE_AUTH_TOKENenvironment variable - Industry standard approach
Why this is clean:
- No
.npmrcauth token needed in the repository - Local devs don't manage environment variables
- CI/CD uses secure secret management
- Both methods work independently without conflicts
Troubleshooting
Publishing Fails
- Check NPM_TOKEN: Ensure the token has publish permissions
- Check package names: Verify packages don't already exist with those versions
- Check tests: Ensure all tests pass before publishing
- Check build: Ensure packages build successfully
Version Already Published
If a version already exists on npm, trigger the publish workflow again - it will automatically bump to the next version. No manual version bumping or commits needed.
Workflow Not Triggering
- Workflows are currently set to manual trigger (
workflow_dispatch) - use GitHub Actions UI to run them - Verify GitHub Actions are enabled in repository settings
- Check workflow file syntax in
.github/workflows/publish.yml - Ensure you have the required
NPM_TOKENsecret configured
Preview Versions
Preview versions allow you to publish pre-release versions from the dev branch for testing and early feedback without affecting the stable release channel.
What are Preview Versions?
Preview versions use the format X.Y.Z-preview.N (e.g., 0.1.0-preview.1, 0.1.0-preview.2) and are published to npm with the preview dist-tag. This means:
- Stable installs:
npm install @solvapay/coregets the latest stable version frommain - Preview installs:
npm install @solvapay/core@previewgets the latest preview version fromdev - Specific version:
npm install @solvapay/core@0.1.0-preview.1installs that exact preview
When to Use Preview Versions
Use preview versions when you want to:
- Share in-progress work with team members or early adopters
- Test features in real environments before merging to
main - Iterate quickly on experimental features
- Get feedback on breaking changes
Don't use preview versions for production deployments - they are intentionally unstable and may change rapidly.
Publishing Preview Versions
Preview versions can be published in two ways:
Option A: Automated Publishing (Recommended)
Trigger the preview publish workflow manually via GitHub Actions UI:
- Go to Actions tab in GitHub
- Select Publish Preview to NPM workflow
- Click Run workflow
- The workflow will:
- Run tests
- Bump the preview version
- Publish to npm with
previewtag - Create and push a git tag (version changes are NOT committed back to git)
Note: Version changes are tracked via git tags only to prevent branch divergence.
Option B: Manual Publishing
For manual control or local testing:
Prerequisites: Authenticate with npm (one-time setup):
npm login
Step 1: Bump to Preview Version
# Increments the preview counter
pnpm version:bump:preview
This will:
- Detect your current version (e.g.,
0.1.0) - Increment to next preview (e.g.,
0.1.0-preview.1) - If already a preview, increment the number (e.g.,
0.1.0-preview.1→0.1.0-preview.2) - Update all seven package.json files
Step 2: Build Packages
pnpm build:packages
Step 3: Publish to npm
pnpm publish:preview
This publishes all seven packages with the preview dist-tag.
Step 4: Commit and Push
git add .
git commit -m "chore: bump preview to 0.1.0-preview.1"
git push origin dev
Installing Preview Versions
Users can install preview versions in several ways:
# Get the latest preview version
npm install @solvapay/core@preview
npm install @solvapay/react@preview
npm install @solvapay/react-supabase@preview
npm install @solvapay/server@preview
npm install @solvapay/auth@preview
npm install @solvapay/next@preview
# Install a specific preview version
npm install @solvapay/core@0.1.0-preview.1
# In package.json
{
"dependencies": {
"@solvapay/core": "preview",
"@solvapay/react": "preview",
"@solvapay/react-supabase": "preview",
"@solvapay/server": "preview",
"@solvapay/auth": "preview",
"@solvapay/next": "preview"
}
}
Promoting Preview to Latest
Sometimes you may want to make a preview version the "latest" version on npm (e.g., when preview is more stable than the current latest). This is done through GitHub Actions:
Steps:
- Go to your repository on GitHub
- Click Actions tab
- Select Tag Version as Latest workflow from the left sidebar
- Click Run workflow dropdown (top right)
- Enter the version you want to tag (e.g.,
1.0.0-preview.9) - Optionally enable Dry run to preview what would be tagged without making changes
- Click Run workflow
What it does:
- Validates the version format
- Checks which packages exist on npm at that version
- Tags all published @solvapay packages at that version as "latest"
- Skips any packages that haven't been published yet
- Shows verification of the tags
- No local setup or authentication required!
Dry Run Mode:
Enable the dry run option to see what would be tagged without actually making changes. This is useful for:
- Verifying which packages exist at a specific version
- Testing before actually changing the tags
- Previewing the impact
Benefits:
- ✅ No need to be logged in to npm locally
- ✅ Consistent environment (same as publishing)
- ✅ Audit trail in GitHub Actions logs
- ✅ Can be triggered from anywhere (even mobile!)
- ✅ Dry run option to preview changes
- ✅ Automatic validation and safety checks
Verify the Tags:
After tagging, verify the changes on npm:
npm dist-tag ls @solvapay/core
npm dist-tag ls @solvapay/react
You should see something like:
latest: 1.0.0-preview.9
preview: 1.0.0-preview.9
Important Notes:
- Only published versions can be tagged - the script will skip packages/versions that don't exist on npm
- This changes what users get when they run
npm install @solvapay/core(without a version/tag) - Use this carefully during the preview phase
- All packages are tagged together to maintain version consistency
Preview Version Lifecycle
- Create preview: When you want to share work from
dev - Iterate: Bump preview versions as often as needed
- Stabilize: Once ready, merge
dev→mainfor a stable release - Reset: After merging to
main, the next preview starts fresh (e.g.,0.1.1-preview.1)
Best Practices for Previews
- Publish often - Preview versions are cheap and meant for rapid iteration
- Test locally first - Even previews should work correctly
- Document breaking changes - Let preview users know what changed
- Don't accumulate previews - Merge to
mainregularly to avoid too many preview versions - Communicate - Let users know when a preview is ready to test
Transitioning from Preview to Stable
When you're ready to release a stable version:
- Ensure all tests pass on
dev - Merge
devintomain - Push to
mainto trigger automated publishing - A new stable patch version is automatically created (e.g.,
0.1.1)
The stable version will supersede all preview versions of that base version.
Best Practices
- Always use conventional commits for better changelogs
- Test locally before merging dev → main
- Review the changelog before publishing major versions
- Update documentation when adding features
- Merge dev → main regularly - use squash merges for clean history
- Never merge main → dev - this creates cycles and conflicts
- Versions are tracked via tags - don't manually commit version changes
Skipping Publishing
Since workflows are manually triggered, you can push to main or dev without triggering a publish. The workflows only run when manually triggered via GitHub Actions UI.
Note: Version bump commits are no longer created, so there's no risk of infinite loops.
Notes
- This workflow is optimized for rapid iteration during the preview/alpha phase (0.x versions)
- Future improvements (release branches, pre-releases, etc.) will be added when moving to v1.0+