After experiencing "merge hell" with v3 – it really was hell – this project now uses a Trunk-Based / Tag-driven workflow. This keeps the codebase clean, ensures CI runs on the latest code, and makes releases predictable.
master: The "Trunk". This is the active development area for the current major version. All PRs target this branch. It must always pass tests.feat/orfix/: Short-lived branches for specific tasks. These are deleted immediately after merging.support/v[x]: Maintenance branches for older major versions (e.g.,support/v3). These are only created if a critical patch is needed for a previous major release.
We use Git Tags to trigger GitHub Actions and automate npm publishing.
- Create a task branch:
git checkout -b feat/my-feature - Open a Pull Request to
master. - After merge, delete the task branch.
To ship a version for testing:
- Tag the commit:
git tag vX.X.X-beta.x - Push the tag:
git push origin vX.X.X-beta.x - Action publishes this to npm under the
@nexttag.
When a version is ready for production:
- Tag the commit:
git tag vX.X.X - Push the tag:
git push origin vX.X.X - Action publishes this to npm under the
@latesttag.
If a bug is found in a previous major version:
-
Checkout the corresponding
support/v[x]branch. -
Apply the fix and tag a new patch (e.g.,
v1.0.5). -
Publish the maintenance release under a dedicated dist-tag so it doesn't overwrite
@lateston npm. Example approaches:- Publish with a tag directly:
npm publish --tag support-v1 - Or publish normally and then add a dist-tag:
npm dist-tag add <package>@<version> support-v1
Use a clear tag (e.g.,
support-v1) so users can opt into older major releases without changing@latest. - Publish with a tag directly:
-
If the bug exists in the current version, port the fix to
master.