@@ -131,6 +131,10 @@ public void PlatformTag_TagExists(
131131 continue ;
132132 }
133133
134+ Version dockerfileVersion = GetVersion ( dockerfileInfo . MajorMinor ) ;
135+
136+ bool hasPreviewInMajorVersionGroup = HasPreviewProductVersion ( repo , dockerfileVersion . Major ) ;
137+
134138 IEnumerable < string > tags = dockerfileTag . Value
135139 . Where ( tag => IsTagOfFormat (
136140 tag ,
@@ -139,12 +143,12 @@ public void PlatformTag_TagExists(
139143 checkOs ? dockerfileInfo . Os : null ,
140144 checkArchitecture ? dockerfileInfo . Architecture : null ) ) ;
141145
142- if ( versionType == VersionType . Major && ! IsExpectedMajorMinorVersion ( repo , dockerfileInfo . MajorMinor ) )
146+ if ( versionType == VersionType . Major && ! IsLatestInMajorVersionGroup ( repo , dockerfileInfo . MajorMinor , hasPreviewInMajorVersionGroup ) )
143147 {
144148 // Special case for major version tags
145- // These tags should be on the most up-to-date Major.Minor version for the respective major version
149+ // These tags should be on the latest Major.Minor GA version for the respective major version
146150 tags . Should ( ) . BeEmpty ( "expected tag to be on latest Major.Minor version for version " +
147- GetVersion ( dockerfileInfo . MajorMinor ) . Major + ", but found the tag on " + dockerfileInfo ) ;
151+ dockerfileVersion . Major + ", but found the tag on " + dockerfileInfo ) ;
148152 }
149153 else
150154 {
@@ -236,8 +240,8 @@ public void VersionTag_SameOsAndVersion(Repo repo, VersionType versionType)
236240
237241 // Special case for major version tags
238242 // These tags should be on the most up-to-date Major.Minor version for the respective major version
239- IsExpectedMajorMinorVersion ( repo , dockerfileVersion ) . Should ( ) . BeTrue (
240- "expected tag to be on the latest Major.Minor version for the major version " +
243+ IsLatestInMajorVersionGroup ( repo , dockerfileVersion , tag . Contains ( "-preview" ) ) . Should ( ) . BeTrue (
244+ "expected tag to be on the latest Major.Minor GA version for the major version " +
241245 GetVersion ( dockerfileVersion ) . Major + ", but found the tag on " + dockerfileVersion ) ;
242246 }
243247
@@ -536,7 +540,14 @@ private static bool IsApplianceVersionUsingOldSchema(DockerfileInfo dockerfileIn
536540 private static bool IsApplianceVersionUsingNewSchema ( DockerfileInfo dockerfileInfo ) =>
537541 ! IsApplianceVersionUsingOldSchema ( dockerfileInfo ) ;
538542
539- private static bool IsExpectedMajorMinorVersion ( Repo repo , string version )
543+ /// <summary>
544+ /// Determines if the <paramref name="majorMinorVersion"/> is the latest in its major version group.
545+ /// </summary>
546+ /// <remarks>
547+ /// By default, this will only consider GA versions within the major version group (unless there are no GA versions).
548+ /// The <paramref name="includePreviewVersions"/> parameter can be set to include preview versions in the check.
549+ /// </remarks>
550+ private static bool IsLatestInMajorVersionGroup ( Repo repo , string majorMinorVersion , bool includePreviewVersions )
540551 {
541552 IEnumerable < string > productVersions = ManifestHelper . GetResolvedProductVersions ( repo ) ;
542553
@@ -546,19 +557,17 @@ private static bool IsExpectedMajorMinorVersion(Repo repo, string version)
546557 . GroupBy ( version => GetVersion ( version ) . Major )
547558 . Select ( group =>
548559 {
549- if ( ! Config . IsNightlyRepo )
560+ if ( includePreviewVersions )
550561 {
551- // Use the latest GA major version on the main branch
552- // Assumes that non-GA versions have a hyphen in them
553- // e.g. non-GA: 5.0.0-preview.1, GA: 5.0.0
554- // RTM versions are also accepted as GA versions for internal testing purposes
562+ return group ;
563+ }
564+ else
565+ {
566+ // Use the latest GA major version.
555567 // If there are no GA versions, use the latest preview version.
556- IEnumerable < string > gaVersions = group . Where ( version =>
557- ! version . Contains ( '-' ) || version . Contains ( "rtm" ) ) ;
568+ IEnumerable < string > gaVersions = group . Where ( version => IsGAVersion ( version ) ) ;
558569 return gaVersions . Any ( ) ? gaVersions : group ;
559570 }
560- // Use the latest major version on the nightly branch
561- return group ;
562571 } )
563572 . Select ( group => group . Select ( version =>
564573 {
@@ -569,10 +578,40 @@ private static bool IsExpectedMajorMinorVersion(Repo repo, string version)
569578 } ) . OrderByDescending ( version => version ) . First ( ) )
570579 . ToList ( ) ;
571580
572- Version inputVersion = GetVersion ( version ) ;
581+ Version inputVersion = GetVersion ( majorMinorVersion ) ;
573582 return majorMinorVersions . Contains ( new Version ( inputVersion . Major , inputVersion . Minor ) ) ;
574583 }
575584
585+ /// <summary>
586+ /// Determines if a major product version has a preview version.
587+ /// </summary>
588+ private static bool HasPreviewProductVersion ( Repo repo , int majorVersion )
589+ {
590+ IEnumerable < string > productVersions = ManifestHelper . GetResolvedProductVersions ( repo ) ;
591+
592+ IGrouping < int , string > ? matchingMajorVersionGroup = productVersions
593+ . GroupBy ( version => GetVersion ( version ) . Major )
594+ . SingleOrDefault ( group => group . Key == majorVersion ) ;
595+
596+ if ( null == matchingMajorVersionGroup )
597+ return false ;
598+
599+ return matchingMajorVersionGroup . Any ( version => ! IsGAVersion ( version ) ) ;
600+ }
601+
602+ /// <summary>
603+ /// Determines if the version is considered a GA version.
604+ /// </summary>
605+ /// <remarks>
606+ /// Assumes that non-GA versions have a hyphen in them
607+ /// e.g. non-GA: 5.0.0-preview.1, GA: 5.0.0
608+ /// RTM versions are also accepted as GA versions.
609+ /// </remarks>
610+ private static bool IsGAVersion ( string version )
611+ {
612+ return ! version . Contains ( '-' ) || version . Contains ( "rtm" ) ;
613+ }
614+
576615 private static bool IsTagOfFormat (
577616 string tag ,
578617 VersionType versionType ,
0 commit comments