Skip to content

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:

  1. Deployments: Existing deployed versions (v8.x, v10.x, v4.x) vs new versions (v0.x)
  2. Release Notes: Users see version "downgrade" from v4.1.5 to v0.1.0
  3. Changelog: Semantic versioning history is broken
  4. 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

  1. 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
  1. GitVersion Configuration: Ensure tag-prefix is configured in each service's GitVersion.yml:
tag-prefix: '[api|pm|web|quartz|s3-notifier]-v'

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

  1. Workflow Integration: The ci-cd.yml workflow already:
  2. Uses GitVersion to calculate versions
  3. Creates prefixed tags ({service}-v{version})
  4. 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

  1. Seamless User Experience: Users see continuous version progression (v11.27.0 → v11.28.0)
  2. Traceability: Clear correlation between polyrepo and monorepo versions
  3. Monitoring Continuity: Version-based alerts and monitoring continue working
  4. Semantic Versioning Integrity: Respects SemVer principles throughout migration
  5. Historical Accuracy: Git history preserves full version timeline

Negative

  1. Mixed Version Numbers: Services at different major versions (v8.x, v10.x, v5.x)
  2. Mitigation: This is acceptable - each service has independent version history
  3. Initial Setup Effort: Requires finding merge commits and creating baseline tags
  4. Mitigation: One-time effort, well-documented in this ADR

Neutral

  1. Tag Cleanup: Old unprefixed tags (v8.20.1) can remain in git history
  2. They provide historical reference
  3. Workflow only considers prefixed tags
  4. No conflict with new versioning

Implementation Checklist

  • Identify exact commit SHAs where polyrepos were merged
  • Create baseline tags:
  • api-v8.20.1 at API merge commit
  • pm-v10.44.1 at PM merge commit
  • web-v4.1.5 at Web merge commit
  • Push baseline tags to origin
  • Verify GitVersion.yml has correct tag-prefix configuration
  • 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
  • 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-prefix configuration ensures only prefixed tags affect version calculation
  • This strategy is common in monorepo migrations (see: Babel, Jest, React monorepo version strategies)