From 8f7703936ff8109b7312f06024eb6022b718e709 Mon Sep 17 00:00:00 2001 From: Yuliia Kovalova Date: Mon, 27 Apr 2026 10:08:10 +0200 Subject: [PATCH] Remove net472 containers Remove the net472 target from the Containers SDK (Microsoft.NET.Build.Containers), keeping only the .NET Core (SdkTargetFramework) target. The net472 build existed to support Visual Studio's Full-Framework MSBuild (MSBuildRuntimeType == Full). Now that VS uses .NET Runtime with HostObject support for container operations, the net472 target and all related infrastructure is no longer needed. Changes: - Remove net472 TFM from Microsoft.NET.Build.Containers.csproj - Delete CreateNewImageToolTask (ToolTask-based implementation) - Delete netframeworkDefinitions.cs (net472-only polyfills) - Remove ToolTask-related properties from targets/props - Remove net472 PublicAPI files - Delete FullFramework test suite (CreateNewImageToolTaskTests) - Exclude Containers from crossgenning in Crossgen.targets - Fix package.csproj: mark as non-shipping, update output paths Fixes: https://github.com/dotnet/msbuild/issues/11333 --- .../AuthHandshakeMessageHandler.cs | 2 +- .../ContainerHelpers.cs | 6 - .../ImageConfig.cs | 2 +- .../Microsoft.NET.Build.Containers.csproj | 42 +- .../PublicAPI/net10.0/PublicAPI.Unshipped.txt | 6 - .../PublicAPI/net472/PublicAPI.Shipped.txt | 1 - .../PublicAPI/net472/PublicAPI.Unshipped.txt | 148 ----- .../Tasks/ComputeDotnetBaseImageAndTag.cs | 3 - .../Tasks/CreateNewImage.Interface.cs | 11 - .../Tasks/CreateNewImage.cs | 12 +- .../Tasks/CreateNewImageToolTask.cs | 247 ------- .../netframeworkDefinitions.cs | 26 - .../containerize/ContainerizeCommand.cs | 4 +- .../Microsoft.NET.Build.Containers.props | 13 +- .../Microsoft.NET.Build.Containers.targets | 11 +- src/Containers/packaging/package.csproj | 31 +- src/Layout/redist/targets/Crossgen.targets | 2 +- .../redist/targets/GenerateLayout.targets | 5 - .../CreateNewImageToolTaskTests.cs | 601 ------------------ ...T.Build.Containers.IntegrationTests.csproj | 18 +- .../PackageTests.cs | 8 - .../RegistryTests.cs | 3 +- test/UnitTests.proj | 1 - 23 files changed, 25 insertions(+), 1178 deletions(-) delete mode 100644 src/Containers/Microsoft.NET.Build.Containers/PublicAPI/net472/PublicAPI.Shipped.txt delete mode 100644 src/Containers/Microsoft.NET.Build.Containers/PublicAPI/net472/PublicAPI.Unshipped.txt delete mode 100644 src/Containers/Microsoft.NET.Build.Containers/Tasks/CreateNewImageToolTask.cs delete mode 100644 src/Containers/Microsoft.NET.Build.Containers/netframeworkDefinitions.cs delete mode 100644 test/Microsoft.NET.Build.Containers.IntegrationTests/FullFramework/CreateNewImageToolTaskTests.cs diff --git a/src/Containers/Microsoft.NET.Build.Containers/AuthHandshakeMessageHandler.cs b/src/Containers/Microsoft.NET.Build.Containers/AuthHandshakeMessageHandler.cs index 46761e94df7c..20f3c20cb464 100644 --- a/src/Containers/Microsoft.NET.Build.Containers/AuthHandshakeMessageHandler.cs +++ b/src/Containers/Microsoft.NET.Build.Containers/AuthHandshakeMessageHandler.cs @@ -403,7 +403,7 @@ protected override async Task SendAsync(HttpRequestMessage // Ideally we'd call LoadIntoBufferAsync, but it has no overload that accepts a CancellationToken so we call ReadAsByteArrayAsync instead. _ = await response.Content.ReadAsByteArrayAsync(cancellationToken).ConfigureAwait(false); - if (await GetAuthenticationAsync(_registryName, scheme, authInfo, cancellationToken).ConfigureAwait(false) is (AuthenticationHeaderValue authHeader, DateTimeOffset expirationTime)) + if (await GetAuthenticationAsync(_registryName, scheme!, authInfo, cancellationToken).ConfigureAwait(false) is (AuthenticationHeaderValue authHeader, DateTimeOffset expirationTime)) { _authenticationHeaders[_registryName] = authHeader; request.Headers.Authorization = authHeader; diff --git a/src/Containers/Microsoft.NET.Build.Containers/ContainerHelpers.cs b/src/Containers/Microsoft.NET.Build.Containers/ContainerHelpers.cs index 7f114caaba21..3ba21da1d98a 100644 --- a/src/Containers/Microsoft.NET.Build.Containers/ContainerHelpers.cs +++ b/src/Containers/Microsoft.NET.Build.Containers/ContainerHelpers.cs @@ -1,13 +1,7 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -#if NETFRAMEWORK -using System; -using System.Linq; -#endif -#if NET using System.Diagnostics.CodeAnalysis; -#endif using System.Text; using System.Text.Json.Nodes; using System.Text.RegularExpressions; diff --git a/src/Containers/Microsoft.NET.Build.Containers/ImageConfig.cs b/src/Containers/Microsoft.NET.Build.Containers/ImageConfig.cs index d16563c052db..e028cee7b45c 100644 --- a/src/Containers/Microsoft.NET.Build.Containers/ImageConfig.cs +++ b/src/Containers/Microsoft.NET.Build.Containers/ImageConfig.cs @@ -240,7 +240,7 @@ private HashSet GetExposedPorts() && property.Value is JsonObject propertyValue && ContainerHelpers.TryParsePort(propertyName, out Port? parsedPort, out ContainerHelpers.ParsePortError? _)) { - ports.Add(parsedPort.Value); + ports.Add(parsedPort!.Value); } } } diff --git a/src/Containers/Microsoft.NET.Build.Containers/Microsoft.NET.Build.Containers.csproj b/src/Containers/Microsoft.NET.Build.Containers/Microsoft.NET.Build.Containers.csproj index 3c4c3d932e9b..95161d783724 100644 --- a/src/Containers/Microsoft.NET.Build.Containers/Microsoft.NET.Build.Containers.csproj +++ b/src/Containers/Microsoft.NET.Build.Containers/Microsoft.NET.Build.Containers.csproj @@ -1,15 +1,15 @@ - $(SdkTargetFramework);net472 - enable + $(SdkTargetFramework) + enable $(TargetsForTfmSpecificBuildOutput);CopyProjectReferencesToPackage - true + true . @@ -26,14 +26,13 @@ build false - + @@ -44,12 +43,7 @@ - runtime - - - - $(SystemTextJsonToolsetPackageVersion) + runtime @@ -57,7 +51,7 @@ - + @@ -65,30 +59,6 @@ - - - - - - - - - - - - - - - - - - - - - - - - True diff --git a/src/Containers/Microsoft.NET.Build.Containers/PublicAPI/net10.0/PublicAPI.Unshipped.txt b/src/Containers/Microsoft.NET.Build.Containers/PublicAPI/net10.0/PublicAPI.Unshipped.txt index 4d92cb103d8d..b2831b2201fe 100644 --- a/src/Containers/Microsoft.NET.Build.Containers/PublicAPI/net10.0/PublicAPI.Unshipped.txt +++ b/src/Containers/Microsoft.NET.Build.Containers/PublicAPI/net10.0/PublicAPI.Unshipped.txt @@ -197,8 +197,6 @@ Microsoft.NET.Build.Containers.Tasks.CreateNewImage.BaseRegistry.set -> void Microsoft.NET.Build.Containers.Tasks.CreateNewImage.Cancel() -> void Microsoft.NET.Build.Containers.Tasks.CreateNewImage.ContainerEnvironmentVariables.get -> Microsoft.Build.Framework.ITaskItem![]! Microsoft.NET.Build.Containers.Tasks.CreateNewImage.ContainerEnvironmentVariables.set -> void -Microsoft.NET.Build.Containers.Tasks.CreateNewImage.ContainerizeDirectory.get -> string! -Microsoft.NET.Build.Containers.Tasks.CreateNewImage.ContainerizeDirectory.set -> void Microsoft.NET.Build.Containers.Tasks.CreateNewImage.ContainerRuntimeIdentifier.get -> string! Microsoft.NET.Build.Containers.Tasks.CreateNewImage.ContainerRuntimeIdentifier.set -> void Microsoft.NET.Build.Containers.Tasks.CreateNewImage.ContainerUser.get -> string! @@ -245,10 +243,6 @@ Microsoft.NET.Build.Containers.Tasks.CreateNewImage.PublishDirectory.get -> stri Microsoft.NET.Build.Containers.Tasks.CreateNewImage.PublishDirectory.set -> void Microsoft.NET.Build.Containers.Tasks.CreateNewImage.RuntimeIdentifierGraphPath.get -> string! Microsoft.NET.Build.Containers.Tasks.CreateNewImage.RuntimeIdentifierGraphPath.set -> void -Microsoft.NET.Build.Containers.Tasks.CreateNewImage.ToolExe.get -> string! -Microsoft.NET.Build.Containers.Tasks.CreateNewImage.ToolExe.set -> void -Microsoft.NET.Build.Containers.Tasks.CreateNewImage.ToolPath.get -> string! -Microsoft.NET.Build.Containers.Tasks.CreateNewImage.ToolPath.set -> void Microsoft.NET.Build.Containers.Tasks.CreateNewImage.WorkingDirectory.get -> string! Microsoft.NET.Build.Containers.Tasks.CreateNewImage.WorkingDirectory.set -> void Microsoft.NET.Build.Containers.Tasks.CreateNewImage.GenerateLabels.get -> bool diff --git a/src/Containers/Microsoft.NET.Build.Containers/PublicAPI/net472/PublicAPI.Shipped.txt b/src/Containers/Microsoft.NET.Build.Containers/PublicAPI/net472/PublicAPI.Shipped.txt deleted file mode 100644 index ab058de62d44..000000000000 --- a/src/Containers/Microsoft.NET.Build.Containers/PublicAPI/net472/PublicAPI.Shipped.txt +++ /dev/null @@ -1 +0,0 @@ -#nullable enable diff --git a/src/Containers/Microsoft.NET.Build.Containers/PublicAPI/net472/PublicAPI.Unshipped.txt b/src/Containers/Microsoft.NET.Build.Containers/PublicAPI/net472/PublicAPI.Unshipped.txt deleted file mode 100644 index 607f906e2676..000000000000 --- a/src/Containers/Microsoft.NET.Build.Containers/PublicAPI/net472/PublicAPI.Unshipped.txt +++ /dev/null @@ -1,148 +0,0 @@ -Microsoft.NET.Build.Containers.ContainerHelpers -Microsoft.NET.Build.Containers.ContainerHelpers.ParsePortError -Microsoft.NET.Build.Containers.ContainerHelpers.ParsePortError.InvalidPortNumber = 2 -> Microsoft.NET.Build.Containers.ContainerHelpers.ParsePortError -Microsoft.NET.Build.Containers.ContainerHelpers.ParsePortError.InvalidPortType = 4 -> Microsoft.NET.Build.Containers.ContainerHelpers.ParsePortError -Microsoft.NET.Build.Containers.ContainerHelpers.ParsePortError.MissingPortNumber = 1 -> Microsoft.NET.Build.Containers.ContainerHelpers.ParsePortError -Microsoft.NET.Build.Containers.ContainerHelpers.ParsePortError.UnknownPortFormat = 8 -> Microsoft.NET.Build.Containers.ContainerHelpers.ParsePortError -Microsoft.NET.Build.Containers.Port -Microsoft.NET.Build.Containers.Port.Deconstruct(out int Number, out Microsoft.NET.Build.Containers.PortType Type) -> void -Microsoft.NET.Build.Containers.Port.Equals(Microsoft.NET.Build.Containers.Port other) -> bool -Microsoft.NET.Build.Containers.Port.Number.get -> int -Microsoft.NET.Build.Containers.Port.Number.set -> void -Microsoft.NET.Build.Containers.Port.Port() -> void -Microsoft.NET.Build.Containers.Port.Port(int Number, Microsoft.NET.Build.Containers.PortType Type) -> void -Microsoft.NET.Build.Containers.Port.Type.get -> Microsoft.NET.Build.Containers.PortType -Microsoft.NET.Build.Containers.Port.Type.set -> void -Microsoft.NET.Build.Containers.Tasks.ComputeDotnetBaseImageAndTag.ContainerFamily.get -> string? -Microsoft.NET.Build.Containers.Tasks.ComputeDotnetBaseImageAndTag.UserBaseImage.get -> string? -Microsoft.NET.Build.Containers.Tasks.ComputeDotnetBaseImageAndTag.UserBaseImage.set -> void -~override Microsoft.NET.Build.Containers.Port.ToString() -> string -static Microsoft.NET.Build.Containers.Port.operator !=(Microsoft.NET.Build.Containers.Port left, Microsoft.NET.Build.Containers.Port right) -> bool -static Microsoft.NET.Build.Containers.Port.operator ==(Microsoft.NET.Build.Containers.Port left, Microsoft.NET.Build.Containers.Port right) -> bool -override Microsoft.NET.Build.Containers.Port.GetHashCode() -> int -~override Microsoft.NET.Build.Containers.Port.Equals(object obj) -> bool -Microsoft.NET.Build.Containers.PortType -Microsoft.NET.Build.Containers.PortType.tcp = 0 -> Microsoft.NET.Build.Containers.PortType -Microsoft.NET.Build.Containers.PortType.udp = 1 -> Microsoft.NET.Build.Containers.PortType -Microsoft.NET.Build.Containers.Tasks.CreateNewImage -Microsoft.NET.Build.Containers.Tasks.CreateNewImage.BaseImageName.get -> string! -Microsoft.NET.Build.Containers.Tasks.CreateNewImage.BaseImageName.set -> void -Microsoft.NET.Build.Containers.Tasks.CreateNewImage.BaseImageTag.get -> string! -Microsoft.NET.Build.Containers.Tasks.CreateNewImage.BaseImageTag.set -> void -Microsoft.NET.Build.Containers.Tasks.CreateNewImage.BaseImageDigest.get -> string! -Microsoft.NET.Build.Containers.Tasks.CreateNewImage.BaseImageDigest.set -> void -Microsoft.NET.Build.Containers.Tasks.CreateNewImage.BaseRegistry.get -> string! -Microsoft.NET.Build.Containers.Tasks.CreateNewImage.BaseRegistry.set -> void -Microsoft.NET.Build.Containers.Tasks.CreateNewImage.ContainerEnvironmentVariables.get -> Microsoft.Build.Framework.ITaskItem![]! -Microsoft.NET.Build.Containers.Tasks.CreateNewImage.ContainerEnvironmentVariables.set -> void -Microsoft.NET.Build.Containers.Tasks.CreateNewImage.ContainerizeDirectory.get -> string! -Microsoft.NET.Build.Containers.Tasks.CreateNewImage.ContainerizeDirectory.set -> void -Microsoft.NET.Build.Containers.Tasks.CreateNewImage.ContainerRuntimeIdentifier.get -> string! -Microsoft.NET.Build.Containers.Tasks.CreateNewImage.ContainerRuntimeIdentifier.set -> void -Microsoft.NET.Build.Containers.Tasks.CreateNewImage.ContainerUser.get -> string! -Microsoft.NET.Build.Containers.Tasks.CreateNewImage.ContainerUser.set -> void -Microsoft.NET.Build.Containers.Tasks.CreateNewImage.CreateNewImage() -> void -Microsoft.NET.Build.Containers.Tasks.CreateNewImage.Entrypoint.get -> Microsoft.Build.Framework.ITaskItem![]! -Microsoft.NET.Build.Containers.Tasks.CreateNewImage.Entrypoint.set -> void -Microsoft.NET.Build.Containers.Tasks.CreateNewImage.EntrypointArgs.get -> Microsoft.Build.Framework.ITaskItem![]! -Microsoft.NET.Build.Containers.Tasks.CreateNewImage.EntrypointArgs.set -> void -Microsoft.NET.Build.Containers.Tasks.CreateNewImage.DefaultArgs.get -> Microsoft.Build.Framework.ITaskItem![]! -Microsoft.NET.Build.Containers.Tasks.CreateNewImage.DefaultArgs.set -> void -Microsoft.NET.Build.Containers.Tasks.CreateNewImage.AppCommand.get -> Microsoft.Build.Framework.ITaskItem![]! -Microsoft.NET.Build.Containers.Tasks.CreateNewImage.AppCommand.set -> void -Microsoft.NET.Build.Containers.Tasks.CreateNewImage.AppCommandArgs.get -> Microsoft.Build.Framework.ITaskItem![]! -Microsoft.NET.Build.Containers.Tasks.CreateNewImage.AppCommandArgs.set -> void -Microsoft.NET.Build.Containers.Tasks.CreateNewImage.AppCommandInstruction.get -> string! -Microsoft.NET.Build.Containers.Tasks.CreateNewImage.AppCommandInstruction.set -> void -Microsoft.NET.Build.Containers.Tasks.CreateNewImage.ExposedPorts.get -> Microsoft.Build.Framework.ITaskItem![]! -Microsoft.NET.Build.Containers.Tasks.CreateNewImage.ExposedPorts.set -> void -Microsoft.NET.Build.Containers.Tasks.CreateNewImage.GeneratedContainerConfiguration.get -> string! -Microsoft.NET.Build.Containers.Tasks.CreateNewImage.GeneratedContainerConfiguration.set -> void -Microsoft.NET.Build.Containers.Tasks.CreateNewImage.GeneratedContainerManifest.get -> string! -Microsoft.NET.Build.Containers.Tasks.CreateNewImage.GeneratedContainerManifest.set -> void -Microsoft.NET.Build.Containers.Tasks.CreateNewImage.GeneratedContainerDigest.get -> string! -Microsoft.NET.Build.Containers.Tasks.CreateNewImage.GeneratedContainerDigest.set -> void -Microsoft.NET.Build.Containers.Tasks.CreateNewImage.GeneratedArchiveOutputPath.get -> string! -Microsoft.NET.Build.Containers.Tasks.CreateNewImage.GeneratedArchiveOutputPath.set -> void -Microsoft.NET.Build.Containers.Tasks.CreateNewImage.GeneratedContainerMediaType.get -> string! -Microsoft.NET.Build.Containers.Tasks.CreateNewImage.GeneratedContainerMediaType.set -> void -Microsoft.NET.Build.Containers.Tasks.CreateNewImage.Repository.get -> string! -Microsoft.NET.Build.Containers.Tasks.CreateNewImage.Repository.set -> void -Microsoft.NET.Build.Containers.Tasks.CreateNewImage.ImageTags.get -> string![]! -Microsoft.NET.Build.Containers.Tasks.CreateNewImage.ImageTags.set -> void -Microsoft.NET.Build.Containers.Tasks.CreateNewImage.Labels.get -> Microsoft.Build.Framework.ITaskItem![]! -Microsoft.NET.Build.Containers.Tasks.CreateNewImage.Labels.set -> void -Microsoft.NET.Build.Containers.Tasks.CreateNewImage.LocalRegistry.get -> string! -Microsoft.NET.Build.Containers.Tasks.CreateNewImage.LocalRegistry.set -> void -Microsoft.NET.Build.Containers.Tasks.CreateNewImage.OutputRegistry.get -> string! -Microsoft.NET.Build.Containers.Tasks.CreateNewImage.OutputRegistry.set -> void -Microsoft.NET.Build.Containers.Tasks.CreateNewImage.ArchiveOutputPath.get -> string! -Microsoft.NET.Build.Containers.Tasks.CreateNewImage.ArchiveOutputPath.set -> void -Microsoft.NET.Build.Containers.Tasks.CreateNewImage.PublishDirectory.get -> string! -Microsoft.NET.Build.Containers.Tasks.CreateNewImage.PublishDirectory.set -> void -Microsoft.NET.Build.Containers.Tasks.CreateNewImage.RuntimeIdentifierGraphPath.get -> string! -Microsoft.NET.Build.Containers.Tasks.CreateNewImage.RuntimeIdentifierGraphPath.set -> void -Microsoft.NET.Build.Containers.Tasks.CreateNewImage.WorkingDirectory.get -> string! -Microsoft.NET.Build.Containers.Tasks.CreateNewImage.WorkingDirectory.set -> void -Microsoft.NET.Build.Containers.Tasks.CreateNewImage.GenerateLabels.get -> bool -Microsoft.NET.Build.Containers.Tasks.CreateNewImage.GenerateLabels.set -> void -Microsoft.NET.Build.Containers.Tasks.CreateNewImage.GenerateDigestLabel.get -> bool -Microsoft.NET.Build.Containers.Tasks.CreateNewImage.GenerateDigestLabel.set -> void -Microsoft.NET.Build.Containers.Tasks.CreateNewImage.SkipPublishing.get -> bool -Microsoft.NET.Build.Containers.Tasks.CreateNewImage.SkipPublishing.set -> void -Microsoft.NET.Build.Containers.Tasks.CreateNewImage.GeneratedContainerNames.get -> Microsoft.Build.Framework.ITaskItem![]! -Microsoft.NET.Build.Containers.Tasks.CreateNewImage.GeneratedContainerNames.set -> void -Microsoft.NET.Build.Containers.Tasks.CreateNewImage.ImageFormat.get -> string? -Microsoft.NET.Build.Containers.Tasks.CreateNewImage.ImageFormat.set -> void -Microsoft.NET.Build.Containers.Tasks.CreateNewImage.GeneratedDigestLabel.get -> Microsoft.Build.Framework.ITaskItem? -Microsoft.NET.Build.Containers.Tasks.CreateNewImage.GeneratedDigestLabel.set -> void -override Microsoft.NET.Build.Containers.Tasks.CreateNewImage.ToolName.get -> string! -override Microsoft.NET.Build.Containers.Tasks.CreateNewImage.GenerateCommandLineCommands() -> string! -override Microsoft.NET.Build.Containers.Tasks.CreateNewImage.GenerateFullPathToTool() -> string! -override Microsoft.NET.Build.Containers.Tasks.CreateNewImage.GetProcessStartInfo(string! pathToTool, string! commandLineCommands, string! responseFileSwitch) -> System.Diagnostics.ProcessStartInfo! -Microsoft.NET.Build.Containers.Tasks.ParseContainerProperties -Microsoft.NET.Build.Containers.Tasks.ParseContainerProperties.ContainerEnvironmentVariables.get -> Microsoft.Build.Framework.ITaskItem![]! -Microsoft.NET.Build.Containers.Tasks.ParseContainerProperties.ContainerEnvironmentVariables.set -> void -Microsoft.NET.Build.Containers.Tasks.ParseContainerProperties.ContainerRepository.get -> string! -Microsoft.NET.Build.Containers.Tasks.ParseContainerProperties.ContainerRepository.set -> void -Microsoft.NET.Build.Containers.Tasks.ParseContainerProperties.ContainerImageTag.get -> string! -Microsoft.NET.Build.Containers.Tasks.ParseContainerProperties.ContainerImageTag.set -> void -Microsoft.NET.Build.Containers.Tasks.ParseContainerProperties.ContainerImageTags.get -> string![]! -Microsoft.NET.Build.Containers.Tasks.ParseContainerProperties.ContainerImageTags.set -> void -Microsoft.NET.Build.Containers.Tasks.ParseContainerProperties.ContainerRegistry.get -> string! -Microsoft.NET.Build.Containers.Tasks.ParseContainerProperties.ContainerRegistry.set -> void -Microsoft.NET.Build.Containers.Tasks.ParseContainerProperties.FullyQualifiedBaseImageName.get -> string! -Microsoft.NET.Build.Containers.Tasks.ParseContainerProperties.FullyQualifiedBaseImageName.set -> void -Microsoft.NET.Build.Containers.Tasks.ParseContainerProperties.NewContainerEnvironmentVariables.get -> Microsoft.Build.Framework.ITaskItem![]! -Microsoft.NET.Build.Containers.Tasks.ParseContainerProperties.NewContainerRepository.get -> string! -Microsoft.NET.Build.Containers.Tasks.ParseContainerProperties.NewContainerRegistry.get -> string! -Microsoft.NET.Build.Containers.Tasks.ParseContainerProperties.NewContainerTags.get -> string![]! -Microsoft.NET.Build.Containers.Tasks.ParseContainerProperties.ParseContainerProperties() -> void -Microsoft.NET.Build.Containers.Tasks.ParseContainerProperties.ParsedContainerImage.get -> string! -Microsoft.NET.Build.Containers.Tasks.ParseContainerProperties.ParsedContainerRegistry.get -> string! -Microsoft.NET.Build.Containers.Tasks.ParseContainerProperties.ParsedContainerTag.get -> string! -Microsoft.NET.Build.Containers.Tasks.ParseContainerProperties.ParsedContainerDigest.get -> string! -override Microsoft.NET.Build.Containers.Tasks.ParseContainerProperties.Execute() -> bool -static Microsoft.NET.Build.Containers.ContainerHelpers.TryParsePort(string! input, out Microsoft.NET.Build.Containers.Port? port, out Microsoft.NET.Build.Containers.ContainerHelpers.ParsePortError? error) -> bool -static Microsoft.NET.Build.Containers.ContainerHelpers.TryParsePort(string? portNumber, string? portType, out Microsoft.NET.Build.Containers.Port? port, out Microsoft.NET.Build.Containers.ContainerHelpers.ParsePortError? error) -> bool -Microsoft.NET.Build.Containers.Tasks.ComputeDotnetBaseImageAndTag.ComputedContainerBaseImage.get -> string? -Microsoft.NET.Build.Containers.Tasks.ComputeDotnetBaseImageAndTag.FrameworkReferences.get -> Microsoft.Build.Framework.ITaskItem![]! -Microsoft.NET.Build.Containers.Tasks.ComputeDotnetBaseImageAndTag.FrameworkReferences.set -> void -Microsoft.NET.Build.Containers.Tasks.ComputeDotnetBaseImageAndTag.IsAotPublished.get -> bool -Microsoft.NET.Build.Containers.Tasks.ComputeDotnetBaseImageAndTag.IsAotPublished.set -> void -Microsoft.NET.Build.Containers.Tasks.ComputeDotnetBaseImageAndTag.IsTrimmed.get -> bool -Microsoft.NET.Build.Containers.Tasks.ComputeDotnetBaseImageAndTag.IsTrimmed.set -> void -Microsoft.NET.Build.Containers.Tasks.ComputeDotnetBaseImageAndTag.IsSelfContained.get -> bool -Microsoft.NET.Build.Containers.Tasks.ComputeDotnetBaseImageAndTag.IsSelfContained.set -> void -Microsoft.NET.Build.Containers.Tasks.ComputeDotnetBaseImageAndTag.TargetRuntimeIdentifiers.get -> string![]! -Microsoft.NET.Build.Containers.Tasks.ComputeDotnetBaseImageAndTag.TargetRuntimeIdentifiers.set -> void -Microsoft.NET.Build.Containers.Tasks.ComputeDotnetBaseImageAndTag.UsesInvariantGlobalization.get -> bool -Microsoft.NET.Build.Containers.Tasks.ComputeDotnetBaseImageAndTag.UsesInvariantGlobalization.set -> void -Microsoft.NET.Build.Containers.Tasks.ComputeDotnetBaseImageAndTag -Microsoft.NET.Build.Containers.Tasks.ComputeDotnetBaseImageAndTag.ComputeDotnetBaseImageAndTag() -> void -Microsoft.NET.Build.Containers.Tasks.ComputeDotnetBaseImageAndTag.ContainerFamily.set -> void -Microsoft.NET.Build.Containers.Tasks.ComputeDotnetBaseImageAndTag.SdkVersion.get -> string! -Microsoft.NET.Build.Containers.Tasks.ComputeDotnetBaseImageAndTag.SdkVersion.set -> void -Microsoft.NET.Build.Containers.Tasks.ComputeDotnetBaseImageAndTag.TargetFrameworkVersion.get -> string! -Microsoft.NET.Build.Containers.Tasks.ComputeDotnetBaseImageAndTag.TargetFrameworkVersion.set -> void -override Microsoft.NET.Build.Containers.Tasks.ComputeDotnetBaseImageAndTag.Execute() -> bool diff --git a/src/Containers/Microsoft.NET.Build.Containers/Tasks/ComputeDotnetBaseImageAndTag.cs b/src/Containers/Microsoft.NET.Build.Containers/Tasks/ComputeDotnetBaseImageAndTag.cs index 69ced08eae1e..5059754aac18 100644 --- a/src/Containers/Microsoft.NET.Build.Containers/Tasks/ComputeDotnetBaseImageAndTag.cs +++ b/src/Containers/Microsoft.NET.Build.Containers/Tasks/ComputeDotnetBaseImageAndTag.cs @@ -4,9 +4,6 @@ using System.Diagnostics.CodeAnalysis; using Microsoft.Build.Framework; using NuGet.Versioning; -#if NETFRAMEWORK -using System.Linq; -#endif namespace Microsoft.NET.Build.Containers.Tasks; diff --git a/src/Containers/Microsoft.NET.Build.Containers/Tasks/CreateNewImage.Interface.cs b/src/Containers/Microsoft.NET.Build.Containers/Tasks/CreateNewImage.Interface.cs index ebbd1de29901..d33273ee309f 100644 --- a/src/Containers/Microsoft.NET.Build.Containers/Tasks/CreateNewImage.Interface.cs +++ b/src/Containers/Microsoft.NET.Build.Containers/Tasks/CreateNewImage.Interface.cs @@ -8,14 +8,6 @@ namespace Microsoft.NET.Build.Containers.Tasks; partial class CreateNewImage { - /// - /// The path to the folder containing `containerize.dll`. - /// - /// - /// Used only for the ToolTask implementation of this task. - /// - public string ContainerizeDirectory { get; set; } - /// /// The base registry to pull from. /// Ex: mcr.microsoft.com @@ -197,9 +189,6 @@ partial class CreateNewImage public CreateNewImage() { - ContainerizeDirectory = ""; - ToolExe = ""; - ToolPath = ""; BaseRegistry = ""; BaseImageName = ""; BaseImageTag = ""; diff --git a/src/Containers/Microsoft.NET.Build.Containers/Tasks/CreateNewImage.cs b/src/Containers/Microsoft.NET.Build.Containers/Tasks/CreateNewImage.cs index 8dc590094f58..613b1c2319bb 100644 --- a/src/Containers/Microsoft.NET.Build.Containers/Tasks/CreateNewImage.cs +++ b/src/Containers/Microsoft.NET.Build.Containers/Tasks/CreateNewImage.cs @@ -14,16 +14,6 @@ public sealed partial class CreateNewImage : Microsoft.Build.Utilities.Task, ICa { private readonly CancellationTokenSource _cancellationTokenSource = new(); - /// - /// Unused. For interface parity with the ToolTask implementation of the task. - /// - public string ToolExe { get; set; } - - /// - /// Unused. For interface parity with the ToolTask implementation of the task. - /// - public string ToolPath { get; set; } - private bool IsLocalPull => string.IsNullOrWhiteSpace(BaseRegistry); public void Cancel() => _cancellationTokenSource.Cancel(); @@ -272,7 +262,7 @@ private void SetPorts(ImageBuilder image, ITaskItem[] exposedPorts) var portType = port.GetMetadata("Type"); if (ContainerHelpers.TryParsePort(portNo, portType, out Port? parsedPort, out ContainerHelpers.ParsePortError? errors)) { - image.ExposePort(parsedPort.Value.Number, parsedPort.Value.Type); + image.ExposePort(parsedPort!.Value.Number, parsedPort.Value.Type); } else { diff --git a/src/Containers/Microsoft.NET.Build.Containers/Tasks/CreateNewImageToolTask.cs b/src/Containers/Microsoft.NET.Build.Containers/Tasks/CreateNewImageToolTask.cs deleted file mode 100644 index 49477208b5c8..000000000000 --- a/src/Containers/Microsoft.NET.Build.Containers/Tasks/CreateNewImageToolTask.cs +++ /dev/null @@ -1,247 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System.Diagnostics; -using Microsoft.Build.Framework; -using Microsoft.Build.Utilities; -using Microsoft.NET.Build.Containers.Resources; -using Microsoft.NET.Sdk.Common; - -namespace Microsoft.NET.Build.Containers.Tasks; - -/// -/// This task will shell out to the net7.0-targeted application for VS scenarios. -/// -public partial class CreateNewImage : ToolTask, ICancelableTask -{ - // Unused, ToolExe is set via targets and overrides this. - protected override string ToolName => "dotnet"; - - private (bool success, string user, string pass) extractionInfo; - - private string DotNetPath - { - get - { - // DOTNET_HOST_PATH, if set, is the full path to the dotnet host executable. - // However, not all environments/scenarios set it correctly - some set it to just the directory. - - // this is the expected correct case - DOTNET_HOST_PATH is set to the full path of the dotnet host executable - string path = Environment.GetEnvironmentVariable("DOTNET_HOST_PATH") ?? ""; - if (Path.IsPathRooted(path) && File.Exists(path)) - { - return path; - } - // some environments set it to just the directory, so we need to check that too - if (Path.IsPathRooted(path) && Directory.Exists(path)) - { - path = Path.Combine(path, ToolExe); - if (File.Exists(path)) - { - return path; - } - } - // last-chance fallback - use the ToolPath and ToolExe properties to try to synthesize the path - if (string.IsNullOrEmpty(path)) - { - // no - path = string.IsNullOrEmpty(ToolPath) ? "" : ToolPath; - path = Path.Combine(path, ToolExe); - } - - return path; - } - } - - protected override string GenerateFullPathToTool() => DotNetPath; - - /// - /// Workaround to avoid storing user/pass into the EnvironmentVariables property, which gets logged by the task. - /// - /// - /// - /// - /// - protected override ProcessStartInfo GetProcessStartInfo(string pathToTool, string commandLineCommands, string responseFileSwitch) - { - VSHostObject hostObj = new(HostObject, Log); - if (hostObj.TryGetCredentials() is (string user, string pass)) - { - extractionInfo = (true, user, pass); - } - else - { - Log.LogMessage(MessageImportance.Low, Resource.GetString(nameof(Strings.HostObjectNotDetected))); - } - - ProcessStartInfo startInfo = base.GetProcessStartInfo(pathToTool, commandLineCommands, responseFileSwitch)!; - - if (extractionInfo.success) - { - startInfo.Environment[ContainerHelpers.HostObjectUser] = extractionInfo.user; - startInfo.Environment[ContainerHelpers.HostObjectPass] = extractionInfo.pass; - } - - return startInfo; - } - - protected override string GenerateCommandLineCommands() => GenerateCommandLineCommandsInt(); - - /// - /// For unit test purposes - /// - internal string GenerateCommandLineCommandsInt() - { - if (string.IsNullOrWhiteSpace(PublishDirectory)) - { - throw new InvalidOperationException(Resource.FormatString(nameof(Strings.RequiredPropertyNotSetOrEmpty), nameof(PublishDirectory))); - } - if (string.IsNullOrWhiteSpace(BaseRegistry)) - { - throw new InvalidOperationException(Resource.FormatString(nameof(Strings.RequiredPropertyNotSetOrEmpty), nameof(BaseRegistry))); - } - if (string.IsNullOrWhiteSpace(BaseImageName)) - { - throw new InvalidOperationException(Resource.FormatString(nameof(Strings.RequiredPropertyNotSetOrEmpty), nameof(BaseImageName))); - } - if (string.IsNullOrWhiteSpace(Repository)) - { - throw new InvalidOperationException(Resource.FormatString(nameof(Strings.RequiredPropertyNotSetOrEmpty), nameof(Repository))); - } - if (string.IsNullOrWhiteSpace(WorkingDirectory)) - { - throw new InvalidOperationException(Resource.FormatString(nameof(Strings.RequiredPropertyNotSetOrEmpty), nameof(WorkingDirectory))); - } - - CommandLineBuilder builder = new(); - - //mandatory options - builder.AppendFileNameIfNotNull(Path.Combine(ContainerizeDirectory, "containerize.dll")); - builder.AppendFileNameIfNotNull(PublishDirectory.TrimEnd(new char[] { Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar })); - builder.AppendSwitchIfNotNull("--baseregistry ", BaseRegistry); - builder.AppendSwitchIfNotNull("--baseimagename ", BaseImageName); - builder.AppendSwitchIfNotNull("--repository ", Repository); - builder.AppendSwitchIfNotNull("--workingdirectory ", WorkingDirectory); - - //optional options - if (!string.IsNullOrWhiteSpace(BaseImageTag)) - { - builder.AppendSwitchIfNotNull("--baseimagetag ", BaseImageTag); - } - if (!string.IsNullOrWhiteSpace(BaseImageDigest)) - { - builder.AppendSwitchIfNotNull("--baseimagedigest ", BaseImageDigest); - } - if (!string.IsNullOrWhiteSpace(OutputRegistry)) - { - builder.AppendSwitchIfNotNull("--outputregistry ", OutputRegistry); - } - if (!string.IsNullOrWhiteSpace(LocalRegistry)) - { - builder.AppendSwitchIfNotNull("--localregistry ", LocalRegistry); - } - if (!string.IsNullOrWhiteSpace(AppCommandInstruction)) - { - builder.AppendSwitchIfNotNull("--appcommandinstruction ", AppCommandInstruction); - } - if (!string.IsNullOrWhiteSpace(ImageFormat)) - { - builder.AppendSwitchIfNotNull("--image-format ", ImageFormat); - } - - AppendSwitchIfNotNullSanitized(builder, "--entrypoint ", nameof(Entrypoint), Entrypoint); - AppendSwitchIfNotNullSanitized(builder, "--entrypointargs ", nameof(EntrypointArgs), EntrypointArgs); - AppendSwitchIfNotNullSanitized(builder, "--defaultargs ", nameof(DefaultArgs), DefaultArgs); - AppendSwitchIfNotNullSanitized(builder, "--appcommand ", nameof(AppCommand), AppCommand); - AppendSwitchIfNotNullSanitized(builder, "--appcommandargs ", nameof(AppCommandArgs), AppCommandArgs); - - if (Labels.Any(e => string.IsNullOrWhiteSpace(e.ItemSpec))) - { - Log.LogWarningWithCodeFromResources(nameof(Strings.EmptyValuesIgnored), nameof(Labels)); - } - var sanitizedLabels = Labels.Where(e => !string.IsNullOrWhiteSpace(e.ItemSpec)); - if (sanitizedLabels.Any(i => i.GetMetadata("Value") is null)) - { - Log.LogWarningWithCodeFromResources(nameof(Strings.ItemsWithoutMetadata), nameof(Labels)); - sanitizedLabels = sanitizedLabels.Where(i => i.GetMetadata("Value") is not null); - } - - string[] readyLabels = sanitizedLabels.Select(i => i.ItemSpec + "=" + i.GetMetadata("Value")).ToArray(); - builder.AppendSwitchIfNotNull("--labels ", readyLabels, delimiter: " "); - - if (ImageTags.Any(string.IsNullOrWhiteSpace)) - { - Log.LogWarningWithCodeFromResources(nameof(Strings.EmptyOrWhitespacePropertyIgnored), nameof(ImageTags)); - } - string[] sanitizedImageTags = ImageTags.Where(i => !string.IsNullOrWhiteSpace(i)).ToArray(); - builder.AppendSwitchIfNotNull("--imagetags ", sanitizedImageTags, delimiter: " "); - - if (ExposedPorts.Any(e => string.IsNullOrWhiteSpace(e.ItemSpec))) - { - Log.LogWarningWithCodeFromResources(nameof(Strings.EmptyValuesIgnored), nameof(ExposedPorts)); - } - var sanitizedPorts = ExposedPorts.Where(e => !string.IsNullOrWhiteSpace(e.ItemSpec)); - string[] readyPorts = - sanitizedPorts - .Select(i => (i.ItemSpec, i.GetMetadata("Type"))) - .Select(pair => string.IsNullOrWhiteSpace(pair.Item2) ? pair.Item1 : (pair.Item1 + "/" + pair.Item2)) - .ToArray(); - builder.AppendSwitchIfNotNull("--ports ", readyPorts, delimiter: " "); - - if (ContainerEnvironmentVariables.Any(e => string.IsNullOrWhiteSpace(e.ItemSpec))) - { - Log.LogWarningWithCodeFromResources(nameof(Strings.EmptyValuesIgnored), nameof(ContainerEnvironmentVariables)); - } - var sanitizedEnvVariables = ContainerEnvironmentVariables.Where(e => !string.IsNullOrWhiteSpace(e.ItemSpec)); - if (sanitizedEnvVariables.Any(i => i.GetMetadata("Value") is null)) - { - Log.LogWarningWithCodeFromResources(nameof(Strings.ItemsWithoutMetadata), nameof(ContainerEnvironmentVariables)); - sanitizedEnvVariables = sanitizedEnvVariables.Where(i => i.GetMetadata("Value") is not null); - } - string[] readyEnvVariables = sanitizedEnvVariables.Select(i => i.ItemSpec + "=" + i.GetMetadata("Value")).ToArray(); - builder.AppendSwitchIfNotNull("--environmentvariables ", readyEnvVariables, delimiter: " "); - - if (!string.IsNullOrWhiteSpace(ContainerRuntimeIdentifier)) - { - builder.AppendSwitchIfNotNull("--rid ", ContainerRuntimeIdentifier); - } - - if (!string.IsNullOrWhiteSpace(RuntimeIdentifierGraphPath)) - { - builder.AppendSwitchIfNotNull("--ridgraphpath ", RuntimeIdentifierGraphPath); - } - - if (!string.IsNullOrWhiteSpace(ContainerUser)) - { - builder.AppendSwitchIfNotNull("--container-user ", ContainerUser); - } - - if (!string.IsNullOrWhiteSpace(ArchiveOutputPath)) - { - builder.AppendSwitchIfNotNull("--archiveoutputpath ", ArchiveOutputPath); - } - - if (GenerateLabels) - { - builder.AppendSwitch("--generate-labels"); - } - - if (GenerateDigestLabel) - { - builder.AppendSwitch("--generate-digest-label"); - } - - return builder.ToString(); - - void AppendSwitchIfNotNullSanitized(CommandLineBuilder builder, string commandArgName, string propertyName, ITaskItem[] value) - { - ITaskItem[] santized = value.Where(e => !string.IsNullOrWhiteSpace(e.ItemSpec)).ToArray(); - if (santized.Length != value.Length) - { - Log.LogWarningWithCodeFromResources(nameof(Strings.EmptyValuesIgnored), propertyName); - } - builder.AppendSwitchIfNotNull(commandArgName, santized, delimiter: " "); - } - } -} - diff --git a/src/Containers/Microsoft.NET.Build.Containers/netframeworkDefinitions.cs b/src/Containers/Microsoft.NET.Build.Containers/netframeworkDefinitions.cs deleted file mode 100644 index 80e475211498..000000000000 --- a/src/Containers/Microsoft.NET.Build.Containers/netframeworkDefinitions.cs +++ /dev/null @@ -1,26 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -namespace System.Runtime.CompilerServices -{ - internal static class IsExternalInit { } -} - -namespace Microsoft.NET.Build.Containers -{ - /// - /// Specifies that when a method returns , the parameter will not be null even if the corresponding type allows it. - /// - [AttributeUsage(AttributeTargets.Parameter, Inherited = false)] - sealed class NotNullWhenAttribute : Attribute - { - /// Initializes the attribute with the specified return value condition. - /// - /// The return value condition. If the method returns this value, the associated parameter will not be null. - /// - public NotNullWhenAttribute(bool returnValue) => ReturnValue = returnValue; - - /// Gets the return value condition. - public bool ReturnValue { get; } - } -} diff --git a/src/Containers/containerize/ContainerizeCommand.cs b/src/Containers/containerize/ContainerizeCommand.cs index 8da04309a921..5137f610670d 100644 --- a/src/Containers/containerize/ContainerizeCommand.cs +++ b/src/Containers/containerize/ContainerizeCommand.cs @@ -135,7 +135,7 @@ internal class ContainerizeCommand : RootCommand { if (ContainerHelpers.TryParsePort(split[0], split[1], out var portInfo, out var portError)) { - goodPorts.Add(portInfo.Value); + goodPorts.Add(portInfo!.Value); } else { @@ -147,7 +147,7 @@ internal class ContainerizeCommand : RootCommand { if (ContainerHelpers.TryParsePort(split[0], out var portInfo, out var portError)) { - goodPorts.Add(portInfo.Value); + goodPorts.Add(portInfo!.Value); } else { diff --git a/src/Containers/packaging/build/Microsoft.NET.Build.Containers.props b/src/Containers/packaging/build/Microsoft.NET.Build.Containers.props index a59da4835066..f01ca606f4e4 100644 --- a/src/Containers/packaging/build/Microsoft.NET.Build.Containers.props +++ b/src/Containers/packaging/build/Microsoft.NET.Build.Containers.props @@ -3,21 +3,18 @@ true tasks - net10.0 - net472 - containerize + net10.0 true $(MSBuildThisFileDirectory)..\$(ContainerTaskFolderName)\$(ContainerTaskFramework)\ - $(MSBuildThisFileDirectory)..\$(ContainerizeFolderName)\ $(ContainerCustomTasksFolder)$(MSBuildThisFileName).dll - - - - + + + + diff --git a/src/Containers/packaging/build/Microsoft.NET.Build.Containers.targets b/src/Containers/packaging/build/Microsoft.NET.Build.Containers.targets index ae67c5c24fce..05b11c18b12c 100644 --- a/src/Containers/packaging/build/Microsoft.NET.Build.Containers.targets +++ b/src/Containers/packaging/build/Microsoft.NET.Build.Containers.targets @@ -252,16 +252,7 @@ - - $(NetCoreRoot) - dotnet - dotnet.exe - - - $(SdkTargetFramework) true true - true - true - NU5100;NU5128 - net472 - + false NU5100;NU5128;NU1507 Microsoft @@ -29,12 +25,6 @@ OutputItemType="ContainerLibraryOutput" GlobalPropertiesToRemove="PublishDir"/> - - - - - - - @@ -72,12 +52,6 @@ - - - - - - @@ -95,7 +69,6 @@ - @@ -111,7 +84,7 @@ - diff --git a/src/Layout/redist/targets/Crossgen.targets b/src/Layout/redist/targets/Crossgen.targets index 0088ba4cd1de..7ab09646ed3c 100644 --- a/src/Layout/redist/targets/Crossgen.targets +++ b/src/Layout/redist/targets/Crossgen.targets @@ -66,7 +66,7 @@ - + diff --git a/src/Layout/redist/targets/GenerateLayout.targets b/src/Layout/redist/targets/GenerateLayout.targets index a5a63a1079b3..0087aee21817 100644 --- a/src/Layout/redist/targets/GenerateLayout.targets +++ b/src/Layout/redist/targets/GenerateLayout.targets @@ -281,11 +281,6 @@ - (() => task.GenerateCommandLineCommandsInt()); - Assert.Equal("CONTAINER4001: Required property 'PublishDirectory' was not set or empty.", e.Message); - - DirectoryInfo publishDir = Directory.CreateDirectory(Path.Combine(Path.GetTempPath(), DateTime.Now.ToString("yyyyMMddHHmmssfff"))); - - task.PublishDirectory = publishDir.FullName; - - e = Assert.Throws(() => task.GenerateCommandLineCommandsInt()); - Assert.Equal("CONTAINER4001: Required property 'BaseRegistry' was not set or empty.", e.Message); - - task.BaseRegistry = "MyBaseRegistry"; - - e = Assert.Throws(() => task.GenerateCommandLineCommandsInt()); - Assert.Equal("CONTAINER4001: Required property 'BaseImageName' was not set or empty.", e.Message); - - task.BaseImageName = "MyBaseImageName"; - - e = Assert.Throws(() => task.GenerateCommandLineCommandsInt()); - Assert.Equal("CONTAINER4001: Required property 'Repository' was not set or empty.", e.Message); - - task.Repository = "MyImageName"; - - e = Assert.Throws(() => task.GenerateCommandLineCommandsInt()); - Assert.Equal("CONTAINER4001: Required property 'WorkingDirectory' was not set or empty.", e.Message); - - task.WorkingDirectory = "MyWorkingDirectory"; - - string args = task.GenerateCommandLineCommandsInt(); - string workDir = GetPathToContainerize(); - - new DotnetCommand(_testOutput, args) - .WithRawArguments() - .WithWorkingDirectory(workDir) - .Execute().Should().Fail() - .And.NotHaveStdOutContaining("Description:"); //standard help output for parse error - - } - - [Theory] - [InlineData(null)] - [InlineData("")] - [InlineData(" ")] - [InlineData("ValidTag", true)] - public void GenerateCommandLineCommands_BaseImageTag(string? value, bool optionExpected = false) - { - CreateNewImage task = new(); - DirectoryInfo publishDir = Directory.CreateDirectory(Path.Combine(Path.GetTempPath(), DateTime.Now.ToString("yyyyMMddHHmmssfff"))); - task.PublishDirectory = publishDir.FullName; - task.BaseRegistry = "MyBaseRegistry"; - task.BaseImageName = "MyBaseImageName"; - task.Repository = "MyImageName"; - task.WorkingDirectory = "MyWorkingDirectory"; - task.Entrypoint = new[] { new TaskItem("MyEntryPoint") }; - - if (value != null) - { - task.BaseImageTag = value; - } - - string args = task.GenerateCommandLineCommandsInt(); - - if (optionExpected) - { - Assert.Contains($"--baseimagetag {value}", args); - } - else - { - Assert.DoesNotContain("--baseimagetag", args); - } - } - - - [Theory] - [InlineData(null)] - [InlineData("")] - [InlineData(" ")] - [InlineData("Valid", true)] - public void GenerateCommandLineCommands_OutputRegistry(string? value, bool optionExpected = false) - { - CreateNewImage task = new(); - DirectoryInfo publishDir = Directory.CreateDirectory(Path.Combine(Path.GetTempPath(), DateTime.Now.ToString("yyyyMMddHHmmssfff"))); - task.PublishDirectory = publishDir.FullName; - task.BaseRegistry = "MyBaseRegistry"; - task.BaseImageName = "MyBaseImageName"; - task.Repository = "MyImageName"; - task.WorkingDirectory = "MyWorkingDirectory"; - task.Entrypoint = new[] { new TaskItem("MyEntryPoint") }; - - if (value != null) - { - task.OutputRegistry = value; - } - - string args = task.GenerateCommandLineCommandsInt(); - - if (optionExpected) - { - Assert.Contains($"--outputregistry {value}", args); - } - else - { - Assert.DoesNotContain("--outputregistry", args); - } - } - - [Theory] - [InlineData(null)] - [InlineData("")] - [InlineData(" ")] - [InlineData("Valid", true)] - public void GenerateCommandLineCommands_ContainerRuntimeIdentifier(string? value, bool optionExpected = false) - { - CreateNewImage task = new(); - DirectoryInfo publishDir = Directory.CreateDirectory(Path.Combine(Path.GetTempPath(), DateTime.Now.ToString("yyyyMMddHHmmssfff"))); - task.PublishDirectory = publishDir.FullName; - task.BaseRegistry = "MyBaseRegistry"; - task.BaseImageName = "MyBaseImageName"; - task.Repository = "MyImageName"; - task.WorkingDirectory = "MyWorkingDirectory"; - task.Entrypoint = new[] { new TaskItem("MyEntryPoint") }; - - if (value != null) - { - task.ContainerRuntimeIdentifier = value; - } - - string args = task.GenerateCommandLineCommandsInt(); - if (optionExpected) - { - Assert.Contains($"--rid {value}", args); - } - else - { - Assert.DoesNotContain("--rid", args); - } - } - - [Theory] - [InlineData(null)] - [InlineData("")] - [InlineData(" ")] - [InlineData("Valid", true)] - public void GenerateCommandLineCommands_RuntimeIdentifierGraphPath(string? value, bool optionExpected = false) - { - CreateNewImage task = new(); - DirectoryInfo publishDir = Directory.CreateDirectory(Path.Combine(Path.GetTempPath(), DateTime.Now.ToString("yyyyMMddHHmmssfff"))); - task.PublishDirectory = publishDir.FullName; - task.BaseRegistry = "MyBaseRegistry"; - task.BaseImageName = "MyBaseImageName"; - task.Repository = "MyImageName"; - task.WorkingDirectory = "MyWorkingDirectory"; - task.Entrypoint = new[] { new TaskItem("MyEntryPoint") }; - - if (value != null) - { - task.RuntimeIdentifierGraphPath = value; - } - - string args = task.GenerateCommandLineCommandsInt(); - - if (optionExpected) - { - Assert.Contains($"--ridgraphpath {value}", args); - } - else - { - Assert.DoesNotContain("--ridgraphpath", args); - } - } - - [Fact] - public void GenerateCommandLineCommands_Labels() - { - CreateNewImage task = new(); - - List warnings = new(); - IBuildEngine buildEngine = A.Fake(); - A.CallTo(() => buildEngine.LogWarningEvent(A.Ignored)).Invokes((BuildWarningEventArgs e) => warnings.Add(e.Message)); - - task.BuildEngine = buildEngine; - - DirectoryInfo publishDir = Directory.CreateDirectory(Path.Combine(Path.GetTempPath(), DateTime.Now.ToString("yyyyMMddHHmmssfff"))); - task.PublishDirectory = publishDir.FullName; - task.BaseRegistry = "MyBaseRegistry"; - task.BaseImageName = "MyBaseImageName"; - task.Repository = "MyImageName"; - task.WorkingDirectory = "MyWorkingDirectory"; - task.Entrypoint = new[] { new TaskItem("MyEntryPoint") }; - - task.Labels = new[] - { - new TaskItem("NoValue"), - new TaskItem(" "), - new TaskItem("Valid1", new Dictionary() {{ "Value", "Val1" }}), - new TaskItem("Valid12", new Dictionary() {{ "Value", "Val2" }}), - new TaskItem("Valid12", new Dictionary() {{ "Value", "" }}), - new TaskItem("Valid3", new Dictionary() {{ "Value", "has space" }}), - new TaskItem("Valid4", new Dictionary() {{ "Value", "has\"quotes\"" }}) - }; - - string args = task.GenerateCommandLineCommandsInt(); - - Assert.Contains(""" - --labels NoValue= Valid1=Val1 Valid12=Val2 Valid12= "Valid3=has space" "Valid4=has\"quotes\"" - """, args); - Assert.Equal("Items 'Labels' contain empty item(s) which will be ignored.", Assert.Single(warnings)); - - string workDir = GetPathToContainerize(); - - new DotnetCommand(_testOutput, args) - .WithRawArguments() - .WithWorkingDirectory(workDir) - .Execute().Should().Fail() - .And.NotHaveStdOutContaining("Description:"); //standard help output for parse error - } - - [Fact] - public void GenerateCommandLineCommands_ContainerEnvironmentVariables() - { - CreateNewImage task = new(); - - List warnings = new(); - IBuildEngine buildEngine = A.Fake(); - A.CallTo(() => buildEngine.LogWarningEvent(A.Ignored)).Invokes((BuildWarningEventArgs e) => warnings.Add(e.Message)); - - task.BuildEngine = buildEngine; - - DirectoryInfo publishDir = Directory.CreateDirectory(Path.Combine(Path.GetTempPath(), DateTime.Now.ToString("yyyyMMddHHmmssfff"))); - task.PublishDirectory = publishDir.FullName; - task.BaseRegistry = "MyBaseRegistry"; - task.BaseImageName = "MyBaseImageName"; - task.Repository = "MyImageName"; - task.WorkingDirectory = "MyWorkingDirectory"; - task.Entrypoint = new[] { new TaskItem("MyEntryPoint") }; - - task.ContainerEnvironmentVariables = new[] - { - new TaskItem("NoValue"), - new TaskItem(" "), - new TaskItem("Valid1", new Dictionary() {{ "Value", "Val1" }}), - new TaskItem("Valid12", new Dictionary() {{ "Value", "Val2" }}), - new TaskItem("Valid12", new Dictionary() {{ "Value", "" }}), - new TaskItem("Valid3", new Dictionary() {{ "Value", "has space" }}), - new TaskItem("Valid4", new Dictionary() {{ "Value", "has\"quotes\"" }}) - }; - - string args = task.GenerateCommandLineCommandsInt(); - - Assert.Contains(""" - --environmentvariables NoValue= Valid1=Val1 Valid12=Val2 Valid12= "Valid3=has space" "Valid4=has\"quotes\"" - """, args); - Assert.Equal("Items 'ContainerEnvironmentVariables' contain empty item(s) which will be ignored.", Assert.Single(warnings)); - - string workDir = GetPathToContainerize(); - - new DotnetCommand(_testOutput, args) - .WithRawArguments() - .WithWorkingDirectory(workDir) - .Execute().Should().Fail() - .And.NotHaveStdOutContaining("Description:"); //standard help output for parse error - } - - [InlineData(nameof(CreateNewImage.Entrypoint), "entrypoint")] - [InlineData(nameof(CreateNewImage.EntrypointArgs), "entrypointargs", true)] - [InlineData(nameof(CreateNewImage.DefaultArgs), "defaultargs", true)] - [InlineData(nameof(CreateNewImage.AppCommand), "appcommand", true)] - [InlineData(nameof(CreateNewImage.AppCommandArgs), "appcommandargs", true)] - [Theory] - public void GenerateCommandLineCommands_EntryPointAndCommand(string propertyName, string commandArgName, bool warningExpected = false) - { - CreateNewImage task = new(); - - List warnings = new(); - IBuildEngine buildEngine = A.Fake(); - A.CallTo(() => buildEngine.LogWarningEvent(A.Ignored)).Invokes((BuildWarningEventArgs e) => warnings.Add(e.Message)); - - task.BuildEngine = buildEngine; - - DirectoryInfo publishDir = Directory.CreateDirectory(Path.Combine(Path.GetTempPath(), DateTime.Now.ToString("yyyyMMddHHmmssfff"))); - task.PublishDirectory = publishDir.FullName; - task.BaseRegistry = "MyBaseRegistry"; - task.BaseImageName = "MyBaseImageName"; - task.Repository = "MyImageName"; - task.WorkingDirectory = "MyWorkingDirectory"; - task.Entrypoint = new[] { new TaskItem("MyEntryPoint") }; - - switch (propertyName) - { - case nameof(CreateNewImage.Entrypoint): - task.Entrypoint = new[] - { - new TaskItem("Valid1"), - new TaskItem("Valid2"), - new TaskItem("Quoted item") - }; - break; - case nameof(CreateNewImage.EntrypointArgs): - task.EntrypointArgs = new[] - { - new TaskItem(""), - new TaskItem(" "), - new TaskItem("Valid1"), - new TaskItem("Valid2"), - new TaskItem("Quoted item") - }; - break; - case nameof(CreateNewImage.DefaultArgs): - task.DefaultArgs = new[] - { - new TaskItem(""), - new TaskItem(" "), - new TaskItem("Valid1"), - new TaskItem("Valid2"), - new TaskItem("Quoted item") - }; - break; - case nameof(CreateNewImage.AppCommand): - task.AppCommand = new[] - { - new TaskItem(""), - new TaskItem(" "), - new TaskItem("Valid1"), - new TaskItem("Valid2"), - new TaskItem("Quoted item") - }; - break; - case nameof(CreateNewImage.AppCommandArgs): - task.AppCommandArgs = new[] - { - new TaskItem(""), - new TaskItem(" "), - new TaskItem("Valid1"), - new TaskItem("Valid2"), - new TaskItem("Quoted item") - }; - break; - } - - string args = task.GenerateCommandLineCommandsInt(); - - Assert.Contains($""" - --{commandArgName} Valid1 Valid2 "Quoted item" - """, args); - - if (warningExpected) - { - Assert.Equal($"Items '{propertyName}' contain empty item(s) which will be ignored.", Assert.Single(warnings)); - } - - string workDir = GetPathToContainerize(); - - new DotnetCommand(_testOutput, args) - .WithRawArguments() - .WithWorkingDirectory(workDir) - .Execute().Should().Fail() - .And.NotHaveStdOutContaining("Description:"); //standard help output for parse error - } - - [InlineData("")] - [InlineData(" ")] - [Theory] - public void GenerateCommandLineCommands_EntryPointCanHaveEmptyItems(string itemValue) - { - CreateNewImage task = new(); - IBuildEngine buildEngine = A.Fake(); - - task.BuildEngine = buildEngine; - - DirectoryInfo publishDir = Directory.CreateDirectory(Path.Combine(Path.GetTempPath(), DateTime.Now.ToString("yyyyMMddHHmmssfff"))); - task.PublishDirectory = publishDir.FullName; - task.BaseRegistry = "MyBaseRegistry"; - task.BaseImageName = "MyBaseImageName"; - task.Repository = "MyImageName"; - task.WorkingDirectory = "MyWorkingDirectory"; - task.Entrypoint = new[] { new TaskItem(itemValue) }; - - task.GenerateCommandLineCommandsInt(); - } - - [Theory] - [InlineData(null)] - [InlineData("")] - [InlineData(" ")] - [InlineData("Valid", true)] - public void GenerateCommandLineCommands_AppCommandInstruction(string? value, bool optionExpected = false) - { - CreateNewImage task = new(); - DirectoryInfo publishDir = Directory.CreateDirectory(Path.Combine(Path.GetTempPath(), DateTime.Now.ToString("yyyyMMddHHmmssfff"))); - task.PublishDirectory = publishDir.FullName; - task.BaseRegistry = "MyBaseRegistry"; - task.BaseImageName = "MyBaseImageName"; - task.Repository = "MyImageName"; - task.WorkingDirectory = "MyWorkingDirectory"; - - if (value != null) - { - task.AppCommandInstruction = value; - } - - string args = task.GenerateCommandLineCommandsInt(); - - if (optionExpected) - { - Assert.Contains($"--appcommandinstruction {value}", args); - } - else - { - Assert.DoesNotContain("--appcommandinstruction", args); - } - } - - [Fact] - public void GenerateCommandLineCommands_ImageTags() - { - CreateNewImage task = new(); - - List warnings = new(); - IBuildEngine buildEngine = A.Fake(); - A.CallTo(() => buildEngine.LogWarningEvent(A.Ignored)).Invokes((BuildWarningEventArgs e) => warnings.Add(e.Message)); - - task.BuildEngine = buildEngine; - - DirectoryInfo publishDir = Directory.CreateDirectory(Path.Combine(Path.GetTempPath(), DateTime.Now.ToString("yyyyMMddHHmmssfff"))); - task.PublishDirectory = publishDir.FullName; - task.BaseRegistry = "MyBaseRegistry"; - task.BaseImageName = "MyBaseImageName"; - task.Repository = "MyImageName"; - task.WorkingDirectory = "MyWorkingDirectory"; - task.Entrypoint = new[] { new TaskItem("MyEntryPoint") }; - - task.ImageTags = new[] { "", " ", "Valid1", "To be quoted" }; - - string args = task.GenerateCommandLineCommandsInt(); - - Assert.Contains(""" - --imagetags Valid1 "To be quoted" - """, actualString: args); - Assert.Equal("Property 'ImageTags' is empty or contains whitespace and will be ignored.", Assert.Single(warnings)); - - string workDir = GetPathToContainerize(); - - new DotnetCommand(_testOutput, args) - .WithRawArguments() - .WithWorkingDirectory(workDir) - .Execute().Should().Fail() - .And.NotHaveStdOutContaining("Description:"); //standard help output for parse error - } - - [Fact] - public void GenerateCommandLineCommands_ExposedPorts() - { - CreateNewImage task = new(); - - List warnings = new(); - IBuildEngine buildEngine = A.Fake(); - A.CallTo(() => buildEngine.LogWarningEvent(A.Ignored)).Invokes((BuildWarningEventArgs e) => warnings.Add(e.Message)); - - task.BuildEngine = buildEngine; - - DirectoryInfo publishDir = Directory.CreateDirectory(Path.Combine(Path.GetTempPath(), DateTime.Now.ToString("yyyyMMddHHmmssfff"))); - task.PublishDirectory = publishDir.FullName; - task.BaseRegistry = "MyBaseRegistry"; - task.BaseImageName = "MyBaseImageName"; - task.Repository = "MyImageName"; - task.WorkingDirectory = "MyWorkingDirectory"; - task.Entrypoint = new[] { new TaskItem("MyEntryPoint") }; - - task.ExposedPorts = new[] - { - new TaskItem("1500"), - new TaskItem(" "), - new TaskItem("1501", new Dictionary() {{ "Type", "udp" }}), - new TaskItem("1501", new Dictionary() {{ "Type", "tcp" }}), - new TaskItem("1502", new Dictionary() {{ "Type", "tcp" }}), - new TaskItem("1503", new Dictionary() {{ "Type", "" }}) - }; - - string args = task.GenerateCommandLineCommandsInt(); - - Assert.Contains(""" - --ports 1500 1501/udp 1501/tcp 1502/tcp 1503 - """, args); - Assert.Equal("Items 'ExposedPorts' contain empty item(s) which will be ignored.", Assert.Single(warnings)); - - string workDir = GetPathToContainerize(); - - new DotnetCommand(_testOutput, args) - .WithRawArguments() - .WithWorkingDirectory(workDir) - .Execute().Should().Fail() - .And.NotHaveStdOutContaining("Description:"); //standard help output for parse error - } - - [Fact] - public void Logging_CanEnableTraceLogging() - { - CreateNewImage task = new(); - DirectoryInfo publishDir = Directory.CreateDirectory(Path.Combine(Path.GetTempPath(), DateTime.Now.ToString("yyyyMMddHHmmssfff"))); - - task.PublishDirectory = publishDir.FullName; - task.BaseRegistry = "MyBaseRegistry"; - task.BaseImageName = "MyBaseImageName"; - task.Repository = "MyImageName"; - task.WorkingDirectory = "MyWorkingDirectory"; - task.Entrypoint = new[] { new TaskItem("") }; - task.Entrypoint = new[] { new TaskItem("MyEntryPoint") }; - - string args = task.GenerateCommandLineCommandsInt(); - string workDir = GetPathToContainerize(); - - new DotnetCommand(_testOutput, args) - .WithRawArguments() - .WithWorkingDirectory(workDir) - .WithEnvironmentVariable("CONTAINERIZE_TRACE_LOGGING_ENABLED", "1") - .Execute().Should().Fail() - .And.NotHaveStdOutContaining("Description:") //standard help output for parse error - .And.HaveStdOutContaining("Trace logging: enabled."); - } - - [Fact] - public void Logging_TraceLoggingIsDisabledByDefault() - { - CreateNewImage task = new(); - DirectoryInfo publishDir = Directory.CreateDirectory(Path.Combine(Path.GetTempPath(), DateTime.Now.ToString("yyyyMMddHHmmssfff"))); - - task.PublishDirectory = publishDir.FullName; - task.BaseRegistry = "MyBaseRegistry"; - task.BaseImageName = "MyBaseImageName"; - task.Repository = "MyImageName"; - task.WorkingDirectory = "MyWorkingDirectory"; - task.Entrypoint = new[] { new TaskItem("") }; - task.Entrypoint = new[] { new TaskItem("MyEntryPoint") }; - - string args = task.GenerateCommandLineCommandsInt(); - string workDir = GetPathToContainerize(); - - new DotnetCommand(_testOutput, args) - .WithRawArguments() - .WithWorkingDirectory(workDir) - .Execute().Should().Fail() - .And.NotHaveStdOutContaining("Description:") //standard help output for parse error - .And.NotHaveStdOutContaining("Trace logging: enabled."); - } - - [Fact] - public void GenerateCommandLineCommands_LabelGeneration() - { - CreateNewImage task = new(); - - List warnings = new(); - IBuildEngine buildEngine = A.Fake(); - - task.BuildEngine = buildEngine; - - DirectoryInfo publishDir = Directory.CreateDirectory(Path.Combine(Path.GetTempPath(), DateTime.Now.ToString("yyyyMMddHHmmssfff"))); - task.PublishDirectory = publishDir.FullName; - task.BaseRegistry = "MyBaseRegistry"; - task.BaseImageName = "MyBaseImageName"; - task.Repository = "MyImageName"; - task.WorkingDirectory = "MyWorkingDirectory"; - task.Entrypoint = new[] { new TaskItem("MyEntryPoint") }; - task.GenerateLabels = true; - task.GenerateDigestLabel = true; - - string args = task.GenerateCommandLineCommandsInt(); - - Assert.Contains("--generate-labels", args); - Assert.Contains("--generate-digest-label", args); - } - - - - private static string GetPathToContainerize() - { - return Path.Combine(SdkTestContext.Current.TestExecutionDirectory, "Container", "containerize"); - } -} diff --git a/test/Microsoft.NET.Build.Containers.IntegrationTests/Microsoft.NET.Build.Containers.IntegrationTests.csproj b/test/Microsoft.NET.Build.Containers.IntegrationTests/Microsoft.NET.Build.Containers.IntegrationTests.csproj index 8d3d1f4bedcd..2b580a92681a 100644 --- a/test/Microsoft.NET.Build.Containers.IntegrationTests/Microsoft.NET.Build.Containers.IntegrationTests.csproj +++ b/test/Microsoft.NET.Build.Containers.IntegrationTests/Microsoft.NET.Build.Containers.IntegrationTests.csproj @@ -1,13 +1,13 @@  - $(SdkTargetFramework);net472 + $(SdkTargetFramework) enable false true true MicrosoftShared - Exe + Exe true @@ -25,23 +25,11 @@ - - - - - - - - - - - - + - diff --git a/test/Microsoft.NET.Build.Containers.IntegrationTests/PackageTests.cs b/test/Microsoft.NET.Build.Containers.IntegrationTests/PackageTests.cs index db1a7aff703e..961fbd76860c 100644 --- a/test/Microsoft.NET.Build.Containers.IntegrationTests/PackageTests.cs +++ b/test/Microsoft.NET.Build.Containers.IntegrationTests/PackageTests.cs @@ -42,7 +42,6 @@ public void SanityTest_NET_Build_ContainersDependencies() "Microsoft.Build.Utilities.Core", "Microsoft.CodeAnalysis.PublicApiAnalyzers", "Nuget.Packaging", - "System.Text.Json", "Valleysoft.DockerCredsProvider", "Microsoft.Extensions.Logging", "Microsoft.Extensions.Logging.Abstractions" @@ -108,13 +107,6 @@ public void PackageContentTest() "Icon.png", "Microsoft.NET.Build.Containers.nuspec", "README.md", - "tasks/net472/Microsoft.NET.Build.Containers.dll", - "tasks/net472/Newtonsoft.Json.dll", - "tasks/net472/NuGet.Common.dll", - "tasks/net472/NuGet.Configuration.dll", - "tasks/net472/NuGet.Frameworks.dll", - "tasks/net472/NuGet.Packaging.dll", - "tasks/net472/NuGet.Versioning.dll", $"tasks/{netTFM}/Microsoft.DotNet.Cli.Utils.dll", $"tasks/{netTFM}/Microsoft.Extensions.DependencyInjection.Abstractions.dll", $"tasks/{netTFM}/Microsoft.Extensions.DependencyInjection.dll", diff --git a/test/Microsoft.NET.Build.Containers.UnitTests/RegistryTests.cs b/test/Microsoft.NET.Build.Containers.UnitTests/RegistryTests.cs index 5ee29863abe7..77300f2682aa 100644 --- a/test/Microsoft.NET.Build.Containers.UnitTests/RegistryTests.cs +++ b/test/Microsoft.NET.Build.Containers.UnitTests/RegistryTests.cs @@ -689,7 +689,8 @@ public string GetCommandPathFromRootPath(string rootPath, string commandName, pa public string GetCommandPathFromRootPath(string rootPath, string commandName, IEnumerable extensions) => throw new NotImplementedException(); - public bool TryGetEnvironmentVariable(string name, [NotNullWhen(true)] out string? value) => _environmentVariables.TryGetValue(name, out value); + public bool TryGetEnvironmentVariable(string name, [NotNullWhen(true)] out string? value) => _environmentVariables.TryGetValue(name, out value!); + public bool TryGetEnvironmentVariableAsBool(string name, [NotNullWhen(true)] out bool value) { if (TryGetEnvironmentVariable(name, out string? strValue) && bool.TryParse(strValue, out bool boolValue)) diff --git a/test/UnitTests.proj b/test/UnitTests.proj index f043119e1b05..746736b1d9fa 100644 --- a/test/UnitTests.proj +++ b/test/UnitTests.proj @@ -46,7 +46,6 @@ Microsoft.DotNet.MSBuildSdkResolver.Tests\Microsoft.DotNet.MSBuildSdkResolver.Tests.csproj; Microsoft.DotNet.PackageValidation.Tests\Microsoft.DotNet.PackageValidation.Tests.csproj; Microsoft.DotNet.TemplateLocator.Tests\Microsoft.DotNet.TemplateLocator.Tests.csproj; - Microsoft.NET.Build.Containers.IntegrationTests\Microsoft.NET.Build.Containers.IntegrationTests.csproj; Microsoft.NET.Sdk.Publish.Tasks.Tests\Microsoft.NET.Sdk.Publish.Tasks.Tests.csproj; Microsoft.NET.Sdk.WorkloadManifestReader.Tests\Microsoft.NET.Sdk.WorkloadManifestReader.Tests.csproj; Microsoft.Win32.Msi.Tests\Microsoft.Win32.Msi.Tests.csproj"