ADR-002: GitVersion Mode - ContinuousDeployment with Conventional Commits¶
Status¶
Approved - Implemented
Context¶
The SyRF monorepo requires a consistent versioning strategy that:
- Supports per-service versioning in a monorepo
- Works with path-based change detection
- Provides semantic versioning based on commit messages
- Integrates with CI/CD workflows
- Maintains performance as the repository grows
Two main GitVersion modes were evaluated:
- Mainline Development: Every commit on main is deployable, uses
+semver:directives - ContinuousDeployment: Version stays stable until tagged, uses conventional commits
Decision¶
Use GitVersion in ContinuousDeployment mode with conventional commit messages.
Configuration¶
mode: ContinuousDeployment
tag-prefix: '{service}-v'
# Conventional commit patterns
major-version-bump-message: '^(feat|fix|chore)(\([a-z]+\))?!:|^BREAKING CHANGE:'
minor-version-bump-message: '^feat(\([a-z]+\))?:'
patch-version-bump-message: '^fix(\([a-z]+\))?:'
no-bump-message: '^(chore|docs|style|refactor|test|ci)(\([a-z]+\))?:'
branches:
master:
increment: Patch
regex: ^master$|^main$
label: ''
Commit Message Convention¶
feat:→ Minor version bump (0.X.0)fix:→ Patch version bump (0.0.X)feat!:orBREAKING CHANGE:→ Major version bump (X.0.0)chore:,docs:,style:→ No version bump
Consequences¶
Positive¶
- Industry Standard: Conventional commits are widely adopted
- Team Familiarity: Developers likely know
feat:andfix:patterns - Tooling Support: Better integration with commitlint, changelog generators
- Performance: No cumulative history calculation, doesn't slow over time
- Monorepo Fit: Path filtering with conventional commits is well-tested
- Clear Workflow: commit → calculate version → tag → build → deploy
Negative¶
- Tag Requirement: Must create tags to mark releases
- Multiple Commits Same Version: Several commits share version until tagged
- Not True CD: Every commit doesn't immediately deploy to production
Alternatives Considered¶
Mainline Development Mode¶
Pros:
- Every commit on main triggers deployment
- Forward-focused development
- Works well with trunk-based development
Cons:
- Performance degrades over time
- Less intuitive syntax (
+semver:vsfix:) - Requires 100% test coverage confidence
Rejected because: Our workflow uses controlled releases via tags and GitOps, not immediate deployment of every commit.
Implementation¶
Service GitVersion Configuration¶
Each service has its own GitVersion.yml:
tag-prefix: 'api-v' # Service-specific prefix
ignore:
paths:
- ^(?!services\/api\/|libs\/).* # Ignore other services
CI/CD Integration¶
- Commit to main with conventional message
- GitVersion calculates next version
- Workflow creates service tag (e.g.,
api-v1.2.3) - Docker build triggered by tag
- Image pushed to registry
- GitOps deployment via promotion PR
Example Workflow¶
# Developer commits
git commit -m "feat(api): add export endpoint"
# CI/CD workflow
# - Detects change in api service
# - GitVersion calculates: 1.2.0 → 1.3.0 (minor bump)
# - Creates tag: api-v1.3.0
# - Builds Docker image: ghcr.io/camaradesuk/syrf-api:1.3.0
# - Creates promotion PR to cluster-gitops