Developer Workflow with Changesets
This guide explains how to use changesets for version management and changelog generation in the ERP-Unlocked monorepo. For the full end-to-end release pipeline, see Releasing.
Table of Contents
Section titled “Table of Contents”- Overview
- Making Changes
- Creating a Changeset
- Checking Release Status
- Version Types
- Release Process
- Pre-commit Hook
- Troubleshooting
Overview
Section titled “Overview”ERP-Unlocked uses Changesets to manage versions and changelogs across the monorepo. Each time you make a change to any app or package, you create a changeset that describes what changed and what type of change it is (major, minor, or patch).
Making Changes
Section titled “Making Changes”The typical workflow for making changes:
- Create a new branch for your feature/fix
- Make your code changes
- Before committing: Create a changeset
- Commit both your changes and the changeset file
- Push and create a pull request against
staging
Creating a Changeset
Section titled “Creating a Changeset”Step 1: Run the changeset command
Section titled “Step 1: Run the changeset command”After making your code changes, run:
pnpm changesetStep 2: Select affected packages
Section titled “Step 2: Select affected packages”The CLI will prompt you to select which apps or packages have changed. Use the arrow keys and spacebar to select from the workspace apps and packages:
Apps (apps/*):
@erp-unlocked/webapp(apps/webapp) - Main customer application@erp-unlocked/internal(apps/internal) - Internal admin application@repo/temporal-worker(apps/temporal-worker) - Primary Python Temporal worker@repo/ts-temporal-worker(apps/ts-temporal-worker) - TypeScript Temporal worker@erp-unlocked/dagster(apps/dagster) - Dagster data pipeline orchestration@erp-unlocked/email-worker(apps/email-worker) - Inbound email Cloudflare Workerops-mcp(apps/ops-mcp),@erp-unlocked/content-mcp(apps/content-mcp),graph-mcp(apps/graph-mcp) - MCP serverspartner-data-api(apps/partner-data-api),tidycal-hubspot-sync(apps/tidycal-hubspot-sync),@repo/docs(apps/docs)
Shared Packages (packages/*):
@repo/db,@repo/ui,@repo/auth,@repo/utils,@repo/ai,@repo/observability,@repo/feature-flags,@repo/contracts,@repo/eval,@repo/integrations,@repo/mcp-oauth,@repo/pricing,@repo/mockoon(and Python packagespackages/pdf-shared,packages/erp-data-py,packages/erp-sql-py,packages/feature-flags-py)
Step 3: Choose the version bump type
Section titled “Step 3: Choose the version bump type”For each selected package, choose the type of change:
- patch - Bug fixes and minor changes (0.1.0 → 0.1.1)
- minor - New features, backward compatible (0.1.0 → 0.2.0)
- major - Breaking changes (0.1.0 → 1.0.0)
Step 4: Write a summary
Section titled “Step 4: Write a summary”Provide a clear, concise summary of the changes. This will appear in the changelog:
Good Examples:
Fixed order validation to properly handle decimal quantitiesAdded support for custom tax rates in the order editorBREAKING: Removed support for legacy CSV formatBad Examples:
Fixed bugUpdated codeStep 5: Commit the changeset
Section titled “Step 5: Commit the changeset”The changeset will be saved to .changeset/random-words-here.md. Commit this file along with your code changes:
git add .changeset/random-words-here.mdgit commit -m "feat: add custom tax rates support"Checking Status
Section titled “Checking Status”View pending releases
Section titled “View pending releases”See what would be released based on current changesets:
pnpm version:checkDetailed view of pending releases
Section titled “Detailed view of pending releases”For more detailed information about what will change:
pnpm version:previewCheck if changesets exist
Section titled “Check if changesets exist”Verify that all necessary changesets are present:
pnpm changeset:statusVersion Types
Section titled “Version Types”Changesets uses Semantic Versioning (SemVer):
Patch (0.1.0 → 0.1.1)
Section titled “Patch (0.1.0 → 0.1.1)”Use for:
- Bug fixes
- Documentation updates
- Internal refactoring
- Performance improvements
Example:
# Select: patch# Summary: Fixed PDF extraction error for invoices with special charactersMinor (0.1.0 → 0.2.0)
Section titled “Minor (0.1.0 → 0.2.0)”Use for:
- New features
- New API endpoints
- Backward-compatible functionality additions
- UI enhancements
Example:
# Select: minor# Summary: Added bulk order import feature with CSV uploadMajor (0.1.0 → 1.0.0)
Section titled “Major (0.1.0 → 1.0.0)”Use for:
- Breaking changes
- API changes that require client updates
- Removal of deprecated features
- Database schema changes
Example:
# Select: major# Summary: BREAKING: Changed authentication to require organization contextRelease Process (Maintainers Only)
Section titled “Release Process (Maintainers Only)”See Releasing for the authoritative runbook.
Automated Release Flow
Section titled “Automated Release Flow”Staging Branch (Automated via release.yml + ordermatic-release-bot)
Section titled “Staging Branch (Automated via release.yml + ordermatic-release-bot)”- All feature PRs merge into
stagingwith a.changeset/*.mdfile (enforced by.husky/pre-commitand theChangeset requiredCI check). .github/workflows/release.ymlruns on an hourly cron schedule (or via manualworkflow_dispatch) againststaging.- Using the
ordermatic-release-botGitHub App token (RELEASE_APP_ID+RELEASE_APP_PRIVATE_KEY),release.ymlopens or updates theVersion Packages (staging)PR (changeset-release/staging), consuming pending.changeset/*.mdfiles, bumpingpackage.jsonversions, and updatingCHANGELOG.mdfiles. release.ymlautomatically approves and squash-merges theVersion Packages (staging)PR once required status checks pass.- Pushes to
stagingtrigger.github/workflows/gcp-deploy.yml→ GCP Cloud Build to deploy updated services to staging.
Production Promotion (staging → main)
Section titled “Production Promotion (staging → main)”- No one merges or pushes to
maindirectly, andrelease.ymlnever runs onmain. - A maintainer promotes
stagingtomainby manually dispatching.github/workflows/auto-deploy-main.yml:Terminal window gh workflow run auto-deploy-main.yml --ref staging auto-deploy-main.ymlverifiesmainis an ancestor ofstagingand fast-forwardsmainto the exactstagingcommit SHA, triggering production deploys viagcp-deploy.yml→ Cloud Build.
Manual Release Dispatch
Section titled “Manual Release Dispatch”Never run pnpm version:apply or scripts/release.sh locally on your machine, and never push directly to staging or main.
To trigger version consumption on staging immediately instead of waiting for the hourly cron:
# Consume pending changesets on staging and auto-merge Version Packages PRgh workflow run release.yml --ref staging
# Promote staging to production (fast-forward main to staging)gh workflow run auto-deploy-main.yml --ref stagingPre-commit Hook
Section titled “Pre-commit Hook”The repository has a .husky/pre-commit hook that enforces changeset creation. If you stage changes under apps/ or packages/ without also staging a .changeset/*.md file, the hook blocks the commit (exit 1):
⚠️ Staged changes under apps/ or packages/ but no staged .changeset/*.md.
Please run: pnpm changesetThen git add the new file under .changeset/Or skip with: git commit --no-verifySkipping the hook
Section titled “Skipping the hook”In rare cases where a changeset is not needed (e.g., CI config changes), you can skip the hook:
git commit --no-verify -m "ci: update workflow configuration"Note: Use --no-verify sparingly. Most code changes should have a changeset.
Troubleshooting
Section titled “Troubleshooting”“No packages selected” error
Section titled ““No packages selected” error”Make sure you’ve made changes to files in apps/ or packages/ directories. Changesets only tracks versioned packages.
Changeset file conflicts
Section titled “Changeset file conflicts”If multiple developers create changesets simultaneously, you may encounter conflicts in changeset files. To resolve:
- Keep both changeset files (they have unique names)
- Don’t try to merge the content
- Both changesets will be processed during release
Pre-commit hook issues
Section titled “Pre-commit hook issues”If the pre-commit hook is not working:
# Reinstall hookspnpm prepareChangeset not detected in CI
Section titled “Changeset not detected in CI”Ensure the changeset file is committed and pushed:
git statusgit add .changeset/*.mdgit commit -m "chore: add changeset"git pushDocker Image Versioning
Section titled “Docker Image Versioning”Production and staging images in GCP Artifact Registry are built by cloudbuild.yaml and tagged with the git commit SHA (and latest), while package.json and CHANGELOG.md files track semantic versions via Changesets.
Examples
Section titled “Examples”Example 1: Bug Fix in Webapp
Section titled “Example 1: Bug Fix in Webapp”# 1. Make the fix# 2. Create changesetpnpm changeset# Select: @erp-unlocked/webapp# Type: patch# Summary: Fixed date formatting in order history
# 3. Commitgit add .git commit -m "fix: correct date formatting in order history"git pushExample 2: New Feature Across Multiple Apps
Section titled “Example 2: New Feature Across Multiple Apps”# 1. Implement feature in webapp and internal# 2. Create changesetpnpm changeset# Select: @erp-unlocked/webapp, @erp-unlocked/internal# Type: minor for both# Summary: Added real-time order status updates
# 3. Commitgit add .git commit -m "feat: add real-time order status updates"git pushExample 3: Breaking Change in Webapp API
Section titled “Example 3: Breaking Change in Webapp API”# 1. Make breaking changes to API# 2. Create changesetpnpm changeset# Select: @erp-unlocked/webapp# Type: major# Summary: BREAKING: Changed /api/erp/orders endpoint to require organization context
# 3. Commitgit add .git commit -m "feat!: require organization context in order endpoints"git pushBest Practices
Section titled “Best Practices”- One changeset per logical change - Don’t combine unrelated changes
- Write clear summaries - They become your changelog
- Use conventional commit messages - Helps with PR organization
- Create changesets early - Don’t wait until the PR is ready
- Review changesets in PRs - Ensure accuracy before merging
- Keep changesets focused - Smaller, focused changes are easier to review
Additional Resources
Section titled “Additional Resources”For questions or issues with the changeset workflow, please reach out to the maintainers or create an issue in the repository.