Sample project demonstrating CalVer (YYYY.MM.DD.MICRO) with hatch
Project description
hatch-calvar-sample-gitlab
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 GitLab CI/CD
- 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
Development Setup
Using Dev Containers (Recommended)
This project includes a VS Code Dev Container configuration for a consistent development environment.
Prerequisites:
Quick Start:
- Open the project in VS Code:
code . - Press
F1→ Select:Dev Containers: Reopen in Container - Wait for container to build and dependencies to install
The container includes:
- Python 3.11 with all development tools
- Pre-commit hooks (automatically installed)
- VS Code extensions for Python development
- All project dependencies pre-installed
See .devcontainer/README.md for detailed instructions.
Local Installation
Installation
pip install hatch-calvar-sample-gitlab
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 GitLab CI/CD for fully automated PyPI releases. No manual tagging required! The workflow consists of two stages:
Stage 1: Auto-tag on Merge
When code is merged to main or master:
- Automatically calculates next CalVer version using
scripts/calc_version.py - Creates a git tag with format
vYYYY.MM.DD.MICRO - Pushes the tag to the repository
Stage 2: Build and Publish
When a git tag matching v* is pushed:
- Extracts version from tag (strips
vprefix) - Validates CalVer format
- Builds package with hatch
- Validates distributions with twine
- Publishes to PyPI using API token authentication
Development Workflow
This project uses a branch-based workflow with merge requests. All changes must go through merge requests - direct pushes to main are not allowed.
-
Create a feature branch:
git checkout main git pull origin main git checkout -b feature/your-feature-name
-
Make your changes and commit:
git add . git commit -m "Your commit message" git push origin feature/your-feature-name
-
Create a merge request:
- GitLab will automatically suggest creating an MR
- Or create manually: GitLab UI → Merge Requests → New merge request
- Fill out the MR template checklist
-
Wait for pipeline to pass:
- All required jobs must pass before merge
- Required jobs:
pre-commit,lint,test,sast-bandit,dependency-scanning,secret-detection,code-quality,build-verify
-
Merge to main:
- Once approved and pipelines pass, merge the MR
- Auto-tag job will run automatically
- Release job will publish to PyPI
Automated Release Steps
- Open a merge request with your changes
- Wait for all pipeline jobs to pass (pre-commit, lint, test, security scans, etc.)
- Get required approvals (if configured)
- Merge the merge request to
main/master - GitLab CI/CD 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
- Calculates next CalVer version (e.g.,
No manual tagging required! The release happens automatically when merge requests are merged.
GitLab CI/CD Pipeline
The project includes a comprehensive .gitlab-ci.yml with the following pipeline stages:
Validate Stage:
- pre-commit: Runs pre-commit hooks (formatting, linting, security)
- lint: Code quality checks (black, isort, ruff, mypy)
Test Stage:
- test: Runs tests across multiple Python versions (3.8-3.12) with coverage reporting (≥70% required)
Security Stage:
- sast-bandit: Static Application Security Testing
- dependency-scanning: Dependency vulnerability scanning (Safety, pip-audit)
- secret-detection: Secret/key detection (Gitleaks)
Quality Stage:
- code-quality: Code complexity and maintainability analysis (Radon, Xenon)
Build Stage:
- build-verify: Builds and verifies package installation across Python 3.9 and 3.11
Compliance Stage:
- license-check: Checks license compliance and generates license reports
Release Stage:
- auto-tag: Automatically creates release tags when code is merged to main/master
- release: Builds and publishes packages to PyPI when tags are pushed
Merge Request Requirements
Before a merge request can be merged, the following must pass:
- ✅ All pipeline jobs (pre-commit, lint, test, security, quality, build)
- ✅ Test coverage ≥70%
- ✅ All discussions resolved
- ✅ Required approvals (if configured)
See CONTRIBUTING.md for detailed development workflow.
To enable PyPI publishing, configure the PYPI_API_TOKEN variable in GitLab CI/CD settings (Settings → CI/CD → Variables).
Manual Release (Optional)
If you need to manually create a release tag (for hotfixes, etc.):
-
Calculate next version:
calver-check calc # Output: 2024.01.18.1
-
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-gitlab/
├── 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
├── .gitlab-ci.yml # GitLab CI/CD pipeline configuration
│ # Includes: test, build-verify, license-check, auto-tag, release
├── 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:
- Package metadata (when installed)
- VERSION file (for development builds)
- 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://gitlab.com/QAToolist/hatch-calvar-sample-gitlab.git
cd hatch-calvar-sample-gitlab
# 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
-
Test version calculation:
python scripts/calc_version.py -
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/*
-
Test installation:
pip install -e . python -c "import hatch_calvar_sample; print(hatch_calvar_sample.__version__)"
Version Calculation Logic
The version calculation script:
- Gets current UTC date →
YYYY.MM.DD - Fetches all git tags (
git fetch --tags) - Parses tags matching CalVer pattern (
YYYY.MM.DD.MICROorvYYYY.MM.DD.MICRO) - Filters tags with the same date
- Extracts MICRO numbers
- Calculates next MICRO =
max(existing) + 1or1if none exist - 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
GitLab CI/CD Issues
For common GitLab CI/CD configuration issues, build problems, and PyPI publishing issues, see the comprehensive GitLab CI/CD Troubleshooting Guide.
Common issues covered:
- CI/CD variable configuration (Protected flags, environment scope)
- Build and package directory issues
- Tag creation and auto-tagging problems
- PyPI publishing failures
- Pipeline configuration errors
Version Not Found
If __version__ is not available:
- Ensure package is installed:
pip install -e . - Check VERSION file exists:
ls src/hatch_calvar_sample/VERSION - Verify git tags:
git tag
Build Errors
If build fails:
- Verify VERSION file exists with valid format
- Check
pyproject.tomldynamic version configuration - Ensure hatch is installed:
pip install hatchling - See GitLab CI/CD Troubleshooting Guide for package directory issues
CLI Not Found
If calver-check command is not available:
- Reinstall package:
pip install -e . - Check entry point in
pyproject.toml - Verify PATH includes Python scripts directory
Contributing
We welcome contributions! Please see CONTRIBUTING.md for detailed guidelines on:
- Development workflow (branch-based with merge requests)
- Branch naming conventions
- Commit message guidelines
- Code standards and testing requirements
- Merge request process
Quick Start:
- Create a branch:
git checkout -b feature/your-feature - Make changes and commit
- Push branch and create merge request
- Wait for pipeline to pass
- Get approval and merge
For more details, see CONTRIBUTING.md.
License
hatch-calvar-sample-gitlab is distributed under the terms of the MIT license.
References
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file hatch_calvar_sample_gitlab-2026.1.20.10.tar.gz.
File metadata
- Download URL: hatch_calvar_sample_gitlab-2026.1.20.10.tar.gz
- Upload date:
- Size: 56.2 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
307d302977e6ccc67a8e43613329b0a3feb4a7673acf6f963374319974854af9
|
|
| MD5 |
f173fe75f64c2ea8f221f572a4360a18
|
|
| BLAKE2b-256 |
354369a5db270a1fdaed35e86600bcee4a8c850bad2a2b9fd453de1ef23fc8e1
|
File details
Details for the file hatch_calvar_sample_gitlab-2026.1.20.10-py3-none-any.whl.
File metadata
- Download URL: hatch_calvar_sample_gitlab-2026.1.20.10-py3-none-any.whl
- Upload date:
- Size: 11.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
eedac49531862def596273cc56457d28f3f5f7cf0bdf5da0e2721f5e6744160c
|
|
| MD5 |
d9b8509417c87c7b883365d4b3c80418
|
|
| BLAKE2b-256 |
0bb4a010087bee35c0dd3f8f61e4b80eb386e827a1c5f41105a922198f6141ba
|