Describe how GET /api/openapi.json sets info.version via get_version_from_setup() (setup.py at runtime, with TIMETRACKER_VERSION or APP_VERSION overrides and Flask APP_VERSION fallback), and point contributors to the same rules in version management and project structure docs. Update the documentation audit entry for the former hardcoded OpenAPI version gap, document tests/test_api_route_contract.py and the refined test_api_v1 isolation guidance in the testing strategy, add a quick-reference pytest invocation for the contract suite, and note info.version in the API consistency audit next to the OpenAPI references.
12 KiB
Version Management System
This document describes the comprehensive version management system for TimeTracker that provides flexible versioning for both GitHub releases and build numbers.
For contributors: Application version is defined only in setup.py. Do not duplicate it in README or other docs. Desktop and mobile builds may use their own version numbers; see BUILD.md and repo scripts.
OpenAPI (/api/openapi.json): The info.version field uses the same resolution as the in-app version helpers: environment variables TIMETRACKER_VERSION or APP_VERSION override the value read from setup.py; see get_version_from_setup() in app/config/analytics_defaults.py and openapi_spec() in app/routes/api_docs.py.
Overview
The version management system provides multiple ways to set version tags:
- GitHub Releases - Automatic versioning when creating releases
- Git Tags - Manual version tagging for releases
- Build Numbers - Automatic versioning for branch builds
- Manual Workflow Dispatch - Custom version input through GitHub Actions
- Local Version Management - Command-line tools for version management
Version Format Support
The system supports various version formats:
Semantic Versions
v1.2.3- Full semantic version (recommended for releases)1.2.3- Semantic version without 'v' prefixv1.2- Major.Minor versionv1- Major version only
Build Versions
build-123- Build number formatmain-build-456- Branch-specific buildfeature-build-789- Feature branch build
Pre-release Versions
rc1- Release candidatebeta1- Beta versionalpha1- Alpha versiondev-123- Development version
GitHub Actions Workflow
Automatic Version Detection
The GitHub Actions workflow automatically determines the version based on the trigger:
- Manual Workflow Dispatch - Uses custom input version
- GitHub Release - Uses release tag name
- Git Tag - Uses git tag name
- Branch Push - Uses branch name + build number
- Fallback - Uses commit SHA
Version Priority
# Priority order for version determination:
# 1. Manual workflow dispatch input
# 2. GitHub release tag
# 3. Git tag
# 4. Branch name with build number
# 5. Fallback to commit SHA
Tag Strategy
- Releases/Tags: Tagged as both
versionandlatest - Main Branch Builds: Tagged as both
versionandmain - Feature Branches: Tagged only as
version - Pull Requests: Build but don't push (preview only)
Usage Methods
1. GitHub Releases (Recommended)
Create a GitHub release to automatically trigger a build with the release version:
- Go to GitHub repository → Releases → "Create a new release"
- Choose a tag (e.g.,
v1.2.3) or create a new one - Fill in release title and description
- Publish the release
- GitHub Actions automatically builds and pushes the Docker image
Result: Image tagged as ghcr.io/drytrix/timetracker:v1.2.3 and ghcr.io/drytrix/timetracker:latest
2. Git Tags
Create a git tag locally and push to trigger a build:
# Create and push a tag
git tag -a v1.2.3 -m "Release 1.2.3"
git push origin v1.2.3
Result: Image tagged as ghcr.io/drytrix/timetracker:v1.2.3 and ghcr.io/drytrix/timetracker:latest
3. Manual Workflow Dispatch
Trigger a build with a custom version through GitHub Actions:
- Go to GitHub repository → Actions → "Build and Publish TimeTracker Docker Image"
- Click "Run workflow"
- Enter custom version (e.g.,
custom-build-123) - Click "Run workflow"
Result: Image tagged as ghcr.io/drytrix/timetracker:custom-build-123
4. Branch Builds
Push to any branch to automatically create a build version:
# Push to main branch
git push origin main
# Results in: main-build-456 (where 456 is the build number)
# Push to feature branch
git push origin feature/new-feature
# Results in: feature-new-feature-build-789
Local Version Management
Installation
Make the scripts executable:
# Unix/Linux/macOS
chmod +x scripts/version-manager.sh
# Windows
# No special action needed, .bat files are executable by default
Basic Commands
Check Current Status
# Unix/Linux/macOS
./scripts/version-manager.sh status
# Windows
scripts\version-manager.bat status
Output:
=== Version Status ===
Current branch: main
Latest tag: v1.2.3
Commits since last tag: 5
Current commit: a1b2c3d
Suggested next version: v1.2.4
=====================
Create a Release Tag
# Unix/Linux/macOS
./scripts/version-manager.sh tag v1.2.4 "Release 1.2.4 with new features"
# Windows
scripts\version-manager.bat tag v1.2.4 "Release 1.2.4 with new features"
Create a Build Tag
# Unix/Linux/macOS
./scripts/version-manager.sh build 123
# Windows
scripts\version-manager.bat build 123
List All Tags
# Unix/Linux/macOS
./scripts/version-manager.sh list
# Windows
scripts\version-manager.bat list
Get Version Suggestions
# Unix/Linux/macOS
./scripts/version-manager.sh suggest
# Windows
scripts\version-manager.bat suggest
Advanced Usage
Create Tag Without Pushing
./scripts/version-manager.sh tag v1.2.4 --no-push
Custom Build Number
./scripts/version-manager.sh build --build-number 999
Show Tag Information
# Show latest tag info
./scripts/version-manager.sh info
# Show specific tag info
./scripts/version-manager.sh info v1.2.3
Docker Image Labels
All Docker images include comprehensive metadata labels:
--label "org.opencontainers.image.version=$VERSION"
--label "org.opencontainers.image.revision=${{ github.sha }}"
--label "org.opencontainers.image.created=$(date -u +'%Y-%m-%dT%H:%M:%SZ')"
--label "org.opencontainers.image.source=${{ github.server_url }}/${{ github.repository }}"
Workflow Examples
Release Workflow
- Develop features on feature branches
- Merge to main when ready
- Create release tag:
./scripts/version-manager.sh tag v1.3.0 "Major feature release" - Push tag to trigger GitHub Actions
- Create GitHub release for the tag
- Docker image automatically built and pushed
Development Workflow
- Work on feature branch:
git checkout -b feature/new-feature # ... make changes ... git push origin feature/new-feature - Automatic build with version like
feature-new-feature-build-123 - Test the image before merging
- Merge to main when ready
- Create release tag for production
Hotfix Workflow
- Create hotfix branch:
git checkout -b hotfix/critical-fix # ... fix the issue ... git push origin hotfix/critical-fix - Test the build with version like
hotfix-critical-fix-build-456 - Create hotfix release:
./scripts/version-manager.sh tag v1.2.4 "Critical security fix"
Best Practices
Version Naming
- Use semantic versioning for releases (
v1.2.3) - Use descriptive names for feature branches
- Include build numbers for development builds
- Be consistent with naming conventions
Tag Management
- Create tags locally before pushing
- Use meaningful commit messages for tags
- Push tags immediately after creation
- Clean up old tags periodically
Release Process
- Test thoroughly before creating releases
- Use release candidates for major versions
- Document changes in release notes
- Tag from main branch only
Troubleshooting
Common Issues
Tag Already Exists
# Delete local tag
git tag -d v1.2.3
# Delete remote tag
git push origin --delete v1.2.3
# Recreate tag
./scripts/version-manager.sh tag v1.2.3
Build Not Triggered
- Check if the tag was pushed to remote
- Verify GitHub Actions permissions
- Check workflow file syntax
- Ensure tag format is valid
Version Format Invalid
The system validates version formats. Common valid formats:
# Valid
v1.2.3, 1.2.3, build-123, rc1, beta1
# Invalid
1.2.3.4, v1.2.3.4, build_123, release-1
Debug Commands
# Check git status
git status
# Check remote tags
git ls-remote --tags origin
# Check local tags
git tag -l
# Check GitHub Actions
# Go to Actions tab in GitHub repository
Integration with CI/CD
GitHub Actions
The version management system integrates seamlessly with GitHub Actions:
- Automatic triggers on tags and releases
- Build number tracking for continuous builds
- Docker image publishing to GitHub Container Registry
- Pull request previews without publishing
External CI/CD
For external CI/CD systems, use the version manager scripts:
# In CI/CD pipeline
./scripts/version-manager.sh build $BUILD_NUMBER
git push origin --tags
Admin in-app update notification (GitHub releases)
Administrators can be notified in the web UI when a newer semantic version exists on GitHub compared to this installation. The feature is server-driven, does not affect non-admin users, and uses caching so routine page loads do not hammer the GitHub API.
Behavior
- Source of truth for “latest”: GitHub’s API for the configured repository (default
DRYTRIX/TimeTracker), eitherreleases/latestor, when pre-releases are enabled, the newest non-draft release from the releases list. - Installed version:
APP_VERSION/GITHUB_TAGfrom the environment (via Flask config) if it parses as a semantic version; otherwise the version read fromsetup.pyat runtime (see the note at the top of this document). Non-semver installs (for exampledev-123) do not show an upgrade prompt. - UI: A small, non-blocking card on authenticated admin pages (templates using
base.html). Dismiss hides until the next load; Don’t show again for this version persists per user in the database (migration148_add_user_dismissed_release_version) and mirrors to browserlocalStorageas a fallback. - API:
GET /api/version/checkandPOST /api/version/dismisson the legacy/apiJSON routes; session or API token; admin-only. See REST API — Admin version check.
Environment variables
| Variable | Default | Description |
|---|---|---|
VERSION_CHECK_GITHUB_REPO |
DRYTRIX/TimeTracker |
owner/repo for api.github.com/repos/{repo}/releases/… |
VERSION_CHECK_GITHUB_CACHE_TTL |
43200 (12h) |
TTL in seconds for the successful GitHub response cache |
VERSION_CHECK_GITHUB_STALE_TTL |
604800 (7d) |
TTL for the last successful payload used when GitHub returns errors (for example 403 rate limit) |
VERSION_CHECK_HTTP_TIMEOUT |
10 |
HTTP timeout in seconds for GitHub requests |
GITHUB_RELEASES_TOKEN |
(empty) | Optional GitHub personal access token (fine-scoped classic token with public_repo is enough for public repos); raises authenticated rate limits. Do not commit tokens; set only via environment or secrets manager. |
ENABLE_PRE_RELEASE_NOTIFICATIONS |
false |
When true, consider the newest non-draft release from the paginated releases list (including pre-releases). When false, use releases/latest (stable only per GitHub’s definition). |
Optional: set APP_VERSION (or GITHUB_TAG) at deploy time to a semver string so Docker images and CI builds compare correctly against release tags.
Future Enhancements
- Version database for tracking all versions
- Release notes generation from commits
- Dependency version tracking for security updates
- Automated changelog generation
- Version compatibility checking
- Rollback support for failed releases