Files
dance-lessons-coach/adr/0014-version-management-lifecycle.md

11 KiB

14. Version Management and Release Lifecycle

Date: 2026-04-05 Status: Proposed Authors: DanceLessonsCoach Team Decision Date: 2026-04-05 Implementation Status: Partial (version package created, need to implement full lifecycle)

Context

As DanceLessonsCoach matures, we need a robust version management and release lifecycle system to:

  1. Track versions consistently across code, documentation, and deployments
  2. Automate version bumping with clear semantic versioning rules
  3. Manage releases through git tags and changelog integration
  4. Provide runtime version info for debugging and support
  5. Support CI/CD pipelines with automated version management

Decision Drivers

  • Consistency: Single source of truth for version information
  • Automation: Reduce manual errors in version management
  • Traceability: Link versions to git commits and builds
  • Semantic Versioning: Follow industry standards (SemVer 2.0.0)
  • Runtime Visibility: Expose version info in running applications
  • Release Management: Support proper release tagging and changelog generation
  • CI/CD Integration: Work seamlessly with automated build pipelines

Decision

We will implement a comprehensive version management system with the following components:

1. Version Package (pkg/version)

Purpose: Centralized version information with runtime access

package version

var (
    Version   = "1.0.0"      // Semantic version
    Commit    = ""           // Git commit hash
    Date      = ""           // Build date
    GoVersion = runtime.Version()
)

func Info() string
func Short() string
func Full() string

Implementation Status: Completed

2. Build-Time Version Injection

Approach: Use Go ldflags to inject version information during build

Timezone Convention: All timestamps use UTC for consistency

# Build command with version injection
go build \
    -ldflags="\
        -X 'DanceLessonsCoach/pkg/version.Version=1.0.0' \
        -X 'DanceLessonsCoach/pkg/version.Commit=abc123' \
        -X 'DanceLessonsCoach/pkg/version.Date=2026-04-05T10:00:00Z'  # UTC format
    " \
    ./cmd/server

Rationale for UTC:

  • Consistent across all build environments
  • Eliminates timezone ambiguity
  • Follows ISO 8601 international standard
  • Sortable and comparable
  • CI/CD friendly

Script: scripts/build-with-version.sh Created

3. VERSION File

Purpose: Source of truth for version numbers

# VERSION file format
MAJOR=1
MINOR=0
PATCH=0
PRERELEASE=""  # alpha.1, beta.2, rc.1, etc.

Status: Created

4. Version Bump Script

Purpose: Automated version increment following SemVer rules

# Usage: ./scripts/version-bump.sh [major|minor|patch|pre|release]
./scripts/version-bump.sh patch      # 1.0.0 → 1.0.1
./scripts/version-bump.sh minor      # 1.0.1 → 1.1.0
./scripts/version-bump.sh major      # 1.1.0 → 2.0.0
./scripts/version-bump.sh pre        # 2.0.0 → 2.0.0-alpha.1
./scripts/version-bump.sh release     # 2.0.0-alpha.1 → 2.0.0

Status: 🟡 Partial (basic script created, needs refinement)

5. Command-Line Version Flag

Implementation: Add --version flag to all binaries

# Check version
dance-lessons-coach --version

# Output:
DanceLessonsCoach Version Information:
  Version:   1.0.0
  Commit:    abc1234
  Built:     2026-04-05T10:00:00+0000
  Go:        go1.26.1

Status: Completed

6. Git Tag Integration

Workflow:

# 1. Bump version
./scripts/version-bump.sh minor

# 2. Update CHANGELOG
# (Manual or automated process)

# 3. Commit changes
git commit -m "📖 chore: bump version to 1.1.0"

# 4. Create annotated tag
git tag -a v1.1.0 -m "Release 1.1.0"

# 5. Push with tags
git push origin main --tags

Status: 🟡 Planned

7. Release Lifecycle

Development Phase

graph LR
    A[Feature Branch] --> B[PR to main]
    B --> C[Auto-build with dev version]
    C --> D[Deploy to dev/staging]

Release Phase

graph LR
    A[Bump version] --> B[Update CHANGELOG]
    B --> C[Create git tag]
    C --> D[Build release binaries]
    D --> E[Push to GitHub Releases]
    E --> F[Deploy to production]

8. Semantic Versioning Rules

Version Part When to Increment Example Changes
MAJOR Breaking changes, major features Database schema changes, API breaking changes
MINOR Backwards-compatible features New API endpoints, new functionality
PATCH Backwards-compatible fixes Bug fixes, performance improvements
PRERELEASE Pre-release versions alpha.1, beta.2, rc.1

9. Version Information Flow

graph TD
    A[VERSION file] -->|source| B[Build Script]
    B -->|ldflags| C[Compiled Binary]
    C -->|runtime| D[Version Command]
    C -->|runtime| E[API Response]
    C -->|runtime| F[Logs/Metrics]

Implementation Plan

Phase 1: Core Version Management (Completed)

  • Create pkg/version package
  • Add version variables with ldflags support
  • Create VERSION file
  • Add --version flag to server
  • Create basic build script

Phase 2: Version Bumping Automation 🟡 (In Progress)

  • Complete version-bump.sh script
  • Add pre-release version support
  • Add validation and safety checks
  • Create version validation script

Phase 3: Release Lifecycle 🟡 (Planned)

  • Create release preparation script
  • Automate CHANGELOG updates
  • Add git tag creation script
  • Create GitHub release script
  • Add release notes generation

Phase 4: CI/CD Integration 🟡 (Planned)

  • Add version info to CI builds
  • Automate version bumping in CI
  • Add version validation to PR checks
  • Create release pipeline
  • Add version to Docker images

Rationale

Why This Approach?

  1. Standard Compliance: Follows Semantic Versioning 2.0.0
  2. Go Idiomatic: Uses Go's ldflags for build-time injection
  3. Single Source of Truth: VERSION file as canonical source
  4. Runtime Visibility: Version info available in running apps
  5. Automation Friendly: Scripts for CI/CD integration
  6. Traceability: Links builds to git commits
  7. Extensible: Can add more metadata as needed

Alternatives Considered

Option 1: Hardcoded Version in main.go

  • Rejected: Manual updates, error-prone, no automation
  • Issue: Version scattered across multiple files

Option 2: Git Tags Only

  • Rejected: No runtime access, requires git in production
  • Issue: Can't access version in running containers

Option 3: External Version File (JSON/YAML)

  • Rejected: More complex, requires parsing
  • Issue: Overkill for simple version management

Option 4: Build System Plugins

  • Rejected: Too complex, vendor lock-in
  • Issue: Not portable across build systems

Pros and Cons of Chosen Approach

Advantages

  1. Simple: Easy to understand and maintain
  2. Portable: Works with any build system
  3. Runtime Access: Version available in running apps
  4. Automatable: Scripts for CI/CD integration
  5. Extensible: Can add more metadata easily
  6. Standard: Follows SemVer and Go conventions

Disadvantages

  1. Manual Bumping: Still requires manual version bumps
  2. Script Maintenance: Need to maintain bash scripts
  3. Learning Curve: Team needs to learn the workflow
  4. Error Potential: Manual processes can have errors

Validation

Does this meet our requirements?

  • Consistency: Single VERSION file as source of truth
  • Automation: Scripts for version bumping and building
  • Traceability: Git commit linked to builds
  • Semantic Versioning: Follows SemVer 2.0.0 standards
  • Runtime Visibility: Version available via --version flag
  • CI/CD Integration: Scripts designed for pipeline use
  • Extensibility: Can add more metadata as needed

What's still needed?

  • Full automation: Complete CI/CD pipeline integration
  • Release automation: Git tag and release creation scripts
  • Changelog automation: Automated changelog updates
  • Validation: Comprehensive version validation

Future Enhancements

Short-Term (Next 3 Months)

  1. Complete version-bump.sh with all features
  2. Add release preparation script
  3. Automate CHANGELOG updates
  4. Add git tag integration
  5. Create validation scripts

Medium-Term (3-6 Months)

  1. CI/CD pipeline integration
  2. Automated release notes
  3. Docker image versioning
  4. Version API endpoint
  5. Metrics and monitoring

Long-Term (6-12 Months)

  1. Automated version bumping based on commit messages
  2. Monorepo version management
  3. Dependency version tracking
  4. Security vulnerability tracking
  5. Deprecation policies

Migration Plan

From Current State

  1. Replace hardcoded version in main.go with VERSION file
  2. Update build scripts to use new version system
  3. Add version command to all binaries
  4. Document workflow for team
  5. Train team on new version management

For Existing Deployments

  1. Gradual rollout: Update version info on next deploy
  2. Backward compatibility: Keep old version formats temporarily
  3. Monitoring: Track version adoption
  4. Documentation: Update all docs with new version info

Success Metrics

  1. 100% of builds include proper version information
  2. 0 manual version errors in releases
  3. All team members can bump versions correctly
  4. CI/CD pipeline handles versioning automatically
  5. Release process is documented and followed
  6. Version visibility in production environments

References

Appendix: Version Management Commands

Check Current Version

# From VERSION file
source VERSION && echo "$MAJOR.$MINOR.$PATCH${PRERELEASE:+-$PRERELEASE}"

# From built binary
./bin/server --version

Bump Version

# Patch version (bug fixes)
./scripts/version-bump.sh patch

# Minor version (new features)
./scripts/version-bump.sh minor

# Major version (breaking changes)
./scripts/version-bump.sh major

# Pre-release version
./scripts/version-bump.sh pre

# Release from pre-release
./scripts/version-bump.sh release

Build with Version

# Development build
./scripts/build-with-version.sh bin/server-dev

# Release build
go build -o bin/server \
    -ldflags="\
        -X 'DanceLessonsCoach/pkg/version.Version=1.0.0' \
        -X 'DanceLessonsCoach/pkg/version.Commit=$(git rev-parse --short HEAD)' \
        -X 'DanceLessonsCoach/pkg/version.Date=$(date +%Y-%m-%dT%H:%M:%S%z)' \
    " \
    ./cmd/server

Create Release

# 1. Bump version
./scripts/version-bump.sh minor

# 2. Update CHANGELOG
# Edit AGENT_CHANGELOG.md

# 3. Commit version bump
git commit -m "📖 chore: bump version to 1.1.0"

# 4. Create annotated tag
git tag -a v1.1.0 -m "Release 1.1.0"

# 5. Push with tags
git push origin main --tags

Status: Proposed
Next Review: 2026-04-12
Implementation Owner: DanceLessonsCoach Team
Approvers Needed: @gabrielradureau