Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for .NET workload sets #14083

Merged
merged 9 commits into from
Oct 20, 2023
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions eng/Versions.props
Original file line number Diff line number Diff line change
Expand Up @@ -50,11 +50,15 @@
<MicrosoftNETRuntimeEmscripten2023Nodewin_x64>6.0.4</MicrosoftNETRuntimeEmscripten2023Nodewin_x64>
<MicrosoftNETRuntimeEmscripten2023Pythonwin_x64>6.0.4</MicrosoftNETRuntimeEmscripten2023Pythonwin_x64>
<MicrosoftNETRuntimeEmscripten2023Sdkwin_x64>6.0.4</MicrosoftNETRuntimeEmscripten2023Sdkwin_x64>
<MicrosoftNETWorkloadBaselineVersion>9.0.100-baseline.1.23464.1</MicrosoftNETWorkloadBaselineVersion>
<MicrosoftNETWorkloadEmscriptenManifest_60200Version>6.0.4</MicrosoftNETWorkloadEmscriptenManifest_60200Version>
<MicrosoftNETWorkloadEmscriptenManifest_80100Preview6Version>8.0.0-preview.6.23326.2</MicrosoftNETWorkloadEmscriptenManifest_80100Preview6Version>
<MicrosoftNETWorkloadMonoToolChainManifest_60200Version>6.0.3</MicrosoftNETWorkloadMonoToolChainManifest_60200Version>
<MicrosoftNETWorkloadMonoToolChainManifest_60200Version_604>6.0.4</MicrosoftNETWorkloadMonoToolChainManifest_60200Version_604>
<MicrosoftNETWorkloadMonoToolChainManifest_60300Version_6021>6.0.21</MicrosoftNETWorkloadMonoToolChainManifest_60300Version_6021>
<MicrosoftNETWorkloadMonoToolChainManifest_60300Version_6022>6.0.22</MicrosoftNETWorkloadMonoToolChainManifest_60300Version_6022>
<MicrosoftiOSTemplatesVersion>15.2.302-preview.14.122</MicrosoftiOSTemplatesVersion>
<MicrosoftiOSTemplatesVersion160527>160527</MicrosoftiOSTemplatesVersion160527>
<SystemCollectionsImmutableVersion>7.0.0</SystemCollectionsImmutableVersion>
<SystemCompositionVersion>7.0.0</SystemCompositionVersion>
<SystemIOPackagingVersion>7.0.0</SystemIOPackagingVersion>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using System.IO;
using System.Linq;
using FluentAssertions;
using Microsoft.Arcade.Test.Common;
using Microsoft.Build.Framework;
using Microsoft.Build.Utilities;
using Microsoft.DotNet.Build.Tasks.Workloads.Msi;
using Xunit;

namespace Microsoft.DotNet.Build.Tasks.Workloads.Tests
{
public class CreateVisualStudioWorkloadSetTests : TestBase
{
[WindowsOnlyFact]
public static void ItCanCreateWorkloadSets()
{
// Create intermediate outputs under %temp% to avoid path issues and make sure it's clean so we don't pick up
// conflicting sources from previous runs.
string baseIntermediateOutputPath = Path.Combine(Path.GetTempPath(), "WLS");

if (Directory.Exists(baseIntermediateOutputPath))
{
Directory.Delete(baseIntermediateOutputPath, recursive: true);
}

ITaskItem[] workloadSetPackages = new[]
{
new TaskItem(Path.Combine(TestAssetsPath, "microsoft.net.workloads.9.0.100.9.0.100-baseline.1.23464.1.nupkg"))
.WithMetadata(Metadata.MsiVersion, "12.8.45")
};

IBuildEngine buildEngine = new MockBuildEngine();

CreateVisualStudioWorkloadSet createWorkloadSetTask = new CreateVisualStudioWorkloadSet()
{
BaseOutputPath = BaseOutputPath,
BaseIntermediateOutputPath = baseIntermediateOutputPath,
BuildEngine = buildEngine,
PackageSource = TestAssetsPath,
WixToolsetPath = WixToolsetPath,
WorkloadSetPackageFiles = workloadSetPackages
};

Assert.True(createWorkloadSetTask.Execute());

// Spot check the x64 generated MSI.
ITaskItem msi = createWorkloadSetTask.Msis.Where(i => i.GetMetadata(Metadata.Platform) == "x64").FirstOrDefault();
Assert.NotNull(msi);

// Verify the workload set records the CLI will use.
MsiUtils.GetAllRegistryKeys(msi.ItemSpec).Should().Contain(r =>
r.Root == 2 &&
r.Key == @"SOFTWARE\Microsoft\dotnet\InstalledWorkloadSets\x64\9.0.100\9.0.100-baseline.1.23464.1" &&
r.Name == "ProductVersion" &&
r.Value == "12.8.45");

// Verify the SWIX authoring for one of the workload set MSIs.
ITaskItem workloadSetSwixItem = createWorkloadSetTask.SwixProjects.Where(s => s.ItemSpec.Contains(@"Microsoft.NET.Workloads.9.0.100.9.0.100-baseline.1.23464.1\x64")).FirstOrDefault();
Assert.Equal(DefaultValues.PackageTypeMsiWorkloadSet, workloadSetSwixItem.GetMetadata(Metadata.PackageType));

string msiSwr = File.ReadAllText(Path.Combine(Path.GetDirectoryName(workloadSetSwixItem.ItemSpec), "msi.swr"));
Assert.Contains("package name=Microsoft.NET.Workloads.9.0.100.9.0.100-baseline.1.23464.1", msiSwr);
Assert.Contains("version=12.8.45", msiSwr);
Assert.DoesNotContain("vs.package.chip=x64", msiSwr);
Assert.Contains("vs.package.machineArch=x64", msiSwr);
Assert.Contains("vs.package.type=msi", msiSwr);

// Verify package group SWIX project
ITaskItem workloadSetPackageGroupSwixItem = createWorkloadSetTask.SwixProjects.Where(
s => s.GetMetadata(Metadata.PackageType).Equals(DefaultValues.PackageTypeWorkloadSetPackageGroup)).
FirstOrDefault();
string packageGroupSwr = File.ReadAllText(Path.Combine(Path.GetDirectoryName(workloadSetPackageGroupSwixItem.ItemSpec), "packageGroup.swr"));
Assert.Contains("package name=PackageGroup.NET.Workloads-9.0.100", packageGroupSwr);
Assert.Contains("vs.dependency id=Microsoft.NET.Workloads.9.0.100.9.0.100-baseline.1.23464.1", packageGroupSwr);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@

namespace Microsoft.DotNet.Build.Tasks.Workloads.Tests
{
[Collection("Workload Creation")]
public class CreateVisualStudioWorkloadTests : TestBase
{
[WindowsOnlyFact]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,15 @@
<ItemGroup>
<PackageDownload Include="Microsoft.Signed.Wix" Version="[$(MicrosoftSignedWixVersion)]" />
<PackageDownload Include="Microsoft.NET.Workload.Mono.ToolChain.Manifest-6.0.200" Version="[$(MicrosoftNETWorkloadMonoToolChainManifest_60200Version)];[$(MicrosoftNETWorkloadMonoToolChainManifest_60200Version_604)]" />
<PackageDownload Include="Microsoft.iOS.Templates" Version="[$(MicrosoftiOSTemplatesVersion)]" />
<PackageDownload Include="Microsoft.NET.Workload.Mono.ToolChain.Manifest-6.0.300" Version="[$(MicrosoftNETWorkloadMonoToolChainManifest_60300Version_6021)];[$(MicrosoftNETWorkloadMonoToolChainManifest_60300Version_6022)]" />
<PackageDownload Include="Microsoft.iOS.Templates" Version="[$(MicrosoftiOSTemplatesVersion)];[$(MicrosoftiOSTemplatesVersion160527)]" />
<PackageDownload Include="Microsoft.NET.Workload.Emscripten.net6.Manifest-8.0.100-preview.6" Version="[$(MicrosoftNETWorkloadEmscriptenManifest_80100Preview6Version)]"/>
<!-- We can only test the task properly by building an actual workload end-to-end. EMSDK is the tiniest one available -->
<PackageDownload Include="Microsoft.NET.Workload.Emscripten.Manifest-6.0.200" Version="[$(MicrosoftNETWorkloadEmscriptenManifest_60200Version)]" />
<PackageDownload Include="Microsoft.NET.Runtime.Emscripten.2.0.23.Node.win-x64" Version="[$(MicrosoftNETRuntimeEmscripten2023Nodewin_x64)]" />
<PackageDownload Include="Microsoft.NET.Runtime.Emscripten.2.0.23.Python.win-x64" Version="[$(MicrosoftNETRuntimeEmscripten2023Pythonwin_x64)]" />
<PackageDownload Include="Microsoft.NET.Runtime.Emscripten.2.0.23.Sdk.win-x64" Version="[$(MicrosoftNETRuntimeEmscripten2023Sdkwin_x64)]" />
<PackageDownload Include="Microsoft.NET.Workloads.9.0.100" Version="[$(MicrosoftNETWorkloadBaselineVersion)]" />
</ItemGroup>

<ItemGroup Condition="'$(TargetFrameworkIdentifier)' == '.NETFramework'">
Expand All @@ -43,12 +45,16 @@
<Content Include="$(NuGetPackageRoot)microsoft.signed.wix\$(MicrosoftSignedWixVersion)\tools\**\*" Link="testassets\wix\%(RecursiveDir)%(Filename)%(Extension)" CopyToOutputDirectory="PreserveNewest" Visible="false" />
<Content Include="$(NuGetPackageRoot)microsoft.net.workload.mono.toolchain.manifest-6.0.200\$(MicrosoftNETWorkloadMonoToolChainManifest_60200Version)\*.nupkg" Link="testassets\%(Filename)%(Extension)" CopyToOutputDirectory="PreserveNewest" Visible="false" />
<Content Include="$(NuGetPackageRoot)microsoft.net.workload.mono.toolchain.manifest-6.0.200\$(MicrosoftNETWorkloadMonoToolChainManifest_60200Version_604)\*.nupkg" Link="testassets\%(Filename)%(Extension)" CopyToOutputDirectory="PreserveNewest" Visible="false" />
<Content Include="$(NuGetPackageRoot)microsoft.net.workload.mono.toolchain.manifest-6.0.300\6.0.22\*.nupkg" Link="testassets\%(Filename)%(Extension)" CopyToOutputDirectory="PreserveNewest" Visible="false" />
<Content Include="$(NuGetPackageRoot)microsoft.net.workload.mono.toolchain.manifest-6.0.300\6.0.21\*.nupkg" Link="testassets\%(Filename)%(Extension)" CopyToOutputDirectory="PreserveNewest" Visible="false" />
<Content Include="$(NuGetPackageRoot)microsoft.ios.templates\$(MicrosoftiOSTemplatesVersion)\*.nupkg" Link="testassets\%(Filename)%(Extension)" CopyToOutputDirectory="PreserveNewest" Visible="false" />
<Content Include="$(NuGetPackageRoot)microsoft.ios.templates\16.0.527\*.nupkg" Link="testassets\%(Filename)%(Extension)" CopyToOutputDirectory="PreserveNewest" Visible="false" />
<Content Include="$(NuGetPackageRoot)microsoft.net.workload.emscripten.manifest-6.0.200\$(MicrosoftNETWorkloadEmscriptenManifest_60200Version)\*.nupkg" Link="testassets\%(Filename)%(Extension)" CopyToOutputDirectory="PreserveNewest" Visible="false" />
<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" />
<Content Include="$(NuGetPackageRoot)microsoft.net.runtime.emscripten.2.0.23.node.win-x64\$(MicrosoftNETRuntimeEmscripten2023Nodewin_x64)\*.nupkg" Link="testassets\%(Filename)%(Extension)" CopyToOutputDirectory="PreserveNewest" Visible="false" />
<Content Include="$(NuGetPackageRoot)microsoft.net.runtime.emscripten.2.0.23.python.win-x64\$(MicrosoftNETRuntimeEmscripten2023Pythonwin_x64)\*.nupkg" Link="testassets\%(Filename)%(Extension)" CopyToOutputDirectory="PreserveNewest" Visible="false" />
<Content Include="$(NuGetPackageRoot)microsoft.net.runtime.emscripten.2.0.23.sdk.win-x64\$(MicrosoftNETRuntimeEmscripten2023Sdkwin_x64)\*.nupkg" Link="testassets\%(Filename)%(Extension)" CopyToOutputDirectory="PreserveNewest" Visible="false" />
<Content Include="$(NuGetPackageRoot)microsoft.net.workloads.9.0.100\9.0.100-baseline.1.23464.1\*.nupkg" Link="testassets\%(Filename)%(Extension)" CopyToOutputDirectory="PreserveNewest" Visible="false" />
joeloff marked this conversation as resolved.
Show resolved Hide resolved
</ItemGroup>

<ItemGroup>
Expand Down
4 changes: 2 additions & 2 deletions src/Microsoft.DotNet.Build.Tasks.Workloads.Tests/MsiTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -104,8 +104,8 @@ public void ItCanBuildATemplatePackMsi()
WorkloadPack p = new(new WorkloadPackId("Microsoft.iOS.Templates"), "15.2.302-preview.14.122", WorkloadPackKind.Template, null);
TemplatePackPackage pkg = new(p, packagePath, new[] { "x64" }, PackageRootDirectory);
pkg.Extract();
WorkloadPackMsi msi = new(pkg, "x64", new MockBuildEngine(), WixToolsetPath, BaseIntermediateOutputPath);

var buildEngine = new MockBuildEngine();
WorkloadPackMsi msi = new(pkg, "x64", buildEngine, WixToolsetPath, BaseIntermediateOutputPath);
ITaskItem item = msi.Build(MsiOutputPath);

string msiPath = item.GetMetadata(Metadata.FullPath);
Expand Down
36 changes: 27 additions & 9 deletions src/Microsoft.DotNet.Build.Tasks.Workloads.Tests/PackageTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,11 @@
// The .NET Foundation licenses this file to you under the MIT license.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Xunit;
using Microsoft.DotNet.Build.Tasks.Workloads;
using System.IO;
using Microsoft.Build.Framework;
using Microsoft.Build.Utilities;
using Microsoft.Deployment.DotNet.Releases;
using System.IO;
using Xunit;

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

TaskItem manifestPackageItem = new(Path.Combine(TestAssetsPath, "microsoft.net.workload.mono.toolchain.manifest-6.0.200.6.0.3.nupkg"));
TaskItem manifestPackageItem = new(Path.Combine(TestAssetsPath, "microsoft.net.workload.mono.toolchain.manifest-6.0.300.6.0.22.nupkg"));
nagilson marked this conversation as resolved.
Show resolved Hide resolved
WorkloadManifestPackage p = new(manifestPackageItem, PackageRootDirectory, new Version("1.2.3"));

ReleaseVersion expectedFeatureBand = new("6.0.200");
ReleaseVersion expectedFeatureBand = new("6.0.300");

Assert.Equal("Microsoft.NET.Workload.Mono.ToolChain", p.ManifestId);
Assert.Equal(expectedFeatureBand, p.SdkFeatureBand);
}

[WindowsOnlyTheory]
[InlineData("Microsoft.NET.Workload.Emscripten.net6.Manifest-8.0.100-alpha.1", WorkloadManifestPackage.ManifestSeparator, "8.0.100-alpha.1")]
[InlineData("Microsoft.NET.Workload.Emscripten.Manifest-8.0.100-alpha.1.23062.6", WorkloadManifestPackage.ManifestSeparator, "8.0.100-alpha.1.23062.6")]
[InlineData("Microsoft.NET.Workloads.8.0.100-preview.7.23376.3", WorkloadSetPackage.SdkFeatureBandSeparator, "8.0.100-preview.7.23376.3")]
[InlineData("Microsoft.NET.Workloads.8.0.100", WorkloadSetPackage.SdkFeatureBandSeparator, "8.0.100")]
public static void ItExtractsTheSdkVersionFromThePackageId(string packageId, string separator, string expectedVersion)
{
string actualSdkVersion = WorkloadPackageBase.GetSdkVersion(packageId, separator);

Assert.Equal(expectedVersion, actualSdkVersion);
}

[WindowsOnlyFact]
public void ItThrowsIfTheMsiVersionIsInvalid()
{
string PackageRootDirectory = Path.Combine(BaseIntermediateOutputPath, "wls-pkg");

ITaskItem workloadSetPackageItem = new TaskItem(Path.Combine(TestAssetsPath, "microsoft.net.workloads.9.0.100.9.0.100-baseline.1.23464.1.nupkg"));

Assert.Throws<ArgumentOutOfRangeException>(() => { WorkloadSetPackage p = new(workloadSetPackageItem, PackageRootDirectory, new Version("256.12.3")); });
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,11 @@
// The .NET Foundation licenses this file to you under the MIT license.

using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using Microsoft.Arcade.Test.Common;
using Microsoft.Build.Framework;
using Microsoft.Build.Utilities;
using Microsoft.Deployment.DotNet.Releases;
using Microsoft.DotNet.Build.Tasks.Workloads.Msi;
using Microsoft.DotNet.Build.Tasks.Workloads.Swix;
using Microsoft.NET.Sdk.WorkloadManifestReader;
using NuGet.Packaging.Core;
using Xunit;

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

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

// Verify the task item metadata
Assert.Equal(expectedFeatureBand, packageGroupItem.GetMetadata(Metadata.SdkFeatureBand));
Assert.Equal(DefaultValues.PackageTypePackageGroup, packageGroupItem.GetMetadata(Metadata.PackageType));
Assert.Equal(DefaultValues.PackageTypeManifestPackageGroup, packageGroupItem.GetMetadata(Metadata.PackageType));
}

public static readonly IEnumerable<object[]> PackageGroupData = new List<object[]>
{
new object[] { "microsoft.net.workload.mono.toolchain.manifest-6.0.200.6.0.3.nupkg", "grp1",
new Version("1.2.3"), s_shortNames, "PackageGroup.Mono.ToolChain.Manifest-6.0.200", new Version("1.2.3"),
" vs.dependency id=Mono.ToolChain.Manifest-6.0.200.6.0.3", "6.0.200" },
new object[] { "microsoft.net.workload.mono.toolchain.manifest-6.0.300.6.0.21.nupkg", "grp1",
new Version("1.2.3"), s_shortNames, "PackageGroup.Mono.ToolChain.Manifest-6.0.300", new Version("1.2.3"),
" vs.dependency id=Mono.ToolChain.Manifest-6.0.300.6.0.21", "6.0.300" },
new object[] { "microsoft.net.workload.emscripten.net6.manifest-8.0.100-preview.6.8.0.0-preview.6.23326.2.nupkg", "grp2",
new Version("1.2.3"), s_shortNames, "PackageGroup.Emscripten.net6.Manifest-8.0.100", new Version("1.2.3"),
" vs.dependency id=Emscripten.net6.Manifest-8.0.100-preview.6.8.0.0-preview.6.23326.2", "8.0.100-preview.6" },
Expand Down
Loading