@@ -107,14 +107,14 @@ public void GoldenPathTest( string targetFramework )
107107 [ DataRow ( "net8.0" ) ]
108108 public void BuildVersionXmlIsUsed ( string targetFramework )
109109 {
110- string buildVersionXml = Context . CreateBuildVersionXmlWithRandomName ( 20 , 1 , 5 ) ;
110+ string buildVersionXmlPath = Context . CreateBuildVersionXmlWithRandomName ( 20 , 1 , 5 ) ;
111111 string buildTime = DateTime . UtcNow . ToString ( "o" ) ;
112112 const string buildIndex = "ABCDEF12" ;
113113 var globalProperties = new Dictionary < string , string >
114114 {
115115 [ PropertyNames . BuildTime ] = buildTime , // should be ignored as presence of explicit CiBuildIndex overrides it
116116 [ PropertyNames . CiBuildIndex ] = buildIndex ,
117- [ "BuildVersionXml" ] = buildVersionXml
117+ [ "BuildVersionXml" ] = buildVersionXmlPath
118118 } ;
119119
120120 using var collection = new ProjectCollection ( globalProperties ) ;
@@ -574,6 +574,228 @@ public void Projects_with_project_references_create_proper_dependencies_in_nuspe
574574 // look into generated nupkg to ensure dependency for dependentProj has correct version (and NOT the default 1.0.0)
575575 }
576576
577+ [ TestMethod ]
578+ [ DataRow ( "netstandard2.0" ) ]
579+ [ DataRow ( "net48" ) ]
580+ [ DataRow ( "net8.0" ) ]
581+ public void BuildVersionXmlSupportsPreReleaseName ( string targetFramework )
582+ {
583+ string buildVersionXmlPath = Context . CreateBuildVersionXmlWithRandomName ( 20 , 1 , 5 , "alpha" ) ;
584+ string buildTime = DateTime . UtcNow . ToString ( "o" ) ;
585+ const string buildIndex = "ABCDEF12" ;
586+ var globalProperties = new Dictionary < string , string >
587+ {
588+ [ PropertyNames . BuildTime ] = buildTime , // should be ignored as presence of explicit CiBuildIndex overrides it
589+ [ PropertyNames . CiBuildIndex ] = buildIndex ,
590+ [ "BuildVersionXml" ] = buildVersionXmlPath
591+ } ;
592+
593+ using var collection = new ProjectCollection ( globalProperties ) ;
594+
595+ using var fullResults = Context . CreateTestProjectAndInvokeTestedPackage ( targetFramework , collection ) ;
596+ var ( buildResults , props ) = fullResults ;
597+ Assert . IsTrue ( buildResults . Success ) ;
598+
599+ // v20.1.5-alpha => 5.44854.3878.23340 [see: https://csemver.org/playground/site/#/]
600+ // NOTE: CI build is Patch+1 for the string form
601+ // and for a FileVersion, it is baseBuild + CI bit.
602+ // Non-prerelease double dash.
603+ string expectedFullBuildNumber = $ "20.1.6-alpha.0.0.ci.ABCDEF12.ZZZ";
604+ string expectedFileVersion = "5.44854.3878.23341" ;
605+
606+ Assert . IsNotNull ( props . BuildMajor ) ;
607+ Assert . AreEqual ( 20u , props . BuildMajor . Value ) ;
608+
609+ Assert . IsNotNull ( props . BuildMinor ) ;
610+ Assert . AreEqual ( 1u , props . BuildMinor . Value ) ;
611+
612+ Assert . IsNotNull ( props . BuildPatch ) ;
613+ Assert . AreEqual ( 5u , props . BuildPatch . Value ) ;
614+
615+ Assert . IsNotNull ( props . PreReleaseName ) ;
616+ Assert . AreEqual ( "alpha" , props . PreReleaseName ) ;
617+
618+ Assert . IsNull ( props . PreReleaseNumber ) ;
619+ Assert . IsNull ( props . PreReleaseFix ) ;
620+
621+ Assert . AreEqual ( expectedFullBuildNumber , props . FullBuildNumber ) ;
622+ Assert . AreEqual ( expectedFullBuildNumber , props . PackageVersion ) ;
623+
624+ // Test for expected global properties (Should not change values)
625+ Assert . AreEqual ( buildTime , props . BuildTime ) ;
626+ Assert . AreEqual ( buildIndex , props . CiBuildIndex ) ;
627+
628+ Assert . AreEqual ( "ZZZ" , props . CiBuildName ) ;
629+
630+ Assert . IsNotNull ( props . FileVersionMajor ) ;
631+ Assert . AreEqual ( 5 , props . FileVersionMajor . Value ) ;
632+
633+ Assert . IsNotNull ( props . FileVersionMinor ) ;
634+ Assert . AreEqual ( 44854 , props . FileVersionMinor . Value ) ;
635+
636+ Assert . IsNotNull ( props . FileVersionBuild ) ;
637+ Assert . AreEqual ( 3878 , props . FileVersionBuild . Value ) ;
638+
639+ Assert . IsNotNull ( props . FileVersionRevision ) ;
640+
641+ // CI Build so patch+1
642+ Assert . AreEqual ( 23341 , props . FileVersionRevision . Value ) ;
643+
644+ Assert . AreEqual ( expectedFileVersion , props . FileVersion ) ;
645+ Assert . AreEqual ( expectedFileVersion , props . AssemblyVersion ) ;
646+ Assert . AreEqual ( expectedFullBuildNumber , props . InformationalVersion ) ;
647+ }
648+
649+ [ TestMethod ]
650+ [ DataRow ( "netstandard2.0" ) ]
651+ [ DataRow ( "net48" ) ]
652+ [ DataRow ( "net8.0" ) ]
653+ public void BuildVersionXmlSupportsPreReleaseFixWithZeroNumber ( string targetFramework )
654+ {
655+ string buildVersionXmlPath = Context . CreateBuildVersionXmlWithRandomName ( 20 , 1 , 5 , "alpha" , 0 , 1 ) ;
656+ string buildTime = DateTime . UtcNow . ToString ( "o" ) ;
657+ const string buildIndex = "ABCDEF12" ;
658+ var globalProperties = new Dictionary < string , string >
659+ {
660+ [ PropertyNames . BuildTime ] = buildTime , // should be ignored as presence of explicit CiBuildIndex overrides it
661+ [ PropertyNames . CiBuildIndex ] = buildIndex ,
662+ [ "BuildVersionXml" ] = buildVersionXmlPath
663+ } ;
664+
665+ using var collection = new ProjectCollection ( globalProperties ) ;
666+
667+ using var fullResults = Context . CreateTestProjectAndInvokeTestedPackage ( targetFramework , collection ) ;
668+ var ( buildResults , props ) = fullResults ;
669+ Assert . IsTrue ( buildResults . Success ) ;
670+
671+ // v20.1.5-alpha.0.1 => 5.44854.3878.23342 [see: https://csemver.org/playground/site/#/]
672+ // NOTE: CI build is Patch+1 for the string form
673+ // and for a FileVersion, it is baseBuild + CI bit.
674+ // Non-prerelease double dash.
675+ string expectedFullBuildNumber = $ "20.1.6-alpha.0.1.ci.ABCDEF12.ZZZ";
676+ string expectedFileVersion = "5.44854.3878.23343" ;
677+
678+ Assert . IsNotNull ( props . BuildMajor ) ;
679+ Assert . AreEqual ( 20u , props . BuildMajor . Value ) ;
680+
681+ Assert . IsNotNull ( props . BuildMinor ) ;
682+ Assert . AreEqual ( 1u , props . BuildMinor . Value ) ;
683+
684+ Assert . IsNotNull ( props . BuildPatch ) ;
685+ Assert . AreEqual ( 5u , props . BuildPatch . Value ) ;
686+
687+ Assert . IsNotNull ( props . PreReleaseName ) ;
688+ Assert . AreEqual ( "alpha" , props . PreReleaseName ) ;
689+
690+ Assert . IsNotNull ( props . PreReleaseNumber ) ;
691+ Assert . AreEqual ( 0 , props . PreReleaseNumber . Value , "PreReleaseNumber should be what was set" ) ;
692+
693+ Assert . IsNotNull ( props . PreReleaseFix ) ;
694+ Assert . AreEqual ( 1 , props . PreReleaseFix . Value , "PreReleaseFix should be what was set" ) ;
695+
696+ Assert . AreEqual ( expectedFullBuildNumber , props . FullBuildNumber ) ;
697+ Assert . AreEqual ( expectedFullBuildNumber , props . PackageVersion ) ;
698+
699+ // Test for expected global properties (Should not change values)
700+ Assert . AreEqual ( buildTime , props . BuildTime ) ;
701+ Assert . AreEqual ( buildIndex , props . CiBuildIndex ) ;
702+
703+ Assert . AreEqual ( "ZZZ" , props . CiBuildName ) ;
704+
705+ Assert . IsNotNull ( props . FileVersionMajor ) ;
706+ Assert . AreEqual ( 5 , props . FileVersionMajor . Value ) ;
707+
708+ Assert . IsNotNull ( props . FileVersionMinor ) ;
709+ Assert . AreEqual ( 44854 , props . FileVersionMinor . Value ) ;
710+
711+ Assert . IsNotNull ( props . FileVersionBuild ) ;
712+ Assert . AreEqual ( 3878 , props . FileVersionBuild . Value ) ;
713+
714+ Assert . IsNotNull ( props . FileVersionRevision ) ;
715+
716+ // CI Build so patch+1
717+ Assert . AreEqual ( 23343 , props . FileVersionRevision . Value ) ;
718+
719+ Assert . AreEqual ( expectedFileVersion , props . FileVersion ) ;
720+ Assert . AreEqual ( expectedFileVersion , props . AssemblyVersion ) ;
721+ Assert . AreEqual ( expectedFullBuildNumber , props . InformationalVersion ) ;
722+ }
723+
724+ [ TestMethod ]
725+ [ DataRow ( "netstandard2.0" ) ]
726+ [ DataRow ( "net48" ) ]
727+ [ DataRow ( "net8.0" ) ]
728+ public void BuildVersionXmlSupportsPreReleaseFixWithZeroNumberRelease ( string targetFramework )
729+ {
730+ string buildVersionXmlPath = Context . CreateBuildVersionXmlWithRandomName ( 20 , 1 , 8 , "alpha" , 0 , 1 ) ;
731+ var globalProperties = new Dictionary < string , string >
732+ {
733+ [ "BuildVersionXml" ] = buildVersionXmlPath ,
734+
735+ // ensure generation is based on the test input and does NOT create
736+ // a CI build version if it isn't supposed to.
737+ [ EnvVarNames . IsReleaseBuild ] = "true"
738+ } ;
739+
740+ using var collection = new ProjectCollection ( globalProperties ) ;
741+
742+ using var fullResults = Context . CreateTestProjectAndInvokeTestedPackage ( targetFramework , collection ) ;
743+ var ( buildResults , props ) = fullResults ;
744+ Assert . IsTrue ( buildResults . Success ) ;
745+
746+ // v20.1.8-alpha.0.1 => 5.44854.3885.44596 [see: https://csemver.org/playground/site/#/]
747+ // NOTE: CI build is Patch+1 for the string form
748+ // and for a FileVersion, it is baseBuild + CI bit.
749+ // Non-prerelease double dash.
750+ string expectedFullBuildNumber = $ "20.1.8-alpha.0.1";
751+ string expectedFileVersion = "5.44854.3885.44596" ;
752+
753+ Assert . IsNotNull ( props . BuildMajor ) ;
754+ Assert . AreEqual ( 20u , props . BuildMajor . Value ) ;
755+
756+ Assert . IsNotNull ( props . BuildMinor ) ;
757+ Assert . AreEqual ( 1u , props . BuildMinor . Value ) ;
758+
759+ Assert . IsNotNull ( props . BuildPatch ) ;
760+ Assert . AreEqual ( 8u , props . BuildPatch . Value ) ;
761+
762+ Assert . IsNotNull ( props . PreReleaseName ) ;
763+ Assert . AreEqual ( "alpha" , props . PreReleaseName ) ;
764+
765+ Assert . IsNotNull ( props . PreReleaseNumber ) ;
766+ Assert . AreEqual ( 0 , props . PreReleaseNumber . Value , "PreReleaseNumber should be what was set" ) ;
767+
768+ Assert . IsNotNull ( props . PreReleaseFix ) ;
769+
770+ Assert . AreEqual ( 1 , props . PreReleaseFix . Value , "PreReleaseFix should be what was set" ) ;
771+ Assert . AreEqual ( expectedFullBuildNumber , props . FullBuildNumber ) ;
772+ Assert . AreEqual ( expectedFullBuildNumber , props . PackageVersion ) ;
773+
774+ // Props file will set these based on runtime context, but then they are not used.
775+ //Assert.AreEqual(buildTime, props.BuildTime);
776+ //Assert.AreEqual(buildIndex, props.CiBuildIndex);
777+
778+ Assert . AreEqual ( string . Empty , props . CiBuildName , "Release builds should not have CI information" ) ;
779+
780+ Assert . IsNotNull ( props . FileVersionMajor ) ;
781+ Assert . AreEqual ( 5 , props . FileVersionMajor . Value ) ;
782+
783+ Assert . IsNotNull ( props . FileVersionMinor ) ;
784+ Assert . AreEqual ( 44854 , props . FileVersionMinor . Value ) ;
785+
786+ Assert . IsNotNull ( props . FileVersionBuild ) ;
787+ Assert . AreEqual ( 3885 , props . FileVersionBuild . Value ) ;
788+
789+ Assert . IsNotNull ( props . FileVersionRevision ) ;
790+
791+ // NOT a CI Build so NOT patch+1
792+ Assert . AreEqual ( 44596 , props . FileVersionRevision . Value ) ;
793+
794+ Assert . AreEqual ( expectedFileVersion , props . FileVersion ) ;
795+ Assert . AreEqual ( expectedFileVersion , props . AssemblyVersion ) ;
796+ Assert . AreEqual ( expectedFullBuildNumber , props . InformationalVersion ) ;
797+ }
798+
577799 private static IEnumerable < PrereleaseTestData > GetPrereleaseTestData ( )
578800 {
579801 return from tfm in TargetFrameworks
0 commit comments