@@ -53,7 +53,25 @@ func (s *Service) GetCurrentVersion(homeDir string) (*domainVersion.Version, err
5353 return v , nil
5454}
5555
56+ // isSameMajorMinor checks if two versions have the same major and minor version.
57+ // Returns true if major.minor are identical, ignoring patch, prerelease, and git metadata.
58+ // For example: 1.2.0 and 1.2.3 -> true, 1.2.0-rc0-7-g... and 1.2.0-rc0-12-g... -> true
59+ func isSameMajorMinor (current , target * version.Version ) bool {
60+ currentSegs := current .Segments ()
61+ targetSegs := target .Segments ()
62+
63+ // Ensure we have at least major.minor for both versions
64+ if len (currentSegs ) < 2 || len (targetSegs ) < 2 {
65+ return false
66+ }
67+
68+ // Check if major and minor are the same
69+ return currentSegs [0 ] == targetSegs [0 ] && currentSegs [1 ] == targetSegs [1 ]
70+ }
71+
5672// CheckAndMigrate checks if migration is needed and applies migrations.
73+ // Note: If major.minor are the same, skip migration entirely and only update the version.
74+ // This avoids issues with prerelease/git-describe version comparisons.
5775func (s * Service ) CheckAndMigrate (ctx context.Context , homeDir string , target string ) (* domainVersion.Version , error ) {
5876 // Get current version
5977 current , err := s .GetCurrentVersion (homeDir )
@@ -72,15 +90,28 @@ func (s *Service) CheckAndMigrate(ctx context.Context, homeDir string, target st
7290 return nil , fmt .Errorf ("invalid target version %s: %w" , target , err )
7391 }
7492
75- // Check if migration is needed
76- if currentVer .Equal (targetVer ) {
77- s .logger .Debug ("Version %s is current, no migration needed" , current .Current )
93+ // Check major.minor first - if same, skip migration entirely (just update version)
94+ // This avoids prerelease comparison issues (e.g., v1.0.0-rc0-7-g... vs v1.0.0-rc0-12-g...)
95+ if isSameMajorMinor (currentVer , targetVer ) {
96+ if current .Current == target {
97+ s .logger .Debug ("Version %s is current, no migration needed" , current .Current )
98+ return current , nil
99+ }
100+ s .logger .Debug ("Same major.minor version %s -> %s, skipping migration" , current .Current , target )
101+ current .Current = target
102+ if err := s .repository .Save (homeDir , current ); err != nil {
103+ return nil , fmt .Errorf ("failed to save version: %w" , err )
104+ }
78105 return current , nil
79106 }
80107
81- if currentVer .GreaterThan (targetVer ) {
82- // Downgrade not supported
83- return nil , fmt .Errorf ("downgrade from %s to %s is not supported" , current .Current , target )
108+ // Different major.minor - check for downgrade
109+ currentSegs := currentVer .Segments ()
110+ targetSegs := targetVer .Segments ()
111+ if len (currentSegs ) >= 2 && len (targetSegs ) >= 2 {
112+ if currentSegs [0 ] > targetSegs [0 ] || (currentSegs [0 ] == targetSegs [0 ] && currentSegs [1 ] > targetSegs [1 ]) {
113+ return nil , fmt .Errorf ("downgrade from %s to %s is not supported" , current .Current , target )
114+ }
84115 }
85116
86117 // Find migration path
0 commit comments