From 19fe7f4b2dac87b4abf9c06c9e116899351141a1 Mon Sep 17 00:00:00 2001 From: Joseph Petersen Date: Wed, 22 Jul 2026 19:26:36 +0200 Subject: [PATCH] Fix multi-arch container label parsing --- .../Microsoft.NET.Build.Containers.targets | 4 +-- .../TargetsTests.cs | 28 +++++++++++++++++++ 2 files changed, 30 insertions(+), 2 deletions(-) diff --git a/src/Containers/packaging/build/Microsoft.NET.Build.Containers.targets b/src/Containers/packaging/build/Microsoft.NET.Build.Containers.targets index af82a666253b..07f09c6aa9b8 100644 --- a/src/Containers/packaging/build/Microsoft.NET.Build.Containers.targets +++ b/src/Containers/packaging/build/Microsoft.NET.Build.Containers.targets @@ -375,8 +375,8 @@ Include="$(_ContainerLabel)"/> + Include="$([System.String]::Copy('%(_ParsedContainerLabel.Identity)').Split(':', 2)[0])" + Value="$([System.String]::Copy('%(_ParsedContainerLabel.Identity)').Split(':', 2)[1])" /> <_ParsedContainerPort Condition="'$(_ContainerPort)' != ':'" diff --git a/test/Microsoft.NET.Build.Containers.IntegrationTests/TargetsTests.cs b/test/Microsoft.NET.Build.Containers.IntegrationTests/TargetsTests.cs index cbcfcadd84c3..b27999795b08 100644 --- a/test/Microsoft.NET.Build.Containers.IntegrationTests/TargetsTests.cs +++ b/test/Microsoft.NET.Build.Containers.IntegrationTests/TargetsTests.cs @@ -140,6 +140,34 @@ public void GetsConventionalLabelsByDefault(bool shouldEvaluateLabels) private static bool LabelMatch(string label, string value, ProjectItemInstance item) => item.EvaluatedInclude == label && item.GetMetadata("Value") is { } v && v.EvaluatedValue == value; + [TestMethod] + public void MultiArchContainerLabelsPreserveColonsInValues() + { + var expectedLabels = new Dictionary + { + ["org.opencontainers.image.source"] = "https://github.com/dotnet/sdk", + ["org.opencontainers.image.created"] = "2026-07-22T12:34:56.7890000Z", + }; + var serializedLabels = string.Join(';', expectedLabels.Select(label => $"{label.Key}:{label.Value}")); + + var (project, logger, d) = ProjectInitializer.InitProject(new() + { + ["_ContainerLabel"] = serializedLabels, + }, projectName: nameof(MultiArchContainerLabelsPreserveColonsInValues)); + using var _ = d; + var instance = project.CreateProjectInstance(ProjectInstanceSettings.None); + + instance.Build(["_ParseItemsForPublishingSingleContainer"], [logger]) + .Should().BeTrue("Build should have succeeded but failed due to {0}", string.Join('\n', logger.AllMessages)); + + var labels = instance.GetItems(ContainerLabel); + labels.Should().HaveCount(expectedLabels.Count); + foreach (var expectedLabel in expectedLabels) + { + labels.Should().ContainSingle(label => LabelMatch(expectedLabel.Key, expectedLabel.Value, label)); + } + } + [DataRow(true)] [DataRow(false)] [TestMethod]