Skip to content

Commit eed07a0

Browse files
joeloffnagilsonMiYanni
authored
Add support for .NET workload sets (#14083)
Co-authored-by: Noah Gilson <OTAKUPENGUINOP@GMAIL.COM> Co-authored-by: Michael Yanni <MiYanni@microsoft.com>
1 parent c287c52 commit eed07a0

32 files changed

+1302
-530
lines changed

eng/Versions.props

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,11 +51,15 @@
5151
<MicrosoftNETRuntimeEmscripten2023Nodewin_x64>6.0.4</MicrosoftNETRuntimeEmscripten2023Nodewin_x64>
5252
<MicrosoftNETRuntimeEmscripten2023Pythonwin_x64>6.0.4</MicrosoftNETRuntimeEmscripten2023Pythonwin_x64>
5353
<MicrosoftNETRuntimeEmscripten2023Sdkwin_x64>6.0.4</MicrosoftNETRuntimeEmscripten2023Sdkwin_x64>
54+
<MicrosoftNETWorkloadBaselineVersion>9.0.100-baseline.1.23464.1</MicrosoftNETWorkloadBaselineVersion>
5455
<MicrosoftNETWorkloadEmscriptenManifest_60200Version>6.0.4</MicrosoftNETWorkloadEmscriptenManifest_60200Version>
5556
<MicrosoftNETWorkloadEmscriptenManifest_80100Preview6Version>8.0.0-preview.6.23326.2</MicrosoftNETWorkloadEmscriptenManifest_80100Preview6Version>
5657
<MicrosoftNETWorkloadMonoToolChainManifest_60200Version>6.0.3</MicrosoftNETWorkloadMonoToolChainManifest_60200Version>
5758
<MicrosoftNETWorkloadMonoToolChainManifest_60200Version_604>6.0.4</MicrosoftNETWorkloadMonoToolChainManifest_60200Version_604>
59+
<MicrosoftNETWorkloadMonoToolChainManifest_60300Version_6021>6.0.21</MicrosoftNETWorkloadMonoToolChainManifest_60300Version_6021>
60+
<MicrosoftNETWorkloadMonoToolChainManifest_60300Version_6022>6.0.22</MicrosoftNETWorkloadMonoToolChainManifest_60300Version_6022>
5861
<MicrosoftiOSTemplatesVersion>15.2.302-preview.14.122</MicrosoftiOSTemplatesVersion>
62+
<MicrosoftiOSTemplatesVersion160527>16.0.527</MicrosoftiOSTemplatesVersion160527>
5963
<!-- Keep this version in sync with what msbuild / VS ships with. -->
6064
<SystemCollectionsImmutableVersion>7.0.0</SystemCollectionsImmutableVersion>
6165
<SystemCompositionVersion>8.0.0-preview.4.23259.5</SystemCompositionVersion>
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
// Licensed to the .NET Foundation under one or more agreements.
2+
// The .NET Foundation licenses this file to you under the MIT license.
3+
4+
using System.IO;
5+
using System.Linq;
6+
using FluentAssertions;
7+
using Microsoft.Arcade.Test.Common;
8+
using Microsoft.Build.Framework;
9+
using Microsoft.Build.Utilities;
10+
using Microsoft.DotNet.Build.Tasks.Workloads.Msi;
11+
using Xunit;
12+
13+
namespace Microsoft.DotNet.Build.Tasks.Workloads.Tests
14+
{
15+
public class CreateVisualStudioWorkloadSetTests : TestBase
16+
{
17+
[WindowsOnlyFact]
18+
public static void ItCanCreateWorkloadSets()
19+
{
20+
// Create intermediate outputs under %temp% to avoid path issues and make sure it's clean so we don't pick up
21+
// conflicting sources from previous runs.
22+
string baseIntermediateOutputPath = Path.Combine(Path.GetTempPath(), "WLS");
23+
24+
if (Directory.Exists(baseIntermediateOutputPath))
25+
{
26+
Directory.Delete(baseIntermediateOutputPath, recursive: true);
27+
}
28+
29+
ITaskItem[] workloadSetPackages = new[]
30+
{
31+
new TaskItem(Path.Combine(TestAssetsPath, "microsoft.net.workloads.9.0.100.9.0.100-baseline.1.23464.1.nupkg"))
32+
.WithMetadata(Metadata.MsiVersion, "12.8.45")
33+
};
34+
35+
IBuildEngine buildEngine = new MockBuildEngine();
36+
37+
CreateVisualStudioWorkloadSet createWorkloadSetTask = new CreateVisualStudioWorkloadSet()
38+
{
39+
BaseOutputPath = BaseOutputPath,
40+
BaseIntermediateOutputPath = baseIntermediateOutputPath,
41+
BuildEngine = buildEngine,
42+
PackageSource = TestAssetsPath,
43+
WixToolsetPath = WixToolsetPath,
44+
WorkloadSetPackageFiles = workloadSetPackages
45+
};
46+
47+
Assert.True(createWorkloadSetTask.Execute());
48+
49+
// Spot check the x64 generated MSI.
50+
ITaskItem msi = createWorkloadSetTask.Msis.Where(i => i.GetMetadata(Metadata.Platform) == "x64").FirstOrDefault();
51+
Assert.NotNull(msi);
52+
53+
// Verify the workload set records the CLI will use.
54+
MsiUtils.GetAllRegistryKeys(msi.ItemSpec).Should().Contain(r =>
55+
r.Root == 2 &&
56+
r.Key == @"SOFTWARE\Microsoft\dotnet\InstalledWorkloadSets\x64\9.0.100\9.0.100-baseline.1.23464.1" &&
57+
r.Name == "ProductVersion" &&
58+
r.Value == "12.8.45");
59+
60+
// Workload sets are SxS. Verify that we don't have an Upgrade table.
61+
Assert.False(MsiUtils.HasTable(msi.ItemSpec, "Upgrade"));
62+
63+
// Verify the SWIX authoring for one of the workload set MSIs.
64+
ITaskItem workloadSetSwixItem = createWorkloadSetTask.SwixProjects.Where(s => s.ItemSpec.Contains(@"Microsoft.NET.Workloads.9.0.100.9.0.100-baseline.1.23464.1\x64")).FirstOrDefault();
65+
Assert.Equal(DefaultValues.PackageTypeMsiWorkloadSet, workloadSetSwixItem.GetMetadata(Metadata.PackageType));
66+
67+
string msiSwr = File.ReadAllText(Path.Combine(Path.GetDirectoryName(workloadSetSwixItem.ItemSpec), "msi.swr"));
68+
Assert.Contains("package name=Microsoft.NET.Workloads.9.0.100.9.0.100-baseline.1.23464.1", msiSwr);
69+
Assert.Contains("version=12.8.45", msiSwr);
70+
Assert.DoesNotContain("vs.package.chip=x64", msiSwr);
71+
Assert.Contains("vs.package.machineArch=x64", msiSwr);
72+
Assert.Contains("vs.package.type=msi", msiSwr);
73+
74+
// Verify package group SWIX project
75+
ITaskItem workloadSetPackageGroupSwixItem = createWorkloadSetTask.SwixProjects.Where(
76+
s => s.GetMetadata(Metadata.PackageType).Equals(DefaultValues.PackageTypeWorkloadSetPackageGroup)).
77+
FirstOrDefault();
78+
string packageGroupSwr = File.ReadAllText(Path.Combine(Path.GetDirectoryName(workloadSetPackageGroupSwixItem.ItemSpec), "packageGroup.swr"));
79+
Assert.Contains("package name=PackageGroup.NET.Workloads-9.0.100", packageGroupSwr);
80+
Assert.Contains("vs.dependency id=Microsoft.NET.Workloads.9.0.100.9.0.100-baseline.1.23464.1", packageGroupSwr);
81+
}
82+
}
83+
}

src/Microsoft.DotNet.Build.Tasks.Workloads.Tests/CreateVisualStudioWorkloadTests.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515

1616
namespace Microsoft.DotNet.Build.Tasks.Workloads.Tests
1717
{
18+
[Collection("Workload Creation")]
1819
public class CreateVisualStudioWorkloadTests : TestBase
1920
{
2021
[WindowsOnlyFact]

src/Microsoft.DotNet.Build.Tasks.Workloads.Tests/Microsoft.DotNet.Build.Tasks.Workloads.Tests.csproj

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,13 +25,15 @@
2525
<ItemGroup>
2626
<PackageDownload Include="Microsoft.Signed.Wix" Version="[$(MicrosoftSignedWixVersion)]" />
2727
<PackageDownload Include="Microsoft.NET.Workload.Mono.ToolChain.Manifest-6.0.200" Version="[$(MicrosoftNETWorkloadMonoToolChainManifest_60200Version)];[$(MicrosoftNETWorkloadMonoToolChainManifest_60200Version_604)]" />
28-
<PackageDownload Include="Microsoft.iOS.Templates" Version="[$(MicrosoftiOSTemplatesVersion)]" />
28+
<PackageDownload Include="Microsoft.NET.Workload.Mono.ToolChain.Manifest-6.0.300" Version="[$(MicrosoftNETWorkloadMonoToolChainManifest_60300Version_6021)];[$(MicrosoftNETWorkloadMonoToolChainManifest_60300Version_6022)]" />
29+
<PackageDownload Include="Microsoft.iOS.Templates" Version="[$(MicrosoftiOSTemplatesVersion)];[$(MicrosoftiOSTemplatesVersion160527)]" />
2930
<PackageDownload Include="Microsoft.NET.Workload.Emscripten.net6.Manifest-8.0.100-preview.6" Version="[$(MicrosoftNETWorkloadEmscriptenManifest_80100Preview6Version)]"/>
3031
<!-- We can only test the task properly by building an actual workload end-to-end. EMSDK is the tiniest one available -->
3132
<PackageDownload Include="Microsoft.NET.Workload.Emscripten.Manifest-6.0.200" Version="[$(MicrosoftNETWorkloadEmscriptenManifest_60200Version)]" />
3233
<PackageDownload Include="Microsoft.NET.Runtime.Emscripten.2.0.23.Node.win-x64" Version="[$(MicrosoftNETRuntimeEmscripten2023Nodewin_x64)]" />
3334
<PackageDownload Include="Microsoft.NET.Runtime.Emscripten.2.0.23.Python.win-x64" Version="[$(MicrosoftNETRuntimeEmscripten2023Pythonwin_x64)]" />
3435
<PackageDownload Include="Microsoft.NET.Runtime.Emscripten.2.0.23.Sdk.win-x64" Version="[$(MicrosoftNETRuntimeEmscripten2023Sdkwin_x64)]" />
36+
<PackageDownload Include="Microsoft.NET.Workloads.9.0.100" Version="[$(MicrosoftNETWorkloadBaselineVersion)]" />
3537
</ItemGroup>
3638

3739
<ItemGroup Condition="'$(TargetFrameworkIdentifier)' == '.NETFramework'">
@@ -43,12 +45,16 @@
4345
<Content Include="$(NuGetPackageRoot)microsoft.signed.wix\$(MicrosoftSignedWixVersion)\tools\**\*" Link="testassets\wix\%(RecursiveDir)%(Filename)%(Extension)" CopyToOutputDirectory="PreserveNewest" Visible="false" />
4446
<Content Include="$(NuGetPackageRoot)microsoft.net.workload.mono.toolchain.manifest-6.0.200\$(MicrosoftNETWorkloadMonoToolChainManifest_60200Version)\*.nupkg" Link="testassets\%(Filename)%(Extension)" CopyToOutputDirectory="PreserveNewest" Visible="false" />
4547
<Content Include="$(NuGetPackageRoot)microsoft.net.workload.mono.toolchain.manifest-6.0.200\$(MicrosoftNETWorkloadMonoToolChainManifest_60200Version_604)\*.nupkg" Link="testassets\%(Filename)%(Extension)" CopyToOutputDirectory="PreserveNewest" Visible="false" />
48+
<Content Include="$(NuGetPackageRoot)microsoft.net.workload.mono.toolchain.manifest-6.0.300\$(MicrosoftNETWorkloadMonoToolChainManifest_60300Version_6022)\*.nupkg" Link="testassets\%(Filename)%(Extension)" CopyToOutputDirectory="PreserveNewest" Visible="false" />
49+
<Content Include="$(NuGetPackageRoot)microsoft.net.workload.mono.toolchain.manifest-6.0.300\$(MicrosoftNETWorkloadMonoToolChainManifest_60300Version_6021)\*.nupkg" Link="testassets\%(Filename)%(Extension)" CopyToOutputDirectory="PreserveNewest" Visible="false" />
4650
<Content Include="$(NuGetPackageRoot)microsoft.ios.templates\$(MicrosoftiOSTemplatesVersion)\*.nupkg" Link="testassets\%(Filename)%(Extension)" CopyToOutputDirectory="PreserveNewest" Visible="false" />
51+
<Content Include="$(NuGetPackageRoot)microsoft.ios.templates\$(MicrosoftiOSTemplatesVersion160527)\*.nupkg" Link="testassets\%(Filename)%(Extension)" CopyToOutputDirectory="PreserveNewest" Visible="false" />
4752
<Content Include="$(NuGetPackageRoot)microsoft.net.workload.emscripten.manifest-6.0.200\$(MicrosoftNETWorkloadEmscriptenManifest_60200Version)\*.nupkg" Link="testassets\%(Filename)%(Extension)" CopyToOutputDirectory="PreserveNewest" Visible="false" />
4853
<Content Include="$(NuGetPackageRoot)microsoft.net.workload.emscripten.net6.manifest-8.0.100-preview.6\$(MicrosoftNETWorkloadEmscriptenManifest_80100Preview6Version)\*.nupkg" Link="testassets\%(Filename)%(Extension)" CopyToOutputDirectory="PreserveNewest" Visible="false" />
4954
<Content Include="$(NuGetPackageRoot)microsoft.net.runtime.emscripten.2.0.23.node.win-x64\$(MicrosoftNETRuntimeEmscripten2023Nodewin_x64)\*.nupkg" Link="testassets\%(Filename)%(Extension)" CopyToOutputDirectory="PreserveNewest" Visible="false" />
5055
<Content Include="$(NuGetPackageRoot)microsoft.net.runtime.emscripten.2.0.23.python.win-x64\$(MicrosoftNETRuntimeEmscripten2023Pythonwin_x64)\*.nupkg" Link="testassets\%(Filename)%(Extension)" CopyToOutputDirectory="PreserveNewest" Visible="false" />
5156
<Content Include="$(NuGetPackageRoot)microsoft.net.runtime.emscripten.2.0.23.sdk.win-x64\$(MicrosoftNETRuntimeEmscripten2023Sdkwin_x64)\*.nupkg" Link="testassets\%(Filename)%(Extension)" CopyToOutputDirectory="PreserveNewest" Visible="false" />
57+
<Content Include="$(NuGetPackageRoot)microsoft.net.workloads.9.0.100\$(MicrosoftNETWorkloadBaselineVersion)\*.nupkg" Link="testassets\%(Filename)%(Extension)" CopyToOutputDirectory="PreserveNewest" Visible="false" />
5258
</ItemGroup>
5359

5460
<ItemGroup>

src/Microsoft.DotNet.Build.Tasks.Workloads.Tests/MsiTests.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -104,8 +104,8 @@ public void ItCanBuildATemplatePackMsi()
104104
WorkloadPack p = new(new WorkloadPackId("Microsoft.iOS.Templates"), "15.2.302-preview.14.122", WorkloadPackKind.Template, null);
105105
TemplatePackPackage pkg = new(p, packagePath, new[] { "x64" }, PackageRootDirectory);
106106
pkg.Extract();
107-
WorkloadPackMsi msi = new(pkg, "x64", new MockBuildEngine(), WixToolsetPath, BaseIntermediateOutputPath);
108-
107+
var buildEngine = new MockBuildEngine();
108+
WorkloadPackMsi msi = new(pkg, "x64", buildEngine, WixToolsetPath, BaseIntermediateOutputPath);
109109
ITaskItem item = msi.Build(MsiOutputPath);
110110

111111
string msiPath = item.GetMetadata(Metadata.FullPath);

src/Microsoft.DotNet.Build.Tasks.Workloads.Tests/PackageTests.cs

Lines changed: 27 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,11 @@
22
// The .NET Foundation licenses this file to you under the MIT license.
33

44
using System;
5-
using System.Collections.Generic;
6-
using System.Linq;
7-
using System.Text;
8-
using System.Threading.Tasks;
9-
using Xunit;
10-
using Microsoft.DotNet.Build.Tasks.Workloads;
5+
using System.IO;
6+
using Microsoft.Build.Framework;
117
using Microsoft.Build.Utilities;
128
using Microsoft.Deployment.DotNet.Releases;
13-
using System.IO;
9+
using Xunit;
1410

1511
namespace Microsoft.DotNet.Build.Tasks.Workloads.Tests
1612
{
@@ -22,13 +18,35 @@ public void ItCanReadAManifestPackage()
2218
{
2319
string PackageRootDirectory = Path.Combine(BaseIntermediateOutputPath, "pkg");
2420

25-
TaskItem manifestPackageItem = new(Path.Combine(TestAssetsPath, "microsoft.net.workload.mono.toolchain.manifest-6.0.200.6.0.3.nupkg"));
21+
TaskItem manifestPackageItem = new(Path.Combine(TestAssetsPath, "microsoft.net.workload.mono.toolchain.manifest-6.0.300.6.0.22.nupkg"));
2622
WorkloadManifestPackage p = new(manifestPackageItem, PackageRootDirectory, new Version("1.2.3"));
2723

28-
ReleaseVersion expectedFeatureBand = new("6.0.200");
24+
ReleaseVersion expectedFeatureBand = new("6.0.300");
2925

3026
Assert.Equal("Microsoft.NET.Workload.Mono.ToolChain", p.ManifestId);
3127
Assert.Equal(expectedFeatureBand, p.SdkFeatureBand);
3228
}
29+
30+
[WindowsOnlyTheory]
31+
[InlineData("Microsoft.NET.Workload.Emscripten.net6.Manifest-8.0.100-alpha.1", WorkloadManifestPackage.ManifestSeparator, "8.0.100-alpha.1")]
32+
[InlineData("Microsoft.NET.Workload.Emscripten.Manifest-8.0.100-alpha.1.23062.6", WorkloadManifestPackage.ManifestSeparator, "8.0.100-alpha.1.23062.6")]
33+
[InlineData("Microsoft.NET.Workloads.8.0.100-preview.7.23376.3", WorkloadSetPackage.SdkFeatureBandSeparator, "8.0.100-preview.7.23376.3")]
34+
[InlineData("Microsoft.NET.Workloads.8.0.100", WorkloadSetPackage.SdkFeatureBandSeparator, "8.0.100")]
35+
public static void ItExtractsTheSdkVersionFromThePackageId(string packageId, string separator, string expectedVersion)
36+
{
37+
string actualSdkVersion = WorkloadPackageBase.GetSdkVersion(packageId, separator);
38+
39+
Assert.Equal(expectedVersion, actualSdkVersion);
40+
}
41+
42+
[WindowsOnlyFact]
43+
public void ItThrowsIfTheMsiVersionIsInvalid()
44+
{
45+
string PackageRootDirectory = Path.Combine(BaseIntermediateOutputPath, "wls-pkg");
46+
47+
ITaskItem workloadSetPackageItem = new TaskItem(Path.Combine(TestAssetsPath, "microsoft.net.workloads.9.0.100.9.0.100-baseline.1.23464.1.nupkg"));
48+
49+
Assert.Throws<ArgumentOutOfRangeException>(() => { WorkloadSetPackage p = new(workloadSetPackageItem, PackageRootDirectory, new Version("256.12.3")); });
50+
}
3351
}
3452
}

src/Microsoft.DotNet.Build.Tasks.Workloads.Tests/SwixPackageGroupTests.cs

Lines changed: 7 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,11 @@
22
// The .NET Foundation licenses this file to you under the MIT license.
33

44
using System;
5-
using System.Collections;
65
using System.Collections.Generic;
76
using System.IO;
8-
using Microsoft.Arcade.Test.Common;
97
using Microsoft.Build.Framework;
108
using Microsoft.Build.Utilities;
11-
using Microsoft.Deployment.DotNet.Releases;
12-
using Microsoft.DotNet.Build.Tasks.Workloads.Msi;
139
using Microsoft.DotNet.Build.Tasks.Workloads.Swix;
14-
using Microsoft.NET.Sdk.WorkloadManifestReader;
15-
using NuGet.Packaging.Core;
1610
using Xunit;
1711

1812
namespace Microsoft.DotNet.Build.Tasks.Workloads.Tests
@@ -31,8 +25,9 @@ public void ItGeneratesPackageGroupsForManifestPackages(string manifestPackageFi
3125
string destinationBaseDirectory = Path.Combine(BaseIntermediateOutputPath, destinationDirectory);
3226
TaskItem manifestPackageItem = new(Path.Combine(TestAssetsPath, manifestPackageFilename));
3327
WorkloadManifestPackage manifestPackage = new(manifestPackageItem, destinationBaseDirectory, msiVersion, shortNames, null, isSxS: true);
34-
var packageGroup = SwixPackageGroup.Create(manifestPackage);
35-
var packageGroupItem = PackageGroupSwixProject.CreateProjectItem(packageGroup, BaseIntermediateOutputPath, BaseOutputPath);
28+
var packageGroup = new SwixPackageGroup(manifestPackage);
29+
var packageGroupItem = PackageGroupSwixProject.CreateProjectItem(packageGroup, BaseIntermediateOutputPath, BaseOutputPath,
30+
DefaultValues.PackageTypeManifestPackageGroup);
3631

3732
// Verify package group expectations
3833
Assert.Equal(expectedPackageId, packageGroup.Name);
@@ -45,14 +40,14 @@ public void ItGeneratesPackageGroupsForManifestPackages(string manifestPackageFi
4540

4641
// Verify the task item metadata
4742
Assert.Equal(expectedFeatureBand, packageGroupItem.GetMetadata(Metadata.SdkFeatureBand));
48-
Assert.Equal(DefaultValues.PackageTypePackageGroup, packageGroupItem.GetMetadata(Metadata.PackageType));
43+
Assert.Equal(DefaultValues.PackageTypeManifestPackageGroup, packageGroupItem.GetMetadata(Metadata.PackageType));
4944
}
5045

5146
public static readonly IEnumerable<object[]> PackageGroupData = new List<object[]>
5247
{
53-
new object[] { "microsoft.net.workload.mono.toolchain.manifest-6.0.200.6.0.3.nupkg", "grp1",
54-
new Version("1.2.3"), s_shortNames, "PackageGroup.Mono.ToolChain.Manifest-6.0.200", new Version("1.2.3"),
55-
" vs.dependency id=Mono.ToolChain.Manifest-6.0.200.6.0.3", "6.0.200" },
48+
new object[] { "microsoft.net.workload.mono.toolchain.manifest-6.0.300.6.0.21.nupkg", "grp1",
49+
new Version("1.2.3"), s_shortNames, "PackageGroup.Mono.ToolChain.Manifest-6.0.300", new Version("1.2.3"),
50+
" vs.dependency id=Mono.ToolChain.Manifest-6.0.300.6.0.21", "6.0.300" },
5651
new object[] { "microsoft.net.workload.emscripten.net6.manifest-8.0.100-preview.6.8.0.0-preview.6.23326.2.nupkg", "grp2",
5752
new Version("1.2.3"), s_shortNames, "PackageGroup.Emscripten.net6.Manifest-8.0.100", new Version("1.2.3"),
5853
" vs.dependency id=Emscripten.net6.Manifest-8.0.100-preview.6.8.0.0-preview.6.23326.2", "8.0.100-preview.6" },

0 commit comments

Comments
 (0)