ADR-004: Version Continuity Strategy Across Polyrepo-to-Monorepo Migration¶
Status¶
Approved - 2025-11-10
Context¶
When migrating from multiple polyrepos (syrf-api, syrf-projectmanagement, syrf-web) to a monorepo structure, we need to decide how to handle semantic versioning for each service.
The Problem¶
The polyrepos had established version histories:
- syrf-api: Last version v8.20.1
- syrf-projectmanagement: Last version v10.44.1
- syrf-web: Last version v4.1.5
After migration to monorepo, the CI/CD initially started versioning from scratch:
api-v0.1.0,api-v0.2.0, ...pm-v0.1.0,pm-v0.2.0, ...web-v0.1.0,web-v0.2.0, ...
This creates version discontinuity that can cause confusion:
- Deployments: Existing deployed versions (v8.x, v10.x, v4.x) vs new versions (v0.x)
- Release Notes: Users see version "downgrade" from v4.1.5 to v0.1.0
- Changelog: Semantic versioning history is broken
- Monitoring/Alerts: Version-based monitoring may break
Options Considered¶
Option 1: Start Fresh at v0.1.0 (Initial Approach)¶
Pros:
- Clean slate for monorepo
- Clear marker of architectural migration
- Simpler initial setup
Cons:
- ❌ Breaks semantic versioning continuity
- ❌ Confusing for users (version "downgrade")
- ❌ Difficult to correlate pre/post-migration versions
- ❌ May break version-dependent monitoring
Option 2: Continue from Last Polyrepo Versions (CHOSEN)¶
Pros:
- ✅ Maintains semantic versioning continuity
- ✅ No user confusion (versions keep incrementing)
- ✅ Easy to trace version history across migration
- ✅ Preserves changelog integrity
- ✅ Version-based monitoring continues working
Cons:
- Requires creating baseline tags
- Slightly more complex initial setup
- Different services at different major versions
Option 3: Bump All to Next Major Version¶
Pros:
- Clear migration marker (v9.0.0, v11.0.0, v12.0.0)
- Aligns with "breaking change" in architecture
Cons:
- Forces major version bump even if no breaking API changes
- Still requires baseline tag creation
- May cause unnecessary major version inflation
Decision¶
We will continue versioning from the last polyrepo versions (Option 2).
Implementation Strategy¶
- Create Baseline Tags at polyrepo merge commits:
# Find commits where polyrepos were merged
git log --grep="Merge syrf-api" --oneline
git log --grep="Merge syrf-projectmanagement" --oneline
git log --grep="Merge syrf-web" --oneline
# Create prefixed baseline tags at those commits
git tag -a api-v8.20.1 <api-merge-commit> -m "Baseline: Continue from polyrepo v8.20.1"
git tag -a pm-v10.44.1 <pm-merge-commit> -m "Baseline: Continue from polyrepo v10.44.1"
git tag -a web-v4.1.5 <web-merge-commit> -m "Baseline: Continue from polyrepo v4.1.5"
# Push baseline tags
git push origin api-v8.20.1 pm-v10.44.1 web-v4.1.5
- GitVersion Configuration: Ensure
tag-prefixis configured in each service'sGitVersion.yml:
GitVersion will:
- Find the latest prefixed tag (e.g., api-v8.20.1)
- Calculate next version based on commits since that tag
- feat: commits → minor bump → api-v8.21.0
- fix: commits → patch bump → api-v8.20.2
- Workflow Integration: The
ci-cd.ymlworkflow already: - Uses GitVersion to calculate versions
- Creates prefixed tags (
{service}-v{version}) - Pushes tags to origin
Version Mapping Table¶
| Service | Last Polyrepo Version | Baseline Monorepo Tag | Current Version | Next Version (feat) | Next Version (fix) |
|---|---|---|---|---|---|
| API | v8.20.1 | api-v8.20.1 |
api-v8.21.0 | api-v8.22.0 | api-v8.21.1 |
| PM | v10.44.1 | pm-v10.44.1 |
pm-v10.45.0 | pm-v10.46.0 | pm-v10.45.1 |
| Web | v4.1.5 | web-v4.1.5 |
web-v5.0.0 | web-v5.1.0 | web-v5.0.1 |
| Quartz | N/A (new) | quartz-v0.1.0 |
quartz-v0.1.0 | quartz-v0.2.0 | quartz-v0.1.1 |
| S3 Notifier | N/A (new) | s3-notifier-v0.1.0 |
s3-notifier-v0.1.0 | s3-notifier-v0.2.0 | s3-notifier-v0.1.1 |
Consequences¶
Positive¶
- Seamless User Experience: Users see continuous version progression (v11.27.0 → v11.28.0)
- Traceability: Clear correlation between polyrepo and monorepo versions
- Monitoring Continuity: Version-based alerts and monitoring continue working
- Semantic Versioning Integrity: Respects SemVer principles throughout migration
- Historical Accuracy: Git history preserves full version timeline
Negative¶
- Mixed Version Numbers: Services at different major versions (v8.x, v10.x, v5.x)
- Mitigation: This is acceptable - each service has independent version history
- Initial Setup Effort: Requires finding merge commits and creating baseline tags
- Mitigation: One-time effort, well-documented in this ADR
Neutral¶
- Tag Cleanup: Old unprefixed tags (
v8.20.1) can remain in git history - They provide historical reference
- Workflow only considers prefixed tags
- No conflict with new versioning
Implementation Checklist¶
- Identify exact commit SHAs where polyrepos were merged
- Create baseline tags:
-
api-v8.20.1at API merge commit -
pm-v10.44.1at PM merge commit -
web-v4.1.5at Web merge commit - Push baseline tags to origin
- Verify GitVersion.yml has correct
tag-prefixconfiguration - Test version calculation:
- API calculates api-v8.21.0 ✅
- PM calculates pm-v10.45.0 ✅
- Web calculates web-v5.0.0 ✅ (major bump due to many commits)
- Delete obsolete v0.x.x tags (completed)
- Update CLAUDE.md with version continuity strategy
- Update cluster-gitops repository with correct version expectations
Related Decisions¶
- ADR-002: GitVersion Mode (ContinuousDeployment) - Version calculation method
- ADR-001: CI/CD Approach - Workflow structure for tag creation
- Child Work Item 2.1: Auto-Version Workflow Cleanup - Implementation work item
References¶
- GitVersion Tag Prefix Documentation: https://gitversion.net/docs/reference/configuration
- Polyrepo migration commits:
- API merge:
21395394- "Merge syrf-api with history into src/services/api" - PM merge:
eddfbc16- "Merge syrf-projectmanagement with history into src/services/project-management" - Web merge:
eaac7bf3- "feat: merge latest syrf-web (Angular 20.2.0) into monorepo with full history" - Last polyrepo versions (git tags):
- API:
v8.20.1(commit: f58380a1) - PM:
v10.44.1(commit: 24aed7c6) - Web:
v4.1.5(commit: 9f79cab5)
Notes¶
- Quartz and S3 Notifier are new services created during monorepo refactoring, so they correctly start at v0.1.0
- The unprefixed tags (v8.20.1, v10.44.1, v11.27.0) can remain in git history for reference
- GitVersion's
tag-prefixconfiguration ensures only prefixed tags affect version calculation - This strategy is common in monorepo migrations (see: Babel, Jest, React monorepo version strategies)