From 2c6e18d6b26914499e205690beec2ee94dd1cb07 Mon Sep 17 00:00:00 2001
From: Z Chen <13544267+zijchen@users.noreply.github.com>
Date: Wed, 25 Sep 2024 10:51:08 -0700
Subject: [PATCH] Add support for dotnet publish (#487)
* Add support for dotnet publish
* Fix test
* Add condition to target override
* Set property directly instead of importing BeforeCommon.targets
---
src/Microsoft.Build.Sql/sdk/Sdk.props | 1 +
src/Microsoft.Build.Sql/sdk/Sdk.targets | 16 ++-
.../DotnetTestBase.cs | 47 +++++++-
.../PackageReferenceTests.cs | 29 -----
.../Microsoft.Build.Sql.Tests/PublishTests.cs | 104 ++++++++++++++++++
5 files changed, 161 insertions(+), 36 deletions(-)
create mode 100644 test/Microsoft.Build.Sql.Tests/PublishTests.cs
diff --git a/src/Microsoft.Build.Sql/sdk/Sdk.props b/src/Microsoft.Build.Sql/sdk/Sdk.props
index 2dfff64..4b94526 100644
--- a/src/Microsoft.Build.Sql/sdk/Sdk.props
+++ b/src/Microsoft.Build.Sql/sdk/Sdk.props
@@ -15,6 +15,7 @@
netstandard2.1
@(SupportedTargetFramework->'%(Alias)')
+ publish
diff --git a/src/Microsoft.Build.Sql/sdk/Sdk.targets b/src/Microsoft.Build.Sql/sdk/Sdk.targets
index 83b798b..c1aa439 100644
--- a/src/Microsoft.Build.Sql/sdk/Sdk.targets
+++ b/src/Microsoft.Build.Sql/sdk/Sdk.targets
@@ -38,6 +38,12 @@
$(NoWarn),NU5128
+
+
+ publish
+ $(OutputPath)$(PublishDirName)\
+
+
@@ -63,6 +71,12 @@
+
+
+
+
+
+
diff --git a/test/Microsoft.Build.Sql.Tests/DotnetTestBase.cs b/test/Microsoft.Build.Sql.Tests/DotnetTestBase.cs
index 12bb3ae..f0df4d3 100644
--- a/test/Microsoft.Build.Sql.Tests/DotnetTestBase.cs
+++ b/test/Microsoft.Build.Sql.Tests/DotnetTestBase.cs
@@ -5,6 +5,7 @@
using System.Diagnostics;
using System.IO;
using System.Text;
+using Microsoft.Build.Construction;
using Microsoft.SqlServer.Dac;
using NUnit.Framework;
using NUnit.Framework.Interfaces;
@@ -36,10 +37,19 @@ protected string CurrentTestDataDirectory
get { return Path.Combine(this.CommonTestDataDirectory, TestUtils.EscapeTestName(TestContext.CurrentContext.Test.Name)); }
}
+ private string LocalNugetSource
+ {
+ get { return Path.Combine(this.WorkingDirectory, "pkg"); }
+ }
+
[SetUp]
public void TestSetup()
{
EnvironmentSetup();
+
+ // Add pkg folder as a nuget source
+ RunGenericDotnetCommand($"nuget add source \"{LocalNugetSource}\" --name TestSource_{TestContext.CurrentContext.Test.Name}", out _, out string stdError);
+ Assert.AreEqual("", stdError, "Failed to add local nuget source: " + stdError);
}
[TearDown]
@@ -85,8 +95,7 @@ protected void EnvironmentSetup()
}
// Copy SDK nuget package to Workingdirectory/pkg/
- string localNugetSource = Path.Combine(this.WorkingDirectory, "pkg");
- TestUtils.CopyDirectoryRecursive("../../../pkg", localNugetSource);
+ TestUtils.CopyDirectoryRecursive("../../../pkg", LocalNugetSource);
// Copy common project files from Template to WorkingDirectory
TestUtils.CopyDirectoryRecursive("../../../Template", this.WorkingDirectory);
@@ -96,10 +105,6 @@ protected void EnvironmentSetup()
{
TestUtils.CopyDirectoryRecursive(this.CurrentTestDataDirectory, this.WorkingDirectory);
}
-
- // Add pkg folder as a nuget source
- RunGenericDotnetCommand($"nuget add source \"{localNugetSource}\" --name TestSource_{TestContext.CurrentContext.Test.Name}", out _, out string stdError);
- Assert.AreEqual("", stdError, "Failed to add local nuget source: " + stdError);
}
///
@@ -294,6 +299,36 @@ protected void AddProjectReference(params string[] projects)
ProjectUtils.AddItemGroup(this.GetProjectFilePath(), "ProjectReference", projects);
}
+ ///
+ /// Add a package reference to a Nuget package.
+ ///
+ protected void AddPackageReference(string packageName, string version, string serverSqlcmdVariable = "", string databaseSqlcmdVariable = "", string databaseVariableLiteralValue = "", bool? suppressMissingDependenciesErrors = null)
+ {
+ ProjectUtils.AddItemGroup(this.GetProjectFilePath(), "PackageReference", new string[] { packageName }, (ProjectItemElement item) => {
+ item.AddMetadata("Version", version);
+
+ if (!string.IsNullOrEmpty(serverSqlcmdVariable))
+ {
+ item.AddMetadata("ServerSqlCmdVariable", serverSqlcmdVariable);
+ }
+
+ if (!string.IsNullOrEmpty(databaseSqlcmdVariable))
+ {
+ item.AddMetadata("DatabaseSqlCmdVariable", databaseSqlcmdVariable);
+ }
+
+ if (!string.IsNullOrEmpty(databaseVariableLiteralValue))
+ {
+ item.AddMetadata("DatabaseVariableLiteralValue", databaseVariableLiteralValue);
+ }
+
+ if (suppressMissingDependenciesErrors.HasValue)
+ {
+ item.AddMetadata("SuppressMissingDependenciesErrors", suppressMissingDependenciesErrors.ToString());
+ }
+ });
+ }
+
///
/// Returns the full path to the sqlproj file used for this test.
///
diff --git a/test/Microsoft.Build.Sql.Tests/PackageReferenceTests.cs b/test/Microsoft.Build.Sql.Tests/PackageReferenceTests.cs
index fd92871..691d77c 100644
--- a/test/Microsoft.Build.Sql.Tests/PackageReferenceTests.cs
+++ b/test/Microsoft.Build.Sql.Tests/PackageReferenceTests.cs
@@ -3,7 +3,6 @@
using System.Collections.Generic;
using System.IO;
-using Microsoft.Build.Construction;
using NUnit.Framework;
namespace Microsoft.Build.Sql.Tests
@@ -110,33 +109,5 @@ public void VerifyPackageReferenceToMasterAndGenerateCreateScript()
this.VerifyDacPackage();
FileAssert.Exists(Path.Combine(this.GetOutputDirectory(), $"{DatabaseProjectName}_Create.sql"));
}
-
- private void AddPackageReference(string packageName, string version, string serverSqlcmdVariable = "", string databaseSqlcmdVariable = "", string databaseVariableLiteralValue = "", bool? suppressMissingDependenciesErrors = null)
- {
- // Add a package reference to ReferenceProj version 5.5.5
- ProjectUtils.AddItemGroup(this.GetProjectFilePath(), "PackageReference", new string[] { packageName }, (ProjectItemElement item) => {
- item.AddMetadata("Version", version);
-
- if (!string.IsNullOrEmpty(serverSqlcmdVariable))
- {
- item.AddMetadata("ServerSqlCmdVariable", serverSqlcmdVariable);
- }
-
- if (!string.IsNullOrEmpty(databaseSqlcmdVariable))
- {
- item.AddMetadata("DatabaseSqlCmdVariable", databaseSqlcmdVariable);
- }
-
- if (!string.IsNullOrEmpty(databaseVariableLiteralValue))
- {
- item.AddMetadata("DatabaseVariableLiteralValue", databaseVariableLiteralValue);
- }
-
- if (suppressMissingDependenciesErrors.HasValue)
- {
- item.AddMetadata("SuppressMissingDependenciesErrors", suppressMissingDependenciesErrors.ToString());
- }
- });
- }
}
}
\ No newline at end of file
diff --git a/test/Microsoft.Build.Sql.Tests/PublishTests.cs b/test/Microsoft.Build.Sql.Tests/PublishTests.cs
new file mode 100644
index 0000000..0119d07
--- /dev/null
+++ b/test/Microsoft.Build.Sql.Tests/PublishTests.cs
@@ -0,0 +1,104 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT License.
+
+using System.IO;
+using Microsoft.Build.Construction;
+using NUnit.Framework;
+
+namespace Microsoft.Build.Sql.Tests
+{
+ [TestFixture]
+ public class PublishTests : DotnetTestBase
+ {
+ [Test]
+ public void VerifySimplePublish()
+ {
+ int exitCode = this.RunDotnetCommandOnProject("publish", out _, out string stdError);
+
+ // Verify success
+ Assert.AreEqual(0, exitCode, "Publish failed with error " + stdError);
+ Assert.AreEqual(string.Empty, stdError);
+ this.VerifyDacPackage();
+ this.VerifyPublishFolder();
+ }
+
+ [Test]
+ public void VerifyPublishWithNoBuild()
+ {
+ // Run build first
+ int exitCode = this.RunDotnetCommandOnProject("publish", out _, out string stdError);
+ Assert.AreEqual(0, exitCode, "Build failed with error " + stdError);
+ Assert.AreEqual(string.Empty, stdError);
+ this.VerifyDacPackage();
+
+ // Run publish with --no-build
+ exitCode = this.RunDotnetCommandOnProject("publish --no-build", out _, out stdError);
+ Assert.AreEqual(0, exitCode, "publish failed with error " + stdError);
+ Assert.AreEqual(string.Empty, stdError);
+ this.VerifyPublishFolder();
+ }
+
+ [Test]
+ public void VerifyPublishkWithIncludedFiles()
+ {
+ // Add a content file that is copied to output
+ string includedContent = Path.Combine(this.WorkingDirectory, "include_content.txt");
+ File.WriteAllText(includedContent, "test");
+ ProjectUtils.AddItemGroup(this.GetProjectFilePath(), "Content", new[] { includedContent }, (ProjectItemElement item) =>
+ {
+ item.AddMetadata("CopyToOutputDirectory", "PreserveNewest");
+ });
+
+ // Run dotnet publish
+ int exitCode = this.RunDotnetCommandOnProject("publish", out _, out string stdError);
+
+ // Verify
+ Assert.AreEqual(0, exitCode, "Publish failed with error " + stdError);
+ Assert.AreEqual(string.Empty, stdError);
+ this.VerifyPublishFolder("include_content.txt");
+ }
+
+ [Test]
+ public void VerifyPublishWithProjectReference()
+ {
+ // Add a project reference to ReferenceProj, which should be copied to the publish directory
+ string tempFolder = TestUtils.CreateTempDirectory();
+ TestUtils.CopyDirectoryRecursive(Path.Combine(this.CommonTestDataDirectory, "ReferenceProj"), tempFolder);
+
+ this.AddProjectReference(Path.Combine(tempFolder, "ReferenceProj.sqlproj"));
+
+ int exitCode = this.RunDotnetCommandOnProject("publish", out _, out string stdError);
+
+ Assert.AreEqual(0, exitCode, "Publish failed with error " + stdError);
+ Assert.AreEqual(string.Empty, stdError);
+ this.VerifyDacPackage();
+ this.VerifyPublishFolder("ReferenceProj.dacpac");
+ }
+
+ [Test]
+ public void VerifyPublishWithPackageReference()
+ {
+ // Add a package reference to master.dacpac, which should be copied to the publish directory
+ this.AddPackageReference(packageName: "Microsoft.SqlServer.Dacpacs.Azure.Master", version: "160.*");
+
+ int exitCode = this.RunDotnetCommandOnProject("publish", out _, out string stdError);
+
+ Assert.AreEqual(0, exitCode, "Publish failed with error " + stdError);
+ Assert.AreEqual(string.Empty, stdError);
+ this.VerifyDacPackage();
+ this.VerifyPublishFolder("master.dacpac");
+ }
+
+ ///
+ /// Verify dacpac is in the publish directory, along with any additional expected files.
+ ///
+ private void VerifyPublishFolder(params string[] additionalFiles)
+ {
+ string publishFolder = Path.Combine(this.GetOutputDirectory(), "publish");
+ FileAssert.Exists(Path.Combine(publishFolder, $"{DatabaseProjectName}.dacpac"));
+ foreach (string file in additionalFiles) {
+ FileAssert.Exists(Path.Combine(publishFolder, file));
+ }
+ }
+ }
+}
\ No newline at end of file