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

402 lines
11 KiB
Markdown

# 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
```go
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
```bash
# 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
```bash
# 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
```bash
# 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
```bash
# 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**:
```bash
# 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
```mermaid
graph LR
A[Feature Branch] --> B[PR to main]
B --> C[Auto-build with dev version]
C --> D[Deploy to dev/staging]
```
#### Release Phase
```mermaid
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
```mermaid
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)
- [x] Create `pkg/version` package
- [x] Add version variables with ldflags support
- [x] Create VERSION file
- [x] Add `--version` flag to server
- [x] 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
- [Semantic Versioning 2.0.0](https://semver.org/)
- [Go ldflags Documentation](https://pkg.go.dev/cmd/link)
- [Git Tags Documentation](https://git-scm.com/book/en/v2/Git-Basics-Tagging)
- [Conventional Commits](https://www.conventionalcommits.org/)
## Appendix: Version Management Commands
### Check Current Version
```bash
# From VERSION file
source VERSION && echo "$MAJOR.$MINOR.$PATCH${PRERELEASE:+-$PRERELEASE}"
# From built binary
./bin/server --version
```
### Bump Version
```bash
# 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
```bash
# 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
```bash
# 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