Skip to main content

Sample project demonstrating CalVer (YYYY.MM.DD.MICRO) with hatch

Project description

hatch-calvar-sample

PyPI - Version PyPI - Python Version

Sample hatch-based Python project demonstrating Calendar Versioning (CalVer) with format YYYY.MM.DD.MICRO and automated PyPI release workflows.

Overview

This project serves as a proof-of-concept for implementing CalVer versioning with the hatch build system. It demonstrates:

  • Calendar Versioning (YYYY.MM.DD.MICRO) calculated from git tags
  • Dynamic versioning with hatch build system
  • Version checking CLI tool with multiple commands
  • Automated PyPI release via GitHub Actions
  • Complete release workflow automation

Version Format

The project uses CalVer format: YYYY.MM.DD.MICRO

  • YYYY - 4-digit year (e.g., 2024)
  • MM - 2-digit month (01-12)
  • DD - 2-digit day (01-31)
  • MICRO - Sequential number for releases on the same day (1, 2, 3, ...)

Examples: 2024.01.18.1, 2024.01.18.2, 2024.03.15.1

Installation

pip install hatch-calvar-sample

Features

Version Calculation

The project includes a script that automatically calculates the next CalVer version based on:

  • Current UTC date
  • Existing git tags matching the CalVer pattern
  • Automatic MICRO increment for same-day releases

CLI Tool

The calver-check CLI provides multiple commands for version management:

# Calculate next version
calver-check calc

# Check current version from different sources
calver-check check

# Validate version format
calver-check validate 2024.01.18.1

# Compare two versions
calver-check compare 2024.01.18.1 2024.01.18.2

# Show version information
calver-check info

All commands support --json flag for machine-readable output:

calver-check calc --json

Usage Examples

Calculating Next Version

# Using the script directly
python scripts/calc_version.py

# Using the CLI tool
calver-check calc

# With validation
python scripts/calc_version.py --validate --pep440

Checking Current Version

# Check version from package metadata
calver-check check

# Check with JSON output
calver-check check --json

Validating Version Format

# Validate a version string
calver-check validate 2024.01.18.1

# Invalid version will exit with error
calver-check validate 2024.1.18.1

Comparing Versions

# Compare two versions
calver-check compare 2024.01.18.1 2024.01.18.2
# Output: 2024.01.18.1 < 2024.01.18.2

Release Process

Fully Automated Release Workflow

The project uses GitHub Actions for fully automated PyPI releases. No manual tagging required! The workflow consists of two stages:

Stage 1: Auto-tag on PR Merge

When a pull request is merged to main or master:

  1. Automatically calculates next CalVer version using scripts/calc_version.py
  2. Creates a git tag with format vYYYY.MM.DD.MICRO
  3. Pushes the tag to the repository

Stage 2: Build and Publish

When a git tag matching v* is pushed:

  1. Extracts version from tag (strips v prefix)
  2. Validates CalVer format
  3. Builds package with hatch
  4. Validates distributions with twine
  5. Publishes to PyPI using Trusted Publishing

Automated Release Steps

  1. Open a pull request with your changes
  2. Merge the pull request to main/master
  3. GitHub Actions automatically:
    • Calculates next CalVer version (e.g., 2024.01.18.1)
    • Creates tag v2024.01.18.1
    • Builds the package
    • Validates version format
    • Publishes to PyPI

No manual tagging required! The release happens automatically when PRs are merged.

Manual Release (Optional)

If you need to manually create a release tag (for hotfixes, etc.):

  1. Calculate next version:

    calver-check calc
    # Output: 2024.01.18.1
    
  2. Create and push git tag:

    git tag v2024.01.18.1 -m "Release 2024.01.18.1"
    git push origin v2024.01.18.1
    

The tag push will trigger the same build and publish workflow.

Using Makefile

For convenience, use the Makefile targets:

# Calculate next version
make version-calc

# Check current version
make version-check

# Validate version format
make version-validate VERSION=2024.01.18.1

# Create and push release tag
make release-tag

# Build package for testing
make build-test

Project Structure

hatch-calvar-sample/
├── pyproject.toml              # Hatch configuration with dynamic versioning
├── README.md                   # This file
├── CHANGELOG.md                # Changelog with CalVer format
├── LICENSE.txt                 # MIT license
├── Makefile                    # Convenient make targets
├── .github/
│   └── workflows/
│       ├── auto-tag.yml        # Auto-create tag on PR merge
│       └── release.yml         # Automated PyPI release workflow
├── scripts/
│   └── calc_version.py         # Version calculation script
├── src/
│   └── hatch_calvar_sample/
│       ├── __init__.py         # Package with __version__
│       ├── __about__.py        # Version metadata
│       ├── VERSION             # Version file (generated during build)
│       └── cli.py              # Version checking CLI implementation
└── tests/
    ├── test_version_calc.py    # Tests for version calculation
    └── test_version_cli.py     # Tests for CLI tool

Configuration

Dynamic Versioning

The project uses hatch's dynamic versioning feature configured in pyproject.toml:

[tool.hatch.version]
path = "src/hatch_calvar_sample/VERSION"

The VERSION file is created during the release workflow with the version extracted from the git tag.

Version Metadata in Code

The package reads version from importlib.metadata when installed, with fallbacks:

  1. Package metadata (when installed)
  2. VERSION file (for development builds)
  3. Environment variable HATCH_CALVER_VERSION

Access version programmatically:

from hatch_calvar_sample import __version__

print(__version__)  # Output: 2024.01.18.1

Development

Setting Up Development Environment

# Clone the repository
git clone https://github.com/QAToolist/hatch-calvar-sample.git
cd hatch-calvar-sample

# Install in development mode
pip install -e .

# Install development dependencies
pip install pytest

Running Tests

# Run all tests
pytest

# Run specific test file
pytest tests/test_version_calc.py

# Run with coverage
pytest --cov=hatch_calvar_sample --cov=scripts

Local Testing

  1. Test version calculation:

    python scripts/calc_version.py
    
  2. Test build process:

    # Create VERSION file manually
    echo "2024.01.18.1" > src/hatch_calvar_sample/VERSION
    
    # Build package
    hatch build
    
    # Check built package
    twine check dist/*
    
  3. Test installation:

    pip install -e .
    python -c "import hatch_calvar_sample; print(hatch_calvar_sample.__version__)"
    

Version Calculation Logic

The version calculation script:

  1. Gets current UTC date → YYYY.MM.DD
  2. Fetches all git tags (git fetch --tags)
  3. Parses tags matching CalVer pattern (YYYY.MM.DD.MICRO or vYYYY.MM.DD.MICRO)
  4. Filters tags with the same date
  5. Extracts MICRO numbers
  6. Calculates next MICRO = max(existing) + 1 or 1 if none exist
  7. Returns: YYYY.MM.DD.MICRO

Edge Cases Handled

  • No tags → Returns YYYY.MM.DD.1
  • Multiple tags same date → Increments MICRO correctly
  • Date boundary crossing → Resets MICRO to 1 for new date
  • Invalid tag formats → Skipped gracefully
  • Timezone handling → Uses UTC for consistency

PEP 440 Compliance

CalVer format YYYY.MM.DD.MICRO is PEP 440 compliant as a release segment. The format:

  • Uses numeric components
  • Follows semantic ordering (newer dates > older dates)
  • Valid for PyPI distribution

Validate PEP 440 compliance:

calver-check validate 2024.01.18.1
python scripts/calc_version.py --pep440

Troubleshooting

Version Not Found

If __version__ is not available:

  1. Ensure package is installed: pip install -e .
  2. Check VERSION file exists: ls src/hatch_calvar_sample/VERSION
  3. Verify git tags: git tag

Build Errors

If build fails:

  1. Verify VERSION file exists with valid format
  2. Check pyproject.toml dynamic version configuration
  3. Ensure hatch is installed: pip install hatchling

CLI Not Found

If calver-check command is not available:

  1. Reinstall package: pip install -e .
  2. Check entry point in pyproject.toml
  3. Verify PATH includes Python scripts directory

Contributing

This is a sample project for demonstration purposes. If you find it useful or want to adapt it for your project:

  1. Review the implementation details in scripts and source code
  2. Check the GitHub Actions workflow for CI/CD patterns
  3. Adapt the configuration for your project structure

License

hatch-calvar-sample is distributed under the terms of the MIT license.

References

Demo Change

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

hatch_calvar_sample-2026.1.18.6.tar.gz (18.7 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

hatch_calvar_sample-2026.1.18.6-py3-none-any.whl (9.1 kB view details)

Uploaded Python 3

File details

Details for the file hatch_calvar_sample-2026.1.18.6.tar.gz.

File metadata

File hashes

Hashes for hatch_calvar_sample-2026.1.18.6.tar.gz
Algorithm Hash digest
SHA256 2c950b7f4f5d592647d54ef51337f17e1133a9d6bebbec02af3ef8746434784e
MD5 7c0dffe4a1afeea6d4072e718da31e11
BLAKE2b-256 afe50d8522b74a888087d40e7a1a5c6deb3456db89a44b6ef3252fdb66571978

See more details on using hashes here.

Provenance

The following attestation bundles were made for hatch_calvar_sample-2026.1.18.6.tar.gz:

Publisher: release.yml on qatoolist/hatch-calvar-sample

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file hatch_calvar_sample-2026.1.18.6-py3-none-any.whl.

File metadata

File hashes

Hashes for hatch_calvar_sample-2026.1.18.6-py3-none-any.whl
Algorithm Hash digest
SHA256 5918a8f49c58ab241bd60bcadd74b4f43cb2126ad5a1bed7519460ed6652e0ed
MD5 0c9b0695cbe4566c9c9e5dd8bc5e8531
BLAKE2b-256 72bebc555aeef022827dacca12264624a0041db0fd76904cfcd978d97bf23194

See more details on using hashes here.

Provenance

The following attestation bundles were made for hatch_calvar_sample-2026.1.18.6-py3-none-any.whl:

Publisher: release.yml on qatoolist/hatch-calvar-sample

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page