Files
TimeTracker/docs/admin/deployment/VERSION_MANAGEMENT.md
T
Dries Peeters 7534e8abe7 docs: align versioning and API testing docs with OpenAPI and contracts
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.
2026-04-16 15:09:45 +02:00

12 KiB
Raw Blame History

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:

  1. GitHub Releases - Automatic versioning when creating releases
  2. Git Tags - Manual version tagging for releases
  3. Build Numbers - Automatic versioning for branch builds
  4. Manual Workflow Dispatch - Custom version input through GitHub Actions
  5. 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' prefix
  • v1.2 - Major.Minor version
  • v1 - Major version only

Build Versions

  • build-123 - Build number format
  • main-build-456 - Branch-specific build
  • feature-build-789 - Feature branch build

Pre-release Versions

  • rc1 - Release candidate
  • beta1 - Beta version
  • alpha1 - Alpha version
  • dev-123 - Development version

GitHub Actions Workflow

Automatic Version Detection

The GitHub Actions workflow automatically determines the version based on the trigger:

  1. Manual Workflow Dispatch - Uses custom input version
  2. GitHub Release - Uses release tag name
  3. Git Tag - Uses git tag name
  4. Branch Push - Uses branch name + build number
  5. 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 version and latest
  • Main Branch Builds: Tagged as both version and main
  • Feature Branches: Tagged only as version
  • Pull Requests: Build but don't push (preview only)

Usage Methods

Create a GitHub release to automatically trigger a build with the release version:

  1. Go to GitHub repository → Releases → "Create a new release"
  2. Choose a tag (e.g., v1.2.3) or create a new one
  3. Fill in release title and description
  4. Publish the release
  5. 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:

  1. Go to GitHub repository → Actions → "Build and Publish TimeTracker Docker Image"
  2. Click "Run workflow"
  3. Enter custom version (e.g., custom-build-123)
  4. 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

  1. Develop features on feature branches
  2. Merge to main when ready
  3. Create release tag:
    ./scripts/version-manager.sh tag v1.3.0 "Major feature release"
    
  4. Push tag to trigger GitHub Actions
  5. Create GitHub release for the tag
  6. Docker image automatically built and pushed

Development Workflow

  1. Work on feature branch:
    git checkout -b feature/new-feature
    # ... make changes ...
    git push origin feature/new-feature
    
  2. Automatic build with version like feature-new-feature-build-123
  3. Test the image before merging
  4. Merge to main when ready
  5. Create release tag for production

Hotfix Workflow

  1. Create hotfix branch:
    git checkout -b hotfix/critical-fix
    # ... fix the issue ...
    git push origin hotfix/critical-fix
    
  2. Test the build with version like hotfix-critical-fix-build-456
  3. 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”: GitHubs API for the configured repository (default DRYTRIX/TimeTracker), either releases/latest or, when pre-releases are enabled, the newest non-draft release from the releases list.
  • Installed version: APP_VERSION / GITHUB_TAG from the environment (via Flask config) if it parses as a semantic version; otherwise the version read from setup.py at runtime (see the note at the top of this document). Non-semver installs (for example dev-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; Dont show again for this version persists per user in the database (migration 148_add_user_dismissed_release_version) and mirrors to browser localStorage as a fallback.
  • API: GET /api/version/check and POST /api/version/dismiss on the legacy /api JSON 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 GitHubs 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