public async Task BasicRepoBuild() { var envVars = Environment.GetEnvironmentVariables(); using (var builder = new TestRepoBuilder(nameof(BasicRepoBuild), _commonRepoResourcesFixture.CommonResources)) { await builder.AddDefaultRepoSetupAsync(); builder.AddProject(ProjectCreator .Create() .PropertyGroup() .Property("AllowEmptySignList", "true"), "eng/Signing.props"); // Create a simple project builder.AddProject(ProjectCreator .Templates .SdkCsproj( targetFramework: "net6.0", outputType: "Exe") .PropertyGroup() .Property("IsPackable", "true"), "./src/FooPackage/FooPackage.csproj"); await builder.AddSimpleCSFile("src/FooPackage/Program.cs"); builder.Build( TestRepoUtils.BuildArg("configuration"), "Release", TestRepoUtils.BuildArg("restore"), TestRepoUtils.BuildArg("sign"), TestRepoUtils.BuildArg("projects"), Path.Combine(builder.TestRepoRoot, "src/FooPackage/FooPackage.csproj")) .Should().NotThrow(); } }
public async Task BuildShouldUseDotNetCertifcateIfSet(bool?useDotNetCert) { var envVars = Environment.GetEnvironmentVariables(); using (var builder = new TestRepoBuilder(nameof(BuildShouldUseDotNetCertifcateIfSet), _commonRepoResourcesFixture.CommonResources)) { await builder.AddDefaultRepoSetupAsync(); // Always put in the AllowEmptySignList var signingProps = ProjectCreator.Create().PropertyGroup(); signingProps.Property("AllowEmptySignList", "true"); if (useDotNetCert.HasValue) { signingProps.Property("UseDotNetCertificate", useDotNetCert.Value.ToString()); } // Clear out ItemsToSignPostBuild signingProps.ItemGroup() .ItemRemove("ItemsToSignPostBuild", "@(ItemsToSignPostBuild)"); builder.AddProject(signingProps, "eng/Signing.props"); // Create a simple project builder.AddProject(ProjectCreator .Templates .SdkCsproj( targetFramework: "net6.0", outputType: "Exe") .PropertyGroup() .Property("IsPackable", "true") .Property("EnableSourceLink", "false"), "./src/FooPackage/FooPackage.csproj"); await builder.AddSimpleCSFile("src/FooPackage/Program.cs"); builder.Build( TestRepoUtils.BuildArg("configuration"), "Release", TestRepoUtils.BuildArg("restore"), TestRepoUtils.BuildArg("pack"), TestRepoUtils.BuildArg("publish"), TestRepoUtils.BuildArg("sign"), TestRepoUtils.BuildArg("projects"), Path.Combine(builder.TestRepoRoot, "src/FooPackage/FooPackage.csproj"), "/p:AutoGenerateSymbolPackages=false") .Should().NotThrow(); // Now, go find the Round0 signing project and ensure that the certificate names were set properly. // The arcade default for an exe is Microsoft400 string round0FilePath = Path.Combine(builder.TestRepoRoot, "artifacts", "tmp", "Release", "Signing", "Round0.proj"); string round0ProjectText = File.ReadAllText(round0FilePath); string expectedCert = useDotNetCert.GetValueOrDefault() ? DotNetCertificate : MicrosoftCertificate; Regex authenticodeRegex = new Regex("<Authenticode>(.*)</Authenticode>"); var matches = authenticodeRegex.Matches(round0ProjectText); matches.Count.Should().Be(1); matches[0].Groups[1].Value.Should().Be(expectedCert); } }
public async Task BuildShouldNotChangeNonMicrosoft400CertsWhenPostBuildSigning() { var envVars = Environment.GetEnvironmentVariables(); using (var builder = new TestRepoBuilder(nameof(BuildShouldNotChangeNonMicrosoft400CertsWhenSigning), _commonRepoResourcesFixture.CommonResources)) { await builder.AddDefaultRepoSetupAsync(); // Always put in the AllowEmptySignList var signingProps = ProjectCreator.Create().PropertyGroup(); signingProps.Property("AllowEmptySignList", "true"); signingProps.Property("UseDotNetCertificate", "true"); // Update the .exe extension with a new cert. const string certOverride = "Microsoft401"; signingProps.ItemGroup() .ItemUpdate("StrongNameSignInfo", update: "MsSharedLib72", metadata: new Dictionary <string, string> { { "PublicKeyToken", "31bf3856ad364e35" }, { "CertificateName", certOverride } }); builder.AddProject(signingProps, "eng/Signing.props"); // Create a simple project builder.AddProject(ProjectCreator .Templates .SdkCsproj( targetFramework: "net6.0", outputType: "Exe") .PropertyGroup() .Property("IsPackable", "true") .Property("EnableSourceLink", "false"), "./src/FooPackage/FooPackage.csproj"); await builder.AddSimpleCSFile("src/FooPackage/Program.cs"); builder.Build( TestRepoUtils.BuildArg("configuration"), "Release", TestRepoUtils.BuildArg("restore"), TestRepoUtils.BuildArg("pack"), TestRepoUtils.BuildArg("publish"), TestRepoUtils.BuildArg("sign"), TestRepoUtils.BuildArg("projects"), Path.Combine(builder.TestRepoRoot, "src/FooPackage/FooPackage.csproj"), "/p:AutoGenerateSymbolPackages=false", "/p:PostBuildSign=true", "/p:DotNetPublishUsingPipelines=true") .Should().NotThrow(); string assetManifestText = GetAssetManifest(builder); // Should find Microsoft401, MicrosoftDotNet500, but not Microsoft400 assetManifestText.IndexOf(DotNetCertificate).Should().NotBe(-1); assetManifestText.IndexOf(certOverride).Should().NotBe(-1); assetManifestText.IndexOf(MicrosoftCertificate).Should().Be(-1); } }
public async Task BuildShouldUseDotNetCertifcateIfSetWithPostBuildSigning(bool?useDotNetCert) { var envVars = Environment.GetEnvironmentVariables(); using (var builder = new TestRepoBuilder(nameof(BuildShouldUseDotNetCertifcateIfSet), _commonRepoResourcesFixture.CommonResources)) { await builder.AddDefaultRepoSetupAsync(); // Always put in the AllowEmptySignList var signingProps = ProjectCreator.Create().PropertyGroup(); signingProps.Property("AllowEmptySignList", "true"); if (useDotNetCert.HasValue) { signingProps.Property("UseDotNetCertificate", useDotNetCert.Value.ToString()); } builder.AddProject(signingProps, "eng/Signing.props"); // Create a simple project builder.AddProject(ProjectCreator .Templates .SdkCsproj( targetFramework: "net6.0", outputType: "Exe") .PropertyGroup() .Property("IsPackable", "true") .Property("EnableSourceLink", "false"), "./src/FooPackage/FooPackage.csproj"); await builder.AddSimpleCSFile("src/FooPackage/Program.cs"); builder.Build( TestRepoUtils.BuildArg("configuration"), "Release", TestRepoUtils.BuildArg("restore"), TestRepoUtils.BuildArg("pack"), TestRepoUtils.BuildArg("publish"), TestRepoUtils.BuildArg("sign"), TestRepoUtils.BuildArg("projects"), Path.Combine(builder.TestRepoRoot, "src/FooPackage/FooPackage.csproj"), "/p:AutoGenerateSymbolPackages=false", "/p:PostBuildSign=true", "/p:DotNetPublishUsingPipelines=true") .Should().NotThrow(); string assetManifestText = GetAssetManifest(builder); string expectedCert = useDotNetCert.GetValueOrDefault() ? DotNetCertificate : MicrosoftCertificate; string unexpectedCert = useDotNetCert.GetValueOrDefault() ? MicrosoftCertificate : DotNetCertificate; // Ensure that we see the expected cert. assetManifestText.IndexOf(unexpectedCert).Should().Be(-1); assetManifestText.IndexOf(expectedCert).Should().NotBe(-1); } }
public async Task BuildShouldErrorIfNoItemsToSignAndNonEmptySignPostBuildList(bool propertyIsSet) { var envVars = Environment.GetEnvironmentVariables(); using (var builder = new TestRepoBuilder(nameof(BuildShouldErrorIfNoItemsToSignAndNonEmptySignPostBuildList), _commonRepoResourcesFixture.CommonResources)) { await builder.AddDefaultRepoSetupAsync(); // Always put in the AllowEmptySignList var signingProps = ProjectCreator.Create().PropertyGroup(); signingProps.Property("AllowEmptySignList", "true"); if (propertyIsSet) { signingProps.Property("AllowEmptySignPostBuildList", "false"); } // Clear out ItemsToSignPostBuild signingProps.ItemGroup() .ItemRemove("ItemsToSignPostBuild", "@(ItemsToSignPostBuild)"); builder.AddProject(signingProps, "eng/Signing.props"); // Create a simple project builder.AddProject(ProjectCreator .Templates .SdkCsproj( targetFramework: "net6.0", outputType: "Exe") .PropertyGroup() .Property("IsPackable", "true") .Property("EnableSourceLink", "false"), "./src/FooPackage/FooPackage.csproj"); await builder.AddSimpleCSFile("src/FooPackage/Program.cs"); builder.Build( TestRepoUtils.BuildArg("configuration"), "Release", TestRepoUtils.BuildArg("restore"), TestRepoUtils.BuildArg("pack"), TestRepoUtils.BuildArg("publish"), TestRepoUtils.BuildArg("sign"), TestRepoUtils.BuildArg("projects"), Path.Combine(builder.TestRepoRoot, "src/FooPackage/FooPackage.csproj"), "/p:AutoGenerateSymbolPackages=false", "/p:PostBuildSign=true") .Should().Throw <Exception>($"build of repo {builder.TestRepoRoot} is post build signed") .WithMessage("*error : List of files to sign post-build is empty. Make sure that ItemsToSignPostBuild is configured correctly.*"); } }
public async Task BuildShouldErrorIfNoItemsToSignAndNonEmptySignList(bool propertyIsSet) { var envVars = Environment.GetEnvironmentVariables(); using (var builder = new TestRepoBuilder(nameof(BuildShouldErrorIfNoItemsToSignAndNonEmptySignList), _commonRepoResourcesFixture.CommonResources)) { await builder.AddDefaultRepoSetupAsync(); if (propertyIsSet) { builder.AddProject(ProjectCreator .Create() .PropertyGroup() .Property("AllowEmptySignList", "false"), "eng/Signing.props"); } // Create a simple project builder.AddProject(ProjectCreator .Templates .SdkCsproj( targetFramework: "net6.0", outputType: "Exe") .PropertyGroup() .Property("IsPackable", "true"), "./src/FooPackage/FooPackage.csproj"); await builder.AddSimpleCSFile("src/FooPackage/Program.cs"); builder.Build( TestRepoUtils.BuildArg("configuration"), "Release", TestRepoUtils.BuildArg("restore"), TestRepoUtils.BuildArg("sign"), TestRepoUtils.BuildArg("projects"), Path.Combine(builder.TestRepoRoot, "src/FooPackage/FooPackage.csproj")) .Should().Throw <Exception>().WithMessage("*error : List of files to sign is empty. Make sure that ItemsToSign is configured correctly*"); } }
public async Task BuildShouldNotChangeNonMicrosoft400CertsWhenSigning() { var envVars = Environment.GetEnvironmentVariables(); using (var builder = new TestRepoBuilder(nameof(BuildShouldNotChangeNonMicrosoft400CertsWhenSigning), _commonRepoResourcesFixture.CommonResources)) { await builder.AddDefaultRepoSetupAsync(); // Always put in the AllowEmptySignList var signingProps = ProjectCreator.Create().PropertyGroup(); signingProps.Property("AllowEmptySignList", "true"); // Clear out ItemsToSignPostBuild signingProps.ItemGroup() .ItemRemove("ItemsToSignPostBuild", "@(ItemsToSignPostBuild)"); // Update the .exe extension with a new cert. // <StrongNameSignInfo Include="MsSharedLib72" PublicKeyToken="31bf3856ad364e35" CertificateName="Microsoft400" /> const string certOverride = "Microsoft401"; signingProps.ItemGroup() .ItemUpdate("StrongNameSignInfo", update: "MsSharedLib72", metadata: new Dictionary <string, string> { { "PublicKeyToken", "31bf3856ad364e35" }, { "CertificateName", certOverride } }); builder.AddProject(signingProps, "eng/Signing.props"); // Create a simple project builder.AddProject(ProjectCreator .Templates .SdkCsproj( targetFramework: "net6.0", outputType: "Exe") .PropertyGroup() .Property("IsPackable", "true") .Property("EnableSourceLink", "false"), "./src/FooPackage/FooPackage.csproj"); await builder.AddSimpleCSFile("src/FooPackage/Program.cs"); builder.Build( TestRepoUtils.BuildArg("configuration"), "Release", TestRepoUtils.BuildArg("restore"), TestRepoUtils.BuildArg("pack"), TestRepoUtils.BuildArg("publish"), TestRepoUtils.BuildArg("sign"), TestRepoUtils.BuildArg("projects"), Path.Combine(builder.TestRepoRoot, "src/FooPackage/FooPackage.csproj"), "/p:AutoGenerateSymbolPackages=false") .Should().NotThrow(); // Now, go find the Round0 signing project and ensure that the certificate names were set properly. // The arcade default for an exe is Microsoft400 string round0FilePath = Path.Combine(builder.TestRepoRoot, "artifacts", "tmp", "Release", "Signing", "Round0.proj"); string round0ProjectText = File.ReadAllText(round0FilePath); Regex authenticodeRegex = new Regex("<Authenticode>(.*)</Authenticode>"); var matches = authenticodeRegex.Matches(round0ProjectText); matches.Count.Should().Be(1); matches[0].Groups[1].Value.Should().Be(certOverride); } }
/// <summary> /// Create a set of repo resources. /// </summary> /// <param name="useIsolatedRoots"> /// Should isolated .dotnet and .packages locations /// be used? If false, then to share a dotnet root, a simple repo is created /// and restored. Then the resulting .dotnet and .packages directories are /// </param> /// <returns></returns> public static async Task <RepoResources> Create(bool useIsolatedRoots) { string dotnetVersion; string arcadeVersion; string dotnetRoot = null; string packagesRoot = null; string commonRoot = null; var globalJsonLocation = TestRepoBuilder.GetTestInputPath("global.json"); using (var reader = new StreamReader(globalJsonLocation)) using (JsonDocument doc = JsonDocument.Parse(reader.BaseStream)) { dotnetVersion = doc.RootElement.GetProperty("tools").GetProperty("dotnet").GetString(); arcadeVersion = doc.RootElement.GetProperty("msbuild-sdks").GetProperty("Microsoft.DotNet.Arcade.Sdk").GetString(); } // If not using isolated roots, create a quick test repo builder // to restore things. if (!useIsolatedRoots) { // Common repo resources for constructing a simple repo. The // repo's test dir is set to not be deleted, and the .dotnet and .packages paths are extracted. // During the disposal of the returned set of resources, the common dir is deleted. var commonRepoResources = new RepoResources() { ArcadeVersion = arcadeVersion, DotNetVersion = dotnetVersion }; using (var builder = new TestRepoBuilder("common", commonRepoResources, deleteOnDispose: false)) { await builder.AddDefaultRepoSetupAsync(); // Create a simple project builder.AddProject(ProjectCreator .Templates .SdkCsproj( targetFramework: "net5.0", outputType: "Exe"), "./src/FooPackage/FooPackage.csproj"); await builder.AddSimpleCSFile("./src/FooPackage/Program.cs"); builder.Build( TestRepoUtils.BuildArg("restore"), TestRepoUtils.BuildArg("ci"), TestRepoUtils.BuildArg("projects"), Path.Combine(builder.TestRepoRoot, "src/FooPackage/FooPackage.csproj"))(); commonRoot = builder.TestRepoRoot; dotnetRoot = Path.Combine(builder.TestRepoRoot, ".dotnet"); if (!Directory.Exists(dotnetRoot)) { // Coming from the machine dotnetRoot = null; } packagesRoot = Path.Combine(builder.TestRepoRoot, ".packages"); if (!Directory.Exists(packagesRoot)) { packagesRoot = null; } } } RepoResources repoResources = new RepoResources() { ArcadeVersion = arcadeVersion, DotNetVersion = dotnetVersion, CommonPackagesRoot = packagesRoot, CommonDotnetRoot = dotnetRoot, CommonRoot = commonRoot }; return(repoResources); }