This document describes the versioning and release process for agentspaces.
The application version must be maintained in two locations that must stay synchronized:
-
src/agentspaces/__init__.py(primary source of truth)__version__ = "0.1.0"
- Used by the application at runtime
- Displayed by
agentspaces --versioncommand - Imported throughout the codebase when version is needed
-
pyproject.toml(build metadata)[project] version = "0.1.0"
- Used by Hatchling during the build process
- Published to PyPI package metadata
- Required for
pip installand package distribution
Automated Validation:
A CI check (scripts/check_version.py) automatically validates that both files contain the same version on every pull request. This prevents version drift from reaching the main branch.
agentspaces follows Semantic Versioning 2.0.0:
MAJOR.MINOR.PATCH
Version Increment Rules:
-
MAJOR (1.0.0): Breaking changes to CLI commands, API, or data formats
- Existing workspaces may not work
- Commands removed or significantly changed
- Configuration format changed
- Examples: Removing commands, changing command syntax, incompatible metadata format
-
MINOR (0.1.0): New features, backward-compatible changes
- New commands added
- New flags or options added
- Enhanced functionality that doesn't break existing usage
- Examples: Adding new subcommands, new optional flags
-
PATCH (0.0.1): Bug fixes, documentation updates, internal refactoring
- No user-facing changes beyond bug fixes
- Performance improvements
- Examples: Fixing crashes, correcting error messages, updating docs
Pre-1.0.0 Versioning:
- Currently in 0.x.y range (pre-stable)
- MINOR version changes may include breaking changes until 1.0.0
- Document all breaking changes in release notes
This project uses Conventional Commits for commit messages. This enables automated versioning and CHANGELOG generation.
Commit Message Format:
<type>(<scope>): <description>
[optional body]
[optional footer]
Types that trigger releases:
feat: New feature (triggers MINOR version bump)fix: Bug fix (triggers PATCH version bump)perf: Performance improvement (triggers PATCH version bump)
Types that don't trigger releases:
docs: Documentation changesstyle: Code style changes (formatting, etc.)refactor: Code refactoring without behavior changetest: Adding or updating testschore: Maintenance tasksci: CI/CD changesbuild: Build system changes
Breaking Changes:
Add ! after type or BREAKING CHANGE: in footer to trigger MAJOR version bump:
feat!: remove workspace sync command
BREAKING CHANGE: The sync command has been removed. Use create instead.
Examples:
feat: add workspace sync command
fix: handle missing .python-version file
docs: update README with installation instructions
refactor: extract path resolution to infrastructure
feat(cli)!: change workspace create to require branch argumentThe project uses python-semantic-release for automated versioning and releases.
How it works:
- Commit with conventional commits to main branch
- GitHub Actions automatically:
- Analyzes commit messages since last release
- Determines version bump (major/minor/patch)
- Updates version in
__init__.pyandpyproject.toml - Generates CHANGELOG.md entries
- Creates git tag (
vX.Y.Z) - Creates GitHub release with notes
- Validates version consistency
Workflow:
# 1. Make changes and commit using conventional commits
git add .
git commit -m "feat: add new workspace feature"
# 2. Push to main (directly or via PR merge)
git push origin main
# 3. GitHub Actions automatically creates release
# - Version is bumped based on commit type
# - Tag and GitHub release are created
# - CHANGELOG is updatedVersion determination:
feat:commits → MINOR version bump (0.1.0 → 0.2.0)fix:orperf:commits → PATCH version bump (0.1.0 → 0.1.1)feat!:orBREAKING CHANGE:→ MAJOR version bump (0.1.0 → 1.0.0)- Other commits (docs, chore, etc.) → No release
Skip automatic release:
Add [skip ci] to your commit message to prevent automatic release:
git commit -m "docs: update README [skip ci]"Use manual releases only when:
- Testing the release process locally
- Creating a release without CI/CD (e.g., initial setup)
- Recovering from a failed automated release
- Creating a hotfix outside the normal workflow
For normal development, always use the automated release process.
a. Ensure clean working tree:
git status
# Should show no uncommitted changesb. Run full test suite:
uv run ruff check src/ tests/ --fix
uv run ruff format src/ tests/
uv run mypy src/
uv run pytest --cov=srcAll checks must pass before proceeding.
c. Update version numbers:
Decide on the new version number based on semantic versioning rules, then update both files:
# Example: bumping from 0.1.0 to 0.2.0
# Update src/agentspaces/__init__.py
__version__ = "0.2.0"
# Update pyproject.toml
version = "0.2.0"d. Verify version display and consistency:
# Test the CLI displays the new version
uv run agentspaces --version
# Should output: agentspaces 0.2.0
# Run the CI version validation check
python scripts/check_version.py
# Should output: ✅ Version consistency check passed: 0.2.0Commit the version bump with a standardized message:
git add src/agentspaces/__init__.py pyproject.toml
git commit -m "chore: bump version to 0.2.0"Commit message format:
chore: bump version to X.Y.Z
Create an annotated tag matching the version:
# Create annotated tag with version info
git tag -a v0.2.0 -m "Release version 0.2.0"
# View the tag
git show v0.2.0Tag naming convention:
- Format:
vX.Y.Z(with 'v' prefix) - Examples:
v0.1.0,v0.2.0,v1.0.0 - Use annotated tags (with
-aflag), not lightweight tags - Tag message should be:
"Release version X.Y.Z"
Push both the commit and the tag:
# Push the commit
git push origin main
# Push the tag
git push origin v0.2.0
# Or push all tags at once (use with caution)
git push origin --tagsWhen ready to publish to PyPI:
# Build the package
uv build
# Publish to PyPI (requires PyPI credentials)
uv publishNote: PyPI publishing is not yet configured.
After release, verify the version is correct:
# Check version command
agentspaces --version
# Check git tag
git describe --tags
# Check latest tag
git tag -l --sort=-version:refname | head -n 1Use this checklist for each release:
- All tests passing (
uv run pytest) - Code formatted (
uv run ruff format) - Linting clean (
uv run ruff check) - Type checking passes (
uv run mypy src/) - Version updated in
src/agentspaces/__init__.py - Version updated in
pyproject.toml - Versions match in both files
-
agentspaces --versiondisplays correct version - Version bump commit created (
chore: bump version to X.Y.Z) - Git tag created (
git tag -a vX.Y.Z -m "Release version X.Y.Z") - Changes pushed to remote (
git push origin main) - Tag pushed to remote (
git push origin vX.Y.Z) - GitHub release created (optional, future)
- PyPI package published (optional, future)
# From CLI
agentspaces --version
# From code
python -c "from agentspaces import __version__; print(__version__)"
# From git tags
git describe --tags --abbrev=0# Run the CI validation check locally
python scripts/check_version.py
# Or check both locations manually
grep "__version__" src/agentspaces/__init__.py
grep "^version" pyproject.toml# Show all version tags
git tag -l 'v*' --sort=-version:refname
# Show tags with dates
git tag -l 'v*' --sort=-version:refname --format='%(refname:short) %(creatordate:short)'# Show changes between versions
git log v0.1.0..v0.2.0 --oneline
# Show detailed diff
git diff v0.1.0..v0.2.0If versions get out of sync:
# Check both locations
grep "__version__" src/agentspaces/__init__.py
grep "^version" pyproject.toml
# Update to match (example)
# Edit both files to match, then:
git add src/agentspaces/__init__.py pyproject.toml
git commit -m "chore: sync version numbers to 0.2.0"# Delete local tag
git tag -d v0.2.0
# Delete remote tag
git push origin :refs/tags/v0.2.0This section provides a high-level summary of major releases. For detailed changes, see CHANGELOG.md.
When to update: After each release (automated or manual), add an entry here summarizing the major themes and breaking changes.
Format:
- **vX.Y.Z** (YYYY-MM-DD) - Brief description
- Key feature or change
- Breaking changes (if any)
- v0.1.0 (2024-12-22) - Initial release
- Core workspace management
- Git worktree integration
- Basic CLI commands
- Automated releases: CHANGELOG.md is automatically updated by semantic-release
- Manual releases: Update CHANGELOG.md manually before creating the release
- Never manually edit version in one location without updating the other
- Always use annotated tags (
-aflag) for releases - Tag names must match version with 'v' prefix (e.g.,
v0.2.0) - Test the version command before creating tags
- Use conventional commit messages to enable automated versioning
- Keep the Version History section updated with major release summaries