get-next-versions
v0.3.4
Published
Automated versioning tool for monorepos based on conventional commits and package dependencies
Downloads
439
Maintainers
Readme
Get Next Versions
⚠️ Development Status: This package is currently in early development (version < 1.0). The API and functionality may change significantly between releases. Use with caution in production environments.
Automated versioning tool based on conventional commits and package dependencies. Available as both an NPM package and a GitHub Action.
🔄 Fun fact: This package uses itself for versioning! Check out our release-config and release workflow to see how we automate our own version management.
Overview
get-next-versions
is a powerful automated versioning tool designed for both monorepos and single-package repositories. It analyzes your git commit history using conventional commits to automatically determine the next semantic version for your packages. Key features include:
- 🔄 Automated version determination based on conventional commits
- 📦 Support for monorepos with multiple packages
- 🔗 Intelligent dependency tracking between packages
- 🤖 Available as both an NPM package and a GitHub Action
- 🎯 Configurable version bump rules
- 💻 Human-readable CLI output and JSON format for CI environments
How It Works
- Analyzes git commit history since the last version tag
- Parses conventional commit messages to determine version changes
- Tracks dependencies between packages to ensure consistent versioning
- Determines appropriate version bumps based on commit types
- Outputs human-readable or JSON-formatted version information
Important Note on Single-Package Repositories
While this tool could be used with single-package repositories, it was primarily designed and tested for monorepo environments. Using it with single-package repositories comes with some trade-offs:
Configuration Overhead
- You still need to maintain a
release-config.json
file - The monorepo-focused configuration might feel unnecessarily complex for a single package
- You still need to maintain a
Tag Management
- The tag prefix system, while powerful for monorepos, adds an extra layer of complexity
- Standard version tags (e.g.,
v1.0.0
) require explicit configuration - Some existing version management tools might be more straightforward for single packages
Feature Underutilization
- The dependency tracking feature becomes redundant
- The package-scoped commit parsing might be overly strict for single-package needs
For single-package repositories, you might want to consider alternatives like:
standard-version
semantic-release
- GitHub's built-in release management
Installation
You can install this package from either NPM or GitHub Packages:
# From NPM
npm install get-next-versions
# From GitHub Packages
npm install @benjamin-kraatz/get-next-versions
NPM Package Usage
Configuration
Create a release-config.json
file in your repository root:
{
"versionedPackages": [
{
"name": "your-package",
"tagPrefix": "pkg-v",
"directory": "packages/your-package",
"dependsOn": ["packages/*"]
}
]
}
CLI Usage
# Add to package.json scripts
{
"scripts": {
"version-check": "get-next-versions"
}
}
# Run version check (human-readable output)
npm run version-check
The tool automatically detects if it's running in a CI environment (GitHub Actions, Jenkins, etc.) and will output JSON format when appropriate.
GitHub Action Usage
name: Version Check
on:
push:
branches: [ main ]
jobs:
check-version:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
with:
fetch-depth: 0
- name: Check Version
uses: yourusername/get-next-versions@v1
id: version_check
with:
config-path: './release-config.json'
- name: Use Version Info
if: ${{ fromJSON(steps.version_check.outputs.changes).your-package.has_changes }}
run: |
echo "New version: ${{ fromJSON(steps.version_check.outputs.changes).your-package.next_version }}"
Configuration Options
The release-config.json
file is the heart of your versioning configuration. Here's a detailed explanation of each configuration option:
{
"versionedPackages": [
{
"name": "your-package",
"tagPrefix": "pkg-v",
"directory": "packages/your-package",
"dependsOn": ["packages/*"]
}
]
}
Package Configuration Fields Explained
name
(required): The package identifier used in commit messages and for version tracking. This should match the package name in your commit scopes (e.g.,feat(your-package): new feature
).tagPrefix
(required): The prefix used for git version tags. For example, with prefixpkg-v
, tags will look likepkg-v1.0.0
. This allows different packages to maintain independent version histories.directory
(required): The location of your package in the repository. This is used to:- Track direct changes to package files
- Determine when changes affect this package
- Support monorepo structures with multiple packages
dependsOn
(optional): An array of glob patterns indicating which other packages or directories this package depends on. When changes are detected in dependent packages, the current package will also receive a version bump. Examples:["packages/*"]
: Depends on all packages in the packages directory["packages/ui", "packages/core"]
: Depends on specific packages["shared/**"]
: Depends on everything in the shared directory
Git Tags and Version History
The tool relies on git tags to track version history for each package. Here's what you need to know:
Tag Format
- Each package uses its own tag prefix (e.g.,
pkg-v1.0.0
,ui-v2.1.0
) - Tags must follow the format:
{tagPrefix}{version}
- Example: For a package with
tagPrefix: "pkg-v"
, tags should be like:pkg-v0.1.0 pkg-v1.0.0 pkg-v1.1.0
- Each package uses its own tag prefix (e.g.,
Version Detection
- The tool checks commit history since the last matching tag for each package
- If no tag exists for a package, it starts from version
0.0.0
- Each package's version history is tracked independently
Tag Management
- Tags should be created after each version bump
- Can be done manually:
# After confirming version bump to 1.1.0 git tag pkg-v1.1.0 git push origin pkg-v1.1.0
- Or automatically in CI (recommended):
# Example GitHub Action workflow - name: Check Version uses: yourusername/get-next-versions@v1 id: version_check - name: Create Tag if: ${{ fromJSON(steps.version_check.outputs.changes).your-package.has_changes }} run: | NEW_VERSION=${{ fromJSON(steps.version_check.outputs.changes).your-package.next_version }} git tag "pkg-v${NEW_VERSION}" git push origin "pkg-v${NEW_VERSION}"
Best Practices
- Always use unique tag prefixes for each package
- Keep tags synchronized between all environments
- In CI, use
fetch-depth: 0
to ensure full git history - Consider automating tag creation to avoid manual errors
Version Bump Rules
The tool follows semantic versioning (MAJOR.MINOR.PATCH) rules based on conventional commits:
Major Version (1.0.0 → 2.0.0) Breaking changes are detected from:
- Commits with a breaking change marker:
feat(pkg)!: message
- Commits with a BREAKING CHANGE footer:
feat(pkg): message BREAKING CHANGE: description of breaking change
- Commits with a breaking change marker:
Minor Version (1.0.0 → 1.1.0) New features are detected from:
- Feature commits:
feat(pkg): message
- New functionality that doesn't break existing code
- Feature commits:
Patch Version (1.0.0 → 1.0.1) Patches are detected from various commit types:
- Bug fixes:
fix(pkg): message
- Documentation:
docs(pkg): message
- Styles:
style(pkg): message
- Code refactoring:
refactor(pkg): message
- Performance improvements:
perf(pkg): message
- Tests:
test(pkg): message
- Build changes:
build(pkg): message
- CI changes:
ci(pkg): message
- Chores:
chore(pkg): message
- Bug fixes:
CLI Output Formats
The tool provides two output formats:
Human-Readable Output (default in non-CI environments):
🚀 Release Check Summary ================================================== 📦 Changes Detected: ✓ your-package: 5 commits 📝 Version Updates: ✓ your-package: pkg-v1.0.0 → pkg-v1.1.0 🔍 Detailed Changes: your-package: • abc1234 feat(your-package): add new feature ↳ Direct changes in packages/your-package • def5678 fix(your-package): fix bug ↳ Direct changes in packages/your-package
JSON Output (automatic in CI environments):
{ "your-package": { "currentVersion": "1.0.0", "nextVersion": "1.1.0", "hasChanges": true } }
Best Practices
Commit Messages
- Always use conventional commit format:
type(scope): message
- Include package name in the scope
- Use clear and descriptive messages
- Always use conventional commit format:
Configuration
- Keep
release-config.json
in your repository root - Use specific
dependsOn
patterns to avoid unnecessary version bumps - Choose clear and consistent
tagPrefix
values
- Keep
Monorepo Usage
- Configure each package separately in
versionedPackages
- Use
dependsOn
to manage package relationships - Maintain independent version histories with unique
tagPrefix
- Configure each package separately in
CI Integration
- Use the GitHub Action for automated version checks
- Leverage JSON output for automated workflows
- Consider implementing automated release processes
Troubleshooting
Common issues and solutions:
No Version Changes Detected
- Verify your commit messages follow conventional commit format
- Check if changes are in the correct package directory
- Ensure your git history is complete (use
fetch-depth: 0
in CI)
Unexpected Version Bumps
- Review
dependsOn
patterns for over-broad matches - Check commit messages for correct package scopes
- Verify breaking change syntax in commits
- Review
Missing Git History
- Ensure you have fetched all tags:
git fetch --tags
- In GitHub Actions, use
fetch-depth: 0
- Verify tag prefix matches your configuration
- Ensure you have fetched all tags:
Development
# Install dependencies
npm install
# Run tests
npm test
# Build
npm run build
Requirements
- Node.js >= 20
License
MIT