From 8fcf234e2b4860deb715428f175253ab5c379e45 Mon Sep 17 00:00:00 2001 From: annie <59816815+JL03-Yue@users.noreply.github.com> Date: Fri, 17 Nov 2023 12:38:58 -0800 Subject: [PATCH 001/577] --roll-forward for dotnet tool run for local tools --- .../CommandResolution/MuxerCommandSpecMaker.cs | 14 ++++++++++++-- .../commands/dotnet-tool/run/ToolRunCommand.cs | 3 +-- .../dotnet-tool/run/ToolRunCommandParser.cs | 1 + 3 files changed, 14 insertions(+), 4 deletions(-) diff --git a/src/Cli/dotnet/CommandFactory/CommandResolution/MuxerCommandSpecMaker.cs b/src/Cli/dotnet/CommandFactory/CommandResolution/MuxerCommandSpecMaker.cs index ece94633785c..036ee54278cc 100644 --- a/src/Cli/dotnet/CommandFactory/CommandResolution/MuxerCommandSpecMaker.cs +++ b/src/Cli/dotnet/CommandFactory/CommandResolution/MuxerCommandSpecMaker.cs @@ -20,12 +20,22 @@ internal static CommandSpec CreatePackageCommandSpecUsingMuxer( { throw new Exception(LocalizableStrings.UnableToLocateDotnetMultiplexer); } + IEnumerable modifiedArguments = commandArguments; + + // Add --roll-forward argument first if exists + if (commandArguments.Any(arg => arg.Equals("--roll-forward", StringComparison.OrdinalIgnoreCase))) + { + int index = commandArguments.ToList().IndexOf("--roll-forward"); + arguments.Add(commandArguments.ElementAt(index)); + arguments.Add(commandArguments.ElementAt(index + 1)); + modifiedArguments = commandArguments.Where((element, i) => i != index && i != index + 1); + } arguments.Add(commandPath); - if (commandArguments != null) + if (modifiedArguments != null) { - arguments.AddRange(commandArguments); + arguments.AddRange(modifiedArguments); } return CreateCommandSpec(host, arguments); diff --git a/src/Cli/dotnet/commands/dotnet-tool/run/ToolRunCommand.cs b/src/Cli/dotnet/commands/dotnet-tool/run/ToolRunCommand.cs index bfd5d26a44c6..48ed773d1f83 100644 --- a/src/Cli/dotnet/commands/dotnet-tool/run/ToolRunCommand.cs +++ b/src/Cli/dotnet/commands/dotnet-tool/run/ToolRunCommand.cs @@ -30,9 +30,8 @@ public override int Execute() { // since LocalToolsCommandResolver is a resolver, and all resolver input have dotnet- CommandName = $"dotnet-{_toolCommandName}", - CommandArguments = _forwardArgument + CommandArguments = (_rollForward != null ? new List { "--roll-forward", _rollForward } : Enumerable.Empty()).Concat(_forwardArgument) }); - if (commandspec == null) { throw new GracefulException( diff --git a/src/Cli/dotnet/commands/dotnet-tool/run/ToolRunCommandParser.cs b/src/Cli/dotnet/commands/dotnet-tool/run/ToolRunCommandParser.cs index 8516ff7c2fdb..fb179725e6a7 100644 --- a/src/Cli/dotnet/commands/dotnet-tool/run/ToolRunCommandParser.cs +++ b/src/Cli/dotnet/commands/dotnet-tool/run/ToolRunCommandParser.cs @@ -33,6 +33,7 @@ private static CliCommand ConstructCommand() command.Arguments.Add(CommandNameArgument); command.Arguments.Add(CommandArgument); + command.Options.Add(RollForwardOption); command.SetAction((parseResult) => new ToolRunCommand(parseResult).Execute()); From 0b156847408fc852b3c2a5090ceaf1f34bff10cc Mon Sep 17 00:00:00 2001 From: annie <59816815+JL03-Yue@users.noreply.github.com> Date: Wed, 29 Nov 2023 15:33:13 -0800 Subject: [PATCH 002/577] add roll forward cli option to tool run --- .../dotnet/commands/dotnet-tool/run/LocalizableStrings.resx | 3 +++ src/Cli/dotnet/commands/dotnet-tool/run/ToolRunCommand.cs | 2 ++ .../dotnet/commands/dotnet-tool/run/ToolRunCommandParser.cs | 5 +++++ .../commands/dotnet-tool/run/xlf/LocalizableStrings.cs.xlf | 5 +++++ .../commands/dotnet-tool/run/xlf/LocalizableStrings.de.xlf | 5 +++++ .../commands/dotnet-tool/run/xlf/LocalizableStrings.es.xlf | 5 +++++ .../commands/dotnet-tool/run/xlf/LocalizableStrings.fr.xlf | 5 +++++ .../commands/dotnet-tool/run/xlf/LocalizableStrings.it.xlf | 5 +++++ .../commands/dotnet-tool/run/xlf/LocalizableStrings.ja.xlf | 5 +++++ .../commands/dotnet-tool/run/xlf/LocalizableStrings.ko.xlf | 5 +++++ .../commands/dotnet-tool/run/xlf/LocalizableStrings.pl.xlf | 5 +++++ .../dotnet-tool/run/xlf/LocalizableStrings.pt-BR.xlf | 5 +++++ .../commands/dotnet-tool/run/xlf/LocalizableStrings.ru.xlf | 5 +++++ .../commands/dotnet-tool/run/xlf/LocalizableStrings.tr.xlf | 5 +++++ .../dotnet-tool/run/xlf/LocalizableStrings.zh-Hans.xlf | 5 +++++ .../dotnet-tool/run/xlf/LocalizableStrings.zh-Hant.xlf | 5 +++++ 16 files changed, 75 insertions(+) diff --git a/src/Cli/dotnet/commands/dotnet-tool/run/LocalizableStrings.resx b/src/Cli/dotnet/commands/dotnet-tool/run/LocalizableStrings.resx index 9106b3bbf2e7..7f51ded07454 100644 --- a/src/Cli/dotnet/commands/dotnet-tool/run/LocalizableStrings.resx +++ b/src/Cli/dotnet/commands/dotnet-tool/run/LocalizableStrings.resx @@ -129,6 +129,9 @@ COMMAND_NAME + + Roll forward to framework version (LatestPatch, Minor, LatestMinor, Major, LatestMajor, Disable). + Specify one command name to run. diff --git a/src/Cli/dotnet/commands/dotnet-tool/run/ToolRunCommand.cs b/src/Cli/dotnet/commands/dotnet-tool/run/ToolRunCommand.cs index 48ed773d1f83..9faa69284baf 100644 --- a/src/Cli/dotnet/commands/dotnet-tool/run/ToolRunCommand.cs +++ b/src/Cli/dotnet/commands/dotnet-tool/run/ToolRunCommand.cs @@ -13,6 +13,7 @@ internal class ToolRunCommand : CommandBase private readonly string _toolCommandName; private readonly LocalToolsCommandResolver _localToolsCommandResolver; private readonly IEnumerable _forwardArgument; + private readonly string _rollForward; public ToolRunCommand( ParseResult result, @@ -22,6 +23,7 @@ public ToolRunCommand( _toolCommandName = result.GetValue(ToolRunCommandParser.CommandNameArgument); _forwardArgument = result.GetValue(ToolRunCommandParser.CommandArgument); _localToolsCommandResolver = localToolsCommandResolver ?? new LocalToolsCommandResolver(); + _rollForward = result.GetValue(ToolRunCommandParser.RollForwardOption); } public override int Execute() diff --git a/src/Cli/dotnet/commands/dotnet-tool/run/ToolRunCommandParser.cs b/src/Cli/dotnet/commands/dotnet-tool/run/ToolRunCommandParser.cs index fb179725e6a7..c9c7c51d6327 100644 --- a/src/Cli/dotnet/commands/dotnet-tool/run/ToolRunCommandParser.cs +++ b/src/Cli/dotnet/commands/dotnet-tool/run/ToolRunCommandParser.cs @@ -19,6 +19,11 @@ internal static class ToolRunCommandParser { Description = "arguments forwarded to the tool" }; + + public static readonly CliOption RollForwardOption = new("--roll-forward") + { + Description = LocalizableStrings.RollForwardDescription + }; private static readonly CliCommand Command = ConstructCommand(); diff --git a/src/Cli/dotnet/commands/dotnet-tool/run/xlf/LocalizableStrings.cs.xlf b/src/Cli/dotnet/commands/dotnet-tool/run/xlf/LocalizableStrings.cs.xlf index b4c0873e8fb5..c3b1cbc660ce 100644 --- a/src/Cli/dotnet/commands/dotnet-tool/run/xlf/LocalizableStrings.cs.xlf +++ b/src/Cli/dotnet/commands/dotnet-tool/run/xlf/LocalizableStrings.cs.xlf @@ -22,6 +22,11 @@ COMMAND_NAME + + Roll forward to framework version (LatestPatch, Minor, LatestMinor, Major, LatestMajor, Disable). + Roll forward to framework version (LatestPatch, Minor, LatestMinor, Major, LatestMajor, Disable). + + Specify one command name to run. Zadejte jeden název příkazu, který se má spustit. diff --git a/src/Cli/dotnet/commands/dotnet-tool/run/xlf/LocalizableStrings.de.xlf b/src/Cli/dotnet/commands/dotnet-tool/run/xlf/LocalizableStrings.de.xlf index 8c7b5bacd5af..7988a6605f5d 100644 --- a/src/Cli/dotnet/commands/dotnet-tool/run/xlf/LocalizableStrings.de.xlf +++ b/src/Cli/dotnet/commands/dotnet-tool/run/xlf/LocalizableStrings.de.xlf @@ -22,6 +22,11 @@ COMMAND_NAME + + Roll forward to framework version (LatestPatch, Minor, LatestMinor, Major, LatestMajor, Disable). + Roll forward to framework version (LatestPatch, Minor, LatestMinor, Major, LatestMajor, Disable). + + Specify one command name to run. Geben Sie einen Befehlsnamen für die Ausführung an. diff --git a/src/Cli/dotnet/commands/dotnet-tool/run/xlf/LocalizableStrings.es.xlf b/src/Cli/dotnet/commands/dotnet-tool/run/xlf/LocalizableStrings.es.xlf index c1d1149f4b03..4cdb0eeaaea3 100644 --- a/src/Cli/dotnet/commands/dotnet-tool/run/xlf/LocalizableStrings.es.xlf +++ b/src/Cli/dotnet/commands/dotnet-tool/run/xlf/LocalizableStrings.es.xlf @@ -22,6 +22,11 @@ COMMAND_NAME + + Roll forward to framework version (LatestPatch, Minor, LatestMinor, Major, LatestMajor, Disable). + Roll forward to framework version (LatestPatch, Minor, LatestMinor, Major, LatestMajor, Disable). + + Specify one command name to run. Especifique un nombre de comando para ejecutar. diff --git a/src/Cli/dotnet/commands/dotnet-tool/run/xlf/LocalizableStrings.fr.xlf b/src/Cli/dotnet/commands/dotnet-tool/run/xlf/LocalizableStrings.fr.xlf index 6f5e5ef53655..51002191f317 100644 --- a/src/Cli/dotnet/commands/dotnet-tool/run/xlf/LocalizableStrings.fr.xlf +++ b/src/Cli/dotnet/commands/dotnet-tool/run/xlf/LocalizableStrings.fr.xlf @@ -22,6 +22,11 @@ COMMAND_NAME + + Roll forward to framework version (LatestPatch, Minor, LatestMinor, Major, LatestMajor, Disable). + Roll forward to framework version (LatestPatch, Minor, LatestMinor, Major, LatestMajor, Disable). + + Specify one command name to run. Spécifiez un nom de commande à exécuter. diff --git a/src/Cli/dotnet/commands/dotnet-tool/run/xlf/LocalizableStrings.it.xlf b/src/Cli/dotnet/commands/dotnet-tool/run/xlf/LocalizableStrings.it.xlf index a2c03d42495e..f87a3762a11a 100644 --- a/src/Cli/dotnet/commands/dotnet-tool/run/xlf/LocalizableStrings.it.xlf +++ b/src/Cli/dotnet/commands/dotnet-tool/run/xlf/LocalizableStrings.it.xlf @@ -22,6 +22,11 @@ COMMAND_NAME + + Roll forward to framework version (LatestPatch, Minor, LatestMinor, Major, LatestMajor, Disable). + Roll forward to framework version (LatestPatch, Minor, LatestMinor, Major, LatestMajor, Disable). + + Specify one command name to run. Specificare il nome di un comando da eseguire. diff --git a/src/Cli/dotnet/commands/dotnet-tool/run/xlf/LocalizableStrings.ja.xlf b/src/Cli/dotnet/commands/dotnet-tool/run/xlf/LocalizableStrings.ja.xlf index f3e91c7e6885..9569cc5f4273 100644 --- a/src/Cli/dotnet/commands/dotnet-tool/run/xlf/LocalizableStrings.ja.xlf +++ b/src/Cli/dotnet/commands/dotnet-tool/run/xlf/LocalizableStrings.ja.xlf @@ -22,6 +22,11 @@ COMMAND_NAME + + Roll forward to framework version (LatestPatch, Minor, LatestMinor, Major, LatestMajor, Disable). + Roll forward to framework version (LatestPatch, Minor, LatestMinor, Major, LatestMajor, Disable). + + Specify one command name to run. 実行するコマンド名を 1 つ指定してください。 diff --git a/src/Cli/dotnet/commands/dotnet-tool/run/xlf/LocalizableStrings.ko.xlf b/src/Cli/dotnet/commands/dotnet-tool/run/xlf/LocalizableStrings.ko.xlf index 03225353ab78..aabf61964d20 100644 --- a/src/Cli/dotnet/commands/dotnet-tool/run/xlf/LocalizableStrings.ko.xlf +++ b/src/Cli/dotnet/commands/dotnet-tool/run/xlf/LocalizableStrings.ko.xlf @@ -22,6 +22,11 @@ COMMAND_NAME + + Roll forward to framework version (LatestPatch, Minor, LatestMinor, Major, LatestMajor, Disable). + Roll forward to framework version (LatestPatch, Minor, LatestMinor, Major, LatestMajor, Disable). + + Specify one command name to run. 실행할 명령 이름을 하나 지정하세요. diff --git a/src/Cli/dotnet/commands/dotnet-tool/run/xlf/LocalizableStrings.pl.xlf b/src/Cli/dotnet/commands/dotnet-tool/run/xlf/LocalizableStrings.pl.xlf index ef27cbb0310e..0d17bb665bd2 100644 --- a/src/Cli/dotnet/commands/dotnet-tool/run/xlf/LocalizableStrings.pl.xlf +++ b/src/Cli/dotnet/commands/dotnet-tool/run/xlf/LocalizableStrings.pl.xlf @@ -22,6 +22,11 @@ COMMAND_NAME + + Roll forward to framework version (LatestPatch, Minor, LatestMinor, Major, LatestMajor, Disable). + Roll forward to framework version (LatestPatch, Minor, LatestMinor, Major, LatestMajor, Disable). + + Specify one command name to run. Określ jedną nazwę polecenia do uruchomienia. diff --git a/src/Cli/dotnet/commands/dotnet-tool/run/xlf/LocalizableStrings.pt-BR.xlf b/src/Cli/dotnet/commands/dotnet-tool/run/xlf/LocalizableStrings.pt-BR.xlf index bf18313eded7..21209afaa841 100644 --- a/src/Cli/dotnet/commands/dotnet-tool/run/xlf/LocalizableStrings.pt-BR.xlf +++ b/src/Cli/dotnet/commands/dotnet-tool/run/xlf/LocalizableStrings.pt-BR.xlf @@ -22,6 +22,11 @@ COMMAND_NAME + + Roll forward to framework version (LatestPatch, Minor, LatestMinor, Major, LatestMajor, Disable). + Roll forward to framework version (LatestPatch, Minor, LatestMinor, Major, LatestMajor, Disable). + + Specify one command name to run. Especifique um nome de comando a ser executado. diff --git a/src/Cli/dotnet/commands/dotnet-tool/run/xlf/LocalizableStrings.ru.xlf b/src/Cli/dotnet/commands/dotnet-tool/run/xlf/LocalizableStrings.ru.xlf index 0631bb8546d5..804551d504fb 100644 --- a/src/Cli/dotnet/commands/dotnet-tool/run/xlf/LocalizableStrings.ru.xlf +++ b/src/Cli/dotnet/commands/dotnet-tool/run/xlf/LocalizableStrings.ru.xlf @@ -22,6 +22,11 @@ COMMAND_NAME + + Roll forward to framework version (LatestPatch, Minor, LatestMinor, Major, LatestMajor, Disable). + Roll forward to framework version (LatestPatch, Minor, LatestMinor, Major, LatestMajor, Disable). + + Specify one command name to run. Укажите одно имя выполняемой команды. diff --git a/src/Cli/dotnet/commands/dotnet-tool/run/xlf/LocalizableStrings.tr.xlf b/src/Cli/dotnet/commands/dotnet-tool/run/xlf/LocalizableStrings.tr.xlf index ad2c3f2c68fa..40006845cfa1 100644 --- a/src/Cli/dotnet/commands/dotnet-tool/run/xlf/LocalizableStrings.tr.xlf +++ b/src/Cli/dotnet/commands/dotnet-tool/run/xlf/LocalizableStrings.tr.xlf @@ -22,6 +22,11 @@ COMMAND_NAME + + Roll forward to framework version (LatestPatch, Minor, LatestMinor, Major, LatestMajor, Disable). + Roll forward to framework version (LatestPatch, Minor, LatestMinor, Major, LatestMajor, Disable). + + Specify one command name to run. Çalıştırılacak tek bir komut adı belirtin. diff --git a/src/Cli/dotnet/commands/dotnet-tool/run/xlf/LocalizableStrings.zh-Hans.xlf b/src/Cli/dotnet/commands/dotnet-tool/run/xlf/LocalizableStrings.zh-Hans.xlf index 7b7ffeb2ddac..a07a13b5f987 100644 --- a/src/Cli/dotnet/commands/dotnet-tool/run/xlf/LocalizableStrings.zh-Hans.xlf +++ b/src/Cli/dotnet/commands/dotnet-tool/run/xlf/LocalizableStrings.zh-Hans.xlf @@ -22,6 +22,11 @@ COMMAND_NAME + + Roll forward to framework version (LatestPatch, Minor, LatestMinor, Major, LatestMajor, Disable). + Roll forward to framework version (LatestPatch, Minor, LatestMinor, Major, LatestMajor, Disable). + + Specify one command name to run. 请指定一个要运行的命令名称。 diff --git a/src/Cli/dotnet/commands/dotnet-tool/run/xlf/LocalizableStrings.zh-Hant.xlf b/src/Cli/dotnet/commands/dotnet-tool/run/xlf/LocalizableStrings.zh-Hant.xlf index cea23c4a3b36..fa8e0b729121 100644 --- a/src/Cli/dotnet/commands/dotnet-tool/run/xlf/LocalizableStrings.zh-Hant.xlf +++ b/src/Cli/dotnet/commands/dotnet-tool/run/xlf/LocalizableStrings.zh-Hant.xlf @@ -22,6 +22,11 @@ COMMAND_NAME + + Roll forward to framework version (LatestPatch, Minor, LatestMinor, Major, LatestMajor, Disable). + Roll forward to framework version (LatestPatch, Minor, LatestMinor, Major, LatestMajor, Disable). + + Specify one command name to run. 請指定一個要執行的命令名稱。 From 4bcbd46488d16f178376b1b1478ad38277e260c8 Mon Sep 17 00:00:00 2001 From: annie <59816815+JL03-Yue@users.noreply.github.com> Date: Wed, 29 Nov 2023 15:57:10 -0800 Subject: [PATCH 003/577] fix nonnullable source commandArguments in muxer --- .../CommandFactory/CommandResolution/MuxerCommandSpecMaker.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Cli/dotnet/CommandFactory/CommandResolution/MuxerCommandSpecMaker.cs b/src/Cli/dotnet/CommandFactory/CommandResolution/MuxerCommandSpecMaker.cs index 036ee54278cc..e7120d2aac01 100644 --- a/src/Cli/dotnet/CommandFactory/CommandResolution/MuxerCommandSpecMaker.cs +++ b/src/Cli/dotnet/CommandFactory/CommandResolution/MuxerCommandSpecMaker.cs @@ -23,7 +23,7 @@ internal static CommandSpec CreatePackageCommandSpecUsingMuxer( IEnumerable modifiedArguments = commandArguments; // Add --roll-forward argument first if exists - if (commandArguments.Any(arg => arg.Equals("--roll-forward", StringComparison.OrdinalIgnoreCase))) + if (commandArguments != null && commandArguments.Any(arg => arg.Equals("--roll-forward", StringComparison.OrdinalIgnoreCase))) { int index = commandArguments.ToList().IndexOf("--roll-forward"); arguments.Add(commandArguments.ElementAt(index)); From da7206bbbb605e6f5c8ce6f7683f0cad3719fb42 Mon Sep 17 00:00:00 2001 From: annie <59816815+JL03-Yue@users.noreply.github.com> Date: Wed, 29 Nov 2023 16:28:04 -0800 Subject: [PATCH 004/577] add tool run roll forward test --- .../dotnet-tool/run/ToolRunCommand.cs | 2 +- .../CommandTests/ToolRunCommandTests.cs | 105 ++++++++++++++++++ 2 files changed, 106 insertions(+), 1 deletion(-) create mode 100644 src/Tests/dotnet.Tests/CommandTests/ToolRunCommandTests.cs diff --git a/src/Cli/dotnet/commands/dotnet-tool/run/ToolRunCommand.cs b/src/Cli/dotnet/commands/dotnet-tool/run/ToolRunCommand.cs index 9faa69284baf..a6220dbaedfb 100644 --- a/src/Cli/dotnet/commands/dotnet-tool/run/ToolRunCommand.cs +++ b/src/Cli/dotnet/commands/dotnet-tool/run/ToolRunCommand.cs @@ -13,7 +13,7 @@ internal class ToolRunCommand : CommandBase private readonly string _toolCommandName; private readonly LocalToolsCommandResolver _localToolsCommandResolver; private readonly IEnumerable _forwardArgument; - private readonly string _rollForward; + public readonly string _rollForward; public ToolRunCommand( ParseResult result, diff --git a/src/Tests/dotnet.Tests/CommandTests/ToolRunCommandTests.cs b/src/Tests/dotnet.Tests/CommandTests/ToolRunCommandTests.cs new file mode 100644 index 000000000000..0b93daa1ecfa --- /dev/null +++ b/src/Tests/dotnet.Tests/CommandTests/ToolRunCommandTests.cs @@ -0,0 +1,105 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using Microsoft.DotNet.Cli; +using Microsoft.DotNet.Cli.Utils; +using Microsoft.DotNet.CommandFactory; +using Microsoft.DotNet.InternalAbstractions; +using Microsoft.DotNet.ToolManifest; +using Microsoft.DotNet.ToolPackage; +using Microsoft.DotNet.Tools.Tool.Run; +using Microsoft.Extensions.DependencyModel.Tests; +using Microsoft.Extensions.EnvironmentAbstractions; +using NuGet.Frameworks; +using NuGet.Versioning; + +namespace Microsoft.DotNet.Tests.Commands.Tool +{ + public class ToolRunCommandTests + { + private readonly IFileSystem _fileSystem; + private const string ManifestFilename = "dotnet-tools.json"; + private readonly string _testDirectoryRoot; + private DirectoryPath _nugetGlobalPackagesFolder; + private readonly LocalToolsResolverCache _localToolsResolverCache; + + public ToolRunCommandTests() + { + _fileSystem = new FileSystemMockBuilder().UseCurrentSystemTemporaryDirectory().Build(); + _nugetGlobalPackagesFolder = new DirectoryPath(NuGetGlobalPackagesFolder.GetLocation()); + string temporaryDirectory = _fileSystem.Directory.CreateTemporaryDirectory().DirectoryPath; + _localToolsResolverCache = new LocalToolsResolverCache( + _fileSystem, + new DirectoryPath(Path.Combine(temporaryDirectory, "cache"))); + _testDirectoryRoot = _fileSystem.Directory.CreateTemporaryDirectory().DirectoryPath; + + } + + [Fact] + public void WhenRunWithRollForwardOptionItShouldIncludeRollForwardInNativeHost() + { + var parseResult = Parser.Instance.Parse($"dotnet tool run $TOOLCOMMAND$ --roll-forward Major"); + + var toolRunCommand = new ToolRunCommand( + parseResult); + + (FilePath fakeExecutable, LocalToolsCommandResolver localToolsCommandResolver) = DefaultSetup("dotnet-a"); + IEnumerable testForwardArgument = Enumerable.Empty(); + + var result = localToolsCommandResolver.Resolve(new CommandResolverArguments() + { + CommandName = "dotnet-a", + CommandArguments = (toolRunCommand._rollForward != null ? new List { "--roll-forward", toolRunCommand._rollForward } : Enumerable.Empty()).Concat(testForwardArgument) + }); + + result.Should().NotBeNull(); + result.Args.Should().Contain("--roll-forward", toolRunCommand._rollForward, fakeExecutable.Value); + } + + private (FilePath, LocalToolsCommandResolver) DefaultSetup(string toolCommand) + { + NuGetVersion packageVersionA = NuGetVersion.Parse("1.0.4"); + _fileSystem.File.WriteAllText(Path.Combine(_testDirectoryRoot, ManifestFilename), + _jsonContent.Replace("$TOOLCOMMAND$", toolCommand)); + ToolManifestFinder toolManifest = + new ToolManifestFinder(new DirectoryPath(_testDirectoryRoot), _fileSystem, new FakeDangerousFileDetector()); + ToolCommandName toolCommandNameA = new ToolCommandName(toolCommand); + FilePath fakeExecutable = _nugetGlobalPackagesFolder.WithFile("fakeExecutable.dll"); + _fileSystem.Directory.CreateDirectory(_nugetGlobalPackagesFolder.Value); + _fileSystem.File.CreateEmptyFile(fakeExecutable.Value); + _localToolsResolverCache.Save( + new Dictionary + { + [new RestoredCommandIdentifier( + new PackageId("local.tool.console.a"), + packageVersionA, + NuGetFramework.Parse(BundledTargetFramework.GetTargetFrameworkMoniker()), + Constants.AnyRid, + toolCommandNameA)] + = new RestoredCommand(toolCommandNameA, "dotnet", fakeExecutable) + }); + + var localToolsCommandResolver = new LocalToolsCommandResolver( + toolManifest, + _localToolsResolverCache, + _fileSystem); + + return (fakeExecutable, localToolsCommandResolver); + } + + private string _jsonContent = + @"{ + ""version"":1, + ""isRoot"":true, + ""tools"":{ + ""local.tool.console.a"":{ + ""version"":""1.0.4"", + ""commands"":[ + ""$TOOLCOMMAND$"" + ] + } + } +}"; + + } +} From 9a04a624241dee2c4ddda3e44b1072623445fafa Mon Sep 17 00:00:00 2001 From: annie <59816815+JL03-Yue@users.noreply.github.com> Date: Wed, 29 Nov 2023 16:42:45 -0800 Subject: [PATCH 005/577] add roll-forward options for install command --- .../commands/dotnet-tool/install/LocalizableStrings.resx | 3 +++ .../commands/dotnet-tool/install/ToolInstallCommandParser.cs | 5 +++++ .../dotnet-tool/install/xlf/LocalizableStrings.cs.xlf | 5 +++++ .../dotnet-tool/install/xlf/LocalizableStrings.de.xlf | 5 +++++ .../dotnet-tool/install/xlf/LocalizableStrings.es.xlf | 5 +++++ .../dotnet-tool/install/xlf/LocalizableStrings.fr.xlf | 5 +++++ .../dotnet-tool/install/xlf/LocalizableStrings.it.xlf | 5 +++++ .../dotnet-tool/install/xlf/LocalizableStrings.ja.xlf | 5 +++++ .../dotnet-tool/install/xlf/LocalizableStrings.ko.xlf | 5 +++++ .../dotnet-tool/install/xlf/LocalizableStrings.pl.xlf | 5 +++++ .../dotnet-tool/install/xlf/LocalizableStrings.pt-BR.xlf | 5 +++++ .../dotnet-tool/install/xlf/LocalizableStrings.ru.xlf | 5 +++++ .../dotnet-tool/install/xlf/LocalizableStrings.tr.xlf | 5 +++++ .../dotnet-tool/install/xlf/LocalizableStrings.zh-Hans.xlf | 5 +++++ .../dotnet-tool/install/xlf/LocalizableStrings.zh-Hant.xlf | 5 +++++ 15 files changed, 73 insertions(+) diff --git a/src/Cli/dotnet/commands/dotnet-tool/install/LocalizableStrings.resx b/src/Cli/dotnet/commands/dotnet-tool/install/LocalizableStrings.resx index cf87d1bac6c3..01b57e5d7e60 100644 --- a/src/Cli/dotnet/commands/dotnet-tool/install/LocalizableStrings.resx +++ b/src/Cli/dotnet/commands/dotnet-tool/install/LocalizableStrings.resx @@ -235,4 +235,7 @@ If you would like to create a manifest, use `dotnet new tool-manifest`, usually Create a tool manifest if one isn't found during tool installation. For information on how manifests are located, see https://aka.ms/dotnet/tools/create-manifest-if-needed + + Roll forward to framework version (LatestPatch, Minor, LatestMinor, Major, LatestMajor, Disable). + \ No newline at end of file diff --git a/src/Cli/dotnet/commands/dotnet-tool/install/ToolInstallCommandParser.cs b/src/Cli/dotnet/commands/dotnet-tool/install/ToolInstallCommandParser.cs index 4f79a5a2362e..6515e7faecd5 100644 --- a/src/Cli/dotnet/commands/dotnet-tool/install/ToolInstallCommandParser.cs +++ b/src/Cli/dotnet/commands/dotnet-tool/install/ToolInstallCommandParser.cs @@ -56,6 +56,11 @@ internal static class ToolInstallCommandParser Description = CommonLocalizableStrings.ArchitectureOptionDescription }; + public static readonly CliOption RollForwardOption = new("--roll-forward") + { + Description = LocalizableStrings.RollForwardOptionDescription + }; + public static readonly CliOption GlobalOption = ToolAppliedOption.GlobalOption; public static readonly CliOption LocalOption = ToolAppliedOption.LocalOption; diff --git a/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.cs.xlf b/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.cs.xlf index 1073407eb811..68900b3339c4 100644 --- a/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.cs.xlf +++ b/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.cs.xlf @@ -83,6 +83,11 @@ Pokud chcete vytvořit manifest, použijte příkaz dotnet new tool-manifest, ob Možnosti --prerelease a --version v jednom příkazu se nepodporují. + + Roll forward to framework version (LatestPatch, Minor, LatestMinor, Major, LatestMajor, Disable). + Roll forward to framework version (LatestPatch, Minor, LatestMinor, Major, LatestMajor, Disable). + + The version of the tool package to install. Verze balíčku nástroje, který se má nainstalovat diff --git a/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.de.xlf b/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.de.xlf index 8439dc3b3908..4c3d5448f2f5 100644 --- a/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.de.xlf +++ b/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.de.xlf @@ -83,6 +83,11 @@ Wenn Sie ein Manifest erstellen möchten, verwenden Sie "dotnet new tool-manifes Die Optionen „--prerelease“ und „--version“ werden im gleichen Befehl nicht unterstützt. + + Roll forward to framework version (LatestPatch, Minor, LatestMinor, Major, LatestMajor, Disable). + Roll forward to framework version (LatestPatch, Minor, LatestMinor, Major, LatestMajor, Disable). + + The version of the tool package to install. Die Version des zu installierenden Toolpakets. diff --git a/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.es.xlf b/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.es.xlf index 1bea2d9d6a19..297ac8610d7f 100644 --- a/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.es.xlf +++ b/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.es.xlf @@ -83,6 +83,11 @@ Si desea crear un manifiesto, utilice "dotnet new tool-manifest", normalmente en No se admiten las opciones --prerelease y --version en el mismo comando. + + Roll forward to framework version (LatestPatch, Minor, LatestMinor, Major, LatestMajor, Disable). + Roll forward to framework version (LatestPatch, Minor, LatestMinor, Major, LatestMajor, Disable). + + The version of the tool package to install. La versión del paquete de herramientas para instalar. diff --git a/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.fr.xlf b/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.fr.xlf index 62b5b8ea09b7..67e0d0040128 100644 --- a/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.fr.xlf +++ b/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.fr.xlf @@ -83,6 +83,11 @@ Si vous souhaitez créer un manifeste, utilisez 'dotnet new tool-manifest', gén Les options --prerelease et --version ne sont pas prises en charge dans la même commande. + + Roll forward to framework version (LatestPatch, Minor, LatestMinor, Major, LatestMajor, Disable). + Roll forward to framework version (LatestPatch, Minor, LatestMinor, Major, LatestMajor, Disable). + + The version of the tool package to install. Version du package d'outils à installer. diff --git a/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.it.xlf b/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.it.xlf index 5b79eb906320..a5592da9b387 100644 --- a/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.it.xlf +++ b/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.it.xlf @@ -83,6 +83,11 @@ Se si vuole creare un manifesto, usare `dotnet new tool-manifest`, in genere nel Le opzioni --prerelease e --version non sono supportate nello stesso comando + + Roll forward to framework version (LatestPatch, Minor, LatestMinor, Major, LatestMajor, Disable). + Roll forward to framework version (LatestPatch, Minor, LatestMinor, Major, LatestMajor, Disable). + + The version of the tool package to install. Versione del pacchetto dello strumento da installare. diff --git a/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.ja.xlf b/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.ja.xlf index dc9cbe468dfa..9ade4457ee46 100644 --- a/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.ja.xlf +++ b/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.ja.xlf @@ -83,6 +83,11 @@ If you would like to create a manifest, use `dotnet new tool-manifest`, usually --prerelease および --version オプションは同じコマンド内ではサポートされません + + Roll forward to framework version (LatestPatch, Minor, LatestMinor, Major, LatestMajor, Disable). + Roll forward to framework version (LatestPatch, Minor, LatestMinor, Major, LatestMajor, Disable). + + The version of the tool package to install. インストールするツール パッケージのバージョン。 diff --git a/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.ko.xlf b/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.ko.xlf index 09523ab43bdc..432a77aaca22 100644 --- a/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.ko.xlf +++ b/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.ko.xlf @@ -83,6 +83,11 @@ If you would like to create a manifest, use `dotnet new tool-manifest`, usually --prerelease 및 --version 옵션은 같은 명령에서 지원되지 않습니다 + + Roll forward to framework version (LatestPatch, Minor, LatestMinor, Major, LatestMajor, Disable). + Roll forward to framework version (LatestPatch, Minor, LatestMinor, Major, LatestMajor, Disable). + + The version of the tool package to install. 설치할 도구 패키지 버전입니다. diff --git a/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.pl.xlf b/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.pl.xlf index 76b632ec7f10..90e2c2041534 100644 --- a/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.pl.xlf +++ b/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.pl.xlf @@ -83,6 +83,11 @@ Jeśli chcesz utworzyć manifest, użyj polecenia „dotnet new tool-manifest” Opcje --prerelease i --version nie są obsługiwane w tym samym poleceniu + + Roll forward to framework version (LatestPatch, Minor, LatestMinor, Major, LatestMajor, Disable). + Roll forward to framework version (LatestPatch, Minor, LatestMinor, Major, LatestMajor, Disable). + + The version of the tool package to install. Wersja pakietu narzędzia do zainstalowania. diff --git a/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.pt-BR.xlf b/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.pt-BR.xlf index 7392c799046c..584281d4be93 100644 --- a/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.pt-BR.xlf +++ b/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.pt-BR.xlf @@ -83,6 +83,11 @@ Se quiser criar um manifesto, use `dotnet new tool-manifest`, normalmente no dir Não há suporte para as opções --prerelease e --version no mesmo comando. + + Roll forward to framework version (LatestPatch, Minor, LatestMinor, Major, LatestMajor, Disable). + Roll forward to framework version (LatestPatch, Minor, LatestMinor, Major, LatestMajor, Disable). + + The version of the tool package to install. A versão do pacote da ferramenta a ser instalada. diff --git a/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.ru.xlf b/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.ru.xlf index 94c8bd4d3f22..346355c70d69 100644 --- a/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.ru.xlf +++ b/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.ru.xlf @@ -83,6 +83,11 @@ If you would like to create a manifest, use `dotnet new tool-manifest`, usually Параметры --prerelease и --version не поддерживаются в одной и той же команде + + Roll forward to framework version (LatestPatch, Minor, LatestMinor, Major, LatestMajor, Disable). + Roll forward to framework version (LatestPatch, Minor, LatestMinor, Major, LatestMajor, Disable). + + The version of the tool package to install. Версия устанавливаемого пакета инструмента. diff --git a/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.tr.xlf b/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.tr.xlf index 6977fd232503..5252e7bf92cc 100644 --- a/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.tr.xlf +++ b/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.tr.xlf @@ -83,6 +83,11 @@ Bir bildirim oluşturmak istiyorsanız 'dotnet new tool-manifest' ifadesini kull --prerelease ve --version seçenekleri aynı komutta desteklenmiyor + + Roll forward to framework version (LatestPatch, Minor, LatestMinor, Major, LatestMajor, Disable). + Roll forward to framework version (LatestPatch, Minor, LatestMinor, Major, LatestMajor, Disable). + + The version of the tool package to install. Yüklenecek araç paketinin sürümü. diff --git a/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.zh-Hans.xlf b/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.zh-Hans.xlf index 1687123d06da..77e1ecc77fc7 100644 --- a/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.zh-Hans.xlf +++ b/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.zh-Hans.xlf @@ -83,6 +83,11 @@ If you would like to create a manifest, use `dotnet new tool-manifest`, usually 不支持在同一命令中同时使用 --prerelease 和 --version 选项 + + Roll forward to framework version (LatestPatch, Minor, LatestMinor, Major, LatestMajor, Disable). + Roll forward to framework version (LatestPatch, Minor, LatestMinor, Major, LatestMajor, Disable). + + The version of the tool package to install. 要安装的工具包版本。 diff --git a/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.zh-Hant.xlf b/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.zh-Hant.xlf index 23b08414bf46..f3db8875cf83 100644 --- a/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.zh-Hant.xlf +++ b/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.zh-Hant.xlf @@ -83,6 +83,11 @@ If you would like to create a manifest, use `dotnet new tool-manifest`, usually 同一個命令中不支援 --prerelease 與 --version 選項 + + Roll forward to framework version (LatestPatch, Minor, LatestMinor, Major, LatestMajor, Disable). + Roll forward to framework version (LatestPatch, Minor, LatestMinor, Major, LatestMajor, Disable). + + The version of the tool package to install. 要安裝之工具套件的版本。 From 171306bcef9de46f4643f374199a01c4ea927eed Mon Sep 17 00:00:00 2001 From: annie <59816815+JL03-Yue@users.noreply.github.com> Date: Wed, 29 Nov 2023 16:45:38 -0800 Subject: [PATCH 006/577] parse roll forward for global tools --- .../dotnet-tool/install/ToolInstallGlobalOrToolPathCommand.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/Cli/dotnet/commands/dotnet-tool/install/ToolInstallGlobalOrToolPathCommand.cs b/src/Cli/dotnet/commands/dotnet-tool/install/ToolInstallGlobalOrToolPathCommand.cs index a9cbfe8d1a63..60e2f510c19e 100644 --- a/src/Cli/dotnet/commands/dotnet-tool/install/ToolInstallGlobalOrToolPathCommand.cs +++ b/src/Cli/dotnet/commands/dotnet-tool/install/ToolInstallGlobalOrToolPathCommand.cs @@ -43,6 +43,7 @@ internal class ToolInstallGlobalOrToolPathCommand : CommandBase private readonly string _toolPath; private readonly string _architectureOption; private IEnumerable _forwardRestoreArguments; + private readonly bool _rollForward; public ToolInstallGlobalOrToolPathCommand( ParseResult parseResult, @@ -80,6 +81,7 @@ public ToolInstallGlobalOrToolPathCommand( Interactive: parseResult.GetValue(ToolCommandRestorePassThroughOptions.InteractiveRestoreOption)); nugetPackageDownloader ??= new NuGetPackageDownloader(tempDir, verboseLogger: new NullLogger(), restoreActionConfig: restoreAction); _shellShimTemplateFinder = new ShellShimTemplateFinder(nugetPackageDownloader, tempDir, packageSourceLocation); + _rollForward = parseResult.GetValue(ToolInstallCommandParser.RollForwardOption); _reporter = (reporter ?? Reporter.Output); _errorReporter = (reporter ?? Reporter.Error); From 458b7d2ba5e36f465ea364d648603952801d7aea Mon Sep 17 00:00:00 2001 From: annie <59816815+JL03-Yue@users.noreply.github.com> Date: Wed, 29 Nov 2023 16:50:32 -0800 Subject: [PATCH 007/577] pass in the parse result --- src/Cli/dotnet/ToolPackage/IToolPackageDownloader.cs | 3 ++- src/Cli/dotnet/ToolPackage/ToolPackageDownloader.cs | 7 ++++++- .../install/ToolInstallGlobalOrToolPathCommand.cs | 3 ++- .../ToolPackageDownloaderMock.cs | 3 ++- 4 files changed, 12 insertions(+), 4 deletions(-) diff --git a/src/Cli/dotnet/ToolPackage/IToolPackageDownloader.cs b/src/Cli/dotnet/ToolPackage/IToolPackageDownloader.cs index 816ead4cdf73..fab2387858f3 100644 --- a/src/Cli/dotnet/ToolPackage/IToolPackageDownloader.cs +++ b/src/Cli/dotnet/ToolPackage/IToolPackageDownloader.cs @@ -13,7 +13,8 @@ IToolPackage InstallPackage(PackageLocation packageLocation, PackageId packageId VerbosityOptions verbosity, VersionRange versionRange = null, string targetFramework = null, - bool isGlobalTool = false + bool isGlobalTool = false, + bool globalToolRollForward = false ); } } diff --git a/src/Cli/dotnet/ToolPackage/ToolPackageDownloader.cs b/src/Cli/dotnet/ToolPackage/ToolPackageDownloader.cs index be97e3937ab0..77f8d7a8604c 100644 --- a/src/Cli/dotnet/ToolPackage/ToolPackageDownloader.cs +++ b/src/Cli/dotnet/ToolPackage/ToolPackageDownloader.cs @@ -27,6 +27,10 @@ using NuGet.Versioning; using NuGet.Configuration; using Microsoft.TemplateEngine.Utils; +using System.Text.Json; +using System.Xml; +using System.Text.Json.Nodes; +using Newtonsoft.Json.Linq; namespace Microsoft.DotNet.Cli.ToolPackage { @@ -72,7 +76,8 @@ public IToolPackage InstallPackage(PackageLocation packageLocation, PackageId pa VerbosityOptions verbosity = VerbosityOptions.normal, VersionRange versionRange = null, string targetFramework = null, - bool isGlobalTool = false + bool isGlobalTool = false, + bool globalToolRollForward = false ) { var packageRootDirectory = _toolPackageStore.GetRootPackageDirectory(packageId); diff --git a/src/Cli/dotnet/commands/dotnet-tool/install/ToolInstallGlobalOrToolPathCommand.cs b/src/Cli/dotnet/commands/dotnet-tool/install/ToolInstallGlobalOrToolPathCommand.cs index 60e2f510c19e..9e470c1dd36b 100644 --- a/src/Cli/dotnet/commands/dotnet-tool/install/ToolInstallGlobalOrToolPathCommand.cs +++ b/src/Cli/dotnet/commands/dotnet-tool/install/ToolInstallGlobalOrToolPathCommand.cs @@ -134,7 +134,8 @@ public override int Execute() versionRange: versionRange, targetFramework: _framework, verbosity: _verbosity, - isGlobalTool: true + isGlobalTool: true, + globalToolRollForward: _rollForward ); NuGetFramework framework; diff --git a/src/Tests/Microsoft.DotNet.Tools.Tests.ComponentMocks/ToolPackageDownloaderMock.cs b/src/Tests/Microsoft.DotNet.Tools.Tests.ComponentMocks/ToolPackageDownloaderMock.cs index 8ce41aef115d..f9ce1331c90e 100644 --- a/src/Tests/Microsoft.DotNet.Tools.Tests.ComponentMocks/ToolPackageDownloaderMock.cs +++ b/src/Tests/Microsoft.DotNet.Tools.Tests.ComponentMocks/ToolPackageDownloaderMock.cs @@ -96,7 +96,8 @@ public IToolPackage InstallPackage(PackageLocation packageLocation, PackageId pa VerbosityOptions verbosity, VersionRange versionRange = null, string targetFramework = null, - bool isGlobalTool = false + bool isGlobalTool = false, + bool globalToolRollForward = false ) { string rollbackDirectory = null; From 3790495d812297267181e9f761a12802541ca777 Mon Sep 17 00:00:00 2001 From: annie <59816815+JL03-Yue@users.noreply.github.com> Date: Wed, 29 Nov 2023 16:57:37 -0800 Subject: [PATCH 008/577] skeleton for update runtime config for global tool --- .../ToolPackage/IToolPackageDownloader.cs | 2 +- .../dotnet/ToolPackage/ToolPackageDownloader.cs | 17 ++++++++++++++++- .../ToolInstallGlobalOrToolPathCommand.cs | 2 +- .../ToolPackageDownloaderMock.cs | 2 +- 4 files changed, 19 insertions(+), 4 deletions(-) diff --git a/src/Cli/dotnet/ToolPackage/IToolPackageDownloader.cs b/src/Cli/dotnet/ToolPackage/IToolPackageDownloader.cs index fab2387858f3..87c810b2f51e 100644 --- a/src/Cli/dotnet/ToolPackage/IToolPackageDownloader.cs +++ b/src/Cli/dotnet/ToolPackage/IToolPackageDownloader.cs @@ -14,7 +14,7 @@ IToolPackage InstallPackage(PackageLocation packageLocation, PackageId packageId VersionRange versionRange = null, string targetFramework = null, bool isGlobalTool = false, - bool globalToolRollForward = false + bool isGlobalToolRollForward = false ); } } diff --git a/src/Cli/dotnet/ToolPackage/ToolPackageDownloader.cs b/src/Cli/dotnet/ToolPackage/ToolPackageDownloader.cs index 77f8d7a8604c..11c6527f35d8 100644 --- a/src/Cli/dotnet/ToolPackage/ToolPackageDownloader.cs +++ b/src/Cli/dotnet/ToolPackage/ToolPackageDownloader.cs @@ -77,7 +77,7 @@ public IToolPackage InstallPackage(PackageLocation packageLocation, PackageId pa VersionRange versionRange = null, string targetFramework = null, bool isGlobalTool = false, - bool globalToolRollForward = false + bool isGlobalToolRollForward = false ) { var packageRootDirectory = _toolPackageStore.GetRootPackageDirectory(packageId); @@ -145,6 +145,11 @@ public IToolPackage InstallPackage(PackageLocation packageLocation, PackageId pa CreateAssetFile(packageId, packageVersion, toolDownloadDir, assetFileDirectory, _runtimeJsonPath, targetFramework); + if (isGlobalToolRollForward) + { + UpdateRuntimeConfig(packageId, packageVersion, toolDownloadDir); + } + DirectoryPath toolReturnPackageDirectory; DirectoryPath toolReturnJsonParentDirectory; @@ -198,6 +203,16 @@ private static void AddToolsAssets( lockFileLib.ToolsAssemblies.AddRange(toolsGroup); } + private static void UpdateRuntimeConfig( + PackageId packageId, + NuGetVersion packageVersion, + DirectoryPath toolDownloadDir + ) + { + + + } + private static IEnumerable GetLockFileItems( IReadOnlyList criteria, ContentItemCollection items, diff --git a/src/Cli/dotnet/commands/dotnet-tool/install/ToolInstallGlobalOrToolPathCommand.cs b/src/Cli/dotnet/commands/dotnet-tool/install/ToolInstallGlobalOrToolPathCommand.cs index 9e470c1dd36b..3875016dcafb 100644 --- a/src/Cli/dotnet/commands/dotnet-tool/install/ToolInstallGlobalOrToolPathCommand.cs +++ b/src/Cli/dotnet/commands/dotnet-tool/install/ToolInstallGlobalOrToolPathCommand.cs @@ -135,7 +135,7 @@ public override int Execute() targetFramework: _framework, verbosity: _verbosity, isGlobalTool: true, - globalToolRollForward: _rollForward + isGlobalToolRollForward: _rollForward ); NuGetFramework framework; diff --git a/src/Tests/Microsoft.DotNet.Tools.Tests.ComponentMocks/ToolPackageDownloaderMock.cs b/src/Tests/Microsoft.DotNet.Tools.Tests.ComponentMocks/ToolPackageDownloaderMock.cs index f9ce1331c90e..f787d1c2415b 100644 --- a/src/Tests/Microsoft.DotNet.Tools.Tests.ComponentMocks/ToolPackageDownloaderMock.cs +++ b/src/Tests/Microsoft.DotNet.Tools.Tests.ComponentMocks/ToolPackageDownloaderMock.cs @@ -97,7 +97,7 @@ public IToolPackage InstallPackage(PackageLocation packageLocation, PackageId pa VersionRange versionRange = null, string targetFramework = null, bool isGlobalTool = false, - bool globalToolRollForward = false + bool isGlobalToolRollForward = false ) { string rollbackDirectory = null; From 6bcf9fde1ebd495a738b7786fd04b7f6afbc152b Mon Sep 17 00:00:00 2001 From: annie <59816815+JL03-Yue@users.noreply.github.com> Date: Wed, 29 Nov 2023 17:11:05 -0800 Subject: [PATCH 009/577] add CliOption --- .../commands/dotnet-tool/install/ToolInstallCommandParser.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Cli/dotnet/commands/dotnet-tool/install/ToolInstallCommandParser.cs b/src/Cli/dotnet/commands/dotnet-tool/install/ToolInstallCommandParser.cs index 6515e7faecd5..9a6f2d915d9c 100644 --- a/src/Cli/dotnet/commands/dotnet-tool/install/ToolInstallCommandParser.cs +++ b/src/Cli/dotnet/commands/dotnet-tool/install/ToolInstallCommandParser.cs @@ -99,6 +99,7 @@ private static CliCommand ConstructCommand() command.Options.Add(VerbosityOption); command.Options.Add(ArchitectureOption); command.Options.Add(CreateManifestIfNeededOption); + command.Options.Add(RollForwardOption); command.SetAction((parseResult) => new ToolInstallCommand(parseResult).Execute()); From 4cb55034da6f6332278bcf7e039250b04da614cf Mon Sep 17 00:00:00 2001 From: annie <59816815+JL03-Yue@users.noreply.github.com> Date: Wed, 29 Nov 2023 17:32:31 -0800 Subject: [PATCH 010/577] draft for global tool roll forward --- .../ToolPackage/ToolPackageDownloader.cs | 49 ++++++++++++++++++- 1 file changed, 48 insertions(+), 1 deletion(-) diff --git a/src/Cli/dotnet/ToolPackage/ToolPackageDownloader.cs b/src/Cli/dotnet/ToolPackage/ToolPackageDownloader.cs index 11c6527f35d8..e9474738989e 100644 --- a/src/Cli/dotnet/ToolPackage/ToolPackageDownloader.cs +++ b/src/Cli/dotnet/ToolPackage/ToolPackageDownloader.cs @@ -209,8 +209,55 @@ private static void UpdateRuntimeConfig( DirectoryPath toolDownloadDir ) { - + var toolsDirectory = Path.Combine(toolDownloadDir.ToString().Trim('"'), packageId.ToString(), packageVersion.ToString(), "tools"); + + // TBD: if roll forward all frameworks + string[] subDirectories = Directory.GetDirectories(toolsDirectory); + foreach (string subDirectory in subDirectories) + { + UpdateRuntimeConfigFile(toolsDirectory, subDirectory); + } + } + + private static void UpdateRuntimeConfigFile( + string toolsDir, + string frameworkDir + ) + { + // Get the setting file + var settingFilePath = Path.Combine(toolsDir, frameworkDir, "any", "DotnetToolSettings.xml"); + if (!File.Exists(settingFilePath)) + { + // TBD + throw new Exception(); + } + // Get runtimeConfig file + string runtimeConfigFileFolder = null; + XDocument dotnetToolSettings = XDocument.Load(settingFilePath); + XElement commandElement = dotnetToolSettings.Descendants("Command").FirstOrDefault(); + if (commandElement != null) + { + XAttribute entryPointAttribute = commandElement.Attribute("EntryPoint"); + if (entryPointAttribute != null) + { + runtimeConfigFileFolder = entryPointAttribute.Value; + } + } + + var runtimeConfigFilePath = $"{Path.GetFileNameWithoutExtension(runtimeConfigFileFolder)}{".runtimeconfig.json"}"; + + // Update the runtimeconfig.json file + string existingJson = File.ReadAllText(runtimeConfigFilePath); + + var jsonObject = JObject.Parse(existingJson); + var runtimeOptions = jsonObject["runtimeOptions"] as JObject; + if (runtimeOptions != null) + { + runtimeOptions["rollForward"] = "LatestMajor"; + string updateJson = jsonObject.ToString(); + File.WriteAllText(runtimeConfigFilePath, updateJson); + } } private static IEnumerable GetLockFileItems( From ef927acbc897a5958256de218681b899dc5e23bc Mon Sep 17 00:00:00 2001 From: annie <59816815+JL03-Yue@users.noreply.github.com> Date: Wed, 29 Nov 2023 20:26:46 -0800 Subject: [PATCH 011/577] fix path errors in global tool roll forward --- src/Cli/dotnet/ToolPackage/ToolPackageDownloader.cs | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/Cli/dotnet/ToolPackage/ToolPackageDownloader.cs b/src/Cli/dotnet/ToolPackage/ToolPackageDownloader.cs index e9474738989e..6a45d8e34352 100644 --- a/src/Cli/dotnet/ToolPackage/ToolPackageDownloader.cs +++ b/src/Cli/dotnet/ToolPackage/ToolPackageDownloader.cs @@ -215,17 +215,16 @@ DirectoryPath toolDownloadDir string[] subDirectories = Directory.GetDirectories(toolsDirectory); foreach (string subDirectory in subDirectories) { - UpdateRuntimeConfigFile(toolsDirectory, subDirectory); + UpdateRuntimeConfigFile(subDirectory); } } private static void UpdateRuntimeConfigFile( - string toolsDir, string frameworkDir ) { // Get the setting file - var settingFilePath = Path.Combine(toolsDir, frameworkDir, "any", "DotnetToolSettings.xml"); + var settingFilePath = Path.Combine(frameworkDir, "any", "DotnetToolSettings.xml"); if (!File.Exists(settingFilePath)) { // TBD @@ -245,7 +244,7 @@ string frameworkDir } } - var runtimeConfigFilePath = $"{Path.GetFileNameWithoutExtension(runtimeConfigFileFolder)}{".runtimeconfig.json"}"; + var runtimeConfigFilePath = Path.Combine(Path.GetDirectoryName(settingFilePath), $"{Path.GetFileNameWithoutExtension(runtimeConfigFileFolder)}{".runtimeconfig.json"}"); // Update the runtimeconfig.json file string existingJson = File.ReadAllText(runtimeConfigFilePath); From 80d4d0039d7bf4e8721e68c0ad12c563f20059fd Mon Sep 17 00:00:00 2001 From: annie <59816815+JL03-Yue@users.noreply.github.com> Date: Wed, 29 Nov 2023 20:42:03 -0800 Subject: [PATCH 012/577] add exception for setting files not found --- src/Cli/dotnet/CommonLocalizableStrings.resx | 3 +++ src/Cli/dotnet/ToolPackage/ToolPackageDownloader.cs | 12 ++++++++---- src/Cli/dotnet/xlf/CommonLocalizableStrings.cs.xlf | 5 +++++ src/Cli/dotnet/xlf/CommonLocalizableStrings.de.xlf | 5 +++++ src/Cli/dotnet/xlf/CommonLocalizableStrings.es.xlf | 5 +++++ src/Cli/dotnet/xlf/CommonLocalizableStrings.fr.xlf | 5 +++++ src/Cli/dotnet/xlf/CommonLocalizableStrings.it.xlf | 5 +++++ src/Cli/dotnet/xlf/CommonLocalizableStrings.ja.xlf | 5 +++++ src/Cli/dotnet/xlf/CommonLocalizableStrings.ko.xlf | 5 +++++ src/Cli/dotnet/xlf/CommonLocalizableStrings.pl.xlf | 5 +++++ .../dotnet/xlf/CommonLocalizableStrings.pt-BR.xlf | 5 +++++ src/Cli/dotnet/xlf/CommonLocalizableStrings.ru.xlf | 5 +++++ src/Cli/dotnet/xlf/CommonLocalizableStrings.tr.xlf | 5 +++++ .../dotnet/xlf/CommonLocalizableStrings.zh-Hans.xlf | 5 +++++ .../dotnet/xlf/CommonLocalizableStrings.zh-Hant.xlf | 5 +++++ 15 files changed, 76 insertions(+), 4 deletions(-) diff --git a/src/Cli/dotnet/CommonLocalizableStrings.resx b/src/Cli/dotnet/CommonLocalizableStrings.resx index 50e7a04745ef..58c9371ccd01 100644 --- a/src/Cli/dotnet/CommonLocalizableStrings.resx +++ b/src/Cli/dotnet/CommonLocalizableStrings.resx @@ -733,4 +733,7 @@ The default is 'false.' However, when targeting .NET 7 or lower, the default is ARTIFACTS_DIR + + Tool settings file does not exist for the tool {0}. + diff --git a/src/Cli/dotnet/ToolPackage/ToolPackageDownloader.cs b/src/Cli/dotnet/ToolPackage/ToolPackageDownloader.cs index 6a45d8e34352..28a8c916abef 100644 --- a/src/Cli/dotnet/ToolPackage/ToolPackageDownloader.cs +++ b/src/Cli/dotnet/ToolPackage/ToolPackageDownloader.cs @@ -215,20 +215,24 @@ DirectoryPath toolDownloadDir string[] subDirectories = Directory.GetDirectories(toolsDirectory); foreach (string subDirectory in subDirectories) { - UpdateRuntimeConfigFile(subDirectory); + UpdateRuntimeConfigFile(subDirectory, packageId); } } private static void UpdateRuntimeConfigFile( - string frameworkDir + string frameworkDir, + PackageId packageId ) { // Get the setting file var settingFilePath = Path.Combine(frameworkDir, "any", "DotnetToolSettings.xml"); if (!File.Exists(settingFilePath)) { - // TBD - throw new Exception(); + throw new ToolPackageException( + string.Format( + CommonLocalizableStrings.ToolSettingsNotFound, + packageId + )); } // Get runtimeConfig file diff --git a/src/Cli/dotnet/xlf/CommonLocalizableStrings.cs.xlf b/src/Cli/dotnet/xlf/CommonLocalizableStrings.cs.xlf index f7bdb5ac0171..4a67e47ab729 100644 --- a/src/Cli/dotnet/xlf/CommonLocalizableStrings.cs.xlf +++ b/src/Cli/dotnet/xlf/CommonLocalizableStrings.cs.xlf @@ -282,6 +282,11 @@ Výchozí hodnota je false, ale pokud cílíte na .NET 7 nebo nižší a je zad Řešení {0} již obsahuje projekt {1} ve složce řešení {2}. + + Tool settings file does not exist for the tool {0}. + Tool settings file does not exist for the tool {0}. + + Update Aktualizovat diff --git a/src/Cli/dotnet/xlf/CommonLocalizableStrings.de.xlf b/src/Cli/dotnet/xlf/CommonLocalizableStrings.de.xlf index 1defd573463a..db52457f42b7 100644 --- a/src/Cli/dotnet/xlf/CommonLocalizableStrings.de.xlf +++ b/src/Cli/dotnet/xlf/CommonLocalizableStrings.de.xlf @@ -282,6 +282,11 @@ Der Standardwert lautet FALSE. Wenn sie jedoch auf .NET 7 oder niedriger abziele Die Projektmappe "{0}" enthält bereits das Projekt "{1}" im Projektmappenordner "{2}". + + Tool settings file does not exist for the tool {0}. + Tool settings file does not exist for the tool {0}. + + Update Aktualisieren diff --git a/src/Cli/dotnet/xlf/CommonLocalizableStrings.es.xlf b/src/Cli/dotnet/xlf/CommonLocalizableStrings.es.xlf index 3cea6479154f..cd76474d7e78 100644 --- a/src/Cli/dotnet/xlf/CommonLocalizableStrings.es.xlf +++ b/src/Cli/dotnet/xlf/CommonLocalizableStrings.es.xlf @@ -283,6 +283,11 @@ El valor predeterminado es "false". Sin embargo, cuando el destino es .NET 7 o i La solución {0} ya contiene el proyecto {1} en la carpeta {2}de la solución. + + Tool settings file does not exist for the tool {0}. + Tool settings file does not exist for the tool {0}. + + Update Actualizar diff --git a/src/Cli/dotnet/xlf/CommonLocalizableStrings.fr.xlf b/src/Cli/dotnet/xlf/CommonLocalizableStrings.fr.xlf index ba4e05a9f6cf..b036db8acb25 100644 --- a/src/Cli/dotnet/xlf/CommonLocalizableStrings.fr.xlf +++ b/src/Cli/dotnet/xlf/CommonLocalizableStrings.fr.xlf @@ -283,6 +283,11 @@ La valeur par défaut est « false ». Toutefois, lorsque vous ciblez .NET 7 ou La solution {0} contient déjà le projet {1} dans le dossier de la solution {2}. + + Tool settings file does not exist for the tool {0}. + Tool settings file does not exist for the tool {0}. + + Update Mettre à jour diff --git a/src/Cli/dotnet/xlf/CommonLocalizableStrings.it.xlf b/src/Cli/dotnet/xlf/CommonLocalizableStrings.it.xlf index 07944103ece3..1030fce6f280 100644 --- a/src/Cli/dotnet/xlf/CommonLocalizableStrings.it.xlf +++ b/src/Cli/dotnet/xlf/CommonLocalizableStrings.it.xlf @@ -282,6 +282,11 @@ Il valore predefinito è 'false'. Tuttavia, quando la destinazione è .NET 7 o u La soluzione {0} contiene già {1} di progetto nella cartella della soluzione {2}. + + Tool settings file does not exist for the tool {0}. + Tool settings file does not exist for the tool {0}. + + Update Aggiorna diff --git a/src/Cli/dotnet/xlf/CommonLocalizableStrings.ja.xlf b/src/Cli/dotnet/xlf/CommonLocalizableStrings.ja.xlf index d0aa6925f528..c6a3c4b3940b 100644 --- a/src/Cli/dotnet/xlf/CommonLocalizableStrings.ja.xlf +++ b/src/Cli/dotnet/xlf/CommonLocalizableStrings.ja.xlf @@ -282,6 +282,11 @@ The default is 'false.' However, when targeting .NET 7 or lower, the default is ソリューション {0} のソリューション フォルダー {2} 内にプロジェクト {1} が既に含まれています。 + + Tool settings file does not exist for the tool {0}. + Tool settings file does not exist for the tool {0}. + + Update 更新 diff --git a/src/Cli/dotnet/xlf/CommonLocalizableStrings.ko.xlf b/src/Cli/dotnet/xlf/CommonLocalizableStrings.ko.xlf index c5e95e77e0d8..00275492059d 100644 --- a/src/Cli/dotnet/xlf/CommonLocalizableStrings.ko.xlf +++ b/src/Cli/dotnet/xlf/CommonLocalizableStrings.ko.xlf @@ -283,6 +283,11 @@ The default is 'false.' However, when targeting .NET 7 or lower, the default is {0} 솔루션은 {2} 솔루션 폴더에 {1} 프로젝트를 이미 포함합니다. + + Tool settings file does not exist for the tool {0}. + Tool settings file does not exist for the tool {0}. + + Update 업데이트 diff --git a/src/Cli/dotnet/xlf/CommonLocalizableStrings.pl.xlf b/src/Cli/dotnet/xlf/CommonLocalizableStrings.pl.xlf index fe436540c9c0..47890260b14e 100644 --- a/src/Cli/dotnet/xlf/CommonLocalizableStrings.pl.xlf +++ b/src/Cli/dotnet/xlf/CommonLocalizableStrings.pl.xlf @@ -282,6 +282,11 @@ Wartość domyślna to „false”. Jednak w przypadku określania wartości doc Rozwiązanie {0} zawiera już projekt {1} w folderze rozwiązania {2}. + + Tool settings file does not exist for the tool {0}. + Tool settings file does not exist for the tool {0}. + + Update Aktualizuj diff --git a/src/Cli/dotnet/xlf/CommonLocalizableStrings.pt-BR.xlf b/src/Cli/dotnet/xlf/CommonLocalizableStrings.pt-BR.xlf index d4483aee4997..107c1da7d2ea 100644 --- a/src/Cli/dotnet/xlf/CommonLocalizableStrings.pt-BR.xlf +++ b/src/Cli/dotnet/xlf/CommonLocalizableStrings.pt-BR.xlf @@ -282,6 +282,11 @@ O padrão é falso.' No entanto, ao direcionar o .NET 7 ou inferior, o padrão A solução {0} já contém o projeto {1} na pasta da solução {2}. + + Tool settings file does not exist for the tool {0}. + Tool settings file does not exist for the tool {0}. + + Update Atualização diff --git a/src/Cli/dotnet/xlf/CommonLocalizableStrings.ru.xlf b/src/Cli/dotnet/xlf/CommonLocalizableStrings.ru.xlf index 38f3941da111..713ddaf2dc19 100644 --- a/src/Cli/dotnet/xlf/CommonLocalizableStrings.ru.xlf +++ b/src/Cli/dotnet/xlf/CommonLocalizableStrings.ru.xlf @@ -282,6 +282,11 @@ The default is 'false.' However, when targeting .NET 7 or lower, the default is Решение {0} уже содержит проект {1} в папке решения {2}. + + Tool settings file does not exist for the tool {0}. + Tool settings file does not exist for the tool {0}. + + Update Обновить diff --git a/src/Cli/dotnet/xlf/CommonLocalizableStrings.tr.xlf b/src/Cli/dotnet/xlf/CommonLocalizableStrings.tr.xlf index 500570fcaeaa..1c0f7f4b4835 100644 --- a/src/Cli/dotnet/xlf/CommonLocalizableStrings.tr.xlf +++ b/src/Cli/dotnet/xlf/CommonLocalizableStrings.tr.xlf @@ -282,6 +282,11 @@ Varsayılan değer 'false' olur. Ancak çalışma zamanı tanımlayıcısı beli {0} çözümü zaten {2} çözüm klasöründe {1} projesini içeriyor. + + Tool settings file does not exist for the tool {0}. + Tool settings file does not exist for the tool {0}. + + Update Güncelleştir diff --git a/src/Cli/dotnet/xlf/CommonLocalizableStrings.zh-Hans.xlf b/src/Cli/dotnet/xlf/CommonLocalizableStrings.zh-Hans.xlf index de29e4e88760..1180bcd41985 100644 --- a/src/Cli/dotnet/xlf/CommonLocalizableStrings.zh-Hans.xlf +++ b/src/Cli/dotnet/xlf/CommonLocalizableStrings.zh-Hans.xlf @@ -282,6 +282,11 @@ The default is 'false.' However, when targeting .NET 7 or lower, the default is 解决方案 {0} 已在解决方案文件夹 {2} 中包含项目 {1}。 + + Tool settings file does not exist for the tool {0}. + Tool settings file does not exist for the tool {0}. + + Update 更新 diff --git a/src/Cli/dotnet/xlf/CommonLocalizableStrings.zh-Hant.xlf b/src/Cli/dotnet/xlf/CommonLocalizableStrings.zh-Hant.xlf index d5b225ea08f3..c453fb9dcb38 100644 --- a/src/Cli/dotnet/xlf/CommonLocalizableStrings.zh-Hant.xlf +++ b/src/Cli/dotnet/xlf/CommonLocalizableStrings.zh-Hant.xlf @@ -282,6 +282,11 @@ The default is 'false.' However, when targeting .NET 7 or lower, the default is 解決方案 {0} 已在解決方案資料夾中 {2} 包含專案 {1}。 + + Tool settings file does not exist for the tool {0}. + Tool settings file does not exist for the tool {0}. + + Update 更新 From 2313cf095e9443c6009dbf32395c9577c9457349 Mon Sep 17 00:00:00 2001 From: annie <59816815+JL03-Yue@users.noreply.github.com> Date: Sun, 3 Dec 2023 19:14:48 -0800 Subject: [PATCH 013/577] write rollforward in manifest file --- .../ToolManifest/IToolManifestEditor.cs | 4 +- .../ToolManifest/LocalizableStrings.resx | 3 ++ .../dotnet/ToolManifest/ToolManifestEditor.cs | 23 ++++++++--- .../ToolManifest/ToolManifestPackage.cs | 6 ++- .../xlf/LocalizableStrings.cs.xlf | 5 +++ .../xlf/LocalizableStrings.de.xlf | 5 +++ .../xlf/LocalizableStrings.es.xlf | 5 +++ .../xlf/LocalizableStrings.fr.xlf | 5 +++ .../xlf/LocalizableStrings.it.xlf | 5 +++ .../xlf/LocalizableStrings.ja.xlf | 5 +++ .../xlf/LocalizableStrings.ko.xlf | 5 +++ .../xlf/LocalizableStrings.pl.xlf | 5 +++ .../xlf/LocalizableStrings.pt-BR.xlf | 5 +++ .../xlf/LocalizableStrings.ru.xlf | 5 +++ .../xlf/LocalizableStrings.tr.xlf | 5 +++ .../xlf/LocalizableStrings.zh-Hans.xlf | 5 +++ .../xlf/LocalizableStrings.zh-Hant.xlf | 5 +++ .../install/ToolInstallLocalCommand.cs | 5 ++- .../CommandTests/ToolListLocalCommandTests.cs | 6 ++- .../CommandTests/ToolManifestFinderTests.cs | 41 ++++++++++++------- .../CommandTests/ToolRestoreCommandTests.cs | 33 ++++++++++----- ...toreCommandWithMultipleNugetConfigTests.cs | 6 ++- 22 files changed, 154 insertions(+), 38 deletions(-) diff --git a/src/Cli/dotnet/ToolManifest/IToolManifestEditor.cs b/src/Cli/dotnet/ToolManifest/IToolManifestEditor.cs index f3a473e7bd9f..c5900d46a3aa 100644 --- a/src/Cli/dotnet/ToolManifest/IToolManifestEditor.cs +++ b/src/Cli/dotnet/ToolManifest/IToolManifestEditor.cs @@ -10,8 +10,8 @@ namespace Microsoft.DotNet.ToolManifest { internal interface IToolManifestEditor { - void Add(FilePath manifest, PackageId packageId, NuGetVersion nuGetVersion, ToolCommandName[] toolCommandNames); + void Add(FilePath manifest, PackageId packageId, NuGetVersion nuGetVersion, ToolCommandName[] toolCommandNames, bool RollForward = false); void Remove(FilePath manifest, PackageId packageId); - void Edit(FilePath manifest, PackageId packageId, NuGetVersion newNuGetVersion, ToolCommandName[] newToolCommandNames); + void Edit(FilePath manifest, PackageId packageId, NuGetVersion newNuGetVersion, ToolCommandName[] newToolCommandNames, bool RollForward = false); } } diff --git a/src/Cli/dotnet/ToolManifest/LocalizableStrings.resx b/src/Cli/dotnet/ToolManifest/LocalizableStrings.resx index c9d74cba328e..5f439b91b802 100644 --- a/src/Cli/dotnet/ToolManifest/LocalizableStrings.resx +++ b/src/Cli/dotnet/ToolManifest/LocalizableStrings.resx @@ -169,4 +169,7 @@ For a list of locations searched, specify the "-d" option before the tool name.< More than one entry exists for package(s): {0}. + + Missing 'rollForward' entry. + \ No newline at end of file diff --git a/src/Cli/dotnet/ToolManifest/ToolManifestEditor.cs b/src/Cli/dotnet/ToolManifest/ToolManifestEditor.cs index a0b6034e3ef6..be775c1c613d 100644 --- a/src/Cli/dotnet/ToolManifest/ToolManifestEditor.cs +++ b/src/Cli/dotnet/ToolManifest/ToolManifestEditor.cs @@ -21,6 +21,7 @@ internal class ToolManifestEditor : IToolManifestEditor private const string JsonPropertyIsRoot = "isRoot"; private const string JsonPropertyCommands = "commands"; private const string JsonPropertyTools = "tools"; + private const string JsonPropertyRollForward = "rollForward"; public ToolManifestEditor(IFileSystem fileSystem = null, IDangerousFileDetector dangerousFileDetector = null) { @@ -32,7 +33,8 @@ public void Add( FilePath manifest, PackageId packageId, NuGetVersion nuGetVersion, - ToolCommandName[] toolCommandNames) + ToolCommandName[] toolCommandNames, + bool rollForward = false) { SerializableLocalToolsManifest deserializedManifest = DeserializeLocalToolsManifest(manifest); @@ -70,7 +72,8 @@ public void Add( { PackageId = packageId.ToString(), Version = nuGetVersion.ToNormalizedString(), - Commands = toolCommandNames.Select(c => c.Value).ToArray() + Commands = toolCommandNames.Select(c => c.Value).ToArray(), + RollForward = rollForward, }); _fileSystem.File.WriteAllText(manifest.Value, deserializedManifest.ToJson()); @@ -80,7 +83,8 @@ public void Edit( FilePath manifest, PackageId packageId, NuGetVersion newNuGetVersion, - ToolCommandName[] newToolCommandNames) + ToolCommandName[] newToolCommandNames, + bool rollForward = false) { SerializableLocalToolsManifest deserializedManifest = DeserializeLocalToolsManifest(manifest); @@ -199,6 +203,11 @@ private SerializableLocalToolsManifest DeserializeLocalToolsManifest(FilePath po serializableLocalToolSinglePackage.Commands = commands.ToArray(); } + if (toolJson.Value.TryGetStringValue(JsonPropertyRollForward, out var rollForwardJson)) + { + serializableLocalToolSinglePackage.RollForward = bool.Parse(rollForwardJson); + } + serializableLocalToolsManifest.Tools.Add(serializableLocalToolSinglePackage); } } @@ -269,6 +278,8 @@ private List GetToolManifestPackageFromOneManifestFile( packageLevelErrors.Add(LocalizableStrings.FieldCommandsIsMissing); } + bool rollForward = tools.RollForward; + if (packageLevelErrors.Any()) { var joinedWithIndentation = string.Join(Environment.NewLine, @@ -282,7 +293,8 @@ private List GetToolManifestPackageFromOneManifestFile( packageId, version, ToolCommandName.Convert(tools.Commands), - correspondingDirectory)); + correspondingDirectory, + rollForward)); } } @@ -325,6 +337,7 @@ private class SerializableLocalToolSinglePackage public string PackageId { get; set; } public string Version { get; set; } public string[] Commands { get; set; } + public bool RollForward { get; set; } } private static bool CommandNamesEqual(ToolCommandName[] left, ToolCommandName[] right) @@ -379,8 +392,8 @@ public string ToJson() { writer.WriteStringValue(toolCommandName); } - writer.WriteEndArray(); + writer.WriteString(JsonPropertyRollForward, tool.RollForward.ToString()); writer.WriteEndObject(); } diff --git a/src/Cli/dotnet/ToolManifest/ToolManifestPackage.cs b/src/Cli/dotnet/ToolManifest/ToolManifestPackage.cs index 31e4005bc47b..5e90154381eb 100644 --- a/src/Cli/dotnet/ToolManifest/ToolManifestPackage.cs +++ b/src/Cli/dotnet/ToolManifest/ToolManifestPackage.cs @@ -1,6 +1,7 @@ // 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.Eventing.Reader; using Microsoft.DotNet.Cli.Utils; using Microsoft.DotNet.ToolPackage; using Microsoft.Extensions.EnvironmentAbstractions; @@ -13,6 +14,7 @@ internal struct ToolManifestPackage : IEquatable public PackageId PackageId { get; } public NuGetVersion Version { get; } public ToolCommandName[] CommandNames { get; } + public bool RollForward { get; } /// /// The directory that will take effect first. /// When it is under .config directory, it is not .config directory @@ -23,12 +25,14 @@ internal struct ToolManifestPackage : IEquatable public ToolManifestPackage(PackageId packagePackageId, NuGetVersion version, ToolCommandName[] toolCommandNames, - DirectoryPath firstEffectDirectory) + DirectoryPath firstEffectDirectory, + bool rollForward) { FirstEffectDirectory = firstEffectDirectory; PackageId = packagePackageId; Version = version ?? throw new ArgumentNullException(nameof(version)); CommandNames = toolCommandNames ?? throw new ArgumentNullException(nameof(toolCommandNames)); + RollForward = rollForward; } public override bool Equals(object obj) diff --git a/src/Cli/dotnet/ToolManifest/xlf/LocalizableStrings.cs.xlf b/src/Cli/dotnet/ToolManifest/xlf/LocalizableStrings.cs.xlf index 05ef93536e45..be0480213746 100644 --- a/src/Cli/dotnet/ToolManifest/xlf/LocalizableStrings.cs.xlf +++ b/src/Cli/dotnet/ToolManifest/xlf/LocalizableStrings.cs.xlf @@ -36,6 +36,11 @@ Pokud si chcete zobrazit seznam prohledaných umístění, zadejte před název Existuje více než jedno zadání pro balíčky: {0}. + + Missing 'rollForward' entry. + Missing 'rollForward' entry. + + Expected a {0} for property '{1}'. Očekává se {0} pro vlastnost {1}. diff --git a/src/Cli/dotnet/ToolManifest/xlf/LocalizableStrings.de.xlf b/src/Cli/dotnet/ToolManifest/xlf/LocalizableStrings.de.xlf index 162eb3a660d3..73281330a972 100644 --- a/src/Cli/dotnet/ToolManifest/xlf/LocalizableStrings.de.xlf +++ b/src/Cli/dotnet/ToolManifest/xlf/LocalizableStrings.de.xlf @@ -36,6 +36,11 @@ Eine Liste der durchsuchten Speicherorte erhalten Sie, indem Sie vor dem Toolnam Für diese Pakete ist mehr als ein Eintrag vorhanden: {0}. + + Missing 'rollForward' entry. + Missing 'rollForward' entry. + + Expected a {0} for property '{1}'. Erwartet wurde "{0}" für die Eigenschaft "{1}". diff --git a/src/Cli/dotnet/ToolManifest/xlf/LocalizableStrings.es.xlf b/src/Cli/dotnet/ToolManifest/xlf/LocalizableStrings.es.xlf index 6bd88db7fd68..7ec2318a8f70 100644 --- a/src/Cli/dotnet/ToolManifest/xlf/LocalizableStrings.es.xlf +++ b/src/Cli/dotnet/ToolManifest/xlf/LocalizableStrings.es.xlf @@ -36,6 +36,11 @@ Para obtener una lista de ubicaciones buscadas, especifique la opción "-d" dela Existe más de una entrada para los paquetes: {0}. + + Missing 'rollForward' entry. + Missing 'rollForward' entry. + + Expected a {0} for property '{1}'. Se esperaba un {0} para la propiedad "{1}". diff --git a/src/Cli/dotnet/ToolManifest/xlf/LocalizableStrings.fr.xlf b/src/Cli/dotnet/ToolManifest/xlf/LocalizableStrings.fr.xlf index b8b22c3dc5fc..43c177a1996d 100644 --- a/src/Cli/dotnet/ToolManifest/xlf/LocalizableStrings.fr.xlf +++ b/src/Cli/dotnet/ToolManifest/xlf/LocalizableStrings.fr.xlf @@ -36,6 +36,11 @@ Pour obtenir une liste des emplacements de recherche, spécifiez l'option "-d" a Il existe plusieurs entrées pour le ou les packages : {0}. + + Missing 'rollForward' entry. + Missing 'rollForward' entry. + + Expected a {0} for property '{1}'. {0} attendu pour la propriété '{1}'. diff --git a/src/Cli/dotnet/ToolManifest/xlf/LocalizableStrings.it.xlf b/src/Cli/dotnet/ToolManifest/xlf/LocalizableStrings.it.xlf index ba3b4a3ab460..5d51a00d1668 100644 --- a/src/Cli/dotnet/ToolManifest/xlf/LocalizableStrings.it.xlf +++ b/src/Cli/dotnet/ToolManifest/xlf/LocalizableStrings.it.xlf @@ -36,6 +36,11 @@ Per un elenco dei percorso di ricerca, specificare l'opzione "-d" prima del nome Sono presenti più voci per i pacchetti: {0}. + + Missing 'rollForward' entry. + Missing 'rollForward' entry. + + Expected a {0} for property '{1}'. È previsto un tipo {0} per la proprietà '{1}'. diff --git a/src/Cli/dotnet/ToolManifest/xlf/LocalizableStrings.ja.xlf b/src/Cli/dotnet/ToolManifest/xlf/LocalizableStrings.ja.xlf index 2cb7df27aea5..8452eaa921c4 100644 --- a/src/Cli/dotnet/ToolManifest/xlf/LocalizableStrings.ja.xlf +++ b/src/Cli/dotnet/ToolManifest/xlf/LocalizableStrings.ja.xlf @@ -36,6 +36,11 @@ For a list of locations searched, specify the "-d" option before the tool name.< パッケージに対して複数のエントリが存在します: {0}。 + + Missing 'rollForward' entry. + Missing 'rollForward' entry. + + Expected a {0} for property '{1}'. プロパティ '{1}' には {0} が必要です。 diff --git a/src/Cli/dotnet/ToolManifest/xlf/LocalizableStrings.ko.xlf b/src/Cli/dotnet/ToolManifest/xlf/LocalizableStrings.ko.xlf index a8f2ee78fe40..03566e31bd82 100644 --- a/src/Cli/dotnet/ToolManifest/xlf/LocalizableStrings.ko.xlf +++ b/src/Cli/dotnet/ToolManifest/xlf/LocalizableStrings.ko.xlf @@ -36,6 +36,11 @@ For a list of locations searched, specify the "-d" option before the tool name.< 패키지 {0}에 항목이 두 개 이상 있습니다. + + Missing 'rollForward' entry. + Missing 'rollForward' entry. + + Expected a {0} for property '{1}'. '{1}' 속성에는 {0}이(가) 필요합니다. diff --git a/src/Cli/dotnet/ToolManifest/xlf/LocalizableStrings.pl.xlf b/src/Cli/dotnet/ToolManifest/xlf/LocalizableStrings.pl.xlf index 4276034f94af..184502e7c14e 100644 --- a/src/Cli/dotnet/ToolManifest/xlf/LocalizableStrings.pl.xlf +++ b/src/Cli/dotnet/ToolManifest/xlf/LocalizableStrings.pl.xlf @@ -36,6 +36,11 @@ Aby uzyskać listę przeszukiwanych lokalizacji, określ opcję „-d” przed n Istnieje wiele pozycji dla pakietów: {0}. + + Missing 'rollForward' entry. + Missing 'rollForward' entry. + + Expected a {0} for property '{1}'. Oczekiwano wartości {0} dla właściwości „{1}”. diff --git a/src/Cli/dotnet/ToolManifest/xlf/LocalizableStrings.pt-BR.xlf b/src/Cli/dotnet/ToolManifest/xlf/LocalizableStrings.pt-BR.xlf index bb06d04304f3..077c85705e73 100644 --- a/src/Cli/dotnet/ToolManifest/xlf/LocalizableStrings.pt-BR.xlf +++ b/src/Cli/dotnet/ToolManifest/xlf/LocalizableStrings.pt-BR.xlf @@ -36,6 +36,11 @@ Para obter uma lista de localizações pesquisadas, especifique a opção "-d" a Existe mais de uma entrada para os pacotes: {0}. + + Missing 'rollForward' entry. + Missing 'rollForward' entry. + + Expected a {0} for property '{1}'. Um {0} era esperado para a propriedade '{1}'. diff --git a/src/Cli/dotnet/ToolManifest/xlf/LocalizableStrings.ru.xlf b/src/Cli/dotnet/ToolManifest/xlf/LocalizableStrings.ru.xlf index 4732f88480e9..7d43d9bc7fd1 100644 --- a/src/Cli/dotnet/ToolManifest/xlf/LocalizableStrings.ru.xlf +++ b/src/Cli/dotnet/ToolManifest/xlf/LocalizableStrings.ru.xlf @@ -36,6 +36,11 @@ For a list of locations searched, specify the "-d" option before the tool name.< Существует несколько записей для следующих пакетов: {0}. + + Missing 'rollForward' entry. + Missing 'rollForward' entry. + + Expected a {0} for property '{1}'. Ожидается {0} для свойства "{1}". diff --git a/src/Cli/dotnet/ToolManifest/xlf/LocalizableStrings.tr.xlf b/src/Cli/dotnet/ToolManifest/xlf/LocalizableStrings.tr.xlf index fa2b940b190e..ae521217b629 100644 --- a/src/Cli/dotnet/ToolManifest/xlf/LocalizableStrings.tr.xlf +++ b/src/Cli/dotnet/ToolManifest/xlf/LocalizableStrings.tr.xlf @@ -36,6 +36,11 @@ Aranan konumların bir listesi için aracın adından önce "-d" seçeneğini be Paketler için birden fazla giriş var: {0}. + + Missing 'rollForward' entry. + Missing 'rollForward' entry. + + Expected a {0} for property '{1}'. '{1}' özelliği için bir {0} bekleniyordu. diff --git a/src/Cli/dotnet/ToolManifest/xlf/LocalizableStrings.zh-Hans.xlf b/src/Cli/dotnet/ToolManifest/xlf/LocalizableStrings.zh-Hans.xlf index 6cb8cf37d545..5fe274276893 100644 --- a/src/Cli/dotnet/ToolManifest/xlf/LocalizableStrings.zh-Hans.xlf +++ b/src/Cli/dotnet/ToolManifest/xlf/LocalizableStrings.zh-Hans.xlf @@ -36,6 +36,11 @@ For a list of locations searched, specify the "-d" option before the tool name.< 包 {0} 存在多个条目。 + + Missing 'rollForward' entry. + Missing 'rollForward' entry. + + Expected a {0} for property '{1}'. 属性“{1}”需要 {0}。 diff --git a/src/Cli/dotnet/ToolManifest/xlf/LocalizableStrings.zh-Hant.xlf b/src/Cli/dotnet/ToolManifest/xlf/LocalizableStrings.zh-Hant.xlf index 0cc57e1c6f85..c843cea44165 100644 --- a/src/Cli/dotnet/ToolManifest/xlf/LocalizableStrings.zh-Hant.xlf +++ b/src/Cli/dotnet/ToolManifest/xlf/LocalizableStrings.zh-Hant.xlf @@ -36,6 +36,11 @@ For a list of locations searched, specify the "-d" option before the tool name.< 封裝存在多個項目: {0}。 + + Missing 'rollForward' entry. + Missing 'rollForward' entry. + + Expected a {0} for property '{1}'. 對屬性 '{1}' 來說應為 {0}。 diff --git a/src/Cli/dotnet/commands/dotnet-tool/install/ToolInstallLocalCommand.cs b/src/Cli/dotnet/commands/dotnet-tool/install/ToolInstallLocalCommand.cs index 9f9980ba9371..871d302e35df 100644 --- a/src/Cli/dotnet/commands/dotnet-tool/install/ToolInstallLocalCommand.cs +++ b/src/Cli/dotnet/commands/dotnet-tool/install/ToolInstallLocalCommand.cs @@ -22,6 +22,7 @@ internal class ToolInstallLocalCommand : CommandBase private readonly string _explicitManifestFile; private readonly bool _createManifestIfNeeded; + private readonly bool _rollForward; public ToolInstallLocalCommand( ParseResult parseResult, @@ -44,6 +45,7 @@ public ToolInstallLocalCommand( _toolManifestEditor = toolManifestEditor ?? new ToolManifestEditor(); _localToolsResolverCache = localToolsResolverCache ?? new LocalToolsResolverCache(); _toolLocalPackageInstaller = new ToolInstallLocalInstaller(parseResult, toolPackageDownloader); + _rollForward = parseResult.GetValue(ToolInstallCommandParser.RollForwardOption); } public override int Execute() @@ -61,7 +63,8 @@ public int Install(FilePath manifestFile) manifestFile, toolDownloadedPackage.Id, toolDownloadedPackage.Version, - toolDownloadedPackage.Commands.Select(c => c.Name).ToArray()); + toolDownloadedPackage.Commands.Select(c => c.Name).ToArray(), + _rollForward); _localToolsResolverCache.SaveToolPackage( toolDownloadedPackage, diff --git a/src/Tests/dotnet.Tests/CommandTests/ToolListLocalCommandTests.cs b/src/Tests/dotnet.Tests/CommandTests/ToolListLocalCommandTests.cs index a639dc05ed48..fc8d1246a871 100644 --- a/src/Tests/dotnet.Tests/CommandTests/ToolListLocalCommandTests.cs +++ b/src/Tests/dotnet.Tests/CommandTests/ToolListLocalCommandTests.cs @@ -34,12 +34,14 @@ public ToolListLocalCommandTests() new PackageId("package.id"), NuGetVersion.Parse("2.1.4"), new[] {new ToolCommandName("package-name")}, - new DirectoryPath(_temporaryDirectory)), new FilePath(_testManifestPath)), + new DirectoryPath(_temporaryDirectory), + false), new FilePath(_testManifestPath)), (new ToolManifestPackage( new PackageId("foo.bar"), NuGetVersion.Parse("1.0.8"), new[] {new ToolCommandName("foo-bar")}, - new DirectoryPath(_temporaryDirectory)), new FilePath(_testManifestPath)) + new DirectoryPath(_temporaryDirectory), + false), new FilePath(_testManifestPath)) } ); _parseResult = Parser.Instance.Parse("dotnet tool list"); diff --git a/src/Tests/dotnet.Tests/CommandTests/ToolManifestFinderTests.cs b/src/Tests/dotnet.Tests/CommandTests/ToolManifestFinderTests.cs index 4b56fad6f7ac..3354e42f3d7b 100644 --- a/src/Tests/dotnet.Tests/CommandTests/ToolManifestFinderTests.cs +++ b/src/Tests/dotnet.Tests/CommandTests/ToolManifestFinderTests.cs @@ -29,13 +29,15 @@ public ToolManifestFinderTests() new ToolManifestPackage( new PackageId("t-rex"), NuGetVersion.Parse("1.0.53"), - new[] {new ToolCommandName("t-rex")}, - new DirectoryPath(_testDirectoryRoot)), + new[] {new ToolCommandName("t-rex"),}, + new DirectoryPath(_testDirectoryRoot), + false), new ToolManifestPackage( new PackageId("dotnetsay"), NuGetVersion.Parse("2.1.4"), new[] {new ToolCommandName("dotnetsay")}, - new DirectoryPath(_testDirectoryRoot)) + new DirectoryPath(_testDirectoryRoot), + false) }; } @@ -112,12 +114,14 @@ public void GivenManifestFileInRootDirectoryForLinuxMacOSItGetsContent() new PackageId("t-rex"), NuGetVersion.Parse("1.0.53"), new[] {new ToolCommandName("t-rex")}, - new DirectoryPath(rootDirectory.Value)), + new DirectoryPath(rootDirectory.Value), + false), new ToolManifestPackage( new PackageId("dotnetsay"), NuGetVersion.Parse("2.1.4"), new[] {new ToolCommandName("dotnetsay")}, - new DirectoryPath(rootDirectory.Value)) + new DirectoryPath(rootDirectory.Value), + false) }; AssertToolManifestPackageListEqual(expectedResult, manifestResult); @@ -178,12 +182,14 @@ public void GivenManifestFileInRootDirectoryWithEnvVariableCHECK_MANIFEST_IN_ROO new PackageId("t-rex"), NuGetVersion.Parse("1.0.53"), new[] {new ToolCommandName("t-rex")}, - new DirectoryPath(rootDirectory.Value)), + new DirectoryPath(rootDirectory.Value), + false), new ToolManifestPackage( new PackageId("dotnetsay"), NuGetVersion.Parse("2.1.4"), new[] {new ToolCommandName("dotnetsay")}, - new DirectoryPath(rootDirectory.Value)) + new DirectoryPath(rootDirectory.Value), + false) }; AssertToolManifestPackageListEqual(expectedResult, manifestResult); @@ -363,7 +369,8 @@ public void GivenConflictedManifestFileInDifferentDirectoriesItReturnMergedConte new PackageId("t-rex"), NuGetVersion.Parse("1.0.49"), new[] { new ToolCommandName("t-rex") }, - new DirectoryPath(subdirectoryOfTestRoot)), + new DirectoryPath(subdirectoryOfTestRoot), + false), because: "when different manifest file has the same package id, " + "only keep entry that is in the manifest close to current directory"); manifestResult.Should().Contain( @@ -371,14 +378,16 @@ public void GivenConflictedManifestFileInDifferentDirectoriesItReturnMergedConte new PackageId("dotnetsay2"), NuGetVersion.Parse("4.0.0"), new[] { new ToolCommandName("dotnetsay2") }, - new DirectoryPath(_testDirectoryRoot))); + new DirectoryPath(_testDirectoryRoot), + false)); manifestResult.Should().Contain( p => p == new ToolManifestPackage( new PackageId("dotnetsay"), NuGetVersion.Parse("2.1.4"), new[] { new ToolCommandName("dotnetsay") }, - new DirectoryPath(subdirectoryOfTestRoot)), + new DirectoryPath(subdirectoryOfTestRoot), + false), because: "combine both content in different manifests"); } @@ -507,7 +516,8 @@ public void GivenManifestFileOnSameDirectoryWhenFindByCommandNameItGetContent() new PackageId("dotnetsay"), NuGetVersion.Parse("2.1.4"), new[] { new ToolCommandName("dotnetsay") }, - new DirectoryPath(_testDirectoryRoot))); + new DirectoryPath(_testDirectoryRoot), + false)); } [Fact] @@ -526,7 +536,8 @@ public void GivenManifestFileOnSameDirectoryWhenFindByCommandNameWithDifferentCa new PackageId("dotnetsay"), NuGetVersion.Parse("2.1.4"), new[] { new ToolCommandName("dotnetsay") }, - new DirectoryPath(_testDirectoryRoot))); + new DirectoryPath(_testDirectoryRoot), + false)); } [Fact] @@ -546,7 +557,8 @@ public void GivenManifestFileOnParentDirectoryWhenFindByCommandNameItGetContent( new PackageId("dotnetsay"), NuGetVersion.Parse("2.1.4"), new[] { new ToolCommandName("dotnetsay") }, - new DirectoryPath(_testDirectoryRoot))); + new DirectoryPath(_testDirectoryRoot), + false)); } [Fact] @@ -624,7 +636,8 @@ public void GivenConflictedManifestFileInDifferentFieldsWhenFindByCommandNameItR new PackageId("t-rex"), NuGetVersion.Parse("1.0.49"), new[] { new ToolCommandName("t-rex") }, - new DirectoryPath(subdirectoryOfTestRoot))); + new DirectoryPath(subdirectoryOfTestRoot), + false)); } [Fact] diff --git a/src/Tests/dotnet.Tests/CommandTests/ToolRestoreCommandTests.cs b/src/Tests/dotnet.Tests/CommandTests/ToolRestoreCommandTests.cs index 192b1fc5215c..502f184d1ded 100644 --- a/src/Tests/dotnet.Tests/CommandTests/ToolRestoreCommandTests.cs +++ b/src/Tests/dotnet.Tests/CommandTests/ToolRestoreCommandTests.cs @@ -119,10 +119,12 @@ public void WhenRunItCanSaveCommandsToCache() { new ToolManifestPackage(_packageIdA, _packageVersionA, new[] {_toolCommandNameA}, - new DirectoryPath(_temporaryDirectory)), + new DirectoryPath(_temporaryDirectory), + false), new ToolManifestPackage(_packageIdB, _packageVersionB, new[] {_toolCommandNameB}, - new DirectoryPath(_temporaryDirectory)) + new DirectoryPath(_temporaryDirectory), + false) }); ToolRestoreCommand toolRestoreCommand = new ToolRestoreCommand(_parseResult, @@ -156,10 +158,12 @@ public void WhenRunItCanSaveCommandsToCacheAndShowSuccessMessage() { new ToolManifestPackage(_packageIdA, _packageVersionA, new[] {_toolCommandNameA}, - new DirectoryPath(_temporaryDirectory)), + new DirectoryPath(_temporaryDirectory), + false), new ToolManifestPackage(_packageIdB, _packageVersionB, new[] {_toolCommandNameB}, - new DirectoryPath(_temporaryDirectory)) + new DirectoryPath(_temporaryDirectory), + false) }); ToolRestoreCommand toolRestoreCommand = new ToolRestoreCommand(_parseResult, @@ -191,10 +195,12 @@ public void WhenRestoredCommandHasTheSameCommandNameItThrows() { new ToolManifestPackage(_packageIdA, _packageVersionA, new[] {_toolCommandNameA}, - new DirectoryPath(_temporaryDirectory)), + new DirectoryPath(_temporaryDirectory), + false), new ToolManifestPackage(_packageIdWithCommandNameCollisionWithA, _packageVersionWithCommandNameCollisionWithA, new[] {_toolCommandNameA}, - new DirectoryPath(_temporaryDirectory)) + new DirectoryPath(_temporaryDirectory), + false) }); ToolRestoreCommand toolRestoreCommand = new ToolRestoreCommand(_parseResult, @@ -246,10 +252,12 @@ public void WhenSomePackageFailedToRestoreItCanRestorePartiallySuccessful() { new ToolManifestPackage(_packageIdA, _packageVersionA, new[] {_toolCommandNameA}, - new DirectoryPath(_temporaryDirectory)), + new DirectoryPath(_temporaryDirectory), + false), new ToolManifestPackage(new PackageId("non-exists"), NuGetVersion.Parse("1.0.0"), new[] {new ToolCommandName("non-exists")}, - new DirectoryPath(_temporaryDirectory)) + new DirectoryPath(_temporaryDirectory), + false) }); ToolRestoreCommand toolRestoreCommand = new ToolRestoreCommand(_parseResult, @@ -289,7 +297,8 @@ public void ItShouldFailWhenPackageCommandNameDoesNotMatchManifestCommands() { new ToolManifestPackage(_packageIdA, _packageVersionA, new[] {differentCommandNameA, differentCommandNameB}, - new DirectoryPath(_temporaryDirectory)), + new DirectoryPath(_temporaryDirectory), + false), }); ToolRestoreCommand toolRestoreCommand = new ToolRestoreCommand(_parseResult, @@ -457,7 +466,8 @@ public void WhenPackageIsRestoredAlreadyItWillNotRestoreItAgain() { new ToolManifestPackage(_packageIdA, _packageVersionA, new[] {_toolCommandNameA}, - new DirectoryPath(_temporaryDirectory)) + new DirectoryPath(_temporaryDirectory), + false) }); ToolRestoreCommand toolRestoreCommand = new ToolRestoreCommand(_parseResult, @@ -484,7 +494,8 @@ public void WhenPackageIsRestoredAlreadyButDllIsRemovedItRestoresAgain() { new ToolManifestPackage(_packageIdA, _packageVersionA, new[] {_toolCommandNameA}, - new DirectoryPath(_temporaryDirectory)) + new DirectoryPath(_temporaryDirectory), + false) }); ToolRestoreCommand toolRestoreCommand = new ToolRestoreCommand(_parseResult, diff --git a/src/Tests/dotnet.Tests/CommandTests/ToolRestoreCommandWithMultipleNugetConfigTests.cs b/src/Tests/dotnet.Tests/CommandTests/ToolRestoreCommandWithMultipleNugetConfigTests.cs index 09519ba7d78e..b4188d649c5b 100644 --- a/src/Tests/dotnet.Tests/CommandTests/ToolRestoreCommandWithMultipleNugetConfigTests.cs +++ b/src/Tests/dotnet.Tests/CommandTests/ToolRestoreCommandWithMultipleNugetConfigTests.cs @@ -115,10 +115,12 @@ public void WhenManifestPackageAreFromDifferentDirectoryItCanFindTheRightNugetCo { new ToolManifestPackage(_packageIdA, _packageVersionA, new[] {_toolCommandNameA}, - new DirectoryPath(Path.GetDirectoryName(_nugetConfigUnderTestRoot))), + new DirectoryPath(Path.GetDirectoryName(_nugetConfigUnderTestRoot)), + false), new ToolManifestPackage(_packageIdB, _packageVersionB, new[] {_toolCommandNameB}, - new DirectoryPath(Path.GetDirectoryName(_nugetConfigUnderSubDir))) + new DirectoryPath(Path.GetDirectoryName(_nugetConfigUnderSubDir)), + false) }); ToolRestoreCommand toolRestoreCommand = new ToolRestoreCommand(_parseResult, From da7e49d3c09cbf6b3847a8bc29f7e372bb4dbdfa Mon Sep 17 00:00:00 2001 From: annie <59816815+JL03-Yue@users.noreply.github.com> Date: Sun, 3 Dec 2023 20:17:13 -0800 Subject: [PATCH 014/577] read from manifest file --- .../dotnet-tool/run/ToolRunCommand.cs | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/src/Cli/dotnet/commands/dotnet-tool/run/ToolRunCommand.cs b/src/Cli/dotnet/commands/dotnet-tool/run/ToolRunCommand.cs index a6220dbaedfb..d94983c6c9a6 100644 --- a/src/Cli/dotnet/commands/dotnet-tool/run/ToolRunCommand.cs +++ b/src/Cli/dotnet/commands/dotnet-tool/run/ToolRunCommand.cs @@ -5,6 +5,8 @@ using Microsoft.DotNet.Cli; using Microsoft.DotNet.Cli.Utils; using Microsoft.DotNet.CommandFactory; +using Microsoft.DotNet.ToolManifest; +using Microsoft.Extensions.EnvironmentAbstractions; namespace Microsoft.DotNet.Tools.Tool.Run { @@ -13,22 +15,33 @@ internal class ToolRunCommand : CommandBase private readonly string _toolCommandName; private readonly LocalToolsCommandResolver _localToolsCommandResolver; private readonly IEnumerable _forwardArgument; - public readonly string _rollForward; + public string _rollForward; + private readonly ToolManifestFinder _toolManifest; public ToolRunCommand( ParseResult result, - LocalToolsCommandResolver localToolsCommandResolver = null) + LocalToolsCommandResolver localToolsCommandResolver = null, + ToolManifestFinder toolManifest = null) : base(result) { _toolCommandName = result.GetValue(ToolRunCommandParser.CommandNameArgument); _forwardArgument = result.GetValue(ToolRunCommandParser.CommandArgument); _localToolsCommandResolver = localToolsCommandResolver ?? new LocalToolsCommandResolver(); _rollForward = result.GetValue(ToolRunCommandParser.RollForwardOption); + _toolManifest = toolManifest ?? new ToolManifestFinder(new DirectoryPath(Directory.GetCurrentDirectory())); } public override int Execute() { - CommandSpec commandspec = _localToolsCommandResolver.ResolveStrict(new CommandResolverArguments() + if (_toolManifest.TryFind(new ToolCommandName(_toolCommandName), out var toolManifestPackage)) + { + if (toolManifestPackage.RollForward) + { + _rollForward = "LatestMajor"; + } + } + + CommandSpec commandspec = _localToolsCommandResolver.ResolveStrict(new CommandResolverArguments() { // since LocalToolsCommandResolver is a resolver, and all resolver input have dotnet- CommandName = $"dotnet-{_toolCommandName}", From e4b098e0ef50c353f505323044e06aaf508ff235 Mon Sep 17 00:00:00 2001 From: annie <59816815+JL03-Yue@users.noreply.github.com> Date: Sun, 3 Dec 2023 20:30:04 -0800 Subject: [PATCH 015/577] Remove the tool manifest editor edit option --- src/Cli/dotnet/ToolManifest/IToolManifestEditor.cs | 2 +- src/Cli/dotnet/ToolManifest/ToolManifestEditor.cs | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Cli/dotnet/ToolManifest/IToolManifestEditor.cs b/src/Cli/dotnet/ToolManifest/IToolManifestEditor.cs index c5900d46a3aa..73e362d1b359 100644 --- a/src/Cli/dotnet/ToolManifest/IToolManifestEditor.cs +++ b/src/Cli/dotnet/ToolManifest/IToolManifestEditor.cs @@ -12,6 +12,6 @@ internal interface IToolManifestEditor { void Add(FilePath manifest, PackageId packageId, NuGetVersion nuGetVersion, ToolCommandName[] toolCommandNames, bool RollForward = false); void Remove(FilePath manifest, PackageId packageId); - void Edit(FilePath manifest, PackageId packageId, NuGetVersion newNuGetVersion, ToolCommandName[] newToolCommandNames, bool RollForward = false); + void Edit(FilePath manifest, PackageId packageId, NuGetVersion newNuGetVersion, ToolCommandName[] newToolCommandNames); } } diff --git a/src/Cli/dotnet/ToolManifest/ToolManifestEditor.cs b/src/Cli/dotnet/ToolManifest/ToolManifestEditor.cs index be775c1c613d..1c760a78fb9f 100644 --- a/src/Cli/dotnet/ToolManifest/ToolManifestEditor.cs +++ b/src/Cli/dotnet/ToolManifest/ToolManifestEditor.cs @@ -47,6 +47,7 @@ public void Add( { var existingPackage = existing.Single(); + // TBD if (existingPackage.PackageId.Equals(packageId) && existingPackage.Version == nuGetVersion && CommandNamesEqual(existingPackage.CommandNames, toolCommandNames)) @@ -83,8 +84,7 @@ public void Edit( FilePath manifest, PackageId packageId, NuGetVersion newNuGetVersion, - ToolCommandName[] newToolCommandNames, - bool rollForward = false) + ToolCommandName[] newToolCommandNames) { SerializableLocalToolsManifest deserializedManifest = DeserializeLocalToolsManifest(manifest); From 026114948b311e7ad017be66c8c10709688d7d0c Mon Sep 17 00:00:00 2001 From: annie <59816815+JL03-Yue@users.noreply.github.com> Date: Sun, 3 Dec 2023 20:41:09 -0800 Subject: [PATCH 016/577] Update the tool manifest if --roll-forward changes --- src/Cli/dotnet/ToolManifest/ToolManifestEditor.cs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/Cli/dotnet/ToolManifest/ToolManifestEditor.cs b/src/Cli/dotnet/ToolManifest/ToolManifestEditor.cs index 1c760a78fb9f..af6a3b9cb1fc 100644 --- a/src/Cli/dotnet/ToolManifest/ToolManifestEditor.cs +++ b/src/Cli/dotnet/ToolManifest/ToolManifestEditor.cs @@ -47,11 +47,14 @@ public void Add( { var existingPackage = existing.Single(); - // TBD + // Update the tool manifest if --roll-forward changes if (existingPackage.PackageId.Equals(packageId) && existingPackage.Version == nuGetVersion && CommandNamesEqual(existingPackage.CommandNames, toolCommandNames)) { + var toEdit = deserializedManifest.Tools.Single(t => new PackageId(t.PackageId).Equals(packageId)); + toEdit.RollForward = rollForward; + _fileSystem.File.WriteAllText(manifest.Value, deserializedManifest.ToJson()); return; } From c0b0f817871d598de607d5168c9a1db441bb160a Mon Sep 17 00:00:00 2001 From: annie <59816815+JL03-Yue@users.noreply.github.com> Date: Sun, 3 Dec 2023 22:50:40 -0800 Subject: [PATCH 017/577] fix tests --- .../CommandTests/ToolManifestEditorTests.cs | 55 +++++++++++-------- 1 file changed, 32 insertions(+), 23 deletions(-) diff --git a/src/Tests/dotnet.Tests/CommandTests/ToolManifestEditorTests.cs b/src/Tests/dotnet.Tests/CommandTests/ToolManifestEditorTests.cs index db0b902251c1..77258c8de50f 100644 --- a/src/Tests/dotnet.Tests/CommandTests/ToolManifestEditorTests.cs +++ b/src/Tests/dotnet.Tests/CommandTests/ToolManifestEditorTests.cs @@ -45,19 +45,22 @@ public void GivenManifestFileItCanAddEntryToIt() ""version"": ""1.0.53"", ""commands"": [ ""t-rex"" - ] + ], + ""rollForward"": ""False"" }, ""dotnetsay"": { ""version"": ""2.1.4"", ""commands"": [ ""dotnetsay"" - ] + ], + ""rollForward"": ""False"" }, ""new-tool"": { ""version"": ""3.0.0"", ""commands"": [ ""newtool"" - ] + ], + ""rollForward"": ""False"" } } }"); @@ -84,7 +87,8 @@ public void GivenManifestFileWithoutToolsEntryItCanAddEntryToIt() ""version"": ""3.0.0"", ""commands"": [ ""newtool"" - ] + ], + ""rollForward"": ""False"" } } }"); @@ -196,7 +200,8 @@ public void GivenManifestFileItCanRemoveEntryFromIt() ""version"": ""1.0.53"", ""commands"": [ ""t-rex"" - ] + ], + ""rollForward"": ""False"" } } }"); @@ -282,13 +287,15 @@ public void GivenManifestFileItCanEditEntry() ""version"": ""3.0.0"", ""commands"": [ ""t-rex3"" - ] + ], + ""rollForward"": ""False"" }, ""dotnetsay"": { ""version"": ""2.1.4"", ""commands"": [ ""dotnetsay"" - ] + ], + ""rollForward"": ""False"" } } }", "And original tools entry order is preserved."); @@ -296,22 +303,24 @@ public void GivenManifestFileItCanEditEntry() private string _jsonContent = @"{ - ""version"":1, - ""isRoot"":true, - ""tools"":{ - ""t-rex"":{ - ""version"":""1.0.53"", - ""commands"":[ - ""t-rex"" - ] - }, - ""dotnetsay"":{ - ""version"":""2.1.4"", - ""commands"":[ - ""dotnetsay"" - ] - } - } + ""version"": 1, + ""isRoot"": true, + ""tools"": { + ""t-rex"": { + ""version"": ""1.0.53"", + ""commands"": [ + ""t-rex"" + ], + ""rollForward"": ""False"" + }, + ""dotnetsay"": { + ""version"": ""2.1.4"", + ""commands"": [ + ""dotnetsay"" + ], + ""rollForward"": ""False"" + } + } }"; private string _jsonContentWithoutToolsEntry = From 7d2b7e249d5a36b36df83d7ed586d062ac8454e5 Mon Sep 17 00:00:00 2001 From: annie <59816815+JL03-Yue@users.noreply.github.com> Date: Mon, 4 Dec 2023 12:21:43 -0800 Subject: [PATCH 018/577] fix test --- .../CommandTests/ToolUninstallLocalCommandTests.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Tests/dotnet.Tests/CommandTests/ToolUninstallLocalCommandTests.cs b/src/Tests/dotnet.Tests/CommandTests/ToolUninstallLocalCommandTests.cs index a5d431d0f6cf..d8f27c0cc033 100644 --- a/src/Tests/dotnet.Tests/CommandTests/ToolUninstallLocalCommandTests.cs +++ b/src/Tests/dotnet.Tests/CommandTests/ToolUninstallLocalCommandTests.cs @@ -211,7 +211,8 @@ public void GivenParentDirHasManifestWithSamePackageIdWhenRunWithPackageIdItShou ""version"": ""1.0.53"", ""commands"": [ ""t-rex"" - ] + ], + ""rollForward"": ""False"" } } }"; From 386ff2e75932094f3ceeeac36e92fa4341ed6c7b Mon Sep 17 00:00:00 2001 From: annie <59816815+JL03-Yue@users.noreply.github.com> Date: Mon, 4 Dec 2023 12:23:34 -0800 Subject: [PATCH 019/577] change default to major --- src/Cli/dotnet/commands/dotnet-tool/run/ToolRunCommand.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Cli/dotnet/commands/dotnet-tool/run/ToolRunCommand.cs b/src/Cli/dotnet/commands/dotnet-tool/run/ToolRunCommand.cs index d94983c6c9a6..b9afdfa90d46 100644 --- a/src/Cli/dotnet/commands/dotnet-tool/run/ToolRunCommand.cs +++ b/src/Cli/dotnet/commands/dotnet-tool/run/ToolRunCommand.cs @@ -37,7 +37,7 @@ public override int Execute() { if (toolManifestPackage.RollForward) { - _rollForward = "LatestMajor"; + _rollForward = "Major"; } } From 0d1ce8b39054028da2f64be0d5a743c88e8690d5 Mon Sep 17 00:00:00 2001 From: annie <59816815+JL03-Yue@users.noreply.github.com> Date: Tue, 5 Dec 2023 21:51:36 -0800 Subject: [PATCH 020/577] change global default to major --- src/Cli/dotnet/ToolPackage/ToolPackageDownloader.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Cli/dotnet/ToolPackage/ToolPackageDownloader.cs b/src/Cli/dotnet/ToolPackage/ToolPackageDownloader.cs index 28a8c916abef..e245b1a52fa5 100644 --- a/src/Cli/dotnet/ToolPackage/ToolPackageDownloader.cs +++ b/src/Cli/dotnet/ToolPackage/ToolPackageDownloader.cs @@ -257,7 +257,7 @@ PackageId packageId var runtimeOptions = jsonObject["runtimeOptions"] as JObject; if (runtimeOptions != null) { - runtimeOptions["rollForward"] = "LatestMajor"; + runtimeOptions["rollForward"] = "Major"; string updateJson = jsonObject.ToString(); File.WriteAllText(runtimeConfigFilePath, updateJson); } From 02c6fc7a6988cc333a8d7733b4e1d863d44ba07f Mon Sep 17 00:00:00 2001 From: annie <59816815+JL03-Yue@users.noreply.github.com> Date: Tue, 5 Dec 2023 21:52:50 -0800 Subject: [PATCH 021/577] add test to local tool roll forward to manifest --- .../ToolInstallLocalCommandTests.cs | 40 +++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/src/Tests/dotnet.Tests/CommandTests/ToolInstallLocalCommandTests.cs b/src/Tests/dotnet.Tests/CommandTests/ToolInstallLocalCommandTests.cs index 898223f16c62..1d9e30dd17f4 100644 --- a/src/Tests/dotnet.Tests/CommandTests/ToolInstallLocalCommandTests.cs +++ b/src/Tests/dotnet.Tests/CommandTests/ToolInstallLocalCommandTests.cs @@ -161,6 +161,46 @@ public void WhenRunWithExplicitManifestFileItShouldAddEntryToExplicitManifestFil _toolManifestFinder.Find(new FilePath(explicitManifestFilePath)).Should().HaveCount(1); } + [Fact] + public void WhenRunWithRollForwardItShouldRollForwardToTrueInManifestFile() + { + ParseResult parseResult = + Parser.Instance.Parse( + $"dotnet tool install {_packageIdA.ToString()} --roll-forward"); + + var installLocalCommand = new ToolInstallLocalCommand( + parseResult, + _toolPackageDownloaderMock, + _toolManifestFinder, + _toolManifestEditor, + _localToolsResolverCache, + _reporter); + + installLocalCommand.Execute().Should().Be(0); + _fileSystem.File.ReadAllText(_manifestFilePath).Should() + .Contain("\"rollForward\": \"True\""); + } + + [Fact] + public void WhenRunWithoutRollForwardItShouldDefaultRollForwardToFalseInManifestFile() + { + ParseResult parseResult = + Parser.Instance.Parse( + $"dotnet tool install {_packageIdA.ToString()}"); + + var installLocalCommand = new ToolInstallLocalCommand( + parseResult, + _toolPackageDownloaderMock, + _toolManifestFinder, + _toolManifestEditor, + _localToolsResolverCache, + _reporter); + + installLocalCommand.Execute().Should().Be(0); + _fileSystem.File.ReadAllText(_manifestFilePath).Should() + .Contain("\"rollForward\": \"False\""); + } + [Fact] public void WhenRunFromToolInstallRedirectCommandWithPackageIdItShouldSaveToCacheAndAddToManifestFile() { From d94b809492de6f7acde230a68a338c2f0b364f27 Mon Sep 17 00:00:00 2001 From: annie <59816815+JL03-Yue@users.noreply.github.com> Date: Wed, 6 Dec 2023 23:57:47 -0800 Subject: [PATCH 022/577] change description --- .../commands/dotnet-tool/install/LocalizableStrings.resx | 2 +- .../dotnet-tool/install/xlf/LocalizableStrings.cs.xlf | 4 ++-- .../dotnet-tool/install/xlf/LocalizableStrings.de.xlf | 4 ++-- .../dotnet-tool/install/xlf/LocalizableStrings.es.xlf | 4 ++-- .../dotnet-tool/install/xlf/LocalizableStrings.fr.xlf | 4 ++-- .../dotnet-tool/install/xlf/LocalizableStrings.it.xlf | 4 ++-- .../dotnet-tool/install/xlf/LocalizableStrings.ja.xlf | 4 ++-- .../dotnet-tool/install/xlf/LocalizableStrings.ko.xlf | 4 ++-- .../dotnet-tool/install/xlf/LocalizableStrings.pl.xlf | 4 ++-- .../dotnet-tool/install/xlf/LocalizableStrings.pt-BR.xlf | 4 ++-- .../dotnet-tool/install/xlf/LocalizableStrings.ru.xlf | 4 ++-- .../dotnet-tool/install/xlf/LocalizableStrings.tr.xlf | 4 ++-- .../dotnet-tool/install/xlf/LocalizableStrings.zh-Hans.xlf | 4 ++-- .../dotnet-tool/install/xlf/LocalizableStrings.zh-Hant.xlf | 4 ++-- 14 files changed, 27 insertions(+), 27 deletions(-) diff --git a/src/Cli/dotnet/commands/dotnet-tool/install/LocalizableStrings.resx b/src/Cli/dotnet/commands/dotnet-tool/install/LocalizableStrings.resx index 01b57e5d7e60..31ffdc6ec674 100644 --- a/src/Cli/dotnet/commands/dotnet-tool/install/LocalizableStrings.resx +++ b/src/Cli/dotnet/commands/dotnet-tool/install/LocalizableStrings.resx @@ -236,6 +236,6 @@ If you would like to create a manifest, use `dotnet new tool-manifest`, usually Create a tool manifest if one isn't found during tool installation. For information on how manifests are located, see https://aka.ms/dotnet/tools/create-manifest-if-needed - Roll forward to framework version (LatestPatch, Minor, LatestMinor, Major, LatestMajor, Disable). + Roll forward to framework version of Major. \ No newline at end of file diff --git a/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.cs.xlf b/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.cs.xlf index 68900b3339c4..5001a7fe78b3 100644 --- a/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.cs.xlf +++ b/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.cs.xlf @@ -84,8 +84,8 @@ Pokud chcete vytvořit manifest, použijte příkaz dotnet new tool-manifest, ob - Roll forward to framework version (LatestPatch, Minor, LatestMinor, Major, LatestMajor, Disable). - Roll forward to framework version (LatestPatch, Minor, LatestMinor, Major, LatestMajor, Disable). + Roll forward to framework version of Major. + Roll forward to framework version of Major. diff --git a/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.de.xlf b/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.de.xlf index 4c3d5448f2f5..ac6bc0c4a217 100644 --- a/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.de.xlf +++ b/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.de.xlf @@ -84,8 +84,8 @@ Wenn Sie ein Manifest erstellen möchten, verwenden Sie "dotnet new tool-manifes - Roll forward to framework version (LatestPatch, Minor, LatestMinor, Major, LatestMajor, Disable). - Roll forward to framework version (LatestPatch, Minor, LatestMinor, Major, LatestMajor, Disable). + Roll forward to framework version of Major. + Roll forward to framework version of Major. diff --git a/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.es.xlf b/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.es.xlf index 297ac8610d7f..f367dc639402 100644 --- a/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.es.xlf +++ b/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.es.xlf @@ -84,8 +84,8 @@ Si desea crear un manifiesto, utilice "dotnet new tool-manifest", normalmente en - Roll forward to framework version (LatestPatch, Minor, LatestMinor, Major, LatestMajor, Disable). - Roll forward to framework version (LatestPatch, Minor, LatestMinor, Major, LatestMajor, Disable). + Roll forward to framework version of Major. + Roll forward to framework version of Major. diff --git a/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.fr.xlf b/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.fr.xlf index 67e0d0040128..e3b70a0d90c7 100644 --- a/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.fr.xlf +++ b/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.fr.xlf @@ -84,8 +84,8 @@ Si vous souhaitez créer un manifeste, utilisez 'dotnet new tool-manifest', gén - Roll forward to framework version (LatestPatch, Minor, LatestMinor, Major, LatestMajor, Disable). - Roll forward to framework version (LatestPatch, Minor, LatestMinor, Major, LatestMajor, Disable). + Roll forward to framework version of Major. + Roll forward to framework version of Major. diff --git a/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.it.xlf b/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.it.xlf index a5592da9b387..d35715ff30b8 100644 --- a/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.it.xlf +++ b/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.it.xlf @@ -84,8 +84,8 @@ Se si vuole creare un manifesto, usare `dotnet new tool-manifest`, in genere nel - Roll forward to framework version (LatestPatch, Minor, LatestMinor, Major, LatestMajor, Disable). - Roll forward to framework version (LatestPatch, Minor, LatestMinor, Major, LatestMajor, Disable). + Roll forward to framework version of Major. + Roll forward to framework version of Major. diff --git a/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.ja.xlf b/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.ja.xlf index 9ade4457ee46..6a02b2828d93 100644 --- a/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.ja.xlf +++ b/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.ja.xlf @@ -84,8 +84,8 @@ If you would like to create a manifest, use `dotnet new tool-manifest`, usually - Roll forward to framework version (LatestPatch, Minor, LatestMinor, Major, LatestMajor, Disable). - Roll forward to framework version (LatestPatch, Minor, LatestMinor, Major, LatestMajor, Disable). + Roll forward to framework version of Major. + Roll forward to framework version of Major. diff --git a/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.ko.xlf b/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.ko.xlf index 432a77aaca22..b8a934984f32 100644 --- a/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.ko.xlf +++ b/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.ko.xlf @@ -84,8 +84,8 @@ If you would like to create a manifest, use `dotnet new tool-manifest`, usually - Roll forward to framework version (LatestPatch, Minor, LatestMinor, Major, LatestMajor, Disable). - Roll forward to framework version (LatestPatch, Minor, LatestMinor, Major, LatestMajor, Disable). + Roll forward to framework version of Major. + Roll forward to framework version of Major. diff --git a/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.pl.xlf b/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.pl.xlf index 90e2c2041534..5b8ab3f66b14 100644 --- a/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.pl.xlf +++ b/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.pl.xlf @@ -84,8 +84,8 @@ Jeśli chcesz utworzyć manifest, użyj polecenia „dotnet new tool-manifest” - Roll forward to framework version (LatestPatch, Minor, LatestMinor, Major, LatestMajor, Disable). - Roll forward to framework version (LatestPatch, Minor, LatestMinor, Major, LatestMajor, Disable). + Roll forward to framework version of Major. + Roll forward to framework version of Major. diff --git a/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.pt-BR.xlf b/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.pt-BR.xlf index 584281d4be93..be5d8d382f66 100644 --- a/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.pt-BR.xlf +++ b/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.pt-BR.xlf @@ -84,8 +84,8 @@ Se quiser criar um manifesto, use `dotnet new tool-manifest`, normalmente no dir - Roll forward to framework version (LatestPatch, Minor, LatestMinor, Major, LatestMajor, Disable). - Roll forward to framework version (LatestPatch, Minor, LatestMinor, Major, LatestMajor, Disable). + Roll forward to framework version of Major. + Roll forward to framework version of Major. diff --git a/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.ru.xlf b/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.ru.xlf index 346355c70d69..bb0cee2355f8 100644 --- a/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.ru.xlf +++ b/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.ru.xlf @@ -84,8 +84,8 @@ If you would like to create a manifest, use `dotnet new tool-manifest`, usually - Roll forward to framework version (LatestPatch, Minor, LatestMinor, Major, LatestMajor, Disable). - Roll forward to framework version (LatestPatch, Minor, LatestMinor, Major, LatestMajor, Disable). + Roll forward to framework version of Major. + Roll forward to framework version of Major. diff --git a/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.tr.xlf b/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.tr.xlf index 5252e7bf92cc..2d5f65fbc9be 100644 --- a/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.tr.xlf +++ b/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.tr.xlf @@ -84,8 +84,8 @@ Bir bildirim oluşturmak istiyorsanız 'dotnet new tool-manifest' ifadesini kull - Roll forward to framework version (LatestPatch, Minor, LatestMinor, Major, LatestMajor, Disable). - Roll forward to framework version (LatestPatch, Minor, LatestMinor, Major, LatestMajor, Disable). + Roll forward to framework version of Major. + Roll forward to framework version of Major. diff --git a/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.zh-Hans.xlf b/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.zh-Hans.xlf index 77e1ecc77fc7..de4a79429d6f 100644 --- a/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.zh-Hans.xlf +++ b/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.zh-Hans.xlf @@ -84,8 +84,8 @@ If you would like to create a manifest, use `dotnet new tool-manifest`, usually - Roll forward to framework version (LatestPatch, Minor, LatestMinor, Major, LatestMajor, Disable). - Roll forward to framework version (LatestPatch, Minor, LatestMinor, Major, LatestMajor, Disable). + Roll forward to framework version of Major. + Roll forward to framework version of Major. diff --git a/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.zh-Hant.xlf b/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.zh-Hant.xlf index f3db8875cf83..e3a398c66034 100644 --- a/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.zh-Hant.xlf +++ b/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.zh-Hant.xlf @@ -84,8 +84,8 @@ If you would like to create a manifest, use `dotnet new tool-manifest`, usually - Roll forward to framework version (LatestPatch, Minor, LatestMinor, Major, LatestMajor, Disable). - Roll forward to framework version (LatestPatch, Minor, LatestMinor, Major, LatestMajor, Disable). + Roll forward to framework version of Major. + Roll forward to framework version of Major. From 28be00f3a3daf1095ecb378cdc633f4db20c159c Mon Sep 17 00:00:00 2001 From: annie <59816815+JL03-Yue@users.noreply.github.com> Date: Mon, 18 Dec 2023 22:51:14 -0800 Subject: [PATCH 023/577] remove extra using --- src/Cli/dotnet/ToolManifest/ToolManifestPackage.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Cli/dotnet/ToolManifest/ToolManifestPackage.cs b/src/Cli/dotnet/ToolManifest/ToolManifestPackage.cs index 5e90154381eb..4cb664884e63 100644 --- a/src/Cli/dotnet/ToolManifest/ToolManifestPackage.cs +++ b/src/Cli/dotnet/ToolManifest/ToolManifestPackage.cs @@ -1,7 +1,6 @@ // 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.Eventing.Reader; using Microsoft.DotNet.Cli.Utils; using Microsoft.DotNet.ToolPackage; using Microsoft.Extensions.EnvironmentAbstractions; From 6ff1d8dcaaa4daac8a6af1b10ff657badc0b73f0 Mon Sep 17 00:00:00 2001 From: annie <59816815+JL03-Yue@users.noreply.github.com> Date: Mon, 18 Dec 2023 23:02:37 -0800 Subject: [PATCH 024/577] update rollforward to write bool in manifest file --- src/Cli/dotnet/ToolManifest/ToolManifestEditor.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Cli/dotnet/ToolManifest/ToolManifestEditor.cs b/src/Cli/dotnet/ToolManifest/ToolManifestEditor.cs index af6a3b9cb1fc..66f340bf5d40 100644 --- a/src/Cli/dotnet/ToolManifest/ToolManifestEditor.cs +++ b/src/Cli/dotnet/ToolManifest/ToolManifestEditor.cs @@ -396,7 +396,7 @@ public string ToJson() writer.WriteStringValue(toolCommandName); } writer.WriteEndArray(); - writer.WriteString(JsonPropertyRollForward, tool.RollForward.ToString()); + writer.WriteBoolean(JsonPropertyRollForward, tool.RollForward); writer.WriteEndObject(); } From 7d04503f26f20b659102225dfbcee0aafbfe9a5b Mon Sep 17 00:00:00 2001 From: annie <59816815+JL03-Yue@users.noreply.github.com> Date: Mon, 18 Dec 2023 23:03:52 -0800 Subject: [PATCH 025/577] update format --- src/Tests/dotnet.Tests/CommandTests/ToolRunCommandTests.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/Tests/dotnet.Tests/CommandTests/ToolRunCommandTests.cs b/src/Tests/dotnet.Tests/CommandTests/ToolRunCommandTests.cs index 0b93daa1ecfa..c13e6b852ac2 100644 --- a/src/Tests/dotnet.Tests/CommandTests/ToolRunCommandTests.cs +++ b/src/Tests/dotnet.Tests/CommandTests/ToolRunCommandTests.cs @@ -40,8 +40,7 @@ public void WhenRunWithRollForwardOptionItShouldIncludeRollForwardInNativeHost() { var parseResult = Parser.Instance.Parse($"dotnet tool run $TOOLCOMMAND$ --roll-forward Major"); - var toolRunCommand = new ToolRunCommand( - parseResult); + var toolRunCommand = new ToolRunCommand(parseResult); (FilePath fakeExecutable, LocalToolsCommandResolver localToolsCommandResolver) = DefaultSetup("dotnet-a"); IEnumerable testForwardArgument = Enumerable.Empty(); From ae814575db068a830497b7debb630c128ea1e5d2 Mon Sep 17 00:00:00 2001 From: annie <59816815+JL03-Yue@users.noreply.github.com> Date: Mon, 8 Jan 2024 14:31:57 -0800 Subject: [PATCH 026/577] change run and install option to allow roll forward and update tests --- .../dotnet-tool/install/ToolInstallCommandParser.cs | 2 +- src/Cli/dotnet/commands/dotnet-tool/run/ToolRunCommand.cs | 6 +++--- .../dotnet/commands/dotnet-tool/run/ToolRunCommandParser.cs | 2 +- src/Tests/dotnet.Tests/CommandTests/ToolRunCommandTests.cs | 4 ++-- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/Cli/dotnet/commands/dotnet-tool/install/ToolInstallCommandParser.cs b/src/Cli/dotnet/commands/dotnet-tool/install/ToolInstallCommandParser.cs index 9a6f2d915d9c..7fb4ee1f5d3d 100644 --- a/src/Cli/dotnet/commands/dotnet-tool/install/ToolInstallCommandParser.cs +++ b/src/Cli/dotnet/commands/dotnet-tool/install/ToolInstallCommandParser.cs @@ -56,7 +56,7 @@ internal static class ToolInstallCommandParser Description = CommonLocalizableStrings.ArchitectureOptionDescription }; - public static readonly CliOption RollForwardOption = new("--roll-forward") + public static readonly CliOption RollForwardOption = new("--allow-roll-forward") { Description = LocalizableStrings.RollForwardOptionDescription }; diff --git a/src/Cli/dotnet/commands/dotnet-tool/run/ToolRunCommand.cs b/src/Cli/dotnet/commands/dotnet-tool/run/ToolRunCommand.cs index b9afdfa90d46..6b3f4bd20062 100644 --- a/src/Cli/dotnet/commands/dotnet-tool/run/ToolRunCommand.cs +++ b/src/Cli/dotnet/commands/dotnet-tool/run/ToolRunCommand.cs @@ -15,7 +15,7 @@ internal class ToolRunCommand : CommandBase private readonly string _toolCommandName; private readonly LocalToolsCommandResolver _localToolsCommandResolver; private readonly IEnumerable _forwardArgument; - public string _rollForward; + public bool _rollForward; private readonly ToolManifestFinder _toolManifest; public ToolRunCommand( @@ -37,7 +37,7 @@ public override int Execute() { if (toolManifestPackage.RollForward) { - _rollForward = "Major"; + _rollForward = true; } } @@ -45,7 +45,7 @@ public override int Execute() { // since LocalToolsCommandResolver is a resolver, and all resolver input have dotnet- CommandName = $"dotnet-{_toolCommandName}", - CommandArguments = (_rollForward != null ? new List { "--roll-forward", _rollForward } : Enumerable.Empty()).Concat(_forwardArgument) + CommandArguments = (_rollForward != false ? new List { "--roll-forward", "Major" } : Enumerable.Empty()).Concat(_forwardArgument) }); if (commandspec == null) { diff --git a/src/Cli/dotnet/commands/dotnet-tool/run/ToolRunCommandParser.cs b/src/Cli/dotnet/commands/dotnet-tool/run/ToolRunCommandParser.cs index c9c7c51d6327..228c722327e5 100644 --- a/src/Cli/dotnet/commands/dotnet-tool/run/ToolRunCommandParser.cs +++ b/src/Cli/dotnet/commands/dotnet-tool/run/ToolRunCommandParser.cs @@ -20,7 +20,7 @@ internal static class ToolRunCommandParser Description = "arguments forwarded to the tool" }; - public static readonly CliOption RollForwardOption = new("--roll-forward") + public static readonly CliOption RollForwardOption = new("--allow-roll-forward") { Description = LocalizableStrings.RollForwardDescription }; diff --git a/src/Tests/dotnet.Tests/CommandTests/ToolRunCommandTests.cs b/src/Tests/dotnet.Tests/CommandTests/ToolRunCommandTests.cs index c13e6b852ac2..3f4c2781c7b5 100644 --- a/src/Tests/dotnet.Tests/CommandTests/ToolRunCommandTests.cs +++ b/src/Tests/dotnet.Tests/CommandTests/ToolRunCommandTests.cs @@ -48,11 +48,11 @@ public void WhenRunWithRollForwardOptionItShouldIncludeRollForwardInNativeHost() var result = localToolsCommandResolver.Resolve(new CommandResolverArguments() { CommandName = "dotnet-a", - CommandArguments = (toolRunCommand._rollForward != null ? new List { "--roll-forward", toolRunCommand._rollForward } : Enumerable.Empty()).Concat(testForwardArgument) + CommandArguments = (toolRunCommand._rollForward != false ? new List { "--roll-forward", "Major" } : Enumerable.Empty()).Concat(testForwardArgument) }); result.Should().NotBeNull(); - result.Args.Should().Contain("--roll-forward", toolRunCommand._rollForward, fakeExecutable.Value); + result.Args.Should().Contain("--roll-forward", "Major", fakeExecutable.Value); } private (FilePath, LocalToolsCommandResolver) DefaultSetup(string toolCommand) From b8b620ee5766cd0b6d68a9a785223f165d6bed92 Mon Sep 17 00:00:00 2001 From: annie <59816815+JL03-Yue@users.noreply.github.com> Date: Mon, 8 Jan 2024 14:39:01 -0800 Subject: [PATCH 027/577] change names --- .../install/ToolInstallGlobalOrToolPathCommand.cs | 6 +++--- .../dotnet-tool/install/ToolInstallLocalCommand.cs | 6 +++--- src/Cli/dotnet/commands/dotnet-tool/run/ToolRunCommand.cs | 8 ++++---- .../dotnet.Tests/CommandTests/ToolRunCommandTests.cs | 2 +- 4 files changed, 11 insertions(+), 11 deletions(-) diff --git a/src/Cli/dotnet/commands/dotnet-tool/install/ToolInstallGlobalOrToolPathCommand.cs b/src/Cli/dotnet/commands/dotnet-tool/install/ToolInstallGlobalOrToolPathCommand.cs index 3875016dcafb..cce024b5f536 100644 --- a/src/Cli/dotnet/commands/dotnet-tool/install/ToolInstallGlobalOrToolPathCommand.cs +++ b/src/Cli/dotnet/commands/dotnet-tool/install/ToolInstallGlobalOrToolPathCommand.cs @@ -43,7 +43,7 @@ internal class ToolInstallGlobalOrToolPathCommand : CommandBase private readonly string _toolPath; private readonly string _architectureOption; private IEnumerable _forwardRestoreArguments; - private readonly bool _rollForward; + private readonly bool _allowRollForward; public ToolInstallGlobalOrToolPathCommand( ParseResult parseResult, @@ -81,7 +81,7 @@ public ToolInstallGlobalOrToolPathCommand( Interactive: parseResult.GetValue(ToolCommandRestorePassThroughOptions.InteractiveRestoreOption)); nugetPackageDownloader ??= new NuGetPackageDownloader(tempDir, verboseLogger: new NullLogger(), restoreActionConfig: restoreAction); _shellShimTemplateFinder = new ShellShimTemplateFinder(nugetPackageDownloader, tempDir, packageSourceLocation); - _rollForward = parseResult.GetValue(ToolInstallCommandParser.RollForwardOption); + _allowRollForward = parseResult.GetValue(ToolInstallCommandParser.RollForwardOption); _reporter = (reporter ?? Reporter.Output); _errorReporter = (reporter ?? Reporter.Error); @@ -135,7 +135,7 @@ public override int Execute() targetFramework: _framework, verbosity: _verbosity, isGlobalTool: true, - isGlobalToolRollForward: _rollForward + isGlobalToolRollForward: _allowRollForward ); NuGetFramework framework; diff --git a/src/Cli/dotnet/commands/dotnet-tool/install/ToolInstallLocalCommand.cs b/src/Cli/dotnet/commands/dotnet-tool/install/ToolInstallLocalCommand.cs index 871d302e35df..333f539192e2 100644 --- a/src/Cli/dotnet/commands/dotnet-tool/install/ToolInstallLocalCommand.cs +++ b/src/Cli/dotnet/commands/dotnet-tool/install/ToolInstallLocalCommand.cs @@ -22,7 +22,7 @@ internal class ToolInstallLocalCommand : CommandBase private readonly string _explicitManifestFile; private readonly bool _createManifestIfNeeded; - private readonly bool _rollForward; + private readonly bool _allowRollForward; public ToolInstallLocalCommand( ParseResult parseResult, @@ -45,7 +45,7 @@ public ToolInstallLocalCommand( _toolManifestEditor = toolManifestEditor ?? new ToolManifestEditor(); _localToolsResolverCache = localToolsResolverCache ?? new LocalToolsResolverCache(); _toolLocalPackageInstaller = new ToolInstallLocalInstaller(parseResult, toolPackageDownloader); - _rollForward = parseResult.GetValue(ToolInstallCommandParser.RollForwardOption); + _allowRollForward = parseResult.GetValue(ToolInstallCommandParser.RollForwardOption); } public override int Execute() @@ -64,7 +64,7 @@ public int Install(FilePath manifestFile) toolDownloadedPackage.Id, toolDownloadedPackage.Version, toolDownloadedPackage.Commands.Select(c => c.Name).ToArray(), - _rollForward); + _allowRollForward); _localToolsResolverCache.SaveToolPackage( toolDownloadedPackage, diff --git a/src/Cli/dotnet/commands/dotnet-tool/run/ToolRunCommand.cs b/src/Cli/dotnet/commands/dotnet-tool/run/ToolRunCommand.cs index 6b3f4bd20062..f3c0330096d2 100644 --- a/src/Cli/dotnet/commands/dotnet-tool/run/ToolRunCommand.cs +++ b/src/Cli/dotnet/commands/dotnet-tool/run/ToolRunCommand.cs @@ -15,7 +15,7 @@ internal class ToolRunCommand : CommandBase private readonly string _toolCommandName; private readonly LocalToolsCommandResolver _localToolsCommandResolver; private readonly IEnumerable _forwardArgument; - public bool _rollForward; + public bool _allowRollForward; private readonly ToolManifestFinder _toolManifest; public ToolRunCommand( @@ -27,7 +27,7 @@ public ToolRunCommand( _toolCommandName = result.GetValue(ToolRunCommandParser.CommandNameArgument); _forwardArgument = result.GetValue(ToolRunCommandParser.CommandArgument); _localToolsCommandResolver = localToolsCommandResolver ?? new LocalToolsCommandResolver(); - _rollForward = result.GetValue(ToolRunCommandParser.RollForwardOption); + _allowRollForward = result.GetValue(ToolRunCommandParser.RollForwardOption); _toolManifest = toolManifest ?? new ToolManifestFinder(new DirectoryPath(Directory.GetCurrentDirectory())); } @@ -37,7 +37,7 @@ public override int Execute() { if (toolManifestPackage.RollForward) { - _rollForward = true; + _allowRollForward = true; } } @@ -45,7 +45,7 @@ public override int Execute() { // since LocalToolsCommandResolver is a resolver, and all resolver input have dotnet- CommandName = $"dotnet-{_toolCommandName}", - CommandArguments = (_rollForward != false ? new List { "--roll-forward", "Major" } : Enumerable.Empty()).Concat(_forwardArgument) + CommandArguments = (_allowRollForward != false ? new List { "--roll-forward", "Major" } : Enumerable.Empty()).Concat(_forwardArgument) }); if (commandspec == null) { diff --git a/src/Tests/dotnet.Tests/CommandTests/ToolRunCommandTests.cs b/src/Tests/dotnet.Tests/CommandTests/ToolRunCommandTests.cs index 3f4c2781c7b5..e95186acff8e 100644 --- a/src/Tests/dotnet.Tests/CommandTests/ToolRunCommandTests.cs +++ b/src/Tests/dotnet.Tests/CommandTests/ToolRunCommandTests.cs @@ -48,7 +48,7 @@ public void WhenRunWithRollForwardOptionItShouldIncludeRollForwardInNativeHost() var result = localToolsCommandResolver.Resolve(new CommandResolverArguments() { CommandName = "dotnet-a", - CommandArguments = (toolRunCommand._rollForward != false ? new List { "--roll-forward", "Major" } : Enumerable.Empty()).Concat(testForwardArgument) + CommandArguments = (toolRunCommand._allowRollForward != false ? new List { "--roll-forward", "Major" } : Enumerable.Empty()).Concat(testForwardArgument) }); result.Should().NotBeNull(); From c141353a3f6d8429f3b4396f68aad634d5fb95a0 Mon Sep 17 00:00:00 2001 From: annie <59816815+JL03-Yue@users.noreply.github.com> Date: Wed, 10 Jan 2024 14:55:03 -0800 Subject: [PATCH 028/577] fix read bool error --- src/Cli/dotnet/ToolManifest/ToolManifestEditor.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Cli/dotnet/ToolManifest/ToolManifestEditor.cs b/src/Cli/dotnet/ToolManifest/ToolManifestEditor.cs index 66f340bf5d40..ec0fbc2a3ad1 100644 --- a/src/Cli/dotnet/ToolManifest/ToolManifestEditor.cs +++ b/src/Cli/dotnet/ToolManifest/ToolManifestEditor.cs @@ -206,9 +206,9 @@ private SerializableLocalToolsManifest DeserializeLocalToolsManifest(FilePath po serializableLocalToolSinglePackage.Commands = commands.ToArray(); } - if (toolJson.Value.TryGetStringValue(JsonPropertyRollForward, out var rollForwardJson)) + if (toolJson.Value.TryGetBooleanValue(JsonPropertyRollForward, out var rollForwardJson)) { - serializableLocalToolSinglePackage.RollForward = bool.Parse(rollForwardJson); + serializableLocalToolSinglePackage.RollForward = rollForwardJson; } serializableLocalToolsManifest.Tools.Add(serializableLocalToolSinglePackage); From 421714e15098d537b1e02888395697cec2edd76c Mon Sep 17 00:00:00 2001 From: annie <59816815+JL03-Yue@users.noreply.github.com> Date: Thu, 11 Jan 2024 13:58:47 -0800 Subject: [PATCH 029/577] fix tests and add roll forward option --- .../dotnet-tool/install/ToolInstallCommandParser.cs | 1 + .../CommandTests/ToolInstallLocalCommandTests.cs | 6 +++--- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/Cli/dotnet/commands/dotnet-tool/install/ToolInstallCommandParser.cs b/src/Cli/dotnet/commands/dotnet-tool/install/ToolInstallCommandParser.cs index 31191d99366a..f07134b986c8 100644 --- a/src/Cli/dotnet/commands/dotnet-tool/install/ToolInstallCommandParser.cs +++ b/src/Cli/dotnet/commands/dotnet-tool/install/ToolInstallCommandParser.cs @@ -92,6 +92,7 @@ private static CliCommand ConstructCommand() command.Options.Add(ArchitectureOption); command.Options.Add(CreateManifestIfNeededOption); command.Options.Add(AllowPackageDowngradeOption); + command.Options.Add(RollForwardOption); command.SetAction((parseResult) => new ToolInstallCommand(parseResult).Execute()); diff --git a/src/Tests/dotnet.Tests/CommandTests/ToolInstallLocalCommandTests.cs b/src/Tests/dotnet.Tests/CommandTests/ToolInstallLocalCommandTests.cs index 8014debf94ec..d873824680c6 100644 --- a/src/Tests/dotnet.Tests/CommandTests/ToolInstallLocalCommandTests.cs +++ b/src/Tests/dotnet.Tests/CommandTests/ToolInstallLocalCommandTests.cs @@ -160,7 +160,7 @@ public void WhenRunWithRollForwardItShouldRollForwardToTrueInManifestFile() { ParseResult parseResult = Parser.Instance.Parse( - $"dotnet tool install {_packageIdA.ToString()} --roll-forward"); + $"dotnet tool install {_packageIdA.ToString()} --allow-roll-forward"); var installLocalCommand = new ToolInstallLocalCommand( parseResult, @@ -172,7 +172,7 @@ public void WhenRunWithRollForwardItShouldRollForwardToTrueInManifestFile() installLocalCommand.Execute().Should().Be(0); _fileSystem.File.ReadAllText(_manifestFilePath).Should() - .Contain("\"rollForward\": \"True\""); + .Contain("\"rollForward\": true"); } [Fact] @@ -192,7 +192,7 @@ public void WhenRunWithoutRollForwardItShouldDefaultRollForwardToFalseInManifest installLocalCommand.Execute().Should().Be(0); _fileSystem.File.ReadAllText(_manifestFilePath).Should() - .Contain("\"rollForward\": \"False\""); + .Contain("\"rollForward\": false"); } [Fact] From 0b261a74353a9ea806ecf01658a8711bac59fe9c Mon Sep 17 00:00:00 2001 From: annie <59816815+JL03-Yue@users.noreply.github.com> Date: Thu, 11 Jan 2024 14:07:53 -0800 Subject: [PATCH 030/577] use sdk test --- src/Tests/dotnet.Tests/CommandTests/ToolRunCommandTests.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Tests/dotnet.Tests/CommandTests/ToolRunCommandTests.cs b/src/Tests/dotnet.Tests/CommandTests/ToolRunCommandTests.cs index e95186acff8e..b8b7e867b7ee 100644 --- a/src/Tests/dotnet.Tests/CommandTests/ToolRunCommandTests.cs +++ b/src/Tests/dotnet.Tests/CommandTests/ToolRunCommandTests.cs @@ -15,7 +15,7 @@ namespace Microsoft.DotNet.Tests.Commands.Tool { - public class ToolRunCommandTests + public class ToolRunCommandTests: SdkTest { private readonly IFileSystem _fileSystem; private const string ManifestFilename = "dotnet-tools.json"; @@ -23,7 +23,7 @@ public class ToolRunCommandTests private DirectoryPath _nugetGlobalPackagesFolder; private readonly LocalToolsResolverCache _localToolsResolverCache; - public ToolRunCommandTests() + public ToolRunCommandTests(ITestOutputHelper log) : base(log) { _fileSystem = new FileSystemMockBuilder().UseCurrentSystemTemporaryDirectory().Build(); _nugetGlobalPackagesFolder = new DirectoryPath(NuGetGlobalPackagesFolder.GetLocation()); From cd8830542b51fa0caa499e32ea405269e2301f96 Mon Sep 17 00:00:00 2001 From: annie <59816815+JL03-Yue@users.noreply.github.com> Date: Thu, 11 Jan 2024 15:53:38 -0800 Subject: [PATCH 031/577] fix test use _testAssetsManager.CreateTestDirectory --- .../CommandTests/ToolRunCommandTests.cs | 36 +++++++++---------- 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/src/Tests/dotnet.Tests/CommandTests/ToolRunCommandTests.cs b/src/Tests/dotnet.Tests/CommandTests/ToolRunCommandTests.cs index b8b7e867b7ee..c56286bc7b0f 100644 --- a/src/Tests/dotnet.Tests/CommandTests/ToolRunCommandTests.cs +++ b/src/Tests/dotnet.Tests/CommandTests/ToolRunCommandTests.cs @@ -17,28 +17,18 @@ namespace Microsoft.DotNet.Tests.Commands.Tool { public class ToolRunCommandTests: SdkTest { - private readonly IFileSystem _fileSystem; private const string ManifestFilename = "dotnet-tools.json"; - private readonly string _testDirectoryRoot; private DirectoryPath _nugetGlobalPackagesFolder; - private readonly LocalToolsResolverCache _localToolsResolverCache; public ToolRunCommandTests(ITestOutputHelper log) : base(log) { - _fileSystem = new FileSystemMockBuilder().UseCurrentSystemTemporaryDirectory().Build(); _nugetGlobalPackagesFolder = new DirectoryPath(NuGetGlobalPackagesFolder.GetLocation()); - string temporaryDirectory = _fileSystem.Directory.CreateTemporaryDirectory().DirectoryPath; - _localToolsResolverCache = new LocalToolsResolverCache( - _fileSystem, - new DirectoryPath(Path.Combine(temporaryDirectory, "cache"))); - _testDirectoryRoot = _fileSystem.Directory.CreateTemporaryDirectory().DirectoryPath; - } [Fact] public void WhenRunWithRollForwardOptionItShouldIncludeRollForwardInNativeHost() { - var parseResult = Parser.Instance.Parse($"dotnet tool run $TOOLCOMMAND$ --roll-forward Major"); + var parseResult = Parser.Instance.Parse($"dotnet tool run $TOOLCOMMAND$ --allow-roll-forward"); var toolRunCommand = new ToolRunCommand(parseResult); @@ -57,16 +47,26 @@ public void WhenRunWithRollForwardOptionItShouldIncludeRollForwardInNativeHost() private (FilePath, LocalToolsCommandResolver) DefaultSetup(string toolCommand) { + var testDirectoryRoot = _testAssetsManager.CreateTestDirectory(); + var fileSystem = new FileSystemWrapper(); NuGetVersion packageVersionA = NuGetVersion.Parse("1.0.4"); - _fileSystem.File.WriteAllText(Path.Combine(_testDirectoryRoot, ManifestFilename), + + fileSystem.File.WriteAllText(Path.Combine(testDirectoryRoot.Path, ManifestFilename), _jsonContent.Replace("$TOOLCOMMAND$", toolCommand)); ToolManifestFinder toolManifest = - new ToolManifestFinder(new DirectoryPath(_testDirectoryRoot), _fileSystem, new FakeDangerousFileDetector()); + new ToolManifestFinder(new DirectoryPath(testDirectoryRoot.Path), fileSystem, new FakeDangerousFileDetector()); ToolCommandName toolCommandNameA = new ToolCommandName(toolCommand); FilePath fakeExecutable = _nugetGlobalPackagesFolder.WithFile("fakeExecutable.dll"); - _fileSystem.Directory.CreateDirectory(_nugetGlobalPackagesFolder.Value); - _fileSystem.File.CreateEmptyFile(fakeExecutable.Value); - _localToolsResolverCache.Save( + + fileSystem.Directory.CreateDirectory(_nugetGlobalPackagesFolder.Value); + fileSystem.File.CreateEmptyFile(fakeExecutable.Value); + + string temporaryDirectory = fileSystem.Directory.CreateTemporaryDirectory().DirectoryPath; + var localToolsResolverCache = new LocalToolsResolverCache( + fileSystem, + new DirectoryPath(Path.Combine(temporaryDirectory, "cache"))); + + localToolsResolverCache.Save( new Dictionary { [new RestoredCommandIdentifier( @@ -80,8 +80,8 @@ [new RestoredCommandIdentifier( var localToolsCommandResolver = new LocalToolsCommandResolver( toolManifest, - _localToolsResolverCache, - _fileSystem); + localToolsResolverCache, + fileSystem); return (fakeExecutable, localToolsCommandResolver); } From 16d98c6dab01491633813126cb70eb58b91e80d3 Mon Sep 17 00:00:00 2001 From: annie <59816815+JL03-Yue@users.noreply.github.com> Date: Thu, 11 Jan 2024 16:35:50 -0800 Subject: [PATCH 032/577] moving check roll forward logic to GetPackageCommandSpecUsingMuxer --- .../LocalToolsCommandResolver.cs | 10 +++++++--- .../commands/dotnet-tool/run/ToolRunCommand.cs | 16 +++++----------- 2 files changed, 12 insertions(+), 14 deletions(-) diff --git a/src/Cli/dotnet/CommandFactory/CommandResolution/LocalToolsCommandResolver.cs b/src/Cli/dotnet/CommandFactory/CommandResolution/LocalToolsCommandResolver.cs index fa9a90094d28..5b18fc86ab9b 100644 --- a/src/Cli/dotnet/CommandFactory/CommandResolution/LocalToolsCommandResolver.cs +++ b/src/Cli/dotnet/CommandFactory/CommandResolution/LocalToolsCommandResolver.cs @@ -1,6 +1,7 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using System.Linq; using Microsoft.DotNet.Cli; using Microsoft.DotNet.Cli.Utils; using Microsoft.DotNet.ToolManifest; @@ -27,7 +28,7 @@ public LocalToolsCommandResolver( _fileSystem = fileSystem ?? new FileSystemWrapper(); } - public CommandSpec ResolveStrict(CommandResolverArguments arguments) + public CommandSpec ResolveStrict(CommandResolverArguments arguments, bool allowRollForward = false) { if (arguments == null || string.IsNullOrWhiteSpace(arguments.CommandName)) { @@ -40,7 +41,7 @@ public CommandSpec ResolveStrict(CommandResolverArguments arguments) } var resolveResult = GetPackageCommandSpecUsingMuxer(arguments, - new ToolCommandName(arguments.CommandName.Substring(LeadingDotnetPrefix.Length))); + new ToolCommandName(arguments.CommandName.Substring(LeadingDotnetPrefix.Length)), allowRollForward); return resolveResult; } @@ -73,13 +74,16 @@ public CommandSpec Resolve(CommandResolverArguments arguments) } private CommandSpec GetPackageCommandSpecUsingMuxer(CommandResolverArguments arguments, - ToolCommandName toolCommandName) + ToolCommandName toolCommandName, bool allowRollForward = false) { if (!_toolManifest.TryFind(toolCommandName, out var toolManifestPackage)) { return null; } + var commandArgument = (allowRollForward != false ? new List { "--roll-forward", "Major" } : Enumerable.Empty()).Concat(arguments.CommandArguments); + arguments.CommandArguments = commandArgument; + if (_localToolsResolverCache.TryLoad( new RestoredCommandIdentifier( toolManifestPackage.PackageId, diff --git a/src/Cli/dotnet/commands/dotnet-tool/run/ToolRunCommand.cs b/src/Cli/dotnet/commands/dotnet-tool/run/ToolRunCommand.cs index f3c0330096d2..389311fa02e0 100644 --- a/src/Cli/dotnet/commands/dotnet-tool/run/ToolRunCommand.cs +++ b/src/Cli/dotnet/commands/dotnet-tool/run/ToolRunCommand.cs @@ -33,20 +33,14 @@ public ToolRunCommand( public override int Execute() { - if (_toolManifest.TryFind(new ToolCommandName(_toolCommandName), out var toolManifestPackage)) - { - if (toolManifestPackage.RollForward) - { - _allowRollForward = true; - } - } - - CommandSpec commandspec = _localToolsCommandResolver.ResolveStrict(new CommandResolverArguments() + CommandSpec commandspec = _localToolsCommandResolver.ResolveStrict(new CommandResolverArguments() { // since LocalToolsCommandResolver is a resolver, and all resolver input have dotnet- CommandName = $"dotnet-{_toolCommandName}", - CommandArguments = (_allowRollForward != false ? new List { "--roll-forward", "Major" } : Enumerable.Empty()).Concat(_forwardArgument) - }); + CommandArguments = _forwardArgument, + + }, _allowRollForward); ; + if (commandspec == null) { throw new GracefulException( From aa9b5461162bff4b9207fc09f05e98b07b7442e5 Mon Sep 17 00:00:00 2001 From: Forgind <12969783+Forgind@users.noreply.github.com> Date: Fri, 12 Jan 2024 13:10:19 -0800 Subject: [PATCH 033/577] 3xx branding --- eng/Versions.props | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/eng/Versions.props b/eng/Versions.props index 0bf09f85e818..e63f5bcc6065 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -11,8 +11,8 @@ - 8.0.200 - 8.0.200 + 8.0.300 + 8.0.300 false release From cb1c7f5c5fb2b3e49cc7efdec80c1f941c4802aa Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" Date: Fri, 12 Jan 2024 23:09:12 +0000 Subject: [PATCH 034/577] Update dependencies from https://github.com/dotnet/msbuild build 20240110.3 Microsoft.SourceBuild.Intermediate.msbuild , Microsoft.Build , Microsoft.Build.Localization From Version 17.9.2-preview-24055-03 -> To Version 17.10.0-preview-24060-03 --- NuGet.config | 1 - eng/Version.Details.xml | 12 ++++++------ eng/Versions.props | 4 ++-- 3 files changed, 8 insertions(+), 9 deletions(-) diff --git a/NuGet.config b/NuGet.config index 68766c29f33f..bade25373cf4 100644 --- a/NuGet.config +++ b/NuGet.config @@ -13,7 +13,6 @@ - diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index d9afa9eaed9e..a6edf8cac5a9 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -51,17 +51,17 @@ https://github.com/dotnet/emsdk 2406616d0e3a31d80b326e27c156955bfa41c791 - + https://github.com/dotnet/msbuild - bb6fadf23225f5097f4e05ed507d93683a21ae56 + 1725b247e8737804076c8ff3b09fcee02ecdf51e - + https://github.com/dotnet/msbuild - bb6fadf23225f5097f4e05ed507d93683a21ae56 + 1725b247e8737804076c8ff3b09fcee02ecdf51e - + https://github.com/dotnet/msbuild - bb6fadf23225f5097f4e05ed507d93683a21ae56 + 1725b247e8737804076c8ff3b09fcee02ecdf51e diff --git a/eng/Versions.props b/eng/Versions.props index e63f5bcc6065..c16ab418707a 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -105,7 +105,7 @@ - 17.9.2 + 17.10.0-preview-24060-03 $(MicrosoftBuildPackageVersion) - 7.0.0-preview.24053.4 - 7.0.0-preview.24053.4 - 7.0.0-preview.24053.4 + 7.0.0-preview.24062.4 + 7.0.0-preview.24062.4 + 7.0.0-preview.24062.4 From 845a23a0b6f2ff8f729df5c02baf9644bedacbc6 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" Date: Fri, 12 Jan 2024 23:10:34 +0000 Subject: [PATCH 036/577] Update dependencies from https://github.com/dotnet/roslyn build 20240112.5 Microsoft.CodeAnalysis , Microsoft.CodeAnalysis.CSharp , Microsoft.CodeAnalysis.CSharp.CodeStyle , Microsoft.CodeAnalysis.CSharp.Features , Microsoft.CodeAnalysis.CSharp.Workspaces , Microsoft.CodeAnalysis.Workspaces.MSBuild , Microsoft.Net.Compilers.Toolset From Version 4.9.0-3.24054.13 -> To Version 4.10.0-1.24062.5 --- eng/Version.Details.xml | 28 ++++++++++++++-------------- eng/Versions.props | 14 +++++++------- 2 files changed, 21 insertions(+), 21 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index d9afa9eaed9e..b65e229824c9 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -78,34 +78,34 @@ 2651752953c0d41c8c7b8d661cf2237151af33d0 - + https://github.com/dotnet/roslyn - 28e49407a6e4744819bd471707259b99964e441c + dfbd88a138bd8f012ac1e5029a3087fe246e96ff - + https://github.com/dotnet/roslyn - 28e49407a6e4744819bd471707259b99964e441c + dfbd88a138bd8f012ac1e5029a3087fe246e96ff - + https://github.com/dotnet/roslyn - 28e49407a6e4744819bd471707259b99964e441c + dfbd88a138bd8f012ac1e5029a3087fe246e96ff - + https://github.com/dotnet/roslyn - 28e49407a6e4744819bd471707259b99964e441c + dfbd88a138bd8f012ac1e5029a3087fe246e96ff - + https://github.com/dotnet/roslyn - 28e49407a6e4744819bd471707259b99964e441c + dfbd88a138bd8f012ac1e5029a3087fe246e96ff - + https://github.com/dotnet/roslyn - 28e49407a6e4744819bd471707259b99964e441c + dfbd88a138bd8f012ac1e5029a3087fe246e96ff - + https://github.com/dotnet/roslyn - 28e49407a6e4744819bd471707259b99964e441c + dfbd88a138bd8f012ac1e5029a3087fe246e96ff https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore diff --git a/eng/Versions.props b/eng/Versions.props index e63f5bcc6065..b12dbb466a44 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -139,13 +139,13 @@ - 4.9.0-3.24054.13 - 4.9.0-3.24054.13 - 4.9.0-3.24054.13 - 4.9.0-3.24054.13 - 4.9.0-3.24054.13 - 4.9.0-3.24054.13 - 4.9.0-3.24054.13 + 4.10.0-1.24062.5 + 4.10.0-1.24062.5 + 4.10.0-1.24062.5 + 4.10.0-1.24062.5 + 4.10.0-1.24062.5 + 4.10.0-1.24062.5 + 4.10.0-1.24062.5 $(MicrosoftNetCompilersToolsetPackageVersion) From 4016f89028b792555f7159be719d95894148ccc5 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" Date: Fri, 12 Jan 2024 23:13:45 +0000 Subject: [PATCH 037/577] Update dependencies from https://github.com/microsoft/vstest build 20240112.1 Microsoft.NET.Test.Sdk , Microsoft.TestPlatform.Build , Microsoft.TestPlatform.CLI From Version 17.9.0-release-23627-01 -> To Version 17.10.0-preview-24062-01 --- eng/Version.Details.xml | 12 ++++++------ eng/Versions.props | 6 +++--- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index d9afa9eaed9e..c9ac70b9ac51 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -179,18 +179,18 @@ https://github.com/nuget/nuget.client e92be3915309e687044768de38933ac5fc4cb40c - + https://github.com/microsoft/vstest - 053d7114a72aac12d1382ecc2a23b2dfdd5b084b + 8fc3926aeb6e9bdbe04f59584194a7be2295bc71 - + https://github.com/microsoft/vstest - 053d7114a72aac12d1382ecc2a23b2dfdd5b084b + 8fc3926aeb6e9bdbe04f59584194a7be2295bc71 - + https://github.com/microsoft/vstest - 053d7114a72aac12d1382ecc2a23b2dfdd5b084b + 8fc3926aeb6e9bdbe04f59584194a7be2295bc71 https://dev.azure.com/dnceng/internal/_git/dotnet-runtime diff --git a/eng/Versions.props b/eng/Versions.props index e63f5bcc6065..03f9dad4c458 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -84,9 +84,9 @@ - 17.9.0-release-23627-01 - 17.9.0-release-23627-01 - 17.9.0-release-23627-01 + 17.10.0-preview-24062-01 + 17.10.0-preview-24062-01 + 17.10.0-preview-24062-01 From 3667f516c451403917558ebae221c4fc2161545b Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Fri, 12 Jan 2024 16:47:39 -0800 Subject: [PATCH 038/577] [release/8.0.3xx] Update dependencies from dotnet/fsharp (#37979) Co-authored-by: dotnet-maestro[bot] --- eng/Version.Details.xml | 8 ++++---- eng/Versions.props | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index d9afa9eaed9e..485d38e5970e 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -64,13 +64,13 @@ bb6fadf23225f5097f4e05ed507d93683a21ae56 - + https://github.com/dotnet/fsharp - 4db7b212f6ea3f43f77e698556c3ab554ed8ddd2 + af386f82dea740bba200d77cf726d4bf0df853e1 - + https://github.com/dotnet/fsharp - 4db7b212f6ea3f43f77e698556c3ab554ed8ddd2 + af386f82dea740bba200d77cf726d4bf0df853e1 diff --git a/eng/Versions.props b/eng/Versions.props index e63f5bcc6065..00341b728b97 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -135,7 +135,7 @@ - 12.8.200-beta.24061.1 + 12.8.300-beta.24062.2 From a46a62a19958b6b018598a049a55051f781ca79c Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Fri, 12 Jan 2024 16:47:57 -0800 Subject: [PATCH 039/577] [release/8.0.3xx] Update dependencies from dotnet/format (#37978) Co-authored-by: dotnet-maestro[bot] --- NuGet.config | 10 ++++------ eng/Version.Details.xml | 6 +++--- eng/Versions.props | 2 +- 3 files changed, 8 insertions(+), 10 deletions(-) diff --git a/NuGet.config b/NuGet.config index 68766c29f33f..feb4306831c5 100644 --- a/NuGet.config +++ b/NuGet.config @@ -6,9 +6,10 @@ - - - + + + + @@ -47,9 +48,6 @@ - - - diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 485d38e5970e..c024dd1f091d 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -73,9 +73,9 @@ af386f82dea740bba200d77cf726d4bf0df853e1 - - https://dev.azure.com/dnceng/internal/_git/dotnet-format - 2651752953c0d41c8c7b8d661cf2237151af33d0 + + https://github.com/dotnet/format + 28925c0e519d66c80328aacf973b74e40bb1d5bd diff --git a/eng/Versions.props b/eng/Versions.props index 00341b728b97..7a267086a1ed 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -96,7 +96,7 @@ - 8.0.453106 + 8.0.456602 From a5e691960f540211af25d7d1afc5de4f323e375d Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Fri, 12 Jan 2024 16:48:15 -0800 Subject: [PATCH 040/577] [release/8.0.3xx] Update dependencies from dotnet/arcade (#37977) Co-authored-by: dotnet-maestro[bot] --- eng/Version.Details.xml | 16 ++++++++-------- eng/Versions.props | 4 ++-- global.json | 4 ++-- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index c024dd1f091d..f919caaf8400 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -411,22 +411,22 @@ - + https://github.com/dotnet/arcade - 61ae141d2bf3534619265c8f691fd55dc3e75147 + 888985fb9a9ae4cb30bca75f98af9126c839e660 - + https://github.com/dotnet/arcade - 61ae141d2bf3534619265c8f691fd55dc3e75147 + 888985fb9a9ae4cb30bca75f98af9126c839e660 - + https://github.com/dotnet/arcade - 61ae141d2bf3534619265c8f691fd55dc3e75147 + 888985fb9a9ae4cb30bca75f98af9126c839e660 - + https://github.com/dotnet/arcade - 61ae141d2bf3534619265c8f691fd55dc3e75147 + 888985fb9a9ae4cb30bca75f98af9126c839e660 https://dev.azure.com/dnceng/internal/_git/dotnet-runtime diff --git a/eng/Versions.props b/eng/Versions.props index 7a267086a1ed..45e69cd32b5f 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -34,7 +34,7 @@ 7.0.0 4.0.0 7.0.0 - 8.0.0-beta.24059.4 + 8.0.0-beta.24060.4 7.0.0-preview.22423.2 8.0.0 4.3.0 @@ -194,7 +194,7 @@ 6.12.0 6.1.0 - 8.0.0-beta.24059.4 + 8.0.0-beta.24060.4 4.18.4 1.3.2 8.0.0-beta.23607.1 diff --git a/global.json b/global.json index 4450e03ee33d..97173728d0ce 100644 --- a/global.json +++ b/global.json @@ -14,7 +14,7 @@ } }, "msbuild-sdks": { - "Microsoft.DotNet.Arcade.Sdk": "8.0.0-beta.24059.4", - "Microsoft.DotNet.Helix.Sdk": "8.0.0-beta.24059.4" + "Microsoft.DotNet.Arcade.Sdk": "8.0.0-beta.24060.4", + "Microsoft.DotNet.Helix.Sdk": "8.0.0-beta.24060.4" } } From baf6df2afeb5a85a1606a9ae7ec9b20a9e30a631 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" Date: Sat, 13 Jan 2024 14:10:10 +0000 Subject: [PATCH 041/577] Update dependencies from https://github.com/dotnet/msbuild build 20240110.3 Microsoft.SourceBuild.Intermediate.msbuild , Microsoft.Build , Microsoft.Build.Localization From Version 17.9.2-preview-24055-03 -> To Version 17.10.0-preview-24060-03 From 9384a8e0ff1e88507da1d6913d0e2ddef1a16b83 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" Date: Sat, 13 Jan 2024 14:10:35 +0000 Subject: [PATCH 042/577] Update dependencies from https://github.com/microsoft/vstest build 20240112.1 Microsoft.NET.Test.Sdk , Microsoft.TestPlatform.Build , Microsoft.TestPlatform.CLI From Version 17.9.0-release-23627-01 -> To Version 17.10.0-preview-24062-01 From b41f1419b8f00997baeac11474332ed3694c25f7 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" Date: Sat, 13 Jan 2024 14:10:58 +0000 Subject: [PATCH 043/577] Update dependencies from https://github.com/dotnet/razor build 20240112.5 Microsoft.AspNetCore.Mvc.Razor.Extensions.Tooling.Internal , Microsoft.CodeAnalysis.Razor.Tooling.Internal , Microsoft.NET.Sdk.Razor.SourceGenerators.Transport From Version 7.0.0-preview.24053.4 -> To Version 7.0.0-preview.24062.5 --- eng/Version.Details.xml | 12 ++++++------ eng/Versions.props | 6 +++--- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 352d6f8f6d36..2fde932d2a73 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -277,18 +277,18 @@ https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore 3f1acb59718cadf111a0a796681e3d3509bb3381 - + https://github.com/dotnet/razor - c2e01a21c8f9d3476b74aaad169a2845e30a27f2 + 55489b88e5dbbe94c2b03d325b12205173da350e - + https://github.com/dotnet/razor - c2e01a21c8f9d3476b74aaad169a2845e30a27f2 + 55489b88e5dbbe94c2b03d325b12205173da350e - + https://github.com/dotnet/razor - c2e01a21c8f9d3476b74aaad169a2845e30a27f2 + 55489b88e5dbbe94c2b03d325b12205173da350e https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore diff --git a/eng/Versions.props b/eng/Versions.props index 15c5c5801d54..9096c8221ede 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -160,9 +160,9 @@ - 7.0.0-preview.24062.4 - 7.0.0-preview.24062.4 - 7.0.0-preview.24062.4 + 7.0.0-preview.24062.5 + 7.0.0-preview.24062.5 + 7.0.0-preview.24062.5 From 6b33dabfa4d5daa9bda1c0a91559698e82bf53d4 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" Date: Sat, 13 Jan 2024 14:12:33 +0000 Subject: [PATCH 044/577] Update dependencies from https://github.com/dotnet/roslyn build 20240112.12 Microsoft.CodeAnalysis , Microsoft.CodeAnalysis.CSharp , Microsoft.CodeAnalysis.CSharp.CodeStyle , Microsoft.CodeAnalysis.CSharp.Features , Microsoft.CodeAnalysis.CSharp.Workspaces , Microsoft.CodeAnalysis.Workspaces.MSBuild , Microsoft.Net.Compilers.Toolset From Version 4.9.0-3.24054.13 -> To Version 4.10.0-1.24062.12 --- eng/Version.Details.xml | 28 ++++++++++++++-------------- eng/Versions.props | 14 +++++++------- 2 files changed, 21 insertions(+), 21 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index b65e229824c9..f557f8d0702d 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -78,34 +78,34 @@ 2651752953c0d41c8c7b8d661cf2237151af33d0 - + https://github.com/dotnet/roslyn - dfbd88a138bd8f012ac1e5029a3087fe246e96ff + e59fce8ec2bef59afebeabc1630f826a0ad86396 - + https://github.com/dotnet/roslyn - dfbd88a138bd8f012ac1e5029a3087fe246e96ff + e59fce8ec2bef59afebeabc1630f826a0ad86396 - + https://github.com/dotnet/roslyn - dfbd88a138bd8f012ac1e5029a3087fe246e96ff + e59fce8ec2bef59afebeabc1630f826a0ad86396 - + https://github.com/dotnet/roslyn - dfbd88a138bd8f012ac1e5029a3087fe246e96ff + e59fce8ec2bef59afebeabc1630f826a0ad86396 - + https://github.com/dotnet/roslyn - dfbd88a138bd8f012ac1e5029a3087fe246e96ff + e59fce8ec2bef59afebeabc1630f826a0ad86396 - + https://github.com/dotnet/roslyn - dfbd88a138bd8f012ac1e5029a3087fe246e96ff + e59fce8ec2bef59afebeabc1630f826a0ad86396 - + https://github.com/dotnet/roslyn - dfbd88a138bd8f012ac1e5029a3087fe246e96ff + e59fce8ec2bef59afebeabc1630f826a0ad86396 https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore diff --git a/eng/Versions.props b/eng/Versions.props index b12dbb466a44..c0894153f709 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -139,13 +139,13 @@ - 4.10.0-1.24062.5 - 4.10.0-1.24062.5 - 4.10.0-1.24062.5 - 4.10.0-1.24062.5 - 4.10.0-1.24062.5 - 4.10.0-1.24062.5 - 4.10.0-1.24062.5 + 4.10.0-1.24062.12 + 4.10.0-1.24062.12 + 4.10.0-1.24062.12 + 4.10.0-1.24062.12 + 4.10.0-1.24062.12 + 4.10.0-1.24062.12 + 4.10.0-1.24062.12 $(MicrosoftNetCompilersToolsetPackageVersion) From ee52bb4a7147422a1329ee5b2db52b8194d8b35f Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" Date: Sun, 14 Jan 2024 14:01:34 +0000 Subject: [PATCH 045/577] Update dependencies from https://github.com/dotnet/msbuild build 20240110.3 Microsoft.SourceBuild.Intermediate.msbuild , Microsoft.Build , Microsoft.Build.Localization From Version 17.9.2-preview-24055-03 -> To Version 17.10.0-preview-24060-03 From b25b3fe9f9232d028e50c761250c0c90c48eb109 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" Date: Sun, 14 Jan 2024 14:01:58 +0000 Subject: [PATCH 046/577] Update dependencies from https://github.com/microsoft/vstest build 20240112.1 Microsoft.NET.Test.Sdk , Microsoft.TestPlatform.Build , Microsoft.TestPlatform.CLI From Version 17.9.0-release-23627-01 -> To Version 17.10.0-preview-24062-01 From 7ea537cf0da4ccdf89fc85728015ee514c7946b1 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" Date: Sun, 14 Jan 2024 14:02:21 +0000 Subject: [PATCH 047/577] Update dependencies from https://github.com/dotnet/razor build 20240112.5 Microsoft.AspNetCore.Mvc.Razor.Extensions.Tooling.Internal , Microsoft.CodeAnalysis.Razor.Tooling.Internal , Microsoft.NET.Sdk.Razor.SourceGenerators.Transport From Version 7.0.0-preview.24053.4 -> To Version 7.0.0-preview.24062.5 From 485730bb44f4032f7d5111c5dc29adf1089e36f7 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" Date: Sun, 14 Jan 2024 14:03:56 +0000 Subject: [PATCH 048/577] Update dependencies from https://github.com/dotnet/roslyn build 20240113.2 Microsoft.CodeAnalysis , Microsoft.CodeAnalysis.CSharp , Microsoft.CodeAnalysis.CSharp.CodeStyle , Microsoft.CodeAnalysis.CSharp.Features , Microsoft.CodeAnalysis.CSharp.Workspaces , Microsoft.CodeAnalysis.Workspaces.MSBuild , Microsoft.Net.Compilers.Toolset From Version 4.9.0-3.24054.13 -> To Version 4.10.0-1.24063.2 --- eng/Version.Details.xml | 28 ++++++++++++++-------------- eng/Versions.props | 14 +++++++------- 2 files changed, 21 insertions(+), 21 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index f557f8d0702d..2c48c1403313 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -78,34 +78,34 @@ 2651752953c0d41c8c7b8d661cf2237151af33d0 - + https://github.com/dotnet/roslyn - e59fce8ec2bef59afebeabc1630f826a0ad86396 + 970a70438f3c5408c742f5345ece3a356f50b553 - + https://github.com/dotnet/roslyn - e59fce8ec2bef59afebeabc1630f826a0ad86396 + 970a70438f3c5408c742f5345ece3a356f50b553 - + https://github.com/dotnet/roslyn - e59fce8ec2bef59afebeabc1630f826a0ad86396 + 970a70438f3c5408c742f5345ece3a356f50b553 - + https://github.com/dotnet/roslyn - e59fce8ec2bef59afebeabc1630f826a0ad86396 + 970a70438f3c5408c742f5345ece3a356f50b553 - + https://github.com/dotnet/roslyn - e59fce8ec2bef59afebeabc1630f826a0ad86396 + 970a70438f3c5408c742f5345ece3a356f50b553 - + https://github.com/dotnet/roslyn - e59fce8ec2bef59afebeabc1630f826a0ad86396 + 970a70438f3c5408c742f5345ece3a356f50b553 - + https://github.com/dotnet/roslyn - e59fce8ec2bef59afebeabc1630f826a0ad86396 + 970a70438f3c5408c742f5345ece3a356f50b553 https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore diff --git a/eng/Versions.props b/eng/Versions.props index c0894153f709..bd29b82e1bb7 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -139,13 +139,13 @@ - 4.10.0-1.24062.12 - 4.10.0-1.24062.12 - 4.10.0-1.24062.12 - 4.10.0-1.24062.12 - 4.10.0-1.24062.12 - 4.10.0-1.24062.12 - 4.10.0-1.24062.12 + 4.10.0-1.24063.2 + 4.10.0-1.24063.2 + 4.10.0-1.24063.2 + 4.10.0-1.24063.2 + 4.10.0-1.24063.2 + 4.10.0-1.24063.2 + 4.10.0-1.24063.2 $(MicrosoftNetCompilersToolsetPackageVersion) From 9027190c68fb53f14ce76ef512eb37364ad6ab4b Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" Date: Mon, 15 Jan 2024 13:50:44 +0000 Subject: [PATCH 049/577] Update dependencies from https://github.com/microsoft/vstest build 20240114.1 Microsoft.NET.Test.Sdk , Microsoft.TestPlatform.Build , Microsoft.TestPlatform.CLI From Version 17.9.0-release-23627-01 -> To Version 17.10.0-preview-24064-01 --- eng/Version.Details.xml | 12 ++++++------ eng/Versions.props | 6 +++--- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index c9ac70b9ac51..9859d0d41d84 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -179,18 +179,18 @@ https://github.com/nuget/nuget.client e92be3915309e687044768de38933ac5fc4cb40c - + https://github.com/microsoft/vstest - 8fc3926aeb6e9bdbe04f59584194a7be2295bc71 + 359bc04f68435c2155ecece1623187ea5f88ace5 - + https://github.com/microsoft/vstest - 8fc3926aeb6e9bdbe04f59584194a7be2295bc71 + 359bc04f68435c2155ecece1623187ea5f88ace5 - + https://github.com/microsoft/vstest - 8fc3926aeb6e9bdbe04f59584194a7be2295bc71 + 359bc04f68435c2155ecece1623187ea5f88ace5 https://dev.azure.com/dnceng/internal/_git/dotnet-runtime diff --git a/eng/Versions.props b/eng/Versions.props index 03f9dad4c458..b6baefe78272 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -84,9 +84,9 @@ - 17.10.0-preview-24062-01 - 17.10.0-preview-24062-01 - 17.10.0-preview-24062-01 + 17.10.0-preview-24064-01 + 17.10.0-preview-24064-01 + 17.10.0-preview-24064-01 From 238e8e7bb35252d015718576ccaf9473b7ae84dd Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Tue, 16 Jan 2024 02:06:33 +0000 Subject: [PATCH 050/577] [release/8.0.3xx] Update dependencies from dotnet/msbuild (#38010) [release/8.0.3xx] Update dependencies from dotnet/msbuild --- eng/Version.Details.xml | 12 ++++++------ eng/Versions.props | 4 ++-- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 9d25fa3df858..76d2b3b479ea 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -51,17 +51,17 @@ https://github.com/dotnet/emsdk 2406616d0e3a31d80b326e27c156955bfa41c791 - + https://github.com/dotnet/msbuild - 1725b247e8737804076c8ff3b09fcee02ecdf51e + ceb160a675bf52a84109d68e3848aaf71fe6677a - + https://github.com/dotnet/msbuild - 1725b247e8737804076c8ff3b09fcee02ecdf51e + ceb160a675bf52a84109d68e3848aaf71fe6677a - + https://github.com/dotnet/msbuild - 1725b247e8737804076c8ff3b09fcee02ecdf51e + ceb160a675bf52a84109d68e3848aaf71fe6677a diff --git a/eng/Versions.props b/eng/Versions.props index 35830dc2f26b..df89da187cdb 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -105,7 +105,7 @@ - 17.10.0-preview-24060-03 + 17.10.0-preview-24065-01 $(MicrosoftBuildPackageVersion) - 6.9.0-rc.74 - 6.9.0-rc.74 + 6.10.0-preview.1.5 + 6.10.0-preview.1.5 6.0.0-rc.278 - 6.9.0-rc.74 - 6.9.0-rc.74 - 6.9.0-rc.74 - 6.9.0-rc.74 - 6.9.0-rc.74 - 6.9.0-rc.74 - 6.9.0-rc.74 - 6.9.0-rc.74 - 6.9.0-rc.74 + 6.10.0-preview.1.5 + 6.10.0-preview.1.5 + 6.10.0-preview.1.5 + 6.10.0-preview.1.5 + 6.10.0-preview.1.5 + 6.10.0-preview.1.5 + 6.10.0-preview.1.5 + 6.10.0-preview.1.5 + 6.10.0-preview.1.5 $(NuGetPackagingPackageVersion) $(NuGetProjectModelPackageVersion) From c33f07fb171ade500ea3b68f86b675d2aa3f5696 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" Date: Tue, 16 Jan 2024 14:09:11 +0000 Subject: [PATCH 052/577] Update dependencies from https://github.com/dotnet/msbuild build 20240116.1 Microsoft.SourceBuild.Intermediate.msbuild , Microsoft.Build , Microsoft.Build.Localization From Version 17.10.0-preview-24065-01 -> To Version 17.10.0-preview-24066-01 --- eng/Version.Details.xml | 12 ++++++------ eng/Versions.props | 4 ++-- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 76d2b3b479ea..92cac68338c0 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -51,17 +51,17 @@ https://github.com/dotnet/emsdk 2406616d0e3a31d80b326e27c156955bfa41c791 - + https://github.com/dotnet/msbuild - ceb160a675bf52a84109d68e3848aaf71fe6677a + d0af670c220f48693d5f1e4bab126d4367d77e05 - + https://github.com/dotnet/msbuild - ceb160a675bf52a84109d68e3848aaf71fe6677a + d0af670c220f48693d5f1e4bab126d4367d77e05 - + https://github.com/dotnet/msbuild - ceb160a675bf52a84109d68e3848aaf71fe6677a + d0af670c220f48693d5f1e4bab126d4367d77e05 diff --git a/eng/Versions.props b/eng/Versions.props index df89da187cdb..6c6a690e7aae 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -105,7 +105,7 @@ - 17.10.0-preview-24065-01 + 17.10.0-preview-24066-01 $(MicrosoftBuildPackageVersion) - 17.10.0-preview-24064-01 - 17.10.0-preview-24064-01 - 17.10.0-preview-24064-01 + 17.10.0-preview-24065-05 + 17.10.0-preview-24065-05 + 17.10.0-preview-24065-05 From 20e5a9ea879d23f74805b1ba1287611e1ae3addc Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" Date: Tue, 16 Jan 2024 14:10:58 +0000 Subject: [PATCH 054/577] Update dependencies from https://github.com/dotnet/roslyn build 20240116.1 Microsoft.CodeAnalysis , Microsoft.CodeAnalysis.CSharp , Microsoft.CodeAnalysis.CSharp.CodeStyle , Microsoft.CodeAnalysis.CSharp.Features , Microsoft.CodeAnalysis.CSharp.Workspaces , Microsoft.CodeAnalysis.Workspaces.MSBuild , Microsoft.Net.Compilers.Toolset From Version 4.10.0-1.24063.2 -> To Version 4.10.0-1.24066.1 --- eng/Version.Details.xml | 28 ++++++++++++++-------------- eng/Versions.props | 14 +++++++------- 2 files changed, 21 insertions(+), 21 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 76d2b3b479ea..57c5fb83dee8 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -78,34 +78,34 @@ 28925c0e519d66c80328aacf973b74e40bb1d5bd - + https://github.com/dotnet/roslyn - 970a70438f3c5408c742f5345ece3a356f50b553 + c02fb4f32a4a2f75454f996b8fc8489712083030 - + https://github.com/dotnet/roslyn - 970a70438f3c5408c742f5345ece3a356f50b553 + c02fb4f32a4a2f75454f996b8fc8489712083030 - + https://github.com/dotnet/roslyn - 970a70438f3c5408c742f5345ece3a356f50b553 + c02fb4f32a4a2f75454f996b8fc8489712083030 - + https://github.com/dotnet/roslyn - 970a70438f3c5408c742f5345ece3a356f50b553 + c02fb4f32a4a2f75454f996b8fc8489712083030 - + https://github.com/dotnet/roslyn - 970a70438f3c5408c742f5345ece3a356f50b553 + c02fb4f32a4a2f75454f996b8fc8489712083030 - + https://github.com/dotnet/roslyn - 970a70438f3c5408c742f5345ece3a356f50b553 + c02fb4f32a4a2f75454f996b8fc8489712083030 - + https://github.com/dotnet/roslyn - 970a70438f3c5408c742f5345ece3a356f50b553 + c02fb4f32a4a2f75454f996b8fc8489712083030 https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore diff --git a/eng/Versions.props b/eng/Versions.props index df89da187cdb..981cc88ba0f3 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -139,13 +139,13 @@ - 4.10.0-1.24063.2 - 4.10.0-1.24063.2 - 4.10.0-1.24063.2 - 4.10.0-1.24063.2 - 4.10.0-1.24063.2 - 4.10.0-1.24063.2 - 4.10.0-1.24063.2 + 4.10.0-1.24066.1 + 4.10.0-1.24066.1 + 4.10.0-1.24066.1 + 4.10.0-1.24066.1 + 4.10.0-1.24066.1 + 4.10.0-1.24066.1 + 4.10.0-1.24066.1 $(MicrosoftNetCompilersToolsetPackageVersion) From cdfd08e40b9ecd642a4a281befe89ceb9df52463 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" Date: Tue, 16 Jan 2024 14:13:04 +0000 Subject: [PATCH 055/577] Update dependencies from https://github.com/dotnet/source-build-externals build 20240115.1 Microsoft.SourceBuild.Intermediate.source-build-externals From Version 8.0.0-alpha.1.24059.4 -> To Version 8.0.0-alpha.1.24065.1 --- eng/Version.Details.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 76d2b3b479ea..da4cced30cc0 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -333,9 +333,9 @@ 02fe27cd6a9b001c8feb7938e6ef4b3799745759 - + https://github.com/dotnet/source-build-externals - 7134e53b6b1210a1ce8838b12b8f6071e0a3433b + 83274d94c7e2ff21081b0d75ecbec2da2241f831 From 26af58bb45648c6bdc8102d7a7dc52e189429d34 Mon Sep 17 00:00:00 2001 From: annie <59816815+JL03-Yue@users.noreply.github.com> Date: Tue, 16 Jan 2024 09:59:17 -0800 Subject: [PATCH 056/577] fix tests --- .../CommandTests/ToolManifestEditorTests.cs | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/Tests/dotnet.Tests/CommandTests/ToolManifestEditorTests.cs b/src/Tests/dotnet.Tests/CommandTests/ToolManifestEditorTests.cs index 77258c8de50f..1306514178f1 100644 --- a/src/Tests/dotnet.Tests/CommandTests/ToolManifestEditorTests.cs +++ b/src/Tests/dotnet.Tests/CommandTests/ToolManifestEditorTests.cs @@ -46,21 +46,21 @@ public void GivenManifestFileItCanAddEntryToIt() ""commands"": [ ""t-rex"" ], - ""rollForward"": ""False"" + ""rollForward"": false }, ""dotnetsay"": { ""version"": ""2.1.4"", ""commands"": [ ""dotnetsay"" ], - ""rollForward"": ""False"" + ""rollForward"": false }, ""new-tool"": { ""version"": ""3.0.0"", ""commands"": [ ""newtool"" ], - ""rollForward"": ""False"" + ""rollForward"": false } } }"); @@ -88,7 +88,7 @@ public void GivenManifestFileWithoutToolsEntryItCanAddEntryToIt() ""commands"": [ ""newtool"" ], - ""rollForward"": ""False"" + ""rollForward"": false } } }"); @@ -201,7 +201,7 @@ public void GivenManifestFileItCanRemoveEntryFromIt() ""commands"": [ ""t-rex"" ], - ""rollForward"": ""False"" + ""rollForward"": false } } }"); @@ -288,14 +288,14 @@ public void GivenManifestFileItCanEditEntry() ""commands"": [ ""t-rex3"" ], - ""rollForward"": ""False"" + ""rollForward"": false }, ""dotnetsay"": { ""version"": ""2.1.4"", ""commands"": [ ""dotnetsay"" ], - ""rollForward"": ""False"" + ""rollForward"": false } } }", "And original tools entry order is preserved."); @@ -311,14 +311,14 @@ public void GivenManifestFileItCanEditEntry() ""commands"": [ ""t-rex"" ], - ""rollForward"": ""False"" + ""rollForward"": false }, ""dotnetsay"": { ""version"": ""2.1.4"", ""commands"": [ ""dotnetsay"" ], - ""rollForward"": ""False"" + ""rollForward"": false } } }"; From 129b393b4d5e77d1a599fda0de90d9bd9a73655c Mon Sep 17 00:00:00 2001 From: annie <59816815+JL03-Yue@users.noreply.github.com> Date: Tue, 16 Jan 2024 10:08:28 -0800 Subject: [PATCH 057/577] update the muxer method --- .../MuxerCommandSpecMaker.cs | 26 ++++++------------- 1 file changed, 8 insertions(+), 18 deletions(-) diff --git a/src/Cli/dotnet/CommandFactory/CommandResolution/MuxerCommandSpecMaker.cs b/src/Cli/dotnet/CommandFactory/CommandResolution/MuxerCommandSpecMaker.cs index e7120d2aac01..d71a840c2d20 100644 --- a/src/Cli/dotnet/CommandFactory/CommandResolution/MuxerCommandSpecMaker.cs +++ b/src/Cli/dotnet/CommandFactory/CommandResolution/MuxerCommandSpecMaker.cs @@ -11,33 +11,23 @@ internal static CommandSpec CreatePackageCommandSpecUsingMuxer( string commandPath, IEnumerable commandArguments) { - var arguments = new List(); - var muxer = new Muxer(); - var host = muxer.MuxerPath; + if (host == null) { throw new Exception(LocalizableStrings.UnableToLocateDotnetMultiplexer); } - IEnumerable modifiedArguments = commandArguments; - - // Add --roll-forward argument first if exists - if (commandArguments != null && commandArguments.Any(arg => arg.Equals("--roll-forward", StringComparison.OrdinalIgnoreCase))) - { - int index = commandArguments.ToList().IndexOf("--roll-forward"); - arguments.Add(commandArguments.ElementAt(index)); - arguments.Add(commandArguments.ElementAt(index + 1)); - modifiedArguments = commandArguments.Where((element, i) => i != index && i != index + 1); - } - arguments.Add(commandPath); + var previousArg = string.Empty; - if (modifiedArguments != null) - { - arguments.AddRange(modifiedArguments); - } + // Group the arguments by if the previous argument or the current argument is --roll-forward. + var argGroups = (commandArguments ?? []) + .GroupBy(a => previousArg.Equals("--roll-forward", StringComparison.OrdinalIgnoreCase) + | (previousArg = a).Equals("--roll-forward", StringComparison.OrdinalIgnoreCase)) + .ToArray(); + string[] arguments = [..argGroups.Where(g => g.Key).SelectMany(g => g), commandPath, .. argGroups.Where(g => !g.Key).SelectMany(g => g)]; return CreateCommandSpec(host, arguments); } From cf874ee8f8015da9e111b45ebf2f0fe011e86a60 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Tue, 16 Jan 2024 18:49:27 +0000 Subject: [PATCH 058/577] [release/8.0.3xx] Update dependencies from dotnet/fsharp (#38039) [release/8.0.3xx] Update dependencies from dotnet/fsharp --- eng/Version.Details.xml | 8 ++++---- eng/Versions.props | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 76d2b3b479ea..34e70cda9cbb 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -64,13 +64,13 @@ ceb160a675bf52a84109d68e3848aaf71fe6677a - + https://github.com/dotnet/fsharp - af386f82dea740bba200d77cf726d4bf0df853e1 + e0b6646d26d31fe50da5563ac44a257cfd8d5322 - + https://github.com/dotnet/fsharp - af386f82dea740bba200d77cf726d4bf0df853e1 + e0b6646d26d31fe50da5563ac44a257cfd8d5322 diff --git a/eng/Versions.props b/eng/Versions.props index df89da187cdb..f3a889ada9d1 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -135,7 +135,7 @@ - 12.8.300-beta.24062.2 + 12.8.300-beta.24065.1 From 7a562eb1276350b63dcc52f0c33b2b8fdc702c04 Mon Sep 17 00:00:00 2001 From: annie <59816815+JL03-Yue@users.noreply.github.com> Date: Tue, 16 Jan 2024 11:11:47 -0800 Subject: [PATCH 059/577] fix tests --- .../CommandResolution/LocalToolsCommandResolver.cs | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/Cli/dotnet/CommandFactory/CommandResolution/LocalToolsCommandResolver.cs b/src/Cli/dotnet/CommandFactory/CommandResolution/LocalToolsCommandResolver.cs index 5b18fc86ab9b..19c1ef4623a4 100644 --- a/src/Cli/dotnet/CommandFactory/CommandResolution/LocalToolsCommandResolver.cs +++ b/src/Cli/dotnet/CommandFactory/CommandResolution/LocalToolsCommandResolver.cs @@ -81,8 +81,12 @@ private CommandSpec GetPackageCommandSpecUsingMuxer(CommandResolverArguments arg return null; } - var commandArgument = (allowRollForward != false ? new List { "--roll-forward", "Major" } : Enumerable.Empty()).Concat(arguments.CommandArguments); - arguments.CommandArguments = commandArgument; + if( arguments.CommandArguments != null) + { + var commandArgument = (allowRollForward != false ? new List { "--roll-forward", "Major" } : Enumerable.Empty()).Concat(arguments.CommandArguments); + arguments.CommandArguments = commandArgument; + } + if (_localToolsResolverCache.TryLoad( new RestoredCommandIdentifier( From 6f7ecda9df953fa6045de071ef81aa1810b33747 Mon Sep 17 00:00:00 2001 From: annie <59816815+JL03-Yue@users.noreply.github.com> Date: Tue, 16 Jan 2024 12:57:00 -0800 Subject: [PATCH 060/577] fix tests --- .../dotnet.Tests/CommandTests/ToolUninstallLocalCommandTests.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Tests/dotnet.Tests/CommandTests/ToolUninstallLocalCommandTests.cs b/src/Tests/dotnet.Tests/CommandTests/ToolUninstallLocalCommandTests.cs index d8f27c0cc033..7aa3558a3fe8 100644 --- a/src/Tests/dotnet.Tests/CommandTests/ToolUninstallLocalCommandTests.cs +++ b/src/Tests/dotnet.Tests/CommandTests/ToolUninstallLocalCommandTests.cs @@ -212,7 +212,7 @@ public void GivenParentDirHasManifestWithSamePackageIdWhenRunWithPackageIdItShou ""commands"": [ ""t-rex"" ], - ""rollForward"": ""False"" + ""rollForward"": false } } }"; From bc3222990f119f55776c7a528069e729ffacd98a Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Tue, 16 Jan 2024 22:42:54 +0000 Subject: [PATCH 061/577] [release/8.0.3xx] Update dependencies from dotnet/razor (#38040) [release/8.0.3xx] Update dependencies from dotnet/razor --- eng/Version.Details.xml | 12 ++++++------ eng/Versions.props | 6 +++--- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 8fd55f5bd5ee..db72c0a9654f 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -277,18 +277,18 @@ https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore 3f1acb59718cadf111a0a796681e3d3509bb3381 - + https://github.com/dotnet/razor - 55489b88e5dbbe94c2b03d325b12205173da350e + 3afb7ffffa878c7f859a3dd24903e52940dac1b8 - + https://github.com/dotnet/razor - 55489b88e5dbbe94c2b03d325b12205173da350e + 3afb7ffffa878c7f859a3dd24903e52940dac1b8 - + https://github.com/dotnet/razor - 55489b88e5dbbe94c2b03d325b12205173da350e + 3afb7ffffa878c7f859a3dd24903e52940dac1b8 https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore diff --git a/eng/Versions.props b/eng/Versions.props index 3bcdff9bf4b3..82f55a5dee4e 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -160,9 +160,9 @@ - 7.0.0-preview.24062.5 - 7.0.0-preview.24062.5 - 7.0.0-preview.24062.5 + 7.0.0-preview.24065.1 + 7.0.0-preview.24065.1 + 7.0.0-preview.24065.1 From 8c8f6cda841bf5d09ad37510c7bc53760c2b9868 Mon Sep 17 00:00:00 2001 From: annie <59816815+JL03-Yue@users.noreply.github.com> Date: Tue, 16 Jan 2024 15:43:16 -0800 Subject: [PATCH 062/577] improve the way to UpdateRuntimeConfig --- .../ToolPackage/ToolPackageDownloader.cs | 60 ++++--------------- 1 file changed, 11 insertions(+), 49 deletions(-) diff --git a/src/Cli/dotnet/ToolPackage/ToolPackageDownloader.cs b/src/Cli/dotnet/ToolPackage/ToolPackageDownloader.cs index e245b1a52fa5..6b5caf25ac6d 100644 --- a/src/Cli/dotnet/ToolPackage/ToolPackageDownloader.cs +++ b/src/Cli/dotnet/ToolPackage/ToolPackageDownloader.cs @@ -144,11 +144,6 @@ public IToolPackage InstallPackage(PackageLocation packageLocation, PackageId pa } CreateAssetFile(packageId, packageVersion, toolDownloadDir, assetFileDirectory, _runtimeJsonPath, targetFramework); - - if (isGlobalToolRollForward) - { - UpdateRuntimeConfig(packageId, packageVersion, toolDownloadDir); - } DirectoryPath toolReturnPackageDirectory; DirectoryPath toolReturnJsonParentDirectory; @@ -168,10 +163,17 @@ public IToolPackage InstallPackage(PackageLocation packageLocation, PackageId pa toolReturnJsonParentDirectory = _localToolAssetDir; } - return new ToolPackageInstance(id: packageId, + var toolPackageInstance = new ToolPackageInstance(id: packageId, version: packageVersion, packageDirectory: toolReturnPackageDirectory, assetsJsonParentDirectory: toolReturnJsonParentDirectory); + + if (isGlobalToolRollForward) + { + UpdateRuntimeConfig(toolPackageInstance); + } + + return toolPackageInstance; }, rollback: () => { @@ -204,51 +206,11 @@ private static void AddToolsAssets( } private static void UpdateRuntimeConfig( - PackageId packageId, - NuGetVersion packageVersion, - DirectoryPath toolDownloadDir - ) - { - var toolsDirectory = Path.Combine(toolDownloadDir.ToString().Trim('"'), packageId.ToString(), packageVersion.ToString(), "tools"); - - // TBD: if roll forward all frameworks - string[] subDirectories = Directory.GetDirectories(toolsDirectory); - foreach (string subDirectory in subDirectories) - { - UpdateRuntimeConfigFile(subDirectory, packageId); - } - } - - private static void UpdateRuntimeConfigFile( - string frameworkDir, - PackageId packageId + ToolPackageInstance toolPackageInstance ) { - // Get the setting file - var settingFilePath = Path.Combine(frameworkDir, "any", "DotnetToolSettings.xml"); - if (!File.Exists(settingFilePath)) - { - throw new ToolPackageException( - string.Format( - CommonLocalizableStrings.ToolSettingsNotFound, - packageId - )); - } - - // Get runtimeConfig file - string runtimeConfigFileFolder = null; - XDocument dotnetToolSettings = XDocument.Load(settingFilePath); - XElement commandElement = dotnetToolSettings.Descendants("Command").FirstOrDefault(); - if (commandElement != null) - { - XAttribute entryPointAttribute = commandElement.Attribute("EntryPoint"); - if (entryPointAttribute != null) - { - runtimeConfigFileFolder = entryPointAttribute.Value; - } - } - - var runtimeConfigFilePath = Path.Combine(Path.GetDirectoryName(settingFilePath), $"{Path.GetFileNameWithoutExtension(runtimeConfigFileFolder)}{".runtimeconfig.json"}"); + var executableFilePath = toolPackageInstance.Commands[0].Executable; + var runtimeConfigFilePath = Path.ChangeExtension(executableFilePath.ToString(), ".runtimeconfig.json"); // Update the runtimeconfig.json file string existingJson = File.ReadAllText(runtimeConfigFilePath); From 5dc7eaa3c0150fbface0ab8382acc6a988b5da8b Mon Sep 17 00:00:00 2001 From: Jacques Eloff Date: Tue, 16 Jan 2024 17:01:02 -0800 Subject: [PATCH 063/577] Enable 3xx CI builds --- .vsts-ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.vsts-ci.yml b/.vsts-ci.yml index 775bc568d823..fa3e6e08fd08 100644 --- a/.vsts-ci.yml +++ b/.vsts-ci.yml @@ -3,7 +3,7 @@ trigger: branches: include: - main - - release/8.0.2xx + - release/8.0.3xx - internal/release/* - exp/* From 685973a29c9b8734e364f4402554d5fa5d3974fd Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" Date: Wed, 17 Jan 2024 14:05:09 +0000 Subject: [PATCH 064/577] Update dependencies from https://github.com/nuget/nuget.client build 6.10.0.5 Microsoft.Build.NuGetSdkResolver , NuGet.Build.Tasks , NuGet.Build.Tasks.Console , NuGet.Build.Tasks.Pack , NuGet.CommandLine.XPlat , NuGet.Commands , NuGet.Common , NuGet.Configuration , NuGet.Credentials , NuGet.DependencyResolver.Core , NuGet.Frameworks , NuGet.LibraryModel , NuGet.Packaging , NuGet.ProjectModel , NuGet.Protocol , NuGet.Versioning From Version 6.9.0-rc.74 -> To Version 6.10.0-preview.1.5 From b5868bc491d95951064ba01635b10499a285409e Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" Date: Wed, 17 Jan 2024 14:06:10 +0000 Subject: [PATCH 065/577] Update dependencies from https://github.com/microsoft/vstest build 20240116.1 Microsoft.NET.Test.Sdk , Microsoft.TestPlatform.Build , Microsoft.TestPlatform.CLI From Version 17.9.0-release-23627-01 -> To Version 17.10.0-preview-24066-01 --- eng/Version.Details.xml | 12 ++++++------ eng/Versions.props | 6 +++--- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 67dfc272d614..c6eb2d5e33aa 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -179,18 +179,18 @@ https://github.com/nuget/nuget.client e92be3915309e687044768de38933ac5fc4cb40c - + https://github.com/microsoft/vstest - d42a88591d4fa91fedc95e8f3af06c1f4ae4ee9d + e5d81ae46d84fb90fb1dbc7c77770cfa585a05da - + https://github.com/microsoft/vstest - d42a88591d4fa91fedc95e8f3af06c1f4ae4ee9d + e5d81ae46d84fb90fb1dbc7c77770cfa585a05da - + https://github.com/microsoft/vstest - d42a88591d4fa91fedc95e8f3af06c1f4ae4ee9d + e5d81ae46d84fb90fb1dbc7c77770cfa585a05da https://dev.azure.com/dnceng/internal/_git/dotnet-runtime diff --git a/eng/Versions.props b/eng/Versions.props index 908e4e166c78..695f88c2f189 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -84,9 +84,9 @@ - 17.10.0-preview-24065-05 - 17.10.0-preview-24065-05 - 17.10.0-preview-24065-05 + 17.10.0-preview-24066-01 + 17.10.0-preview-24066-01 + 17.10.0-preview-24066-01 From e9449407087bb6c21131a6578d392e6f8d09d128 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Wed, 17 Jan 2024 18:49:57 +0000 Subject: [PATCH 066/577] [release/8.0.3xx] Update dependencies from dotnet/msbuild (#38072) [release/8.0.3xx] Update dependencies from dotnet/msbuild --- eng/Version.Details.xml | 12 ++++++------ eng/Versions.props | 4 ++-- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 369dfc1fe1b7..966c4395fdad 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -51,17 +51,17 @@ https://github.com/dotnet/emsdk 2406616d0e3a31d80b326e27c156955bfa41c791 - + https://github.com/dotnet/msbuild - d0af670c220f48693d5f1e4bab126d4367d77e05 + f1448f15870e0d229cb9ae6efe336b94cefe3ab3 - + https://github.com/dotnet/msbuild - d0af670c220f48693d5f1e4bab126d4367d77e05 + f1448f15870e0d229cb9ae6efe336b94cefe3ab3 - + https://github.com/dotnet/msbuild - d0af670c220f48693d5f1e4bab126d4367d77e05 + f1448f15870e0d229cb9ae6efe336b94cefe3ab3 diff --git a/eng/Versions.props b/eng/Versions.props index 20fa88dac8a7..1006a5a91041 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -105,7 +105,7 @@ - 17.10.0-preview-24066-01 + 17.10.0-preview-24067-01 $(MicrosoftBuildPackageVersion) - 12.8.300-beta.24065.1 + 12.8.300-beta.24066.3 From 667d60697fa0ca773181759cc27719b9d691ec47 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Wed, 17 Jan 2024 18:51:02 +0000 Subject: [PATCH 068/577] [release/8.0.3xx] Update dependencies from dotnet/razor (#38074) [release/8.0.3xx] Update dependencies from dotnet/razor --- eng/Version.Details.xml | 12 ++++++------ eng/Versions.props | 6 +++--- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 17c3cc4dcda3..95ba0001a96b 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -277,18 +277,18 @@ https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore 3f1acb59718cadf111a0a796681e3d3509bb3381 - + https://github.com/dotnet/razor - 3afb7ffffa878c7f859a3dd24903e52940dac1b8 + 71bfe681f7bac3b0e3cc1b6dc5ac5d94cf461ee1 - + https://github.com/dotnet/razor - 3afb7ffffa878c7f859a3dd24903e52940dac1b8 + 71bfe681f7bac3b0e3cc1b6dc5ac5d94cf461ee1 - + https://github.com/dotnet/razor - 3afb7ffffa878c7f859a3dd24903e52940dac1b8 + 71bfe681f7bac3b0e3cc1b6dc5ac5d94cf461ee1 https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore diff --git a/eng/Versions.props b/eng/Versions.props index 9aaa8868fdc5..ae28b827bd76 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -160,9 +160,9 @@ - 7.0.0-preview.24065.1 - 7.0.0-preview.24065.1 - 7.0.0-preview.24065.1 + 7.0.0-preview.24066.1 + 7.0.0-preview.24066.1 + 7.0.0-preview.24066.1 From a585c60cad72a31ff26125065c0cd861e861ec48 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Wed, 17 Jan 2024 18:51:10 +0000 Subject: [PATCH 069/577] [release/8.0.3xx] Update dependencies from dotnet/roslyn (#38075) [release/8.0.3xx] Update dependencies from dotnet/roslyn --- eng/Version.Details.xml | 28 ++++++++++++++-------------- eng/Versions.props | 14 +++++++------- 2 files changed, 21 insertions(+), 21 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 95ba0001a96b..1f477c765864 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -78,34 +78,34 @@ 28925c0e519d66c80328aacf973b74e40bb1d5bd - + https://github.com/dotnet/roslyn - c02fb4f32a4a2f75454f996b8fc8489712083030 + fda44c407b951fe551c2a9935faf500bc3aea18b - + https://github.com/dotnet/roslyn - c02fb4f32a4a2f75454f996b8fc8489712083030 + fda44c407b951fe551c2a9935faf500bc3aea18b - + https://github.com/dotnet/roslyn - c02fb4f32a4a2f75454f996b8fc8489712083030 + fda44c407b951fe551c2a9935faf500bc3aea18b - + https://github.com/dotnet/roslyn - c02fb4f32a4a2f75454f996b8fc8489712083030 + fda44c407b951fe551c2a9935faf500bc3aea18b - + https://github.com/dotnet/roslyn - c02fb4f32a4a2f75454f996b8fc8489712083030 + fda44c407b951fe551c2a9935faf500bc3aea18b - + https://github.com/dotnet/roslyn - c02fb4f32a4a2f75454f996b8fc8489712083030 + fda44c407b951fe551c2a9935faf500bc3aea18b - + https://github.com/dotnet/roslyn - c02fb4f32a4a2f75454f996b8fc8489712083030 + fda44c407b951fe551c2a9935faf500bc3aea18b https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore diff --git a/eng/Versions.props b/eng/Versions.props index ae28b827bd76..5d5a4ec471d6 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -139,13 +139,13 @@ - 4.10.0-1.24066.1 - 4.10.0-1.24066.1 - 4.10.0-1.24066.1 - 4.10.0-1.24066.1 - 4.10.0-1.24066.1 - 4.10.0-1.24066.1 - 4.10.0-1.24066.1 + 4.10.0-1.24067.1 + 4.10.0-1.24067.1 + 4.10.0-1.24067.1 + 4.10.0-1.24067.1 + 4.10.0-1.24067.1 + 4.10.0-1.24067.1 + 4.10.0-1.24067.1 $(MicrosoftNetCompilersToolsetPackageVersion) From b4ecb9ab48d163169e74af11dda030cb5021ca4d Mon Sep 17 00:00:00 2001 From: Forgind <12969783+Forgind@users.noreply.github.com> Date: Wed, 17 Jan 2024 11:49:45 -0800 Subject: [PATCH 070/577] Fix NRE when using workload set mode --- .../dotnet-workload/install/NetSdkMsiInstallerServer.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Cli/dotnet/commands/dotnet-workload/install/NetSdkMsiInstallerServer.cs b/src/Cli/dotnet/commands/dotnet-workload/install/NetSdkMsiInstallerServer.cs index c62dd4b36096..02c3bd3ead58 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/install/NetSdkMsiInstallerServer.cs +++ b/src/Cli/dotnet/commands/dotnet-workload/install/NetSdkMsiInstallerServer.cs @@ -105,7 +105,7 @@ public void Run() case InstallRequestType.AdjustWorkloadMode: UpdateInstallMode(new SdkFeatureBand(request.SdkFeatureBand), request.UseWorkloadSets); - string newMode = request.ProductCode.Equals("true", StringComparison.OrdinalIgnoreCase) ? "workload sets" : "loose manifests"; + string newMode = request.UseWorkloadSets ? "workload sets" : "loose manifests"; Dispatcher.ReplySuccess($"Updated install mode to use {newMode}."); break; From 3ec1b9940131afb0d1c837fabd755de040be84aa Mon Sep 17 00:00:00 2001 From: Rainer Sigwald Date: Thu, 18 Jan 2024 03:28:15 -0600 Subject: [PATCH 071/577] Streamline and comment Roslyn->ApiCompat dependencies (#38086) --- .../Microsoft.DotNet.ApiCompat.Task.csproj | 8 ++++++++ .../Microsoft.DotNet.ApiCompatibility.csproj | 2 -- .../Microsoft.DotNet.ApiSymbolExtensions.csproj | 2 +- 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/src/ApiCompat/Microsoft.DotNet.ApiCompat.Task/Microsoft.DotNet.ApiCompat.Task.csproj b/src/ApiCompat/Microsoft.DotNet.ApiCompat.Task/Microsoft.DotNet.ApiCompat.Task.csproj index 6e6311533f68..3496e2086265 100644 --- a/src/ApiCompat/Microsoft.DotNet.ApiCompat.Task/Microsoft.DotNet.ApiCompat.Task.csproj +++ b/src/ApiCompat/Microsoft.DotNet.ApiCompat.Task/Microsoft.DotNet.ApiCompat.Task.csproj @@ -43,6 +43,14 @@ + diff --git a/src/ApiCompat/Microsoft.DotNet.ApiCompatibility/Microsoft.DotNet.ApiCompatibility.csproj b/src/ApiCompat/Microsoft.DotNet.ApiCompatibility/Microsoft.DotNet.ApiCompatibility.csproj index 6f12ef4f6bd7..60dfe5a399f3 100644 --- a/src/ApiCompat/Microsoft.DotNet.ApiCompatibility/Microsoft.DotNet.ApiCompatibility.csproj +++ b/src/ApiCompat/Microsoft.DotNet.ApiCompatibility/Microsoft.DotNet.ApiCompatibility.csproj @@ -15,8 +15,6 @@ - - diff --git a/src/Microsoft.DotNet.ApiSymbolExtensions/Microsoft.DotNet.ApiSymbolExtensions.csproj b/src/Microsoft.DotNet.ApiSymbolExtensions/Microsoft.DotNet.ApiSymbolExtensions.csproj index 3f1c9f3ddfb8..a014b2499ad7 100644 --- a/src/Microsoft.DotNet.ApiSymbolExtensions/Microsoft.DotNet.ApiSymbolExtensions.csproj +++ b/src/Microsoft.DotNet.ApiSymbolExtensions/Microsoft.DotNet.ApiSymbolExtensions.csproj @@ -14,7 +14,7 @@ - + From 65161fa371d11489e5c12a2b7d19a51dab85fa3b Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" Date: Thu, 18 Jan 2024 14:01:17 +0000 Subject: [PATCH 072/577] Update dependencies from https://github.com/nuget/nuget.client build 6.10.0.7 Microsoft.Build.NuGetSdkResolver , NuGet.Build.Tasks , NuGet.Build.Tasks.Console , NuGet.Build.Tasks.Pack , NuGet.CommandLine.XPlat , NuGet.Commands , NuGet.Common , NuGet.Configuration , NuGet.Credentials , NuGet.DependencyResolver.Core , NuGet.Frameworks , NuGet.LibraryModel , NuGet.Packaging , NuGet.ProjectModel , NuGet.Protocol , NuGet.Versioning From Version 6.9.0-rc.74 -> To Version 6.10.0-preview.1.7 --- eng/Version.Details.xml | 64 ++++++++++++++++++++--------------------- eng/Versions.props | 22 +++++++------- 2 files changed, 43 insertions(+), 43 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 6f1072077dd1..6586ece1122b 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -115,69 +115,69 @@ https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore 3f1acb59718cadf111a0a796681e3d3509bb3381 - + https://github.com/nuget/nuget.client - 28f7ba7a1e5c5d6db2e21e18b4ed2904ad9c0b6a + 9dd33574b0cf5110692ee8e9401a39857fb5523a - + https://github.com/nuget/nuget.client - 28f7ba7a1e5c5d6db2e21e18b4ed2904ad9c0b6a + 9dd33574b0cf5110692ee8e9401a39857fb5523a - + https://github.com/nuget/nuget.client - 28f7ba7a1e5c5d6db2e21e18b4ed2904ad9c0b6a + 9dd33574b0cf5110692ee8e9401a39857fb5523a - + https://github.com/nuget/nuget.client - 28f7ba7a1e5c5d6db2e21e18b4ed2904ad9c0b6a + 9dd33574b0cf5110692ee8e9401a39857fb5523a - + https://github.com/nuget/nuget.client - 28f7ba7a1e5c5d6db2e21e18b4ed2904ad9c0b6a + 9dd33574b0cf5110692ee8e9401a39857fb5523a - + https://github.com/nuget/nuget.client - 28f7ba7a1e5c5d6db2e21e18b4ed2904ad9c0b6a + 9dd33574b0cf5110692ee8e9401a39857fb5523a - + https://github.com/nuget/nuget.client - 28f7ba7a1e5c5d6db2e21e18b4ed2904ad9c0b6a + 9dd33574b0cf5110692ee8e9401a39857fb5523a - + https://github.com/nuget/nuget.client - 28f7ba7a1e5c5d6db2e21e18b4ed2904ad9c0b6a + 9dd33574b0cf5110692ee8e9401a39857fb5523a - + https://github.com/nuget/nuget.client - 28f7ba7a1e5c5d6db2e21e18b4ed2904ad9c0b6a + 9dd33574b0cf5110692ee8e9401a39857fb5523a - + https://github.com/nuget/nuget.client - 28f7ba7a1e5c5d6db2e21e18b4ed2904ad9c0b6a + 9dd33574b0cf5110692ee8e9401a39857fb5523a - + https://github.com/nuget/nuget.client - 28f7ba7a1e5c5d6db2e21e18b4ed2904ad9c0b6a + 9dd33574b0cf5110692ee8e9401a39857fb5523a - + https://github.com/nuget/nuget.client - 28f7ba7a1e5c5d6db2e21e18b4ed2904ad9c0b6a + 9dd33574b0cf5110692ee8e9401a39857fb5523a - + https://github.com/nuget/nuget.client - 28f7ba7a1e5c5d6db2e21e18b4ed2904ad9c0b6a + 9dd33574b0cf5110692ee8e9401a39857fb5523a - + https://github.com/nuget/nuget.client - 28f7ba7a1e5c5d6db2e21e18b4ed2904ad9c0b6a + 9dd33574b0cf5110692ee8e9401a39857fb5523a - + https://github.com/nuget/nuget.client - 28f7ba7a1e5c5d6db2e21e18b4ed2904ad9c0b6a + 9dd33574b0cf5110692ee8e9401a39857fb5523a - + https://github.com/nuget/nuget.client - 28f7ba7a1e5c5d6db2e21e18b4ed2904ad9c0b6a + 9dd33574b0cf5110692ee8e9401a39857fb5523a https://github.com/microsoft/vstest diff --git a/eng/Versions.props b/eng/Versions.props index 31ca2b40e3ec..fba5e84222e1 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -67,18 +67,18 @@ - 6.10.0-preview.1.5 - 6.10.0-preview.1.5 + 6.10.0-preview.1.7 + 6.10.0-preview.1.7 6.0.0-rc.278 - 6.10.0-preview.1.5 - 6.10.0-preview.1.5 - 6.10.0-preview.1.5 - 6.10.0-preview.1.5 - 6.10.0-preview.1.5 - 6.10.0-preview.1.5 - 6.10.0-preview.1.5 - 6.10.0-preview.1.5 - 6.10.0-preview.1.5 + 6.10.0-preview.1.7 + 6.10.0-preview.1.7 + 6.10.0-preview.1.7 + 6.10.0-preview.1.7 + 6.10.0-preview.1.7 + 6.10.0-preview.1.7 + 6.10.0-preview.1.7 + 6.10.0-preview.1.7 + 6.10.0-preview.1.7 $(NuGetPackagingPackageVersion) $(NuGetProjectModelPackageVersion) From e0e225cc467b6802c33ce78f0412a509411d190f Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" Date: Thu, 18 Jan 2024 14:02:27 +0000 Subject: [PATCH 073/577] Update dependencies from https://github.com/microsoft/vstest build 20240117.1 Microsoft.NET.Test.Sdk , Microsoft.TestPlatform.Build , Microsoft.TestPlatform.CLI From Version 17.9.0-release-23627-01 -> To Version 17.10.0-preview-24067-01 --- eng/Version.Details.xml | 12 ++++++------ eng/Versions.props | 6 +++--- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index c6eb2d5e33aa..b97264520502 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -179,18 +179,18 @@ https://github.com/nuget/nuget.client e92be3915309e687044768de38933ac5fc4cb40c - + https://github.com/microsoft/vstest - e5d81ae46d84fb90fb1dbc7c77770cfa585a05da + 1c68c247cc3d69ad04afeb574c3d0bc352ff16e5 - + https://github.com/microsoft/vstest - e5d81ae46d84fb90fb1dbc7c77770cfa585a05da + 1c68c247cc3d69ad04afeb574c3d0bc352ff16e5 - + https://github.com/microsoft/vstest - e5d81ae46d84fb90fb1dbc7c77770cfa585a05da + 1c68c247cc3d69ad04afeb574c3d0bc352ff16e5 https://dev.azure.com/dnceng/internal/_git/dotnet-runtime diff --git a/eng/Versions.props b/eng/Versions.props index 695f88c2f189..b1cb69a976ca 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -84,9 +84,9 @@ - 17.10.0-preview-24066-01 - 17.10.0-preview-24066-01 - 17.10.0-preview-24066-01 + 17.10.0-preview-24067-01 + 17.10.0-preview-24067-01 + 17.10.0-preview-24067-01 From d37744031f363a1108a5e17cf23b310f2bd6bd56 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Thu, 18 Jan 2024 17:20:53 +0000 Subject: [PATCH 074/577] [release/8.0.3xx] Update dependencies from dotnet/roslyn (#38107) [release/8.0.3xx] Update dependencies from dotnet/roslyn --- eng/Version.Details.xml | 28 ++++++++++++++-------------- eng/Versions.props | 14 +++++++------- 2 files changed, 21 insertions(+), 21 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 1f477c765864..3ef9ccd85b9d 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -78,34 +78,34 @@ 28925c0e519d66c80328aacf973b74e40bb1d5bd - + https://github.com/dotnet/roslyn - fda44c407b951fe551c2a9935faf500bc3aea18b + 3cd939f76803da435c20b082a5cfcc844386fcfb - + https://github.com/dotnet/roslyn - fda44c407b951fe551c2a9935faf500bc3aea18b + 3cd939f76803da435c20b082a5cfcc844386fcfb - + https://github.com/dotnet/roslyn - fda44c407b951fe551c2a9935faf500bc3aea18b + 3cd939f76803da435c20b082a5cfcc844386fcfb - + https://github.com/dotnet/roslyn - fda44c407b951fe551c2a9935faf500bc3aea18b + 3cd939f76803da435c20b082a5cfcc844386fcfb - + https://github.com/dotnet/roslyn - fda44c407b951fe551c2a9935faf500bc3aea18b + 3cd939f76803da435c20b082a5cfcc844386fcfb - + https://github.com/dotnet/roslyn - fda44c407b951fe551c2a9935faf500bc3aea18b + 3cd939f76803da435c20b082a5cfcc844386fcfb - + https://github.com/dotnet/roslyn - fda44c407b951fe551c2a9935faf500bc3aea18b + 3cd939f76803da435c20b082a5cfcc844386fcfb https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore diff --git a/eng/Versions.props b/eng/Versions.props index 5d5a4ec471d6..00054371d2b6 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -139,13 +139,13 @@ - 4.10.0-1.24067.1 - 4.10.0-1.24067.1 - 4.10.0-1.24067.1 - 4.10.0-1.24067.1 - 4.10.0-1.24067.1 - 4.10.0-1.24067.1 - 4.10.0-1.24067.1 + 4.10.0-1.24067.21 + 4.10.0-1.24067.21 + 4.10.0-1.24067.21 + 4.10.0-1.24067.21 + 4.10.0-1.24067.21 + 4.10.0-1.24067.21 + 4.10.0-1.24067.21 $(MicrosoftNetCompilersToolsetPackageVersion) From d1029788f6c55b9f7788cd63cd3f09aaf4e858d0 Mon Sep 17 00:00:00 2001 From: Marc Paine Date: Thu, 18 Jan 2024 12:32:11 -0800 Subject: [PATCH 075/577] Try disabling CPM in the dotnet new tests only --- .../TestDirectoryBuildProps/Directory.Build.props | 8 ++++++++ .../dotnet-new.Tests/dotnet-new.IntegrationTests.csproj | 4 ++++ 2 files changed, 12 insertions(+) create mode 100644 src/Tests/dotnet-new.Tests/TestDirectoryBuildProps/Directory.Build.props diff --git a/src/Tests/dotnet-new.Tests/TestDirectoryBuildProps/Directory.Build.props b/src/Tests/dotnet-new.Tests/TestDirectoryBuildProps/Directory.Build.props new file mode 100644 index 000000000000..b5f441385aef --- /dev/null +++ b/src/Tests/dotnet-new.Tests/TestDirectoryBuildProps/Directory.Build.props @@ -0,0 +1,8 @@ + + + + + + false + + diff --git a/src/Tests/dotnet-new.Tests/dotnet-new.IntegrationTests.csproj b/src/Tests/dotnet-new.Tests/dotnet-new.IntegrationTests.csproj index 3082e288c03f..7da7702341e7 100644 --- a/src/Tests/dotnet-new.Tests/dotnet-new.IntegrationTests.csproj +++ b/src/Tests/dotnet-new.Tests/dotnet-new.IntegrationTests.csproj @@ -62,6 +62,10 @@ namespace Microsoft.DotNet.Cli.New.IntegrationTests + + + + From 9186c42b3d18b8896f01a36e7f7404442e6eeec5 Mon Sep 17 00:00:00 2001 From: annie <59816815+JL03-Yue@users.noreply.github.com> Date: Thu, 18 Jan 2024 14:21:42 -0800 Subject: [PATCH 076/577] update roll forward description --- .../commands/dotnet-tool/install/LocalizableStrings.resx | 2 +- .../dotnet-tool/install/xlf/LocalizableStrings.cs.xlf | 4 ++-- .../dotnet-tool/install/xlf/LocalizableStrings.de.xlf | 4 ++-- .../dotnet-tool/install/xlf/LocalizableStrings.es.xlf | 4 ++-- .../dotnet-tool/install/xlf/LocalizableStrings.fr.xlf | 4 ++-- .../dotnet-tool/install/xlf/LocalizableStrings.it.xlf | 4 ++-- .../dotnet-tool/install/xlf/LocalizableStrings.ja.xlf | 4 ++-- .../dotnet-tool/install/xlf/LocalizableStrings.ko.xlf | 4 ++-- .../dotnet-tool/install/xlf/LocalizableStrings.pl.xlf | 4 ++-- .../dotnet-tool/install/xlf/LocalizableStrings.pt-BR.xlf | 4 ++-- .../dotnet-tool/install/xlf/LocalizableStrings.ru.xlf | 4 ++-- .../dotnet-tool/install/xlf/LocalizableStrings.tr.xlf | 4 ++-- .../dotnet-tool/install/xlf/LocalizableStrings.zh-Hans.xlf | 4 ++-- .../dotnet-tool/install/xlf/LocalizableStrings.zh-Hant.xlf | 4 ++-- 14 files changed, 27 insertions(+), 27 deletions(-) diff --git a/src/Cli/dotnet/commands/dotnet-tool/install/LocalizableStrings.resx b/src/Cli/dotnet/commands/dotnet-tool/install/LocalizableStrings.resx index 559c7f70dd29..8ac4b5009da6 100644 --- a/src/Cli/dotnet/commands/dotnet-tool/install/LocalizableStrings.resx +++ b/src/Cli/dotnet/commands/dotnet-tool/install/LocalizableStrings.resx @@ -236,7 +236,7 @@ If you would like to create a manifest, use `dotnet new tool-manifest`, usually Create a tool manifest if one isn't found during tool installation. For information on how manifests are located, see https://aka.ms/dotnet/tools/create-manifest-if-needed - Roll forward to framework version of Major. + Allow a .NET tool to roll forward to newer versions of the .NET runtime if the runtime it targets isn't installed. Allow package downgrade when installing a .NET tool package. diff --git a/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.cs.xlf b/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.cs.xlf index 30234b4843ef..735a157bc6e0 100644 --- a/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.cs.xlf +++ b/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.cs.xlf @@ -89,8 +89,8 @@ Pokud chcete vytvořit manifest, použijte příkaz dotnet new tool-manifest, ob - Roll forward to framework version of Major. - Roll forward to framework version of Major. + Allow a .NET tool to roll forward to newer versions of the .NET runtime if the runtime it targets isn't installed. + Allow a .NET tool to roll forward to newer versions of the .NET runtime if the runtime it targets isn't installed. diff --git a/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.de.xlf b/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.de.xlf index 745e3dbc0949..1b7f7e703936 100644 --- a/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.de.xlf +++ b/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.de.xlf @@ -89,8 +89,8 @@ Wenn Sie ein Manifest erstellen möchten, verwenden Sie "dotnet new tool-manifes - Roll forward to framework version of Major. - Roll forward to framework version of Major. + Allow a .NET tool to roll forward to newer versions of the .NET runtime if the runtime it targets isn't installed. + Allow a .NET tool to roll forward to newer versions of the .NET runtime if the runtime it targets isn't installed. diff --git a/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.es.xlf b/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.es.xlf index ff85ad03d789..9c9f846c914b 100644 --- a/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.es.xlf +++ b/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.es.xlf @@ -89,8 +89,8 @@ Si desea crear un manifiesto, utilice "dotnet new tool-manifest", normalmente en - Roll forward to framework version of Major. - Roll forward to framework version of Major. + Allow a .NET tool to roll forward to newer versions of the .NET runtime if the runtime it targets isn't installed. + Allow a .NET tool to roll forward to newer versions of the .NET runtime if the runtime it targets isn't installed. diff --git a/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.fr.xlf b/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.fr.xlf index 34a8bf330e10..9dfad6c47230 100644 --- a/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.fr.xlf +++ b/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.fr.xlf @@ -89,8 +89,8 @@ Si vous souhaitez créer un manifeste, utilisez 'dotnet new tool-manifest', gén - Roll forward to framework version of Major. - Roll forward to framework version of Major. + Allow a .NET tool to roll forward to newer versions of the .NET runtime if the runtime it targets isn't installed. + Allow a .NET tool to roll forward to newer versions of the .NET runtime if the runtime it targets isn't installed. diff --git a/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.it.xlf b/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.it.xlf index 5508e7fa4b46..84fe98987e13 100644 --- a/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.it.xlf +++ b/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.it.xlf @@ -89,8 +89,8 @@ Se si vuole creare un manifesto, usare `dotnet new tool-manifest`, in genere nel - Roll forward to framework version of Major. - Roll forward to framework version of Major. + Allow a .NET tool to roll forward to newer versions of the .NET runtime if the runtime it targets isn't installed. + Allow a .NET tool to roll forward to newer versions of the .NET runtime if the runtime it targets isn't installed. diff --git a/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.ja.xlf b/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.ja.xlf index 3f72bc8aa0df..67ae0b159ded 100644 --- a/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.ja.xlf +++ b/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.ja.xlf @@ -89,8 +89,8 @@ If you would like to create a manifest, use `dotnet new tool-manifest`, usually - Roll forward to framework version of Major. - Roll forward to framework version of Major. + Allow a .NET tool to roll forward to newer versions of the .NET runtime if the runtime it targets isn't installed. + Allow a .NET tool to roll forward to newer versions of the .NET runtime if the runtime it targets isn't installed. diff --git a/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.ko.xlf b/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.ko.xlf index f96623967394..a0f08847fa64 100644 --- a/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.ko.xlf +++ b/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.ko.xlf @@ -89,8 +89,8 @@ If you would like to create a manifest, use `dotnet new tool-manifest`, usually - Roll forward to framework version of Major. - Roll forward to framework version of Major. + Allow a .NET tool to roll forward to newer versions of the .NET runtime if the runtime it targets isn't installed. + Allow a .NET tool to roll forward to newer versions of the .NET runtime if the runtime it targets isn't installed. diff --git a/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.pl.xlf b/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.pl.xlf index 1fc5eeb0f5d5..f194562ee05f 100644 --- a/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.pl.xlf +++ b/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.pl.xlf @@ -89,8 +89,8 @@ Jeśli chcesz utworzyć manifest, użyj polecenia „dotnet new tool-manifest” - Roll forward to framework version of Major. - Roll forward to framework version of Major. + Allow a .NET tool to roll forward to newer versions of the .NET runtime if the runtime it targets isn't installed. + Allow a .NET tool to roll forward to newer versions of the .NET runtime if the runtime it targets isn't installed. diff --git a/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.pt-BR.xlf b/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.pt-BR.xlf index d166554888b3..8fdf1c9f92ed 100644 --- a/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.pt-BR.xlf +++ b/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.pt-BR.xlf @@ -89,8 +89,8 @@ Se quiser criar um manifesto, use `dotnet new tool-manifest`, normalmente no dir - Roll forward to framework version of Major. - Roll forward to framework version of Major. + Allow a .NET tool to roll forward to newer versions of the .NET runtime if the runtime it targets isn't installed. + Allow a .NET tool to roll forward to newer versions of the .NET runtime if the runtime it targets isn't installed. diff --git a/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.ru.xlf b/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.ru.xlf index f7e0926cb427..0fe3aa552cec 100644 --- a/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.ru.xlf +++ b/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.ru.xlf @@ -89,8 +89,8 @@ If you would like to create a manifest, use `dotnet new tool-manifest`, usually - Roll forward to framework version of Major. - Roll forward to framework version of Major. + Allow a .NET tool to roll forward to newer versions of the .NET runtime if the runtime it targets isn't installed. + Allow a .NET tool to roll forward to newer versions of the .NET runtime if the runtime it targets isn't installed. diff --git a/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.tr.xlf b/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.tr.xlf index 9483f86584a7..ff47821bbced 100644 --- a/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.tr.xlf +++ b/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.tr.xlf @@ -89,8 +89,8 @@ Bir bildirim oluşturmak istiyorsanız 'dotnet new tool-manifest' ifadesini kull - Roll forward to framework version of Major. - Roll forward to framework version of Major. + Allow a .NET tool to roll forward to newer versions of the .NET runtime if the runtime it targets isn't installed. + Allow a .NET tool to roll forward to newer versions of the .NET runtime if the runtime it targets isn't installed. diff --git a/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.zh-Hans.xlf b/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.zh-Hans.xlf index 80da952f9c2a..716870df80b6 100644 --- a/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.zh-Hans.xlf +++ b/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.zh-Hans.xlf @@ -89,8 +89,8 @@ If you would like to create a manifest, use `dotnet new tool-manifest`, usually - Roll forward to framework version of Major. - Roll forward to framework version of Major. + Allow a .NET tool to roll forward to newer versions of the .NET runtime if the runtime it targets isn't installed. + Allow a .NET tool to roll forward to newer versions of the .NET runtime if the runtime it targets isn't installed. diff --git a/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.zh-Hant.xlf b/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.zh-Hant.xlf index 7800ac7449cc..3ae4eebbc937 100644 --- a/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.zh-Hant.xlf +++ b/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.zh-Hant.xlf @@ -89,8 +89,8 @@ If you would like to create a manifest, use `dotnet new tool-manifest`, usually - Roll forward to framework version of Major. - Roll forward to framework version of Major. + Allow a .NET tool to roll forward to newer versions of the .NET runtime if the runtime it targets isn't installed. + Allow a .NET tool to roll forward to newer versions of the .NET runtime if the runtime it targets isn't installed. From f7e473220665acfbd65b6ed03db7dbae263466f2 Mon Sep 17 00:00:00 2001 From: annie <59816815+JL03-Yue@users.noreply.github.com> Date: Thu, 18 Jan 2024 14:23:29 -0800 Subject: [PATCH 077/577] skip updating runtime config if does not exist --- .../ToolPackage/ToolPackageDownloader.cs | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/src/Cli/dotnet/ToolPackage/ToolPackageDownloader.cs b/src/Cli/dotnet/ToolPackage/ToolPackageDownloader.cs index 6b5caf25ac6d..12c33edcbb8a 100644 --- a/src/Cli/dotnet/ToolPackage/ToolPackageDownloader.cs +++ b/src/Cli/dotnet/ToolPackage/ToolPackageDownloader.cs @@ -213,15 +213,18 @@ ToolPackageInstance toolPackageInstance var runtimeConfigFilePath = Path.ChangeExtension(executableFilePath.ToString(), ".runtimeconfig.json"); // Update the runtimeconfig.json file - string existingJson = File.ReadAllText(runtimeConfigFilePath); - - var jsonObject = JObject.Parse(existingJson); - var runtimeOptions = jsonObject["runtimeOptions"] as JObject; - if (runtimeOptions != null) + if (File.Exists(runtimeConfigFilePath)) { - runtimeOptions["rollForward"] = "Major"; - string updateJson = jsonObject.ToString(); - File.WriteAllText(runtimeConfigFilePath, updateJson); + string existingJson = File.ReadAllText(runtimeConfigFilePath); + + var jsonObject = JObject.Parse(existingJson); + var runtimeOptions = jsonObject["runtimeOptions"] as JObject; + if (runtimeOptions != null) + { + runtimeOptions["rollForward"] = "Major"; + string updateJson = jsonObject.ToString(); + File.WriteAllText(runtimeConfigFilePath, updateJson); + } } } From 1f08c96921f40d92ace753531f3c27fb90778a12 Mon Sep 17 00:00:00 2001 From: annie <59816815+JL03-Yue@users.noreply.github.com> Date: Thu, 18 Jan 2024 14:25:48 -0800 Subject: [PATCH 078/577] take roll forward into consideration in ToolManifestPackage --- src/Cli/dotnet/ToolManifest/ToolManifestPackage.cs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/Cli/dotnet/ToolManifest/ToolManifestPackage.cs b/src/Cli/dotnet/ToolManifest/ToolManifestPackage.cs index 4cb664884e63..57bf419a0f89 100644 --- a/src/Cli/dotnet/ToolManifest/ToolManifestPackage.cs +++ b/src/Cli/dotnet/ToolManifest/ToolManifestPackage.cs @@ -46,7 +46,8 @@ public bool Equals(ToolManifestPackage other) EqualityComparer.Default.Equals(Version, other.Version) && CommandNamesEqual(other.CommandNames) && FirstEffectDirectory.Value.TrimEnd('/', '\\') - .Equals(other.FirstEffectDirectory.Value.TrimEnd('/', '\\'), StringComparison.Ordinal); + .Equals(other.FirstEffectDirectory.Value.TrimEnd('/', '\\'), StringComparison.Ordinal) && + RollForward.Equals(other.RollForward); } private bool CommandNamesEqual(ToolCommandName[] otherCommandNames) @@ -66,7 +67,7 @@ private bool CommandNamesEqual(ToolCommandName[] otherCommandNames) public override int GetHashCode() { - return HashCode.Combine(PackageId, Version, CommandNames); + return HashCode.Combine(PackageId, Version, CommandNames, RollForward); } public static bool operator ==(ToolManifestPackage tool1, From 5718c7e4f56f6e1da7fb4f3524b736b74994232e Mon Sep 17 00:00:00 2001 From: annie <59816815+JL03-Yue@users.noreply.github.com> Date: Thu, 18 Jan 2024 14:29:12 -0800 Subject: [PATCH 079/577] change from --roll-forward to --allow-roll-forward --- .../CommandFactory/CommandResolution/MuxerCommandSpecMaker.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Cli/dotnet/CommandFactory/CommandResolution/MuxerCommandSpecMaker.cs b/src/Cli/dotnet/CommandFactory/CommandResolution/MuxerCommandSpecMaker.cs index d71a840c2d20..a08661efe8e9 100644 --- a/src/Cli/dotnet/CommandFactory/CommandResolution/MuxerCommandSpecMaker.cs +++ b/src/Cli/dotnet/CommandFactory/CommandResolution/MuxerCommandSpecMaker.cs @@ -23,8 +23,8 @@ internal static CommandSpec CreatePackageCommandSpecUsingMuxer( // Group the arguments by if the previous argument or the current argument is --roll-forward. var argGroups = (commandArguments ?? []) - .GroupBy(a => previousArg.Equals("--roll-forward", StringComparison.OrdinalIgnoreCase) - | (previousArg = a).Equals("--roll-forward", StringComparison.OrdinalIgnoreCase)) + .GroupBy(a => previousArg.Equals("--allow-roll-forward", StringComparison.OrdinalIgnoreCase) + | (previousArg = a).Equals("--allow-roll-forward", StringComparison.OrdinalIgnoreCase)) .ToArray(); string[] arguments = [..argGroups.Where(g => g.Key).SelectMany(g => g), commandPath, .. argGroups.Where(g => !g.Key).SelectMany(g => g)]; From 6459f969a7c0915eee3064fb0e4d0a7aed2359a1 Mon Sep 17 00:00:00 2001 From: annie <59816815+JL03-Yue@users.noreply.github.com> Date: Thu, 18 Jan 2024 14:30:21 -0800 Subject: [PATCH 080/577] simplify logic --- .../CommandResolution/LocalToolsCommandResolver.cs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/Cli/dotnet/CommandFactory/CommandResolution/LocalToolsCommandResolver.cs b/src/Cli/dotnet/CommandFactory/CommandResolution/LocalToolsCommandResolver.cs index 19c1ef4623a4..35d7cba716a1 100644 --- a/src/Cli/dotnet/CommandFactory/CommandResolution/LocalToolsCommandResolver.cs +++ b/src/Cli/dotnet/CommandFactory/CommandResolution/LocalToolsCommandResolver.cs @@ -81,10 +81,9 @@ private CommandSpec GetPackageCommandSpecUsingMuxer(CommandResolverArguments arg return null; } - if( arguments.CommandArguments != null) + if( arguments.CommandArguments != null && allowRollForward) { - var commandArgument = (allowRollForward != false ? new List { "--roll-forward", "Major" } : Enumerable.Empty()).Concat(arguments.CommandArguments); - arguments.CommandArguments = commandArgument; + arguments.CommandArguments = ["--roll-forward", "Major", .. arguments.CommandArguments]; } From 85a63440726719ff4456741f81111036a53f8f80 Mon Sep 17 00:00:00 2001 From: annie <59816815+JL03-Yue@users.noreply.github.com> Date: Thu, 18 Jan 2024 14:55:43 -0800 Subject: [PATCH 081/577] remove RollForwardOption in ToolRunCommand and reuse the one in install --- .../dotnet/commands/dotnet-tool/run/LocalizableStrings.resx | 3 --- .../dotnet/commands/dotnet-tool/run/ToolRunCommandParser.cs | 3 ++- .../commands/dotnet-tool/run/xlf/LocalizableStrings.cs.xlf | 5 ----- .../commands/dotnet-tool/run/xlf/LocalizableStrings.de.xlf | 5 ----- .../commands/dotnet-tool/run/xlf/LocalizableStrings.es.xlf | 5 ----- .../commands/dotnet-tool/run/xlf/LocalizableStrings.fr.xlf | 5 ----- .../commands/dotnet-tool/run/xlf/LocalizableStrings.it.xlf | 5 ----- .../commands/dotnet-tool/run/xlf/LocalizableStrings.ja.xlf | 5 ----- .../commands/dotnet-tool/run/xlf/LocalizableStrings.ko.xlf | 5 ----- .../commands/dotnet-tool/run/xlf/LocalizableStrings.pl.xlf | 5 ----- .../dotnet-tool/run/xlf/LocalizableStrings.pt-BR.xlf | 5 ----- .../commands/dotnet-tool/run/xlf/LocalizableStrings.ru.xlf | 5 ----- .../commands/dotnet-tool/run/xlf/LocalizableStrings.tr.xlf | 5 ----- .../dotnet-tool/run/xlf/LocalizableStrings.zh-Hans.xlf | 5 ----- .../dotnet-tool/run/xlf/LocalizableStrings.zh-Hant.xlf | 5 ----- 15 files changed, 2 insertions(+), 69 deletions(-) diff --git a/src/Cli/dotnet/commands/dotnet-tool/run/LocalizableStrings.resx b/src/Cli/dotnet/commands/dotnet-tool/run/LocalizableStrings.resx index 7f51ded07454..9106b3bbf2e7 100644 --- a/src/Cli/dotnet/commands/dotnet-tool/run/LocalizableStrings.resx +++ b/src/Cli/dotnet/commands/dotnet-tool/run/LocalizableStrings.resx @@ -129,9 +129,6 @@ COMMAND_NAME - - Roll forward to framework version (LatestPatch, Minor, LatestMinor, Major, LatestMajor, Disable). - Specify one command name to run. diff --git a/src/Cli/dotnet/commands/dotnet-tool/run/ToolRunCommandParser.cs b/src/Cli/dotnet/commands/dotnet-tool/run/ToolRunCommandParser.cs index 228c722327e5..1c7138cf49d7 100644 --- a/src/Cli/dotnet/commands/dotnet-tool/run/ToolRunCommandParser.cs +++ b/src/Cli/dotnet/commands/dotnet-tool/run/ToolRunCommandParser.cs @@ -3,6 +3,7 @@ using System.CommandLine; using Microsoft.DotNet.Tools.Tool.Run; +using Microsoft.DotNet.Tools.Tool.Install; using LocalizableStrings = Microsoft.DotNet.Tools.Tool.Run.LocalizableStrings; namespace Microsoft.DotNet.Cli @@ -22,7 +23,7 @@ internal static class ToolRunCommandParser public static readonly CliOption RollForwardOption = new("--allow-roll-forward") { - Description = LocalizableStrings.RollForwardDescription + Description = Tools.Tool.Install.LocalizableStrings.RollForwardOptionDescription }; private static readonly CliCommand Command = ConstructCommand(); diff --git a/src/Cli/dotnet/commands/dotnet-tool/run/xlf/LocalizableStrings.cs.xlf b/src/Cli/dotnet/commands/dotnet-tool/run/xlf/LocalizableStrings.cs.xlf index c3b1cbc660ce..b4c0873e8fb5 100644 --- a/src/Cli/dotnet/commands/dotnet-tool/run/xlf/LocalizableStrings.cs.xlf +++ b/src/Cli/dotnet/commands/dotnet-tool/run/xlf/LocalizableStrings.cs.xlf @@ -22,11 +22,6 @@ COMMAND_NAME - - Roll forward to framework version (LatestPatch, Minor, LatestMinor, Major, LatestMajor, Disable). - Roll forward to framework version (LatestPatch, Minor, LatestMinor, Major, LatestMajor, Disable). - - Specify one command name to run. Zadejte jeden název příkazu, který se má spustit. diff --git a/src/Cli/dotnet/commands/dotnet-tool/run/xlf/LocalizableStrings.de.xlf b/src/Cli/dotnet/commands/dotnet-tool/run/xlf/LocalizableStrings.de.xlf index 7988a6605f5d..8c7b5bacd5af 100644 --- a/src/Cli/dotnet/commands/dotnet-tool/run/xlf/LocalizableStrings.de.xlf +++ b/src/Cli/dotnet/commands/dotnet-tool/run/xlf/LocalizableStrings.de.xlf @@ -22,11 +22,6 @@ COMMAND_NAME - - Roll forward to framework version (LatestPatch, Minor, LatestMinor, Major, LatestMajor, Disable). - Roll forward to framework version (LatestPatch, Minor, LatestMinor, Major, LatestMajor, Disable). - - Specify one command name to run. Geben Sie einen Befehlsnamen für die Ausführung an. diff --git a/src/Cli/dotnet/commands/dotnet-tool/run/xlf/LocalizableStrings.es.xlf b/src/Cli/dotnet/commands/dotnet-tool/run/xlf/LocalizableStrings.es.xlf index 4cdb0eeaaea3..c1d1149f4b03 100644 --- a/src/Cli/dotnet/commands/dotnet-tool/run/xlf/LocalizableStrings.es.xlf +++ b/src/Cli/dotnet/commands/dotnet-tool/run/xlf/LocalizableStrings.es.xlf @@ -22,11 +22,6 @@ COMMAND_NAME - - Roll forward to framework version (LatestPatch, Minor, LatestMinor, Major, LatestMajor, Disable). - Roll forward to framework version (LatestPatch, Minor, LatestMinor, Major, LatestMajor, Disable). - - Specify one command name to run. Especifique un nombre de comando para ejecutar. diff --git a/src/Cli/dotnet/commands/dotnet-tool/run/xlf/LocalizableStrings.fr.xlf b/src/Cli/dotnet/commands/dotnet-tool/run/xlf/LocalizableStrings.fr.xlf index 51002191f317..6f5e5ef53655 100644 --- a/src/Cli/dotnet/commands/dotnet-tool/run/xlf/LocalizableStrings.fr.xlf +++ b/src/Cli/dotnet/commands/dotnet-tool/run/xlf/LocalizableStrings.fr.xlf @@ -22,11 +22,6 @@ COMMAND_NAME - - Roll forward to framework version (LatestPatch, Minor, LatestMinor, Major, LatestMajor, Disable). - Roll forward to framework version (LatestPatch, Minor, LatestMinor, Major, LatestMajor, Disable). - - Specify one command name to run. Spécifiez un nom de commande à exécuter. diff --git a/src/Cli/dotnet/commands/dotnet-tool/run/xlf/LocalizableStrings.it.xlf b/src/Cli/dotnet/commands/dotnet-tool/run/xlf/LocalizableStrings.it.xlf index f87a3762a11a..a2c03d42495e 100644 --- a/src/Cli/dotnet/commands/dotnet-tool/run/xlf/LocalizableStrings.it.xlf +++ b/src/Cli/dotnet/commands/dotnet-tool/run/xlf/LocalizableStrings.it.xlf @@ -22,11 +22,6 @@ COMMAND_NAME - - Roll forward to framework version (LatestPatch, Minor, LatestMinor, Major, LatestMajor, Disable). - Roll forward to framework version (LatestPatch, Minor, LatestMinor, Major, LatestMajor, Disable). - - Specify one command name to run. Specificare il nome di un comando da eseguire. diff --git a/src/Cli/dotnet/commands/dotnet-tool/run/xlf/LocalizableStrings.ja.xlf b/src/Cli/dotnet/commands/dotnet-tool/run/xlf/LocalizableStrings.ja.xlf index 9569cc5f4273..f3e91c7e6885 100644 --- a/src/Cli/dotnet/commands/dotnet-tool/run/xlf/LocalizableStrings.ja.xlf +++ b/src/Cli/dotnet/commands/dotnet-tool/run/xlf/LocalizableStrings.ja.xlf @@ -22,11 +22,6 @@ COMMAND_NAME - - Roll forward to framework version (LatestPatch, Minor, LatestMinor, Major, LatestMajor, Disable). - Roll forward to framework version (LatestPatch, Minor, LatestMinor, Major, LatestMajor, Disable). - - Specify one command name to run. 実行するコマンド名を 1 つ指定してください。 diff --git a/src/Cli/dotnet/commands/dotnet-tool/run/xlf/LocalizableStrings.ko.xlf b/src/Cli/dotnet/commands/dotnet-tool/run/xlf/LocalizableStrings.ko.xlf index aabf61964d20..03225353ab78 100644 --- a/src/Cli/dotnet/commands/dotnet-tool/run/xlf/LocalizableStrings.ko.xlf +++ b/src/Cli/dotnet/commands/dotnet-tool/run/xlf/LocalizableStrings.ko.xlf @@ -22,11 +22,6 @@ COMMAND_NAME - - Roll forward to framework version (LatestPatch, Minor, LatestMinor, Major, LatestMajor, Disable). - Roll forward to framework version (LatestPatch, Minor, LatestMinor, Major, LatestMajor, Disable). - - Specify one command name to run. 실행할 명령 이름을 하나 지정하세요. diff --git a/src/Cli/dotnet/commands/dotnet-tool/run/xlf/LocalizableStrings.pl.xlf b/src/Cli/dotnet/commands/dotnet-tool/run/xlf/LocalizableStrings.pl.xlf index 0d17bb665bd2..ef27cbb0310e 100644 --- a/src/Cli/dotnet/commands/dotnet-tool/run/xlf/LocalizableStrings.pl.xlf +++ b/src/Cli/dotnet/commands/dotnet-tool/run/xlf/LocalizableStrings.pl.xlf @@ -22,11 +22,6 @@ COMMAND_NAME - - Roll forward to framework version (LatestPatch, Minor, LatestMinor, Major, LatestMajor, Disable). - Roll forward to framework version (LatestPatch, Minor, LatestMinor, Major, LatestMajor, Disable). - - Specify one command name to run. Określ jedną nazwę polecenia do uruchomienia. diff --git a/src/Cli/dotnet/commands/dotnet-tool/run/xlf/LocalizableStrings.pt-BR.xlf b/src/Cli/dotnet/commands/dotnet-tool/run/xlf/LocalizableStrings.pt-BR.xlf index 21209afaa841..bf18313eded7 100644 --- a/src/Cli/dotnet/commands/dotnet-tool/run/xlf/LocalizableStrings.pt-BR.xlf +++ b/src/Cli/dotnet/commands/dotnet-tool/run/xlf/LocalizableStrings.pt-BR.xlf @@ -22,11 +22,6 @@ COMMAND_NAME - - Roll forward to framework version (LatestPatch, Minor, LatestMinor, Major, LatestMajor, Disable). - Roll forward to framework version (LatestPatch, Minor, LatestMinor, Major, LatestMajor, Disable). - - Specify one command name to run. Especifique um nome de comando a ser executado. diff --git a/src/Cli/dotnet/commands/dotnet-tool/run/xlf/LocalizableStrings.ru.xlf b/src/Cli/dotnet/commands/dotnet-tool/run/xlf/LocalizableStrings.ru.xlf index 804551d504fb..0631bb8546d5 100644 --- a/src/Cli/dotnet/commands/dotnet-tool/run/xlf/LocalizableStrings.ru.xlf +++ b/src/Cli/dotnet/commands/dotnet-tool/run/xlf/LocalizableStrings.ru.xlf @@ -22,11 +22,6 @@ COMMAND_NAME - - Roll forward to framework version (LatestPatch, Minor, LatestMinor, Major, LatestMajor, Disable). - Roll forward to framework version (LatestPatch, Minor, LatestMinor, Major, LatestMajor, Disable). - - Specify one command name to run. Укажите одно имя выполняемой команды. diff --git a/src/Cli/dotnet/commands/dotnet-tool/run/xlf/LocalizableStrings.tr.xlf b/src/Cli/dotnet/commands/dotnet-tool/run/xlf/LocalizableStrings.tr.xlf index 40006845cfa1..ad2c3f2c68fa 100644 --- a/src/Cli/dotnet/commands/dotnet-tool/run/xlf/LocalizableStrings.tr.xlf +++ b/src/Cli/dotnet/commands/dotnet-tool/run/xlf/LocalizableStrings.tr.xlf @@ -22,11 +22,6 @@ COMMAND_NAME - - Roll forward to framework version (LatestPatch, Minor, LatestMinor, Major, LatestMajor, Disable). - Roll forward to framework version (LatestPatch, Minor, LatestMinor, Major, LatestMajor, Disable). - - Specify one command name to run. Çalıştırılacak tek bir komut adı belirtin. diff --git a/src/Cli/dotnet/commands/dotnet-tool/run/xlf/LocalizableStrings.zh-Hans.xlf b/src/Cli/dotnet/commands/dotnet-tool/run/xlf/LocalizableStrings.zh-Hans.xlf index a07a13b5f987..7b7ffeb2ddac 100644 --- a/src/Cli/dotnet/commands/dotnet-tool/run/xlf/LocalizableStrings.zh-Hans.xlf +++ b/src/Cli/dotnet/commands/dotnet-tool/run/xlf/LocalizableStrings.zh-Hans.xlf @@ -22,11 +22,6 @@ COMMAND_NAME - - Roll forward to framework version (LatestPatch, Minor, LatestMinor, Major, LatestMajor, Disable). - Roll forward to framework version (LatestPatch, Minor, LatestMinor, Major, LatestMajor, Disable). - - Specify one command name to run. 请指定一个要运行的命令名称。 diff --git a/src/Cli/dotnet/commands/dotnet-tool/run/xlf/LocalizableStrings.zh-Hant.xlf b/src/Cli/dotnet/commands/dotnet-tool/run/xlf/LocalizableStrings.zh-Hant.xlf index fa8e0b729121..cea23c4a3b36 100644 --- a/src/Cli/dotnet/commands/dotnet-tool/run/xlf/LocalizableStrings.zh-Hant.xlf +++ b/src/Cli/dotnet/commands/dotnet-tool/run/xlf/LocalizableStrings.zh-Hant.xlf @@ -22,11 +22,6 @@ COMMAND_NAME - - Roll forward to framework version (LatestPatch, Minor, LatestMinor, Major, LatestMajor, Disable). - Roll forward to framework version (LatestPatch, Minor, LatestMinor, Major, LatestMajor, Disable). - - Specify one command name to run. 請指定一個要執行的命令名稱。 From 86bdc77dd0d70ecf5e71727443c800f9d33b9751 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Thu, 18 Jan 2024 23:09:40 +0000 Subject: [PATCH 082/577] [release/8.0.3xx] Update dependencies from dotnet/msbuild (#38105) [release/8.0.3xx] Update dependencies from dotnet/msbuild --- eng/Version.Details.xml | 12 ++++++------ eng/Versions.props | 4 ++-- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 3ef9ccd85b9d..c1be2889d951 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -51,17 +51,17 @@ https://github.com/dotnet/emsdk 2406616d0e3a31d80b326e27c156955bfa41c791 - + https://github.com/dotnet/msbuild - f1448f15870e0d229cb9ae6efe336b94cefe3ab3 + 6e97308dc4652452833d8ee1ca1d0c1cf5d17ad3 - + https://github.com/dotnet/msbuild - f1448f15870e0d229cb9ae6efe336b94cefe3ab3 + 6e97308dc4652452833d8ee1ca1d0c1cf5d17ad3 - + https://github.com/dotnet/msbuild - f1448f15870e0d229cb9ae6efe336b94cefe3ab3 + 6e97308dc4652452833d8ee1ca1d0c1cf5d17ad3 diff --git a/eng/Versions.props b/eng/Versions.props index 00054371d2b6..9df7b80630c9 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -105,7 +105,7 @@ - 17.10.0-preview-24067-01 + 17.10.0-preview-24068-10 $(MicrosoftBuildPackageVersion) - 7.0.0-preview.24066.1 - 7.0.0-preview.24066.1 - 7.0.0-preview.24066.1 + 7.0.0-preview.24067.4 + 7.0.0-preview.24067.4 + 7.0.0-preview.24067.4 From 27e1f949245ce233a1975479629bbaa6a46bce0f Mon Sep 17 00:00:00 2001 From: Marc Paine Date: Thu, 18 Jan 2024 14:48:24 -0800 Subject: [PATCH 084/577] Add System.Data.Client to the set of centrally managed versions for tests --- eng/Versions.props | 1 + .../CompilationContext/TestApp/TestApp.csproj | 2 +- .../GivenThatWeWantToPreserveCompilationContext.cs | 4 ++-- src/Tests/Microsoft.NET.TestFramework/ToolsetInfo.cs | 11 +++++++++++ 4 files changed, 15 insertions(+), 3 deletions(-) diff --git a/eng/Versions.props b/eng/Versions.props index e30dd571a418..e367d12254bb 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -30,6 +30,7 @@ 2.21.0 2.0.1-servicing-26011-01 13.0.3 + 4.8.6 1.2.0-beta.435 7.0.0 4.0.0 diff --git a/src/Assets/TestProjects/CompilationContext/TestApp/TestApp.csproj b/src/Assets/TestProjects/CompilationContext/TestApp/TestApp.csproj index e5ed95dd4815..dd45346cf8fc 100644 --- a/src/Assets/TestProjects/CompilationContext/TestApp/TestApp.csproj +++ b/src/Assets/TestProjects/CompilationContext/TestApp/TestApp.csproj @@ -10,6 +10,6 @@ - + \ No newline at end of file diff --git a/src/Tests/Microsoft.NET.Publish.Tests/GivenThatWeWantToPreserveCompilationContext.cs b/src/Tests/Microsoft.NET.Publish.Tests/GivenThatWeWantToPreserveCompilationContext.cs index ba0dbada6b99..e9c364476f2d 100644 --- a/src/Tests/Microsoft.NET.Publish.Tests/GivenThatWeWantToPreserveCompilationContext.cs +++ b/src/Tests/Microsoft.NET.Publish.Tests/GivenThatWeWantToPreserveCompilationContext.cs @@ -48,7 +48,7 @@ public void It_publishes_the_project_with_a_refs_folder_and_correct_deps_file(st testProject.ReferencedProjects.Add(testLibraryProject); testProject.PackageReferences.Add(new TestPackageReference("Newtonsoft.Json", ToolsetInfo.GetNewtonsoftJsonPackageVersion())); - testProject.PackageReferences.Add(new TestPackageReference("System.Data.SqlClient", "4.4.3")); + testProject.PackageReferences.Add(new TestPackageReference("System.Data.SqlClient", ToolsetInfo.GetSystemDataSqlClientPackageVersion())); var testAsset = _testAssetsManager.CreateTestProject(testProject, identifier: appTargetFramework + withoutCopyingRefs); @@ -185,7 +185,7 @@ public void It_excludes_runtime_store_packages_from_the_refs_folder() { "", $@" ", - @" ", + $@" ", "", }); diff --git a/src/Tests/Microsoft.NET.TestFramework/ToolsetInfo.cs b/src/Tests/Microsoft.NET.TestFramework/ToolsetInfo.cs index 098c7f489143..fc3505893bdc 100644 --- a/src/Tests/Microsoft.NET.TestFramework/ToolsetInfo.cs +++ b/src/Tests/Microsoft.NET.TestFramework/ToolsetInfo.cs @@ -423,5 +423,16 @@ public static string GetNewtonsoftJsonPackageVersion() return _NewtonsoftJsonPackageVersion.Value; } + private static readonly Lazy _SystemDataSqlClientPackageVersion = new(() => + { + Assembly assembly = Assembly.GetExecutingAssembly(); + return assembly.GetCustomAttributes(true).OfType().FirstOrDefault(a => a.Key == "SystemDataSqlClientPackageVersion").Value; + }); + + public static string GetSystemDataSqlClientPackageVersion() + { + return _SystemDataSqlClientPackageVersion.Value; + } + } } From 84e5dd06d67a052eee3c6d683e5b7f8d44e02447 Mon Sep 17 00:00:00 2001 From: Jason Zhai Date: Thu, 18 Jan 2024 23:03:05 -0800 Subject: [PATCH 085/577] Fix --- .../Microsoft.NET.TestFramework.csproj | 4 ++++ .../Microsoft.NET.TestFramework/TestAsset.cs | 15 +++++++++++---- ...oPackAToolProjectWithComplexNugetDependency.cs | 2 +- 3 files changed, 16 insertions(+), 5 deletions(-) diff --git a/src/Tests/Microsoft.NET.TestFramework/Microsoft.NET.TestFramework.csproj b/src/Tests/Microsoft.NET.TestFramework/Microsoft.NET.TestFramework.csproj index aa0505d0761a..ab4fb9b1096b 100644 --- a/src/Tests/Microsoft.NET.TestFramework/Microsoft.NET.TestFramework.csproj +++ b/src/Tests/Microsoft.NET.TestFramework/Microsoft.NET.TestFramework.csproj @@ -25,6 +25,10 @@ <_Parameter1>NewtonsoftJsonPackageVersion <_Parameter2>$(NewtonsoftJsonPackageVersion) + + <_Parameter1>SystemDataSqlClientPackageVersion + <_Parameter2>$(SystemDataSqlClientPackageVersion) + diff --git a/src/Tests/Microsoft.NET.TestFramework/TestAsset.cs b/src/Tests/Microsoft.NET.TestFramework/TestAsset.cs index ff6a2a27bb5a..07c3bd1f557a 100644 --- a/src/Tests/Microsoft.NET.TestFramework/TestAsset.cs +++ b/src/Tests/Microsoft.NET.TestFramework/TestAsset.cs @@ -102,7 +102,15 @@ public TestAsset WithSource() this.UpdateProjProperty(property[0], property[1], property[2]); } - this.ReplaceTheNewtonsoftJsonPackageVersionVariable(); + string[][] PackageVersionVariables = { + new string[] { "NewtonsoftJsonPackageVersion", ToolsetInfo.GetNewtonsoftJsonPackageVersion() }, + new string[] { "SystemDataSqlClientPackageVersion", ToolsetInfo.GetSystemDataSqlClientPackageVersion() }}; + + + foreach (string[] PackageVersionVariable in PackageVersionVariables) + { + this.ReplacePackageVersionVariable(PackageVersionVariable[0], PackageVersionVariable[1]); + } return this; } @@ -119,10 +127,9 @@ public TestAsset UpdateProjProperty(string propertyName, string variableName, st }); } - public TestAsset ReplaceTheNewtonsoftJsonPackageVersionVariable() + public TestAsset ReplacePackageVersionVariable(string targetName, string targetValue) { string[] PropertyNames = new[] { "PackageReference", "Package" }; - string targetName = "NewtonsoftJsonPackageVersion"; return WithProjectChanges(project => { @@ -134,7 +141,7 @@ public TestAsset ReplaceTheNewtonsoftJsonPackageVersionVariable() .Where(p => p.Attribute("Version") != null && p.Attribute("Version").Value.Equals($"$({targetName})", StringComparison.OrdinalIgnoreCase)); foreach (var packageReference in packageReferencesToUpdate) { - packageReference.Attribute("Version").Value = ToolsetInfo.GetNewtonsoftJsonPackageVersion(); + packageReference.Attribute("Version").Value = targetValue; } } }); diff --git a/src/Tests/Microsoft.NET.ToolPack.Tests/GivenThatWeWantToPackAToolProjectWithComplexNugetDependency.cs b/src/Tests/Microsoft.NET.ToolPack.Tests/GivenThatWeWantToPackAToolProjectWithComplexNugetDependency.cs index d15b6d064dbc..9c39b17ecf1d 100644 --- a/src/Tests/Microsoft.NET.ToolPack.Tests/GivenThatWeWantToPackAToolProjectWithComplexNugetDependency.cs +++ b/src/Tests/Microsoft.NET.ToolPack.Tests/GivenThatWeWantToPackAToolProjectWithComplexNugetDependency.cs @@ -61,7 +61,7 @@ private static void ChangeToPackageThatDependsOnOtherPackage(XDocument project) XNamespace ns = project.Root.Name.Namespace; XElement itemGroup = project.Root.Elements(ns + "ItemGroup").First(); itemGroup.Add(new XElement(ns + "PackageReference", new XAttribute("Include", "System.Data.SqlClient"), - new XAttribute("Version", "4.3.0"))); + new XAttribute("Version", ToolsetInfo.GetSystemDataSqlClientPackageVersion()))); } } } From d87a2bb623f4194303bab0e970ca168677bb470e Mon Sep 17 00:00:00 2001 From: Jason Zhai Date: Fri, 19 Jan 2024 01:46:40 -0800 Subject: [PATCH 086/577] Fix the failures for It_has_native_and_transitive_dependencies_dll test --- ...nThatWeWantToPackAToolProjectWithComplexNugetDependency.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Tests/Microsoft.NET.ToolPack.Tests/GivenThatWeWantToPackAToolProjectWithComplexNugetDependency.cs b/src/Tests/Microsoft.NET.ToolPack.Tests/GivenThatWeWantToPackAToolProjectWithComplexNugetDependency.cs index 9c39b17ecf1d..2858280eedd4 100644 --- a/src/Tests/Microsoft.NET.ToolPack.Tests/GivenThatWeWantToPackAToolProjectWithComplexNugetDependency.cs +++ b/src/Tests/Microsoft.NET.ToolPack.Tests/GivenThatWeWantToPackAToolProjectWithComplexNugetDependency.cs @@ -38,8 +38,8 @@ public void It_has_native_and_transitive_dependencies_dll(bool multiTarget) IEnumerable supportedFrameworks = nupkgReader.GetSupportedFrameworks(); supportedFrameworks.Should().NotBeEmpty(); - var transitiveDependency = "runtimes/unix/lib/netstandard1.3/System.Data.SqlClient.dll"; - var nativeDependency = "runtimes/win7-x86/native/sni.dll"; + var transitiveDependency = "runtimes/unix/lib/netcoreapp2.1/System.Data.SqlClient.dll"; + var nativeDependency = "runtimes/win-x86/native/sni.dll"; foreach (var dependency in new string[] { transitiveDependency, nativeDependency }) { From 7b0485609c915c168a61acab397dccde94851c69 Mon Sep 17 00:00:00 2001 From: Jason Zhai Date: Fri, 19 Jan 2024 01:52:00 -0800 Subject: [PATCH 087/577] The target framework 'netcoreapp1.1' is out of support and will not receive security updates in the future --- ...nThatWeWantToPreserveCompilationContext.cs | 89 ------------------- 1 file changed, 89 deletions(-) diff --git a/src/Tests/Microsoft.NET.Publish.Tests/GivenThatWeWantToPreserveCompilationContext.cs b/src/Tests/Microsoft.NET.Publish.Tests/GivenThatWeWantToPreserveCompilationContext.cs index e9c364476f2d..85bb7c693a49 100644 --- a/src/Tests/Microsoft.NET.Publish.Tests/GivenThatWeWantToPreserveCompilationContext.cs +++ b/src/Tests/Microsoft.NET.Publish.Tests/GivenThatWeWantToPreserveCompilationContext.cs @@ -13,7 +13,6 @@ public GivenThatWeWantToPreserveCompilationContext(ITestOutputHelper log) : base [Theory] [InlineData("net46", "netstandard1.3", false)] - [InlineData("netcoreapp1.1", "netstandard1.3", false)] [InlineData("netcoreapp2.0", "netstandard2.0", false)] [InlineData("netcoreapp2.0", "netstandard2.0", true)] [InlineData("netcoreapp3.0", "netstandard2.0", false)] @@ -305,94 +304,6 @@ public void It_excludes_runtime_store_packages_from_the_refs_folder() System.Security.Cryptography.Primitives.dll System.Security.Cryptography.X509Certificates.dll System.Xml.ReaderWriter.dll -TestLibrary.dll" - }, - { - "netcoreapp1.1", -@"TestApp.dll -Microsoft.CSharp.dll -Microsoft.VisualBasic.dll -Microsoft.Win32.Primitives.dll -Newtonsoft.Json.dll -System.AppContext.dll -System.Buffers.dll -System.Collections.dll -System.Collections.Concurrent.dll -System.Collections.Immutable.dll -System.ComponentModel.dll -System.ComponentModel.Annotations.dll -System.Console.dll -System.Collections.NonGeneric.dll -System.ComponentModel.Primitives.dll -System.ComponentModel.TypeConverter.dll -System.Data.Common.dll -System.Data.SqlClient.dll -System.Diagnostics.Debug.dll -System.Diagnostics.DiagnosticSource.dll -System.Diagnostics.Process.dll -System.Diagnostics.Tools.dll -System.Diagnostics.Tracing.dll -System.Dynamic.Runtime.dll -System.Globalization.dll -System.Globalization.Calendars.dll -System.Globalization.Extensions.dll -System.IO.dll -System.IO.Compression.dll -System.IO.Compression.ZipFile.dll -System.IO.FileSystem.dll -System.IO.FileSystem.Primitives.dll -System.IO.FileSystem.Watcher.dll -System.IO.MemoryMappedFiles.dll -System.IO.UnmanagedMemoryStream.dll -System.Linq.dll -System.Linq.Expressions.dll -System.Linq.Parallel.dll -System.Linq.Queryable.dll -System.Net.Http.dll -System.Net.NameResolution.dll -System.Net.Primitives.dll -System.Net.Requests.dll -System.Net.Security.dll -System.Net.Sockets.dll -System.Net.WebHeaderCollection.dll -System.Numerics.Vectors.dll -System.ObjectModel.dll -System.Reflection.dll -System.Reflection.DispatchProxy.dll -System.Reflection.Extensions.dll -System.Reflection.Metadata.dll -System.Reflection.Primitives.dll -System.Reflection.TypeExtensions.dll -System.Resources.Reader.dll -System.Resources.ResourceManager.dll -System.Runtime.dll -System.Runtime.Extensions.dll -System.Runtime.Handles.dll -System.Runtime.InteropServices.dll -System.Runtime.InteropServices.RuntimeInformation.dll -System.Runtime.Numerics.dll -System.Runtime.Serialization.Primitives.dll -System.Runtime.Serialization.Formatters.dll -System.Security.Cryptography.Algorithms.dll -System.Security.Cryptography.Encoding.dll -System.Security.Cryptography.OpenSsl.dll -System.Security.Cryptography.Primitives.dll -System.Security.Cryptography.X509Certificates.dll -System.Security.Principal.dll -System.Text.Encoding.dll -System.Text.Encoding.Extensions.dll -System.Text.RegularExpressions.dll -System.Threading.dll -System.Threading.Tasks.dll -System.Threading.Tasks.Dataflow.dll -System.Threading.Tasks.Extensions.dll -System.Threading.Tasks.Parallel.dll -System.Threading.Thread.dll -System.Threading.ThreadPool.dll -System.Threading.Timer.dll -System.Xml.ReaderWriter.dll -System.Xml.XDocument.dll -System.Xml.XmlDocument.dll TestLibrary.dll" }, { From de16d1777166ffc7544a99241f5805d0ed2ccd85 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" Date: Fri, 19 Jan 2024 14:00:12 +0000 Subject: [PATCH 088/577] Update dependencies from https://github.com/nuget/nuget.client build 6.10.0.8 Microsoft.Build.NuGetSdkResolver , NuGet.Build.Tasks , NuGet.Build.Tasks.Console , NuGet.Build.Tasks.Pack , NuGet.CommandLine.XPlat , NuGet.Commands , NuGet.Common , NuGet.Configuration , NuGet.Credentials , NuGet.DependencyResolver.Core , NuGet.Frameworks , NuGet.LibraryModel , NuGet.Packaging , NuGet.ProjectModel , NuGet.Protocol , NuGet.Versioning From Version 6.9.0-rc.74 -> To Version 6.10.0-preview.1.8 --- eng/Version.Details.xml | 64 ++++++++++++++++++++--------------------- eng/Versions.props | 22 +++++++------- 2 files changed, 43 insertions(+), 43 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 6586ece1122b..f36ffbf73e63 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -115,69 +115,69 @@ https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore 3f1acb59718cadf111a0a796681e3d3509bb3381 - + https://github.com/nuget/nuget.client - 9dd33574b0cf5110692ee8e9401a39857fb5523a + 1870d8c7b326de0ae23a0ebb15a147ce718de2fc - + https://github.com/nuget/nuget.client - 9dd33574b0cf5110692ee8e9401a39857fb5523a + 1870d8c7b326de0ae23a0ebb15a147ce718de2fc - + https://github.com/nuget/nuget.client - 9dd33574b0cf5110692ee8e9401a39857fb5523a + 1870d8c7b326de0ae23a0ebb15a147ce718de2fc - + https://github.com/nuget/nuget.client - 9dd33574b0cf5110692ee8e9401a39857fb5523a + 1870d8c7b326de0ae23a0ebb15a147ce718de2fc - + https://github.com/nuget/nuget.client - 9dd33574b0cf5110692ee8e9401a39857fb5523a + 1870d8c7b326de0ae23a0ebb15a147ce718de2fc - + https://github.com/nuget/nuget.client - 9dd33574b0cf5110692ee8e9401a39857fb5523a + 1870d8c7b326de0ae23a0ebb15a147ce718de2fc - + https://github.com/nuget/nuget.client - 9dd33574b0cf5110692ee8e9401a39857fb5523a + 1870d8c7b326de0ae23a0ebb15a147ce718de2fc - + https://github.com/nuget/nuget.client - 9dd33574b0cf5110692ee8e9401a39857fb5523a + 1870d8c7b326de0ae23a0ebb15a147ce718de2fc - + https://github.com/nuget/nuget.client - 9dd33574b0cf5110692ee8e9401a39857fb5523a + 1870d8c7b326de0ae23a0ebb15a147ce718de2fc - + https://github.com/nuget/nuget.client - 9dd33574b0cf5110692ee8e9401a39857fb5523a + 1870d8c7b326de0ae23a0ebb15a147ce718de2fc - + https://github.com/nuget/nuget.client - 9dd33574b0cf5110692ee8e9401a39857fb5523a + 1870d8c7b326de0ae23a0ebb15a147ce718de2fc - + https://github.com/nuget/nuget.client - 9dd33574b0cf5110692ee8e9401a39857fb5523a + 1870d8c7b326de0ae23a0ebb15a147ce718de2fc - + https://github.com/nuget/nuget.client - 9dd33574b0cf5110692ee8e9401a39857fb5523a + 1870d8c7b326de0ae23a0ebb15a147ce718de2fc - + https://github.com/nuget/nuget.client - 9dd33574b0cf5110692ee8e9401a39857fb5523a + 1870d8c7b326de0ae23a0ebb15a147ce718de2fc - + https://github.com/nuget/nuget.client - 9dd33574b0cf5110692ee8e9401a39857fb5523a + 1870d8c7b326de0ae23a0ebb15a147ce718de2fc - + https://github.com/nuget/nuget.client - 9dd33574b0cf5110692ee8e9401a39857fb5523a + 1870d8c7b326de0ae23a0ebb15a147ce718de2fc https://github.com/microsoft/vstest diff --git a/eng/Versions.props b/eng/Versions.props index fba5e84222e1..ae6675ae8551 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -67,18 +67,18 @@ - 6.10.0-preview.1.7 - 6.10.0-preview.1.7 + 6.10.0-preview.1.8 + 6.10.0-preview.1.8 6.0.0-rc.278 - 6.10.0-preview.1.7 - 6.10.0-preview.1.7 - 6.10.0-preview.1.7 - 6.10.0-preview.1.7 - 6.10.0-preview.1.7 - 6.10.0-preview.1.7 - 6.10.0-preview.1.7 - 6.10.0-preview.1.7 - 6.10.0-preview.1.7 + 6.10.0-preview.1.8 + 6.10.0-preview.1.8 + 6.10.0-preview.1.8 + 6.10.0-preview.1.8 + 6.10.0-preview.1.8 + 6.10.0-preview.1.8 + 6.10.0-preview.1.8 + 6.10.0-preview.1.8 + 6.10.0-preview.1.8 $(NuGetPackagingPackageVersion) $(NuGetProjectModelPackageVersion) From ce2636af0b56a081297be5fca345bf201e285434 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" Date: Fri, 19 Jan 2024 14:01:20 +0000 Subject: [PATCH 089/577] Update dependencies from https://github.com/microsoft/vstest build 20240118.2 Microsoft.NET.Test.Sdk , Microsoft.TestPlatform.Build , Microsoft.TestPlatform.CLI From Version 17.9.0-release-23627-01 -> To Version 17.10.0-preview-24068-02 --- eng/Version.Details.xml | 12 ++++++------ eng/Versions.props | 6 +++--- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index b97264520502..31e34413a003 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -179,18 +179,18 @@ https://github.com/nuget/nuget.client e92be3915309e687044768de38933ac5fc4cb40c - + https://github.com/microsoft/vstest - 1c68c247cc3d69ad04afeb574c3d0bc352ff16e5 + 58a1f6b114170b612224731442a8245845dad722 - + https://github.com/microsoft/vstest - 1c68c247cc3d69ad04afeb574c3d0bc352ff16e5 + 58a1f6b114170b612224731442a8245845dad722 - + https://github.com/microsoft/vstest - 1c68c247cc3d69ad04afeb574c3d0bc352ff16e5 + 58a1f6b114170b612224731442a8245845dad722 https://dev.azure.com/dnceng/internal/_git/dotnet-runtime diff --git a/eng/Versions.props b/eng/Versions.props index b1cb69a976ca..ca7fdc1672af 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -84,9 +84,9 @@ - 17.10.0-preview-24067-01 - 17.10.0-preview-24067-01 - 17.10.0-preview-24067-01 + 17.10.0-preview-24068-02 + 17.10.0-preview-24068-02 + 17.10.0-preview-24068-02 From 4173b51e72a6bdf7dd0cca32a23915d6afb289db Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Fri, 19 Jan 2024 19:30:52 +0000 Subject: [PATCH 090/577] [release/8.0.3xx] Update dependencies from dotnet/msbuild (#38135) [release/8.0.3xx] Update dependencies from dotnet/msbuild --- eng/Version.Details.xml | 12 ++++++------ eng/Versions.props | 4 ++-- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 58fedf232be7..958dddbc34e1 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -51,17 +51,17 @@ https://github.com/dotnet/emsdk 2406616d0e3a31d80b326e27c156955bfa41c791 - + https://github.com/dotnet/msbuild - 6e97308dc4652452833d8ee1ca1d0c1cf5d17ad3 + 0932b436c6fa26bb356ce21815d5892ed41834d3 - + https://github.com/dotnet/msbuild - 6e97308dc4652452833d8ee1ca1d0c1cf5d17ad3 + 0932b436c6fa26bb356ce21815d5892ed41834d3 - + https://github.com/dotnet/msbuild - 6e97308dc4652452833d8ee1ca1d0c1cf5d17ad3 + 0932b436c6fa26bb356ce21815d5892ed41834d3 diff --git a/eng/Versions.props b/eng/Versions.props index e30dd571a418..ce2e506e153f 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -105,7 +105,7 @@ - 17.10.0-preview-24068-10 + 17.10.0-preview-24069-02 $(MicrosoftBuildPackageVersion) - 7.0.0-preview.24067.4 - 7.0.0-preview.24067.4 - 7.0.0-preview.24067.4 + 7.0.0-preview.24068.3 + 7.0.0-preview.24068.3 + 7.0.0-preview.24068.3 From cc852e53bf88bd18a9cfc052aad0c1e76fd4e221 Mon Sep 17 00:00:00 2001 From: Daniel Plaisted Date: Thu, 11 Jan 2024 11:32:43 -0500 Subject: [PATCH 092/577] Move GetWorkloadPackRecords into partial class file of NetSdkMsiInstallerClient --- .../install/MsiInstallerBase.cs | 85 -------------- ...NetSdkMsiInstallerClient.InstallRecords.cs | 106 ++++++++++++++++++ 2 files changed, 106 insertions(+), 85 deletions(-) create mode 100644 src/Cli/dotnet/commands/dotnet-workload/install/NetSdkMsiInstallerClient.InstallRecords.cs diff --git a/src/Cli/dotnet/commands/dotnet-workload/install/MsiInstallerBase.cs b/src/Cli/dotnet/commands/dotnet-workload/install/MsiInstallerBase.cs index 60d086bb4d1a..a2b493d6260f 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/install/MsiInstallerBase.cs +++ b/src/Cli/dotnet/commands/dotnet-workload/install/MsiInstallerBase.cs @@ -109,91 +109,6 @@ public MsiInstallerBase(InstallElevationContextBase elevationContext, ISetupLogg Reporter = reporter; } - /// - /// Detect installed workload pack records. Only the default registry hive is searched. Finding a workload pack - /// record does not necessarily guarantee that the MSI is installed. - /// - protected List GetWorkloadPackRecords() - { - Log?.LogMessage($"Detecting installed workload packs for {HostArchitecture}."); - List workloadPackRecords = new(); - using RegistryKey installedPacksKey = Registry.LocalMachine.OpenSubKey(@$"SOFTWARE\Microsoft\dotnet\InstalledPacks\{HostArchitecture}"); - - static void SetRecordMsiProperties(WorkloadPackRecord record, RegistryKey key) - { - record.ProviderKeyName = (string)key.GetValue("DependencyProviderKey"); - record.ProductCode = (string)key.GetValue("ProductCode"); - record.ProductVersion = new Version((string)key.GetValue("ProductVersion")); - record.UpgradeCode = (string)key.GetValue("UpgradeCode"); - } - - if (installedPacksKey != null) - { - foreach (string packId in installedPacksKey.GetSubKeyNames()) - { - using RegistryKey packKey = installedPacksKey.OpenSubKey(packId); - - foreach (string packVersion in packKey.GetSubKeyNames()) - { - using RegistryKey packVersionKey = packKey.OpenSubKey(packVersion); - - WorkloadPackRecord record = new WorkloadPackRecord - { - MsiId = packId, - MsiNuGetVersion = packVersion, - }; - - SetRecordMsiProperties(record, packVersionKey); - - record.InstalledPacks.Add((new WorkloadPackId(packId), new NuGetVersion(packVersion))); - - Log?.LogMessage($"Found workload pack record, Id: {packId}, version: {packVersion}, ProductCode: {record.ProductCode}, provider key: {record.ProviderKeyName}"); - - workloadPackRecords.Add(record); - } - } - } - - // Workload pack group installation records are in a similar format as the pack installation records. They use the "InstalledPackGroups" key, - // and under the key for each pack group/version are keys for the workload pack IDs and versions that are in the pack gorup. - using RegistryKey installedPackGroupsKey = Registry.LocalMachine.OpenSubKey(@$"SOFTWARE\Microsoft\dotnet\InstalledPackGroups\{HostArchitecture}"); - if (installedPackGroupsKey != null) - { - foreach (string packGroupId in installedPackGroupsKey.GetSubKeyNames()) - { - using RegistryKey packGroupKey = installedPackGroupsKey.OpenSubKey(packGroupId); - foreach (string packGroupVersion in packGroupKey.GetSubKeyNames()) - { - using RegistryKey packGroupVersionKey = packGroupKey.OpenSubKey(packGroupVersion); - - WorkloadPackRecord record = new WorkloadPackRecord - { - MsiId = packGroupId, - MsiNuGetVersion = packGroupVersion - }; - - SetRecordMsiProperties(record, packGroupVersionKey); - - Log?.LogMessage($"Found workload pack group record, Id: {packGroupId}, version: {packGroupVersion}, ProductCode: {record.ProductCode}, provider key: {record.ProviderKeyName}"); - - foreach (string packId in packGroupVersionKey.GetSubKeyNames()) - { - using RegistryKey packIdKey = packGroupVersionKey.OpenSubKey(packId); - foreach (string packVersion in packIdKey.GetSubKeyNames()) - { - record.InstalledPacks.Add((new WorkloadPackId(packId), new NuGetVersion(packVersion))); - Log?.LogMessage($"Found workload pack in group, Id: {packId}, version: {packVersion}"); - } - } - - workloadPackRecords.Add(record); - } - } - } - - return workloadPackRecords; - } - /// /// Determines the per-machine install location for .NET. This is similar to the logic in the standalone installers. /// diff --git a/src/Cli/dotnet/commands/dotnet-workload/install/NetSdkMsiInstallerClient.InstallRecords.cs b/src/Cli/dotnet/commands/dotnet-workload/install/NetSdkMsiInstallerClient.InstallRecords.cs new file mode 100644 index 000000000000..a0ec8d500227 --- /dev/null +++ b/src/Cli/dotnet/commands/dotnet-workload/install/NetSdkMsiInstallerClient.InstallRecords.cs @@ -0,0 +1,106 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.Net; +using System.Text.Json; +using Microsoft.Deployment.DotNet.Releases; +using Microsoft.DotNet.Cli; +using Microsoft.DotNet.Cli.Utils; +using Microsoft.DotNet.Installer.Windows; +using Microsoft.NET.Sdk.WorkloadManifestReader; +using Microsoft.Win32; +using Microsoft.Win32.Msi; +using NuGet.Packaging.Core; +using NuGet.Versioning; +using static Microsoft.NET.Sdk.WorkloadManifestReader.WorkloadResolver; + +namespace Microsoft.DotNet.Workloads.Workload.Install +{ + internal partial class NetSdkMsiInstallerClient + { + /// + /// Detect installed workload pack records. Only the default registry hive is searched. Finding a workload pack + /// record does not necessarily guarantee that the MSI is installed. + /// + protected List GetWorkloadPackRecords() + { + Log?.LogMessage($"Detecting installed workload packs for {HostArchitecture}."); + List workloadPackRecords = new(); + using RegistryKey installedPacksKey = Registry.LocalMachine.OpenSubKey(@$"SOFTWARE\Microsoft\dotnet\InstalledPacks\{HostArchitecture}"); + + static void SetRecordMsiProperties(WorkloadPackRecord record, RegistryKey key) + { + record.ProviderKeyName = (string)key.GetValue("DependencyProviderKey"); + record.ProductCode = (string)key.GetValue("ProductCode"); + record.ProductVersion = new Version((string)key.GetValue("ProductVersion")); + record.UpgradeCode = (string)key.GetValue("UpgradeCode"); + } + + if (installedPacksKey != null) + { + foreach (string packId in installedPacksKey.GetSubKeyNames()) + { + using RegistryKey packKey = installedPacksKey.OpenSubKey(packId); + + foreach (string packVersion in packKey.GetSubKeyNames()) + { + using RegistryKey packVersionKey = packKey.OpenSubKey(packVersion); + + WorkloadPackRecord record = new WorkloadPackRecord + { + MsiId = packId, + MsiNuGetVersion = packVersion, + }; + + SetRecordMsiProperties(record, packVersionKey); + + record.InstalledPacks.Add((new WorkloadPackId(packId), new NuGetVersion(packVersion))); + + Log?.LogMessage($"Found workload pack record, Id: {packId}, version: {packVersion}, ProductCode: {record.ProductCode}, provider key: {record.ProviderKeyName}"); + + workloadPackRecords.Add(record); + } + } + } + + // Workload pack group installation records are in a similar format as the pack installation records. They use the "InstalledPackGroups" key, + // and under the key for each pack group/version are keys for the workload pack IDs and versions that are in the pack gorup. + using RegistryKey installedPackGroupsKey = Registry.LocalMachine.OpenSubKey(@$"SOFTWARE\Microsoft\dotnet\InstalledPackGroups\{HostArchitecture}"); + if (installedPackGroupsKey != null) + { + foreach (string packGroupId in installedPackGroupsKey.GetSubKeyNames()) + { + using RegistryKey packGroupKey = installedPackGroupsKey.OpenSubKey(packGroupId); + foreach (string packGroupVersion in packGroupKey.GetSubKeyNames()) + { + using RegistryKey packGroupVersionKey = packGroupKey.OpenSubKey(packGroupVersion); + + WorkloadPackRecord record = new WorkloadPackRecord + { + MsiId = packGroupId, + MsiNuGetVersion = packGroupVersion + }; + + SetRecordMsiProperties(record, packGroupVersionKey); + + Log?.LogMessage($"Found workload pack group record, Id: {packGroupId}, version: {packGroupVersion}, ProductCode: {record.ProductCode}, provider key: {record.ProviderKeyName}"); + + foreach (string packId in packGroupVersionKey.GetSubKeyNames()) + { + using RegistryKey packIdKey = packGroupVersionKey.OpenSubKey(packId); + foreach (string packVersion in packIdKey.GetSubKeyNames()) + { + record.InstalledPacks.Add((new WorkloadPackId(packId), new NuGetVersion(packVersion))); + Log?.LogMessage($"Found workload pack in group, Id: {packId}, version: {packVersion}"); + } + } + + workloadPackRecords.Add(record); + } + } + } + + return workloadPackRecords; + } + } +} From 81cd978ebbef5c9712e6fd4fef6f8152fc718d32 Mon Sep 17 00:00:00 2001 From: Daniel Plaisted Date: Fri, 12 Jan 2024 14:38:51 -0500 Subject: [PATCH 093/577] Remove logic for supporting MSI upgrades Workload MSIs are now all side-by-side --- .../dotnet/Installer/Windows/DetectState.cs | 8 - .../dotnet/Installer/Windows/InstallAction.cs | 4 - .../install/NetSdkMsiInstallerClient.cs | 154 +----------------- 3 files changed, 8 insertions(+), 158 deletions(-) diff --git a/src/Cli/dotnet/Installer/Windows/DetectState.cs b/src/Cli/dotnet/Installer/Windows/DetectState.cs index cc2b2eed349e..4e01a9243559 100644 --- a/src/Cli/dotnet/Installer/Windows/DetectState.cs +++ b/src/Cli/dotnet/Installer/Windows/DetectState.cs @@ -21,13 +21,5 @@ internal enum DetectState /// The package is not installed. /// Absent = 2, - /// - /// A newer version of the package is already installed. - /// - Superseded = 3, - /// - /// The installed package is older than the new package. - /// - Obsolete = 4, } } diff --git a/src/Cli/dotnet/Installer/Windows/InstallAction.cs b/src/Cli/dotnet/Installer/Windows/InstallAction.cs index 04f5cf42338f..3c6a4aed7a9f 100644 --- a/src/Cli/dotnet/Installer/Windows/InstallAction.cs +++ b/src/Cli/dotnet/Installer/Windows/InstallAction.cs @@ -12,9 +12,5 @@ public enum InstallAction Install, Uninstall, Repair, - Rollback, - MinorUpdate, - MajorUpgrade, - Downgrade, } } diff --git a/src/Cli/dotnet/commands/dotnet-workload/install/NetSdkMsiInstallerClient.cs b/src/Cli/dotnet/commands/dotnet-workload/install/NetSdkMsiInstallerClient.cs index 6ff3b44635d5..f0fe66d764ad 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/install/NetSdkMsiInstallerClient.cs +++ b/src/Cli/dotnet/commands/dotnet-workload/install/NetSdkMsiInstallerClient.cs @@ -363,57 +363,7 @@ void InstallWorkloadManifestImplementation(ManifestVersionUpdate manifestUpdate, MsiPayload msi = GetCachedMsiPayload(msiPackageId, msiPackageVersion, offlineCache); VerifyPackage(msi); DetectState state = DetectPackage(msi.ProductCode, out Version installedVersion); - InstallAction plannedAction = PlanPackage(msi, state, InstallAction.Install, installedVersion, out IEnumerable relatedProducts); - - // If we've detected a downgrade, it's possible we might be doing a rollback after the manifests were updated, - // but another error occurred. In this case we need to try and uninstall the upgrade and then install the lower - // version of the MSI. The downgrade can also be a deliberate rollback. - if (plannedAction == InstallAction.Downgrade && isRollback && state == DetectState.Absent) - { - Log?.LogMessage($"Rolling back manifest update."); - - // The provider keys for manifest packages are stable across feature bands so we retain dependents during upgrades. - DependencyProvider depProvider = new DependencyProvider(msi.Manifest.ProviderKeyName); - - // Try and remove the SDK dependency, but ignore any remaining dependencies since - // we want to force the removal of the old version. The remaining dependencies and the provider - // key won't be removed. - UpdateDependent(InstallRequestType.RemoveDependent, msi.Manifest.ProviderKeyName, _dependent); - - // Since we don't have records for manifests, we need to try and retrieve the ProductCode of - // the newer MSI that's installed that we want to remove using its dependency provider. - string productCode = depProvider.ProductCode; - - if (string.IsNullOrWhiteSpace(productCode)) - { - // We don't know the MSI package that wrote this provider key, so if the ProductCode is missing - // we can't do anything else. - Log?.LogMessage($"Failed to retrieve the ProductCode for provider: {depProvider.ProviderKeyName}."); - return; - } - - Log?.LogMessage($"Found ProductCode {productCode} registered against provider, {depProvider.ProviderKeyName}."); - - // This is a best effort. If for some reason the manifest installers were fixed, for example, manually - // adding additional upgrade paths to work around previous faulty authoring, we may have multiple related - // products. The best we can do is to check for at least one match and remove it and then try the rollback. - if (!relatedProducts.Contains(productCode, StringComparer.OrdinalIgnoreCase)) - { - Log?.LogMessage($"Cannot rollback manifest. ProductCode does not match any detected related products."); - return; - } - - string logFile = GetMsiLogName(productCode, InstallAction.Uninstall); - uint error = UninstallMsi(productCode, logFile, ignoreDependencies: true); - - ExitOnError(error, "Failed to uninstall manifest package."); - - // Detect the package again and fall through to the original execution. If that fails, then there's nothing - // we could have done. - Log?.LogMessage("Replanning manifest package."); - state = DetectPackage(msi, out Version _); - plannedAction = PlanPackage(msi, state, InstallAction.Install, installedVersion, out IEnumerable _); - } + InstallAction plannedAction = PlanPackage(msi, state, InstallAction.Install, installedVersion); ExecutePackage(msi, plannedAction, msiPackageId); @@ -433,7 +383,7 @@ public void RepairWorkloads(IEnumerable workloadIds, SdkFeatureBand MsiPayload msi = GetCachedMsiPayload(aquirableMsi.NuGetPackageId, aquirableMsi.NuGetPackageVersion, offlineCache); VerifyPackage(msi); DetectState state = DetectPackage(msi, out Version installedVersion); - InstallAction plannedAction = PlanPackage(msi, state, InstallAction.Repair, installedVersion, out _); + InstallAction plannedAction = PlanPackage(msi, state, InstallAction.Repair, installedVersion); ExecutePackage(msi, plannedAction, aquirableMsi.NuGetPackageId); // Update the reference count against the MSI. @@ -465,7 +415,7 @@ public void InstallWorkloads(IEnumerable workloadIds, SdkFeatureBand MsiPayload msi = GetCachedMsiPayload(msiToInstall.NuGetPackageId, msiToInstall.NuGetPackageVersion, offlineCache); VerifyPackage(msi); DetectState state = DetectPackage(msi, out Version installedVersion); - InstallAction plannedAction = PlanPackage(msi, state, InstallAction.Install, installedVersion, out _); + InstallAction plannedAction = PlanPackage(msi, state, InstallAction.Install, installedVersion); if (plannedAction == InstallAction.Install) { shouldRollBackPack = true; @@ -517,7 +467,7 @@ void RollBackMsiInstall(WorkloadDownload msiToRollback, DirectoryPath? offlineCa // Make sure the MSI is actually installed. DetectState state = DetectPackage(msi, out Version installedVersion); - InstallAction plannedAction = PlanPackage(msi, state, InstallAction.Uninstall, installedVersion, out _); + InstallAction plannedAction = PlanPackage(msi, state, InstallAction.Uninstall, installedVersion); // The previous steps would have logged the final action. If the verdict is not to uninstall we can exit. if (plannedAction == InstallAction.Uninstall) @@ -687,31 +637,22 @@ private DetectState DetectPackage(MsiPayload msi, out Version installedVersion) /// The detected state of the package. /// The requested action to perform. /// The action that will be performed. - private InstallAction PlanPackage(MsiPayload msi, DetectState state, InstallAction requestedAction, Version installedVersion, out IEnumerable relatedProductCodes) + private InstallAction PlanPackage(MsiPayload msi, DetectState state, InstallAction requestedAction, Version installedVersion) { InstallAction plannedAction = InstallAction.None; - HashSet relatedProducts = new(); Log?.LogMessage($"PlanPackage: Begin, name: {msi.Name}, version: {msi.ProductVersion}, state: {state}, installed version: {installedVersion?.ToString() ?? "n/a"}, requested: {requestedAction}."); - // Manifest packages should support major upgrades (both the ProductCode and ProductVersion should be different) while - // workload packs should always be SxS (ProductCode and Upgrade should be different for each version). - // - // We cannot discount someone generating a minor update (ProductCode remains unchanged, but ProductVersion changes), - // so we'll detect downgrades and minor updates. For more details, see https://docs.microsoft.com/en-us/windows/win32/msi/minor-upgrades. + // Manifest packages, workload packs, and workload sets should now always be SxS (ProductCode and Upgrade should be different for each version). if (state == DetectState.Present) { if (msi.ProductVersion < installedVersion) { - Log?.LogMessage($"PlanPackage: Downgrade detected, installed version: {installedVersion}, requested version: {msi.ProductVersion}."); - plannedAction = InstallAction.Downgrade; - state = DetectState.Superseded; + throw new WorkloadException($"PlanPackage: Downgrade detected, installed version: {installedVersion}, requested version: {msi.ProductVersion}."); } else if (msi.ProductVersion > installedVersion) { - Log?.LogMessage($"PlanPackage: Minor update detected, installed version: {installedVersion}, requested version: {msi.ProductVersion}."); - plannedAction = InstallAction.MinorUpdate; - state = DetectState.Obsolete; + throw new WorkloadException($"PlanPackage: Minor update detected, installed version: {installedVersion}, requested version: {msi.ProductVersion}."); } else { @@ -727,84 +668,8 @@ private InstallAction PlanPackage(MsiPayload msi, DetectState state, InstallActi : InstallAction.None; } - // If we know the MSI is absent, there are only three outcomes when executing the package: - // 1. We'll just do a clean install if we don't find related products so we're either brand new or SxS. - // 2. We'll perform a major upgrade. - // 3. We'll trigger a downgrade and likely an error since most MSIs detect and block downgrades. - // - // We'll process the related product information to make a determination. This is similar to what the FindRelatedProducts - // action does when an MSI is executed. - foreach (RelatedProduct relatedProduct in msi.RelatedProducts) - { - foreach (string relatedProductCode in WindowsInstaller.FindRelatedProducts(relatedProduct.UpgradeCode)) - { - // Ignore potentially detecting ourselves. - if (string.Equals(relatedProductCode, msi.ProductCode, StringComparison.OrdinalIgnoreCase)) - { - continue; - } - - // Check whether the related product is installed and retrieve its version to determine - // how we're related. - uint error = WindowsInstaller.GetProductInfo(relatedProductCode, InstallProperty.VERSIONSTRING, out string relatedVersionValue); - - // Continue searching if the related product is not installed. - if (error == Error.UNKNOWN_PRODUCT || error == Error.UNKNOWN_PROPERTY) - { - continue; - } - - ExitOnError(error, $"PlanPackage: Failed to retrieve version for related product: ProductCode: {relatedProductCode}."); - - // Parse the version, but don't try to catch any errors. If the version is invalid we want to fail - // because we can't compare invalid versions to see whether it's excluded by the VersionMin and VersionMax - // columns from the Upgrade table. - Version relatedVersion = Version.Parse(relatedVersionValue); - - if (relatedProduct.ExcludesMinVersion(relatedVersion) || relatedProduct.ExcludesMaxVersion(relatedVersion)) - { - continue; - } - - // Check if the related product contains a matching language code (LCID). If we don't have any languages, - // all languages are detectable as related and we can ignore the msidbUpgradeAttributesLanguagesExclusive flag. - if (relatedProduct.Languages.Any()) - { - string relatedLanguage = "0"; - error = WindowsInstaller.GetProductInfo(relatedProductCode, InstallProperty.LANGUAGE, out relatedLanguage); - - if (int.TryParse(relatedLanguage, out int lcid)) - { - if (relatedProduct.ExcludesLanguage(lcid)) - { - continue; - } - } - else - { - Log?.LogMessage($"PlanPackage: Failed to read Language property for related product, ProductCode: {relatedProductCode}. The related product will be skipped."); - continue; - } - } - - relatedProducts.Add(relatedProductCode); - plannedAction = InstallAction.MajorUpgrade; - - if (relatedProduct.Attributes.HasFlag(UpgradeAttributes.OnlyDetect) && (state == DetectState.Absent)) - { - // If we're not installed, but detect-only related, it's very likely that - // that we'd trigger a downgrade launch condition. We can't know for sure, but - // generally that's the most common use for detect-only entries. - plannedAction = InstallAction.Downgrade; - } - - Log?.LogMessage($"PlanPackage: Detected related product, ProductCode: {relatedProductCode}, version: {relatedVersion}, attributes: {relatedProduct.Attributes}, planned action: {plannedAction}."); - } - } - Log?.LogMessage($"PlanPackage: Completed, name: {msi.Name}, version: {msi.ProductVersion}, state: {state}, installed version: {installedVersion?.ToString() ?? "n/a"}, requested: {requestedAction}, planned: {plannedAction}."); - relatedProductCodes = relatedProducts.Select(p => p); return plannedAction; } @@ -927,9 +792,7 @@ private void ExecutePackage(MsiPayload msi, InstallAction action, string display switch (action) { - case InstallAction.MinorUpdate: case InstallAction.Install: - case InstallAction.MajorUpgrade: error = ExecuteWithProgress(String.Format(LocalizableStrings.MsiProgressInstall, name), () => InstallMsi(msi.MsiPath, logFile)); ExitOnError(error, $"Failed to install {msi.Payload}."); break; @@ -945,7 +808,6 @@ private void ExecutePackage(MsiPayload msi, InstallAction action, string display break; case InstallAction.None: - case InstallAction.Downgrade: default: break; } From 4ea4b69c7fa7d629a657b115b3f1409aaba774cb Mon Sep 17 00:00:00 2001 From: Daniel Plaisted Date: Fri, 12 Jan 2024 14:39:26 -0500 Subject: [PATCH 094/577] Add logic to get installed manifests (for MSI-based installs) --- .../DependencyProvider.cs | 18 ++ .../Windows/WorkloadManifestRecord.cs | 69 ++++++ ...NetSdkMsiInstallerClient.InstallRecords.cs | 218 ++++++++++++++++++ 3 files changed, 305 insertions(+) create mode 100644 src/Cli/dotnet/Installer/Windows/WorkloadManifestRecord.cs diff --git a/src/Cli/Microsoft.DotNet.Cli.Utils/DependencyProvider.cs b/src/Cli/Microsoft.DotNet.Cli.Utils/DependencyProvider.cs index a9264c18c6ba..0a3afe8596bd 100644 --- a/src/Cli/Microsoft.DotNet.Cli.Utils/DependencyProvider.cs +++ b/src/Cli/Microsoft.DotNet.Cli.Utils/DependencyProvider.cs @@ -174,5 +174,23 @@ private string GetProductCode() using RegistryKey providerKey = BaseKey.OpenSubKey(ProviderKeyPath); return providerKey?.GetValue(null) as string ?? null; } + + public static DependencyProvider GetFromProductCode(string productCode, bool allUsers = true) + { + var baseKey = allUsers ? Registry.LocalMachine : Registry.CurrentUser; + using RegistryKey dependenciesKey = baseKey.OpenSubKey(DependenciesKeyRelativePath); + + foreach (var providerKeyName in dependenciesKey.GetSubKeyNames()) + { + using RegistryKey providerKey = dependenciesKey.OpenSubKey(providerKeyName); + var thisProductCode = providerKey?.GetValue(null) as string ?? null; + if (thisProductCode == productCode) + { + return new DependencyProvider(providerKeyName, allUsers); + } + } + + return null; + } } } diff --git a/src/Cli/dotnet/Installer/Windows/WorkloadManifestRecord.cs b/src/Cli/dotnet/Installer/Windows/WorkloadManifestRecord.cs new file mode 100644 index 000000000000..1b7dadad9b24 --- /dev/null +++ b/src/Cli/dotnet/Installer/Windows/WorkloadManifestRecord.cs @@ -0,0 +1,69 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using Microsoft.NET.Sdk.WorkloadManifestReader; + +using NuGet.Versioning; + +namespace Microsoft.DotNet.Installer.Windows +{ + /// + /// Represents a workload manifest that has been installed + /// + internal class WorkloadManifestRecord + { + /// + /// The dependency provider key of the workload pack MSI used for reference counting shared installations. + /// + public string ProviderKeyName + { + get; + set; + } + + /// + /// The Manifest ID, such as Microsoft.NET.Workload.Mono.ToolChain.Current. This ID does NOT include the ".Manifest-{FeatureBand}" or ".Msi.{HostArchitecture}" suffix + /// + public string ManifestId + { + get; + set; + } + + /// + /// The version of the manifest installed by this MSI + /// + public string ManifestVersion + { + get; + set; + } + + /// + /// The product code (GUID) of the workload manifest MSI. + /// + public string ProductCode + { + get; + set; + } + + /// + /// The version of the workload manifest MSI. + /// + public Version ProductVersion + { + get; + set; + } + + /// + /// The upgrade code (GUID) of the workload pack MSI. + /// + public string UpgradeCode + { + get; + set; + } + } +} diff --git a/src/Cli/dotnet/commands/dotnet-workload/install/NetSdkMsiInstallerClient.InstallRecords.cs b/src/Cli/dotnet/commands/dotnet-workload/install/NetSdkMsiInstallerClient.InstallRecords.cs index a0ec8d500227..b8fad9f5a6be 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/install/NetSdkMsiInstallerClient.InstallRecords.cs +++ b/src/Cli/dotnet/commands/dotnet-workload/install/NetSdkMsiInstallerClient.InstallRecords.cs @@ -18,6 +18,224 @@ namespace Microsoft.DotNet.Workloads.Workload.Install { internal partial class NetSdkMsiInstallerClient { + internal static readonly Guid UpgradeCodeNamespaceUuid = Guid.Parse("C743F81B-B3B5-4E77-9F6D-474EFF3A722C"); + + protected List GetWorkloadManifestRecords() + { + Log?.LogMessage($"Detecting installed workload manifests for {HostArchitecture}."); + + var manifestRecords = new List(); + HashSet<(string id, string version)> discoveredManifests = new(); + + using RegistryKey installedManifestsKey = Registry.LocalMachine.OpenSubKey(@$"SOFTWARE\Microsoft\dotnet\InstalledManifests\{HostArchitecture}"); + if (installedManifestsKey != null) + { + foreach (string manifestId in installedManifestsKey.GetSubKeyNames()) + { + using RegistryKey manifestKey = installedManifestsKey.OpenSubKey(manifestId); + foreach (string manifestVersion in manifestKey.GetSubKeyNames()) + { + using RegistryKey manifestVersionKey = manifestKey.OpenSubKey(manifestVersion); + WorkloadManifestRecord record = new WorkloadManifestRecord + { + ManifestId = manifestId, + ManifestVersion = manifestVersion, + ProductCode = (string)manifestVersionKey.GetValue("ProductCode"), + UpgradeCode = (string)manifestVersionKey.GetValue("UpgradeCode"), + ProductVersion = new Version((string)manifestVersionKey.GetValue("ProductVersion")), + ProviderKeyName = (string)manifestVersionKey.GetValue("DependencyProviderKey") + }; + + Log.LogMessage($"Found workload manifest record, Id: {manifestId}, version: {manifestVersion}, ProductCode: {record.ProductCode}, provider key: {record.ProviderKeyName}"); + manifestRecords.Add(record); + discoveredManifests.Add((manifestId, manifestVersion)); + } + } + } + + // Workload manifest MSIs for 8.0.100 don't yet write the same type of installation records to the registry that workload packs do. + // So to find what is installed, we look for the manifests on disk, and then map that to installed MSIs + // To do the mapping to installed MSIs, we rely on the fact that the MSI UpgradeCode is generated in a stable fashion from the + // NuGet package identity and platform: Utils.CreateUuid(UpgradeCodeNamespaceUuid, $"{Package.Identity};{Platform}") + // The NuGet package identity used is the vanilla (non-MSI) manifest package, for example Microsoft.NET.Workload.Mono.ToolChain.Current.Manifest-8.0.100 version 8.0.0 + + // Manifest IDs are lowercased on disk, we need to map them back to the original casing to generate the right UpgradeCode + Dictionary manifestIDCasing = new Dictionary(); + foreach (var casedManifestID in new[] + { + "Microsoft.NET.Sdk.Android", + "Microsoft.NET.Sdk.Aspire", + "Microsoft.NET.Sdk.iOS", + "Microsoft.NET.Sdk.MacCatalyst", + "Microsoft.NET.Sdk.macOS", + "Microsoft.NET.Sdk.Maui", + "Microsoft.NET.Sdk.tvOS", + "Microsoft.NET.Workload.Emscripten.Current", + "Microsoft.NET.Workload.Emscripten.net6", + "Microsoft.NET.Workload.Emscripten.net7", + "Microsoft.NET.Workload.Mono.ToolChain.Current", + "Microsoft.NET.Workload.Mono.ToolChain.net6", + "Microsoft.NET.Workload.Mono.ToolChain.net7", + }) + { + manifestIDCasing[casedManifestID.ToLowerInvariant()] = casedManifestID; + } + + string sdkManifestFolder = Path.Combine(DotNetHome, "sdk-manifests"); + + foreach (var manifestFeatureBandFolder in Directory.GetDirectories(sdkManifestFolder)) + { + if (!ReleaseVersion.TryParse(Path.GetFileName(manifestFeatureBandFolder), out ReleaseVersion releaseVersion)) + { + // Ignore folders which aren't valid version numbers + Log.LogMessage($"Skipping invalid feature band version folder: {manifestFeatureBandFolder}"); + continue; + } + if (releaseVersion.Major < 8) + { + // Ignore manifests prior to 8.0.100, they were not side-by-side + continue; + } + var manifestFeatureBand = new SdkFeatureBand(releaseVersion); + + foreach (var manifestIDFolder in Directory.GetDirectories(manifestFeatureBandFolder)) + { + var lowerCasedManifestID = Path.GetFileName(manifestIDFolder); + if (manifestIDCasing.TryGetValue(lowerCasedManifestID, out string manifestID)) + { + foreach (var manifestVersionFolder in Directory.GetDirectories(manifestIDFolder)) + { + string manifestVersionString = Path.GetFileName(manifestVersionFolder); + + if (discoveredManifests.Contains((manifestID, manifestVersionString))) + { + continue; + } + + Log.LogMessage($"Discovered manifest installation in {manifestVersionFolder} which didn't have corresponding installation record in Registry"); + + if (NuGetVersion.TryParse(manifestVersionString, out NuGetVersion manifestVersion)) + { + var packageIdentity = new PackageIdentity(manifestID + ".Manifest-" + manifestFeatureBand, manifestVersion); + string uuidName = $"{packageIdentity};{HostArchitecture}"; + var upgradeCode = '{' + CreateUuid(UpgradeCodeNamespaceUuid, uuidName).ToString() + '}'; + Log.LogMessage($"Looking for upgrade code {upgradeCode} for {uuidName}"); + List relatedProductCodes; + try + { + relatedProductCodes = WindowsInstaller.FindRelatedProducts(upgradeCode.ToString()).ToList(); + } + catch (WindowsInstallerException) + { + Console.WriteLine("Error getting related products for " + upgradeCode); + throw; + } + DependencyProvider dependencyProvider; + if (relatedProductCodes.Count == 1 && + DetectPackage(relatedProductCodes[0], out Version installedVersion) == DetectState.Present && + (dependencyProvider = DependencyProvider.GetFromProductCode(relatedProductCodes[0])) != null) + { + var manifestRecord = new WorkloadManifestRecord(); + manifestRecord.ProductCode = relatedProductCodes[0]; + manifestRecord.UpgradeCode = upgradeCode; + manifestRecord.ManifestVersion = manifestVersion.ToString(); + manifestRecord.ManifestId = manifestID; + manifestRecord.ProductVersion = installedVersion; + manifestRecord.ProviderKeyName = dependencyProvider.ProviderKeyName; + + manifestRecords.Add(manifestRecord); + + Log.LogMessage($"Found installed manifest: {manifestRecord.ProviderKeyName}, {manifestRecord.ProductCode}"); + } + else if (relatedProductCodes.Count > 1) + { + Log.LogMessage($"Found multiple product codes for {uuidName}, which is not expected for side-by-side manifests."); + } + else + { + Log.LogMessage($"Found manifest on disk for {uuidName}, but did not find installation information in registry."); + } + + } + else + { + Log.LogMessage($"Skipping invalid manifest version for {manifestVersionFolder}"); + } + } + } + else + { + Log.LogMessage($"Skipping unknown manifest ID {lowerCasedManifestID}."); + } + } + } + + return manifestRecords; + } + + /// + /// Generates a version 3 UUID given a namespace UUID and name. This is based on the algorithm described in + /// RFC 4122 (https://tools.ietf.org/html/rfc4122), section 4.3. + /// + /// The UUID representing the namespace. + /// The name for which to generate a UUID within the given namespace. + /// A UUID generated using the given namespace UUID and name. + public static Guid CreateUuid(Guid namespaceUuid, string name) + { + // 1. Convert the name to a canonical sequence of octets (as defined by the standards or conventions of its name space); put the name space ID in network byte order. + byte[] namespaceBytes = namespaceUuid.ToByteArray(); + // Octet 0-3 + int timeLow = IPAddress.HostToNetworkOrder(BitConverter.ToInt32(namespaceBytes, 0)); + // Octet 4-5 + short timeMid = IPAddress.HostToNetworkOrder(BitConverter.ToInt16(namespaceBytes, 4)); + // Octet 6-7 + short timeHiVersion = IPAddress.HostToNetworkOrder(BitConverter.ToInt16(namespaceBytes, 6)); + + // 2. Compute the hash of the namespace ID concatenated with the name + byte[] nameBytes = Encoding.Unicode.GetBytes(name); + byte[] hashBuffer = new byte[namespaceBytes.Length + nameBytes.Length]; + + Buffer.BlockCopy(BitConverter.GetBytes(timeLow), 0, hashBuffer, 0, 4); + Buffer.BlockCopy(BitConverter.GetBytes(timeMid), 0, hashBuffer, 4, 2); + Buffer.BlockCopy(BitConverter.GetBytes(timeHiVersion), 0, hashBuffer, 6, 2); + Buffer.BlockCopy(namespaceBytes, 8, hashBuffer, 8, 8); + Buffer.BlockCopy(nameBytes, 0, hashBuffer, 16, nameBytes.Length); + byte[] hash; + + using (System.Security.Cryptography.SHA256 sha256 = System.Security.Cryptography.SHA256.Create()) + { + hash = sha256.ComputeHash(hashBuffer); + } + + Array.Resize(ref hash, 16); + + // 3. Set octets zero through 3 of the time_low field to octets zero through 3 of the hash. + timeLow = IPAddress.NetworkToHostOrder(BitConverter.ToInt32(hash, 0)); + Buffer.BlockCopy(BitConverter.GetBytes(timeLow), 0, hash, 0, 4); + + // 4. Set octets zero and one of the time_mid field to octets 4 and 5 of the hash. + timeMid = IPAddress.NetworkToHostOrder(BitConverter.ToInt16(hash, 4)); + Buffer.BlockCopy(BitConverter.GetBytes(timeMid), 0, hash, 4, 2); + + // 5. Set octets zero and one of the time_hi_and_version field to octets 6 and 7 of the hash. + timeHiVersion = IPAddress.NetworkToHostOrder(BitConverter.ToInt16(hash, 6)); + + // 6. Set the four most significant bits (bits 12 through 15) of the time_hi_and_version field to the appropriate 4-bit version number from Section 4.1.3. + timeHiVersion = (short)((timeHiVersion & 0x0fff) | 0x3000); + Buffer.BlockCopy(BitConverter.GetBytes(timeHiVersion), 0, hash, 6, 2); + + // 7. Set the clock_seq_hi_and_reserved field to octet 8 of the hash. + // 8. Set the two most significant bits (bits 6 and 7) of the clock_seq_hi_and_reserved to zero and one, respectively. + hash[8] = (byte)((hash[8] & 0x3f) | 0x80); + + // Steps 9-11 are essentially no-ops, but provided for completion sake + // 9. Set the clock_seq_low field to octet 9 of the hash. + // 10. Set octets zero through five of the node field to octets 10 through 15 of the hash. + // 11. Convert the resulting UUID to local byte order. + + return new Guid(hash); + } + /// /// Detect installed workload pack records. Only the default registry hive is searched. Finding a workload pack /// record does not necessarily guarantee that the MSI is installed. From 4011508d2c7a8d516443f642264ad10db0a5a6ce Mon Sep 17 00:00:00 2001 From: Daniel Plaisted Date: Fri, 19 Jan 2024 13:28:33 -0500 Subject: [PATCH 095/577] Use resolved alias for workload packs --- .../dotnet-workload/install/FileBasedInstaller.cs | 8 ++++---- .../dotnet-workload/install/WorkloadGarbageCollector.cs | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/Cli/dotnet/commands/dotnet-workload/install/FileBasedInstaller.cs b/src/Cli/dotnet/commands/dotnet-workload/install/FileBasedInstaller.cs index 08cd93199320..f9f03a27940f 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/install/FileBasedInstaller.cs +++ b/src/Cli/dotnet/commands/dotnet-workload/install/FileBasedInstaller.cs @@ -296,7 +296,7 @@ public IEnumerable GetDownloads(IEnumerable worklo public void GarbageCollect(Func getResolverForWorkloadSet, DirectoryPath? offlineCache = null, bool cleanAllPacks = false) { - var garbageCollector = new WorkloadGarbageCollector(_dotnetDir, _sdkFeatureBand, _installationRecordRepository.GetInstalledWorkloads(_sdkFeatureBand), getResolverForWorkloadSet); + var garbageCollector = new WorkloadGarbageCollector(_dotnetDir, _sdkFeatureBand, _installationRecordRepository.GetInstalledWorkloads(_sdkFeatureBand), getResolverForWorkloadSet, Reporter.Verbose); garbageCollector.Collect(); var featureBandsWithWorkloadInstallRecords = _installationRecordRepository.GetFeatureBandsWithInstallationRecords(); @@ -665,8 +665,8 @@ private string GetPackInstallRecordPath(WorkloadPackId packId, string packVersio private void WritePackInstallationRecord(PackInfo packInfo, SdkFeatureBand featureBand) { - _reporter.WriteLine(string.Format(LocalizableStrings.WritingPackInstallRecordMessage, packInfo.Id, packInfo.Version)); - var path = GetPackInstallRecordPath(packInfo.Id, packInfo.Version, featureBand); + _reporter.WriteLine(string.Format(LocalizableStrings.WritingPackInstallRecordMessage, packInfo.ResolvedPackageId, packInfo.Version)); + var path = GetPackInstallRecordPath(new WorkloadPackId(packInfo.ResolvedPackageId), packInfo.Version, featureBand); if (!Directory.Exists(Path.GetDirectoryName(path))) { Directory.CreateDirectory(Path.GetDirectoryName(path)); @@ -676,7 +676,7 @@ private void WritePackInstallationRecord(PackInfo packInfo, SdkFeatureBand featu private void DeletePackInstallationRecord(PackInfo packInfo, SdkFeatureBand featureBand) { - var packInstallRecord = GetPackInstallRecordPath(packInfo.Id, packInfo.Version, featureBand); + var packInstallRecord = GetPackInstallRecordPath(new WorkloadPackId(packInfo.ResolvedPackageId), packInfo.Version, featureBand); if (File.Exists(packInstallRecord)) { File.Delete(packInstallRecord); diff --git a/src/Cli/dotnet/commands/dotnet-workload/install/WorkloadGarbageCollector.cs b/src/Cli/dotnet/commands/dotnet-workload/install/WorkloadGarbageCollector.cs index 9273cb8e0cef..a74a44e4d7ff 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/install/WorkloadGarbageCollector.cs +++ b/src/Cli/dotnet/commands/dotnet-workload/install/WorkloadGarbageCollector.cs @@ -137,7 +137,7 @@ void GarbageCollectWorkloadManifestsAndPacks() .Select(packId => resolver.TryGetPackInfo(packId)) .Where(pack => pack != null)) { - PacksToKeep.Add((pack.Id, pack.Version)); + PacksToKeep.Add((new WorkloadPackId(pack.ResolvedPackageId), pack.Version)); } } From e9a9b61cab1a8f9ab79302c9a1999442b7d05d9f Mon Sep 17 00:00:00 2001 From: Daniel Plaisted Date: Fri, 19 Jan 2024 13:33:00 -0500 Subject: [PATCH 096/577] Garbage collect workload manifests for MSI-based installs --- .../DependencyProvider.cs | 2 + .../Windows/WorkloadManifestRecord.cs | 6 + ...NetSdkMsiInstallerClient.InstallRecords.cs | 23 ++- .../install/NetSdkMsiInstallerClient.cs | 183 ++++++++++++------ .../install/WorkloadGarbageCollector.cs | 22 ++- 5 files changed, 172 insertions(+), 64 deletions(-) diff --git a/src/Cli/Microsoft.DotNet.Cli.Utils/DependencyProvider.cs b/src/Cli/Microsoft.DotNet.Cli.Utils/DependencyProvider.cs index 0a3afe8596bd..46c926577e48 100644 --- a/src/Cli/Microsoft.DotNet.Cli.Utils/DependencyProvider.cs +++ b/src/Cli/Microsoft.DotNet.Cli.Utils/DependencyProvider.cs @@ -175,6 +175,8 @@ private string GetProductCode() return providerKey?.GetValue(null) as string ?? null; } + public override string ToString() => ProviderKeyName; + public static DependencyProvider GetFromProductCode(string productCode, bool allUsers = true) { var baseKey = allUsers ? Registry.LocalMachine : Registry.CurrentUser; diff --git a/src/Cli/dotnet/Installer/Windows/WorkloadManifestRecord.cs b/src/Cli/dotnet/Installer/Windows/WorkloadManifestRecord.cs index 1b7dadad9b24..3487f3606f80 100644 --- a/src/Cli/dotnet/Installer/Windows/WorkloadManifestRecord.cs +++ b/src/Cli/dotnet/Installer/Windows/WorkloadManifestRecord.cs @@ -39,6 +39,12 @@ public string ManifestVersion set; } + public string ManifestFeatureBand + { + get; + set; + } + /// /// The product code (GUID) of the workload manifest MSI. /// diff --git a/src/Cli/dotnet/commands/dotnet-workload/install/NetSdkMsiInstallerClient.InstallRecords.cs b/src/Cli/dotnet/commands/dotnet-workload/install/NetSdkMsiInstallerClient.InstallRecords.cs index b8fad9f5a6be..29b1a50db1e5 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/install/NetSdkMsiInstallerClient.InstallRecords.cs +++ b/src/Cli/dotnet/commands/dotnet-workload/install/NetSdkMsiInstallerClient.InstallRecords.cs @@ -30,23 +30,37 @@ protected List GetWorkloadManifestRecords() using RegistryKey installedManifestsKey = Registry.LocalMachine.OpenSubKey(@$"SOFTWARE\Microsoft\dotnet\InstalledManifests\{HostArchitecture}"); if (installedManifestsKey != null) { - foreach (string manifestId in installedManifestsKey.GetSubKeyNames()) + foreach (string manifestPackageId in installedManifestsKey.GetSubKeyNames()) { - using RegistryKey manifestKey = installedManifestsKey.OpenSubKey(manifestId); + const string ManifestSeparator = ".Manifest-"; + + int separatorIndex = manifestPackageId.IndexOf(ManifestSeparator); + if (separatorIndex < 0 || manifestPackageId.Length < separatorIndex + ManifestSeparator.Length + 1) + { + Log.LogMessage($"Found apparent manifest package ID '{manifestPackageId} which did not correctly parse into manifest ID and feature band."); + continue; + } + + string manifestId = manifestPackageId.Substring(0, separatorIndex); + string manifestFeatureBand = manifestPackageId.Substring(separatorIndex + ManifestSeparator.Length); + + using RegistryKey manifestKey = installedManifestsKey.OpenSubKey(manifestPackageId); foreach (string manifestVersion in manifestKey.GetSubKeyNames()) { using RegistryKey manifestVersionKey = manifestKey.OpenSubKey(manifestVersion); + WorkloadManifestRecord record = new WorkloadManifestRecord { ManifestId = manifestId, ManifestVersion = manifestVersion, + ManifestFeatureBand = manifestFeatureBand, ProductCode = (string)manifestVersionKey.GetValue("ProductCode"), UpgradeCode = (string)manifestVersionKey.GetValue("UpgradeCode"), ProductVersion = new Version((string)manifestVersionKey.GetValue("ProductVersion")), ProviderKeyName = (string)manifestVersionKey.GetValue("DependencyProviderKey") }; - Log.LogMessage($"Found workload manifest record, Id: {manifestId}, version: {manifestVersion}, ProductCode: {record.ProductCode}, provider key: {record.ProviderKeyName}"); + Log.LogMessage($"Found workload manifest record, Id: {manifestId}, version: {manifestVersion}, feature band: {manifestFeatureBand}, ProductCode: {record.ProductCode}, provider key: {record.ProviderKeyName}"); manifestRecords.Add(record); discoveredManifests.Add((manifestId, manifestVersion)); } @@ -138,8 +152,9 @@ protected List GetWorkloadManifestRecords() var manifestRecord = new WorkloadManifestRecord(); manifestRecord.ProductCode = relatedProductCodes[0]; manifestRecord.UpgradeCode = upgradeCode; - manifestRecord.ManifestVersion = manifestVersion.ToString(); manifestRecord.ManifestId = manifestID; + manifestRecord.ManifestVersion = manifestVersion.ToString(); + manifestRecord.ManifestFeatureBand = manifestFeatureBand.ToString(); manifestRecord.ProductVersion = installedVersion; manifestRecord.ProviderKeyName = dependencyProvider.ProviderKeyName; diff --git a/src/Cli/dotnet/commands/dotnet-workload/install/NetSdkMsiInstallerClient.cs b/src/Cli/dotnet/commands/dotnet-workload/install/NetSdkMsiInstallerClient.cs index f0fe66d764ad..022be1690a5e 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/install/NetSdkMsiInstallerClient.cs +++ b/src/Cli/dotnet/commands/dotnet-workload/install/NetSdkMsiInstallerClient.cs @@ -8,10 +8,12 @@ using Microsoft.DotNet.Installer.Windows; using Microsoft.DotNet.ToolPackage; using Microsoft.DotNet.Workloads.Workload.Install.InstallRecord; +using Microsoft.Extensions.DependencyModel; using Microsoft.Extensions.EnvironmentAbstractions; using Microsoft.NET.Sdk.WorkloadManifestReader; using Microsoft.Win32.Msi; using NuGet.Common; +using NuGet.Packaging.Signing; using NuGet.Versioning; using static Microsoft.NET.Sdk.WorkloadManifestReader.WorkloadResolver; @@ -97,6 +99,24 @@ public IEnumerable GetDownloads(IEnumerable worklo return msis.ToList(); ; } + // Wrap the setup logger in an IReporter so it can be passed to the garbage collector + private class SetupLogReporter : IReporter + { + private ISetupLogger _setupLogger; + + public SetupLogReporter(ISetupLogger setupLogger) + { + _setupLogger = setupLogger; + } + + // SetupLogger doesn't have a way of writing a message that shouldn't include a newline. So if this method is used a message may be split across multiple lines, + // but that's probably better than not writing a message at all or throwing an exception + public void Write(string message) => _setupLogger.LogMessage(message); + public void WriteLine(string message) => _setupLogger.LogMessage(message); + public void WriteLine() => _setupLogger.LogMessage(""); + public void WriteLine(string format, params object[] args) => _setupLogger.LogMessage(string.Format(format, args)); + } + /// /// Cleans up and removes stale workload packs. /// @@ -108,38 +128,64 @@ public void GarbageCollect(Func getResolverForWorkloa Log?.LogMessage($"Starting garbage collection."); Log?.LogMessage($"Garbage Collection Mode: CleanAllPacks={cleanAllPacks}."); - IEnumerable installedFeatureBands = GetInstalledFeatureBands(Log); - IEnumerable installedWorkloads = RecordRepository.GetInstalledWorkloads(_sdkFeatureBand); + var garbageCollector = new WorkloadGarbageCollector(DotNetHome, _sdkFeatureBand, RecordRepository.GetInstalledWorkloads(_sdkFeatureBand), getResolverForWorkloadSet, new SetupLogReporter(Log)); + garbageCollector.Collect(); + - var installedPacks = installedWorkloads.SelectMany(workload => _workloadResolver.GetPacksInWorkload(workload)) - .Distinct(); + IEnumerable installedFeatureBands = GetInstalledFeatureBands(Log); - var installedPackInfos = installedPacks.Select(pack => _workloadResolver.TryGetPackInfo(pack)) - .Where(pack => pack != null); + List manifestsToRemove = new(); - // The same workload pack may be aliased from two different names, for example - // Microsoft.NETCore.App.Runtime.Mono.android-arm is aliased from Microsoft.NETCore.App.Runtime.Mono.net6.android-arm and - // from Microsoft.NETCore.App.Runtime.Mono.net6.android-arm64 - HashSet<(WorkloadPackId id, string version)> expectedWorkloadPacks = new HashSet<(WorkloadPackId id, string version)>(); - foreach (var expectedPack in installedPackInfos) + var installedWorkloadManifests = GetWorkloadManifestRecords(); + foreach (var manifestRecord in installedWorkloadManifests) { - if (!expectedPack.Id.ToString().Equals(expectedPack.ResolvedPackageId, StringComparison.OrdinalIgnoreCase)) + DependencyProvider depProvider = new DependencyProvider(manifestRecord.ProviderKeyName); + + (bool shouldBeInstalled, string reason) shouldBeInstalled(SdkFeatureBand dependentFeatureBand) { - Log?.LogMessage($"Expected workload pack, ID: {expectedPack.ResolvedPackageId}, version: {expectedPack.Version}, aliased from: {expectedPack.Id}"); + if (!installedFeatureBands.Contains(dependentFeatureBand)) + { + return (false, $"SDK feature band {dependentFeatureBand} does not match any installed feature bands."); + } + else if (dependentFeatureBand.Equals(_sdkFeatureBand)) + { + if (garbageCollector.ManifestsToKeep.Contains((new ManifestId(manifestRecord.ManifestId), new ManifestVersion(manifestRecord.ManifestVersion), new SdkFeatureBand(manifestRecord.ManifestFeatureBand)))) + { + return (true, $"the manifest is still needed for SDK feature band {dependentFeatureBand}."); + } + else + { + return (false, $"the manifest is no longer needed for SDK feature band {dependentFeatureBand}."); + } + } + else + { + return (true, $"the manifest may still be needed for SDK feature band {dependentFeatureBand}, which is different than the current SDK feature band of {_sdkFeatureBand}"); + } + } + + Log?.LogMessage($"Evaluating dependents for workload manifest, dependent: {depProvider}, ID: {manifestRecord.ManifestId}, Version: {manifestRecord.ManifestVersion}, Feature Band: {manifestRecord.ManifestFeatureBand}"); + UpdateDependentReferenceCounts(depProvider, shouldBeInstalled); + + // Recheck the registry to see if there are any remaining dependents. If not, we can + // remove the workload manifest. We'll add it to the list and remove the packs at the end. + IEnumerable remainingDependents = depProvider.Dependents; + + if (remainingDependents.Any()) + { + Log?.LogMessage($"{manifestRecord.ManifestId} {manifestRecord.ManifestVersion}/{manifestRecord.ManifestFeatureBand} will not be removed because other dependents remain: {string.Join(", ", remainingDependents)}."); } else { - Log?.LogMessage($"Expected workload pack, ID: {expectedPack.ResolvedPackageId}, version: {expectedPack.Version}."); + manifestsToRemove.Add(manifestRecord); + Log?.LogMessage($"Removing {manifestRecord.ManifestId} {manifestRecord.ManifestVersion}/{manifestRecord.ManifestFeatureBand} as no dependents remain."); } - expectedWorkloadPacks.Add((new WorkloadPackId(expectedPack.ResolvedPackageId), expectedPack.Version)); } - foreach (SdkFeatureBand installedFeatureBand in installedFeatureBands) - { - Log?.LogMessage($"Installed feature band: {installedFeatureBand}"); - } + RemoveWorkloadManifests(manifestsToRemove, offlineCache); + // If aliased, the pack records here are the resolved pack from the alias IEnumerable installedWorkloadPacks = GetWorkloadPackRecords(); List packsToRemove = new List(); @@ -151,7 +197,36 @@ public void GarbageCollect(Func getResolverForWorkloa { DependencyProvider depProvider = new DependencyProvider(packRecord.ProviderKeyName); - UpdateDependentReferenceCounts(packRecord, depProvider, installedFeatureBands, expectedWorkloadPacks, cleanAllPacks); + (bool shouldBeInstalled, string reason) shouldBeInstalled(SdkFeatureBand dependentFeatureBand) + { + if (!installedFeatureBands.Contains(dependentFeatureBand)) + { + return (false, $"SDK feature band {dependentFeatureBand} does not match any installed feature bands."); + } + else if (cleanAllPacks) + { + return (false, "dotnet has been told to clean everything."); + } + else if (dependentFeatureBand.Equals(_sdkFeatureBand)) + { + // If the current SDK feature band is listed as a dependent, we can validate + // the workload packs against the expected pack IDs and versions to potentially remove it. + if (packRecord.InstalledPacks.All(p => !garbageCollector.PacksToKeep.Contains((p.id, p.version.ToString())))) + { + // None of the packs installed by this MSI are necessary any longer for this feature band, so we can remove the reference count + return (false, "the pack record(s) do not match any expected packs."); + } + else + { + return (true, $"the packs are still needed. Mode: {cleanAllPacks} | Dependent band: {dependentFeatureBand} | SDK band: {_sdkFeatureBand}."); + } + } + return (true, $"no conditions for removal were met. Mode: {cleanAllPacks} | Dependent band: {dependentFeatureBand} | SDK band: {_sdkFeatureBand}."); + } + + + Log?.LogMessage($"Evaluating dependents for workload pack, dependent: {depProvider}, MSI ID: {packRecord.MsiId}, MSI version: {packRecord.MsiNuGetVersion}"); + UpdateDependentReferenceCounts(depProvider, shouldBeInstalled); // Recheck the registry to see if there are any remaining dependents. If not, we can // remove the workload pack. We'll add it to the list and remove the packs at the end. @@ -187,17 +262,11 @@ public void GarbageCollect(Func getResolverForWorkloa /// about dependents that match the SDK host we're running under. For example, an x86 SDK should not be /// modifying the x64 MSI dependents. After this, decrement any dependents (registry keys) that should be removed. /// - /// /// - /// - /// - /// If true, decrement reference counts for all CLI MSI workloads. Elsewise, only deference dependents for orphaned packs. + /// Function to determine whether a dependency record (reference count) for a feature band should be kept private void UpdateDependentReferenceCounts( - WorkloadPackRecord packRecordToUpdate, DependencyProvider depProvider, - IEnumerable installedFeatureBands, - HashSet<(WorkloadPackId id, string version)> expectedWorkloadPacks, - bool cleanAllPacks + Func shouldBeInstalledFunc ) { IEnumerable sdkDependents = depProvider.Dependents @@ -206,8 +275,6 @@ bool cleanAllPacks foreach (string dependent in sdkDependents) { - Log?.LogMessage($"Evaluating dependent for workload pack, dependent: {dependent}, MSI ID: {packRecordToUpdate.MsiId}, MSI version: {packRecordToUpdate.MsiNuGetVersion}"); - // Dependents created by the SDK should have 3 parts, for example, "Microsoft.NET.Sdk,6.0.100,x86". string[] dependentParts = dependent.Split(','); @@ -221,35 +288,15 @@ bool cleanAllPacks { SdkFeatureBand dependentFeatureBand = new SdkFeatureBand(dependentParts[1]); - if (!installedFeatureBands.Contains(dependentFeatureBand)) + var (shouldBeInstalled, reason) = shouldBeInstalledFunc(dependentFeatureBand); + if (shouldBeInstalled) { - Log?.LogMessage($"Removing dependent '{dependent}' from provider key '{depProvider.ProviderKeyName}' because its SDK feature band does not match any installed feature bands."); - UpdateDependent(InstallRequestType.RemoveDependent, depProvider.ProviderKeyName, dependent); - } - else if (cleanAllPacks) - { - Log?.LogMessage($"Adding dependent '{dependent}' for removal as part as dotnet has been told to clean everything."); - // VS will manage its own MSI packs, so no need to worry about decrementing too much here. - UpdateDependent(InstallRequestType.RemoveDependent, depProvider.ProviderKeyName, dependent); - } - else if (dependentFeatureBand.Equals(_sdkFeatureBand)) - { - // If the current SDK feature band is listed as a dependent, we can validate - // the workload packs against the expected pack IDs and versions to potentially remove it. - if (packRecordToUpdate.InstalledPacks.All(p => !expectedWorkloadPacks.Contains((p.id, p.version.ToString())))) - { - // None of the packs installed by this MSI are necessary any longer for this feature band, so we can remove the reference count - Log?.LogMessage($"Removing dependent '{dependent}' because the pack record(s) do not match any expected packs."); - UpdateDependent(InstallRequestType.RemoveDependent, depProvider.ProviderKeyName, dependent); - } - else - { - Log?.LogMessage($"Dependent '{dependent}' was not removed as the packs are still needed. Mode: {cleanAllPacks} | Dependent band: {dependentFeatureBand} | SDK band: {_sdkFeatureBand}."); - } + Log?.LogMessage($"Dependent '{dependent}' was not removed because {reason}"); } else { - Log?.LogMessage($"Dependent '{dependent}' was not removed. Mode: {cleanAllPacks} | Dependent band: {dependentFeatureBand} | SDK band: {_sdkFeatureBand}."); + Log?.LogMessage($"Removing dependent '{dependent}' from provider key '{depProvider.ProviderKeyName}' because {reason}"); + UpdateDependent(InstallRequestType.RemoveDependent, depProvider.ProviderKeyName, dependent); } } catch (Exception e) @@ -261,6 +308,32 @@ bool cleanAllPacks } } + private void RemoveWorkloadManifests(List manifestToRemove, DirectoryPath? offlineCach) + { + foreach (WorkloadManifestRecord record in manifestToRemove) + { + DetectState state = DetectPackage(record.ProductCode, out Version _); + if (state == DetectState.Present) + { + string msiNuGetPackageId = $"{record.ManifestId}.Manifest-{record.ManifestFeatureBand}.Msi.{HostArchitecture}"; + MsiPayload msi = GetCachedMsiPayload(msiNuGetPackageId, record.ManifestVersion, offlineCach); + + if (!string.Equals(record.ProductCode, msi.ProductCode, StringComparison.OrdinalIgnoreCase)) + { + Log?.LogMessage($"ProductCode mismatch! Cached package: {msi.ProductCode}, manifest record: {record.ProductCode}."); + string logFile = GetMsiLogName(record.ProductCode, InstallAction.Uninstall); + uint error = ExecuteWithProgress(String.Format(LocalizableStrings.MsiProgressUninstall, msiNuGetPackageId), () => UninstallMsi(record.ProductCode, logFile)); + ExitOnError(error, $"Failed to uninstall {msi.MsiPath}."); + } + else + { + VerifyPackage(msi); + ExecutePackage(msi, InstallAction.Uninstall, msiNuGetPackageId); + } + } + } + } + private void RemoveWorkloadPacks(List packsToRemove, DirectoryPath? offlineCache) { foreach (WorkloadPackRecord record in packsToRemove) diff --git a/src/Cli/dotnet/commands/dotnet-workload/install/WorkloadGarbageCollector.cs b/src/Cli/dotnet/commands/dotnet-workload/install/WorkloadGarbageCollector.cs index a74a44e4d7ff..cf25019d9994 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/install/WorkloadGarbageCollector.cs +++ b/src/Cli/dotnet/commands/dotnet-workload/install/WorkloadGarbageCollector.cs @@ -8,6 +8,7 @@ using System.Text; using System.Threading.Tasks; using Microsoft.Deployment.DotNet.Releases; +using Microsoft.DotNet.Cli.Utils; using Microsoft.DotNet.NativeWrapper; using Microsoft.NET.Sdk.WorkloadManifestReader; @@ -29,21 +30,27 @@ internal class WorkloadGarbageCollector string _dotnetDir; IEnumerable _installedWorkloads; Func _getResolverForWorkloadSet; + IReporter _verboseReporter; public HashSet WorkloadSetsToKeep = new(); public HashSet<(ManifestId id, ManifestVersion version, SdkFeatureBand featureBand)> ManifestsToKeep = new(); public HashSet<(WorkloadPackId id, string version)> PacksToKeep = new(); - public WorkloadGarbageCollector(string dotnetDir, SdkFeatureBand sdkFeatureBand, IEnumerable installedWorkloads, Func getResolverForWorkloadSet) + public WorkloadGarbageCollector(string dotnetDir, SdkFeatureBand sdkFeatureBand, IEnumerable installedWorkloads, Func getResolverForWorkloadSet, + IReporter verboseReporter) { _dotnetDir = dotnetDir; _sdkFeatureBand = sdkFeatureBand; _installedWorkloads = installedWorkloads; _getResolverForWorkloadSet = getResolverForWorkloadSet; + _verboseReporter = verboseReporter ?? Reporter.NullReporter; } public void Collect() { + _verboseReporter.WriteLine("GC: Beginning workload garbage collection."); + _verboseReporter.WriteLine($"GC: Installed workloads: {string.Join(", ", _installedWorkloads)}"); + GarbageCollectWorkloadSets(); GarbageCollectWorkloadManifestsAndPacks(); } @@ -75,6 +82,7 @@ void GarbageCollectWorkloadSets() if (!string.IsNullOrEmpty(installState.WorkloadSetVersion)) { WorkloadSetsToKeep.Add(installState.WorkloadSetVersion); + _verboseReporter.WriteLine($"GC: Keeping workload set version {installState.WorkloadSetVersion} because it is specified in the install state file {installStateFilePath}"); } } else @@ -84,6 +92,7 @@ void GarbageCollectWorkloadSets() { var latestWorkloadSetVersion = installedWorkloadSets.Keys.MaxBy(k => new ReleaseVersion(k)); WorkloadSetsToKeep.Add(latestWorkloadSetVersion); + _verboseReporter.WriteLine($"GC: Keeping latest installed workload set version {latestWorkloadSetVersion}"); } } @@ -93,6 +102,7 @@ void GarbageCollectWorkloadSets() if (workloadSet.IsBaselineWorkloadSet) { WorkloadSetsToKeep.Add(workloadSet.Version); + _verboseReporter.WriteLine($"GC: Keeping baseline workload set version {workloadSet.Version}"); } } @@ -115,21 +125,22 @@ void GarbageCollectWorkloadManifestsAndPacks() // - Any manifests listed in the rollback state file (default.json) // - The latest version of each manifest, if a workload set is not installed and there is no rollback state file - List resolvers = new List(); - resolvers.Add(GetResolver()); + List<(IWorkloadResolver, string workloadSet)> resolvers = new(); + resolvers.Add((GetResolver(), "")); // Iterate through all installed workload sets for this SDK feature band that have not been marked for garbage collection // For each manifest version listed in a workload set, add it to a list to keep foreach (var workloadSet in WorkloadSetsToKeep) { - resolvers.Add(GetResolver(workloadSet)); + resolvers.Add((GetResolver(workloadSet), workloadSet)); } - foreach (var resolver in resolvers) + foreach (var (resolver, workloadSet) in resolvers) { foreach (var manifest in resolver.GetInstalledManifests()) { + _verboseReporter.WriteLine($"GC: Keeping manifest {manifest.Id} {manifest.Version}/{manifest.ManifestFeatureBand} as part of workload set {workloadSet}"); ManifestsToKeep.Add((new ManifestId(manifest.Id), new ManifestVersion(manifest.Version), new SdkFeatureBand(manifest.ManifestFeatureBand))); } @@ -137,6 +148,7 @@ void GarbageCollectWorkloadManifestsAndPacks() .Select(packId => resolver.TryGetPackInfo(packId)) .Where(pack => pack != null)) { + _verboseReporter.WriteLine($"GC: Keeping workload pack {pack.ResolvedPackageId} {pack.Version} as part of workload set {workloadSet}"); PacksToKeep.Add((new WorkloadPackId(pack.ResolvedPackageId), pack.Version)); } } From 5395566bc10e7c482085c2deec909905177e23d7 Mon Sep 17 00:00:00 2001 From: Forgind <12969783+Forgind@users.noreply.github.com> Date: Fri, 19 Jan 2024 15:30:33 -0800 Subject: [PATCH 097/577] Avoid elevation if we will noop in MSI-based operations to adjust the install state (#38117) --- .../dotnet-workload/InstallStateContents.cs | 5 ++++ .../install/FileBasedInstaller.cs | 6 ++--- .../install/MsiInstallerBase.cs | 26 +++++++++++++++---- .../MockPackWorkloadInstaller.cs | 4 +-- 4 files changed, 31 insertions(+), 10 deletions(-) diff --git a/src/Cli/dotnet/commands/dotnet-workload/InstallStateContents.cs b/src/Cli/dotnet/commands/dotnet-workload/InstallStateContents.cs index d6fcc23bf654..3c30ce66ab73 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/InstallStateContents.cs +++ b/src/Cli/dotnet/commands/dotnet-workload/InstallStateContents.cs @@ -25,6 +25,11 @@ public static InstallStateContents FromString(string contents) return JsonSerializer.Deserialize(contents, s_options); } + public static InstallStateContents FromPath(string path) + { + return File.Exists(path) ? FromString(File.ReadAllText(path)) : new InstallStateContents(); + } + public override string ToString() { return JsonSerializer.Serialize(this, s_options); diff --git a/src/Cli/dotnet/commands/dotnet-workload/install/FileBasedInstaller.cs b/src/Cli/dotnet/commands/dotnet-workload/install/FileBasedInstaller.cs index 08cd93199320..526842ea5e49 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/install/FileBasedInstaller.cs +++ b/src/Cli/dotnet/commands/dotnet-workload/install/FileBasedInstaller.cs @@ -458,7 +458,7 @@ public void RemoveManifestsFromInstallState(SdkFeatureBand sdkFeatureBand) if (File.Exists(path)) { - var installStateContents = File.Exists(path) ? InstallStateContents.FromString(File.ReadAllText(path)) : new InstallStateContents(); + var installStateContents = InstallStateContents.FromString(File.ReadAllText(path)); installStateContents.Manifests = null; File.WriteAllText(path, installStateContents.ToString()); } @@ -468,7 +468,7 @@ public void SaveInstallStateManifestVersions(SdkFeatureBand sdkFeatureBand, Dict { string path = Path.Combine(WorkloadInstallType.GetInstallStateFolder(_sdkFeatureBand, _dotnetDir), "default.json"); Directory.CreateDirectory(Path.GetDirectoryName(path)); - var installStateContents = File.Exists(path) ? InstallStateContents.FromString(File.ReadAllText(path)) : new InstallStateContents(); + var installStateContents = InstallStateContents.FromPath(path); installStateContents.Manifests = manifestContents; File.WriteAllText(path, installStateContents.ToString()); } @@ -477,7 +477,7 @@ public void UpdateInstallMode(SdkFeatureBand sdkFeatureBand, bool newMode) { string path = Path.Combine(WorkloadInstallType.GetInstallStateFolder(sdkFeatureBand, _dotnetDir), "default.json"); Directory.CreateDirectory(Path.GetDirectoryName(path)); - var installStateContents = File.Exists(path) ? InstallStateContents.FromString(File.ReadAllText(path)) : new InstallStateContents(); + var installStateContents = InstallStateContents.FromPath(path); installStateContents.UseWorkloadSets = newMode; File.WriteAllText(path, installStateContents.ToString()); } diff --git a/src/Cli/dotnet/commands/dotnet-workload/install/MsiInstallerBase.cs b/src/Cli/dotnet/commands/dotnet-workload/install/MsiInstallerBase.cs index 60d086bb4d1a..62bb3a9bcd8d 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/install/MsiInstallerBase.cs +++ b/src/Cli/dotnet/commands/dotnet-workload/install/MsiInstallerBase.cs @@ -285,17 +285,21 @@ protected uint RepairMsi(string productCode, string logFile) /// protected void UpdateInstallMode(SdkFeatureBand sdkFeatureBand, bool newMode) { + string path = Path.Combine(WorkloadInstallType.GetInstallStateFolder(sdkFeatureBand, DotNetHome), "default.json"); + var installStateContents = InstallStateContents.FromPath(path); + if (installStateContents.UseWorkloadSets == newMode) + { + return; + } + Elevate(); if (IsElevated) { - string path = Path.Combine(WorkloadInstallType.GetInstallStateFolder(sdkFeatureBand, DotNetHome), "default.json"); // Create the parent folder for the state file and set up all required ACLs SecurityUtils.CreateSecureDirectory(Path.GetDirectoryName(path)); - var installStateContents = File.Exists(path) ? InstallStateContents.FromString(File.ReadAllText(path)) : new InstallStateContents(); installStateContents.UseWorkloadSets = newMode; File.WriteAllText(path, installStateContents.ToString()); - SecurityUtils.SecureFile(path); } else if (IsClient) @@ -537,6 +541,11 @@ protected void UpdateDependent(InstallRequestType requestType, string providerKe public void RemoveManifestsFromInstallState(SdkFeatureBand sdkFeatureBand) { string path = Path.Combine(WorkloadInstallType.GetInstallStateFolder(sdkFeatureBand, DotNetHome), "default.json"); + var installStateContents = InstallStateContents.FromPath(path); + if (installStateContents.Manifests == null) + { + return; + } if (!File.Exists(path)) { @@ -550,7 +559,6 @@ public void RemoveManifestsFromInstallState(SdkFeatureBand sdkFeatureBand) { if (File.Exists(path)) { - var installStateContents = InstallStateContents.FromString(File.ReadAllText(path)); installStateContents.Manifests = null; File.WriteAllText(path, installStateContents.ToString()); } @@ -570,6 +578,14 @@ public void RemoveManifestsFromInstallState(SdkFeatureBand sdkFeatureBand) public void SaveInstallStateManifestVersions(SdkFeatureBand sdkFeatureBand, Dictionary manifestContents) { string path = Path.Combine(WorkloadInstallType.GetInstallStateFolder(sdkFeatureBand, DotNetHome), "default.json"); + var installStateContents = InstallStateContents.FromPath(path); + if (installStateContents.Manifests != null && // manifestContents should not be null here + installStateContents.Manifests.Count == manifestContents.Count && + installStateContents.Manifests.All(m => manifestContents.TryGetValue(m.Key, out var val) && val.Equals(m.Value))) + { + return; + } + Elevate(); if (IsElevated) @@ -577,7 +593,7 @@ public void SaveInstallStateManifestVersions(SdkFeatureBand sdkFeatureBand, Dict // Create the parent folder for the state file and set up all required ACLs SecurityUtils.CreateSecureDirectory(Path.GetDirectoryName(path)); - var installStateContents = File.Exists(path) ? InstallStateContents.FromString(File.ReadAllText(path)) : new InstallStateContents(); + installStateContents.Manifests = manifestContents; File.WriteAllText(path, installStateContents.ToString()); diff --git a/src/Tests/dotnet-workload-install.Tests/MockPackWorkloadInstaller.cs b/src/Tests/dotnet-workload-install.Tests/MockPackWorkloadInstaller.cs index 61d6dc6f24d8..37a204706607 100644 --- a/src/Tests/dotnet-workload-install.Tests/MockPackWorkloadInstaller.cs +++ b/src/Tests/dotnet-workload-install.Tests/MockPackWorkloadInstaller.cs @@ -170,7 +170,7 @@ public void RemoveManifestsFromInstallState(SdkFeatureBand sdkFeatureBand) string path = Path.Combine(WorkloadInstallType.GetInstallStateFolder(sdkFeatureBand, _dotnetDir), "default.json"); if (File.Exists(path)) { - var installStateContents = File.Exists(path) ? InstallStateContents.FromString(File.ReadAllText(path)) : new InstallStateContents(); + var installStateContents = InstallStateContents.FromPath(path); installStateContents.Manifests = null; File.WriteAllText(path, installStateContents.ToString()); } @@ -180,7 +180,7 @@ public void SaveInstallStateManifestVersions(SdkFeatureBand sdkFeatureBand, Dict { string path = Path.Combine(WorkloadInstallType.GetInstallStateFolder(sdkFeatureBand, _dotnetDir), "default.json"); Directory.CreateDirectory(Path.GetDirectoryName(path)); - var installStateContents = File.Exists(path) ? InstallStateContents.FromString(File.ReadAllText(path)) : new InstallStateContents(); + var installStateContents = InstallStateContents.FromPath(path); installStateContents.Manifests = manifestContents; File.WriteAllText(path, installStateContents.ToString()); } From e523643d6c6df310532fb177760d9a0e38e6adc6 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" Date: Sat, 20 Jan 2024 13:53:29 +0000 Subject: [PATCH 098/577] Update dependencies from https://github.com/nuget/nuget.client build 6.10.0.8 Microsoft.Build.NuGetSdkResolver , NuGet.Build.Tasks , NuGet.Build.Tasks.Console , NuGet.Build.Tasks.Pack , NuGet.CommandLine.XPlat , NuGet.Commands , NuGet.Common , NuGet.Configuration , NuGet.Credentials , NuGet.DependencyResolver.Core , NuGet.Frameworks , NuGet.LibraryModel , NuGet.Packaging , NuGet.ProjectModel , NuGet.Protocol , NuGet.Versioning From Version 6.9.0-rc.74 -> To Version 6.10.0-preview.1.8 From 232800251388f65fa553f312f4c6fe13e1db2ff5 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" Date: Sat, 20 Jan 2024 13:54:04 +0000 Subject: [PATCH 099/577] Update dependencies from https://github.com/dotnet/msbuild build 20240119.3 Microsoft.SourceBuild.Intermediate.msbuild , Microsoft.Build , Microsoft.Build.Localization From Version 17.10.0-preview-24069-02 -> To Version 17.10.0-preview-24069-03 --- eng/Version.Details.xml | 12 ++++++------ eng/Versions.props | 4 ++-- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 2cff07542428..52d05ea3b95a 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -51,17 +51,17 @@ https://github.com/dotnet/emsdk 2406616d0e3a31d80b326e27c156955bfa41c791 - + https://github.com/dotnet/msbuild - 0932b436c6fa26bb356ce21815d5892ed41834d3 + 6d97976719d4aefae595ee919b942da452e97e57 - + https://github.com/dotnet/msbuild - 0932b436c6fa26bb356ce21815d5892ed41834d3 + 6d97976719d4aefae595ee919b942da452e97e57 - + https://github.com/dotnet/msbuild - 0932b436c6fa26bb356ce21815d5892ed41834d3 + 6d97976719d4aefae595ee919b942da452e97e57 diff --git a/eng/Versions.props b/eng/Versions.props index 2fda4fb22f1d..3ed868a18c7f 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -105,7 +105,7 @@ - 17.10.0-preview-24069-02 + 17.10.0-preview-24069-03 $(MicrosoftBuildPackageVersion) - 17.10.0-preview-24068-02 - 17.10.0-preview-24068-02 - 17.10.0-preview-24068-02 + 17.10.0-preview-24069-04 + 17.10.0-preview-24069-04 + 17.10.0-preview-24069-04 From 0f792287cce49200dece68eb5c4b3d03d9a7c6e9 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" Date: Sat, 20 Jan 2024 13:54:43 +0000 Subject: [PATCH 101/577] Update dependencies from https://github.com/dotnet/razor build 20240119.1 Microsoft.AspNetCore.Mvc.Razor.Extensions.Tooling.Internal , Microsoft.CodeAnalysis.Razor.Tooling.Internal , Microsoft.NET.Sdk.Razor.SourceGenerators.Transport From Version 7.0.0-preview.24068.3 -> To Version 7.0.0-preview.24069.1 --- eng/Version.Details.xml | 12 ++++++------ eng/Versions.props | 6 +++--- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 2cff07542428..424a0a146bf8 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -277,18 +277,18 @@ https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore 3f1acb59718cadf111a0a796681e3d3509bb3381 - + https://github.com/dotnet/razor - 35529773663446c499b7cee3ca924612c6e945b3 + 999b33452cdd3c4ac639e21419f4b34f2999571d - + https://github.com/dotnet/razor - 35529773663446c499b7cee3ca924612c6e945b3 + 999b33452cdd3c4ac639e21419f4b34f2999571d - + https://github.com/dotnet/razor - 35529773663446c499b7cee3ca924612c6e945b3 + 999b33452cdd3c4ac639e21419f4b34f2999571d https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore diff --git a/eng/Versions.props b/eng/Versions.props index 2fda4fb22f1d..30caee27043b 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -160,9 +160,9 @@ - 7.0.0-preview.24068.3 - 7.0.0-preview.24068.3 - 7.0.0-preview.24068.3 + 7.0.0-preview.24069.1 + 7.0.0-preview.24069.1 + 7.0.0-preview.24069.1 From 82a693283d1c5629f626fd9caf07e58131a9f057 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" Date: Sun, 21 Jan 2024 13:42:10 +0000 Subject: [PATCH 102/577] Update dependencies from https://github.com/nuget/nuget.client build 6.10.0.9 Microsoft.Build.NuGetSdkResolver , NuGet.Build.Tasks , NuGet.Build.Tasks.Console , NuGet.Build.Tasks.Pack , NuGet.CommandLine.XPlat , NuGet.Commands , NuGet.Common , NuGet.Configuration , NuGet.Credentials , NuGet.DependencyResolver.Core , NuGet.Frameworks , NuGet.LibraryModel , NuGet.Packaging , NuGet.ProjectModel , NuGet.Protocol , NuGet.Versioning From Version 6.9.0-rc.74 -> To Version 6.10.0-preview.1.9 --- eng/Version.Details.xml | 64 ++++++++++++++++++++--------------------- eng/Versions.props | 22 +++++++------- 2 files changed, 43 insertions(+), 43 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index f36ffbf73e63..f8805723fac9 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -115,69 +115,69 @@ https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore 3f1acb59718cadf111a0a796681e3d3509bb3381 - + https://github.com/nuget/nuget.client - 1870d8c7b326de0ae23a0ebb15a147ce718de2fc + 566e2853b8537e8b484844fad32b3f6073ba3167 - + https://github.com/nuget/nuget.client - 1870d8c7b326de0ae23a0ebb15a147ce718de2fc + 566e2853b8537e8b484844fad32b3f6073ba3167 - + https://github.com/nuget/nuget.client - 1870d8c7b326de0ae23a0ebb15a147ce718de2fc + 566e2853b8537e8b484844fad32b3f6073ba3167 - + https://github.com/nuget/nuget.client - 1870d8c7b326de0ae23a0ebb15a147ce718de2fc + 566e2853b8537e8b484844fad32b3f6073ba3167 - + https://github.com/nuget/nuget.client - 1870d8c7b326de0ae23a0ebb15a147ce718de2fc + 566e2853b8537e8b484844fad32b3f6073ba3167 - + https://github.com/nuget/nuget.client - 1870d8c7b326de0ae23a0ebb15a147ce718de2fc + 566e2853b8537e8b484844fad32b3f6073ba3167 - + https://github.com/nuget/nuget.client - 1870d8c7b326de0ae23a0ebb15a147ce718de2fc + 566e2853b8537e8b484844fad32b3f6073ba3167 - + https://github.com/nuget/nuget.client - 1870d8c7b326de0ae23a0ebb15a147ce718de2fc + 566e2853b8537e8b484844fad32b3f6073ba3167 - + https://github.com/nuget/nuget.client - 1870d8c7b326de0ae23a0ebb15a147ce718de2fc + 566e2853b8537e8b484844fad32b3f6073ba3167 - + https://github.com/nuget/nuget.client - 1870d8c7b326de0ae23a0ebb15a147ce718de2fc + 566e2853b8537e8b484844fad32b3f6073ba3167 - + https://github.com/nuget/nuget.client - 1870d8c7b326de0ae23a0ebb15a147ce718de2fc + 566e2853b8537e8b484844fad32b3f6073ba3167 - + https://github.com/nuget/nuget.client - 1870d8c7b326de0ae23a0ebb15a147ce718de2fc + 566e2853b8537e8b484844fad32b3f6073ba3167 - + https://github.com/nuget/nuget.client - 1870d8c7b326de0ae23a0ebb15a147ce718de2fc + 566e2853b8537e8b484844fad32b3f6073ba3167 - + https://github.com/nuget/nuget.client - 1870d8c7b326de0ae23a0ebb15a147ce718de2fc + 566e2853b8537e8b484844fad32b3f6073ba3167 - + https://github.com/nuget/nuget.client - 1870d8c7b326de0ae23a0ebb15a147ce718de2fc + 566e2853b8537e8b484844fad32b3f6073ba3167 - + https://github.com/nuget/nuget.client - 1870d8c7b326de0ae23a0ebb15a147ce718de2fc + 566e2853b8537e8b484844fad32b3f6073ba3167 https://github.com/microsoft/vstest diff --git a/eng/Versions.props b/eng/Versions.props index ae6675ae8551..ff73aaa301c1 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -67,18 +67,18 @@ - 6.10.0-preview.1.8 - 6.10.0-preview.1.8 + 6.10.0-preview.1.9 + 6.10.0-preview.1.9 6.0.0-rc.278 - 6.10.0-preview.1.8 - 6.10.0-preview.1.8 - 6.10.0-preview.1.8 - 6.10.0-preview.1.8 - 6.10.0-preview.1.8 - 6.10.0-preview.1.8 - 6.10.0-preview.1.8 - 6.10.0-preview.1.8 - 6.10.0-preview.1.8 + 6.10.0-preview.1.9 + 6.10.0-preview.1.9 + 6.10.0-preview.1.9 + 6.10.0-preview.1.9 + 6.10.0-preview.1.9 + 6.10.0-preview.1.9 + 6.10.0-preview.1.9 + 6.10.0-preview.1.9 + 6.10.0-preview.1.9 $(NuGetPackagingPackageVersion) $(NuGetProjectModelPackageVersion) From 600d06c24d216be2b39f1f397a7f0553afe429fa Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" Date: Sun, 21 Jan 2024 13:42:52 +0000 Subject: [PATCH 103/577] Update dependencies from https://github.com/dotnet/msbuild build 20240119.3 Microsoft.SourceBuild.Intermediate.msbuild , Microsoft.Build , Microsoft.Build.Localization From Version 17.10.0-preview-24069-02 -> To Version 17.10.0-preview-24069-03 From 88af623e78a6c7adf02903e176928a0c9abaeaaa Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" Date: Sun, 21 Jan 2024 13:43:13 +0000 Subject: [PATCH 104/577] Update dependencies from https://github.com/microsoft/vstest build 20240119.4 Microsoft.NET.Test.Sdk , Microsoft.TestPlatform.Build , Microsoft.TestPlatform.CLI From Version 17.9.0-release-23627-01 -> To Version 17.10.0-preview-24069-04 From 94843ea8887f1494654d393aa13a29517eb49449 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" Date: Sun, 21 Jan 2024 13:43:34 +0000 Subject: [PATCH 105/577] Update dependencies from https://github.com/dotnet/razor build 20240119.1 Microsoft.AspNetCore.Mvc.Razor.Extensions.Tooling.Internal , Microsoft.CodeAnalysis.Razor.Tooling.Internal , Microsoft.NET.Sdk.Razor.SourceGenerators.Transport From Version 7.0.0-preview.24068.3 -> To Version 7.0.0-preview.24069.1 From 8812661984211545223c2a0f00cd1ff4de9cc332 Mon Sep 17 00:00:00 2001 From: Jason Zhai Date: Mon, 22 Jan 2024 00:45:58 -0800 Subject: [PATCH 106/577] Simplified the code according to #38123 comment --- .../Microsoft.NET.TestFramework/TestAsset.cs | 1 - .../Microsoft.NET.TestFramework/ToolsetInfo.cs | 17 ++++++++--------- 2 files changed, 8 insertions(+), 10 deletions(-) diff --git a/src/Tests/Microsoft.NET.TestFramework/TestAsset.cs b/src/Tests/Microsoft.NET.TestFramework/TestAsset.cs index 07c3bd1f557a..14c7aa518c5f 100644 --- a/src/Tests/Microsoft.NET.TestFramework/TestAsset.cs +++ b/src/Tests/Microsoft.NET.TestFramework/TestAsset.cs @@ -106,7 +106,6 @@ public TestAsset WithSource() new string[] { "NewtonsoftJsonPackageVersion", ToolsetInfo.GetNewtonsoftJsonPackageVersion() }, new string[] { "SystemDataSqlClientPackageVersion", ToolsetInfo.GetSystemDataSqlClientPackageVersion() }}; - foreach (string[] PackageVersionVariable in PackageVersionVariables) { this.ReplacePackageVersionVariable(PackageVersionVariable[0], PackageVersionVariable[1]); diff --git a/src/Tests/Microsoft.NET.TestFramework/ToolsetInfo.cs b/src/Tests/Microsoft.NET.TestFramework/ToolsetInfo.cs index fc3505893bdc..9aeb184a6aac 100644 --- a/src/Tests/Microsoft.NET.TestFramework/ToolsetInfo.cs +++ b/src/Tests/Microsoft.NET.TestFramework/ToolsetInfo.cs @@ -412,27 +412,26 @@ private bool UsingFullMSBuildWithoutExtensionsTargets() return !File.Exists(extensionsImportAfterPath); } - private static readonly Lazy _NewtonsoftJsonPackageVersion = new Lazy(() => + private static string GetPackageVersion(string key) { Assembly assembly = Assembly.GetExecutingAssembly(); - return assembly.GetCustomAttributes(true).OfType().FirstOrDefault(a => a.Key == "NewtonsoftJsonPackageVersion").Value; - }); + return assembly.GetCustomAttributes(true) + .OfType() + .FirstOrDefault(a => a.Key == key)?.Value; + } + + private static readonly Lazy _NewtonsoftJsonPackageVersion = new Lazy(() => GetPackageVersion( "NewtonsoftJsonPackageVersion")); public static string GetNewtonsoftJsonPackageVersion() { return _NewtonsoftJsonPackageVersion.Value; } - private static readonly Lazy _SystemDataSqlClientPackageVersion = new(() => - { - Assembly assembly = Assembly.GetExecutingAssembly(); - return assembly.GetCustomAttributes(true).OfType().FirstOrDefault(a => a.Key == "SystemDataSqlClientPackageVersion").Value; - }); + private static readonly Lazy _SystemDataSqlClientPackageVersion = new(() => GetPackageVersion("SystemDataSqlClientPackageVersion")); public static string GetSystemDataSqlClientPackageVersion() { return _SystemDataSqlClientPackageVersion.Value; } - } } From 569b2216fcda413bc347a9c3de4c445cb0095145 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" Date: Mon, 22 Jan 2024 13:35:01 +0000 Subject: [PATCH 107/577] Update dependencies from https://github.com/nuget/nuget.client build 6.10.0.9 Microsoft.Build.NuGetSdkResolver , NuGet.Build.Tasks , NuGet.Build.Tasks.Console , NuGet.Build.Tasks.Pack , NuGet.CommandLine.XPlat , NuGet.Commands , NuGet.Common , NuGet.Configuration , NuGet.Credentials , NuGet.DependencyResolver.Core , NuGet.Frameworks , NuGet.LibraryModel , NuGet.Packaging , NuGet.ProjectModel , NuGet.Protocol , NuGet.Versioning From Version 6.9.0-rc.74 -> To Version 6.10.0-preview.1.9 From ada1bad402578da11d7906af496f919159b0e345 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" Date: Mon, 22 Jan 2024 13:35:43 +0000 Subject: [PATCH 108/577] Update dependencies from https://github.com/microsoft/vstest build 20240119.4 Microsoft.NET.Test.Sdk , Microsoft.TestPlatform.Build , Microsoft.TestPlatform.CLI From Version 17.9.0-release-23627-01 -> To Version 17.10.0-preview-24069-04 From 5a477642ce8a348d05385bbc2d3297e0793070af Mon Sep 17 00:00:00 2001 From: Forgind <12969783+Forgind@users.noreply.github.com> Date: Mon, 22 Jan 2024 12:20:01 -0800 Subject: [PATCH 109/577] Update CI (#37984) From 82605fd9c0404af0a4b844a9bcd4312f9b830803 Mon Sep 17 00:00:00 2001 From: Forgind <12969783+Forgind@users.noreply.github.com> Date: Mon, 22 Jan 2024 12:20:28 -0800 Subject: [PATCH 110/577] Treat rtm as stable Fixes #36500 (#37160) --- .../Microsoft.NET.Sdk.WorkloadManifestReader/SdkFeatureBand.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/SdkFeatureBand.cs b/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/SdkFeatureBand.cs index ac23e482e83d..e496e9d757d9 100644 --- a/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/SdkFeatureBand.cs +++ b/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/SdkFeatureBand.cs @@ -15,7 +15,7 @@ public struct SdkFeatureBand : IEquatable, IComparable Date: Tue, 23 Jan 2024 14:00:41 +0000 Subject: [PATCH 111/577] Update dependencies from https://github.com/nuget/nuget.client build 6.10.0.9 Microsoft.Build.NuGetSdkResolver , NuGet.Build.Tasks , NuGet.Build.Tasks.Console , NuGet.Build.Tasks.Pack , NuGet.CommandLine.XPlat , NuGet.Commands , NuGet.Common , NuGet.Configuration , NuGet.Credentials , NuGet.DependencyResolver.Core , NuGet.Frameworks , NuGet.LibraryModel , NuGet.Packaging , NuGet.ProjectModel , NuGet.Protocol , NuGet.Versioning From Version 6.9.0-rc.74 -> To Version 6.10.0-preview.1.9 From 5bd532c0bdabaf9e1523ce57f45b503db4f8a333 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" Date: Tue, 23 Jan 2024 14:01:38 +0000 Subject: [PATCH 112/577] Update dependencies from https://github.com/microsoft/vstest build 20240122.1 Microsoft.NET.Test.Sdk , Microsoft.TestPlatform.Build , Microsoft.TestPlatform.CLI From Version 17.9.0-release-23627-01 -> To Version 17.10.0-preview-24072-01 --- eng/Version.Details.xml | 12 ++++++------ eng/Versions.props | 6 +++--- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index bfaa8280041b..5b414fc71d39 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -179,18 +179,18 @@ https://github.com/nuget/nuget.client e92be3915309e687044768de38933ac5fc4cb40c - + https://github.com/microsoft/vstest - 53df73d3373e7964f6fb37f4437bda2720a75ef2 + e6c166f6c346b6c60092121419529e2cd9dbbbcc - + https://github.com/microsoft/vstest - 53df73d3373e7964f6fb37f4437bda2720a75ef2 + e6c166f6c346b6c60092121419529e2cd9dbbbcc - + https://github.com/microsoft/vstest - 53df73d3373e7964f6fb37f4437bda2720a75ef2 + e6c166f6c346b6c60092121419529e2cd9dbbbcc https://dev.azure.com/dnceng/internal/_git/dotnet-runtime diff --git a/eng/Versions.props b/eng/Versions.props index 6ccb73aa6592..5f7b211a9639 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -84,9 +84,9 @@ - 17.10.0-preview-24069-04 - 17.10.0-preview-24069-04 - 17.10.0-preview-24069-04 + 17.10.0-preview-24072-01 + 17.10.0-preview-24072-01 + 17.10.0-preview-24072-01 From 565cb9ab50f845e5071133c7d5a06402eec7f4bb Mon Sep 17 00:00:00 2001 From: annie <59816815+JL03-Yue@users.noreply.github.com> Date: Tue, 23 Jan 2024 11:32:02 -0800 Subject: [PATCH 113/577] update runtimeconfig for all commands --- .../ToolPackage/ToolPackageDownloader.cs | 27 ++++++++++--------- 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/src/Cli/dotnet/ToolPackage/ToolPackageDownloader.cs b/src/Cli/dotnet/ToolPackage/ToolPackageDownloader.cs index 12c33edcbb8a..82ee1ea585b1 100644 --- a/src/Cli/dotnet/ToolPackage/ToolPackageDownloader.cs +++ b/src/Cli/dotnet/ToolPackage/ToolPackageDownloader.cs @@ -209,21 +209,24 @@ private static void UpdateRuntimeConfig( ToolPackageInstance toolPackageInstance ) { - var executableFilePath = toolPackageInstance.Commands[0].Executable; - var runtimeConfigFilePath = Path.ChangeExtension(executableFilePath.ToString(), ".runtimeconfig.json"); - - // Update the runtimeconfig.json file - if (File.Exists(runtimeConfigFilePath)) + for (int i = 0; i < toolPackageInstance.Commands.Count; i++) { - string existingJson = File.ReadAllText(runtimeConfigFilePath); + var command = toolPackageInstance.Commands[i]; + var runtimeConfigFilePath = Path.ChangeExtension(command.Executable.Value, ".runtimeconfig.json"); - var jsonObject = JObject.Parse(existingJson); - var runtimeOptions = jsonObject["runtimeOptions"] as JObject; - if (runtimeOptions != null) + // Update the runtimeconfig.json file + if (File.Exists(runtimeConfigFilePath)) { - runtimeOptions["rollForward"] = "Major"; - string updateJson = jsonObject.ToString(); - File.WriteAllText(runtimeConfigFilePath, updateJson); + string existingJson = File.ReadAllText(runtimeConfigFilePath); + + var jsonObject = JObject.Parse(existingJson); + var runtimeOptions = jsonObject["runtimeOptions"] as JObject; + if (runtimeOptions != null) + { + runtimeOptions["rollForward"] = "Major"; + string updateJson = jsonObject.ToString(); + File.WriteAllText(runtimeConfigFilePath, updateJson); + } } } } From 205fa58e08f7c26004971aba47e8e86b206676f5 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Tue, 23 Jan 2024 11:41:39 -0800 Subject: [PATCH 114/577] [release/8.0.3xx] Update dependencies from dotnet/razor (#38196) Co-authored-by: dotnet-maestro[bot] --- eng/Version.Details.xml | 12 ++++++------ eng/Versions.props | 6 +++--- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index a5f84f6ed4b0..135d1c9ee50d 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -277,18 +277,18 @@ https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore 3f1acb59718cadf111a0a796681e3d3509bb3381 - + https://github.com/dotnet/razor - 999b33452cdd3c4ac639e21419f4b34f2999571d + 45a71626e342c0694b2a56d856cda5498cd0d6e4 - + https://github.com/dotnet/razor - 999b33452cdd3c4ac639e21419f4b34f2999571d + 45a71626e342c0694b2a56d856cda5498cd0d6e4 - + https://github.com/dotnet/razor - 999b33452cdd3c4ac639e21419f4b34f2999571d + 45a71626e342c0694b2a56d856cda5498cd0d6e4 https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore diff --git a/eng/Versions.props b/eng/Versions.props index a94664571c8f..391daa639cab 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -161,9 +161,9 @@ - 7.0.0-preview.24069.1 - 7.0.0-preview.24069.1 - 7.0.0-preview.24069.1 + 7.0.0-preview.24072.2 + 7.0.0-preview.24072.2 + 7.0.0-preview.24072.2 From 31a989319810e1a861b20b8bf1b9ca5903717571 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Tue, 23 Jan 2024 11:42:01 -0800 Subject: [PATCH 115/577] [release/8.0.3xx] Update dependencies from dotnet/msbuild (#38195) Co-authored-by: dotnet-maestro[bot] --- eng/Version.Details.xml | 12 ++++++------ eng/Versions.props | 4 ++-- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 135d1c9ee50d..4769ed7e755f 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -51,17 +51,17 @@ https://github.com/dotnet/emsdk 2406616d0e3a31d80b326e27c156955bfa41c791 - + https://github.com/dotnet/msbuild - 6d97976719d4aefae595ee919b942da452e97e57 + f0936bf4b63d97a87e163fb1cb204e447550bcae - + https://github.com/dotnet/msbuild - 6d97976719d4aefae595ee919b942da452e97e57 + f0936bf4b63d97a87e163fb1cb204e447550bcae - + https://github.com/dotnet/msbuild - 6d97976719d4aefae595ee919b942da452e97e57 + f0936bf4b63d97a87e163fb1cb204e447550bcae diff --git a/eng/Versions.props b/eng/Versions.props index 391daa639cab..7119cbe3fb83 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -106,7 +106,7 @@ - 17.10.0-preview-24069-03 + 17.10.0-preview-24073-01 $(MicrosoftBuildPackageVersion) - 6.10.0-preview.1.9 - 6.10.0-preview.1.9 + 6.10.0-preview.1.12 + 6.10.0-preview.1.12 6.0.0-rc.278 - 6.10.0-preview.1.9 - 6.10.0-preview.1.9 - 6.10.0-preview.1.9 - 6.10.0-preview.1.9 - 6.10.0-preview.1.9 - 6.10.0-preview.1.9 - 6.10.0-preview.1.9 - 6.10.0-preview.1.9 - 6.10.0-preview.1.9 + 6.10.0-preview.1.12 + 6.10.0-preview.1.12 + 6.10.0-preview.1.12 + 6.10.0-preview.1.12 + 6.10.0-preview.1.12 + 6.10.0-preview.1.12 + 6.10.0-preview.1.12 + 6.10.0-preview.1.12 + 6.10.0-preview.1.12 $(NuGetPackagingPackageVersion) $(NuGetProjectModelPackageVersion) From f9007480df2760573549ca6c4ddf6a84f5dba85e Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" Date: Wed, 24 Jan 2024 14:03:59 +0000 Subject: [PATCH 120/577] Update dependencies from https://github.com/dotnet/msbuild build 20240123.2 Microsoft.SourceBuild.Intermediate.msbuild , Microsoft.Build , Microsoft.Build.Localization From Version 17.10.0-preview-24073-01 -> To Version 17.10.0-preview-24073-02 --- eng/Version.Details.xml | 12 ++++++------ eng/Versions.props | 4 ++-- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 4769ed7e755f..d9b460d39ae1 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -51,17 +51,17 @@ https://github.com/dotnet/emsdk 2406616d0e3a31d80b326e27c156955bfa41c791 - + https://github.com/dotnet/msbuild - f0936bf4b63d97a87e163fb1cb204e447550bcae + d51ae5297cd0a24caa8cfe356442cc8634c3f087 - + https://github.com/dotnet/msbuild - f0936bf4b63d97a87e163fb1cb204e447550bcae + d51ae5297cd0a24caa8cfe356442cc8634c3f087 - + https://github.com/dotnet/msbuild - f0936bf4b63d97a87e163fb1cb204e447550bcae + d51ae5297cd0a24caa8cfe356442cc8634c3f087 diff --git a/eng/Versions.props b/eng/Versions.props index 7119cbe3fb83..53895953b2e4 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -106,7 +106,7 @@ - 17.10.0-preview-24073-01 + 17.10.0-preview-24073-02 $(MicrosoftBuildPackageVersion) - 17.10.0-preview-24072-01 - 17.10.0-preview-24072-01 - 17.10.0-preview-24072-01 + 17.10.0-preview-24073-02 + 17.10.0-preview-24073-02 + 17.10.0-preview-24073-02 From e991fc864e3691230fa4c4b2a94c593749340632 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" Date: Wed, 24 Jan 2024 14:05:15 +0000 Subject: [PATCH 122/577] Update dependencies from https://github.com/dotnet/razor build 20240124.1 Microsoft.AspNetCore.Mvc.Razor.Extensions.Tooling.Internal , Microsoft.CodeAnalysis.Razor.Tooling.Internal , Microsoft.NET.Sdk.Razor.SourceGenerators.Transport From Version 7.0.0-preview.24072.2 -> To Version 7.0.0-preview.24074.1 --- eng/Version.Details.xml | 12 ++++++------ eng/Versions.props | 6 +++--- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 4769ed7e755f..a5f8df261e67 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -277,18 +277,18 @@ https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore 3f1acb59718cadf111a0a796681e3d3509bb3381 - + https://github.com/dotnet/razor - 45a71626e342c0694b2a56d856cda5498cd0d6e4 + c8adb2660fb4aca398fe4151435f92d0a113369f - + https://github.com/dotnet/razor - 45a71626e342c0694b2a56d856cda5498cd0d6e4 + c8adb2660fb4aca398fe4151435f92d0a113369f - + https://github.com/dotnet/razor - 45a71626e342c0694b2a56d856cda5498cd0d6e4 + c8adb2660fb4aca398fe4151435f92d0a113369f https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore diff --git a/eng/Versions.props b/eng/Versions.props index 7119cbe3fb83..abacf91420f1 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -161,9 +161,9 @@ - 7.0.0-preview.24072.2 - 7.0.0-preview.24072.2 - 7.0.0-preview.24072.2 + 7.0.0-preview.24074.1 + 7.0.0-preview.24074.1 + 7.0.0-preview.24074.1 From 24c5c70eb8250db96d2545b85181fc6075f49ac7 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" Date: Wed, 24 Jan 2024 14:10:19 +0000 Subject: [PATCH 123/577] Update dependencies from https://github.com/dotnet/arcade build 20240124.2 Microsoft.DotNet.Arcade.Sdk , Microsoft.DotNet.Helix.Sdk , Microsoft.DotNet.SignTool , Microsoft.DotNet.XUnitExtensions From Version 8.0.0-beta.24060.4 -> To Version 8.0.0-beta.24074.2 --- eng/Version.Details.xml | 16 ++++++++-------- eng/Versions.props | 4 ++-- global.json | 4 ++-- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 4769ed7e755f..c35c49803f9c 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -411,22 +411,22 @@ - + https://github.com/dotnet/arcade - 888985fb9a9ae4cb30bca75f98af9126c839e660 + 96c2cee493aa1542c0b06a6498e0379eb11e005f - + https://github.com/dotnet/arcade - 888985fb9a9ae4cb30bca75f98af9126c839e660 + 96c2cee493aa1542c0b06a6498e0379eb11e005f - + https://github.com/dotnet/arcade - 888985fb9a9ae4cb30bca75f98af9126c839e660 + 96c2cee493aa1542c0b06a6498e0379eb11e005f - + https://github.com/dotnet/arcade - 888985fb9a9ae4cb30bca75f98af9126c839e660 + 96c2cee493aa1542c0b06a6498e0379eb11e005f https://dev.azure.com/dnceng/internal/_git/dotnet-runtime diff --git a/eng/Versions.props b/eng/Versions.props index 7119cbe3fb83..9afae5daf5dc 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -35,7 +35,7 @@ 7.0.0 4.0.0 7.0.0 - 8.0.0-beta.24060.4 + 8.0.0-beta.24074.2 7.0.0-preview.22423.2 8.0.0 4.3.0 @@ -195,7 +195,7 @@ 6.12.0 6.1.0 - 8.0.0-beta.24060.4 + 8.0.0-beta.24074.2 4.18.4 1.3.2 8.0.0-beta.23607.1 diff --git a/global.json b/global.json index 97173728d0ce..3a79a4ae9a72 100644 --- a/global.json +++ b/global.json @@ -14,7 +14,7 @@ } }, "msbuild-sdks": { - "Microsoft.DotNet.Arcade.Sdk": "8.0.0-beta.24060.4", - "Microsoft.DotNet.Helix.Sdk": "8.0.0-beta.24060.4" + "Microsoft.DotNet.Arcade.Sdk": "8.0.0-beta.24074.2", + "Microsoft.DotNet.Helix.Sdk": "8.0.0-beta.24074.2" } } From 6167e9a62a5200f5ee4962c829a3b76dd65a9907 Mon Sep 17 00:00:00 2001 From: annie <59816815+JL03-Yue@users.noreply.github.com> Date: Thu, 25 Jan 2024 00:47:25 -0800 Subject: [PATCH 124/577] update the logic detection fo --allow-roll-forward and improve coding style --- .../LocalToolsCommandResolver.cs | 2 +- .../MuxerCommandSpecMaker.cs | 23 +++++++++++++------ .../ToolPackage/ToolPackageDownloader.cs | 3 +-- 3 files changed, 18 insertions(+), 10 deletions(-) diff --git a/src/Cli/dotnet/CommandFactory/CommandResolution/LocalToolsCommandResolver.cs b/src/Cli/dotnet/CommandFactory/CommandResolution/LocalToolsCommandResolver.cs index d31feaf6f88f..524ea1eb0d04 100644 --- a/src/Cli/dotnet/CommandFactory/CommandResolution/LocalToolsCommandResolver.cs +++ b/src/Cli/dotnet/CommandFactory/CommandResolution/LocalToolsCommandResolver.cs @@ -98,7 +98,7 @@ private CommandSpec GetPackageCommandSpecUsingMuxer(CommandResolverArguments arg if (toolManifestPackage.RollForward || allowRollForward) { - arguments.CommandArguments = ["--roll-forward", "Major", .. arguments.CommandArguments]; + arguments.CommandArguments = ["--allow-roll-forward", .. arguments.CommandArguments]; } return MuxerCommandSpecMaker.CreatePackageCommandSpecUsingMuxer( diff --git a/src/Cli/dotnet/CommandFactory/CommandResolution/MuxerCommandSpecMaker.cs b/src/Cli/dotnet/CommandFactory/CommandResolution/MuxerCommandSpecMaker.cs index d71a840c2d20..2d55577acf7f 100644 --- a/src/Cli/dotnet/CommandFactory/CommandResolution/MuxerCommandSpecMaker.cs +++ b/src/Cli/dotnet/CommandFactory/CommandResolution/MuxerCommandSpecMaker.cs @@ -11,7 +11,10 @@ internal static CommandSpec CreatePackageCommandSpecUsingMuxer( string commandPath, IEnumerable commandArguments) { + var arguments = new List(); + var muxer = new Muxer(); + var host = muxer.MuxerPath; if (host == null) @@ -19,15 +22,21 @@ internal static CommandSpec CreatePackageCommandSpecUsingMuxer( throw new Exception(LocalizableStrings.UnableToLocateDotnetMultiplexer); } - var previousArg = string.Empty; + var rollForwardArgument = (commandArguments ?? []).Where(arg => arg.Equals("--allow-roll-forward", StringComparison.OrdinalIgnoreCase)); + + if (rollForwardArgument.Any()) + { + arguments.Add("--roll-forward"); + arguments.Add("Major"); + } + + arguments.Add(commandPath); - // Group the arguments by if the previous argument or the current argument is --roll-forward. - var argGroups = (commandArguments ?? []) - .GroupBy(a => previousArg.Equals("--roll-forward", StringComparison.OrdinalIgnoreCase) - | (previousArg = a).Equals("--roll-forward", StringComparison.OrdinalIgnoreCase)) - .ToArray(); + if (commandArguments != null) + { + arguments.AddRange(commandArguments.Except(rollForwardArgument)); + } - string[] arguments = [..argGroups.Where(g => g.Key).SelectMany(g => g), commandPath, .. argGroups.Where(g => !g.Key).SelectMany(g => g)]; return CreateCommandSpec(host, arguments); } diff --git a/src/Cli/dotnet/ToolPackage/ToolPackageDownloader.cs b/src/Cli/dotnet/ToolPackage/ToolPackageDownloader.cs index 82ee1ea585b1..37f9fde52cb2 100644 --- a/src/Cli/dotnet/ToolPackage/ToolPackageDownloader.cs +++ b/src/Cli/dotnet/ToolPackage/ToolPackageDownloader.cs @@ -209,9 +209,8 @@ private static void UpdateRuntimeConfig( ToolPackageInstance toolPackageInstance ) { - for (int i = 0; i < toolPackageInstance.Commands.Count; i++) + foreach (var command in toolPackageInstance.Commands) { - var command = toolPackageInstance.Commands[i]; var runtimeConfigFilePath = Path.ChangeExtension(command.Executable.Value, ".runtimeconfig.json"); // Update the runtimeconfig.json file From b784fed4cd16d2ad36d6a3e9bd0d5a798b478aeb Mon Sep 17 00:00:00 2001 From: annie <59816815+JL03-Yue@users.noreply.github.com> Date: Thu, 25 Jan 2024 01:14:06 -0800 Subject: [PATCH 125/577] fixed tests --- .../CommandTests/ToolRunCommandTests.cs | 21 ++++++++++--------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/src/Tests/dotnet.Tests/CommandTests/ToolRunCommandTests.cs b/src/Tests/dotnet.Tests/CommandTests/ToolRunCommandTests.cs index ada4bab06ba9..61c3491ef035 100644 --- a/src/Tests/dotnet.Tests/CommandTests/ToolRunCommandTests.cs +++ b/src/Tests/dotnet.Tests/CommandTests/ToolRunCommandTests.cs @@ -28,18 +28,18 @@ public ToolRunCommandTests(ITestOutputHelper log) : base(log) [Fact] public void WhenRunWithRollForwardOptionItShouldIncludeRollForwardInNativeHost() { - var parseResult = Parser.Instance.Parse($"dotnet tool run $TOOLCOMMAND$ --allow-roll-forward"); + var parseResult = Parser.Instance.Parse($"dotnet tool run dotnet-a --allow-roll-forward"); var toolRunCommand = new ToolRunCommand(parseResult); - (FilePath fakeExecutable, LocalToolsCommandResolver localToolsCommandResolver) = DefaultSetup("dotnet-a"); + (FilePath fakeExecutable, LocalToolsCommandResolver localToolsCommandResolver) = DefaultSetup("a"); IEnumerable testForwardArgument = Enumerable.Empty(); - var result = localToolsCommandResolver.Resolve(new CommandResolverArguments() + var result = localToolsCommandResolver.ResolveStrict(new CommandResolverArguments() { CommandName = "dotnet-a", - CommandArguments = (toolRunCommand._allowRollForward != false ? new List { "--roll-forward", "Major" } : Enumerable.Empty()).Concat(testForwardArgument) - }); + CommandArguments = testForwardArgument + }, toolRunCommand._allowRollForward); result.Should().NotBeNull(); result.Args.Should().Contain("--roll-forward", "Major", fakeExecutable.Value); @@ -48,21 +48,22 @@ public void WhenRunWithRollForwardOptionItShouldIncludeRollForwardInNativeHost() [Fact] public void WhenRunWithoutRollForwardOptionItShouldNotIncludeRollForwardInNativeHost() { - var parseResult = Parser.Instance.Parse($"dotnet tool run $TOOLCOMMAND$"); + var parseResult = Parser.Instance.Parse($"dotnet tool run dotnet-a"); var toolRunCommand = new ToolRunCommand(parseResult); - (FilePath fakeExecutable, LocalToolsCommandResolver localToolsCommandResolver) = DefaultSetup("dotnet-a"); + (FilePath fakeExecutable, LocalToolsCommandResolver localToolsCommandResolver) = DefaultSetup("a"); IEnumerable testForwardArgument = Enumerable.Empty(); - var result = localToolsCommandResolver.Resolve(new CommandResolverArguments() + var result = localToolsCommandResolver.ResolveStrict(new CommandResolverArguments() { CommandName = "dotnet-a", - CommandArguments = (toolRunCommand._allowRollForward != false ? new List { "--roll-forward", "Major" } : Enumerable.Empty()).Concat(testForwardArgument) - }); + CommandArguments = testForwardArgument + }, toolRunCommand._allowRollForward); result.Should().NotBeNull(); result.Args.Should().Contain(fakeExecutable.Value); + result.Args.Should().NotContain("--roll-forward", "Major"); } private (FilePath, LocalToolsCommandResolver) DefaultSetup(string toolCommand) From d9c6d235064f7654abc7ac9f1d666bc1f3f22082 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" Date: Thu, 25 Jan 2024 13:59:10 +0000 Subject: [PATCH 126/577] Update dependencies from https://github.com/microsoft/vstest build 20240123.2 Microsoft.NET.Test.Sdk , Microsoft.TestPlatform.Build , Microsoft.TestPlatform.CLI From Version 17.9.0-release-23627-01 -> To Version 17.10.0-preview-24073-02 From ec70e2d765a8a546a153317d10b9677e6aed80e3 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" Date: Thu, 25 Jan 2024 13:59:52 +0000 Subject: [PATCH 127/577] Update dependencies from https://github.com/dotnet/razor build 20240124.5 Microsoft.AspNetCore.Mvc.Razor.Extensions.Tooling.Internal , Microsoft.CodeAnalysis.Razor.Tooling.Internal , Microsoft.NET.Sdk.Razor.SourceGenerators.Transport From Version 7.0.0-preview.24074.1 -> To Version 7.0.0-preview.24074.5 --- eng/Version.Details.xml | 12 ++++++------ eng/Versions.props | 6 +++--- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 8e7afa4cc4f8..179ceb55d1ae 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -277,18 +277,18 @@ https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore 3f1acb59718cadf111a0a796681e3d3509bb3381 - + https://github.com/dotnet/razor - c8adb2660fb4aca398fe4151435f92d0a113369f + 00a9bb181a4028e7fff09d989c5540cff677e411 - + https://github.com/dotnet/razor - c8adb2660fb4aca398fe4151435f92d0a113369f + 00a9bb181a4028e7fff09d989c5540cff677e411 - + https://github.com/dotnet/razor - c8adb2660fb4aca398fe4151435f92d0a113369f + 00a9bb181a4028e7fff09d989c5540cff677e411 https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore diff --git a/eng/Versions.props b/eng/Versions.props index e76c4b980e44..3ccee9a81355 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -161,9 +161,9 @@ - 7.0.0-preview.24074.1 - 7.0.0-preview.24074.1 - 7.0.0-preview.24074.1 + 7.0.0-preview.24074.5 + 7.0.0-preview.24074.5 + 7.0.0-preview.24074.5 From ec6f1420fdd732aa27c30a2e78a55a6997c6703f Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Thu, 25 Jan 2024 18:09:17 +0000 Subject: [PATCH 128/577] [release/8.0.3xx] Update dependencies from dotnet/templating (#38263) [release/8.0.3xx] Update dependencies from dotnet/templating --- eng/Version.Details.xml | 8 ++++---- eng/Versions.props | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 8e7afa4cc4f8..a9fae932a17f 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -1,14 +1,14 @@ - + https://github.com/dotnet/templating - 563930b1d9ad60c8d7dbd1975390f5870601defa + 8ead8596ce97dcf6464354f6819da5baddf1b609 - + https://github.com/dotnet/templating - 563930b1d9ad60c8d7dbd1975390f5870601defa + 8ead8596ce97dcf6464354f6819da5baddf1b609 https://dev.azure.com/dnceng/internal/_git/dotnet-runtime diff --git a/eng/Versions.props b/eng/Versions.props index e76c4b980e44..7641dce30195 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -123,13 +123,13 @@ - 8.0.200-preview.24060.12 + 8.0.300-preview.24074.2 $(MicrosoftTemplateEngineAbstractionsPackageVersion) $(MicrosoftTemplateEngineAbstractionsPackageVersion) $(MicrosoftTemplateEngineAbstractionsPackageVersion) $(MicrosoftTemplateEngineAbstractionsPackageVersion) - 8.0.200-preview.24060.12 + 8.0.300-preview.24074.2 $(MicrosoftTemplateEngineMocksPackageVersion) $(MicrosoftTemplateEngineAbstractionsPackageVersion) $(MicrosoftTemplateEngineMocksPackageVersion) From 2ba007be02aee40728511ccd323de0a17718971f Mon Sep 17 00:00:00 2001 From: annie <59816815+JL03-Yue@users.noreply.github.com> Date: Thu, 25 Jan 2024 14:17:33 -0800 Subject: [PATCH 129/577] fix tests --- .../MuxerCommandSpecMaker.cs | 22 +++++++++++-------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/src/Cli/dotnet/CommandFactory/CommandResolution/MuxerCommandSpecMaker.cs b/src/Cli/dotnet/CommandFactory/CommandResolution/MuxerCommandSpecMaker.cs index 2d55577acf7f..7ed92869267a 100644 --- a/src/Cli/dotnet/CommandFactory/CommandResolution/MuxerCommandSpecMaker.cs +++ b/src/Cli/dotnet/CommandFactory/CommandResolution/MuxerCommandSpecMaker.cs @@ -22,20 +22,24 @@ internal static CommandSpec CreatePackageCommandSpecUsingMuxer( throw new Exception(LocalizableStrings.UnableToLocateDotnetMultiplexer); } - var rollForwardArgument = (commandArguments ?? []).Where(arg => arg.Equals("--allow-roll-forward", StringComparison.OrdinalIgnoreCase)); - - if (rollForwardArgument.Any()) + if (commandArguments != null) { - arguments.Add("--roll-forward"); - arguments.Add("Major"); - } + var rollForwardArgument = (commandArguments ?? Enumerable.Empty()).Where(arg => arg.Equals("--allow-roll-forward", StringComparison.OrdinalIgnoreCase)); - arguments.Add(commandPath); + if (rollForwardArgument.Any()) + { + arguments.Add("--roll-forward"); + arguments.Add("Major"); + } + + arguments.Add(commandPath); - if (commandArguments != null) - { arguments.AddRange(commandArguments.Except(rollForwardArgument)); } + else + { + arguments.Add(commandPath); + } return CreateCommandSpec(host, arguments); } From 892811c65aa4fb4306e66baf0af4d04b3caf8261 Mon Sep 17 00:00:00 2001 From: annie <59816815+JL03-Yue@users.noreply.github.com> Date: Thu, 25 Jan 2024 15:58:33 -0800 Subject: [PATCH 130/577] fix tests --- .../MuxerCommandSpecMaker.cs | 29 ++++++++++--------- 1 file changed, 16 insertions(+), 13 deletions(-) diff --git a/src/Cli/dotnet/CommandFactory/CommandResolution/MuxerCommandSpecMaker.cs b/src/Cli/dotnet/CommandFactory/CommandResolution/MuxerCommandSpecMaker.cs index 7ed92869267a..509afbbb138b 100644 --- a/src/Cli/dotnet/CommandFactory/CommandResolution/MuxerCommandSpecMaker.cs +++ b/src/Cli/dotnet/CommandFactory/CommandResolution/MuxerCommandSpecMaker.cs @@ -1,6 +1,7 @@ // 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.Eventing.Reader; using Microsoft.DotNet.Cli.Utils; namespace Microsoft.DotNet.CommandFactory @@ -22,25 +23,27 @@ internal static CommandSpec CreatePackageCommandSpecUsingMuxer( throw new Exception(LocalizableStrings.UnableToLocateDotnetMultiplexer); } - if (commandArguments != null) + var rollForwardArgument = (commandArguments ?? Enumerable.Empty()).Where(arg => arg.Equals("--allow-roll-forward", StringComparison.OrdinalIgnoreCase)); + + if (rollForwardArgument.Any()) { - var rollForwardArgument = (commandArguments ?? Enumerable.Empty()).Where(arg => arg.Equals("--allow-roll-forward", StringComparison.OrdinalIgnoreCase)); + arguments.Add("--roll-forward"); + arguments.Add("Major"); + } + + arguments.Add(commandPath); + if (commandArguments != null) + { if (rollForwardArgument.Any()) { - arguments.Add("--roll-forward"); - arguments.Add("Major"); + arguments.AddRange(commandArguments.Except(rollForwardArgument)); + } + else + { + arguments.AddRange(commandArguments); } - - arguments.Add(commandPath); - - arguments.AddRange(commandArguments.Except(rollForwardArgument)); - } - else - { - arguments.Add(commandPath); } - return CreateCommandSpec(host, arguments); } From 9b3fc2a64d274a031a85f911762fe29fb8db1a22 Mon Sep 17 00:00:00 2001 From: Mark Li Date: Thu, 25 Jan 2024 11:56:23 -0800 Subject: [PATCH 131/577] fix verbosity --- src/Cli/dotnet/CommonOptions.cs | 4 ++-- .../NuGetPackageDownloader.cs | 18 ++++++++++----- .../ToolPackage/ToolPackageDownloader.cs | 2 +- .../ToolInstallGlobalOrToolPathCommand.cs | 2 +- .../NuGetPackageInstallerTests.cs | 22 +++++++++++++++++++ 5 files changed, 38 insertions(+), 10 deletions(-) diff --git a/src/Cli/dotnet/CommonOptions.cs b/src/Cli/dotnet/CommonOptions.cs index a11b13c4476c..78ecc5dd31e8 100644 --- a/src/Cli/dotnet/CommonOptions.cs +++ b/src/Cli/dotnet/CommonOptions.cs @@ -281,10 +281,10 @@ internal static CliArgument AddCompletions(this CliArgument argument, F public enum VerbosityOptions { - quiet, - q, minimal, m, + quiet, + q, normal, n, detailed, diff --git a/src/Cli/dotnet/NugetPackageDownloader/NuGetPackageDownloader.cs b/src/Cli/dotnet/NugetPackageDownloader/NuGetPackageDownloader.cs index 933f561d985c..dba4ebe5df8a 100644 --- a/src/Cli/dotnet/NugetPackageDownloader/NuGetPackageDownloader.cs +++ b/src/Cli/dotnet/NugetPackageDownloader/NuGetPackageDownloader.cs @@ -42,6 +42,7 @@ internal class NuGetPackageDownloader : INuGetPackageDownloader private readonly bool _isNuGetTool; private bool _verifySignatures; + private VerbosityOptions _verbosityOptions; public NuGetPackageDownloader( DirectoryPath packageInstallDir, @@ -52,7 +53,8 @@ public NuGetPackageDownloader( RestoreActionConfig restoreActionConfig = null, Func> timer = null, bool verifySignatures = false, - bool isNuGetTool = false) + bool isNuGetTool = false, + VerbosityOptions verbosityOptions = VerbosityOptions.minimal) { _packageInstallDir = packageInstallDir; _reporter = reporter ?? Reporter.Output; @@ -75,6 +77,7 @@ public NuGetPackageDownloader( DefaultCredentialServiceUtility.SetupDefaultCredentialService(new NuGetConsoleLogger(), !_restoreActionConfig.Interactive); _isNuGetTool = isNuGetTool; + _verbosityOptions = verbosityOptions; } public async Task DownloadPackageAsync(PackageId packageId, @@ -134,15 +137,18 @@ public async Task DownloadPackageAsync(PackageId packageId, private void VerifySigning(string nupkgPath) { - if (!_verifySignatures) + + if (!_verifySignatures && !_validationMessagesDisplayed) { - if (!_validationMessagesDisplayed) + if (_verbosityOptions != VerbosityOptions.quiet && _verbosityOptions != VerbosityOptions.q) { - _reporter.WriteLine( - LocalizableStrings.NuGetPackageSignatureVerificationSkipped); - _validationMessagesDisplayed = true; + _reporter.WriteLine(LocalizableStrings.NuGetPackageSignatureVerificationSkipped); } + _validationMessagesDisplayed = true; + } + if (!_verifySignatures) + { return; } diff --git a/src/Cli/dotnet/ToolPackage/ToolPackageDownloader.cs b/src/Cli/dotnet/ToolPackage/ToolPackageDownloader.cs index be97e3937ab0..87e5131a8e39 100644 --- a/src/Cli/dotnet/ToolPackage/ToolPackageDownloader.cs +++ b/src/Cli/dotnet/ToolPackage/ToolPackageDownloader.cs @@ -95,7 +95,7 @@ public IToolPackage InstallPackage(PackageLocation packageLocation, PackageId pa var toolDownloadDir = isGlobalTool ? _globalToolStageDir : _localToolDownloadDir; var assetFileDirectory = isGlobalTool ? _globalToolStageDir : _localToolAssetDir; - var nugetPackageDownloader = new NuGetPackageDownloader.NuGetPackageDownloader(toolDownloadDir, verboseLogger: nugetLogger, isNuGetTool: true); + var nugetPackageDownloader = new NuGetPackageDownloader.NuGetPackageDownloader(toolDownloadDir, verboseLogger: nugetLogger, isNuGetTool: true, verbosityOptions: verbosity); var packageSourceLocation = new PackageSourceLocation(packageLocation.NugetConfig, packageLocation.RootConfigDirectory, null, packageLocation.AdditionalFeeds); diff --git a/src/Cli/dotnet/commands/dotnet-tool/install/ToolInstallGlobalOrToolPathCommand.cs b/src/Cli/dotnet/commands/dotnet-tool/install/ToolInstallGlobalOrToolPathCommand.cs index e722b6af6c5e..2786f22de8f1 100644 --- a/src/Cli/dotnet/commands/dotnet-tool/install/ToolInstallGlobalOrToolPathCommand.cs +++ b/src/Cli/dotnet/commands/dotnet-tool/install/ToolInstallGlobalOrToolPathCommand.cs @@ -79,7 +79,7 @@ public ToolInstallGlobalOrToolPathCommand( NoCache: parseResult.GetValue(ToolCommandRestorePassThroughOptions.NoCacheOption), IgnoreFailedSources: parseResult.GetValue(ToolCommandRestorePassThroughOptions.IgnoreFailedSourcesOption), Interactive: parseResult.GetValue(ToolCommandRestorePassThroughOptions.InteractiveRestoreOption)); - nugetPackageDownloader ??= new NuGetPackageDownloader(tempDir, verboseLogger: new NullLogger(), restoreActionConfig: restoreAction); + nugetPackageDownloader ??= new NuGetPackageDownloader(tempDir, verboseLogger: new NullLogger(), restoreActionConfig: restoreAction, verbosityOptions: _verbosity); _shellShimTemplateFinder = new ShellShimTemplateFinder(nugetPackageDownloader, tempDir, packageSourceLocation); _allowPackageDowngrade = parseResult.GetValue(ToolInstallCommandParser.AllowPackageDowngradeOption); _createToolPackageStoreDownloaderUninstaller = createToolPackageStoreDownloaderUninstaller ?? diff --git a/src/Tests/Microsoft.DotNet.PackageInstall.Tests/NuGetPackageInstallerTests.cs b/src/Tests/Microsoft.DotNet.PackageInstall.Tests/NuGetPackageInstallerTests.cs index cb6847476a02..dfac631f34c2 100644 --- a/src/Tests/Microsoft.DotNet.PackageInstall.Tests/NuGetPackageInstallerTests.cs +++ b/src/Tests/Microsoft.DotNet.PackageInstall.Tests/NuGetPackageInstallerTests.cs @@ -247,6 +247,28 @@ await nuGetPackageDownloader.DownloadPackageAsync( File.Exists(packagePath).Should().BeTrue(); } + [WindowsOnlyFact] + public async Task GivenANonSignedSdkItShouldNotPrintMessageInQuiet() + { + BufferedReporter bufferedReporter = new BufferedReporter(); + NuGetPackageDownloader nuGetPackageDownloader = new NuGetPackageDownloader(_tempDirectory, null, + new MockFirstPartyNuGetPackageSigningVerifier(), + _logger, bufferedReporter, restoreActionConfig: new RestoreActionConfig(NoCache: true), verbosityOptions: VerbosityOptions.quiet); + await nuGetPackageDownloader.DownloadPackageAsync( + TestPackageId, + new NuGetVersion(TestPackageVersion), + new PackageSourceLocation(sourceFeedOverrides: new[] { GetTestLocalFeedPath() })); + + // download 2 packages should only print the message once + string packagePath = await nuGetPackageDownloader.DownloadPackageAsync( + TestPackageId, + new NuGetVersion(TestPackageVersion), + new PackageSourceLocation(sourceFeedOverrides: new[] { GetTestLocalFeedPath() })); + + bufferedReporter.Lines.Should().BeEmpty(); + File.Exists(packagePath).Should().BeTrue(); + } + [WindowsOnlyFact] public async Task WhenCalledWithNotSignedPackageItShouldThrowWithCommandOutput() { From 337d1cc6f475c3e9337c0070565cf27968290cd3 Mon Sep 17 00:00:00 2001 From: Mark Li Date: Thu, 25 Jan 2024 15:15:18 -0800 Subject: [PATCH 132/577] update printing minimal verbosity --- .../NugetPackageDownloader/NuGetPackageDownloader.cs | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/Cli/dotnet/NugetPackageDownloader/NuGetPackageDownloader.cs b/src/Cli/dotnet/NugetPackageDownloader/NuGetPackageDownloader.cs index dba4ebe5df8a..3bc31808eace 100644 --- a/src/Cli/dotnet/NugetPackageDownloader/NuGetPackageDownloader.cs +++ b/src/Cli/dotnet/NugetPackageDownloader/NuGetPackageDownloader.cs @@ -54,7 +54,7 @@ public NuGetPackageDownloader( Func> timer = null, bool verifySignatures = false, bool isNuGetTool = false, - VerbosityOptions verbosityOptions = VerbosityOptions.minimal) + VerbosityOptions verbosityOptions = VerbosityOptions.normal) { _packageInstallDir = packageInstallDir; _reporter = reporter ?? Reporter.Output; @@ -135,12 +135,17 @@ public async Task DownloadPackageAsync(PackageId packageId, return nupkgPath; } - private void VerifySigning(string nupkgPath) + private bool verbosityGreaterThanMinimal() { + return _verbosityOptions != VerbosityOptions.quiet && _verbosityOptions != VerbosityOptions.q + && _verbosityOptions != VerbosityOptions.minimal && _verbosityOptions != VerbosityOptions.m; + } + private void VerifySigning(string nupkgPath) + { if (!_verifySignatures && !_validationMessagesDisplayed) { - if (_verbosityOptions != VerbosityOptions.quiet && _verbosityOptions != VerbosityOptions.q) + if (verbosityGreaterThanMinimal()) { _reporter.WriteLine(LocalizableStrings.NuGetPackageSignatureVerificationSkipped); } From 8854f8d2643403a223092c319b1e277016d2418a Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" Date: Fri, 26 Jan 2024 13:56:26 +0000 Subject: [PATCH 133/577] Update dependencies from https://github.com/dotnet/msbuild build 20240126.1 Microsoft.SourceBuild.Intermediate.msbuild , Microsoft.Build , Microsoft.Build.Localization From Version 17.10.0-preview-24073-02 -> To Version 17.10.0-preview-24076-01 --- eng/Version.Details.xml | 12 ++++++------ eng/Versions.props | 4 ++-- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index fb55fcf61577..4d3576a4960d 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -51,17 +51,17 @@ https://github.com/dotnet/emsdk 2406616d0e3a31d80b326e27c156955bfa41c791 - + https://github.com/dotnet/msbuild - d51ae5297cd0a24caa8cfe356442cc8634c3f087 + e7a44d757e097eb17dcac5a8436645dc612fec4b - + https://github.com/dotnet/msbuild - d51ae5297cd0a24caa8cfe356442cc8634c3f087 + e7a44d757e097eb17dcac5a8436645dc612fec4b - + https://github.com/dotnet/msbuild - d51ae5297cd0a24caa8cfe356442cc8634c3f087 + e7a44d757e097eb17dcac5a8436645dc612fec4b diff --git a/eng/Versions.props b/eng/Versions.props index a72e7e86cdba..6a485a8dcb54 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -106,7 +106,7 @@ - 17.10.0-preview-24073-02 + 17.10.0-preview-24076-01 $(MicrosoftBuildPackageVersion) - 12.8.300-beta.24066.3 + 12.8.300-beta.24075.4 From 17c7a9e75ea5dcfbe73ab00bb8673cb45fb767d7 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" Date: Fri, 26 Jan 2024 13:57:26 +0000 Subject: [PATCH 136/577] Update dependencies from https://github.com/dotnet/razor build 20240126.1 Microsoft.AspNetCore.Mvc.Razor.Extensions.Tooling.Internal , Microsoft.CodeAnalysis.Razor.Tooling.Internal , Microsoft.NET.Sdk.Razor.SourceGenerators.Transport From Version 7.0.0-preview.24074.5 -> To Version 7.0.0-preview.24076.1 --- eng/Version.Details.xml | 12 ++++++------ eng/Versions.props | 6 +++--- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index fb55fcf61577..e8ea46e9a85b 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -277,18 +277,18 @@ https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore 3f1acb59718cadf111a0a796681e3d3509bb3381 - + https://github.com/dotnet/razor - 00a9bb181a4028e7fff09d989c5540cff677e411 + 46a1c23286c5eedd38fe2c071c50d703a26f582b - + https://github.com/dotnet/razor - 00a9bb181a4028e7fff09d989c5540cff677e411 + 46a1c23286c5eedd38fe2c071c50d703a26f582b - + https://github.com/dotnet/razor - 00a9bb181a4028e7fff09d989c5540cff677e411 + 46a1c23286c5eedd38fe2c071c50d703a26f582b https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore diff --git a/eng/Versions.props b/eng/Versions.props index a72e7e86cdba..a5a4caaf4703 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -161,9 +161,9 @@ - 7.0.0-preview.24074.5 - 7.0.0-preview.24074.5 - 7.0.0-preview.24074.5 + 7.0.0-preview.24076.1 + 7.0.0-preview.24076.1 + 7.0.0-preview.24076.1 From b9301f19ffd510fc3e177b4c6a2a81ed2f80c43c Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" Date: Sat, 27 Jan 2024 14:01:03 +0000 Subject: [PATCH 137/577] Update dependencies from https://github.com/dotnet/msbuild build 20240126.3 Microsoft.SourceBuild.Intermediate.msbuild , Microsoft.Build , Microsoft.Build.Localization From Version 17.10.0-preview-24076-01 -> To Version 17.10.0-preview-24076-03 --- eng/Version.Details.xml | 12 ++++++------ eng/Versions.props | 4 ++-- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index f3738948875d..d51fcfdd88bb 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -51,17 +51,17 @@ https://github.com/dotnet/emsdk 2406616d0e3a31d80b326e27c156955bfa41c791 - + https://github.com/dotnet/msbuild - e7a44d757e097eb17dcac5a8436645dc612fec4b + 0d8d09e5c582526daeb4af0b52956c3290e424d1 - + https://github.com/dotnet/msbuild - e7a44d757e097eb17dcac5a8436645dc612fec4b + 0d8d09e5c582526daeb4af0b52956c3290e424d1 - + https://github.com/dotnet/msbuild - e7a44d757e097eb17dcac5a8436645dc612fec4b + 0d8d09e5c582526daeb4af0b52956c3290e424d1 diff --git a/eng/Versions.props b/eng/Versions.props index fe096fc1b26a..e79ca1aafe7b 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -106,7 +106,7 @@ - 17.10.0-preview-24076-01 + 17.10.0-preview-24076-03 $(MicrosoftBuildPackageVersion) - 17.10.0-preview-24073-02 - 17.10.0-preview-24073-02 - 17.10.0-preview-24073-02 + 17.10.0-preview-24076-01 + 17.10.0-preview-24076-01 + 17.10.0-preview-24076-01 From 29ffef3546455fb2a0003b3326169368765a1bf3 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" Date: Sat, 27 Jan 2024 14:01:48 +0000 Subject: [PATCH 139/577] Update dependencies from https://github.com/dotnet/razor build 20240126.2 Microsoft.AspNetCore.Mvc.Razor.Extensions.Tooling.Internal , Microsoft.CodeAnalysis.Razor.Tooling.Internal , Microsoft.NET.Sdk.Razor.SourceGenerators.Transport From Version 7.0.0-preview.24074.5 -> To Version 7.0.0-preview.24076.2 --- eng/Version.Details.xml | 12 ++++++------ eng/Versions.props | 6 +++--- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index e8ea46e9a85b..6b94087f3a92 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -277,18 +277,18 @@ https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore 3f1acb59718cadf111a0a796681e3d3509bb3381 - + https://github.com/dotnet/razor - 46a1c23286c5eedd38fe2c071c50d703a26f582b + 8fce635c1c8103890849423200725a59783575ec - + https://github.com/dotnet/razor - 46a1c23286c5eedd38fe2c071c50d703a26f582b + 8fce635c1c8103890849423200725a59783575ec - + https://github.com/dotnet/razor - 46a1c23286c5eedd38fe2c071c50d703a26f582b + 8fce635c1c8103890849423200725a59783575ec https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore diff --git a/eng/Versions.props b/eng/Versions.props index a5a4caaf4703..ea032f3fc031 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -161,9 +161,9 @@ - 7.0.0-preview.24076.1 - 7.0.0-preview.24076.1 - 7.0.0-preview.24076.1 + 7.0.0-preview.24076.2 + 7.0.0-preview.24076.2 + 7.0.0-preview.24076.2 From 5ac37a0201075ea97dc0da417166c42d667429d8 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" Date: Sat, 27 Jan 2024 14:05:58 +0000 Subject: [PATCH 140/577] Update dependencies from https://github.com/dotnet/arcade build 20240125.5 Microsoft.DotNet.Arcade.Sdk , Microsoft.DotNet.Helix.Sdk , Microsoft.DotNet.SignTool , Microsoft.DotNet.XUnitExtensions From Version 8.0.0-beta.24074.2 -> To Version 8.0.0-beta.24075.5 --- eng/Version.Details.xml | 16 ++++++++-------- eng/Versions.props | 4 ++-- global.json | 4 ++-- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index f3738948875d..404ec297f784 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -411,22 +411,22 @@ - + https://github.com/dotnet/arcade - 96c2cee493aa1542c0b06a6498e0379eb11e005f + 07cf24f27ee58b5d1a9662334a101d84bd1e07e5 - + https://github.com/dotnet/arcade - 96c2cee493aa1542c0b06a6498e0379eb11e005f + 07cf24f27ee58b5d1a9662334a101d84bd1e07e5 - + https://github.com/dotnet/arcade - 96c2cee493aa1542c0b06a6498e0379eb11e005f + 07cf24f27ee58b5d1a9662334a101d84bd1e07e5 - + https://github.com/dotnet/arcade - 96c2cee493aa1542c0b06a6498e0379eb11e005f + 07cf24f27ee58b5d1a9662334a101d84bd1e07e5 https://dev.azure.com/dnceng/internal/_git/dotnet-runtime diff --git a/eng/Versions.props b/eng/Versions.props index fe096fc1b26a..7cfc3ebdabd4 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -35,7 +35,7 @@ 7.0.0 4.0.0 7.0.0 - 8.0.0-beta.24074.2 + 8.0.0-beta.24075.5 7.0.0-preview.22423.2 8.0.0 4.3.0 @@ -195,7 +195,7 @@ 6.12.0 6.1.0 - 8.0.0-beta.24074.2 + 8.0.0-beta.24075.5 4.18.4 1.3.2 8.0.0-beta.23607.1 diff --git a/global.json b/global.json index 3a79a4ae9a72..a2d298658396 100644 --- a/global.json +++ b/global.json @@ -14,7 +14,7 @@ } }, "msbuild-sdks": { - "Microsoft.DotNet.Arcade.Sdk": "8.0.0-beta.24074.2", - "Microsoft.DotNet.Helix.Sdk": "8.0.0-beta.24074.2" + "Microsoft.DotNet.Arcade.Sdk": "8.0.0-beta.24075.5", + "Microsoft.DotNet.Helix.Sdk": "8.0.0-beta.24075.5" } } From ec6394b6eab953e26624dfbfd52baa515bb7688d Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" Date: Sun, 28 Jan 2024 13:44:07 +0000 Subject: [PATCH 141/577] Update dependencies from https://github.com/dotnet/msbuild build 20240126.3 Microsoft.SourceBuild.Intermediate.msbuild , Microsoft.Build , Microsoft.Build.Localization From Version 17.10.0-preview-24076-01 -> To Version 17.10.0-preview-24076-03 From eca72f121fbb569eedea7bdd012219d0a4498ea8 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" Date: Sun, 28 Jan 2024 13:44:28 +0000 Subject: [PATCH 142/577] Update dependencies from https://github.com/microsoft/vstest build 20240126.1 Microsoft.NET.Test.Sdk , Microsoft.TestPlatform.Build , Microsoft.TestPlatform.CLI From Version 17.9.0-release-23627-01 -> To Version 17.10.0-preview-24076-01 From e2eaa452cbd26be015093ba33ba0690e6bb2a995 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" Date: Sun, 28 Jan 2024 13:44:48 +0000 Subject: [PATCH 143/577] Update dependencies from https://github.com/dotnet/razor build 20240127.1 Microsoft.AspNetCore.Mvc.Razor.Extensions.Tooling.Internal , Microsoft.CodeAnalysis.Razor.Tooling.Internal , Microsoft.NET.Sdk.Razor.SourceGenerators.Transport From Version 7.0.0-preview.24074.5 -> To Version 7.0.0-preview.24077.1 --- eng/Version.Details.xml | 12 ++++++------ eng/Versions.props | 6 +++--- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 6b94087f3a92..5d29ceba5220 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -277,18 +277,18 @@ https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore 3f1acb59718cadf111a0a796681e3d3509bb3381 - + https://github.com/dotnet/razor - 8fce635c1c8103890849423200725a59783575ec + 1789ca8211001451ec03962a43228755820b77b9 - + https://github.com/dotnet/razor - 8fce635c1c8103890849423200725a59783575ec + 1789ca8211001451ec03962a43228755820b77b9 - + https://github.com/dotnet/razor - 8fce635c1c8103890849423200725a59783575ec + 1789ca8211001451ec03962a43228755820b77b9 https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore diff --git a/eng/Versions.props b/eng/Versions.props index ea032f3fc031..8e2d49de3493 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -161,9 +161,9 @@ - 7.0.0-preview.24076.2 - 7.0.0-preview.24076.2 - 7.0.0-preview.24076.2 + 7.0.0-preview.24077.1 + 7.0.0-preview.24077.1 + 7.0.0-preview.24077.1 From 1c89fabb0a3fe722334394c5533cf4f1514bfff3 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" Date: Sun, 28 Jan 2024 13:49:13 +0000 Subject: [PATCH 144/577] Update dependencies from https://github.com/dotnet/arcade build 20240125.5 Microsoft.DotNet.Arcade.Sdk , Microsoft.DotNet.Helix.Sdk , Microsoft.DotNet.SignTool , Microsoft.DotNet.XUnitExtensions From Version 8.0.0-beta.24074.2 -> To Version 8.0.0-beta.24075.5 From e280f94fef7bbb4c9ebc613fd95feaedf7a07917 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" Date: Mon, 29 Jan 2024 13:37:52 +0000 Subject: [PATCH 145/577] Update dependencies from https://github.com/dotnet/msbuild build 20240126.3 Microsoft.SourceBuild.Intermediate.msbuild , Microsoft.Build , Microsoft.Build.Localization From Version 17.10.0-preview-24076-01 -> To Version 17.10.0-preview-24076-03 From be2ff375d2de5b13df509153995166d006f9f332 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" Date: Mon, 29 Jan 2024 13:38:26 +0000 Subject: [PATCH 146/577] Update dependencies from https://github.com/microsoft/vstest build 20240128.3 Microsoft.NET.Test.Sdk , Microsoft.TestPlatform.Build , Microsoft.TestPlatform.CLI From Version 17.9.0-release-23627-01 -> To Version 17.10.0-preview-24078-03 --- eng/Version.Details.xml | 12 ++++++------ eng/Versions.props | 6 +++--- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 46c094bd87f5..979a2d081643 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -179,18 +179,18 @@ https://github.com/nuget/nuget.client e92be3915309e687044768de38933ac5fc4cb40c - + https://github.com/microsoft/vstest - 1cc29f8bab538e5fa31f799845e80c04cfa365c7 + a09e17e9efd7f85abab5a83d627d15aef5b6a954 - + https://github.com/microsoft/vstest - 1cc29f8bab538e5fa31f799845e80c04cfa365c7 + a09e17e9efd7f85abab5a83d627d15aef5b6a954 - + https://github.com/microsoft/vstest - 1cc29f8bab538e5fa31f799845e80c04cfa365c7 + a09e17e9efd7f85abab5a83d627d15aef5b6a954 https://dev.azure.com/dnceng/internal/_git/dotnet-runtime diff --git a/eng/Versions.props b/eng/Versions.props index 0ee627b98650..4e4b8bb14cff 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -84,9 +84,9 @@ - 17.10.0-preview-24076-01 - 17.10.0-preview-24076-01 - 17.10.0-preview-24076-01 + 17.10.0-preview-24078-03 + 17.10.0-preview-24078-03 + 17.10.0-preview-24078-03 From dcf3478a7f69ce2d0cfac7a31fbfa072d6ba1de1 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" Date: Mon, 29 Jan 2024 13:38:49 +0000 Subject: [PATCH 147/577] Update dependencies from https://github.com/dotnet/razor build 20240127.1 Microsoft.AspNetCore.Mvc.Razor.Extensions.Tooling.Internal , Microsoft.CodeAnalysis.Razor.Tooling.Internal , Microsoft.NET.Sdk.Razor.SourceGenerators.Transport From Version 7.0.0-preview.24074.5 -> To Version 7.0.0-preview.24077.1 From f4bfe66b02ebb4e2f6207cabb4f7a8ffb311e5f6 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" Date: Mon, 29 Jan 2024 13:39:42 +0000 Subject: [PATCH 148/577] Update dependencies from https://github.com/dotnet/templating build 20240128.2 Microsoft.TemplateEngine.Abstractions , Microsoft.TemplateEngine.Mocks From Version 8.0.300-preview.24074.2 -> To Version 8.0.300-preview.24078.2 --- eng/Version.Details.xml | 8 ++++---- eng/Versions.props | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 404ec297f784..eb1b2bb14dd6 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -1,14 +1,14 @@ - + https://github.com/dotnet/templating - 8ead8596ce97dcf6464354f6819da5baddf1b609 + 9a7274da6e9f9de9cb2cd7a6efa2ae30d3d73f4f - + https://github.com/dotnet/templating - 8ead8596ce97dcf6464354f6819da5baddf1b609 + 9a7274da6e9f9de9cb2cd7a6efa2ae30d3d73f4f https://dev.azure.com/dnceng/internal/_git/dotnet-runtime diff --git a/eng/Versions.props b/eng/Versions.props index 7cfc3ebdabd4..08d2f409c1bb 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -123,13 +123,13 @@ - 8.0.300-preview.24074.2 + 8.0.300-preview.24078.2 $(MicrosoftTemplateEngineAbstractionsPackageVersion) $(MicrosoftTemplateEngineAbstractionsPackageVersion) $(MicrosoftTemplateEngineAbstractionsPackageVersion) $(MicrosoftTemplateEngineAbstractionsPackageVersion) - 8.0.300-preview.24074.2 + 8.0.300-preview.24078.2 $(MicrosoftTemplateEngineMocksPackageVersion) $(MicrosoftTemplateEngineAbstractionsPackageVersion) $(MicrosoftTemplateEngineMocksPackageVersion) From 21cd581f75935444825a051769c5104f428f3e15 Mon Sep 17 00:00:00 2001 From: Marc Paine Date: Mon, 29 Jan 2024 12:45:50 -0800 Subject: [PATCH 149/577] Update to the Jan 8.0.1 released version of the runtime --- eng/Version.Details.xml | 134 ++++++++++++++++++++-------------------- eng/Versions.props | 30 ++++----- 2 files changed, 82 insertions(+), 82 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 404ec297f784..e4217464eda7 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -10,46 +10,46 @@ https://github.com/dotnet/templating 8ead8596ce97dcf6464354f6819da5baddf1b609 - + https://dev.azure.com/dnceng/internal/_git/dotnet-runtime - 5535e31a712343a63f5d7d796cd874e563e5ac14 + bf5e279d9239bfef5bb1b8d6212f1b971c434606 - + https://dev.azure.com/dnceng/internal/_git/dotnet-runtime - 5535e31a712343a63f5d7d796cd874e563e5ac14 + bf5e279d9239bfef5bb1b8d6212f1b971c434606 - + https://dev.azure.com/dnceng/internal/_git/dotnet-runtime - 5535e31a712343a63f5d7d796cd874e563e5ac14 + bf5e279d9239bfef5bb1b8d6212f1b971c434606 - + https://dev.azure.com/dnceng/internal/_git/dotnet-runtime - 5535e31a712343a63f5d7d796cd874e563e5ac14 + bf5e279d9239bfef5bb1b8d6212f1b971c434606 - + https://dev.azure.com/dnceng/internal/_git/dotnet-runtime - 5535e31a712343a63f5d7d796cd874e563e5ac14 + bf5e279d9239bfef5bb1b8d6212f1b971c434606 - + https://dev.azure.com/dnceng/internal/_git/dotnet-runtime - 5535e31a712343a63f5d7d796cd874e563e5ac14 + bf5e279d9239bfef5bb1b8d6212f1b971c434606 - + https://dev.azure.com/dnceng/internal/_git/dotnet-runtime - 5535e31a712343a63f5d7d796cd874e563e5ac14 + bf5e279d9239bfef5bb1b8d6212f1b971c434606 https://dev.azure.com/dnceng/internal/_git/dotnet-runtime 5535e31a712343a63f5d7d796cd874e563e5ac14 - + https://dev.azure.com/dnceng/internal/_git/dotnet-runtime - 5535e31a712343a63f5d7d796cd874e563e5ac14 + bf5e279d9239bfef5bb1b8d6212f1b971c434606 - + https://github.com/dotnet/emsdk - 2406616d0e3a31d80b326e27c156955bfa41c791 + 201f4dae9d1a1e105d8ba86d7ece61eed1f665e0 https://github.com/dotnet/msbuild @@ -107,13 +107,13 @@ https://github.com/dotnet/roslyn 3cd939f76803da435c20b082a5cfcc844386fcfb - + https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore - 3f1acb59718cadf111a0a796681e3d3509bb3381 + 8e941eb42f819adb116b881195158b3887a70a1c - + https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore - 3f1acb59718cadf111a0a796681e3d3509bb3381 + 8e941eb42f819adb116b881195158b3887a70a1c https://github.com/nuget/nuget.client @@ -192,9 +192,9 @@ https://github.com/microsoft/vstest 053d7114a72aac12d1382ecc2a23b2dfdd5b084b - + https://dev.azure.com/dnceng/internal/_git/dotnet-runtime - 5535e31a712343a63f5d7d796cd874e563e5ac14 + bf5e279d9239bfef5bb1b8d6212f1b971c434606 https://dev.azure.com/dnceng/internal/_git/dotnet-runtime @@ -212,70 +212,70 @@ https://dev.azure.com/dnceng/internal/_git/dotnet-runtime 5535e31a712343a63f5d7d796cd874e563e5ac14 - + https://dev.azure.com/dnceng/internal/_git/dotnet-windowsdesktop - c0170915ed6c164a594cd9d558d44aaf98fc6961 + a0e7b5d8673f28c41bcac6e2001b39ba2c8fab54 - + https://dev.azure.com/dnceng/internal/_git/dotnet-windowsdesktop - c0170915ed6c164a594cd9d558d44aaf98fc6961 + a0e7b5d8673f28c41bcac6e2001b39ba2c8fab54 - + https://dev.azure.com/dnceng/internal/_git/dotnet-windowsdesktop - c0170915ed6c164a594cd9d558d44aaf98fc6961 + a0e7b5d8673f28c41bcac6e2001b39ba2c8fab54 - + https://dev.azure.com/dnceng/internal/_git/dotnet-windowsdesktop - c0170915ed6c164a594cd9d558d44aaf98fc6961 + a0e7b5d8673f28c41bcac6e2001b39ba2c8fab54 - + https://dev.azure.com/dnceng/internal/_git/dotnet-wpf - 239f8da8fbf8cf2a6cd0c793f0d02679bf4ccf6a + ac40bed7a33baf164d3984ca90c2aedba996a7b2 - + https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore - 3f1acb59718cadf111a0a796681e3d3509bb3381 + 8e941eb42f819adb116b881195158b3887a70a1c - + https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore - 3f1acb59718cadf111a0a796681e3d3509bb3381 + 8e941eb42f819adb116b881195158b3887a70a1c - + https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore - 3f1acb59718cadf111a0a796681e3d3509bb3381 + 8e941eb42f819adb116b881195158b3887a70a1c - + https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore - 3f1acb59718cadf111a0a796681e3d3509bb3381 + 8e941eb42f819adb116b881195158b3887a70a1c - + https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore - 3f1acb59718cadf111a0a796681e3d3509bb3381 + 8e941eb42f819adb116b881195158b3887a70a1c - + https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore - 3f1acb59718cadf111a0a796681e3d3509bb3381 + 8e941eb42f819adb116b881195158b3887a70a1c - + https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore - 3f1acb59718cadf111a0a796681e3d3509bb3381 + 8e941eb42f819adb116b881195158b3887a70a1c - + https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore - 3f1acb59718cadf111a0a796681e3d3509bb3381 + 8e941eb42f819adb116b881195158b3887a70a1c - + https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore - 3f1acb59718cadf111a0a796681e3d3509bb3381 + 8e941eb42f819adb116b881195158b3887a70a1c - + https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore - 3f1acb59718cadf111a0a796681e3d3509bb3381 + 8e941eb42f819adb116b881195158b3887a70a1c - + https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore - 3f1acb59718cadf111a0a796681e3d3509bb3381 + 8e941eb42f819adb116b881195158b3887a70a1c https://github.com/dotnet/razor @@ -290,21 +290,21 @@ https://github.com/dotnet/razor 00a9bb181a4028e7fff09d989c5540cff677e411 - + https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore - 3f1acb59718cadf111a0a796681e3d3509bb3381 + 8e941eb42f819adb116b881195158b3887a70a1c - + https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore - 3f1acb59718cadf111a0a796681e3d3509bb3381 + 8e941eb42f819adb116b881195158b3887a70a1c - + https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore - 3f1acb59718cadf111a0a796681e3d3509bb3381 + 8e941eb42f819adb116b881195158b3887a70a1c - + https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore - 3f1acb59718cadf111a0a796681e3d3509bb3381 + 8e941eb42f819adb116b881195158b3887a70a1c https://github.com/dotnet/xdt @@ -333,9 +333,9 @@ 02fe27cd6a9b001c8feb7938e6ef4b3799745759 - - https://github.com/dotnet/source-build-externals - 83274d94c7e2ff21081b0d75ecbec2da2241f831 + + https://dev.azure.com/dnceng/internal/_git/dotnet-source-build-externals + 0f0f1f0f33830f27ed0ff357145d2464b96b1a3e diff --git a/eng/Versions.props b/eng/Versions.props index 7cfc3ebdabd4..0e6f8706cf0e 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -51,19 +51,19 @@ - 8.0.0 - 8.0.0-rtm.23531.3 - 8.0.0 + 8.0.1 + 8.0.1-servicing.23580.1 + 8.0.1 $(MicrosoftNETCoreAppRuntimewinx64PackageVersion) 8.0.0 - 8.0.0 - 8.0.0-rtm.23531.3 + 8.0.1 + 8.0.1-servicing.23580.1 8.0.0 $(MicrosoftExtensionsDependencyModelPackageVersion) 8.0.0 8.0.0 8.0.0 - 8.0.0 + 8.0.1 8.0.0 @@ -151,13 +151,13 @@ - 8.0.0 - 8.0.0-rtm.23531.12 - 8.0.0-rtm.23531.12 - 8.0.0-rtm.23531.12 - 8.0.0-rtm.23531.12 - 8.0.0-rtm.23531.12 - 8.0.0 + 8.0.1 + 8.0.1-servicing.23580.8 + 8.0.1-servicing.23580.8 + 8.0.1-servicing.23580.8 + 8.0.1-servicing.23580.8 + 8.0.1-servicing.23580.8 + 8.0.1 @@ -167,7 +167,7 @@ - 8.0.0-rtm.23531.4 + 8.0.1-servicing.23580.5 @@ -212,7 +212,7 @@ 8.0.0 - 8.0.0 + 8.0.1 $(MicrosoftNETWorkloadEmscriptenCurrentManifest80100PackageVersion) 8.0.100$([System.Text.RegularExpressions.Regex]::Match($(EmscriptenWorkloadManifestVersion), `-rtm|-[A-z]*\.*\d*`)) From 232429be817d8279127ab8c1442f6bc140892ccd Mon Sep 17 00:00:00 2001 From: Noah Gilson Date: Mon, 29 Jan 2024 13:19:36 -0800 Subject: [PATCH 150/577] Try adding install records for VS only workloads during 'workload update' --- .../install/NetSdkMsiInstallerClient.cs | 8 +++++ .../update/WorkloadUpdateCommand.cs | 31 +++++++++++++++++++ 2 files changed, 39 insertions(+) diff --git a/src/Cli/dotnet/commands/dotnet-workload/install/NetSdkMsiInstallerClient.cs b/src/Cli/dotnet/commands/dotnet-workload/install/NetSdkMsiInstallerClient.cs index 6ff3b44635d5..dd3bb8a7aa0d 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/install/NetSdkMsiInstallerClient.cs +++ b/src/Cli/dotnet/commands/dotnet-workload/install/NetSdkMsiInstallerClient.cs @@ -491,6 +491,14 @@ public void InstallWorkloads(IEnumerable workloadIds, SdkFeatureBand } } + public void WriteWorkloadInstallRecords(IEnumerable workloadsToWriteRecordsFor) + { + foreach (var workload in workloadsToWriteRecordsFor.AsEnumerable()) + { + RecordRepository.WriteWorkloadInstallationRecord(workload, _sdkFeatureBand); + } + } + void RollBackMsiInstall(WorkloadDownload msiToRollback, DirectoryPath? offlineCache = null) { try diff --git a/src/Cli/dotnet/commands/dotnet-workload/update/WorkloadUpdateCommand.cs b/src/Cli/dotnet/commands/dotnet-workload/update/WorkloadUpdateCommand.cs index a14ad7e4d00b..1e1df507bbc8 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/update/WorkloadUpdateCommand.cs +++ b/src/Cli/dotnet/commands/dotnet-workload/update/WorkloadUpdateCommand.cs @@ -6,8 +6,11 @@ using Microsoft.DotNet.Cli; using Microsoft.DotNet.Cli.NuGetPackageDownloader; using Microsoft.DotNet.Cli.Utils; +using Microsoft.DotNet.Installer.Windows; using Microsoft.DotNet.ToolPackage; using Microsoft.DotNet.Workloads.Workload.Install; +using Microsoft.DotNet.Workloads.Workload.Install.InstallRecord; +using Microsoft.DotNet.Workloads.Workload.List; using Microsoft.Extensions.EnvironmentAbstractions; using Microsoft.NET.Sdk.WorkloadManifestReader; using NuGet.Versioning; @@ -119,6 +122,8 @@ public void UpdateWorkloads(bool includePreviews = false, DirectoryPath? offline { Reporter.WriteLine(); + WriteSDKInstallRecordsForVSWorkloads(); + var workloadIds = GetUpdatableWorkloads(); _workloadManifestUpdater.UpdateAdvertisingManifestsAsync(includePreviews, offlineCache).Wait(); @@ -139,6 +144,32 @@ public void UpdateWorkloads(bool includePreviews = false, DirectoryPath? offline Reporter.WriteLine(); } + /// + /// Writes install records for VS Workloads so we later install the packs via the CLI for workloads managed by VS. + /// This is to fix a bug where updating the manifests in the CLI will cause VS to also be told to use these newer workloads via the workload resolver. + /// ... but these workloads don't have their corresponding packs installed as VS doesnt update its workloads as the CLI does. + /// + private void WriteSDKInstallRecordsForVSWorkloads() + { +#if !DOT_NET_BUILD_FROM_SOURCE + if (OperatingSystem.IsWindows()) + { + // Do this gross check to avoid adding an unused & unnecessary method to FileBasedInstallers + if(typeof(NetSdkMsiInstallerClient) == _workloadInstaller.GetType()) + { + InstalledWorkloadsCollection vsWorkloads = new(); + VisualStudioWorkloads.GetInstalledWorkloads(_workloadResolver, vsWorkloads); + // Remove workloads with an SDK installation source, as we've already created install records for them, and don't need to again. + List vsOnlyWorkloads = vsWorkloads.AsEnumerable().Where(w => !w.Value.Contains("SDK")).Select(w => new WorkloadId(w.Key)).ToList(); + List workloadsWithExistingInstallRecords = (List)GetUpdatableWorkloads(); + List workloadsToWriteRecordsFor = (List)vsOnlyWorkloads.Except(workloadsWithExistingInstallRecords); + + ((NetSdkMsiInstallerClient)_workloadInstaller).WriteWorkloadInstallRecords(workloadsToWriteRecordsFor); + } + } +#endif + } + private void UpdateWorkloadsWithInstallRecord( SdkFeatureBand sdkFeatureBand, IEnumerable manifestsToUpdate, From 77c50dd8669998e227280728780c3c15d544f19f Mon Sep 17 00:00:00 2001 From: Noah Gilson Date: Mon, 29 Jan 2024 16:09:13 -0800 Subject: [PATCH 151/577] Switch from List to IEnumerable because List is unnecessary --- .../dotnet-workload/install/NetSdkMsiInstallerClient.cs | 1 + .../dotnet-workload/update/WorkloadUpdateCommand.cs | 6 +++--- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/Cli/dotnet/commands/dotnet-workload/install/NetSdkMsiInstallerClient.cs b/src/Cli/dotnet/commands/dotnet-workload/install/NetSdkMsiInstallerClient.cs index dd3bb8a7aa0d..98dc0d117e89 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/install/NetSdkMsiInstallerClient.cs +++ b/src/Cli/dotnet/commands/dotnet-workload/install/NetSdkMsiInstallerClient.cs @@ -495,6 +495,7 @@ public void WriteWorkloadInstallRecords(IEnumerable workloadsToWrite { foreach (var workload in workloadsToWriteRecordsFor.AsEnumerable()) { + Log?.LogMessage($"The workload with id: {workload} was detected as being from VS only and having no SDK records. Creating one now."); RecordRepository.WriteWorkloadInstallationRecord(workload, _sdkFeatureBand); } } diff --git a/src/Cli/dotnet/commands/dotnet-workload/update/WorkloadUpdateCommand.cs b/src/Cli/dotnet/commands/dotnet-workload/update/WorkloadUpdateCommand.cs index 1e1df507bbc8..29c30482c356 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/update/WorkloadUpdateCommand.cs +++ b/src/Cli/dotnet/commands/dotnet-workload/update/WorkloadUpdateCommand.cs @@ -160,9 +160,9 @@ private void WriteSDKInstallRecordsForVSWorkloads() InstalledWorkloadsCollection vsWorkloads = new(); VisualStudioWorkloads.GetInstalledWorkloads(_workloadResolver, vsWorkloads); // Remove workloads with an SDK installation source, as we've already created install records for them, and don't need to again. - List vsOnlyWorkloads = vsWorkloads.AsEnumerable().Where(w => !w.Value.Contains("SDK")).Select(w => new WorkloadId(w.Key)).ToList(); - List workloadsWithExistingInstallRecords = (List)GetUpdatableWorkloads(); - List workloadsToWriteRecordsFor = (List)vsOnlyWorkloads.Except(workloadsWithExistingInstallRecords); + var vsOnlyWorkloads = vsWorkloads.AsEnumerable().Where(w => !w.Value.Contains("SDK")).Select(w => new WorkloadId(w.Key)); + var workloadsWithExistingInstallRecords = GetUpdatableWorkloads(); + var workloadsToWriteRecordsFor = vsOnlyWorkloads.Except(workloadsWithExistingInstallRecords); ((NetSdkMsiInstallerClient)_workloadInstaller).WriteWorkloadInstallRecords(workloadsToWriteRecordsFor); } From 5a563e8be9330bb655177143d0b0c60131c35b9f Mon Sep 17 00:00:00 2001 From: Jason Zhai Date: Mon, 29 Jan 2024 00:15:23 -0800 Subject: [PATCH 152/577] Bump required MSBuild version --- .../BuildWithComponentsIntegrationTest.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Tests/Microsoft.NET.Sdk.Razor.Tests/BuildWithComponentsIntegrationTest.cs b/src/Tests/Microsoft.NET.Sdk.Razor.Tests/BuildWithComponentsIntegrationTest.cs index 9c32669466ff..b7dcb6f14821 100644 --- a/src/Tests/Microsoft.NET.Sdk.Razor.Tests/BuildWithComponentsIntegrationTest.cs +++ b/src/Tests/Microsoft.NET.Sdk.Razor.Tests/BuildWithComponentsIntegrationTest.cs @@ -12,7 +12,7 @@ public BuildWithComponentsIntegrationTest(ITestOutputHelper log) : base(log) {} [CoreMSBuildOnlyFact] public void Build_Components_WithDotNetCoreMSBuild_Works() => Build_ComponentsWorks(); - [RequiresMSBuildVersionFact("17.8.0.37606")] + [RequiresMSBuildVersionFact("17.9.2.5503")] public void Build_Components_WithDesktopMSBuild_Works() => Build_ComponentsWorks(); [Fact] From e01219153f915192c2e598d711990cd9f7a3b726 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" Date: Tue, 30 Jan 2024 14:00:08 +0000 Subject: [PATCH 153/577] Update dependencies from https://github.com/nuget/nuget.client build 6.10.0.17 Microsoft.Build.NuGetSdkResolver , NuGet.Build.Tasks , NuGet.Build.Tasks.Console , NuGet.Build.Tasks.Pack , NuGet.CommandLine.XPlat , NuGet.Commands , NuGet.Common , NuGet.Configuration , NuGet.Credentials , NuGet.DependencyResolver.Core , NuGet.Frameworks , NuGet.LibraryModel , NuGet.Packaging , NuGet.ProjectModel , NuGet.Protocol , NuGet.Versioning From Version 6.10.0-preview.1.12 -> To Version 6.10.0-preview.1.17 --- eng/Version.Details.xml | 64 ++++++++++++++++++++--------------------- eng/Versions.props | 22 +++++++------- 2 files changed, 43 insertions(+), 43 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 1002611d0e8b..2287bb64ee1e 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -115,69 +115,69 @@ https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore 3f1acb59718cadf111a0a796681e3d3509bb3381 - + https://github.com/nuget/nuget.client - e4899ee48ff3d7787ee345f546c818ce6b962807 + 98b7d827d91c055fcaa77be7f34bf66811381b5a - + https://github.com/nuget/nuget.client - e4899ee48ff3d7787ee345f546c818ce6b962807 + 98b7d827d91c055fcaa77be7f34bf66811381b5a - + https://github.com/nuget/nuget.client - e4899ee48ff3d7787ee345f546c818ce6b962807 + 98b7d827d91c055fcaa77be7f34bf66811381b5a - + https://github.com/nuget/nuget.client - e4899ee48ff3d7787ee345f546c818ce6b962807 + 98b7d827d91c055fcaa77be7f34bf66811381b5a - + https://github.com/nuget/nuget.client - e4899ee48ff3d7787ee345f546c818ce6b962807 + 98b7d827d91c055fcaa77be7f34bf66811381b5a - + https://github.com/nuget/nuget.client - e4899ee48ff3d7787ee345f546c818ce6b962807 + 98b7d827d91c055fcaa77be7f34bf66811381b5a - + https://github.com/nuget/nuget.client - e4899ee48ff3d7787ee345f546c818ce6b962807 + 98b7d827d91c055fcaa77be7f34bf66811381b5a - + https://github.com/nuget/nuget.client - e4899ee48ff3d7787ee345f546c818ce6b962807 + 98b7d827d91c055fcaa77be7f34bf66811381b5a - + https://github.com/nuget/nuget.client - e4899ee48ff3d7787ee345f546c818ce6b962807 + 98b7d827d91c055fcaa77be7f34bf66811381b5a - + https://github.com/nuget/nuget.client - e4899ee48ff3d7787ee345f546c818ce6b962807 + 98b7d827d91c055fcaa77be7f34bf66811381b5a - + https://github.com/nuget/nuget.client - e4899ee48ff3d7787ee345f546c818ce6b962807 + 98b7d827d91c055fcaa77be7f34bf66811381b5a - + https://github.com/nuget/nuget.client - e4899ee48ff3d7787ee345f546c818ce6b962807 + 98b7d827d91c055fcaa77be7f34bf66811381b5a - + https://github.com/nuget/nuget.client - e4899ee48ff3d7787ee345f546c818ce6b962807 + 98b7d827d91c055fcaa77be7f34bf66811381b5a - + https://github.com/nuget/nuget.client - e4899ee48ff3d7787ee345f546c818ce6b962807 + 98b7d827d91c055fcaa77be7f34bf66811381b5a - + https://github.com/nuget/nuget.client - e4899ee48ff3d7787ee345f546c818ce6b962807 + 98b7d827d91c055fcaa77be7f34bf66811381b5a - + https://github.com/nuget/nuget.client - e4899ee48ff3d7787ee345f546c818ce6b962807 + 98b7d827d91c055fcaa77be7f34bf66811381b5a https://github.com/microsoft/vstest diff --git a/eng/Versions.props b/eng/Versions.props index 878e0574424b..ffb4785ca74a 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -68,18 +68,18 @@ - 6.10.0-preview.1.12 - 6.10.0-preview.1.12 + 6.10.0-preview.1.17 + 6.10.0-preview.1.17 6.0.0-rc.278 - 6.10.0-preview.1.12 - 6.10.0-preview.1.12 - 6.10.0-preview.1.12 - 6.10.0-preview.1.12 - 6.10.0-preview.1.12 - 6.10.0-preview.1.12 - 6.10.0-preview.1.12 - 6.10.0-preview.1.12 - 6.10.0-preview.1.12 + 6.10.0-preview.1.17 + 6.10.0-preview.1.17 + 6.10.0-preview.1.17 + 6.10.0-preview.1.17 + 6.10.0-preview.1.17 + 6.10.0-preview.1.17 + 6.10.0-preview.1.17 + 6.10.0-preview.1.17 + 6.10.0-preview.1.17 $(NuGetPackagingPackageVersion) $(NuGetProjectModelPackageVersion) From ce3ba99f4f9a52e626b1d0467d363c1d7eba7cc1 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" Date: Tue, 30 Jan 2024 14:01:09 +0000 Subject: [PATCH 154/577] Update dependencies from https://github.com/dotnet/msbuild build 20240130.2 Microsoft.SourceBuild.Intermediate.msbuild , Microsoft.Build , Microsoft.Build.Localization From Version 17.10.0-preview-24076-03 -> To Version 17.10.0-preview-24080-02 --- eng/Version.Details.xml | 12 ++++++------ eng/Versions.props | 4 ++-- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 1002611d0e8b..cf53883deca9 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -51,17 +51,17 @@ https://github.com/dotnet/emsdk 2406616d0e3a31d80b326e27c156955bfa41c791 - + https://github.com/dotnet/msbuild - 0d8d09e5c582526daeb4af0b52956c3290e424d1 + caaccdd1ec890391d936f491a1a411b473853c2b - + https://github.com/dotnet/msbuild - 0d8d09e5c582526daeb4af0b52956c3290e424d1 + caaccdd1ec890391d936f491a1a411b473853c2b - + https://github.com/dotnet/msbuild - 0d8d09e5c582526daeb4af0b52956c3290e424d1 + caaccdd1ec890391d936f491a1a411b473853c2b diff --git a/eng/Versions.props b/eng/Versions.props index 878e0574424b..b5d862680daa 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -106,7 +106,7 @@ - 17.10.0-preview-24076-03 + 17.10.0-preview-24080-02 $(MicrosoftBuildPackageVersion) - 17.10.0-preview-24078-03 - 17.10.0-preview-24078-03 - 17.10.0-preview-24078-03 + 17.10.0-preview-24080-01 + 17.10.0-preview-24080-01 + 17.10.0-preview-24080-01 From d35e727e9d7b8ce67df6ce94e8b657c4a7030efc Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" Date: Tue, 30 Jan 2024 14:02:08 +0000 Subject: [PATCH 156/577] Update dependencies from https://github.com/dotnet/fsharp build 20240130.1 Microsoft.SourceBuild.Intermediate.fsharp , Microsoft.FSharp.Compiler From Version 8.0.300-beta.24075.4 -> To Version 8.0.300-beta.24080.1 --- eng/Version.Details.xml | 8 ++++---- eng/Versions.props | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 1002611d0e8b..be5d3dfbc536 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -64,13 +64,13 @@ 0d8d09e5c582526daeb4af0b52956c3290e424d1 - + https://github.com/dotnet/fsharp - 32898dc51efc669de98e7e47f57d521bc07ac4cc + 3def38d082f0e3b15b4be08f273f3d616776cd32 - + https://github.com/dotnet/fsharp - 32898dc51efc669de98e7e47f57d521bc07ac4cc + 3def38d082f0e3b15b4be08f273f3d616776cd32 diff --git a/eng/Versions.props b/eng/Versions.props index 878e0574424b..6275f330f18b 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -136,7 +136,7 @@ - 12.8.300-beta.24075.4 + 12.8.300-beta.24080.1 From 4b92db03663eacdfe3c825f7fe6c61ac2d1be6c7 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" Date: Tue, 30 Jan 2024 14:02:39 +0000 Subject: [PATCH 157/577] Update dependencies from https://github.com/dotnet/razor build 20240130.1 Microsoft.AspNetCore.Mvc.Razor.Extensions.Tooling.Internal , Microsoft.CodeAnalysis.Razor.Tooling.Internal , Microsoft.NET.Sdk.Razor.SourceGenerators.Transport From Version 7.0.0-preview.24074.5 -> To Version 7.0.0-preview.24080.1 --- eng/Version.Details.xml | 12 ++++++------ eng/Versions.props | 6 +++--- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 5d29ceba5220..bdedfb8f02ed 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -277,18 +277,18 @@ https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore 3f1acb59718cadf111a0a796681e3d3509bb3381 - + https://github.com/dotnet/razor - 1789ca8211001451ec03962a43228755820b77b9 + 59421532418d132935fd48a4d363bd8cecd4e34a - + https://github.com/dotnet/razor - 1789ca8211001451ec03962a43228755820b77b9 + 59421532418d132935fd48a4d363bd8cecd4e34a - + https://github.com/dotnet/razor - 1789ca8211001451ec03962a43228755820b77b9 + 59421532418d132935fd48a4d363bd8cecd4e34a https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore diff --git a/eng/Versions.props b/eng/Versions.props index 8e2d49de3493..fdd44d1083c2 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -161,9 +161,9 @@ - 7.0.0-preview.24077.1 - 7.0.0-preview.24077.1 - 7.0.0-preview.24077.1 + 7.0.0-preview.24080.1 + 7.0.0-preview.24080.1 + 7.0.0-preview.24080.1 From b6073c5f180887d4cf1f20b3d3f5fc5e73439cde Mon Sep 17 00:00:00 2001 From: Marc Paine Date: Thu, 18 Jan 2024 16:04:32 -0800 Subject: [PATCH 158/577] Cherry pick change to fix up the CPM versions to package specific versions (#38116) --- Directory.Packages.props | 32 ++++++++++---------- eng/Version.Details.xml | 64 ++++++++++++++++++++++++++++++++++++++++ eng/Versions.props | 21 ++++++++++--- 3 files changed, 97 insertions(+), 20 deletions(-) diff --git a/Directory.Packages.props b/Directory.Packages.props index 49e2459b9fb4..5d37eb795d6b 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -9,7 +9,7 @@ - + @@ -32,12 +32,12 @@ - + - + @@ -55,8 +55,8 @@ - + @@ -82,27 +82,27 @@ - - - - - - - + + + + + + + - + - - + + - - + + diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index e4217464eda7..aeb92295eb49 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -409,6 +409,70 @@ https://dev.azure.com/dnceng/internal/_git/dotnet-runtime 5535e31a712343a63f5d7d796cd874e563e5ac14 + + https://dev.azure.com/dnceng/internal/_git/dotnet-runtime + bf5e279d9239bfef5bb1b8d6212f1b971c434606 + + + https://dev.azure.com/dnceng/internal/_git/dotnet-runtime + 5535e31a712343a63f5d7d796cd874e563e5ac14 + + + https://dev.azure.com/dnceng/internal/_git/dotnet-runtime + 5535e31a712343a63f5d7d796cd874e563e5ac14 + + + https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore + 8e941eb42f819adb116b881195158b3887a70a1c + + + https://dev.azure.com/dnceng/internal/_git/dotnet-runtime + 5535e31a712343a63f5d7d796cd874e563e5ac14 + + + https://dev.azure.com/dnceng/internal/_git/dotnet-runtime + 5535e31a712343a63f5d7d796cd874e563e5ac14 + + + https://dev.azure.com/dnceng/internal/_git/dotnet-runtime + 5535e31a712343a63f5d7d796cd874e563e5ac14 + + + https://dev.azure.com/dnceng/internal/_git/dotnet-runtime + 5535e31a712343a63f5d7d796cd874e563e5ac14 + + + https://dev.azure.com/dnceng/internal/_git/dotnet-runtime + 5535e31a712343a63f5d7d796cd874e563e5ac14 + + + https://dev.azure.com/dnceng/internal/_git/dotnet-runtime + 5535e31a712343a63f5d7d796cd874e563e5ac14 + + + https://dev.azure.com/dnceng/internal/_git/dotnet-runtime + 5535e31a712343a63f5d7d796cd874e563e5ac14 + + + https://dev.azure.com/dnceng/internal/_git/dotnet-winforms + 0b4028eb507aeb222f5bd1fc421876cc5e5e3fb8 + + + https://dev.azure.com/dnceng/internal/_git/dotnet-runtime + 5535e31a712343a63f5d7d796cd874e563e5ac14 + + + https://dev.azure.com/dnceng/internal/_git/dotnet-runtime + 5535e31a712343a63f5d7d796cd874e563e5ac14 + + + https://dev.azure.com/dnceng/internal/_git/dotnet-runtime + 5535e31a712343a63f5d7d796cd874e563e5ac14 + + + https://dev.azure.com/dnceng/internal/_git/dotnet-runtime + 5535e31a712343a63f5d7d796cd874e563e5ac14 + diff --git a/eng/Versions.props b/eng/Versions.props index 0e6f8706cf0e..ea81afbc2200 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -26,7 +26,6 @@ 1.0.0-20230414.1 - 2.1.0-preview2-26306-03 2.21.0 2.0.1-servicing-26011-01 13.0.3 @@ -41,7 +40,6 @@ 4.3.0 4.3.0 4.0.5 - 7.0.3 8.0.0 4.6.0 2.0.0-beta4.23307.1 @@ -60,11 +58,27 @@ 8.0.1-servicing.23580.1 8.0.0 $(MicrosoftExtensionsDependencyModelPackageVersion) + 8.0.0 8.0.0 8.0.0 - 8.0.0 8.0.1 + 8.0.0 + 8.0.0 + 8.0.1 + 8.0.0 + 8.0.0 + 8.0.0 + 8.0.0 + 8.0.0 + 8.0.0 + 8.0.0 + 8.0.1 + 8.0.0 + 8.0.0 + 8.0.0 8.0.0 + 8.0.1 + 8.0.0 @@ -211,7 +225,6 @@ - 8.0.0 8.0.1 $(MicrosoftNETWorkloadEmscriptenCurrentManifest80100PackageVersion) From 1e0b7ffd31c10b4592f5f64c29701b1b44551ac2 Mon Sep 17 00:00:00 2001 From: Michael Yanni Date: Thu, 25 Jan 2024 10:01:44 -0800 Subject: [PATCH 159/577] Skipping flaky tests documented in https://github.com/dotnet/sdk/issues/38268. --- .../GivenThatWeHaveAPackageReferenceWithAliases.cs | 2 +- src/Tests/dotnet-run.Tests/GivenDotnetRunIsInterrupted.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Tests/Microsoft.NET.Build.Tests/GivenThatWeHaveAPackageReferenceWithAliases.cs b/src/Tests/Microsoft.NET.Build.Tests/GivenThatWeHaveAPackageReferenceWithAliases.cs index 09bac098e4db..b20f0bcb70df 100644 --- a/src/Tests/Microsoft.NET.Build.Tests/GivenThatWeHaveAPackageReferenceWithAliases.cs +++ b/src/Tests/Microsoft.NET.Build.Tests/GivenThatWeHaveAPackageReferenceWithAliases.cs @@ -49,7 +49,7 @@ public void CanBuildProjectWithPackageReferencesWithConflictingTypes() .Pass(); } - [RequiresMSBuildVersionFact("16.8.0")] + [RequiresMSBuildVersionFact("16.8.0", Skip = "https://github.com/dotnet/sdk/issues/38268")] public void CanBuildProjectWithMultiplePackageReferencesWithAliases() { var targetFramework = ToolsetInfo.CurrentTargetFramework; diff --git a/src/Tests/dotnet-run.Tests/GivenDotnetRunIsInterrupted.cs b/src/Tests/dotnet-run.Tests/GivenDotnetRunIsInterrupted.cs index 69da2737b025..5863caefa0a5 100644 --- a/src/Tests/dotnet-run.Tests/GivenDotnetRunIsInterrupted.cs +++ b/src/Tests/dotnet-run.Tests/GivenDotnetRunIsInterrupted.cs @@ -104,7 +104,7 @@ public void ItPassesSIGTERMToChild() } } - [WindowsOnlyFact] + [WindowsOnlyFact(Skip = "https://github.com/dotnet/sdk/issues/38268")] public void ItTerminatesTheChildWhenKilled() { var asset = _testAssetsManager.CopyTestAsset("TestAppThatWaits") From 5024365c98171bb8651731f1afbad6e84dbda705 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" Date: Wed, 31 Jan 2024 14:00:48 +0000 Subject: [PATCH 160/577] Update dependencies from https://github.com/dotnet/msbuild build 20240131.2 Microsoft.SourceBuild.Intermediate.msbuild , Microsoft.Build , Microsoft.Build.Localization From Version 17.10.0-preview-24080-02 -> To Version 17.10.0-preview-24081-02 --- eng/Version.Details.xml | 12 ++++++------ eng/Versions.props | 4 ++-- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 61e03c5abf39..dfa4d3e9ec0b 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -51,17 +51,17 @@ https://github.com/dotnet/emsdk 2406616d0e3a31d80b326e27c156955bfa41c791 - + https://github.com/dotnet/msbuild - caaccdd1ec890391d936f491a1a411b473853c2b + 25df00b64f0dc3cf47bcbbc99dc9ad384e74454a - + https://github.com/dotnet/msbuild - caaccdd1ec890391d936f491a1a411b473853c2b + 25df00b64f0dc3cf47bcbbc99dc9ad384e74454a - + https://github.com/dotnet/msbuild - caaccdd1ec890391d936f491a1a411b473853c2b + 25df00b64f0dc3cf47bcbbc99dc9ad384e74454a diff --git a/eng/Versions.props b/eng/Versions.props index 9d0f132b987b..6bfa6b22df0d 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -106,7 +106,7 @@ - 17.10.0-preview-24080-02 + 17.10.0-preview-24081-02 $(MicrosoftBuildPackageVersion) - 12.8.300-beta.24080.1 + 12.8.300-beta.24080.5 From aa33af22dc4b0565a8dfbcea00c81a9276fdcb5c Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" Date: Wed, 31 Jan 2024 14:01:51 +0000 Subject: [PATCH 162/577] Update dependencies from https://github.com/dotnet/razor build 20240130.3 Microsoft.AspNetCore.Mvc.Razor.Extensions.Tooling.Internal , Microsoft.CodeAnalysis.Razor.Tooling.Internal , Microsoft.NET.Sdk.Razor.SourceGenerators.Transport From Version 7.0.0-preview.24080.1 -> To Version 7.0.0-preview.24080.3 --- eng/Version.Details.xml | 12 ++++++------ eng/Versions.props | 6 +++--- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 61e03c5abf39..c496be2d9414 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -277,18 +277,18 @@ https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore 3f1acb59718cadf111a0a796681e3d3509bb3381 - + https://github.com/dotnet/razor - 59421532418d132935fd48a4d363bd8cecd4e34a + af4ac8c7f8bc3e7af4019805d44ee4f4c547a19e - + https://github.com/dotnet/razor - 59421532418d132935fd48a4d363bd8cecd4e34a + af4ac8c7f8bc3e7af4019805d44ee4f4c547a19e - + https://github.com/dotnet/razor - 59421532418d132935fd48a4d363bd8cecd4e34a + af4ac8c7f8bc3e7af4019805d44ee4f4c547a19e https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore diff --git a/eng/Versions.props b/eng/Versions.props index 9d0f132b987b..af979fefcc44 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -161,9 +161,9 @@ - 7.0.0-preview.24080.1 - 7.0.0-preview.24080.1 - 7.0.0-preview.24080.1 + 7.0.0-preview.24080.3 + 7.0.0-preview.24080.3 + 7.0.0-preview.24080.3 From 58115a093ed0bf9c162c19d4528f1743f543fb4d Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Thu, 1 Feb 2024 02:11:21 +0000 Subject: [PATCH 163/577] [release/8.0.3xx] Update dependencies from microsoft/vstest (#38415) [release/8.0.3xx] Update dependencies from microsoft/vstest --- eng/Version.Details.xml | 12 ++++++------ eng/Versions.props | 6 +++--- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 9b5002963489..7cb5e9e84b76 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -179,18 +179,18 @@ https://github.com/nuget/nuget.client 98b7d827d91c055fcaa77be7f34bf66811381b5a - + https://github.com/microsoft/vstest - d61759559535f43790211fa53be7829dfe598841 + fa9d5c94bd4311da4db7e48dd990484e7ad4b120 - + https://github.com/microsoft/vstest - d61759559535f43790211fa53be7829dfe598841 + fa9d5c94bd4311da4db7e48dd990484e7ad4b120 - + https://github.com/microsoft/vstest - d61759559535f43790211fa53be7829dfe598841 + fa9d5c94bd4311da4db7e48dd990484e7ad4b120 https://dev.azure.com/dnceng/internal/_git/dotnet-runtime diff --git a/eng/Versions.props b/eng/Versions.props index 679cdf017a27..6a284aeb42d7 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -99,9 +99,9 @@ - 17.10.0-preview-24080-01 - 17.10.0-preview-24080-01 - 17.10.0-preview-24080-01 + 17.10.0-preview-24080-03 + 17.10.0-preview-24080-03 + 17.10.0-preview-24080-03 From 8bc6626451f9e9475fae3c322366502668be6974 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Thu, 1 Feb 2024 17:45:58 +0000 Subject: [PATCH 164/577] [release/8.0.3xx] Update dependencies from dotnet/msbuild (#38458) [release/8.0.3xx] Update dependencies from dotnet/msbuild --- eng/Version.Details.xml | 12 ++++++------ eng/Versions.props | 4 ++-- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 3d58b713e1c1..1074077db5e9 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -51,17 +51,17 @@ https://github.com/dotnet/emsdk 201f4dae9d1a1e105d8ba86d7ece61eed1f665e0 - + https://github.com/dotnet/msbuild - 25df00b64f0dc3cf47bcbbc99dc9ad384e74454a + 07fd5d51f25134ea3ab3620c66f6501a74df2921 - + https://github.com/dotnet/msbuild - 25df00b64f0dc3cf47bcbbc99dc9ad384e74454a + 07fd5d51f25134ea3ab3620c66f6501a74df2921 - + https://github.com/dotnet/msbuild - 25df00b64f0dc3cf47bcbbc99dc9ad384e74454a + 07fd5d51f25134ea3ab3620c66f6501a74df2921 diff --git a/eng/Versions.props b/eng/Versions.props index fca0c2a805e7..bff421e1f727 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -120,7 +120,7 @@ - 17.10.0-preview-24081-02 + 17.10.0-preview-24101-01 $(MicrosoftBuildPackageVersion) - 17.10.0-preview-24080-03 - 17.10.0-preview-24080-03 - 17.10.0-preview-24080-03 + 17.10.0-preview-24081-04 + 17.10.0-preview-24081-04 + 17.10.0-preview-24081-04 From aea2d74c7c440d77f8f014ab8bb913246f5d5364 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Thu, 1 Feb 2024 17:46:47 +0000 Subject: [PATCH 166/577] [release/8.0.3xx] Update dependencies from dotnet/arcade (#38461) [release/8.0.3xx] Update dependencies from dotnet/arcade --- eng/Version.Details.xml | 16 ++++++++-------- eng/Versions.props | 4 ++-- global.json | 4 ++-- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 94422803404c..045bd4ad4f8c 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -475,22 +475,22 @@ - + https://github.com/dotnet/arcade - 07cf24f27ee58b5d1a9662334a101d84bd1e07e5 + be88b08c41971b52ec11aec05ef31e72185d4a1f - + https://github.com/dotnet/arcade - 07cf24f27ee58b5d1a9662334a101d84bd1e07e5 + be88b08c41971b52ec11aec05ef31e72185d4a1f - + https://github.com/dotnet/arcade - 07cf24f27ee58b5d1a9662334a101d84bd1e07e5 + be88b08c41971b52ec11aec05ef31e72185d4a1f - + https://github.com/dotnet/arcade - 07cf24f27ee58b5d1a9662334a101d84bd1e07e5 + be88b08c41971b52ec11aec05ef31e72185d4a1f https://dev.azure.com/dnceng/internal/_git/dotnet-runtime diff --git a/eng/Versions.props b/eng/Versions.props index aae89bace699..5768861aa00c 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -34,7 +34,7 @@ 7.0.0 4.0.0 7.0.0 - 8.0.0-beta.24075.5 + 8.0.0-beta.24081.5 7.0.0-preview.22423.2 8.0.0 4.3.0 @@ -209,7 +209,7 @@ 6.12.0 6.1.0 - 8.0.0-beta.24075.5 + 8.0.0-beta.24081.5 4.18.4 1.3.2 8.0.0-beta.23607.1 diff --git a/global.json b/global.json index a2d298658396..9a628d8f0702 100644 --- a/global.json +++ b/global.json @@ -14,7 +14,7 @@ } }, "msbuild-sdks": { - "Microsoft.DotNet.Arcade.Sdk": "8.0.0-beta.24075.5", - "Microsoft.DotNet.Helix.Sdk": "8.0.0-beta.24075.5" + "Microsoft.DotNet.Arcade.Sdk": "8.0.0-beta.24081.5", + "Microsoft.DotNet.Helix.Sdk": "8.0.0-beta.24081.5" } } From 8b4d4e61bc30a189071113cdbebc655c96247232 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Thu, 1 Feb 2024 17:49:13 +0000 Subject: [PATCH 167/577] [release/8.0.3xx] Update dependencies from nuget/nuget.client (#38457) [release/8.0.3xx] Update dependencies from nuget/nuget.client --- eng/Version.Details.xml | 64 ++++++++++++++++++++--------------------- eng/Versions.props | 22 +++++++------- 2 files changed, 43 insertions(+), 43 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 045bd4ad4f8c..e0204f087289 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -115,69 +115,69 @@ https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore 8e941eb42f819adb116b881195158b3887a70a1c - + https://github.com/nuget/nuget.client - 98b7d827d91c055fcaa77be7f34bf66811381b5a + f207cbb3530350f785d1b04014e15563cc9b5e03 - + https://github.com/nuget/nuget.client - 98b7d827d91c055fcaa77be7f34bf66811381b5a + f207cbb3530350f785d1b04014e15563cc9b5e03 - + https://github.com/nuget/nuget.client - 98b7d827d91c055fcaa77be7f34bf66811381b5a + f207cbb3530350f785d1b04014e15563cc9b5e03 - + https://github.com/nuget/nuget.client - 98b7d827d91c055fcaa77be7f34bf66811381b5a + f207cbb3530350f785d1b04014e15563cc9b5e03 - + https://github.com/nuget/nuget.client - 98b7d827d91c055fcaa77be7f34bf66811381b5a + f207cbb3530350f785d1b04014e15563cc9b5e03 - + https://github.com/nuget/nuget.client - 98b7d827d91c055fcaa77be7f34bf66811381b5a + f207cbb3530350f785d1b04014e15563cc9b5e03 - + https://github.com/nuget/nuget.client - 98b7d827d91c055fcaa77be7f34bf66811381b5a + f207cbb3530350f785d1b04014e15563cc9b5e03 - + https://github.com/nuget/nuget.client - 98b7d827d91c055fcaa77be7f34bf66811381b5a + f207cbb3530350f785d1b04014e15563cc9b5e03 - + https://github.com/nuget/nuget.client - 98b7d827d91c055fcaa77be7f34bf66811381b5a + f207cbb3530350f785d1b04014e15563cc9b5e03 - + https://github.com/nuget/nuget.client - 98b7d827d91c055fcaa77be7f34bf66811381b5a + f207cbb3530350f785d1b04014e15563cc9b5e03 - + https://github.com/nuget/nuget.client - 98b7d827d91c055fcaa77be7f34bf66811381b5a + f207cbb3530350f785d1b04014e15563cc9b5e03 - + https://github.com/nuget/nuget.client - 98b7d827d91c055fcaa77be7f34bf66811381b5a + f207cbb3530350f785d1b04014e15563cc9b5e03 - + https://github.com/nuget/nuget.client - 98b7d827d91c055fcaa77be7f34bf66811381b5a + f207cbb3530350f785d1b04014e15563cc9b5e03 - + https://github.com/nuget/nuget.client - 98b7d827d91c055fcaa77be7f34bf66811381b5a + f207cbb3530350f785d1b04014e15563cc9b5e03 - + https://github.com/nuget/nuget.client - 98b7d827d91c055fcaa77be7f34bf66811381b5a + f207cbb3530350f785d1b04014e15563cc9b5e03 - + https://github.com/nuget/nuget.client - 98b7d827d91c055fcaa77be7f34bf66811381b5a + f207cbb3530350f785d1b04014e15563cc9b5e03 https://github.com/microsoft/vstest diff --git a/eng/Versions.props b/eng/Versions.props index 5768861aa00c..d9faf9c352e9 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -82,18 +82,18 @@ - 6.10.0-preview.1.17 - 6.10.0-preview.1.17 + 6.10.0-preview.1.18 + 6.10.0-preview.1.18 6.0.0-rc.278 - 6.10.0-preview.1.17 - 6.10.0-preview.1.17 - 6.10.0-preview.1.17 - 6.10.0-preview.1.17 - 6.10.0-preview.1.17 - 6.10.0-preview.1.17 - 6.10.0-preview.1.17 - 6.10.0-preview.1.17 - 6.10.0-preview.1.17 + 6.10.0-preview.1.18 + 6.10.0-preview.1.18 + 6.10.0-preview.1.18 + 6.10.0-preview.1.18 + 6.10.0-preview.1.18 + 6.10.0-preview.1.18 + 6.10.0-preview.1.18 + 6.10.0-preview.1.18 + 6.10.0-preview.1.18 $(NuGetPackagingPackageVersion) $(NuGetProjectModelPackageVersion) From 9898fa5d5f47fb7c2669fdf47c05ebc2d220e904 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Thu, 1 Feb 2024 12:35:17 -0800 Subject: [PATCH 168/577] [release/8.0.3xx] Update dependencies from dotnet/razor (#38460) Co-authored-by: dotnet-maestro[bot] --- eng/Version.Details.xml | 12 ++++++------ eng/Versions.props | 6 +++--- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index e0204f087289..228dc6891ef3 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -277,18 +277,18 @@ https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore 8e941eb42f819adb116b881195158b3887a70a1c - + https://github.com/dotnet/razor - af4ac8c7f8bc3e7af4019805d44ee4f4c547a19e + ae120b9fbe2d7af4dcaadd7f3cc5ea8c28ccca96 - + https://github.com/dotnet/razor - af4ac8c7f8bc3e7af4019805d44ee4f4c547a19e + ae120b9fbe2d7af4dcaadd7f3cc5ea8c28ccca96 - + https://github.com/dotnet/razor - af4ac8c7f8bc3e7af4019805d44ee4f4c547a19e + ae120b9fbe2d7af4dcaadd7f3cc5ea8c28ccca96 https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore diff --git a/eng/Versions.props b/eng/Versions.props index d9faf9c352e9..9dd1c53b75e7 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -175,9 +175,9 @@ - 7.0.0-preview.24080.3 - 7.0.0-preview.24080.3 - 7.0.0-preview.24080.3 + 7.0.0-preview.24081.3 + 7.0.0-preview.24081.3 + 7.0.0-preview.24081.3 From 71b81b43082a766920e13d2ccbd8451d339488fb Mon Sep 17 00:00:00 2001 From: Mark Li Date: Fri, 2 Feb 2024 02:40:53 -0800 Subject: [PATCH 169/577] locally change default option in `tool install` --- src/Cli/dotnet/CommonOptions.cs | 4 ++-- .../ToolInstallGlobalOrToolPathCommand.cs | 13 +++++++++- ...ToolInstallGlobalOrToolPathCommandTests.cs | 24 +++++++++---------- 3 files changed, 26 insertions(+), 15 deletions(-) diff --git a/src/Cli/dotnet/CommonOptions.cs b/src/Cli/dotnet/CommonOptions.cs index 78ecc5dd31e8..a11b13c4476c 100644 --- a/src/Cli/dotnet/CommonOptions.cs +++ b/src/Cli/dotnet/CommonOptions.cs @@ -281,10 +281,10 @@ internal static CliArgument AddCompletions(this CliArgument argument, F public enum VerbosityOptions { - minimal, - m, quiet, q, + minimal, + m, normal, n, detailed, diff --git a/src/Cli/dotnet/commands/dotnet-tool/install/ToolInstallGlobalOrToolPathCommand.cs b/src/Cli/dotnet/commands/dotnet-tool/install/ToolInstallGlobalOrToolPathCommand.cs index 2786f22de8f1..c2e180495b9e 100644 --- a/src/Cli/dotnet/commands/dotnet-tool/install/ToolInstallGlobalOrToolPathCommand.cs +++ b/src/Cli/dotnet/commands/dotnet-tool/install/ToolInstallGlobalOrToolPathCommand.cs @@ -62,7 +62,7 @@ public ToolInstallGlobalOrToolPathCommand( _framework = parseResult.GetValue(ToolInstallCommandParser.FrameworkOption); _source = parseResult.GetValue(ToolInstallCommandParser.AddSourceOption); _global = parseResult.GetValue(ToolAppliedOption.GlobalOption); - _verbosity = parseResult.GetValue(ToolInstallCommandParser.VerbosityOption); + _verbosity = GetValueOrDefault(ToolInstallCommandParser.VerbosityOption, VerbosityOptions.minimal, parseResult); _toolPath = parseResult.GetValue(ToolAppliedOption.ToolPathOption); _architectureOption = parseResult.GetValue(ToolInstallCommandParser.ArchitectureOption); @@ -89,6 +89,17 @@ public ToolInstallGlobalOrToolPathCommand( _errorReporter = (reporter ?? Reporter.Error); } + public T GetValueOrDefault(CliOption option, T defaultOption, ParseResult parseResult) + { + if (parseResult.GetResult(option) is { } result && + result.GetValueOrDefault() is { } t) + { + return t; + } + + return defaultOption; + } + public override int Execute() { ValidateArguments(); diff --git a/src/Tests/dotnet.Tests/CommandTests/ToolInstallGlobalOrToolPathCommandTests.cs b/src/Tests/dotnet.Tests/CommandTests/ToolInstallGlobalOrToolPathCommandTests.cs index 0d15084cb1f3..3c2268b28038 100644 --- a/src/Tests/dotnet.Tests/CommandTests/ToolInstallGlobalOrToolPathCommandTests.cs +++ b/src/Tests/dotnet.Tests/CommandTests/ToolInstallGlobalOrToolPathCommandTests.cs @@ -71,7 +71,7 @@ public ToolInstallGlobalOrToolPathCommandTests(ITestOutputHelper log): base(log) _createToolPackageStoreDownloaderUninstaller = (location, forwardArguments) => (_toolPackageStore, _toolPackageStoreQuery, CreateToolPackageDownloader(), _toolPackageUninstallerMock); - _parseResult = Parser.Instance.Parse($"dotnet tool install -g {PackageId} --verbosity minimal"); + _parseResult = Parser.Instance.Parse($"dotnet tool install -g {PackageId}"); } [Fact] @@ -341,7 +341,7 @@ public void WhenRunWithInvalidVersionItShouldThrow() [Fact] public void WhenRunWithExactVersionItShouldSucceed() { - ParseResult result = Parser.Instance.Parse($"dotnet tool install -g {PackageId} --version {PackageVersion} --verbosity minimal"); + ParseResult result = Parser.Instance.Parse($"dotnet tool install -g {PackageId} --version {PackageVersion}"); var toolInstallGlobalOrToolPathCommand = new ToolInstallGlobalOrToolPathCommand( result, @@ -365,7 +365,7 @@ public void WhenRunWithExactVersionItShouldSucceed() [Fact] public void WhenInstallTheSameVersionTwiceItShouldSucceed() { - ParseResult result = Parser.Instance.Parse($"dotnet tool install -g {PackageId} --version {PackageVersion} --verbosity minimal"); + ParseResult result = Parser.Instance.Parse($"dotnet tool install -g {PackageId} --version {PackageVersion}"); var toolInstallGlobalOrToolPathCommand = new ToolInstallGlobalOrToolPathCommand( result, @@ -401,7 +401,7 @@ public void WhenInstallTheSameVersionTwiceItShouldSucceed() public void WhenInstallWithHigherVersionItShouldUpdate() { IToolPackageDownloader toolToolPackageDownloader = GetToolPackageDownloaderWithHigherVersionInFeed(); - ParseResult result = Parser.Instance.Parse($"dotnet tool install -g {PackageId} --version {PackageVersion} --verbosity minimal"); + ParseResult result = Parser.Instance.Parse($"dotnet tool install -g {PackageId} --version {PackageVersion}"); var toolInstallGlobalOrToolPathCommand = new ToolInstallGlobalOrToolPathCommand( result, @@ -422,7 +422,7 @@ public void WhenInstallWithHigherVersionItShouldUpdate() PackageVersion).Green()); _reporter.Clear(); - ParseResult result2 = Parser.Instance.Parse($"dotnet tool install -g {PackageId} --version {HigherPackageVersion} --verbosity minimal"); + ParseResult result2 = Parser.Instance.Parse($"dotnet tool install -g {PackageId} --version {HigherPackageVersion}"); var toolInstallGlobalOrToolPathCommand2 = new ToolInstallGlobalOrToolPathCommand( result2, @@ -447,7 +447,7 @@ public void WhenInstallWithHigherVersionItShouldUpdate() public void WhenInstallWithLowerVersionWithAllowDowngradeOptionItShouldDowngrade() { IToolPackageDownloader toolToolPackageDownloader = GetToolPackageDownloaderWithLowerVersionInFeed(); - ParseResult result = Parser.Instance.Parse($"dotnet tool install -g {PackageId} --version {PackageVersion} --verbosity minimal"); + ParseResult result = Parser.Instance.Parse($"dotnet tool install -g {PackageId} --version {PackageVersion}"); var toolInstallGlobalOrToolPathCommand = new ToolInstallGlobalOrToolPathCommand( result, @@ -468,7 +468,7 @@ public void WhenInstallWithLowerVersionWithAllowDowngradeOptionItShouldDowngrade PackageVersion).Green()); _reporter.Clear(); - ParseResult result2 = Parser.Instance.Parse($"dotnet tool install -g {PackageId} --version {LowerPackageVersion} --verbosity minimal --allow-downgrade"); + ParseResult result2 = Parser.Instance.Parse($"dotnet tool install -g {PackageId} --version {LowerPackageVersion} --allow-downgrade"); var toolInstallGlobalOrToolPathCommand2 = new ToolInstallGlobalOrToolPathCommand( result2, @@ -493,7 +493,7 @@ public void WhenInstallWithLowerVersionWithAllowDowngradeOptionItShouldDowngrade public void WhenInstallWithLowerVersionItShouldFail() { IToolPackageDownloader toolToolPackageDownloader = GetToolPackageDownloaderWithLowerVersionInFeed(); - ParseResult result = Parser.Instance.Parse($"dotnet tool install -g {PackageId} --version {PackageVersion} --verbosity minimal"); + ParseResult result = Parser.Instance.Parse($"dotnet tool install -g {PackageId} --version {PackageVersion}"); var toolInstallGlobalOrToolPathCommand = new ToolInstallGlobalOrToolPathCommand( result, @@ -514,7 +514,7 @@ public void WhenInstallWithLowerVersionItShouldFail() PackageVersion).Green()); _reporter.Clear(); - ParseResult result2 = Parser.Instance.Parse($"dotnet tool install -g {PackageId} --version {LowerPackageVersion} --verbosity minimal"); + ParseResult result2 = Parser.Instance.Parse($"dotnet tool install -g {PackageId} --version {LowerPackageVersion}"); var toolInstallGlobalOrToolPathCommand2 = new ToolInstallGlobalOrToolPathCommand( result2, @@ -530,7 +530,7 @@ public void WhenInstallWithLowerVersionItShouldFail() [Fact] public void WhenRunWithValidVersionRangeItShouldSucceed() { - ParseResult result = Parser.Instance.Parse($"dotnet tool install -g {PackageId} --version [1.0,2.0] --verbosity minimal"); + ParseResult result = Parser.Instance.Parse($"dotnet tool install -g {PackageId} --version [1.0,2.0]"); var toolInstallGlobalOrToolPathCommand = new ToolInstallGlobalOrToolPathCommand( result, @@ -603,7 +603,7 @@ public void WhenRunWithPrereleaseItShouldSucceed() { IToolPackageDownloader toolToolPackageDownloader = GetToolToolPackageDownloaderWithPreviewInFeed(); - ParseResult result = Parser.Instance.Parse($"dotnet tool install -g {PackageId} --prerelease --verbosity minimal"); + ParseResult result = Parser.Instance.Parse($"dotnet tool install -g {PackageId} --prerelease"); var toolInstallGlobalOrToolPathCommand = new ToolInstallGlobalOrToolPathCommand( result, @@ -751,7 +751,7 @@ public void WhenRunWithoutAMatchingRangeItShouldFail() [Fact] public void WhenRunWithValidVersionWildcardItShouldSucceed() { - ParseResult result = Parser.Instance.Parse($"dotnet tool install -g {PackageId} --version 1.0.* --verbosity minimal"); + ParseResult result = Parser.Instance.Parse($"dotnet tool install -g {PackageId} --version 1.0.*"); var toolInstallGlobalOrToolPathCommand = new ToolInstallGlobalOrToolPathCommand( result, From 21dbb3e95fb7eed38d4f627d370328ed0b4112f3 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Fri, 2 Feb 2024 18:40:51 +0000 Subject: [PATCH 170/577] [release/8.0.3xx] Update dependencies from microsoft/vstest (#38494) [release/8.0.3xx] Update dependencies from microsoft/vstest --- eng/Version.Details.xml | 12 ++++++------ eng/Versions.props | 6 +++--- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 228dc6891ef3..abbcb30f9f93 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -179,18 +179,18 @@ https://github.com/nuget/nuget.client f207cbb3530350f785d1b04014e15563cc9b5e03 - + https://github.com/microsoft/vstest - 73d640131c4c120f3d865cfc91790dde49710e71 + edaf4ff11b2b706e88c74d870035d2025776ec06 - + https://github.com/microsoft/vstest - 73d640131c4c120f3d865cfc91790dde49710e71 + edaf4ff11b2b706e88c74d870035d2025776ec06 - + https://github.com/microsoft/vstest - 73d640131c4c120f3d865cfc91790dde49710e71 + edaf4ff11b2b706e88c74d870035d2025776ec06 https://dev.azure.com/dnceng/internal/_git/dotnet-runtime diff --git a/eng/Versions.props b/eng/Versions.props index 9dd1c53b75e7..b532b213f694 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -99,9 +99,9 @@ - 17.10.0-preview-24081-04 - 17.10.0-preview-24081-04 - 17.10.0-preview-24081-04 + 17.10.0-preview-24101-03 + 17.10.0-preview-24101-03 + 17.10.0-preview-24101-03 From 8902ed8b0bb3cbbd4066b10037c0b158371b84b7 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Fri, 2 Feb 2024 18:41:19 +0000 Subject: [PATCH 171/577] [release/8.0.3xx] Update dependencies from dotnet/fsharp (#38495) [release/8.0.3xx] Update dependencies from dotnet/fsharp --- eng/Version.Details.xml | 8 ++++---- eng/Versions.props | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index abbcb30f9f93..78fa83520f5c 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -64,13 +64,13 @@ 07fd5d51f25134ea3ab3620c66f6501a74df2921 - + https://github.com/dotnet/fsharp - 80003bb3f0516455a0046887aa169febf2c4d3a8 + 052d1133c78aa5af36c8e100afb91b1b5fc478af - + https://github.com/dotnet/fsharp - 80003bb3f0516455a0046887aa169febf2c4d3a8 + 052d1133c78aa5af36c8e100afb91b1b5fc478af diff --git a/eng/Versions.props b/eng/Versions.props index b532b213f694..403af38052bf 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -150,7 +150,7 @@ - 12.8.300-beta.24080.5 + 12.8.300-beta.24101.1 From 3d6bcf550e499dd3b474e29940cc4724e9aaede1 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Fri, 2 Feb 2024 18:41:46 +0000 Subject: [PATCH 172/577] [release/8.0.3xx] Update dependencies from dotnet/razor (#38496) [release/8.0.3xx] Update dependencies from dotnet/razor --- eng/Version.Details.xml | 12 ++++++------ eng/Versions.props | 6 +++--- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 78fa83520f5c..b49d3f9e6d7e 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -277,18 +277,18 @@ https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore 8e941eb42f819adb116b881195158b3887a70a1c - + https://github.com/dotnet/razor - ae120b9fbe2d7af4dcaadd7f3cc5ea8c28ccca96 + 616dc6fd3435bc8289cea9550a7993d750b9af07 - + https://github.com/dotnet/razor - ae120b9fbe2d7af4dcaadd7f3cc5ea8c28ccca96 + 616dc6fd3435bc8289cea9550a7993d750b9af07 - + https://github.com/dotnet/razor - ae120b9fbe2d7af4dcaadd7f3cc5ea8c28ccca96 + 616dc6fd3435bc8289cea9550a7993d750b9af07 https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore diff --git a/eng/Versions.props b/eng/Versions.props index 403af38052bf..e94ee8d9f303 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -175,9 +175,9 @@ - 7.0.0-preview.24081.3 - 7.0.0-preview.24081.3 - 7.0.0-preview.24081.3 + 7.0.0-preview.24102.1 + 7.0.0-preview.24102.1 + 7.0.0-preview.24102.1 From 99ceaab89c3224e05dc7054433233532be57616b Mon Sep 17 00:00:00 2001 From: Mark Li Date: Sat, 3 Feb 2024 02:26:38 -0800 Subject: [PATCH 173/577] update GetValueOrDefault to static --- .../dotnet-tool/install/ToolInstallGlobalOrToolPathCommand.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Cli/dotnet/commands/dotnet-tool/install/ToolInstallGlobalOrToolPathCommand.cs b/src/Cli/dotnet/commands/dotnet-tool/install/ToolInstallGlobalOrToolPathCommand.cs index c2e180495b9e..dc78164bdff6 100644 --- a/src/Cli/dotnet/commands/dotnet-tool/install/ToolInstallGlobalOrToolPathCommand.cs +++ b/src/Cli/dotnet/commands/dotnet-tool/install/ToolInstallGlobalOrToolPathCommand.cs @@ -89,7 +89,7 @@ public ToolInstallGlobalOrToolPathCommand( _errorReporter = (reporter ?? Reporter.Error); } - public T GetValueOrDefault(CliOption option, T defaultOption, ParseResult parseResult) + public static T GetValueOrDefault(CliOption option, T defaultOption, ParseResult parseResult) { if (parseResult.GetResult(option) is { } result && result.GetValueOrDefault() is { } t) From 47c3c910e986f01d13055259fc4e485fe88fa1b1 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" Date: Sat, 3 Feb 2024 13:56:32 +0000 Subject: [PATCH 174/577] Update dependencies from https://github.com/dotnet/razor build 20240203.1 Microsoft.AspNetCore.Mvc.Razor.Extensions.Tooling.Internal , Microsoft.CodeAnalysis.Razor.Tooling.Internal , Microsoft.NET.Sdk.Razor.SourceGenerators.Transport From Version 7.0.0-preview.24102.1 -> To Version 7.0.0-preview.24103.1 --- eng/Version.Details.xml | 12 ++++++------ eng/Versions.props | 6 +++--- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index b49d3f9e6d7e..fb84b4c8bbb9 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -277,18 +277,18 @@ https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore 8e941eb42f819adb116b881195158b3887a70a1c - + https://github.com/dotnet/razor - 616dc6fd3435bc8289cea9550a7993d750b9af07 + 7c2bfb5912f042717fb113c7a6ba472a90e5beec - + https://github.com/dotnet/razor - 616dc6fd3435bc8289cea9550a7993d750b9af07 + 7c2bfb5912f042717fb113c7a6ba472a90e5beec - + https://github.com/dotnet/razor - 616dc6fd3435bc8289cea9550a7993d750b9af07 + 7c2bfb5912f042717fb113c7a6ba472a90e5beec https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore diff --git a/eng/Versions.props b/eng/Versions.props index e94ee8d9f303..0f3df6964c89 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -175,9 +175,9 @@ - 7.0.0-preview.24102.1 - 7.0.0-preview.24102.1 - 7.0.0-preview.24102.1 + 7.0.0-preview.24103.1 + 7.0.0-preview.24103.1 + 7.0.0-preview.24103.1 From 4723eb3124f71fb16fbbbe726e69ec381e1af17c Mon Sep 17 00:00:00 2001 From: Chet Husk Date: Mon, 5 Feb 2024 11:35:58 -0600 Subject: [PATCH 175/577] Remove unused StringWriter from GenerateToolSettingsFile Task (#38378) --- .../Microsoft.NET.Build.Tasks/GenerateToolsSettingsFile.cs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/Tasks/Microsoft.NET.Build.Tasks/GenerateToolsSettingsFile.cs b/src/Tasks/Microsoft.NET.Build.Tasks/GenerateToolsSettingsFile.cs index 080305f4e9bc..984d372c512f 100644 --- a/src/Tasks/Microsoft.NET.Build.Tasks/GenerateToolsSettingsFile.cs +++ b/src/Tasks/Microsoft.NET.Build.Tasks/GenerateToolsSettingsFile.cs @@ -21,10 +21,7 @@ public class GenerateToolsSettingsFile : TaskBase protected override void ExecuteCore() { - using (StringWriter writer = new StringWriter()) - { - GenerateDocument(EntryPointRelativePath, CommandName).Save(ToolsSettingsFilePath); - } + GenerateDocument(EntryPointRelativePath, CommandName).Save(ToolsSettingsFilePath); } internal static XDocument GenerateDocument(string entryPointRelativePath, string commandName) From 2ee7582271ec559688f13c3343c97f4b702566ef Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Mon, 5 Feb 2024 20:22:31 +0000 Subject: [PATCH 176/577] [release/8.0.3xx] Update dependencies from dotnet/msbuild (#38536) [release/8.0.3xx] Update dependencies from dotnet/msbuild --- eng/Version.Details.xml | 12 ++++++------ eng/Versions.props | 4 ++-- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index fb84b4c8bbb9..890cfa090906 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -51,17 +51,17 @@ https://github.com/dotnet/emsdk 201f4dae9d1a1e105d8ba86d7ece61eed1f665e0 - + https://github.com/dotnet/msbuild - 07fd5d51f25134ea3ab3620c66f6501a74df2921 + bea6b4aebe6548d714ca643db9107162965b94d5 - + https://github.com/dotnet/msbuild - 07fd5d51f25134ea3ab3620c66f6501a74df2921 + bea6b4aebe6548d714ca643db9107162965b94d5 - + https://github.com/dotnet/msbuild - 07fd5d51f25134ea3ab3620c66f6501a74df2921 + bea6b4aebe6548d714ca643db9107162965b94d5 diff --git a/eng/Versions.props b/eng/Versions.props index 0f3df6964c89..34986a13521e 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -120,7 +120,7 @@ - 17.10.0-preview-24101-01 + 17.10.0-preview-24105-01 $(MicrosoftBuildPackageVersion) - 17.10.0-preview-24105-01 + 17.10.0-preview-24106-02 $(MicrosoftBuildPackageVersion) - 17.10.0-preview-24101-03 - 17.10.0-preview-24101-03 - 17.10.0-preview-24101-03 + 17.10.0-preview-24106-01 + 17.10.0-preview-24106-01 + 17.10.0-preview-24106-01 From 480ff95491d27ffa0d414a86e48c90a420a51ab1 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" Date: Tue, 6 Feb 2024 14:00:12 +0000 Subject: [PATCH 179/577] Update dependencies from https://github.com/dotnet/razor build 20240205.1 Microsoft.AspNetCore.Mvc.Razor.Extensions.Tooling.Internal , Microsoft.CodeAnalysis.Razor.Tooling.Internal , Microsoft.NET.Sdk.Razor.SourceGenerators.Transport From Version 7.0.0-preview.24103.1 -> To Version 7.0.0-preview.24105.1 --- eng/Version.Details.xml | 12 ++++++------ eng/Versions.props | 6 +++--- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 890cfa090906..bb3b4bc745ee 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -277,18 +277,18 @@ https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore 8e941eb42f819adb116b881195158b3887a70a1c - + https://github.com/dotnet/razor - 7c2bfb5912f042717fb113c7a6ba472a90e5beec + e71445b4873e223d12d0c16bb09a47c06e4355f2 - + https://github.com/dotnet/razor - 7c2bfb5912f042717fb113c7a6ba472a90e5beec + e71445b4873e223d12d0c16bb09a47c06e4355f2 - + https://github.com/dotnet/razor - 7c2bfb5912f042717fb113c7a6ba472a90e5beec + e71445b4873e223d12d0c16bb09a47c06e4355f2 https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore diff --git a/eng/Versions.props b/eng/Versions.props index 34986a13521e..0b77c1de58b6 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -175,9 +175,9 @@ - 7.0.0-preview.24103.1 - 7.0.0-preview.24103.1 - 7.0.0-preview.24103.1 + 7.0.0-preview.24105.1 + 7.0.0-preview.24105.1 + 7.0.0-preview.24105.1 From bafad7148caa0c1bddfc36e4312615f7186ae82a Mon Sep 17 00:00:00 2001 From: Noah Gilson Date: Tue, 6 Feb 2024 16:52:41 -0800 Subject: [PATCH 180/577] Add VS Workload Install Record Creation for both Workload Install and Restore --- .../install/WorkloadInstallCommand.cs | 13 ++++++++++ .../list/VisualStudioWorkloads.cs | 25 +++++++++++++++++++ .../update/WorkloadUpdateCommand.cs | 18 +------------ 3 files changed, 39 insertions(+), 17 deletions(-) diff --git a/src/Cli/dotnet/commands/dotnet-workload/install/WorkloadInstallCommand.cs b/src/Cli/dotnet/commands/dotnet-workload/install/WorkloadInstallCommand.cs index 97a63aea9d47..571665ccaf3b 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/install/WorkloadInstallCommand.cs +++ b/src/Cli/dotnet/commands/dotnet-workload/install/WorkloadInstallCommand.cs @@ -163,6 +163,8 @@ public void InstallWorkloads(IEnumerable workloadIds, bool skipManif manifestsToUpdate = useRollback ? _workloadManifestUpdater.CalculateManifestRollbacks(_fromRollbackDefinition) : _workloadManifestUpdater.CalculateManifestUpdates().Select(m => m.ManifestUpdate); + + WriteSDKInstallRecordsForVSWorkloads(); } InstallWorkloadsWithInstallRecord(_workloadInstaller, workloadIds, _sdkFeatureBand, manifestsToUpdate, offlineCache, useRollback); @@ -188,6 +190,17 @@ internal static void TryRunGarbageCollection(IInstaller workloadInstaller, IRepo } } + private void WriteSDKInstallRecordsForVSWorkloads() + { +#if !DOT_NET_BUILD_FROM_SOURCE + if (OperatingSystem.IsWindows()) + { + // The 'workload restore' command relies on this happening through the existing chain of logic, if this is massively refactored please ensure this is called. + VisualStudioWorkloads.WriteSDKInstallRecordsForVSWorkloads(_workloadInstaller, _workloadResolver, GetInstalledWorkloads(false)); + } +#endif + } + private void InstallWorkloadsWithInstallRecord( IInstaller installer, IEnumerable workloadIds, diff --git a/src/Cli/dotnet/commands/dotnet-workload/list/VisualStudioWorkloads.cs b/src/Cli/dotnet/commands/dotnet-workload/list/VisualStudioWorkloads.cs index e50d2d345d34..a67253c0f8e2 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/list/VisualStudioWorkloads.cs +++ b/src/Cli/dotnet/commands/dotnet-workload/list/VisualStudioWorkloads.cs @@ -3,6 +3,7 @@ using System.Runtime.Versioning; using Microsoft.Deployment.DotNet.Releases; +using Microsoft.DotNet.Workloads.Workload.Install; using Microsoft.DotNet.Workloads.Workload.List; using Microsoft.NET.Sdk.WorkloadManifestReader; using Microsoft.VisualStudio.Setup.Configuration; @@ -119,6 +120,30 @@ internal static void GetInstalledWorkloads(IWorkloadResolver workloadResolver, } } + /// + /// Writes install records for VS Workloads so we later install the packs via the CLI for workloads managed by VS. + /// This is to fix a bug where updating the manifests in the CLI will cause VS to also be told to use these newer workloads via the workload resolver. + /// ... but these workloads don't have their corresponding packs installed as VS doesnt update its workloads as the CLI does. + /// + internal static void WriteSDKInstallRecordsForVSWorkloads(IInstaller workloadInstaller, IWorkloadResolver workloadResolver, + IEnumerable workloadsWithExistingInstallRecords) + { + if (OperatingSystem.IsWindows()) + { + // Do this check to avoid adding an unused & unnecessary method to FileBasedInstallers + if (typeof(NetSdkMsiInstallerClient) == workloadInstaller.GetType()) + { + InstalledWorkloadsCollection vsWorkloads = new(); + GetInstalledWorkloads(workloadResolver, vsWorkloads); + + // Remove workloads with an SDK installation source, as we've already created install records for them, and don't need to again. + var vsOnlyWorkloads = vsWorkloads.AsEnumerable().Where(w => !w.Value.Contains("SDK")).Select(w => new WorkloadId(w.Key)); + var workloadsToWriteRecordsFor = vsOnlyWorkloads.Except(workloadsWithExistingInstallRecords); + ((NetSdkMsiInstallerClient)workloadResolver).WriteWorkloadInstallRecords(workloadsToWriteRecordsFor); + } + } + } + /// /// Gets a list of all Visual Studio instances. /// diff --git a/src/Cli/dotnet/commands/dotnet-workload/update/WorkloadUpdateCommand.cs b/src/Cli/dotnet/commands/dotnet-workload/update/WorkloadUpdateCommand.cs index 29c30482c356..5bd010066914 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/update/WorkloadUpdateCommand.cs +++ b/src/Cli/dotnet/commands/dotnet-workload/update/WorkloadUpdateCommand.cs @@ -144,28 +144,12 @@ public void UpdateWorkloads(bool includePreviews = false, DirectoryPath? offline Reporter.WriteLine(); } - /// - /// Writes install records for VS Workloads so we later install the packs via the CLI for workloads managed by VS. - /// This is to fix a bug where updating the manifests in the CLI will cause VS to also be told to use these newer workloads via the workload resolver. - /// ... but these workloads don't have their corresponding packs installed as VS doesnt update its workloads as the CLI does. - /// private void WriteSDKInstallRecordsForVSWorkloads() { #if !DOT_NET_BUILD_FROM_SOURCE if (OperatingSystem.IsWindows()) { - // Do this gross check to avoid adding an unused & unnecessary method to FileBasedInstallers - if(typeof(NetSdkMsiInstallerClient) == _workloadInstaller.GetType()) - { - InstalledWorkloadsCollection vsWorkloads = new(); - VisualStudioWorkloads.GetInstalledWorkloads(_workloadResolver, vsWorkloads); - // Remove workloads with an SDK installation source, as we've already created install records for them, and don't need to again. - var vsOnlyWorkloads = vsWorkloads.AsEnumerable().Where(w => !w.Value.Contains("SDK")).Select(w => new WorkloadId(w.Key)); - var workloadsWithExistingInstallRecords = GetUpdatableWorkloads(); - var workloadsToWriteRecordsFor = vsOnlyWorkloads.Except(workloadsWithExistingInstallRecords); - - ((NetSdkMsiInstallerClient)_workloadInstaller).WriteWorkloadInstallRecords(workloadsToWriteRecordsFor); - } + VisualStudioWorkloads.WriteSDKInstallRecordsForVSWorkloads(_workloadInstaller, _workloadResolver, GetUpdatableWorkloads()); } #endif } From c8f1df6d84a2fdfea5a5733a0daf21e5a6cf13c9 Mon Sep 17 00:00:00 2001 From: Noah Gilson Date: Wed, 7 Feb 2024 14:19:20 -0800 Subject: [PATCH 181/577] Cast a workload installer, not a resolver (copy paste error) --- .../commands/dotnet-workload/list/VisualStudioWorkloads.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Cli/dotnet/commands/dotnet-workload/list/VisualStudioWorkloads.cs b/src/Cli/dotnet/commands/dotnet-workload/list/VisualStudioWorkloads.cs index a67253c0f8e2..4ac3775cdba5 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/list/VisualStudioWorkloads.cs +++ b/src/Cli/dotnet/commands/dotnet-workload/list/VisualStudioWorkloads.cs @@ -123,7 +123,7 @@ internal static void GetInstalledWorkloads(IWorkloadResolver workloadResolver, /// /// Writes install records for VS Workloads so we later install the packs via the CLI for workloads managed by VS. /// This is to fix a bug where updating the manifests in the CLI will cause VS to also be told to use these newer workloads via the workload resolver. - /// ... but these workloads don't have their corresponding packs installed as VS doesnt update its workloads as the CLI does. + /// ... but these workloads don't have their corresponding packs installed as VS doesn't update its workloads as the CLI does. /// internal static void WriteSDKInstallRecordsForVSWorkloads(IInstaller workloadInstaller, IWorkloadResolver workloadResolver, IEnumerable workloadsWithExistingInstallRecords) @@ -139,7 +139,7 @@ internal static void WriteSDKInstallRecordsForVSWorkloads(IInstaller workloadIns // Remove workloads with an SDK installation source, as we've already created install records for them, and don't need to again. var vsOnlyWorkloads = vsWorkloads.AsEnumerable().Where(w => !w.Value.Contains("SDK")).Select(w => new WorkloadId(w.Key)); var workloadsToWriteRecordsFor = vsOnlyWorkloads.Except(workloadsWithExistingInstallRecords); - ((NetSdkMsiInstallerClient)workloadResolver).WriteWorkloadInstallRecords(workloadsToWriteRecordsFor); + ((NetSdkMsiInstallerClient)workloadInstaller).WriteWorkloadInstallRecords(workloadsToWriteRecordsFor); } } } From 56356e997eee4c6304f93afb1e7d0ebed0beccd0 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Fri, 9 Feb 2024 21:40:15 +0000 Subject: [PATCH 182/577] [release/8.0.3xx] Update dependencies from dotnet/format (#38631) [release/8.0.3xx] Update dependencies from dotnet/format --- NuGet.config | 5 +---- eng/Version.Details.xml | 4 ++-- eng/Versions.props | 2 +- 3 files changed, 4 insertions(+), 7 deletions(-) diff --git a/NuGet.config b/NuGet.config index 68cf6b44395c..f0f46aa5cb53 100644 --- a/NuGet.config +++ b/NuGet.config @@ -6,10 +6,7 @@ - - - - + diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 4e6b8c2ec72f..2a0ff7b3335e 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -73,9 +73,9 @@ 052d1133c78aa5af36c8e100afb91b1b5fc478af - + https://github.com/dotnet/format - 28925c0e519d66c80328aacf973b74e40bb1d5bd + 4ffa2f1691a4ac3ebad3fe840d7a25f35feba635 diff --git a/eng/Versions.props b/eng/Versions.props index 9e40af5dcaa8..7708db9a75ee 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -111,7 +111,7 @@ - 8.0.456602 + 8.0.510703 From 2edcc99d3f1044fd9431b0b9fcab863f4c9a7fc9 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Fri, 9 Feb 2024 21:42:40 +0000 Subject: [PATCH 183/577] [release/8.0.3xx] Update dependencies from dotnet/msbuild (#38627) [release/8.0.3xx] Update dependencies from dotnet/msbuild --- eng/Version.Details.xml | 12 ++++++------ eng/Versions.props | 4 ++-- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 2a0ff7b3335e..d12fb052c503 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -51,17 +51,17 @@ https://github.com/dotnet/emsdk 201f4dae9d1a1e105d8ba86d7ece61eed1f665e0 - + https://github.com/dotnet/msbuild - 668b19903aec6334c05190cb336a10b9a9aba01f + e71eb7a1fc535b438007286c840d7cecc139d13b - + https://github.com/dotnet/msbuild - 668b19903aec6334c05190cb336a10b9a9aba01f + e71eb7a1fc535b438007286c840d7cecc139d13b - + https://github.com/dotnet/msbuild - 668b19903aec6334c05190cb336a10b9a9aba01f + e71eb7a1fc535b438007286c840d7cecc139d13b diff --git a/eng/Versions.props b/eng/Versions.props index 7708db9a75ee..6e66e3afb03d 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -120,7 +120,7 @@ - 17.10.0-preview-24106-02 + 17.10.0-preview-24108-04 $(MicrosoftBuildPackageVersion) - 17.10.0-preview-24106-01 - 17.10.0-preview-24106-01 - 17.10.0-preview-24106-01 + 17.10.0-preview-24107-02 + 17.10.0-preview-24107-02 + 17.10.0-preview-24107-02 From 6089042d06190f2606f42988acb0691e4c10aa8a Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Fri, 9 Feb 2024 21:43:43 +0000 Subject: [PATCH 185/577] [release/8.0.3xx] Update dependencies from dotnet/fsharp (#38629) [release/8.0.3xx] Update dependencies from dotnet/fsharp --- eng/Version.Details.xml | 8 ++++---- eng/Versions.props | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index a2228364e3fd..5f60f770d51e 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -64,13 +64,13 @@ e71eb7a1fc535b438007286c840d7cecc139d13b - + https://github.com/dotnet/fsharp - 052d1133c78aa5af36c8e100afb91b1b5fc478af + dcbb4d3d5bd6de445d48002367a474f7b0fc199c - + https://github.com/dotnet/fsharp - 052d1133c78aa5af36c8e100afb91b1b5fc478af + dcbb4d3d5bd6de445d48002367a474f7b0fc199c diff --git a/eng/Versions.props b/eng/Versions.props index c13d938ac844..54b44f973a85 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -150,7 +150,7 @@ - 12.8.300-beta.24101.1 + 12.8.300-beta.24108.7 From 01376e11d17c415323b948891435af848d7effb6 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Fri, 9 Feb 2024 21:44:05 +0000 Subject: [PATCH 186/577] [release/8.0.3xx] Update dependencies from dotnet/razor (#38630) [release/8.0.3xx] Update dependencies from dotnet/razor --- eng/Version.Details.xml | 12 ++++++------ eng/Versions.props | 6 +++--- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 5f60f770d51e..88fd56fcebd6 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -277,18 +277,18 @@ https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore 8e941eb42f819adb116b881195158b3887a70a1c - + https://github.com/dotnet/razor - e71445b4873e223d12d0c16bb09a47c06e4355f2 + eaa8ee7de408aacfc0f0ad69891287e9d9e2f786 - + https://github.com/dotnet/razor - e71445b4873e223d12d0c16bb09a47c06e4355f2 + eaa8ee7de408aacfc0f0ad69891287e9d9e2f786 - + https://github.com/dotnet/razor - e71445b4873e223d12d0c16bb09a47c06e4355f2 + eaa8ee7de408aacfc0f0ad69891287e9d9e2f786 https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore diff --git a/eng/Versions.props b/eng/Versions.props index 54b44f973a85..5baadbf0805d 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -175,9 +175,9 @@ - 7.0.0-preview.24105.1 - 7.0.0-preview.24105.1 - 7.0.0-preview.24105.1 + 7.0.0-preview.24108.2 + 7.0.0-preview.24108.2 + 7.0.0-preview.24108.2 From fd4c111e4349a465ad29c2ceb4992b4ffe486e34 Mon Sep 17 00:00:00 2001 From: Daniel Plaisted Date: Mon, 12 Feb 2024 08:54:10 -0500 Subject: [PATCH 187/577] Code review feedback --- .../DependencyProvider.cs | 2 +- ...NetSdkMsiInstallerClient.InstallRecords.cs | 55 ++++++++++--------- .../install/NetSdkMsiInstallerClient.cs | 8 +-- 3 files changed, 34 insertions(+), 31 deletions(-) diff --git a/src/Cli/Microsoft.DotNet.Cli.Utils/DependencyProvider.cs b/src/Cli/Microsoft.DotNet.Cli.Utils/DependencyProvider.cs index 46c926577e48..89cfa926049e 100644 --- a/src/Cli/Microsoft.DotNet.Cli.Utils/DependencyProvider.cs +++ b/src/Cli/Microsoft.DotNet.Cli.Utils/DependencyProvider.cs @@ -186,7 +186,7 @@ public static DependencyProvider GetFromProductCode(string productCode, bool all { using RegistryKey providerKey = dependenciesKey.OpenSubKey(providerKeyName); var thisProductCode = providerKey?.GetValue(null) as string ?? null; - if (thisProductCode == productCode) + if (string.Equals(thisProductCode, productCode, StringComparison.OrdinalIgnoreCase)) { return new DependencyProvider(providerKeyName, allUsers); } diff --git a/src/Cli/dotnet/commands/dotnet-workload/install/NetSdkMsiInstallerClient.InstallRecords.cs b/src/Cli/dotnet/commands/dotnet-workload/install/NetSdkMsiInstallerClient.InstallRecords.cs index 29b1a50db1e5..af1d9c9af30e 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/install/NetSdkMsiInstallerClient.InstallRecords.cs +++ b/src/Cli/dotnet/commands/dotnet-workload/install/NetSdkMsiInstallerClient.InstallRecords.cs @@ -18,7 +18,25 @@ namespace Microsoft.DotNet.Workloads.Workload.Install { internal partial class NetSdkMsiInstallerClient { - internal static readonly Guid UpgradeCodeNamespaceUuid = Guid.Parse("C743F81B-B3B5-4E77-9F6D-474EFF3A722C"); + // Manifest IDs are lowercased on disk, we need to map them back to the original casing to generate the right UpgradeCode + private static readonly string[] CasedManifestIds = + [ + "Microsoft.NET.Sdk.Android", + "Microsoft.NET.Sdk.Aspire", + "Microsoft.NET.Sdk.iOS", + "Microsoft.NET.Sdk.MacCatalyst", + "Microsoft.NET.Sdk.macOS", + "Microsoft.NET.Sdk.Maui", + "Microsoft.NET.Sdk.tvOS", + "Microsoft.NET.Workload.Emscripten.Current", + "Microsoft.NET.Workload.Emscripten.net6", + "Microsoft.NET.Workload.Emscripten.net7", + "Microsoft.NET.Workload.Mono.ToolChain.Current", + "Microsoft.NET.Workload.Mono.ToolChain.net6", + "Microsoft.NET.Workload.Mono.ToolChain.net7", + ]; + + private static readonly IReadOnlyDictionary ManifestIdCasing = CasedManifestIds.ToDictionary(id => id.ToLowerInvariant()).AsReadOnly(); protected List GetWorkloadManifestRecords() { @@ -72,29 +90,6 @@ protected List GetWorkloadManifestRecords() // To do the mapping to installed MSIs, we rely on the fact that the MSI UpgradeCode is generated in a stable fashion from the // NuGet package identity and platform: Utils.CreateUuid(UpgradeCodeNamespaceUuid, $"{Package.Identity};{Platform}") // The NuGet package identity used is the vanilla (non-MSI) manifest package, for example Microsoft.NET.Workload.Mono.ToolChain.Current.Manifest-8.0.100 version 8.0.0 - - // Manifest IDs are lowercased on disk, we need to map them back to the original casing to generate the right UpgradeCode - Dictionary manifestIDCasing = new Dictionary(); - foreach (var casedManifestID in new[] - { - "Microsoft.NET.Sdk.Android", - "Microsoft.NET.Sdk.Aspire", - "Microsoft.NET.Sdk.iOS", - "Microsoft.NET.Sdk.MacCatalyst", - "Microsoft.NET.Sdk.macOS", - "Microsoft.NET.Sdk.Maui", - "Microsoft.NET.Sdk.tvOS", - "Microsoft.NET.Workload.Emscripten.Current", - "Microsoft.NET.Workload.Emscripten.net6", - "Microsoft.NET.Workload.Emscripten.net7", - "Microsoft.NET.Workload.Mono.ToolChain.Current", - "Microsoft.NET.Workload.Mono.ToolChain.net6", - "Microsoft.NET.Workload.Mono.ToolChain.net7", - }) - { - manifestIDCasing[casedManifestID.ToLowerInvariant()] = casedManifestID; - } - string sdkManifestFolder = Path.Combine(DotNetHome, "sdk-manifests"); foreach (var manifestFeatureBandFolder in Directory.GetDirectories(sdkManifestFolder)) @@ -115,7 +110,7 @@ protected List GetWorkloadManifestRecords() foreach (var manifestIDFolder in Directory.GetDirectories(manifestFeatureBandFolder)) { var lowerCasedManifestID = Path.GetFileName(manifestIDFolder); - if (manifestIDCasing.TryGetValue(lowerCasedManifestID, out string manifestID)) + if (ManifestIdCasing.TryGetValue(lowerCasedManifestID, out string manifestID)) { foreach (var manifestVersionFolder in Directory.GetDirectories(manifestIDFolder)) { @@ -164,7 +159,7 @@ protected List GetWorkloadManifestRecords() } else if (relatedProductCodes.Count > 1) { - Log.LogMessage($"Found multiple product codes for {uuidName}, which is not expected for side-by-side manifests."); + Log.LogMessage($"Found multiple product codes for {uuidName}, which is not expected for side-by-side manifests: {string.Join(' ', relatedProductCodes)}"); } else { @@ -188,6 +183,14 @@ protected List GetWorkloadManifestRecords() return manifestRecords; } + // From dotnet/arcade: https://github.com/dotnet/arcade/blob/c3f5cbfb2829795294f5c2d9fa5a0522f47e91fb/src/Microsoft.DotNet.Build.Tasks.Workloads/src/Msi/MsiBase.wix.cs#L38 + /// + /// The UUID namespace to use for generating an upgrade code. + /// + internal static readonly Guid UpgradeCodeNamespaceUuid = Guid.Parse("C743F81B-B3B5-4E77-9F6D-474EFF3A722C"); + + + // From dotnet/arcade: https://github.com/dotnet/arcade/blob/c3f5cbfb2829795294f5c2d9fa5a0522f47e91fb/src/Microsoft.DotNet.Build.Tasks.Workloads/src/Utils.cs#L128 /// /// Generates a version 3 UUID given a namespace UUID and name. This is based on the algorithm described in /// RFC 4122 (https://tools.ietf.org/html/rfc4122), section 4.3. diff --git a/src/Cli/dotnet/commands/dotnet-workload/install/NetSdkMsiInstallerClient.cs b/src/Cli/dotnet/commands/dotnet-workload/install/NetSdkMsiInstallerClient.cs index 022be1690a5e..546347dc3cac 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/install/NetSdkMsiInstallerClient.cs +++ b/src/Cli/dotnet/commands/dotnet-workload/install/NetSdkMsiInstallerClient.cs @@ -141,7 +141,7 @@ public void GarbageCollect(Func getResolverForWorkloa { DependencyProvider depProvider = new DependencyProvider(manifestRecord.ProviderKeyName); - (bool shouldBeInstalled, string reason) shouldBeInstalled(SdkFeatureBand dependentFeatureBand) + (bool shouldBeInstalled, string reason) ShouldBeInstalled(SdkFeatureBand dependentFeatureBand) { if (!installedFeatureBands.Contains(dependentFeatureBand)) { @@ -165,7 +165,7 @@ public void GarbageCollect(Func getResolverForWorkloa } Log?.LogMessage($"Evaluating dependents for workload manifest, dependent: {depProvider}, ID: {manifestRecord.ManifestId}, Version: {manifestRecord.ManifestVersion}, Feature Band: {manifestRecord.ManifestFeatureBand}"); - UpdateDependentReferenceCounts(depProvider, shouldBeInstalled); + UpdateDependentReferenceCounts(depProvider, ShouldBeInstalled); // Recheck the registry to see if there are any remaining dependents. If not, we can // remove the workload manifest. We'll add it to the list and remove the packs at the end. @@ -197,7 +197,7 @@ public void GarbageCollect(Func getResolverForWorkloa { DependencyProvider depProvider = new DependencyProvider(packRecord.ProviderKeyName); - (bool shouldBeInstalled, string reason) shouldBeInstalled(SdkFeatureBand dependentFeatureBand) + (bool shouldBeInstalled, string reason) ShouldBeInstalled(SdkFeatureBand dependentFeatureBand) { if (!installedFeatureBands.Contains(dependentFeatureBand)) { @@ -226,7 +226,7 @@ public void GarbageCollect(Func getResolverForWorkloa Log?.LogMessage($"Evaluating dependents for workload pack, dependent: {depProvider}, MSI ID: {packRecord.MsiId}, MSI version: {packRecord.MsiNuGetVersion}"); - UpdateDependentReferenceCounts(depProvider, shouldBeInstalled); + UpdateDependentReferenceCounts(depProvider, ShouldBeInstalled); // Recheck the registry to see if there are any remaining dependents. If not, we can // remove the workload pack. We'll add it to the list and remove the packs at the end. From 30d8d21ede6cc777dc2a17831945cff261f35839 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Mon, 12 Feb 2024 17:32:52 +0000 Subject: [PATCH 188/577] [release/8.0.3xx] Update dependencies from nuget/nuget.client (#38672) [release/8.0.3xx] Update dependencies from nuget/nuget.client --- eng/Version.Details.xml | 64 ++++++++++++++++++++--------------------- eng/Versions.props | 22 +++++++------- 2 files changed, 43 insertions(+), 43 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 88fd56fcebd6..9a27a250683a 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -115,69 +115,69 @@ https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore 8e941eb42f819adb116b881195158b3887a70a1c - + https://github.com/nuget/nuget.client - f207cbb3530350f785d1b04014e15563cc9b5e03 + 8b658e2eee6391936887b9fd1b39f7918d16a9cb - + https://github.com/nuget/nuget.client - f207cbb3530350f785d1b04014e15563cc9b5e03 + 8b658e2eee6391936887b9fd1b39f7918d16a9cb - + https://github.com/nuget/nuget.client - f207cbb3530350f785d1b04014e15563cc9b5e03 + 8b658e2eee6391936887b9fd1b39f7918d16a9cb - + https://github.com/nuget/nuget.client - f207cbb3530350f785d1b04014e15563cc9b5e03 + 8b658e2eee6391936887b9fd1b39f7918d16a9cb - + https://github.com/nuget/nuget.client - f207cbb3530350f785d1b04014e15563cc9b5e03 + 8b658e2eee6391936887b9fd1b39f7918d16a9cb - + https://github.com/nuget/nuget.client - f207cbb3530350f785d1b04014e15563cc9b5e03 + 8b658e2eee6391936887b9fd1b39f7918d16a9cb - + https://github.com/nuget/nuget.client - f207cbb3530350f785d1b04014e15563cc9b5e03 + 8b658e2eee6391936887b9fd1b39f7918d16a9cb - + https://github.com/nuget/nuget.client - f207cbb3530350f785d1b04014e15563cc9b5e03 + 8b658e2eee6391936887b9fd1b39f7918d16a9cb - + https://github.com/nuget/nuget.client - f207cbb3530350f785d1b04014e15563cc9b5e03 + 8b658e2eee6391936887b9fd1b39f7918d16a9cb - + https://github.com/nuget/nuget.client - f207cbb3530350f785d1b04014e15563cc9b5e03 + 8b658e2eee6391936887b9fd1b39f7918d16a9cb - + https://github.com/nuget/nuget.client - f207cbb3530350f785d1b04014e15563cc9b5e03 + 8b658e2eee6391936887b9fd1b39f7918d16a9cb - + https://github.com/nuget/nuget.client - f207cbb3530350f785d1b04014e15563cc9b5e03 + 8b658e2eee6391936887b9fd1b39f7918d16a9cb - + https://github.com/nuget/nuget.client - f207cbb3530350f785d1b04014e15563cc9b5e03 + 8b658e2eee6391936887b9fd1b39f7918d16a9cb - + https://github.com/nuget/nuget.client - f207cbb3530350f785d1b04014e15563cc9b5e03 + 8b658e2eee6391936887b9fd1b39f7918d16a9cb - + https://github.com/nuget/nuget.client - f207cbb3530350f785d1b04014e15563cc9b5e03 + 8b658e2eee6391936887b9fd1b39f7918d16a9cb - + https://github.com/nuget/nuget.client - f207cbb3530350f785d1b04014e15563cc9b5e03 + 8b658e2eee6391936887b9fd1b39f7918d16a9cb https://github.com/microsoft/vstest diff --git a/eng/Versions.props b/eng/Versions.props index 5baadbf0805d..5ff130911730 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -82,18 +82,18 @@ - 6.10.0-preview.1.18 - 6.10.0-preview.1.18 + 6.10.0-preview.2.32 + 6.10.0-preview.2.32 6.0.0-rc.278 - 6.10.0-preview.1.18 - 6.10.0-preview.1.18 - 6.10.0-preview.1.18 - 6.10.0-preview.1.18 - 6.10.0-preview.1.18 - 6.10.0-preview.1.18 - 6.10.0-preview.1.18 - 6.10.0-preview.1.18 - 6.10.0-preview.1.18 + 6.10.0-preview.2.32 + 6.10.0-preview.2.32 + 6.10.0-preview.2.32 + 6.10.0-preview.2.32 + 6.10.0-preview.2.32 + 6.10.0-preview.2.32 + 6.10.0-preview.2.32 + 6.10.0-preview.2.32 + 6.10.0-preview.2.32 $(NuGetPackagingPackageVersion) $(NuGetProjectModelPackageVersion) From 17257017e48f5179cfefcedf085298e9d539a5a0 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Mon, 12 Feb 2024 17:33:13 +0000 Subject: [PATCH 189/577] [release/8.0.3xx] Update dependencies from dotnet/msbuild (#38673) [release/8.0.3xx] Update dependencies from dotnet/msbuild --- eng/Version.Details.xml | 12 ++++++------ eng/Versions.props | 4 ++-- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 9a27a250683a..7c7527b613de 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -51,17 +51,17 @@ https://github.com/dotnet/emsdk 201f4dae9d1a1e105d8ba86d7ece61eed1f665e0 - + https://github.com/dotnet/msbuild - e71eb7a1fc535b438007286c840d7cecc139d13b + 15f7ddcaafa6622447fa69c1785ab7b3d1183719 - + https://github.com/dotnet/msbuild - e71eb7a1fc535b438007286c840d7cecc139d13b + 15f7ddcaafa6622447fa69c1785ab7b3d1183719 - + https://github.com/dotnet/msbuild - e71eb7a1fc535b438007286c840d7cecc139d13b + 15f7ddcaafa6622447fa69c1785ab7b3d1183719 diff --git a/eng/Versions.props b/eng/Versions.props index 5ff130911730..fc49db390fcb 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -120,7 +120,7 @@ - 17.10.0-preview-24108-04 + 17.10.0-preview-24109-03 $(MicrosoftBuildPackageVersion) - 12.8.300-beta.24108.7 + 12.8.300-beta.24109.4 From 42f34f357a44a937872a3eb9c8220d5d4d7e0fe9 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Mon, 12 Feb 2024 17:36:19 +0000 Subject: [PATCH 191/577] [release/8.0.3xx] Update dependencies from dotnet/razor (#38675) [release/8.0.3xx] Update dependencies from dotnet/razor --- eng/Version.Details.xml | 12 ++++++------ eng/Versions.props | 6 +++--- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 8a913eefd47c..9e03fb7f0406 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -277,18 +277,18 @@ https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore 8e941eb42f819adb116b881195158b3887a70a1c - + https://github.com/dotnet/razor - eaa8ee7de408aacfc0f0ad69891287e9d9e2f786 + 9bd9433008944b67709b8cbe521a6838e050943e - + https://github.com/dotnet/razor - eaa8ee7de408aacfc0f0ad69891287e9d9e2f786 + 9bd9433008944b67709b8cbe521a6838e050943e - + https://github.com/dotnet/razor - eaa8ee7de408aacfc0f0ad69891287e9d9e2f786 + 9bd9433008944b67709b8cbe521a6838e050943e https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore diff --git a/eng/Versions.props b/eng/Versions.props index d807a3b3540e..b3feafb59074 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -175,9 +175,9 @@ - 7.0.0-preview.24108.2 - 7.0.0-preview.24108.2 - 7.0.0-preview.24108.2 + 7.0.0-preview.24110.1 + 7.0.0-preview.24110.1 + 7.0.0-preview.24110.1 From 4e4e4964db4a859e898264486bee44e9ff95f8c8 Mon Sep 17 00:00:00 2001 From: Daniel Plaisted Date: Sun, 11 Feb 2024 22:03:01 -0500 Subject: [PATCH 192/577] Fix issue where applying rollback file would incorrectly uninstall workload packs --- .../update/WorkloadUpdateCommand.cs | 14 +++++----- .../IWorkloadManifestProvider.cs | 1 + .../SdkDirectoryWorkloadManifestProvider.cs | 26 +++++++++++++------ .../TempDirectoryWorkloadManifestProvider.cs | 2 ++ .../WorkloadResolver.cs | 3 +++ .../FakeManifestProvider.cs | 4 +++ .../MockManifestProvider.cs | 2 ++ 7 files changed, 38 insertions(+), 14 deletions(-) diff --git a/src/Cli/dotnet/commands/dotnet-workload/update/WorkloadUpdateCommand.cs b/src/Cli/dotnet/commands/dotnet-workload/update/WorkloadUpdateCommand.cs index a14ad7e4d00b..80cdf1cc0091 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/update/WorkloadUpdateCommand.cs +++ b/src/Cli/dotnet/commands/dotnet-workload/update/WorkloadUpdateCommand.cs @@ -166,12 +166,6 @@ private void UpdateWorkloadsWithInstallRecord( _workloadInstaller.InstallWorkloadManifest(manifestUpdate, context, offlineCache, useRollback); } - _workloadResolver.RefreshWorkloadManifests(); - - var workloads = GetUpdatableWorkloads(); - - _workloadInstaller.InstallWorkloads(workloads, sdkFeatureBand, context, offlineCache); - if (useRollback) { _workloadInstaller.SaveInstallStateManifestVersions(sdkFeatureBand, GetInstallStateContents(manifestsToUpdate)); @@ -180,10 +174,18 @@ private void UpdateWorkloadsWithInstallRecord( { _workloadInstaller.RemoveManifestsFromInstallState(sdkFeatureBand); } + + _workloadResolver.RefreshWorkloadManifests(); + + var workloads = GetUpdatableWorkloads(); + + _workloadInstaller.InstallWorkloads(workloads, sdkFeatureBand, context, offlineCache); }, rollback: () => { // Nothing to roll back at this level, InstallWorkloadManifest and InstallWorkloadPacks handle the transaction rollback + // We will refresh the workload manifests to make sure that the resolver has the updated state after the rollback + _workloadResolver.RefreshWorkloadManifests(); }); } diff --git a/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/IWorkloadManifestProvider.cs b/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/IWorkloadManifestProvider.cs index 28b2862b979b..a3acabf746e2 100644 --- a/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/IWorkloadManifestProvider.cs +++ b/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/IWorkloadManifestProvider.cs @@ -9,6 +9,7 @@ namespace Microsoft.NET.Sdk.WorkloadManifestReader /// public interface IWorkloadManifestProvider { + void RefreshWorkloadManifests(); IEnumerable GetManifests(); string GetSdkFeatureBand(); diff --git a/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/SdkDirectoryWorkloadManifestProvider.cs b/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/SdkDirectoryWorkloadManifestProvider.cs index 286a858bdebf..95e51e8a6e6a 100644 --- a/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/SdkDirectoryWorkloadManifestProvider.cs +++ b/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/SdkDirectoryWorkloadManifestProvider.cs @@ -25,9 +25,12 @@ public partial class SdkDirectoryWorkloadManifestProvider : IWorkloadManifestPro "microsoft.net.workload.maccatalyst", "microsoft.net.workload.macos", "microsoft.net.workload.tvos", "microsoft.net.workload.mono.toolchain" }; private readonly Dictionary? _knownManifestIdsAndOrder; - private readonly WorkloadSet? _workloadSet; - private readonly WorkloadSet? _manifestsFromInstallState; - private readonly string? _installStateFilePath; + private readonly string? _workloadSetVersionFromConstructor; + private readonly string? _globalJsonPathFromConstructor; + + private WorkloadSet? _workloadSet; + private WorkloadSet? _manifestsFromInstallState; + private string? _installStateFilePath; public SdkDirectoryWorkloadManifestProvider(string sdkRootPath, string sdkVersion, string? userProfileDir, string? globalJsonPath) : this(sdkRootPath, sdkVersion, Environment.GetEnvironmentVariable, userProfileDir, globalJsonPath) @@ -59,6 +62,8 @@ internal SdkDirectoryWorkloadManifestProvider(string sdkRootPath, string sdkVers _sdkRootPath = sdkRootPath; _sdkVersionBand = new SdkFeatureBand(sdkVersion); + _workloadSetVersionFromConstructor = workloadSetVersion; + _globalJsonPathFromConstructor = globalJsonPath; var knownManifestIdsFilePath = Path.Combine(_sdkRootPath, "sdk", sdkVersion, "KnownWorkloadManifests.txt"); if (!File.Exists(knownManifestIdsFilePath)) @@ -102,23 +107,28 @@ internal SdkDirectoryWorkloadManifestProvider(string sdkRootPath, string sdkVers _manifestRoots ??= Array.Empty(); + RefreshWorkloadManifests(); + } + + public void RefreshWorkloadManifests() + { var availableWorkloadSets = GetAvailableWorkloadSets(); - if (workloadSetVersion != null) + if (_workloadSetVersionFromConstructor != null) { - if (!availableWorkloadSets.TryGetValue(workloadSetVersion, out _workloadSet)) + if (!availableWorkloadSets.TryGetValue(_workloadSetVersionFromConstructor, out _workloadSet)) { - throw new FileNotFoundException(string.Format(Strings.WorkloadVersionNotFound, workloadSetVersion)); + throw new FileNotFoundException(string.Format(Strings.WorkloadVersionNotFound, _workloadSetVersionFromConstructor)); } } else { - string? globalJsonWorkloadSetVersion = GlobalJsonReader.GetWorkloadVersionFromGlobalJson(globalJsonPath); + string? globalJsonWorkloadSetVersion = GlobalJsonReader.GetWorkloadVersionFromGlobalJson(_globalJsonPathFromConstructor); if (globalJsonWorkloadSetVersion != null) { if (!availableWorkloadSets.TryGetValue(globalJsonWorkloadSetVersion, out _workloadSet)) { - throw new FileNotFoundException(string.Format(Strings.WorkloadVersionFromGlobalJsonNotFound, globalJsonWorkloadSetVersion, globalJsonPath)); + throw new FileNotFoundException(string.Format(Strings.WorkloadVersionFromGlobalJsonNotFound, globalJsonWorkloadSetVersion, _globalJsonPathFromConstructor)); } } else diff --git a/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/TempDirectoryWorkloadManifestProvider.cs b/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/TempDirectoryWorkloadManifestProvider.cs index 950d99753bd7..b45a463771b2 100644 --- a/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/TempDirectoryWorkloadManifestProvider.cs +++ b/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/TempDirectoryWorkloadManifestProvider.cs @@ -14,6 +14,8 @@ public TempDirectoryWorkloadManifestProvider(string manifestsPath, string sdkFea _sdkVersionBand = sdkFeatureBand; } + public void RefreshWorkloadManifests() { } + public IEnumerable GetManifests() { diff --git a/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/WorkloadResolver.cs b/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/WorkloadResolver.cs index 5e5e28cab079..040a0f7a1495 100644 --- a/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/WorkloadResolver.cs +++ b/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/WorkloadResolver.cs @@ -102,6 +102,8 @@ public void RefreshWorkloadManifests() { throw new InvalidOperationException("Resolver was created without provider and cannot be refreshed"); } + + _manifestProvider.RefreshWorkloadManifests(); _manifests.Clear(); LoadManifestsFromProvider(_manifestProvider); ComposeWorkloadManifests(); @@ -735,6 +737,7 @@ public EmptyWorkloadManifestProvider(string sdkFeatureBand) _sdkFeatureBand = sdkFeatureBand; } + public void RefreshWorkloadManifests() { } public Dictionary GetAvailableWorkloadSets() => new(); public IEnumerable GetManifests() => Enumerable.Empty(); public string GetSdkFeatureBand() => _sdkFeatureBand; diff --git a/src/Tests/Microsoft.NET.Sdk.WorkloadManifestReader.Tests/FakeManifestProvider.cs b/src/Tests/Microsoft.NET.Sdk.WorkloadManifestReader.Tests/FakeManifestProvider.cs index 8f53b3051420..92ddb64a0829 100644 --- a/src/Tests/Microsoft.NET.Sdk.WorkloadManifestReader.Tests/FakeManifestProvider.cs +++ b/src/Tests/Microsoft.NET.Sdk.WorkloadManifestReader.Tests/FakeManifestProvider.cs @@ -20,6 +20,8 @@ public FakeManifestProvider(params (string manifest, string? localizationCatalog _filePaths = filePaths; } + public void RefreshWorkloadManifests() { } + public IEnumerable GetManifests() { foreach (var filePath in _filePaths) @@ -46,6 +48,8 @@ internal class InMemoryFakeManifestProvider : IWorkloadManifestProvider, IEnumer public void Add(string id, string content) => _manifests.Add((id, Encoding.UTF8.GetBytes(content))); + public void RefreshWorkloadManifests() { } + public IEnumerable GetManifests() => _manifests.Select(m => new ReadableWorkloadManifest( m.id, diff --git a/src/Tests/dotnet-workload-install.Tests/MockManifestProvider.cs b/src/Tests/dotnet-workload-install.Tests/MockManifestProvider.cs index fb94af52d370..f3298b0d654b 100644 --- a/src/Tests/dotnet-workload-install.Tests/MockManifestProvider.cs +++ b/src/Tests/dotnet-workload-install.Tests/MockManifestProvider.cs @@ -29,6 +29,8 @@ public MockManifestProvider(params (string name, string path, string featureBand public Dictionary GetAvailableWorkloadSets() => new(); + public void RefreshWorkloadManifests() { } + public IEnumerable GetManifests() { foreach ((var id, var path, var featureBand) in _manifests) From a9a10728dd22cccea8449c7f5b664927659c204b Mon Sep 17 00:00:00 2001 From: Daniel Plaisted Date: Tue, 13 Feb 2024 13:19:09 -0500 Subject: [PATCH 193/577] Fix install with rollback --- .../install/WorkloadInstallCommand.cs | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/Cli/dotnet/commands/dotnet-workload/install/WorkloadInstallCommand.cs b/src/Cli/dotnet/commands/dotnet-workload/install/WorkloadInstallCommand.cs index 97a63aea9d47..82547363054e 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/install/WorkloadInstallCommand.cs +++ b/src/Cli/dotnet/commands/dotnet-workload/install/WorkloadInstallCommand.cs @@ -216,6 +216,11 @@ private void InstallWorkloadsWithInstallRecord( installer.InstallWorkloadManifest(manifestUpdate, context, offlineCache, rollback); } + if (usingRollback) + { + installer.SaveInstallStateManifestVersions(sdkFeatureBand, GetInstallStateContents(manifestsToUpdate)); + } + _workloadResolver.RefreshWorkloadManifests(); installer.InstallWorkloads(workloadIds, sdkFeatureBand, context, offlineCache); @@ -227,10 +232,6 @@ private void InstallWorkloadsWithInstallRecord( recordRepo.WriteWorkloadInstallationRecord(workloadId, sdkFeatureBand); } - if (usingRollback) - { - installer.SaveInstallStateManifestVersions(sdkFeatureBand, GetInstallStateContents(manifestsToUpdate)); - } }, rollback: () => { @@ -242,6 +243,9 @@ private void InstallWorkloadsWithInstallRecord( installer.GetWorkloadInstallationRecordRepository() .DeleteWorkloadInstallationRecord(workloadId, sdkFeatureBand); } + + // Refresh the workload manifests to make sure that the resolver has the updated state after the rollback + _workloadResolver.RefreshWorkloadManifests(); }); } From 813434365c5ec9285947b2c7a53a8df58fee7eda Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Tue, 13 Feb 2024 20:47:07 +0000 Subject: [PATCH 194/577] [release/8.0.3xx] Update dependencies from microsoft/vstest (#38721) [release/8.0.3xx] Update dependencies from microsoft/vstest --- NuGet.config | 1 - eng/Version.Details.xml | 12 ++++++------ eng/Versions.props | 6 +++--- 3 files changed, 9 insertions(+), 10 deletions(-) diff --git a/NuGet.config b/NuGet.config index a7b4a3b27f65..f0f46aa5cb53 100644 --- a/NuGet.config +++ b/NuGet.config @@ -11,7 +11,6 @@ - diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 9e03fb7f0406..2cd888ba0841 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -179,18 +179,18 @@ https://github.com/nuget/nuget.client 8b658e2eee6391936887b9fd1b39f7918d16a9cb - + https://github.com/microsoft/vstest - f21d0dae0b91fe59e4afa92166bd721ddd2f0036 + 5eed35d4a9a2e1b688eb86c5e4171e370a561b2a - + https://github.com/microsoft/vstest - f21d0dae0b91fe59e4afa92166bd721ddd2f0036 + 5eed35d4a9a2e1b688eb86c5e4171e370a561b2a - + https://github.com/microsoft/vstest - f21d0dae0b91fe59e4afa92166bd721ddd2f0036 + 5eed35d4a9a2e1b688eb86c5e4171e370a561b2a https://dev.azure.com/dnceng/internal/_git/dotnet-runtime diff --git a/eng/Versions.props b/eng/Versions.props index b3feafb59074..cb18b0047f28 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -99,9 +99,9 @@ - 17.10.0-preview-24107-02 - 17.10.0-preview-24107-02 - 17.10.0-preview-24107-02 + 17.10.0-preview-24112-02 + 17.10.0-preview-24112-02 + 17.10.0-preview-24112-02 From b76f306e56498e363652c34a8c0f0704846a2a66 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Tue, 13 Feb 2024 20:47:20 +0000 Subject: [PATCH 195/577] [release/8.0.3xx] Update dependencies from dotnet/fsharp (#38722) [release/8.0.3xx] Update dependencies from dotnet/fsharp --- eng/Version.Details.xml | 8 ++++---- eng/Versions.props | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 2cd888ba0841..f495d08708c5 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -64,13 +64,13 @@ 15f7ddcaafa6622447fa69c1785ab7b3d1183719 - + https://github.com/dotnet/fsharp - 099e0ae7d788bb0f53f14b5c349012c33bff3372 + 9de468a9bcd1dd5f3791639e0be2227aee0696a7 - + https://github.com/dotnet/fsharp - 099e0ae7d788bb0f53f14b5c349012c33bff3372 + 9de468a9bcd1dd5f3791639e0be2227aee0696a7 diff --git a/eng/Versions.props b/eng/Versions.props index cb18b0047f28..ce4114e49bcd 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -150,7 +150,7 @@ - 12.8.300-beta.24109.4 + 12.8.300-beta.24112.4 From ff9e2c6f223d006a93bc2dcf172c2ab364fc5d9c Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Tue, 13 Feb 2024 20:47:34 +0000 Subject: [PATCH 196/577] [release/8.0.3xx] Update dependencies from dotnet/razor (#38723) [release/8.0.3xx] Update dependencies from dotnet/razor --- eng/Version.Details.xml | 12 ++++++------ eng/Versions.props | 6 +++--- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index f495d08708c5..e54094422509 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -277,18 +277,18 @@ https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore 8e941eb42f819adb116b881195158b3887a70a1c - + https://github.com/dotnet/razor - 9bd9433008944b67709b8cbe521a6838e050943e + f7ea4168060fa228acc3175604a3013bd94134a6 - + https://github.com/dotnet/razor - 9bd9433008944b67709b8cbe521a6838e050943e + f7ea4168060fa228acc3175604a3013bd94134a6 - + https://github.com/dotnet/razor - 9bd9433008944b67709b8cbe521a6838e050943e + f7ea4168060fa228acc3175604a3013bd94134a6 https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore diff --git a/eng/Versions.props b/eng/Versions.props index ce4114e49bcd..c4c53022269f 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -175,9 +175,9 @@ - 7.0.0-preview.24110.1 - 7.0.0-preview.24110.1 - 7.0.0-preview.24110.1 + 7.0.0-preview.24112.4 + 7.0.0-preview.24112.4 + 7.0.0-preview.24112.4 From 31796416d2fcfc5106435bafc46ee80440544579 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Wed, 14 Feb 2024 11:49:39 +0000 Subject: [PATCH 197/577] [release/8.0.3xx] Update dependencies from dotnet/roslyn (#38156) [release/8.0.3xx] Update dependencies from dotnet/roslyn - Workaround missing ref modifier for ref structs (#38179) - Remove workaround - Merge branch 'release/8.0.3xx' into darc-release/8.0.3xx-d6592c21-e955-4ad8-aad0-4f2a55ebac18 - Allow System.Drawing.Common prebuilt Per https://github.com/dotnet/source-build-reference-packages/pull/892#pullrequestreview-1878062640. --- eng/SourceBuildPrebuiltBaseline.xml | 3 ++ eng/Version.Details.xml | 28 +++++++++---------- eng/Versions.props | 14 +++++----- .../SyntaxGeneratorExtensions.cs | 21 ++++---------- .../CSharpFileBuilderTests.cs | 6 ++-- 5 files changed, 33 insertions(+), 39 deletions(-) diff --git a/eng/SourceBuildPrebuiltBaseline.xml b/eng/SourceBuildPrebuiltBaseline.xml index 3dcc5ba862f5..d27ee35f4f45 100644 --- a/eng/SourceBuildPrebuiltBaseline.xml +++ b/eng/SourceBuildPrebuiltBaseline.xml @@ -37,4 +37,7 @@ is only applicable to 8.0.1xx. --> + + + diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index e54094422509..410a870a119a 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -78,34 +78,34 @@ 4ffa2f1691a4ac3ebad3fe840d7a25f35feba635 - + https://github.com/dotnet/roslyn - 3cd939f76803da435c20b082a5cfcc844386fcfb + 892d5f01f7f41dfe7fcd82522276c5628255ef74 - + https://github.com/dotnet/roslyn - 3cd939f76803da435c20b082a5cfcc844386fcfb + 892d5f01f7f41dfe7fcd82522276c5628255ef74 - + https://github.com/dotnet/roslyn - 3cd939f76803da435c20b082a5cfcc844386fcfb + 892d5f01f7f41dfe7fcd82522276c5628255ef74 - + https://github.com/dotnet/roslyn - 3cd939f76803da435c20b082a5cfcc844386fcfb + 892d5f01f7f41dfe7fcd82522276c5628255ef74 - + https://github.com/dotnet/roslyn - 3cd939f76803da435c20b082a5cfcc844386fcfb + 892d5f01f7f41dfe7fcd82522276c5628255ef74 - + https://github.com/dotnet/roslyn - 3cd939f76803da435c20b082a5cfcc844386fcfb + 892d5f01f7f41dfe7fcd82522276c5628255ef74 - + https://github.com/dotnet/roslyn - 3cd939f76803da435c20b082a5cfcc844386fcfb + 892d5f01f7f41dfe7fcd82522276c5628255ef74 https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore diff --git a/eng/Versions.props b/eng/Versions.props index c4c53022269f..250b82422ff3 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -154,13 +154,13 @@ - 4.10.0-1.24067.21 - 4.10.0-1.24067.21 - 4.10.0-1.24067.21 - 4.10.0-1.24067.21 - 4.10.0-1.24067.21 - 4.10.0-1.24067.21 - 4.10.0-1.24067.21 + 4.10.0-2.24112.13 + 4.10.0-2.24112.13 + 4.10.0-2.24112.13 + 4.10.0-2.24112.13 + 4.10.0-2.24112.13 + 4.10.0-2.24112.13 + 4.10.0-2.24112.13 $(MicrosoftNetCompilersToolsetPackageVersion) diff --git a/src/GenAPI/Microsoft.DotNet.GenAPI/SyntaxGeneratorExtensions.cs b/src/GenAPI/Microsoft.DotNet.GenAPI/SyntaxGeneratorExtensions.cs index 984d1e60a2cd..7cc5c73865c6 100644 --- a/src/GenAPI/Microsoft.DotNet.GenAPI/SyntaxGeneratorExtensions.cs +++ b/src/GenAPI/Microsoft.DotNet.GenAPI/SyntaxGeneratorExtensions.cs @@ -80,22 +80,13 @@ public static SyntaxNode DeclarationExt(this SyntaxGenerator syntaxGenerator, IS } } - if (symbol is IEventSymbol eventSymbol) + if (symbol is IEventSymbol eventSymbol && !eventSymbol.IsAbstract) { - if (eventSymbol.IsAbstract) - { - // TODO: remove a work around solution after the Roslyn issue https://github.com/dotnet/roslyn/issues/66966 is fixed - EventFieldDeclarationSyntax eventDeclaration = (EventFieldDeclarationSyntax)syntaxGenerator.Declaration(symbol); - return eventDeclaration.AddModifiers(SyntaxFactory.Token(SyntaxKind.AbstractKeyword)); - } - else - { - // adds generation of add & remove accessors for the non abstract events. - return syntaxGenerator.CustomEventDeclaration(eventSymbol.Name, - syntaxGenerator.TypeExpression(eventSymbol.Type), - eventSymbol.DeclaredAccessibility, - DeclarationModifiers.From(eventSymbol)); - } + // adds generation of add & remove accessors for the non abstract events. + return syntaxGenerator.CustomEventDeclaration(eventSymbol.Name, + syntaxGenerator.TypeExpression(eventSymbol.Type), + eventSymbol.DeclaredAccessibility, + DeclarationModifiers.From(eventSymbol)); } if (symbol is IPropertySymbol propertySymbol) diff --git a/src/Tests/Microsoft.DotNet.GenAPI.Tests/CSharpFileBuilderTests.cs b/src/Tests/Microsoft.DotNet.GenAPI.Tests/CSharpFileBuilderTests.cs index 94fabc2fc4ae..2d7fb43dcd25 100644 --- a/src/Tests/Microsoft.DotNet.GenAPI.Tests/CSharpFileBuilderTests.cs +++ b/src/Tests/Microsoft.DotNet.GenAPI.Tests/CSharpFileBuilderTests.cs @@ -159,7 +159,7 @@ internal partial struct InternalStruct { } - public readonly partial struct PublicReadonlyRefStruct + public readonly ref partial struct PublicReadonlyRefStruct { } @@ -167,7 +167,7 @@ public readonly partial struct PublicReadonlyStruct { } - public partial struct PublicRefStruct + public ref partial struct PublicRefStruct { } @@ -2919,7 +2919,7 @@ public static void M(this object c, scoped System.ReadOnlySpan values) { } expected: """ namespace N { - public partial struct C + public ref partial struct C where T : unmanaged { public required (string? k, dynamic v, nint n) X { get { throw null; } init { } } From 67085515119d3576b1df0acefc1d950e0c343024 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" Date: Wed, 14 Feb 2024 13:52:46 +0000 Subject: [PATCH 198/577] Update dependencies from https://github.com/microsoft/vstest build 20240213.2 Microsoft.NET.Test.Sdk , Microsoft.TestPlatform.Build , Microsoft.TestPlatform.CLI From Version 17.10.0-preview-24112-02 -> To Version 17.10.0-preview-24113-02 --- eng/Version.Details.xml | 12 ++++++------ eng/Versions.props | 6 +++--- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 410a870a119a..93a8153c34a6 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -179,18 +179,18 @@ https://github.com/nuget/nuget.client 8b658e2eee6391936887b9fd1b39f7918d16a9cb - + https://github.com/microsoft/vstest - 5eed35d4a9a2e1b688eb86c5e4171e370a561b2a + 8013ffe0d6569902dc085f697741ee55059f1199 - + https://github.com/microsoft/vstest - 5eed35d4a9a2e1b688eb86c5e4171e370a561b2a + 8013ffe0d6569902dc085f697741ee55059f1199 - + https://github.com/microsoft/vstest - 5eed35d4a9a2e1b688eb86c5e4171e370a561b2a + 8013ffe0d6569902dc085f697741ee55059f1199 https://dev.azure.com/dnceng/internal/_git/dotnet-runtime diff --git a/eng/Versions.props b/eng/Versions.props index 250b82422ff3..6ede6620b8f5 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -99,9 +99,9 @@ - 17.10.0-preview-24112-02 - 17.10.0-preview-24112-02 - 17.10.0-preview-24112-02 + 17.10.0-preview-24113-02 + 17.10.0-preview-24113-02 + 17.10.0-preview-24113-02 From b97db0d2065d1152dda35d1fd9a8b3f80a342609 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" Date: Wed, 14 Feb 2024 13:53:37 +0000 Subject: [PATCH 199/577] Update dependencies from https://github.com/dotnet/razor build 20240213.2 Microsoft.AspNetCore.Mvc.Razor.Extensions.Tooling.Internal , Microsoft.CodeAnalysis.Razor.Tooling.Internal , Microsoft.NET.Sdk.Razor.SourceGenerators.Transport From Version 7.0.0-preview.24112.4 -> To Version 7.0.0-preview.24113.2 --- eng/Version.Details.xml | 12 ++++++------ eng/Versions.props | 6 +++--- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 410a870a119a..801b805ad0a4 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -277,18 +277,18 @@ https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore 8e941eb42f819adb116b881195158b3887a70a1c - + https://github.com/dotnet/razor - f7ea4168060fa228acc3175604a3013bd94134a6 + 90821780eb485a66734f1d68a40a047d55345a39 - + https://github.com/dotnet/razor - f7ea4168060fa228acc3175604a3013bd94134a6 + 90821780eb485a66734f1d68a40a047d55345a39 - + https://github.com/dotnet/razor - f7ea4168060fa228acc3175604a3013bd94134a6 + 90821780eb485a66734f1d68a40a047d55345a39 https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore diff --git a/eng/Versions.props b/eng/Versions.props index 250b82422ff3..f33e23886d05 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -175,9 +175,9 @@ - 7.0.0-preview.24112.4 - 7.0.0-preview.24112.4 - 7.0.0-preview.24112.4 + 7.0.0-preview.24113.2 + 7.0.0-preview.24113.2 + 7.0.0-preview.24113.2 From f3d3ce740df9a42b7faa3b4263cddfb23e93e8e5 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" Date: Wed, 14 Feb 2024 13:56:25 +0000 Subject: [PATCH 200/577] Update dependencies from https://github.com/dotnet/arcade build 20240209.2 Microsoft.DotNet.Arcade.Sdk , Microsoft.DotNet.Helix.Sdk , Microsoft.DotNet.SignTool , Microsoft.DotNet.XUnitExtensions From Version 8.0.0-beta.24081.5 -> To Version 8.0.0-beta.24109.2 --- eng/Version.Details.xml | 16 ++++++++-------- eng/Versions.props | 4 ++-- eng/common/post-build/publish-using-darc.ps1 | 4 ++-- .../templates/job/publish-build-assets.yml | 14 +++++++------- eng/common/templates/post-build/post-build.yml | 16 ++++++++-------- .../templates/variables/pool-providers.yml | 12 ++++++------ global.json | 4 ++-- 7 files changed, 35 insertions(+), 35 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 410a870a119a..0fb4d7ab77e0 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -475,22 +475,22 @@ - + https://github.com/dotnet/arcade - be88b08c41971b52ec11aec05ef31e72185d4a1f + 26e06f1515561b634abf0f9e511f29d1baf56be5 - + https://github.com/dotnet/arcade - be88b08c41971b52ec11aec05ef31e72185d4a1f + 26e06f1515561b634abf0f9e511f29d1baf56be5 - + https://github.com/dotnet/arcade - be88b08c41971b52ec11aec05ef31e72185d4a1f + 26e06f1515561b634abf0f9e511f29d1baf56be5 - + https://github.com/dotnet/arcade - be88b08c41971b52ec11aec05ef31e72185d4a1f + 26e06f1515561b634abf0f9e511f29d1baf56be5 https://dev.azure.com/dnceng/internal/_git/dotnet-runtime diff --git a/eng/Versions.props b/eng/Versions.props index 250b82422ff3..a2676ff7ff1e 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -34,7 +34,7 @@ 7.0.0 4.0.0 7.0.0 - 8.0.0-beta.24081.5 + 8.0.0-beta.24109.2 7.0.0-preview.22423.2 8.0.0 4.3.0 @@ -209,7 +209,7 @@ 6.12.0 6.1.0 - 8.0.0-beta.24081.5 + 8.0.0-beta.24109.2 4.18.4 1.3.2 8.0.0-beta.23607.1 diff --git a/eng/common/post-build/publish-using-darc.ps1 b/eng/common/post-build/publish-using-darc.ps1 index 1e779fec4dd1..5a3a32ea8d75 100644 --- a/eng/common/post-build/publish-using-darc.ps1 +++ b/eng/common/post-build/publish-using-darc.ps1 @@ -12,7 +12,7 @@ param( try { . $PSScriptRoot\post-build-utils.ps1 - $darc = Get-Darc + $darc = Get-Darc $optionalParams = [System.Collections.ArrayList]::new() @@ -46,7 +46,7 @@ try { } Write-Host 'done.' -} +} catch { Write-Host $_ Write-PipelineTelemetryError -Category 'PromoteBuild' -Message "There was an error while trying to publish build '$BuildId' to default channels." diff --git a/eng/common/templates/job/publish-build-assets.yml b/eng/common/templates/job/publish-build-assets.yml index fa5446c093dd..8ec0151def21 100644 --- a/eng/common/templates/job/publish-build-assets.yml +++ b/eng/common/templates/job/publish-build-assets.yml @@ -58,7 +58,7 @@ jobs: demands: Cmd # If it's not devdiv, it's dnceng ${{ if ne(variables['System.TeamProject'], 'DevDiv') }}: - name: $(DncEngInternalBuildPool) + name: NetCore1ESPool-Publishing-Internal demands: ImageOverride -equals windows.vs2019.amd64 steps: @@ -71,7 +71,7 @@ jobs: checkDownloadedFiles: true condition: ${{ parameters.condition }} continueOnError: ${{ parameters.continueOnError }} - + - task: NuGetAuthenticate@1 - task: PowerShell@2 @@ -86,7 +86,7 @@ jobs: /p:OfficialBuildId=$(Build.BuildNumber) condition: ${{ parameters.condition }} continueOnError: ${{ parameters.continueOnError }} - + - task: powershell@2 displayName: Create ReleaseConfigs Artifact inputs: @@ -95,7 +95,7 @@ jobs: Add-Content -Path "$(Build.StagingDirectory)/ReleaseConfigs.txt" -Value $(BARBuildId) Add-Content -Path "$(Build.StagingDirectory)/ReleaseConfigs.txt" -Value "$(DefaultChannels)" Add-Content -Path "$(Build.StagingDirectory)/ReleaseConfigs.txt" -Value $(IsStableBuild) - + - task: PublishBuildArtifacts@1 displayName: Publish ReleaseConfigs Artifact inputs: @@ -121,7 +121,7 @@ jobs: - task: PublishBuildArtifacts@1 displayName: Publish SymbolPublishingExclusionsFile Artifact - condition: eq(variables['SymbolExclusionFile'], 'true') + condition: eq(variables['SymbolExclusionFile'], 'true') inputs: PathtoPublish: '$(Build.SourcesDirectory)/eng/SymbolPublishingExclusionsFile.txt' PublishLocation: Container @@ -137,7 +137,7 @@ jobs: displayName: Publish Using Darc inputs: filePath: $(Build.SourcesDirectory)/eng/common/post-build/publish-using-darc.ps1 - arguments: -BuildId $(BARBuildId) + arguments: -BuildId $(BARBuildId) -PublishingInfraVersion 3 -AzdoToken '$(publishing-dnceng-devdiv-code-r-build-re)' -MaestroToken '$(MaestroApiAccessToken)' @@ -148,4 +148,4 @@ jobs: - ${{ if eq(parameters.enablePublishBuildArtifacts, 'true') }}: - template: /eng/common/templates/steps/publish-logs.yml parameters: - JobLabel: 'Publish_Artifacts_Logs' + JobLabel: 'Publish_Artifacts_Logs' diff --git a/eng/common/templates/post-build/post-build.yml b/eng/common/templates/post-build/post-build.yml index 3f74abf7ce0f..aba44a25a338 100644 --- a/eng/common/templates/post-build/post-build.yml +++ b/eng/common/templates/post-build/post-build.yml @@ -39,7 +39,7 @@ parameters: displayName: Enable NuGet validation type: boolean default: true - + - name: publishInstallersAndChecksums displayName: Publish installers and checksums type: boolean @@ -131,8 +131,8 @@ stages: displayName: Validate inputs: filePath: $(Build.SourcesDirectory)/eng/common/post-build/nuget-validation.ps1 - arguments: -PackagesPath $(Build.ArtifactStagingDirectory)/PackageArtifacts/ - -ToolDestinationPath $(Agent.BuildDirectory)/Extract/ + arguments: -PackagesPath $(Build.ArtifactStagingDirectory)/PackageArtifacts/ + -ToolDestinationPath $(Agent.BuildDirectory)/Extract/ - job: displayName: Signing Validation @@ -221,9 +221,9 @@ stages: displayName: Validate inputs: filePath: $(Build.SourcesDirectory)/eng/common/post-build/sourcelink-validation.ps1 - arguments: -InputPath $(Build.ArtifactStagingDirectory)/BlobArtifacts/ - -ExtractPath $(Agent.BuildDirectory)/Extract/ - -GHRepoName $(Build.Repository.Name) + arguments: -InputPath $(Build.ArtifactStagingDirectory)/BlobArtifacts/ + -ExtractPath $(Agent.BuildDirectory)/Extract/ + -GHRepoName $(Build.Repository.Name) -GHCommit $(Build.SourceVersion) -SourcelinkCliVersion $(SourceLinkCLIVersion) continueOnError: true @@ -258,7 +258,7 @@ stages: demands: Cmd # If it's not devdiv, it's dnceng ${{ else }}: - name: $(DncEngInternalBuildPool) + name: NetCore1ESPool-Publishing-Internal demands: ImageOverride -equals windows.vs2019.amd64 steps: - template: setup-maestro-vars.yml @@ -272,7 +272,7 @@ stages: displayName: Publish Using Darc inputs: filePath: $(Build.SourcesDirectory)/eng/common/post-build/publish-using-darc.ps1 - arguments: -BuildId $(BARBuildId) + arguments: -BuildId $(BARBuildId) -PublishingInfraVersion ${{ parameters.publishingInfraVersion }} -AzdoToken '$(publishing-dnceng-devdiv-code-r-build-re)' -MaestroToken '$(MaestroApiAccessToken)' diff --git a/eng/common/templates/variables/pool-providers.yml b/eng/common/templates/variables/pool-providers.yml index 9cc5c550d3b3..d236f9fdbb15 100644 --- a/eng/common/templates/variables/pool-providers.yml +++ b/eng/common/templates/variables/pool-providers.yml @@ -1,15 +1,15 @@ -# Select a pool provider based off branch name. Anything with branch name containing 'release' must go into an -Svc pool, +# Select a pool provider based off branch name. Anything with branch name containing 'release' must go into an -Svc pool, # otherwise it should go into the "normal" pools. This separates out the queueing and billing of released branches. -# Motivation: +# Motivation: # Once a given branch of a repository's output has been officially "shipped" once, it is then considered to be COGS # (Cost of goods sold) and should be moved to a servicing pool provider. This allows both separation of queueing # (allowing release builds and main PR builds to not intefere with each other) and billing (required for COGS. -# Additionally, the pool provider name itself may be subject to change when the .NET Core Engineering Services -# team needs to move resources around and create new and potentially differently-named pools. Using this template +# Additionally, the pool provider name itself may be subject to change when the .NET Core Engineering Services +# team needs to move resources around and create new and potentially differently-named pools. Using this template # file from an Arcade-ified repo helps guard against both having to update one's release/* branches and renaming. -# How to use: +# How to use: # This yaml assumes your shipped product branches use the naming convention "release/..." (which many do). # If we find alternate naming conventions in broad usage it can be added to the condition below. # @@ -54,4 +54,4 @@ variables: False, 'NetCore1ESPool-Internal' ) - ] \ No newline at end of file + ] diff --git a/global.json b/global.json index 9a628d8f0702..b9b4d19763fb 100644 --- a/global.json +++ b/global.json @@ -14,7 +14,7 @@ } }, "msbuild-sdks": { - "Microsoft.DotNet.Arcade.Sdk": "8.0.0-beta.24081.5", - "Microsoft.DotNet.Helix.Sdk": "8.0.0-beta.24081.5" + "Microsoft.DotNet.Arcade.Sdk": "8.0.0-beta.24109.2", + "Microsoft.DotNet.Helix.Sdk": "8.0.0-beta.24109.2" } } From 7a580101c3ba38287df492cf78d946a1637572a0 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" Date: Wed, 14 Feb 2024 19:34:08 +0000 Subject: [PATCH 201/577] Update dependencies from https://github.com/dotnet/arcade build 20240213.2 Microsoft.DotNet.Arcade.Sdk , Microsoft.DotNet.Helix.Sdk , Microsoft.DotNet.SignTool , Microsoft.DotNet.XUnitExtensions From Version 8.0.0-beta.24081.5 -> To Version 8.0.0-beta.24113.2 --- eng/Version.Details.xml | 16 ++++++++-------- eng/Versions.props | 4 ++-- global.json | 4 ++-- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 0fb4d7ab77e0..f61f28f076ed 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -475,22 +475,22 @@ - + https://github.com/dotnet/arcade - 26e06f1515561b634abf0f9e511f29d1baf56be5 + da98edc4c3ea539f109ea320672136ceb32591a7 - + https://github.com/dotnet/arcade - 26e06f1515561b634abf0f9e511f29d1baf56be5 + da98edc4c3ea539f109ea320672136ceb32591a7 - + https://github.com/dotnet/arcade - 26e06f1515561b634abf0f9e511f29d1baf56be5 + da98edc4c3ea539f109ea320672136ceb32591a7 - + https://github.com/dotnet/arcade - 26e06f1515561b634abf0f9e511f29d1baf56be5 + da98edc4c3ea539f109ea320672136ceb32591a7 https://dev.azure.com/dnceng/internal/_git/dotnet-runtime diff --git a/eng/Versions.props b/eng/Versions.props index a2676ff7ff1e..fd71c496b4c8 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -34,7 +34,7 @@ 7.0.0 4.0.0 7.0.0 - 8.0.0-beta.24109.2 + 8.0.0-beta.24113.2 7.0.0-preview.22423.2 8.0.0 4.3.0 @@ -209,7 +209,7 @@ 6.12.0 6.1.0 - 8.0.0-beta.24109.2 + 8.0.0-beta.24113.2 4.18.4 1.3.2 8.0.0-beta.23607.1 diff --git a/global.json b/global.json index b9b4d19763fb..e4a4db23631d 100644 --- a/global.json +++ b/global.json @@ -14,7 +14,7 @@ } }, "msbuild-sdks": { - "Microsoft.DotNet.Arcade.Sdk": "8.0.0-beta.24109.2", - "Microsoft.DotNet.Helix.Sdk": "8.0.0-beta.24109.2" + "Microsoft.DotNet.Arcade.Sdk": "8.0.0-beta.24113.2", + "Microsoft.DotNet.Helix.Sdk": "8.0.0-beta.24113.2" } } From 04f5b268fea66f951b28cb8d11efdb2905e59861 Mon Sep 17 00:00:00 2001 From: dotnet bot Date: Thu, 15 Feb 2024 02:45:43 -0800 Subject: [PATCH 202/577] Localized file check-in by OneLocBuild Task: Build definition ID 140: Build ID 2378822 (#38776) --- src/Cli/dotnet/ToolManifest/xlf/LocalizableStrings.cs.xlf | 2 +- src/Cli/dotnet/ToolManifest/xlf/LocalizableStrings.de.xlf | 2 +- src/Cli/dotnet/ToolManifest/xlf/LocalizableStrings.es.xlf | 2 +- src/Cli/dotnet/ToolManifest/xlf/LocalizableStrings.fr.xlf | 2 +- src/Cli/dotnet/ToolManifest/xlf/LocalizableStrings.it.xlf | 2 +- src/Cli/dotnet/ToolManifest/xlf/LocalizableStrings.ja.xlf | 2 +- src/Cli/dotnet/ToolManifest/xlf/LocalizableStrings.ko.xlf | 2 +- src/Cli/dotnet/ToolManifest/xlf/LocalizableStrings.pl.xlf | 2 +- src/Cli/dotnet/ToolManifest/xlf/LocalizableStrings.pt-BR.xlf | 2 +- src/Cli/dotnet/ToolManifest/xlf/LocalizableStrings.ru.xlf | 2 +- src/Cli/dotnet/ToolManifest/xlf/LocalizableStrings.tr.xlf | 2 +- src/Cli/dotnet/ToolManifest/xlf/LocalizableStrings.zh-Hans.xlf | 2 +- src/Cli/dotnet/ToolManifest/xlf/LocalizableStrings.zh-Hant.xlf | 2 +- .../commands/dotnet-tool/install/xlf/LocalizableStrings.cs.xlf | 2 +- .../commands/dotnet-tool/install/xlf/LocalizableStrings.de.xlf | 2 +- .../commands/dotnet-tool/install/xlf/LocalizableStrings.es.xlf | 2 +- .../commands/dotnet-tool/install/xlf/LocalizableStrings.fr.xlf | 2 +- .../commands/dotnet-tool/install/xlf/LocalizableStrings.it.xlf | 2 +- .../commands/dotnet-tool/install/xlf/LocalizableStrings.ja.xlf | 2 +- .../commands/dotnet-tool/install/xlf/LocalizableStrings.ko.xlf | 2 +- .../commands/dotnet-tool/install/xlf/LocalizableStrings.pl.xlf | 2 +- .../dotnet-tool/install/xlf/LocalizableStrings.pt-BR.xlf | 2 +- .../commands/dotnet-tool/install/xlf/LocalizableStrings.ru.xlf | 2 +- .../commands/dotnet-tool/install/xlf/LocalizableStrings.tr.xlf | 2 +- .../dotnet-tool/install/xlf/LocalizableStrings.zh-Hans.xlf | 2 +- .../dotnet-tool/install/xlf/LocalizableStrings.zh-Hant.xlf | 2 +- src/Cli/dotnet/xlf/CommonLocalizableStrings.cs.xlf | 2 +- src/Cli/dotnet/xlf/CommonLocalizableStrings.de.xlf | 2 +- src/Cli/dotnet/xlf/CommonLocalizableStrings.es.xlf | 2 +- src/Cli/dotnet/xlf/CommonLocalizableStrings.fr.xlf | 2 +- src/Cli/dotnet/xlf/CommonLocalizableStrings.it.xlf | 2 +- src/Cli/dotnet/xlf/CommonLocalizableStrings.ja.xlf | 2 +- src/Cli/dotnet/xlf/CommonLocalizableStrings.ko.xlf | 2 +- src/Cli/dotnet/xlf/CommonLocalizableStrings.pl.xlf | 2 +- src/Cli/dotnet/xlf/CommonLocalizableStrings.pt-BR.xlf | 2 +- src/Cli/dotnet/xlf/CommonLocalizableStrings.ru.xlf | 2 +- src/Cli/dotnet/xlf/CommonLocalizableStrings.tr.xlf | 2 +- src/Cli/dotnet/xlf/CommonLocalizableStrings.zh-Hans.xlf | 2 +- src/Cli/dotnet/xlf/CommonLocalizableStrings.zh-Hant.xlf | 2 +- 39 files changed, 39 insertions(+), 39 deletions(-) diff --git a/src/Cli/dotnet/ToolManifest/xlf/LocalizableStrings.cs.xlf b/src/Cli/dotnet/ToolManifest/xlf/LocalizableStrings.cs.xlf index be0480213746..76df803cd4f9 100644 --- a/src/Cli/dotnet/ToolManifest/xlf/LocalizableStrings.cs.xlf +++ b/src/Cli/dotnet/ToolManifest/xlf/LocalizableStrings.cs.xlf @@ -38,7 +38,7 @@ Pokud si chcete zobrazit seznam prohledaných umístění, zadejte před název Missing 'rollForward' entry. - Missing 'rollForward' entry. + Chybí položka rollForward. diff --git a/src/Cli/dotnet/ToolManifest/xlf/LocalizableStrings.de.xlf b/src/Cli/dotnet/ToolManifest/xlf/LocalizableStrings.de.xlf index 73281330a972..329228f3a879 100644 --- a/src/Cli/dotnet/ToolManifest/xlf/LocalizableStrings.de.xlf +++ b/src/Cli/dotnet/ToolManifest/xlf/LocalizableStrings.de.xlf @@ -38,7 +38,7 @@ Eine Liste der durchsuchten Speicherorte erhalten Sie, indem Sie vor dem Toolnam Missing 'rollForward' entry. - Missing 'rollForward' entry. + Fehlender "rollForward"-Eintrag. diff --git a/src/Cli/dotnet/ToolManifest/xlf/LocalizableStrings.es.xlf b/src/Cli/dotnet/ToolManifest/xlf/LocalizableStrings.es.xlf index 7ec2318a8f70..955ae400fd4f 100644 --- a/src/Cli/dotnet/ToolManifest/xlf/LocalizableStrings.es.xlf +++ b/src/Cli/dotnet/ToolManifest/xlf/LocalizableStrings.es.xlf @@ -38,7 +38,7 @@ Para obtener una lista de ubicaciones buscadas, especifique la opción "-d" dela Missing 'rollForward' entry. - Missing 'rollForward' entry. + Falta la entrada "rollForward". diff --git a/src/Cli/dotnet/ToolManifest/xlf/LocalizableStrings.fr.xlf b/src/Cli/dotnet/ToolManifest/xlf/LocalizableStrings.fr.xlf index 43c177a1996d..a6292c7c9205 100644 --- a/src/Cli/dotnet/ToolManifest/xlf/LocalizableStrings.fr.xlf +++ b/src/Cli/dotnet/ToolManifest/xlf/LocalizableStrings.fr.xlf @@ -38,7 +38,7 @@ Pour obtenir une liste des emplacements de recherche, spécifiez l'option "-d" a Missing 'rollForward' entry. - Missing 'rollForward' entry. + Entrée 'rollForward' manquante. diff --git a/src/Cli/dotnet/ToolManifest/xlf/LocalizableStrings.it.xlf b/src/Cli/dotnet/ToolManifest/xlf/LocalizableStrings.it.xlf index 5d51a00d1668..7c3a8c1b0462 100644 --- a/src/Cli/dotnet/ToolManifest/xlf/LocalizableStrings.it.xlf +++ b/src/Cli/dotnet/ToolManifest/xlf/LocalizableStrings.it.xlf @@ -38,7 +38,7 @@ Per un elenco dei percorso di ricerca, specificare l'opzione "-d" prima del nome Missing 'rollForward' entry. - Missing 'rollForward' entry. + Voce 'rollForward' mancante. diff --git a/src/Cli/dotnet/ToolManifest/xlf/LocalizableStrings.ja.xlf b/src/Cli/dotnet/ToolManifest/xlf/LocalizableStrings.ja.xlf index 8452eaa921c4..2bb0cdd205d7 100644 --- a/src/Cli/dotnet/ToolManifest/xlf/LocalizableStrings.ja.xlf +++ b/src/Cli/dotnet/ToolManifest/xlf/LocalizableStrings.ja.xlf @@ -38,7 +38,7 @@ For a list of locations searched, specify the "-d" option before the tool name.< Missing 'rollForward' entry. - Missing 'rollForward' entry. + 'rollForward' エントリがありません。 diff --git a/src/Cli/dotnet/ToolManifest/xlf/LocalizableStrings.ko.xlf b/src/Cli/dotnet/ToolManifest/xlf/LocalizableStrings.ko.xlf index 03566e31bd82..d7bf5492de01 100644 --- a/src/Cli/dotnet/ToolManifest/xlf/LocalizableStrings.ko.xlf +++ b/src/Cli/dotnet/ToolManifest/xlf/LocalizableStrings.ko.xlf @@ -38,7 +38,7 @@ For a list of locations searched, specify the "-d" option before the tool name.< Missing 'rollForward' entry. - Missing 'rollForward' entry. + 'rollForward' 항목이 없습니다. diff --git a/src/Cli/dotnet/ToolManifest/xlf/LocalizableStrings.pl.xlf b/src/Cli/dotnet/ToolManifest/xlf/LocalizableStrings.pl.xlf index 184502e7c14e..62fc59d7abd7 100644 --- a/src/Cli/dotnet/ToolManifest/xlf/LocalizableStrings.pl.xlf +++ b/src/Cli/dotnet/ToolManifest/xlf/LocalizableStrings.pl.xlf @@ -38,7 +38,7 @@ Aby uzyskać listę przeszukiwanych lokalizacji, określ opcję „-d” przed n Missing 'rollForward' entry. - Missing 'rollForward' entry. + Brak wpisu "rollForward". diff --git a/src/Cli/dotnet/ToolManifest/xlf/LocalizableStrings.pt-BR.xlf b/src/Cli/dotnet/ToolManifest/xlf/LocalizableStrings.pt-BR.xlf index 077c85705e73..b418c6eb5056 100644 --- a/src/Cli/dotnet/ToolManifest/xlf/LocalizableStrings.pt-BR.xlf +++ b/src/Cli/dotnet/ToolManifest/xlf/LocalizableStrings.pt-BR.xlf @@ -38,7 +38,7 @@ Para obter uma lista de localizações pesquisadas, especifique a opção "-d" a Missing 'rollForward' entry. - Missing 'rollForward' entry. + Entrada 'rollForward' ausente. diff --git a/src/Cli/dotnet/ToolManifest/xlf/LocalizableStrings.ru.xlf b/src/Cli/dotnet/ToolManifest/xlf/LocalizableStrings.ru.xlf index 7d43d9bc7fd1..5bfd82d01820 100644 --- a/src/Cli/dotnet/ToolManifest/xlf/LocalizableStrings.ru.xlf +++ b/src/Cli/dotnet/ToolManifest/xlf/LocalizableStrings.ru.xlf @@ -38,7 +38,7 @@ For a list of locations searched, specify the "-d" option before the tool name.< Missing 'rollForward' entry. - Missing 'rollForward' entry. + Отсутствует запись rollForward. diff --git a/src/Cli/dotnet/ToolManifest/xlf/LocalizableStrings.tr.xlf b/src/Cli/dotnet/ToolManifest/xlf/LocalizableStrings.tr.xlf index ae521217b629..00e8bdc592a2 100644 --- a/src/Cli/dotnet/ToolManifest/xlf/LocalizableStrings.tr.xlf +++ b/src/Cli/dotnet/ToolManifest/xlf/LocalizableStrings.tr.xlf @@ -38,7 +38,7 @@ Aranan konumların bir listesi için aracın adından önce "-d" seçeneğini be Missing 'rollForward' entry. - Missing 'rollForward' entry. + 'rollForward' girişi eksik. diff --git a/src/Cli/dotnet/ToolManifest/xlf/LocalizableStrings.zh-Hans.xlf b/src/Cli/dotnet/ToolManifest/xlf/LocalizableStrings.zh-Hans.xlf index 5fe274276893..bca5b5255265 100644 --- a/src/Cli/dotnet/ToolManifest/xlf/LocalizableStrings.zh-Hans.xlf +++ b/src/Cli/dotnet/ToolManifest/xlf/LocalizableStrings.zh-Hans.xlf @@ -38,7 +38,7 @@ For a list of locations searched, specify the "-d" option before the tool name.< Missing 'rollForward' entry. - Missing 'rollForward' entry. + 缺少“rollForward”条目。 diff --git a/src/Cli/dotnet/ToolManifest/xlf/LocalizableStrings.zh-Hant.xlf b/src/Cli/dotnet/ToolManifest/xlf/LocalizableStrings.zh-Hant.xlf index c843cea44165..0a73248fb8d6 100644 --- a/src/Cli/dotnet/ToolManifest/xlf/LocalizableStrings.zh-Hant.xlf +++ b/src/Cli/dotnet/ToolManifest/xlf/LocalizableStrings.zh-Hant.xlf @@ -38,7 +38,7 @@ For a list of locations searched, specify the "-d" option before the tool name.< Missing 'rollForward' entry. - Missing 'rollForward' entry. + 遺漏 'rollForward' 項目。 diff --git a/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.cs.xlf b/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.cs.xlf index c10453509089..5d2446e57a9b 100644 --- a/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.cs.xlf +++ b/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.cs.xlf @@ -90,7 +90,7 @@ Pokud chcete vytvořit manifest, použijte příkaz dotnet new tool-manifest, ob Allow a .NET tool to roll forward to newer versions of the .NET runtime if the runtime it targets isn't installed. - Allow a .NET tool to roll forward to newer versions of the .NET runtime if the runtime it targets isn't installed. + Povolí nástroji .NET přejít na novější verze modulu .NET runtime, pokud není nainstalován modul runtime, na který cílí. diff --git a/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.de.xlf b/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.de.xlf index 388a9618a438..a594ad8dccce 100644 --- a/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.de.xlf +++ b/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.de.xlf @@ -90,7 +90,7 @@ Wenn Sie ein Manifest erstellen möchten, verwenden Sie "dotnet new tool-manifes Allow a .NET tool to roll forward to newer versions of the .NET runtime if the runtime it targets isn't installed. - Allow a .NET tool to roll forward to newer versions of the .NET runtime if the runtime it targets isn't installed. + Ermöglicht einem .NET-Tool, ein Rollforward auf neuere Versionen der .NET-Runtime auszuführen, wenn die Runtime, auf die es abzielt, nicht installiert ist. diff --git a/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.es.xlf b/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.es.xlf index ca6a3b8da751..d5292983e37c 100644 --- a/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.es.xlf +++ b/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.es.xlf @@ -90,7 +90,7 @@ Si desea crear un manifiesto, utilice "dotnet new tool-manifest", normalmente en Allow a .NET tool to roll forward to newer versions of the .NET runtime if the runtime it targets isn't installed. - Allow a .NET tool to roll forward to newer versions of the .NET runtime if the runtime it targets isn't installed. + Permitir que una herramienta .NET se revierta a versiones más recientes del entorno de ejecución de .NET si el entorno de ejecución al que se dirige no está instalado. diff --git a/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.fr.xlf b/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.fr.xlf index 4fa8740f0afb..daed41262aea 100644 --- a/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.fr.xlf +++ b/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.fr.xlf @@ -90,7 +90,7 @@ Si vous souhaitez créer un manifeste, utilisez 'dotnet new tool-manifest', gén Allow a .NET tool to roll forward to newer versions of the .NET runtime if the runtime it targets isn't installed. - Allow a .NET tool to roll forward to newer versions of the .NET runtime if the runtime it targets isn't installed. + Autorisez un outil .NET à être restauré par progression vers des versions plus récentes du runtime .NET si le runtime qu’il cible n’est pas installé. diff --git a/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.it.xlf b/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.it.xlf index f88449997376..bf4300523c75 100644 --- a/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.it.xlf +++ b/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.it.xlf @@ -90,7 +90,7 @@ Se si vuole creare un manifesto, usare `dotnet new tool-manifest`, in genere nel Allow a .NET tool to roll forward to newer versions of the .NET runtime if the runtime it targets isn't installed. - Allow a .NET tool to roll forward to newer versions of the .NET runtime if the runtime it targets isn't installed. + Consente a uno strumento .NET di eseguire il roll forward alle versioni più recenti del runtime .NET se il runtime a cui è destinato non è installato. diff --git a/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.ja.xlf b/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.ja.xlf index eeb2b6f09898..9de440884dc6 100644 --- a/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.ja.xlf +++ b/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.ja.xlf @@ -90,7 +90,7 @@ If you would like to create a manifest, use `dotnet new tool-manifest`, usually Allow a .NET tool to roll forward to newer versions of the .NET runtime if the runtime it targets isn't installed. - Allow a .NET tool to roll forward to newer versions of the .NET runtime if the runtime it targets isn't installed. + 対象となるランタイムがインストールされていない場合、.NET ツールが新しいバージョンの .NET ランタイムにロールフォワードできるようにします。 diff --git a/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.ko.xlf b/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.ko.xlf index dfef15785b77..3c13ae8c3a89 100644 --- a/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.ko.xlf +++ b/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.ko.xlf @@ -90,7 +90,7 @@ If you would like to create a manifest, use `dotnet new tool-manifest`, usually Allow a .NET tool to roll forward to newer versions of the .NET runtime if the runtime it targets isn't installed. - Allow a .NET tool to roll forward to newer versions of the .NET runtime if the runtime it targets isn't installed. + 대상으로 하는 런타임이 설치되어 있지 않은 경우 .NET 도구가 최신 버전의 .NET 런타임으로 롤백하도록 허용합니다. diff --git a/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.pl.xlf b/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.pl.xlf index 2ac1b909209f..d099c2e53d1d 100644 --- a/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.pl.xlf +++ b/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.pl.xlf @@ -90,7 +90,7 @@ Jeśli chcesz utworzyć manifest, użyj polecenia „dotnet new tool-manifest” Allow a .NET tool to roll forward to newer versions of the .NET runtime if the runtime it targets isn't installed. - Allow a .NET tool to roll forward to newer versions of the .NET runtime if the runtime it targets isn't installed. + Zezwalaj narzędziu platformy .NET na przekazywanie do nowszych wersji środowiska uruchomieniowego platformy .NET, jeśli docelowe środowisko uruchomieniowe nie jest zainstalowane. diff --git a/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.pt-BR.xlf b/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.pt-BR.xlf index 6592d4baff85..7573d26a2d4a 100644 --- a/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.pt-BR.xlf +++ b/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.pt-BR.xlf @@ -90,7 +90,7 @@ Se quiser criar um manifesto, use `dotnet new tool-manifest`, normalmente no dir Allow a .NET tool to roll forward to newer versions of the .NET runtime if the runtime it targets isn't installed. - Allow a .NET tool to roll forward to newer versions of the .NET runtime if the runtime it targets isn't installed. + Permitir que uma ferramenta .NET seja revertida para versões mais recentes do runtime do .NET se o runtime direcionado a ele não estiver instalado. diff --git a/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.ru.xlf b/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.ru.xlf index baadb2a2a235..7d863dce02b9 100644 --- a/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.ru.xlf +++ b/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.ru.xlf @@ -90,7 +90,7 @@ If you would like to create a manifest, use `dotnet new tool-manifest`, usually Allow a .NET tool to roll forward to newer versions of the .NET runtime if the runtime it targets isn't installed. - Allow a .NET tool to roll forward to newer versions of the .NET runtime if the runtime it targets isn't installed. + Разрешить развертывание средства .NET до более новых версий среды выполнения .NET, если целевая среда выполнения не установлена. diff --git a/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.tr.xlf b/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.tr.xlf index 549627312465..ea340df7b328 100644 --- a/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.tr.xlf +++ b/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.tr.xlf @@ -90,7 +90,7 @@ Bir bildirim oluşturmak istiyorsanız 'dotnet new tool-manifest' ifadesini kull Allow a .NET tool to roll forward to newer versions of the .NET runtime if the runtime it targets isn't installed. - Allow a .NET tool to roll forward to newer versions of the .NET runtime if the runtime it targets isn't installed. + Hedeflene çalışma zamanı yüklü değilse bir .NET aracının .NET çalışma zamanının daha yeni sürümlerine ileri sarmal işlemine izin ver. diff --git a/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.zh-Hans.xlf b/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.zh-Hans.xlf index 5f9cc008342e..18abc7bb451e 100644 --- a/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.zh-Hans.xlf +++ b/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.zh-Hans.xlf @@ -90,7 +90,7 @@ If you would like to create a manifest, use `dotnet new tool-manifest`, usually Allow a .NET tool to roll forward to newer versions of the .NET runtime if the runtime it targets isn't installed. - Allow a .NET tool to roll forward to newer versions of the .NET runtime if the runtime it targets isn't installed. + 如果未安装所面向的运行时,则允许 .NET 工具向前滚动到较新版本的 .NET 运行时。 diff --git a/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.zh-Hant.xlf b/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.zh-Hant.xlf index 85888c68c5e8..572a2ced65ab 100644 --- a/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.zh-Hant.xlf +++ b/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.zh-Hant.xlf @@ -90,7 +90,7 @@ If you would like to create a manifest, use `dotnet new tool-manifest`, usually Allow a .NET tool to roll forward to newer versions of the .NET runtime if the runtime it targets isn't installed. - Allow a .NET tool to roll forward to newer versions of the .NET runtime if the runtime it targets isn't installed. + 如果未安裝 .NET 執行階段目標,則允許 .NET 工具向前復原至較新版本的 .NET 執行階段。 diff --git a/src/Cli/dotnet/xlf/CommonLocalizableStrings.cs.xlf b/src/Cli/dotnet/xlf/CommonLocalizableStrings.cs.xlf index 4a67e47ab729..8ae7960c4016 100644 --- a/src/Cli/dotnet/xlf/CommonLocalizableStrings.cs.xlf +++ b/src/Cli/dotnet/xlf/CommonLocalizableStrings.cs.xlf @@ -284,7 +284,7 @@ Výchozí hodnota je false, ale pokud cílíte na .NET 7 nebo nižší a je zad Tool settings file does not exist for the tool {0}. - Tool settings file does not exist for the tool {0}. + Soubor nastavení nástroje {0} neexistuje. diff --git a/src/Cli/dotnet/xlf/CommonLocalizableStrings.de.xlf b/src/Cli/dotnet/xlf/CommonLocalizableStrings.de.xlf index db52457f42b7..e8aed6ea1205 100644 --- a/src/Cli/dotnet/xlf/CommonLocalizableStrings.de.xlf +++ b/src/Cli/dotnet/xlf/CommonLocalizableStrings.de.xlf @@ -284,7 +284,7 @@ Der Standardwert lautet FALSE. Wenn sie jedoch auf .NET 7 oder niedriger abziele Tool settings file does not exist for the tool {0}. - Tool settings file does not exist for the tool {0}. + Die Tooleinstellungsdatei ist für das Tool „{0}“ nicht vorhanden. diff --git a/src/Cli/dotnet/xlf/CommonLocalizableStrings.es.xlf b/src/Cli/dotnet/xlf/CommonLocalizableStrings.es.xlf index cd76474d7e78..a68745a2f01c 100644 --- a/src/Cli/dotnet/xlf/CommonLocalizableStrings.es.xlf +++ b/src/Cli/dotnet/xlf/CommonLocalizableStrings.es.xlf @@ -285,7 +285,7 @@ El valor predeterminado es "false". Sin embargo, cuando el destino es .NET 7 o i Tool settings file does not exist for the tool {0}. - Tool settings file does not exist for the tool {0}. + El archivo de configuración de herramientas no existe para el {0} de herramientas. diff --git a/src/Cli/dotnet/xlf/CommonLocalizableStrings.fr.xlf b/src/Cli/dotnet/xlf/CommonLocalizableStrings.fr.xlf index b036db8acb25..da5f2b48c79d 100644 --- a/src/Cli/dotnet/xlf/CommonLocalizableStrings.fr.xlf +++ b/src/Cli/dotnet/xlf/CommonLocalizableStrings.fr.xlf @@ -285,7 +285,7 @@ La valeur par défaut est « false ». Toutefois, lorsque vous ciblez .NET 7 ou Tool settings file does not exist for the tool {0}. - Tool settings file does not exist for the tool {0}. + Le fichier de paramètres d’outil n’existe pas pour l’outil {0}. diff --git a/src/Cli/dotnet/xlf/CommonLocalizableStrings.it.xlf b/src/Cli/dotnet/xlf/CommonLocalizableStrings.it.xlf index 1030fce6f280..006c842582e2 100644 --- a/src/Cli/dotnet/xlf/CommonLocalizableStrings.it.xlf +++ b/src/Cli/dotnet/xlf/CommonLocalizableStrings.it.xlf @@ -284,7 +284,7 @@ Il valore predefinito è 'false'. Tuttavia, quando la destinazione è .NET 7 o u Tool settings file does not exist for the tool {0}. - Tool settings file does not exist for the tool {0}. + Il file di impostazioni dello strumento non esiste per lo strumento {0}. diff --git a/src/Cli/dotnet/xlf/CommonLocalizableStrings.ja.xlf b/src/Cli/dotnet/xlf/CommonLocalizableStrings.ja.xlf index c6a3c4b3940b..955e9cfc91e8 100644 --- a/src/Cli/dotnet/xlf/CommonLocalizableStrings.ja.xlf +++ b/src/Cli/dotnet/xlf/CommonLocalizableStrings.ja.xlf @@ -284,7 +284,7 @@ The default is 'false.' However, when targeting .NET 7 or lower, the default is Tool settings file does not exist for the tool {0}. - Tool settings file does not exist for the tool {0}. + ツール {0} のツール設定ファイルが存在しません。 diff --git a/src/Cli/dotnet/xlf/CommonLocalizableStrings.ko.xlf b/src/Cli/dotnet/xlf/CommonLocalizableStrings.ko.xlf index 00275492059d..39fa586e98bf 100644 --- a/src/Cli/dotnet/xlf/CommonLocalizableStrings.ko.xlf +++ b/src/Cli/dotnet/xlf/CommonLocalizableStrings.ko.xlf @@ -285,7 +285,7 @@ The default is 'false.' However, when targeting .NET 7 or lower, the default is Tool settings file does not exist for the tool {0}. - Tool settings file does not exist for the tool {0}. + 도구 {0} 도구 설정 파일이 없습니다. diff --git a/src/Cli/dotnet/xlf/CommonLocalizableStrings.pl.xlf b/src/Cli/dotnet/xlf/CommonLocalizableStrings.pl.xlf index 47890260b14e..091c83288270 100644 --- a/src/Cli/dotnet/xlf/CommonLocalizableStrings.pl.xlf +++ b/src/Cli/dotnet/xlf/CommonLocalizableStrings.pl.xlf @@ -284,7 +284,7 @@ Wartość domyślna to „false”. Jednak w przypadku określania wartości doc Tool settings file does not exist for the tool {0}. - Tool settings file does not exist for the tool {0}. + Plik ustawień narzędzia nie istnieje dla narzędzia {0}. diff --git a/src/Cli/dotnet/xlf/CommonLocalizableStrings.pt-BR.xlf b/src/Cli/dotnet/xlf/CommonLocalizableStrings.pt-BR.xlf index 107c1da7d2ea..2a82fe3a1562 100644 --- a/src/Cli/dotnet/xlf/CommonLocalizableStrings.pt-BR.xlf +++ b/src/Cli/dotnet/xlf/CommonLocalizableStrings.pt-BR.xlf @@ -284,7 +284,7 @@ O padrão é falso.' No entanto, ao direcionar o .NET 7 ou inferior, o padrão Tool settings file does not exist for the tool {0}. - Tool settings file does not exist for the tool {0}. + O arquivo de configurações de ferramenta não existe para a ferramenta {0}. diff --git a/src/Cli/dotnet/xlf/CommonLocalizableStrings.ru.xlf b/src/Cli/dotnet/xlf/CommonLocalizableStrings.ru.xlf index 713ddaf2dc19..a2ff7cca1c23 100644 --- a/src/Cli/dotnet/xlf/CommonLocalizableStrings.ru.xlf +++ b/src/Cli/dotnet/xlf/CommonLocalizableStrings.ru.xlf @@ -284,7 +284,7 @@ The default is 'false.' However, when targeting .NET 7 or lower, the default is Tool settings file does not exist for the tool {0}. - Tool settings file does not exist for the tool {0}. + Файл параметров инструмента не существует для данного {0}. diff --git a/src/Cli/dotnet/xlf/CommonLocalizableStrings.tr.xlf b/src/Cli/dotnet/xlf/CommonLocalizableStrings.tr.xlf index 1c0f7f4b4835..953211564e6b 100644 --- a/src/Cli/dotnet/xlf/CommonLocalizableStrings.tr.xlf +++ b/src/Cli/dotnet/xlf/CommonLocalizableStrings.tr.xlf @@ -284,7 +284,7 @@ Varsayılan değer 'false' olur. Ancak çalışma zamanı tanımlayıcısı beli Tool settings file does not exist for the tool {0}. - Tool settings file does not exist for the tool {0}. + Araç ayarları dosyası, araç ayarları {0}. diff --git a/src/Cli/dotnet/xlf/CommonLocalizableStrings.zh-Hans.xlf b/src/Cli/dotnet/xlf/CommonLocalizableStrings.zh-Hans.xlf index 1180bcd41985..2345a2ae6ecd 100644 --- a/src/Cli/dotnet/xlf/CommonLocalizableStrings.zh-Hans.xlf +++ b/src/Cli/dotnet/xlf/CommonLocalizableStrings.zh-Hans.xlf @@ -284,7 +284,7 @@ The default is 'false.' However, when targeting .NET 7 or lower, the default is Tool settings file does not exist for the tool {0}. - Tool settings file does not exist for the tool {0}. + 工具 {0} 的工具设置文件不存在。 diff --git a/src/Cli/dotnet/xlf/CommonLocalizableStrings.zh-Hant.xlf b/src/Cli/dotnet/xlf/CommonLocalizableStrings.zh-Hant.xlf index c453fb9dcb38..aff0bb272f7f 100644 --- a/src/Cli/dotnet/xlf/CommonLocalizableStrings.zh-Hant.xlf +++ b/src/Cli/dotnet/xlf/CommonLocalizableStrings.zh-Hant.xlf @@ -284,7 +284,7 @@ The default is 'false.' However, when targeting .NET 7 or lower, the default is Tool settings file does not exist for the tool {0}. - Tool settings file does not exist for the tool {0}. + 工具 {0} 沒有工具設定檔案。 From 02fc5fe88c8754f7d2fee053c8823d2cdfb64705 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" Date: Thu, 15 Feb 2024 13:37:53 +0000 Subject: [PATCH 203/577] Update dependencies from https://github.com/microsoft/vstest build 20240214.1 Microsoft.NET.Test.Sdk , Microsoft.TestPlatform.Build , Microsoft.TestPlatform.CLI From Version 17.10.0-preview-24112-02 -> To Version 17.10.0-preview-24114-01 --- eng/Version.Details.xml | 12 ++++++------ eng/Versions.props | 6 +++--- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 93a8153c34a6..ba2fbba6929a 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -179,18 +179,18 @@ https://github.com/nuget/nuget.client 8b658e2eee6391936887b9fd1b39f7918d16a9cb - + https://github.com/microsoft/vstest - 8013ffe0d6569902dc085f697741ee55059f1199 + f6c1ca66f0e01c64d663a8780d501432b680d804 - + https://github.com/microsoft/vstest - 8013ffe0d6569902dc085f697741ee55059f1199 + f6c1ca66f0e01c64d663a8780d501432b680d804 - + https://github.com/microsoft/vstest - 8013ffe0d6569902dc085f697741ee55059f1199 + f6c1ca66f0e01c64d663a8780d501432b680d804 https://dev.azure.com/dnceng/internal/_git/dotnet-runtime diff --git a/eng/Versions.props b/eng/Versions.props index 6ede6620b8f5..739b98da2655 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -99,9 +99,9 @@ - 17.10.0-preview-24113-02 - 17.10.0-preview-24113-02 - 17.10.0-preview-24113-02 + 17.10.0-preview-24114-01 + 17.10.0-preview-24114-01 + 17.10.0-preview-24114-01 From 7afe7660f78fe84de331fd40ca997747b6484a5f Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" Date: Thu, 15 Feb 2024 13:38:54 +0000 Subject: [PATCH 204/577] Update dependencies from https://github.com/dotnet/razor build 20240214.2 Microsoft.AspNetCore.Mvc.Razor.Extensions.Tooling.Internal , Microsoft.CodeAnalysis.Razor.Tooling.Internal , Microsoft.NET.Sdk.Razor.SourceGenerators.Transport From Version 7.0.0-preview.24112.4 -> To Version 7.0.0-preview.24114.2 --- eng/Version.Details.xml | 12 ++++++------ eng/Versions.props | 6 +++--- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 801b805ad0a4..5d77f1457fb3 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -277,18 +277,18 @@ https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore 8e941eb42f819adb116b881195158b3887a70a1c - + https://github.com/dotnet/razor - 90821780eb485a66734f1d68a40a047d55345a39 + 4e4a8df527f847cf152970a1eedae822a8fe1843 - + https://github.com/dotnet/razor - 90821780eb485a66734f1d68a40a047d55345a39 + 4e4a8df527f847cf152970a1eedae822a8fe1843 - + https://github.com/dotnet/razor - 90821780eb485a66734f1d68a40a047d55345a39 + 4e4a8df527f847cf152970a1eedae822a8fe1843 https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore diff --git a/eng/Versions.props b/eng/Versions.props index f33e23886d05..ccca116e6ba3 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -175,9 +175,9 @@ - 7.0.0-preview.24113.2 - 7.0.0-preview.24113.2 - 7.0.0-preview.24113.2 + 7.0.0-preview.24114.2 + 7.0.0-preview.24114.2 + 7.0.0-preview.24114.2 From 2843055d793cfe2238c7bd87eef641b5867b8d0f Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" Date: Thu, 15 Feb 2024 13:42:34 +0000 Subject: [PATCH 205/577] Update dependencies from https://github.com/dotnet/arcade build 20240213.2 Microsoft.DotNet.Arcade.Sdk , Microsoft.DotNet.Helix.Sdk , Microsoft.DotNet.SignTool , Microsoft.DotNet.XUnitExtensions From Version 8.0.0-beta.24081.5 -> To Version 8.0.0-beta.24113.2 From 1919c17c87e11d77ba8b909f08d9466224143281 Mon Sep 17 00:00:00 2001 From: dotnet bot Date: Thu, 15 Feb 2024 06:30:15 -0800 Subject: [PATCH 206/577] Localized file check-in by OneLocBuild Task: Build definition ID 140: Build ID 2379624 (#38795) --- src/Cli/dotnet/ToolManifest/xlf/LocalizableStrings.ru.xlf | 2 +- .../commands/dotnet-tool/install/xlf/LocalizableStrings.es.xlf | 2 +- .../commands/dotnet-tool/install/xlf/LocalizableStrings.ko.xlf | 2 +- .../commands/dotnet-tool/install/xlf/LocalizableStrings.ru.xlf | 2 +- src/Cli/dotnet/xlf/CommonLocalizableStrings.es.xlf | 2 +- src/Cli/dotnet/xlf/CommonLocalizableStrings.ko.xlf | 2 +- src/Cli/dotnet/xlf/CommonLocalizableStrings.ru.xlf | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/Cli/dotnet/ToolManifest/xlf/LocalizableStrings.ru.xlf b/src/Cli/dotnet/ToolManifest/xlf/LocalizableStrings.ru.xlf index 5bfd82d01820..77c624c8b694 100644 --- a/src/Cli/dotnet/ToolManifest/xlf/LocalizableStrings.ru.xlf +++ b/src/Cli/dotnet/ToolManifest/xlf/LocalizableStrings.ru.xlf @@ -38,7 +38,7 @@ For a list of locations searched, specify the "-d" option before the tool name.< Missing 'rollForward' entry. - Отсутствует запись rollForward. + Отсутствует запись "rollForward". diff --git a/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.es.xlf b/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.es.xlf index d5292983e37c..63064a9c78cb 100644 --- a/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.es.xlf +++ b/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.es.xlf @@ -90,7 +90,7 @@ Si desea crear un manifiesto, utilice "dotnet new tool-manifest", normalmente en Allow a .NET tool to roll forward to newer versions of the .NET runtime if the runtime it targets isn't installed. - Permitir que una herramienta .NET se revierta a versiones más recientes del entorno de ejecución de .NET si el entorno de ejecución al que se dirige no está instalado. + Permitir que una herramienta .NET se ponga al día a versiones más recientes del runtime de .NET si el runtime al que se dirige no está instalado. diff --git a/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.ko.xlf b/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.ko.xlf index 3c13ae8c3a89..37b702b530e0 100644 --- a/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.ko.xlf +++ b/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.ko.xlf @@ -90,7 +90,7 @@ If you would like to create a manifest, use `dotnet new tool-manifest`, usually Allow a .NET tool to roll forward to newer versions of the .NET runtime if the runtime it targets isn't installed. - 대상으로 하는 런타임이 설치되어 있지 않은 경우 .NET 도구가 최신 버전의 .NET 런타임으로 롤백하도록 허용합니다. + 대상으로 하는 런타임이 설치되지 않은 경우 .NET 도구가 최신 버전의 .NET 런타임으로 롤포워드하도록 허용합니다. diff --git a/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.ru.xlf b/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.ru.xlf index 7d863dce02b9..f755fd7b1699 100644 --- a/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.ru.xlf +++ b/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.ru.xlf @@ -90,7 +90,7 @@ If you would like to create a manifest, use `dotnet new tool-manifest`, usually Allow a .NET tool to roll forward to newer versions of the .NET runtime if the runtime it targets isn't installed. - Разрешить развертывание средства .NET до более новых версий среды выполнения .NET, если целевая среда выполнения не установлена. + Разрешить накат средства .NET до более новых версий среды выполнения .NET, если целевая среда выполнения для средства не установлена. diff --git a/src/Cli/dotnet/xlf/CommonLocalizableStrings.es.xlf b/src/Cli/dotnet/xlf/CommonLocalizableStrings.es.xlf index a68745a2f01c..d0456889ad38 100644 --- a/src/Cli/dotnet/xlf/CommonLocalizableStrings.es.xlf +++ b/src/Cli/dotnet/xlf/CommonLocalizableStrings.es.xlf @@ -285,7 +285,7 @@ El valor predeterminado es "false". Sin embargo, cuando el destino es .NET 7 o i Tool settings file does not exist for the tool {0}. - El archivo de configuración de herramientas no existe para el {0} de herramientas. + El archivo de configuración de herramientas no existe para la herramienta {0}. diff --git a/src/Cli/dotnet/xlf/CommonLocalizableStrings.ko.xlf b/src/Cli/dotnet/xlf/CommonLocalizableStrings.ko.xlf index 39fa586e98bf..d26185296366 100644 --- a/src/Cli/dotnet/xlf/CommonLocalizableStrings.ko.xlf +++ b/src/Cli/dotnet/xlf/CommonLocalizableStrings.ko.xlf @@ -285,7 +285,7 @@ The default is 'false.' However, when targeting .NET 7 or lower, the default is Tool settings file does not exist for the tool {0}. - 도구 {0} 도구 설정 파일이 없습니다. + 도구 {0}에 대한 도구 설정 파일이 없습니다. diff --git a/src/Cli/dotnet/xlf/CommonLocalizableStrings.ru.xlf b/src/Cli/dotnet/xlf/CommonLocalizableStrings.ru.xlf index a2ff7cca1c23..30524ccfe60c 100644 --- a/src/Cli/dotnet/xlf/CommonLocalizableStrings.ru.xlf +++ b/src/Cli/dotnet/xlf/CommonLocalizableStrings.ru.xlf @@ -284,7 +284,7 @@ The default is 'false.' However, when targeting .NET 7 or lower, the default is Tool settings file does not exist for the tool {0}. - Файл параметров инструмента не существует для данного {0}. + Файл параметров для средства {0} не существует. From 8ec7792f8e49b7ad306e82424fc7f2ffd57b81f4 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 15 Feb 2024 08:44:46 -0800 Subject: [PATCH 207/577] [release/8.0.3xx] [`dotnet list package`]Resolve relative paths (#38724) Co-authored-by: Nigusu Yenework --- .../ListPackageReferencesCommand.cs | 8 +- .../GivenDotnetListPackage.cs | 73 +++++++++++++++++++ 2 files changed, 80 insertions(+), 1 deletion(-) diff --git a/src/Cli/dotnet/commands/dotnet-list/dotnet-list-package/ListPackageReferencesCommand.cs b/src/Cli/dotnet/commands/dotnet-list/dotnet-list-package/ListPackageReferencesCommand.cs index d8a8a88f6129..9ca3b27a500f 100644 --- a/src/Cli/dotnet/commands/dotnet-list/dotnet-list-package/ListPackageReferencesCommand.cs +++ b/src/Cli/dotnet/commands/dotnet-list/dotnet-list-package/ListPackageReferencesCommand.cs @@ -16,7 +16,13 @@ internal class ListPackageReferencesCommand : CommandBase public ListPackageReferencesCommand( ParseResult parseResult) : base(parseResult) { - _fileOrDirectory = parseResult.GetValue(ListCommandParser.SlnOrProjectArgument); + _fileOrDirectory = GetAbsolutePath(Directory.GetCurrentDirectory(), + parseResult.GetValue(ListCommandParser.SlnOrProjectArgument)); + } + + private static string GetAbsolutePath(string currentDirectory, string relativePath) + { + return Path.GetFullPath(Path.Combine(currentDirectory, relativePath)); } public override int Execute() diff --git a/src/Tests/dotnet-list-package.Tests/GivenDotnetListPackage.cs b/src/Tests/dotnet-list-package.Tests/GivenDotnetListPackage.cs index b4c78a31b134..263eea206aca 100644 --- a/src/Tests/dotnet-list-package.Tests/GivenDotnetListPackage.cs +++ b/src/Tests/dotnet-list-package.Tests/GivenDotnetListPackage.cs @@ -345,5 +345,78 @@ public void ItRunsInCurrentDirectoryWithPoundInPath() .Should() .Pass(); } + + [Fact] + public void ItRecognizesRelativePathsForAProject() + { + var testAssetName = "TestAppSimple"; + var testAsset = _testAssetsManager + .CopyTestAsset(testAssetName) + .WithSource(); + + var projectDirectory = testAsset.Path; + + new RestoreCommand(testAsset) + .Execute() + .Should() + .Pass(); + + new ListPackageCommand(Log) + .WithProject("TestAppSimple.csproj") + .WithWorkingDirectory(projectDirectory) + .Execute() + .Should() + .Pass(); + } + + [Fact] + public void ItRecognizesRelativePathsForASolution() + { + var sln = "TestAppWithSlnAndSolutionFolders"; + var testAsset = _testAssetsManager + .CopyTestAsset(sln) + .WithSource(); + + var projectDirectory = testAsset.Path; + + new RestoreCommand(testAsset, "App.sln") + .Execute() + .Should() + .Pass(); + + new ListPackageCommand(Log) + .WithProject("App.sln") + .WithWorkingDirectory(projectDirectory) + .Execute() + .Should() + .Pass(); + } + + [Fact] + public void ItRecognizesRelativePathsForASolutionFromSubFolder() + { + var sln = "TestAppWithSlnAndSolutionFolders"; + var testAsset = _testAssetsManager + .CopyTestAsset(sln) + .WithSource(); + + var projectDirectory = testAsset.Path; + + string subFolderName = "subFolder"; + var subFolderPath = Path.Combine(projectDirectory, subFolderName); + Directory.CreateDirectory(subFolderPath); + + new RestoreCommand(testAsset, "App.sln") + .Execute() + .Should() + .Pass(); + + new ListPackageCommand(Log) + .WithProject("../App.sln") + .WithWorkingDirectory(subFolderPath) + .Execute() + .Should() + .Pass(); + } } } From 09237736922a818f423f96e30428abff8226372c Mon Sep 17 00:00:00 2001 From: dotnet bot Date: Thu, 15 Feb 2024 08:47:01 -0800 Subject: [PATCH 208/577] Localized file check-in by OneLocBuild Task: Build definition ID 140: Build ID 2379710 (#38800) --- src/Cli/dotnet/ToolManifest/xlf/LocalizableStrings.pl.xlf | 2 +- src/Cli/dotnet/ToolManifest/xlf/LocalizableStrings.pt-BR.xlf | 2 +- .../commands/dotnet-tool/install/xlf/LocalizableStrings.pl.xlf | 2 +- .../dotnet-tool/install/xlf/LocalizableStrings.pt-BR.xlf | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Cli/dotnet/ToolManifest/xlf/LocalizableStrings.pl.xlf b/src/Cli/dotnet/ToolManifest/xlf/LocalizableStrings.pl.xlf index 62fc59d7abd7..a2bf88c86b76 100644 --- a/src/Cli/dotnet/ToolManifest/xlf/LocalizableStrings.pl.xlf +++ b/src/Cli/dotnet/ToolManifest/xlf/LocalizableStrings.pl.xlf @@ -38,7 +38,7 @@ Aby uzyskać listę przeszukiwanych lokalizacji, określ opcję „-d” przed n Missing 'rollForward' entry. - Brak wpisu "rollForward". + Brak wpisu „rollForward”. diff --git a/src/Cli/dotnet/ToolManifest/xlf/LocalizableStrings.pt-BR.xlf b/src/Cli/dotnet/ToolManifest/xlf/LocalizableStrings.pt-BR.xlf index b418c6eb5056..81e41df7154b 100644 --- a/src/Cli/dotnet/ToolManifest/xlf/LocalizableStrings.pt-BR.xlf +++ b/src/Cli/dotnet/ToolManifest/xlf/LocalizableStrings.pt-BR.xlf @@ -38,7 +38,7 @@ Para obter uma lista de localizações pesquisadas, especifique a opção "-d" a Missing 'rollForward' entry. - Entrada 'rollForward' ausente. + Entrada "rollForward" ausente. diff --git a/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.pl.xlf b/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.pl.xlf index d099c2e53d1d..6d8423ed8c5c 100644 --- a/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.pl.xlf +++ b/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.pl.xlf @@ -90,7 +90,7 @@ Jeśli chcesz utworzyć manifest, użyj polecenia „dotnet new tool-manifest” Allow a .NET tool to roll forward to newer versions of the .NET runtime if the runtime it targets isn't installed. - Zezwalaj narzędziu platformy .NET na przekazywanie do nowszych wersji środowiska uruchomieniowego platformy .NET, jeśli docelowe środowisko uruchomieniowe nie jest zainstalowane. + Zezwalaj narzędziu środowiska .NET na przekazywanie do nowszych wersji środowiska uruchomieniowego .NET, jeśli docelowe środowiska uruchomieniowe nie są zainstalowane. diff --git a/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.pt-BR.xlf b/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.pt-BR.xlf index 7573d26a2d4a..d74b09c99177 100644 --- a/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.pt-BR.xlf +++ b/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.pt-BR.xlf @@ -90,7 +90,7 @@ Se quiser criar um manifesto, use `dotnet new tool-manifest`, normalmente no dir Allow a .NET tool to roll forward to newer versions of the .NET runtime if the runtime it targets isn't installed. - Permitir que uma ferramenta .NET seja revertida para versões mais recentes do runtime do .NET se o runtime direcionado a ele não estiver instalado. + Permitir que uma ferramenta .NET seja revertida para versões mais recentes do runtime do .NET se o runtime ao qual ela se destina não estiver instalado. From bac9b27723ae9d3dc4f6fb8f47d9d2da1a0a0a0c Mon Sep 17 00:00:00 2001 From: Chet Husk Date: Thu, 15 Feb 2024 11:24:32 -0600 Subject: [PATCH 209/577] Include MSBuild version as part of --info, not every build. (#37804) --- .../MSBuildForwardingAppWithoutLogging.cs | 10 +++++++--- src/Cli/dotnet/CommandLineInfo.cs | 1 + .../dotnet-msbuild/MSBuildForwardingApp.cs | 5 +++-- src/Cli/dotnet/commands/dotnet-msbuild/Program.cs | 9 +++++---- src/Cli/dotnet/commands/dotnet-restore/Program.cs | 15 ++++----------- .../dotnet-msbuild/GivenDotnetBuildInvocation.cs | 2 +- .../dotnet-msbuild/GivenDotnetCleanInvocation.cs | 6 +++--- .../dotnet-msbuild/GivenDotnetOsArchOptions.cs | 4 ++-- .../dotnet-msbuild/GivenDotnetPackInvocation.cs | 4 ++-- .../GivenDotnetPublishInvocation.cs | 2 +- .../dotnet-msbuild/GivenDotnetStoreInvocation.cs | 2 +- .../dotnet-msbuild/GivenDotnetTestInvocation.cs | 2 +- 12 files changed, 31 insertions(+), 31 deletions(-) diff --git a/src/Cli/Microsoft.DotNet.Cli.Utils/MSBuildForwardingAppWithoutLogging.cs b/src/Cli/Microsoft.DotNet.Cli.Utils/MSBuildForwardingAppWithoutLogging.cs index 5980424e8495..6018f47e46b7 100644 --- a/src/Cli/Microsoft.DotNet.Cli.Utils/MSBuildForwardingAppWithoutLogging.cs +++ b/src/Cli/Microsoft.DotNet.Cli.Utils/MSBuildForwardingAppWithoutLogging.cs @@ -19,6 +19,10 @@ internal class MSBuildForwardingAppWithoutLogging private static readonly bool UseMSBuildServer = Env.GetEnvironmentVariableAsBool("DOTNET_CLI_USE_MSBUILD_SERVER", false); private static readonly string TerminalLoggerDefault = Env.GetEnvironmentVariable("DOTNET_CLI_CONFIGURE_MSBUILD_TERMINAL_LOGGER"); + public static string MSBuildVersion + { + get => Microsoft.Build.Evaluation.ProjectCollection.DisplayVersion; + } private const string MSBuildExeName = "MSBuild.dll"; private const string SdksDirectoryName = "Sdks"; @@ -39,7 +43,7 @@ internal class MSBuildForwardingAppWithoutLogging private readonly Dictionary _msbuildRequiredEnvironmentVariables = new Dictionary - { + { { "MSBuildExtensionsPath", MSBuildExtensionsPathTestHook ?? AppContext.BaseDirectory }, { "MSBuildSDKsPath", GetMSBuildSDKsPath() }, { "DOTNET_HOST_PATH", GetDotnetPath() }, @@ -48,11 +52,11 @@ internal class MSBuildForwardingAppWithoutLogging private readonly IEnumerable _msbuildRequiredParameters = new List { "-maxcpucount", "-verbosity:m" }; - public MSBuildForwardingAppWithoutLogging(IEnumerable argsToForward, string msbuildPath = null) + public MSBuildForwardingAppWithoutLogging(IEnumerable argsToForward, string msbuildPath = null, bool includeLogo = false) { string defaultMSBuildPath = GetMSBuildExePath(); - _argsToForward = argsToForward; + _argsToForward = includeLogo ? argsToForward : ["-nologo", ..argsToForward]; string tlpDefault = TerminalLoggerDefault; /* TODO: Consider to enable it for dotnet 9+ SDK if (!string.IsNullOrWhiteSpace(tlpDefault)) diff --git a/src/Cli/dotnet/CommandLineInfo.cs b/src/Cli/dotnet/CommandLineInfo.cs index b931a2cbe157..596381bdf8d1 100644 --- a/src/Cli/dotnet/CommandLineInfo.cs +++ b/src/Cli/dotnet/CommandLineInfo.cs @@ -22,6 +22,7 @@ public static void PrintInfo() Reporter.Output.WriteLine($" Version: {Product.Version}"); Reporter.Output.WriteLine($" Commit: {commitSha}"); Reporter.Output.WriteLine($" Workload version: {WorkloadCommandParser.GetWorkloadsVersion()}"); + Reporter.Output.WriteLine($" MSBuild version: {MSBuildForwardingAppWithoutLogging.MSBuildVersion.ToString()}"); Reporter.Output.WriteLine(); Reporter.Output.WriteLine($"{LocalizableStrings.DotNetRuntimeInfoLabel}"); Reporter.Output.WriteLine($" OS Name: {RuntimeEnvironment.OperatingSystem}"); diff --git a/src/Cli/dotnet/commands/dotnet-msbuild/MSBuildForwardingApp.cs b/src/Cli/dotnet/commands/dotnet-msbuild/MSBuildForwardingApp.cs index 23b0296bc434..632eab370eec 100644 --- a/src/Cli/dotnet/commands/dotnet-msbuild/MSBuildForwardingApp.cs +++ b/src/Cli/dotnet/commands/dotnet-msbuild/MSBuildForwardingApp.cs @@ -38,11 +38,12 @@ private static IEnumerable ConcatTelemetryLogger(IEnumerable arg return argsToForward; } - public MSBuildForwardingApp(IEnumerable argsToForward, string msbuildPath = null) + public MSBuildForwardingApp(IEnumerable argsToForward, string msbuildPath = null, bool includeLogo = false) { _forwardingAppWithoutLogging = new MSBuildForwardingAppWithoutLogging( ConcatTelemetryLogger(argsToForward), - msbuildPath); + msbuildPath: msbuildPath, + includeLogo: includeLogo); // Add the performance log location to the environment of the target process. if (PerformanceLogManager.Instance != null && !string.IsNullOrEmpty(PerformanceLogManager.Instance.CurrentLogDirectory)) diff --git a/src/Cli/dotnet/commands/dotnet-msbuild/Program.cs b/src/Cli/dotnet/commands/dotnet-msbuild/Program.cs index 7fb86fe63d69..e4672cdeb906 100644 --- a/src/Cli/dotnet/commands/dotnet-msbuild/Program.cs +++ b/src/Cli/dotnet/commands/dotnet-msbuild/Program.cs @@ -10,13 +10,14 @@ public class MSBuildCommand : MSBuildForwardingApp { public MSBuildCommand (IEnumerable msbuildArgs, - string msbuildPath = null) - : base(msbuildArgs, msbuildPath) + string msbuildPath = null + ) + : base(msbuildArgs, msbuildPath, includeLogo: true) { } public static MSBuildCommand FromArgs(string[] args, string msbuildPath = null) - { + { var parser = Cli.Parser.Instance; var result = parser.ParseFrom("dotnet msbuild", args); return FromParseResult(result, msbuildPath); @@ -32,7 +33,7 @@ public static MSBuildCommand FromParseResult(ParseResult parseResult, string msb MSBuildCommand command = new MSBuildCommand( msbuildArgs, - msbuildPath); + msbuildPath: msbuildPath); return command; } diff --git a/src/Cli/dotnet/commands/dotnet-restore/Program.cs b/src/Cli/dotnet/commands/dotnet-restore/Program.cs index 774a2b1b1e63..0248557356e0 100644 --- a/src/Cli/dotnet/commands/dotnet-restore/Program.cs +++ b/src/Cli/dotnet/commands/dotnet-restore/Program.cs @@ -17,27 +17,20 @@ public RestoreCommand(IEnumerable msbuildArgs, string msbuildPath = null NuGetSignatureVerificationEnabler.ConditionallyEnable(this); } - public static RestoreCommand FromArgs(string[] args, string msbuildPath = null, bool noLogo = true) + public static RestoreCommand FromArgs(string[] args, string msbuildPath = null) { var parser = Parser.Instance; var result = parser.ParseFrom("dotnet restore", args); - return FromParseResult(result, msbuildPath, noLogo); + return FromParseResult(result, msbuildPath); } - public static RestoreCommand FromParseResult(ParseResult result, string msbuildPath = null, bool noLogo = true) + public static RestoreCommand FromParseResult(ParseResult result, string msbuildPath = null) { result.HandleDebugSwitch(); result.ShowHelpOrErrorIfAppropriate(); - var msbuildArgs = new List(); - - if (noLogo) - { - msbuildArgs.Add("-nologo"); - } - - msbuildArgs.Add("-target:Restore"); + List msbuildArgs = ["-target:Restore"]; msbuildArgs.AddRange(result.OptionValuesToBeForwarded(RestoreCommandParser.GetCommand())); diff --git a/src/Tests/dotnet.Tests/dotnet-msbuild/GivenDotnetBuildInvocation.cs b/src/Tests/dotnet.Tests/dotnet-msbuild/GivenDotnetBuildInvocation.cs index f415b52c8e88..0b2f0abebca4 100644 --- a/src/Tests/dotnet.Tests/dotnet-msbuild/GivenDotnetBuildInvocation.cs +++ b/src/Tests/dotnet.Tests/dotnet-msbuild/GivenDotnetBuildInvocation.cs @@ -8,7 +8,7 @@ namespace Microsoft.DotNet.Cli.MSBuild.Tests [Collection(TestConstants.UsesStaticTelemetryState)] public class GivenDotnetBuildInvocation : IClassFixture { - const string ExpectedPrefix = "-maxcpucount -verbosity:m"; + const string ExpectedPrefix = "-maxcpucount -verbosity:m -nologo"; private static readonly string WorkingDirectory = TestPathUtilities.FormatAbsolutePath(nameof(GivenDotnetBuildInvocation)); diff --git a/src/Tests/dotnet.Tests/dotnet-msbuild/GivenDotnetCleanInvocation.cs b/src/Tests/dotnet.Tests/dotnet-msbuild/GivenDotnetCleanInvocation.cs index fe089572002f..2416a1725a69 100644 --- a/src/Tests/dotnet.Tests/dotnet-msbuild/GivenDotnetCleanInvocation.cs +++ b/src/Tests/dotnet.Tests/dotnet-msbuild/GivenDotnetCleanInvocation.cs @@ -8,9 +8,9 @@ namespace Microsoft.DotNet.Cli.MSBuild.Tests [Collection(TestConstants.UsesStaticTelemetryState)] public class GivenDotnetCleanInvocation : IClassFixture { - const string ExpectedPrefix = "-maxcpucount -verbosity:m -verbosity:normal -target:Clean"; + const string ExpectedPrefix = "-maxcpucount -verbosity:m -nologo -verbosity:normal -target:Clean"; - private static readonly string WorkingDirectory = + private static readonly string WorkingDirectory = TestPathUtilities.FormatAbsolutePath(nameof(GivenDotnetCleanInvocation)); [Fact] @@ -18,7 +18,7 @@ public void ItAddsProjectToMsbuildInvocation() { var msbuildPath = ""; CleanCommand.FromArgs(new string[] { "" }, msbuildPath) - .GetArgumentsToMSBuild().Should().Be("-maxcpucount -verbosity:m -verbosity:normal -target:Clean"); + .GetArgumentsToMSBuild().Should().Be("-maxcpucount -verbosity:m -nologo -verbosity:normal -target:Clean"); } [Theory] diff --git a/src/Tests/dotnet.Tests/dotnet-msbuild/GivenDotnetOsArchOptions.cs b/src/Tests/dotnet.Tests/dotnet-msbuild/GivenDotnetOsArchOptions.cs index 658a5590ab25..33eba5f44b33 100644 --- a/src/Tests/dotnet.Tests/dotnet-msbuild/GivenDotnetOsArchOptions.cs +++ b/src/Tests/dotnet.Tests/dotnet-msbuild/GivenDotnetOsArchOptions.cs @@ -14,7 +14,7 @@ public GivenDotnetOsArchOptions(ITestOutputHelper log) : base(log) { } - const string ExpectedPrefix = "-maxcpucount -verbosity:m"; + const string ExpectedPrefix = "-maxcpucount -verbosity:m -nologo"; private static readonly string WorkingDirectory = TestPathUtilities.FormatAbsolutePath(nameof(GivenDotnetBuildInvocation)); @@ -195,7 +195,7 @@ public void OsOptionIsResolvedFromRidUnderDifferentCulture() .StartWith($"{ExpectedPrefix} -restore -consoleloggerparameters:Summary -property:RuntimeIdentifier={expectedOs}-arch"); }); } - finally { CultureInfo.CurrentCulture = currentCultureBefore;} + finally { CultureInfo.CurrentCulture = currentCultureBefore; } } } } diff --git a/src/Tests/dotnet.Tests/dotnet-msbuild/GivenDotnetPackInvocation.cs b/src/Tests/dotnet.Tests/dotnet-msbuild/GivenDotnetPackInvocation.cs index d1f66d1c0962..d8f23871a36f 100644 --- a/src/Tests/dotnet.Tests/dotnet-msbuild/GivenDotnetPackInvocation.cs +++ b/src/Tests/dotnet.Tests/dotnet-msbuild/GivenDotnetPackInvocation.cs @@ -8,8 +8,8 @@ namespace Microsoft.DotNet.Cli.MSBuild.Tests [Collection(TestConstants.UsesStaticTelemetryState)] public class GivenDotnetPackInvocation : IClassFixture { - const string ExpectedPrefix = "-maxcpucount -verbosity:m -restore -target:pack"; - const string ExpectedNoBuildPrefix = "-maxcpucount -verbosity:m -target:pack"; + const string ExpectedPrefix = "-maxcpucount -verbosity:m -nologo -restore -target:pack"; + const string ExpectedNoBuildPrefix = "-maxcpucount -verbosity:m -nologo -target:pack"; const string ExpectedProperties = "--property:_IsPacking=true"; private static readonly string WorkingDirectory = diff --git a/src/Tests/dotnet.Tests/dotnet-msbuild/GivenDotnetPublishInvocation.cs b/src/Tests/dotnet.Tests/dotnet-msbuild/GivenDotnetPublishInvocation.cs index e7e2964cdbbd..14f7cb55d375 100644 --- a/src/Tests/dotnet.Tests/dotnet-msbuild/GivenDotnetPublishInvocation.cs +++ b/src/Tests/dotnet.Tests/dotnet-msbuild/GivenDotnetPublishInvocation.cs @@ -17,7 +17,7 @@ public GivenDotnetPublishInvocation(ITestOutputHelper output) this.output = output; } - const string ExpectedPrefix = "-maxcpucount -verbosity:m"; + const string ExpectedPrefix = "-maxcpucount -verbosity:m -nologo"; const string ExpectedProperties = "--property:_IsPublishing=true"; [Theory] diff --git a/src/Tests/dotnet.Tests/dotnet-msbuild/GivenDotnetStoreInvocation.cs b/src/Tests/dotnet.Tests/dotnet-msbuild/GivenDotnetStoreInvocation.cs index 07e4dd9d1f1d..32fc1dd0dce5 100644 --- a/src/Tests/dotnet.Tests/dotnet-msbuild/GivenDotnetStoreInvocation.cs +++ b/src/Tests/dotnet.Tests/dotnet-msbuild/GivenDotnetStoreInvocation.cs @@ -8,7 +8,7 @@ namespace Microsoft.DotNet.Cli.MSBuild.Tests [Collection(TestConstants.UsesStaticTelemetryState)] public class GivenDotnetStoreInvocation : IClassFixture { - const string ExpectedPrefix = "-maxcpucount -verbosity:m -target:ComposeStore "; + const string ExpectedPrefix = "-maxcpucount -verbosity:m -nologo -target:ComposeStore "; static readonly string[] ArgsPrefix = { "--manifest", "" }; private static readonly string WorkingDirectory = TestPathUtilities.FormatAbsolutePath(nameof(GivenDotnetStoreInvocation)); diff --git a/src/Tests/dotnet.Tests/dotnet-msbuild/GivenDotnetTestInvocation.cs b/src/Tests/dotnet.Tests/dotnet-msbuild/GivenDotnetTestInvocation.cs index 035afa9f2051..cc7b6771dfc5 100644 --- a/src/Tests/dotnet.Tests/dotnet-msbuild/GivenDotnetTestInvocation.cs +++ b/src/Tests/dotnet.Tests/dotnet-msbuild/GivenDotnetTestInvocation.cs @@ -8,7 +8,7 @@ namespace Microsoft.DotNet.Cli.MSBuild.Tests [Collection(TestConstants.UsesStaticTelemetryState)] public class GivenDotnetTestInvocation : IClassFixture { - private const string ExpectedPrefix = "-maxcpucount -verbosity:m -restore -target:VSTest -nodereuse:false -nologo"; + private const string ExpectedPrefix = "-maxcpucount -verbosity:m -nologo -restore -target:VSTest -nodereuse:false -nologo"; private static readonly string WorkingDirectory = TestPathUtilities.FormatAbsolutePath(nameof(GivenDotnetTestInvocation)); [Theory] From f310c34cbb5d38bf4b50cac6b8d793b1884b75ca Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Thu, 15 Feb 2024 18:24:52 +0000 Subject: [PATCH 210/577] [release/8.0.3xx] Update dependencies from dotnet/roslyn (#38767) [release/8.0.3xx] Update dependencies from dotnet/roslyn --- eng/Version.Details.xml | 28 ++++++++++++++-------------- eng/Versions.props | 14 +++++++------- 2 files changed, 21 insertions(+), 21 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 410a870a119a..057fd1986af0 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -78,34 +78,34 @@ 4ffa2f1691a4ac3ebad3fe840d7a25f35feba635 - + https://github.com/dotnet/roslyn - 892d5f01f7f41dfe7fcd82522276c5628255ef74 + 77372c66fd54927312b5b0a2e399e192f74445c9 - + https://github.com/dotnet/roslyn - 892d5f01f7f41dfe7fcd82522276c5628255ef74 + 77372c66fd54927312b5b0a2e399e192f74445c9 - + https://github.com/dotnet/roslyn - 892d5f01f7f41dfe7fcd82522276c5628255ef74 + 77372c66fd54927312b5b0a2e399e192f74445c9 - + https://github.com/dotnet/roslyn - 892d5f01f7f41dfe7fcd82522276c5628255ef74 + 77372c66fd54927312b5b0a2e399e192f74445c9 - + https://github.com/dotnet/roslyn - 892d5f01f7f41dfe7fcd82522276c5628255ef74 + 77372c66fd54927312b5b0a2e399e192f74445c9 - + https://github.com/dotnet/roslyn - 892d5f01f7f41dfe7fcd82522276c5628255ef74 + 77372c66fd54927312b5b0a2e399e192f74445c9 - + https://github.com/dotnet/roslyn - 892d5f01f7f41dfe7fcd82522276c5628255ef74 + 77372c66fd54927312b5b0a2e399e192f74445c9 https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore diff --git a/eng/Versions.props b/eng/Versions.props index 250b82422ff3..6391485f169b 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -154,13 +154,13 @@ - 4.10.0-2.24112.13 - 4.10.0-2.24112.13 - 4.10.0-2.24112.13 - 4.10.0-2.24112.13 - 4.10.0-2.24112.13 - 4.10.0-2.24112.13 - 4.10.0-2.24112.13 + 4.10.0-2.24114.13 + 4.10.0-2.24114.13 + 4.10.0-2.24114.13 + 4.10.0-2.24114.13 + 4.10.0-2.24114.13 + 4.10.0-2.24114.13 + 4.10.0-2.24114.13 $(MicrosoftNetCompilersToolsetPackageVersion) From f31440f0ef5f22065e8326f4f7d30e3ca2ad0f5a Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Thu, 15 Feb 2024 18:26:09 +0000 Subject: [PATCH 211/577] [release/8.0.3xx] Update dependencies from dotnet/msbuild (#38762) [release/8.0.3xx] Update dependencies from dotnet/msbuild --- eng/Version.Details.xml | 12 ++++++------ eng/Versions.props | 4 ++-- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 057fd1986af0..6d090c2560cf 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -51,17 +51,17 @@ https://github.com/dotnet/emsdk 201f4dae9d1a1e105d8ba86d7ece61eed1f665e0 - + https://github.com/dotnet/msbuild - 15f7ddcaafa6622447fa69c1785ab7b3d1183719 + b783f61ef6fcadef68c54daac21e18c1c20fc071 - + https://github.com/dotnet/msbuild - 15f7ddcaafa6622447fa69c1785ab7b3d1183719 + b783f61ef6fcadef68c54daac21e18c1c20fc071 - + https://github.com/dotnet/msbuild - 15f7ddcaafa6622447fa69c1785ab7b3d1183719 + b783f61ef6fcadef68c54daac21e18c1c20fc071 diff --git a/eng/Versions.props b/eng/Versions.props index 6391485f169b..dd8b7be32674 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -120,7 +120,7 @@ - 17.10.0-preview-24109-03 + 17.10.0-preview-24115-01 $(MicrosoftBuildPackageVersion) - 12.8.300-beta.24112.4 + 12.8.300-beta.24114.2 From fdf3b60efd1111e45fc69303a839a369a318bac1 Mon Sep 17 00:00:00 2001 From: Marc Paine Date: Thu, 15 Feb 2024 13:52:26 -0800 Subject: [PATCH 213/577] Update to the Feb 8.0.2 runtime --- NuGet.config | 39 ++++++++++- eng/Version.Details.xml | 140 ++++++++++++++++++++-------------------- eng/Versions.props | 36 +++++------ 3 files changed, 126 insertions(+), 89 deletions(-) diff --git a/NuGet.config b/NuGet.config index 5a8cd2045ba8..753d8e59857f 100644 --- a/NuGet.config +++ b/NuGet.config @@ -4,6 +4,10 @@ + + + + @@ -15,12 +19,28 @@ + + + + + - + + + + + + + + + + + + @@ -48,8 +68,25 @@ + + + + + + + + + + + + + + + + + diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index c8a1059462d8..ce73b399ce81 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -10,46 +10,46 @@ https://github.com/dotnet/templating 9a7274da6e9f9de9cb2cd7a6efa2ae30d3d73f4f - + https://dev.azure.com/dnceng/internal/_git/dotnet-runtime - bf5e279d9239bfef5bb1b8d6212f1b971c434606 + 1381d5ebd2ab1f292848d5b19b80cf71ac332508 - + https://dev.azure.com/dnceng/internal/_git/dotnet-runtime - bf5e279d9239bfef5bb1b8d6212f1b971c434606 + 1381d5ebd2ab1f292848d5b19b80cf71ac332508 - + https://dev.azure.com/dnceng/internal/_git/dotnet-runtime - bf5e279d9239bfef5bb1b8d6212f1b971c434606 + 1381d5ebd2ab1f292848d5b19b80cf71ac332508 - + https://dev.azure.com/dnceng/internal/_git/dotnet-runtime - bf5e279d9239bfef5bb1b8d6212f1b971c434606 + 1381d5ebd2ab1f292848d5b19b80cf71ac332508 - + https://dev.azure.com/dnceng/internal/_git/dotnet-runtime - bf5e279d9239bfef5bb1b8d6212f1b971c434606 + 1381d5ebd2ab1f292848d5b19b80cf71ac332508 - + https://dev.azure.com/dnceng/internal/_git/dotnet-runtime - bf5e279d9239bfef5bb1b8d6212f1b971c434606 + 1381d5ebd2ab1f292848d5b19b80cf71ac332508 - + https://dev.azure.com/dnceng/internal/_git/dotnet-runtime - bf5e279d9239bfef5bb1b8d6212f1b971c434606 + 1381d5ebd2ab1f292848d5b19b80cf71ac332508 https://dev.azure.com/dnceng/internal/_git/dotnet-runtime 5535e31a712343a63f5d7d796cd874e563e5ac14 - + https://dev.azure.com/dnceng/internal/_git/dotnet-runtime - bf5e279d9239bfef5bb1b8d6212f1b971c434606 + 1381d5ebd2ab1f292848d5b19b80cf71ac332508 - + https://github.com/dotnet/emsdk - 201f4dae9d1a1e105d8ba86d7ece61eed1f665e0 + 2fc2ffd960930318f33fcaa690cbdbc55d72f52d https://github.com/dotnet/msbuild @@ -107,13 +107,13 @@ https://github.com/dotnet/roslyn 77372c66fd54927312b5b0a2e399e192f74445c9 - + https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore - 8e941eb42f819adb116b881195158b3887a70a1c + da7e9894ce22ef8cc02e5acc56e95a6f8cf8f644 - + https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore - 8e941eb42f819adb116b881195158b3887a70a1c + da7e9894ce22ef8cc02e5acc56e95a6f8cf8f644 https://github.com/nuget/nuget.client @@ -192,9 +192,9 @@ https://github.com/microsoft/vstest f6c1ca66f0e01c64d663a8780d501432b680d804 - + https://dev.azure.com/dnceng/internal/_git/dotnet-runtime - bf5e279d9239bfef5bb1b8d6212f1b971c434606 + 1381d5ebd2ab1f292848d5b19b80cf71ac332508 https://dev.azure.com/dnceng/internal/_git/dotnet-runtime @@ -212,70 +212,70 @@ https://dev.azure.com/dnceng/internal/_git/dotnet-runtime 5535e31a712343a63f5d7d796cd874e563e5ac14 - + https://dev.azure.com/dnceng/internal/_git/dotnet-windowsdesktop - a0e7b5d8673f28c41bcac6e2001b39ba2c8fab54 + 593444ad8328a5a933c006c6564469666f45ad2e - + https://dev.azure.com/dnceng/internal/_git/dotnet-windowsdesktop - a0e7b5d8673f28c41bcac6e2001b39ba2c8fab54 + 593444ad8328a5a933c006c6564469666f45ad2e - + https://dev.azure.com/dnceng/internal/_git/dotnet-windowsdesktop - a0e7b5d8673f28c41bcac6e2001b39ba2c8fab54 + 593444ad8328a5a933c006c6564469666f45ad2e - + https://dev.azure.com/dnceng/internal/_git/dotnet-windowsdesktop - a0e7b5d8673f28c41bcac6e2001b39ba2c8fab54 + 593444ad8328a5a933c006c6564469666f45ad2e - + https://dev.azure.com/dnceng/internal/_git/dotnet-wpf - ac40bed7a33baf164d3984ca90c2aedba996a7b2 + 472140dd926227876848e48f41cfc9acb9275492 - + https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore - 8e941eb42f819adb116b881195158b3887a70a1c + da7e9894ce22ef8cc02e5acc56e95a6f8cf8f644 - + https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore - 8e941eb42f819adb116b881195158b3887a70a1c + da7e9894ce22ef8cc02e5acc56e95a6f8cf8f644 - + https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore - 8e941eb42f819adb116b881195158b3887a70a1c + da7e9894ce22ef8cc02e5acc56e95a6f8cf8f644 - + https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore - 8e941eb42f819adb116b881195158b3887a70a1c + da7e9894ce22ef8cc02e5acc56e95a6f8cf8f644 - + https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore - 8e941eb42f819adb116b881195158b3887a70a1c + da7e9894ce22ef8cc02e5acc56e95a6f8cf8f644 - + https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore - 8e941eb42f819adb116b881195158b3887a70a1c + da7e9894ce22ef8cc02e5acc56e95a6f8cf8f644 - + https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore - 8e941eb42f819adb116b881195158b3887a70a1c + da7e9894ce22ef8cc02e5acc56e95a6f8cf8f644 - + https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore - 8e941eb42f819adb116b881195158b3887a70a1c + da7e9894ce22ef8cc02e5acc56e95a6f8cf8f644 - + https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore - 8e941eb42f819adb116b881195158b3887a70a1c + da7e9894ce22ef8cc02e5acc56e95a6f8cf8f644 - + https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore - 8e941eb42f819adb116b881195158b3887a70a1c + da7e9894ce22ef8cc02e5acc56e95a6f8cf8f644 - + https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore - 8e941eb42f819adb116b881195158b3887a70a1c + da7e9894ce22ef8cc02e5acc56e95a6f8cf8f644 https://github.com/dotnet/razor @@ -290,21 +290,21 @@ https://github.com/dotnet/razor f7ea4168060fa228acc3175604a3013bd94134a6 - + https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore - 8e941eb42f819adb116b881195158b3887a70a1c + da7e9894ce22ef8cc02e5acc56e95a6f8cf8f644 - + https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore - 8e941eb42f819adb116b881195158b3887a70a1c + da7e9894ce22ef8cc02e5acc56e95a6f8cf8f644 - + https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore - 8e941eb42f819adb116b881195158b3887a70a1c + da7e9894ce22ef8cc02e5acc56e95a6f8cf8f644 - + https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore - 8e941eb42f819adb116b881195158b3887a70a1c + da7e9894ce22ef8cc02e5acc56e95a6f8cf8f644 https://github.com/dotnet/xdt @@ -409,9 +409,9 @@ https://dev.azure.com/dnceng/internal/_git/dotnet-runtime 5535e31a712343a63f5d7d796cd874e563e5ac14 - + https://dev.azure.com/dnceng/internal/_git/dotnet-runtime - bf5e279d9239bfef5bb1b8d6212f1b971c434606 + 1381d5ebd2ab1f292848d5b19b80cf71ac332508 https://dev.azure.com/dnceng/internal/_git/dotnet-runtime @@ -421,9 +421,9 @@ https://dev.azure.com/dnceng/internal/_git/dotnet-runtime 5535e31a712343a63f5d7d796cd874e563e5ac14 - + https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore - 8e941eb42f819adb116b881195158b3887a70a1c + da7e9894ce22ef8cc02e5acc56e95a6f8cf8f644 https://dev.azure.com/dnceng/internal/_git/dotnet-runtime @@ -453,9 +453,9 @@ https://dev.azure.com/dnceng/internal/_git/dotnet-runtime 5535e31a712343a63f5d7d796cd874e563e5ac14 - + https://dev.azure.com/dnceng/internal/_git/dotnet-winforms - 0b4028eb507aeb222f5bd1fc421876cc5e5e3fb8 + c58fa00bd16b92aab1d7fb2b93e71af6a7768139 https://dev.azure.com/dnceng/internal/_git/dotnet-runtime diff --git a/eng/Versions.props b/eng/Versions.props index 7a98b090421b..7f3ce5a4cadb 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -49,22 +49,22 @@ - 8.0.1 - 8.0.1-servicing.23580.1 - 8.0.1 + 8.0.2 + 8.0.2-servicing.24067.11 + 8.0.2 $(MicrosoftNETCoreAppRuntimewinx64PackageVersion) 8.0.0 - 8.0.1 - 8.0.1-servicing.23580.1 + 8.0.2 + 8.0.2-servicing.24067.11 8.0.0 $(MicrosoftExtensionsDependencyModelPackageVersion) 8.0.0 8.0.0 8.0.0 - 8.0.1 + 8.0.2 8.0.0 8.0.0 - 8.0.1 + 8.0.2 8.0.0 8.0.0 8.0.0 @@ -72,12 +72,12 @@ 8.0.0 8.0.0 8.0.0 - 8.0.1 + 8.0.2 8.0.0 8.0.0 8.0.0 8.0.0 - 8.0.1 + 8.0.2 8.0.0 @@ -165,13 +165,13 @@ - 8.0.1 - 8.0.1-servicing.23580.8 - 8.0.1-servicing.23580.8 - 8.0.1-servicing.23580.8 - 8.0.1-servicing.23580.8 - 8.0.1-servicing.23580.8 - 8.0.1 + 8.0.2 + 8.0.2-servicing.24068.4 + 8.0.2-servicing.24068.4 + 8.0.2-servicing.24068.4 + 8.0.2-servicing.24068.4 + 8.0.2-servicing.24068.4 + 8.0.2 @@ -181,7 +181,7 @@ - 8.0.1-servicing.23580.5 + 8.0.2-servicing.24068.6 @@ -225,7 +225,7 @@ - 8.0.1 + 8.0.2 $(MicrosoftNETWorkloadEmscriptenCurrentManifest80100PackageVersion) 8.0.100$([System.Text.RegularExpressions.Regex]::Match($(EmscriptenWorkloadManifestVersion), `-rtm|-[A-z]*\.*\d*`)) From af541f602ae7dc559c395a34658fa72a9f900988 Mon Sep 17 00:00:00 2001 From: dotnet bot Date: Fri, 16 Feb 2024 03:58:47 -0800 Subject: [PATCH 214/577] Localized file check-in by OneLocBuild Task: Build definition ID 140: Build ID 2380882 --- .../commands/dotnet-tool/install/xlf/LocalizableStrings.it.xlf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.it.xlf b/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.it.xlf index bf4300523c75..280164a23d02 100644 --- a/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.it.xlf +++ b/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.it.xlf @@ -90,7 +90,7 @@ Se si vuole creare un manifesto, usare `dotnet new tool-manifest`, in genere nel Allow a .NET tool to roll forward to newer versions of the .NET runtime if the runtime it targets isn't installed. - Consente a uno strumento .NET di eseguire il roll forward alle versioni più recenti del runtime .NET se il runtime a cui è destinato non è installato. + Consente a uno strumento .NET di eseguire il roll forward alle versioni più recenti del runtime .NET se il runtime di destinazione non è installato. From facae724894c637246e780f513678db5748ae937 Mon Sep 17 00:00:00 2001 From: dotnet bot Date: Fri, 16 Feb 2024 03:59:53 -0800 Subject: [PATCH 215/577] Localized file check-in by OneLocBuild Task: Build definition ID 140: Build ID 2380882 --- .../commands/dotnet-tool/install/xlf/LocalizableStrings.tr.xlf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.tr.xlf b/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.tr.xlf index ea340df7b328..606e3b643915 100644 --- a/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.tr.xlf +++ b/src/Cli/dotnet/commands/dotnet-tool/install/xlf/LocalizableStrings.tr.xlf @@ -90,7 +90,7 @@ Bir bildirim oluşturmak istiyorsanız 'dotnet new tool-manifest' ifadesini kull Allow a .NET tool to roll forward to newer versions of the .NET runtime if the runtime it targets isn't installed. - Hedeflene çalışma zamanı yüklü değilse bir .NET aracının .NET çalışma zamanının daha yeni sürümlerine ileri sarmal işlemine izin ver. + Hedeflediği çalışma zamanı yüklü değilse, bir .NET aracının daha yeni .NET çalışma zamanı sürümlerine ileri alınmasına izin verin. From 6b6caace48eda1ea0c423089237fb7537bdd9082 Mon Sep 17 00:00:00 2001 From: dotnet bot Date: Fri, 16 Feb 2024 04:05:19 -0800 Subject: [PATCH 216/577] Localized file check-in by OneLocBuild Task: Build definition ID 140: Build ID 2380882 --- src/Cli/dotnet/ToolManifest/xlf/LocalizableStrings.tr.xlf | 2 +- src/Cli/dotnet/xlf/CommonLocalizableStrings.it.xlf | 2 +- src/Cli/dotnet/xlf/CommonLocalizableStrings.tr.xlf | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Cli/dotnet/ToolManifest/xlf/LocalizableStrings.tr.xlf b/src/Cli/dotnet/ToolManifest/xlf/LocalizableStrings.tr.xlf index 00e8bdc592a2..926be091bf23 100644 --- a/src/Cli/dotnet/ToolManifest/xlf/LocalizableStrings.tr.xlf +++ b/src/Cli/dotnet/ToolManifest/xlf/LocalizableStrings.tr.xlf @@ -38,7 +38,7 @@ Aranan konumların bir listesi için aracın adından önce "-d" seçeneğini be Missing 'rollForward' entry. - 'rollForward' girişi eksik. + ‘RollForward’ girişi eksik. diff --git a/src/Cli/dotnet/xlf/CommonLocalizableStrings.it.xlf b/src/Cli/dotnet/xlf/CommonLocalizableStrings.it.xlf index 006c842582e2..84b8e63f7b0d 100644 --- a/src/Cli/dotnet/xlf/CommonLocalizableStrings.it.xlf +++ b/src/Cli/dotnet/xlf/CommonLocalizableStrings.it.xlf @@ -284,7 +284,7 @@ Il valore predefinito è 'false'. Tuttavia, quando la destinazione è .NET 7 o u Tool settings file does not exist for the tool {0}. - Il file di impostazioni dello strumento non esiste per lo strumento {0}. + Il file delle impostazioni dello strumento non esiste per lo strumento {0}. diff --git a/src/Cli/dotnet/xlf/CommonLocalizableStrings.tr.xlf b/src/Cli/dotnet/xlf/CommonLocalizableStrings.tr.xlf index 953211564e6b..2cd50917f9fc 100644 --- a/src/Cli/dotnet/xlf/CommonLocalizableStrings.tr.xlf +++ b/src/Cli/dotnet/xlf/CommonLocalizableStrings.tr.xlf @@ -284,7 +284,7 @@ Varsayılan değer 'false' olur. Ancak çalışma zamanı tanımlayıcısı beli Tool settings file does not exist for the tool {0}. - Araç ayarları dosyası, araç ayarları {0}. + {0} aracı için araç ayarları dosyası mevcut değil. From 8f3e00cab7ade20f3f6218c3cfbff2300d50d85a Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" Date: Fri, 16 Feb 2024 13:47:37 +0000 Subject: [PATCH 217/577] Update dependencies from https://github.com/dotnet/arcade build 20240213.2 Microsoft.DotNet.Arcade.Sdk , Microsoft.DotNet.Helix.Sdk , Microsoft.DotNet.SignTool , Microsoft.DotNet.XUnitExtensions From Version 8.0.0-beta.24081.5 -> To Version 8.0.0-beta.24113.2 From 653ac48e5f480f385cccba74deb97c6acb885a1c Mon Sep 17 00:00:00 2001 From: Matt Thalman Date: Fri, 16 Feb 2024 08:52:49 -0600 Subject: [PATCH 218/577] Ignore System.Drawing.Common.8.0.* prebuilts --- eng/SourceBuildPrebuiltBaseline.xml | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/eng/SourceBuildPrebuiltBaseline.xml b/eng/SourceBuildPrebuiltBaseline.xml index cee70c108618..6ed13d40390a 100644 --- a/eng/SourceBuildPrebuiltBaseline.xml +++ b/eng/SourceBuildPrebuiltBaseline.xml @@ -42,9 +42,7 @@ + - - - From 862c93e49a1749c61f2c4dccea19f829cce08af5 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Fri, 16 Feb 2024 18:41:54 +0000 Subject: [PATCH 219/577] [release/8.0.3xx] Update dependencies from dotnet/format (#38845) [release/8.0.3xx] Update dependencies from dotnet/format --- NuGet.config | 2 +- eng/Version.Details.xml | 4 ++-- eng/Versions.props | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/NuGet.config b/NuGet.config index 753d8e59857f..fed0c66309f5 100644 --- a/NuGet.config +++ b/NuGet.config @@ -10,7 +10,7 @@ - + diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 3faba04d0aee..54d8a18dd6d2 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -73,9 +73,9 @@ 14ddb01cad17d7737028afdd90e36b85a1086626 - + https://github.com/dotnet/format - 4ffa2f1691a4ac3ebad3fe840d7a25f35feba635 + d237e172b324021b97effa244af44d63d1a8bb7e diff --git a/eng/Versions.props b/eng/Versions.props index 7ff36b0bf5ca..20ded5a55669 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -111,7 +111,7 @@ - 8.0.510703 + 8.0.511601 From 6637c996a14a434625262e7fddea9ab71cb21d85 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Fri, 16 Feb 2024 18:42:35 +0000 Subject: [PATCH 220/577] [release/8.0.3xx] Update dependencies from dotnet/msbuild (#38840) [release/8.0.3xx] Update dependencies from dotnet/msbuild --- eng/Version.Details.xml | 12 ++++++------ eng/Versions.props | 4 ++-- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 54d8a18dd6d2..399cbd3cffde 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -51,17 +51,17 @@ https://github.com/dotnet/emsdk 2fc2ffd960930318f33fcaa690cbdbc55d72f52d - + https://github.com/dotnet/msbuild - b783f61ef6fcadef68c54daac21e18c1c20fc071 + 23f77529a83531782dd498bf400381842c3d2d9e - + https://github.com/dotnet/msbuild - b783f61ef6fcadef68c54daac21e18c1c20fc071 + 23f77529a83531782dd498bf400381842c3d2d9e - + https://github.com/dotnet/msbuild - b783f61ef6fcadef68c54daac21e18c1c20fc071 + 23f77529a83531782dd498bf400381842c3d2d9e diff --git a/eng/Versions.props b/eng/Versions.props index 20ded5a55669..e24e236a4da6 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -120,7 +120,7 @@ - 17.10.0-preview-24115-01 + 17.10.0-preview-24116-06 $(MicrosoftBuildPackageVersion) - 12.8.300-beta.24114.2 + 12.8.300-beta.24115.2 From 02ee03638a6b477d8b973edddc48aede49e70070 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Fri, 16 Feb 2024 18:43:16 +0000 Subject: [PATCH 222/577] [release/8.0.3xx] Update dependencies from dotnet/razor (#38842) [release/8.0.3xx] Update dependencies from dotnet/razor --- eng/Version.Details.xml | 12 ++++++------ eng/Versions.props | 6 +++--- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 9dd53c5d3ed2..cce56edb74ac 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -277,18 +277,18 @@ https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore da7e9894ce22ef8cc02e5acc56e95a6f8cf8f644 - + https://github.com/dotnet/razor - 4e4a8df527f847cf152970a1eedae822a8fe1843 + f01e110af179981942987384d2b5d4e489eab014 - + https://github.com/dotnet/razor - 4e4a8df527f847cf152970a1eedae822a8fe1843 + f01e110af179981942987384d2b5d4e489eab014 - + https://github.com/dotnet/razor - 4e4a8df527f847cf152970a1eedae822a8fe1843 + f01e110af179981942987384d2b5d4e489eab014 https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore diff --git a/eng/Versions.props b/eng/Versions.props index 16c535d6e2a7..85091336f9c8 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -175,9 +175,9 @@ - 7.0.0-preview.24114.2 - 7.0.0-preview.24114.2 - 7.0.0-preview.24114.2 + 7.0.0-preview.24115.4 + 7.0.0-preview.24115.4 + 7.0.0-preview.24115.4 From e1c22f0a550151706c02943e313381169b40b9c2 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Fri, 16 Feb 2024 18:43:42 +0000 Subject: [PATCH 223/577] [release/8.0.3xx] Update dependencies from dotnet/roslyn (#38843) [release/8.0.3xx] Update dependencies from dotnet/roslyn --- eng/Version.Details.xml | 28 ++++++++++++++-------------- eng/Versions.props | 14 +++++++------- 2 files changed, 21 insertions(+), 21 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index cce56edb74ac..b55d8eef387c 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -78,34 +78,34 @@ d237e172b324021b97effa244af44d63d1a8bb7e - + https://github.com/dotnet/roslyn - 77372c66fd54927312b5b0a2e399e192f74445c9 + d3a41ae7c758b1195f64dc5f57a6eafc8d959469 - + https://github.com/dotnet/roslyn - 77372c66fd54927312b5b0a2e399e192f74445c9 + d3a41ae7c758b1195f64dc5f57a6eafc8d959469 - + https://github.com/dotnet/roslyn - 77372c66fd54927312b5b0a2e399e192f74445c9 + d3a41ae7c758b1195f64dc5f57a6eafc8d959469 - + https://github.com/dotnet/roslyn - 77372c66fd54927312b5b0a2e399e192f74445c9 + d3a41ae7c758b1195f64dc5f57a6eafc8d959469 - + https://github.com/dotnet/roslyn - 77372c66fd54927312b5b0a2e399e192f74445c9 + d3a41ae7c758b1195f64dc5f57a6eafc8d959469 - + https://github.com/dotnet/roslyn - 77372c66fd54927312b5b0a2e399e192f74445c9 + d3a41ae7c758b1195f64dc5f57a6eafc8d959469 - + https://github.com/dotnet/roslyn - 77372c66fd54927312b5b0a2e399e192f74445c9 + d3a41ae7c758b1195f64dc5f57a6eafc8d959469 https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore diff --git a/eng/Versions.props b/eng/Versions.props index 85091336f9c8..daaf8dabc65b 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -154,13 +154,13 @@ - 4.10.0-2.24114.13 - 4.10.0-2.24114.13 - 4.10.0-2.24114.13 - 4.10.0-2.24114.13 - 4.10.0-2.24114.13 - 4.10.0-2.24114.13 - 4.10.0-2.24114.13 + 4.10.0-2.24115.8 + 4.10.0-2.24115.8 + 4.10.0-2.24115.8 + 4.10.0-2.24115.8 + 4.10.0-2.24115.8 + 4.10.0-2.24115.8 + 4.10.0-2.24115.8 $(MicrosoftNetCompilersToolsetPackageVersion) From c2c4e3c9ebc3f38e2aa38b80481200a620ccee00 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Fri, 16 Feb 2024 18:44:19 +0000 Subject: [PATCH 224/577] [release/8.0.3xx] Update dependencies from dotnet/templating (#38844) [release/8.0.3xx] Update dependencies from dotnet/templating --- eng/Version.Details.xml | 8 ++++---- eng/Versions.props | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index b55d8eef387c..598c849e8ffb 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -1,14 +1,14 @@ - + https://github.com/dotnet/templating - 9a7274da6e9f9de9cb2cd7a6efa2ae30d3d73f4f + 82f5e89616d0c7a6f2f6f21d02181ef49de26b52 - + https://github.com/dotnet/templating - 9a7274da6e9f9de9cb2cd7a6efa2ae30d3d73f4f + 82f5e89616d0c7a6f2f6f21d02181ef49de26b52 https://dev.azure.com/dnceng/internal/_git/dotnet-runtime diff --git a/eng/Versions.props b/eng/Versions.props index daaf8dabc65b..5fa4eaef868f 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -137,13 +137,13 @@ - 8.0.300-preview.24078.2 + 8.0.300-preview.24115.30 $(MicrosoftTemplateEngineAbstractionsPackageVersion) $(MicrosoftTemplateEngineAbstractionsPackageVersion) $(MicrosoftTemplateEngineAbstractionsPackageVersion) $(MicrosoftTemplateEngineAbstractionsPackageVersion) - 8.0.300-preview.24078.2 + 8.0.300-preview.24115.30 $(MicrosoftTemplateEngineMocksPackageVersion) $(MicrosoftTemplateEngineAbstractionsPackageVersion) $(MicrosoftTemplateEngineMocksPackageVersion) From dae79d603653b790d671094499a250a03f001376 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" Date: Sat, 17 Feb 2024 13:30:27 +0000 Subject: [PATCH 225/577] Update dependencies from https://github.com/microsoft/vstest build 20240216.1 Microsoft.NET.Test.Sdk , Microsoft.TestPlatform.Build , Microsoft.TestPlatform.CLI From Version 17.10.0-preview-24114-01 -> To Version 17.10.0-preview-24116-01 --- NuGet.config | 10 ---------- eng/Version.Details.xml | 12 ++++++------ eng/Versions.props | 6 +++--- 3 files changed, 9 insertions(+), 19 deletions(-) diff --git a/NuGet.config b/NuGet.config index fed0c66309f5..75383082025c 100644 --- a/NuGet.config +++ b/NuGet.config @@ -19,11 +19,6 @@ - - - - - @@ -68,11 +63,6 @@ - - - - - diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index e703db216934..6feec26204b5 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -179,18 +179,18 @@ https://github.com/nuget/nuget.client 8b658e2eee6391936887b9fd1b39f7918d16a9cb - + https://github.com/microsoft/vstest - f6c1ca66f0e01c64d663a8780d501432b680d804 + 5d731c3c1afa6456b447c7efa11eacb313964e02 - + https://github.com/microsoft/vstest - f6c1ca66f0e01c64d663a8780d501432b680d804 + 5d731c3c1afa6456b447c7efa11eacb313964e02 - + https://github.com/microsoft/vstest - f6c1ca66f0e01c64d663a8780d501432b680d804 + 5d731c3c1afa6456b447c7efa11eacb313964e02 https://dev.azure.com/dnceng/internal/_git/dotnet-runtime diff --git a/eng/Versions.props b/eng/Versions.props index 4d5cc2a421f4..52d4174b32af 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -99,9 +99,9 @@ - 17.10.0-preview-24114-01 - 17.10.0-preview-24114-01 - 17.10.0-preview-24114-01 + 17.10.0-preview-24116-01 + 17.10.0-preview-24116-01 + 17.10.0-preview-24116-01 From 5da2869e81ee923252a44625e286420d12e39b34 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" Date: Sat, 17 Feb 2024 13:30:51 +0000 Subject: [PATCH 226/577] Update dependencies from https://github.com/dotnet/razor build 20240216.1 Microsoft.AspNetCore.Mvc.Razor.Extensions.Tooling.Internal , Microsoft.CodeAnalysis.Razor.Tooling.Internal , Microsoft.NET.Sdk.Razor.SourceGenerators.Transport From Version 7.0.0-preview.24115.4 -> To Version 7.0.0-preview.24116.1 --- NuGet.config | 10 ---------- eng/Version.Details.xml | 12 ++++++------ eng/Versions.props | 6 +++--- 3 files changed, 9 insertions(+), 19 deletions(-) diff --git a/NuGet.config b/NuGet.config index fed0c66309f5..75383082025c 100644 --- a/NuGet.config +++ b/NuGet.config @@ -19,11 +19,6 @@ - - - - - @@ -68,11 +63,6 @@ - - - - - diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index e703db216934..d8784dcea07d 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -277,18 +277,18 @@ https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore da7e9894ce22ef8cc02e5acc56e95a6f8cf8f644 - + https://github.com/dotnet/razor - f01e110af179981942987384d2b5d4e489eab014 + 9af334dcb6eaab7a7fe0764f0cc135cde2064751 - + https://github.com/dotnet/razor - f01e110af179981942987384d2b5d4e489eab014 + 9af334dcb6eaab7a7fe0764f0cc135cde2064751 - + https://github.com/dotnet/razor - f01e110af179981942987384d2b5d4e489eab014 + 9af334dcb6eaab7a7fe0764f0cc135cde2064751 https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore diff --git a/eng/Versions.props b/eng/Versions.props index 4d5cc2a421f4..aa2da892f614 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -175,9 +175,9 @@ - 7.0.0-preview.24115.4 - 7.0.0-preview.24115.4 - 7.0.0-preview.24115.4 + 7.0.0-preview.24116.1 + 7.0.0-preview.24116.1 + 7.0.0-preview.24116.1 From 9b8eb24dd028e83cc7e838ccff8aed869114f2a9 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" Date: Sat, 17 Feb 2024 13:31:12 +0000 Subject: [PATCH 227/577] Update dependencies from https://github.com/dotnet/roslyn build 20240216.4 Microsoft.CodeAnalysis , Microsoft.CodeAnalysis.CSharp , Microsoft.CodeAnalysis.CSharp.CodeStyle , Microsoft.CodeAnalysis.CSharp.Features , Microsoft.CodeAnalysis.CSharp.Workspaces , Microsoft.CodeAnalysis.Workspaces.MSBuild , Microsoft.Net.Compilers.Toolset From Version 4.10.0-2.24115.8 -> To Version 4.10.0-2.24116.4 --- NuGet.config | 10 ---------- eng/Version.Details.xml | 28 ++++++++++++++-------------- eng/Versions.props | 14 +++++++------- 3 files changed, 21 insertions(+), 31 deletions(-) diff --git a/NuGet.config b/NuGet.config index fed0c66309f5..75383082025c 100644 --- a/NuGet.config +++ b/NuGet.config @@ -19,11 +19,6 @@ - - - - - @@ -68,11 +63,6 @@ - - - - - diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index e703db216934..2244b1ec4f8a 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -78,34 +78,34 @@ d237e172b324021b97effa244af44d63d1a8bb7e - + https://github.com/dotnet/roslyn - d3a41ae7c758b1195f64dc5f57a6eafc8d959469 + f656544b1a42c3d212362dab79829e0b3abe30f4 - + https://github.com/dotnet/roslyn - d3a41ae7c758b1195f64dc5f57a6eafc8d959469 + f656544b1a42c3d212362dab79829e0b3abe30f4 - + https://github.com/dotnet/roslyn - d3a41ae7c758b1195f64dc5f57a6eafc8d959469 + f656544b1a42c3d212362dab79829e0b3abe30f4 - + https://github.com/dotnet/roslyn - d3a41ae7c758b1195f64dc5f57a6eafc8d959469 + f656544b1a42c3d212362dab79829e0b3abe30f4 - + https://github.com/dotnet/roslyn - d3a41ae7c758b1195f64dc5f57a6eafc8d959469 + f656544b1a42c3d212362dab79829e0b3abe30f4 - + https://github.com/dotnet/roslyn - d3a41ae7c758b1195f64dc5f57a6eafc8d959469 + f656544b1a42c3d212362dab79829e0b3abe30f4 - + https://github.com/dotnet/roslyn - d3a41ae7c758b1195f64dc5f57a6eafc8d959469 + f656544b1a42c3d212362dab79829e0b3abe30f4 https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore diff --git a/eng/Versions.props b/eng/Versions.props index 4d5cc2a421f4..fe0f1d6300d2 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -154,13 +154,13 @@ - 4.10.0-2.24115.8 - 4.10.0-2.24115.8 - 4.10.0-2.24115.8 - 4.10.0-2.24115.8 - 4.10.0-2.24115.8 - 4.10.0-2.24115.8 - 4.10.0-2.24115.8 + 4.10.0-2.24116.4 + 4.10.0-2.24116.4 + 4.10.0-2.24116.4 + 4.10.0-2.24116.4 + 4.10.0-2.24116.4 + 4.10.0-2.24116.4 + 4.10.0-2.24116.4 $(MicrosoftNetCompilersToolsetPackageVersion) From 968d3807b78573197be8b751d0c235bee3e6dc9e Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" Date: Mon, 19 Feb 2024 13:26:23 +0000 Subject: [PATCH 228/577] Update dependencies from https://github.com/dotnet/msbuild build 20240219.2 Microsoft.SourceBuild.Intermediate.msbuild , Microsoft.Build , Microsoft.Build.Localization From Version 17.10.0-preview-24116-06 -> To Version 17.10.0-preview-24119-02 --- NuGet.config | 21 +-------------------- eng/Version.Details.xml | 12 ++++++------ eng/Versions.props | 4 ++-- 3 files changed, 9 insertions(+), 28 deletions(-) diff --git a/NuGet.config b/NuGet.config index 75383082025c..9dbb9bf109fe 100644 --- a/NuGet.config +++ b/NuGet.config @@ -11,6 +11,7 @@ + @@ -23,18 +24,8 @@ - - - - - - - - - - @@ -65,17 +56,7 @@ - - - - - - - - - - diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index a5a3e2317dbc..19cc42836616 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -51,17 +51,17 @@ https://github.com/dotnet/emsdk 2fc2ffd960930318f33fcaa690cbdbc55d72f52d - + https://github.com/dotnet/msbuild - 23f77529a83531782dd498bf400381842c3d2d9e + 3f6dd37bc7a4ee5d1a75e4d690b7278c5cd91683 - + https://github.com/dotnet/msbuild - 23f77529a83531782dd498bf400381842c3d2d9e + 3f6dd37bc7a4ee5d1a75e4d690b7278c5cd91683 - + https://github.com/dotnet/msbuild - 23f77529a83531782dd498bf400381842c3d2d9e + 3f6dd37bc7a4ee5d1a75e4d690b7278c5cd91683 diff --git a/eng/Versions.props b/eng/Versions.props index 8b47137f3176..65c1def2f634 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -120,7 +120,7 @@ - 17.10.0-preview-24116-06 + 17.10.0-preview-24119-02 $(MicrosoftBuildPackageVersion) + @@ -23,18 +24,8 @@ - - - - - - - - - - @@ -65,17 +56,7 @@ - - - - - - - - - - diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index a5a3e2317dbc..8066bdad39a6 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -277,18 +277,18 @@ https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore da7e9894ce22ef8cc02e5acc56e95a6f8cf8f644 - + https://github.com/dotnet/razor - 9af334dcb6eaab7a7fe0764f0cc135cde2064751 + c1a86938485f17cd84a0d412715a9d56ba70ed10 - + https://github.com/dotnet/razor - 9af334dcb6eaab7a7fe0764f0cc135cde2064751 + c1a86938485f17cd84a0d412715a9d56ba70ed10 - + https://github.com/dotnet/razor - 9af334dcb6eaab7a7fe0764f0cc135cde2064751 + c1a86938485f17cd84a0d412715a9d56ba70ed10 https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore diff --git a/eng/Versions.props b/eng/Versions.props index 8b47137f3176..b773da33d110 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -175,9 +175,9 @@ - 7.0.0-preview.24116.1 - 7.0.0-preview.24116.1 - 7.0.0-preview.24116.1 + 7.0.0-preview.24119.1 + 7.0.0-preview.24119.1 + 7.0.0-preview.24119.1 From d039ad8330c94cf1e27ebbc97f0a85f659033865 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" Date: Tue, 20 Feb 2024 13:33:49 +0000 Subject: [PATCH 230/577] Update dependencies from https://github.com/dotnet/msbuild build 20240220.3 Microsoft.SourceBuild.Intermediate.msbuild , Microsoft.Build , Microsoft.Build.Localization From Version 17.10.0-preview-24119-02 -> To Version 17.10.0-preview-24120-03 --- NuGet.config | 4 ---- eng/Version.Details.xml | 12 ++++++------ eng/Versions.props | 4 ++-- 3 files changed, 8 insertions(+), 12 deletions(-) diff --git a/NuGet.config b/NuGet.config index 9dbb9bf109fe..20c9125ee569 100644 --- a/NuGet.config +++ b/NuGet.config @@ -4,10 +4,6 @@ - - - - diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 19e0d31c0b5f..f1b9b195751f 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -51,17 +51,17 @@ https://github.com/dotnet/emsdk 2fc2ffd960930318f33fcaa690cbdbc55d72f52d - + https://github.com/dotnet/msbuild - 3f6dd37bc7a4ee5d1a75e4d690b7278c5cd91683 + 53c4f49868e88ecd7407339a3f4dab9e75c7937f - + https://github.com/dotnet/msbuild - 3f6dd37bc7a4ee5d1a75e4d690b7278c5cd91683 + 53c4f49868e88ecd7407339a3f4dab9e75c7937f - + https://github.com/dotnet/msbuild - 3f6dd37bc7a4ee5d1a75e4d690b7278c5cd91683 + 53c4f49868e88ecd7407339a3f4dab9e75c7937f diff --git a/eng/Versions.props b/eng/Versions.props index daf954986b3b..a097d713e5c6 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -120,7 +120,7 @@ - 17.10.0-preview-24119-02 + 17.10.0-preview-24120-03 $(MicrosoftBuildPackageVersion) - - - - diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 19e0d31c0b5f..254eac26c3ce 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -179,18 +179,18 @@ https://github.com/nuget/nuget.client 8b658e2eee6391936887b9fd1b39f7918d16a9cb - + https://github.com/microsoft/vstest - 5d731c3c1afa6456b447c7efa11eacb313964e02 + c13b1f9b2bb6acbb9785de003be3d9ace33c9d7c - + https://github.com/microsoft/vstest - 5d731c3c1afa6456b447c7efa11eacb313964e02 + c13b1f9b2bb6acbb9785de003be3d9ace33c9d7c - + https://github.com/microsoft/vstest - 5d731c3c1afa6456b447c7efa11eacb313964e02 + c13b1f9b2bb6acbb9785de003be3d9ace33c9d7c https://dev.azure.com/dnceng/internal/_git/dotnet-runtime diff --git a/eng/Versions.props b/eng/Versions.props index daf954986b3b..b3ba7e273775 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -99,9 +99,9 @@ - 17.10.0-preview-24116-01 - 17.10.0-preview-24116-01 - 17.10.0-preview-24116-01 + 17.10.0-preview-24119-01 + 17.10.0-preview-24119-01 + 17.10.0-preview-24119-01 From 637887b66c5fd9b2121381e1536f6f25341e68e4 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Tue, 20 Feb 2024 17:58:06 +0000 Subject: [PATCH 232/577] [release/8.0.3xx] Update dependencies from dotnet/fsharp (#38895) [release/8.0.3xx] Update dependencies from dotnet/fsharp --- eng/Version.Details.xml | 8 ++++---- eng/Versions.props | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 254eac26c3ce..25aa3b78a812 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -64,13 +64,13 @@ 3f6dd37bc7a4ee5d1a75e4d690b7278c5cd91683 - + https://github.com/dotnet/fsharp - efff9e358a26116fe7f0c513ed5534dc4de740a6 + e74bc18e6411ce3a6265aabd36ae6491ee4ebf5c - + https://github.com/dotnet/fsharp - efff9e358a26116fe7f0c513ed5534dc4de740a6 + e74bc18e6411ce3a6265aabd36ae6491ee4ebf5c diff --git a/eng/Versions.props b/eng/Versions.props index b3ba7e273775..ffe07f0a00fe 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -150,7 +150,7 @@ - 12.8.300-beta.24115.2 + 12.8.300-beta.24119.1 From b9d5f1adbbbd5319d2c69133c4cb371018769a32 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Tue, 20 Feb 2024 17:58:25 +0000 Subject: [PATCH 233/577] [release/8.0.3xx] Update dependencies from dotnet/razor (#38896) [release/8.0.3xx] Update dependencies from dotnet/razor --- eng/Version.Details.xml | 12 ++++++------ eng/Versions.props | 6 +++--- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 25aa3b78a812..b1913dee9533 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -277,18 +277,18 @@ https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore da7e9894ce22ef8cc02e5acc56e95a6f8cf8f644 - + https://github.com/dotnet/razor - c1a86938485f17cd84a0d412715a9d56ba70ed10 + 667c05ce82ca55f15ecb4578274df4aa0af9d204 - + https://github.com/dotnet/razor - c1a86938485f17cd84a0d412715a9d56ba70ed10 + 667c05ce82ca55f15ecb4578274df4aa0af9d204 - + https://github.com/dotnet/razor - c1a86938485f17cd84a0d412715a9d56ba70ed10 + 667c05ce82ca55f15ecb4578274df4aa0af9d204 https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore diff --git a/eng/Versions.props b/eng/Versions.props index ffe07f0a00fe..7b6e665d0789 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -175,9 +175,9 @@ - 7.0.0-preview.24119.1 - 7.0.0-preview.24119.1 - 7.0.0-preview.24119.1 + 7.0.0-preview.24119.2 + 7.0.0-preview.24119.2 + 7.0.0-preview.24119.2 From addf6cb4ce9577551a8fd691e365834a15e82ea6 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Tue, 20 Feb 2024 17:58:49 +0000 Subject: [PATCH 234/577] [release/8.0.3xx] Update dependencies from dotnet/roslyn (#38897) [release/8.0.3xx] Update dependencies from dotnet/roslyn --- eng/Version.Details.xml | 28 ++++++++++++++-------------- eng/Versions.props | 14 +++++++------- 2 files changed, 21 insertions(+), 21 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index b1913dee9533..ae924623aad1 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -78,34 +78,34 @@ d237e172b324021b97effa244af44d63d1a8bb7e - + https://github.com/dotnet/roslyn - f656544b1a42c3d212362dab79829e0b3abe30f4 + 25aa74d725e801b8232dbb3e5abcda0fa72da8c5 - + https://github.com/dotnet/roslyn - f656544b1a42c3d212362dab79829e0b3abe30f4 + 25aa74d725e801b8232dbb3e5abcda0fa72da8c5 - + https://github.com/dotnet/roslyn - f656544b1a42c3d212362dab79829e0b3abe30f4 + 25aa74d725e801b8232dbb3e5abcda0fa72da8c5 - + https://github.com/dotnet/roslyn - f656544b1a42c3d212362dab79829e0b3abe30f4 + 25aa74d725e801b8232dbb3e5abcda0fa72da8c5 - + https://github.com/dotnet/roslyn - f656544b1a42c3d212362dab79829e0b3abe30f4 + 25aa74d725e801b8232dbb3e5abcda0fa72da8c5 - + https://github.com/dotnet/roslyn - f656544b1a42c3d212362dab79829e0b3abe30f4 + 25aa74d725e801b8232dbb3e5abcda0fa72da8c5 - + https://github.com/dotnet/roslyn - f656544b1a42c3d212362dab79829e0b3abe30f4 + 25aa74d725e801b8232dbb3e5abcda0fa72da8c5 https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore diff --git a/eng/Versions.props b/eng/Versions.props index 7b6e665d0789..882a34f30d1c 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -154,13 +154,13 @@ - 4.10.0-2.24116.4 - 4.10.0-2.24116.4 - 4.10.0-2.24116.4 - 4.10.0-2.24116.4 - 4.10.0-2.24116.4 - 4.10.0-2.24116.4 - 4.10.0-2.24116.4 + 4.10.0-2.24120.1 + 4.10.0-2.24120.1 + 4.10.0-2.24120.1 + 4.10.0-2.24120.1 + 4.10.0-2.24120.1 + 4.10.0-2.24120.1 + 4.10.0-2.24120.1 $(MicrosoftNetCompilersToolsetPackageVersion) From 41d72d20451bd5fc94bcb5d5d189e6f720890615 Mon Sep 17 00:00:00 2001 From: Noah Gilson Date: Tue, 20 Feb 2024 16:52:44 -0800 Subject: [PATCH 235/577] Move Record Creation to before installed workloads are queried so It executes properly and fixes preexisting bad states even if skip manifest update is on --- .../install/WorkloadInstallCommand.cs | 21 +++++++++++-------- .../list/VisualStudioWorkloads.cs | 5 ++++- .../update/WorkloadUpdateCommand.cs | 2 +- 3 files changed, 17 insertions(+), 11 deletions(-) diff --git a/src/Cli/dotnet/commands/dotnet-workload/install/WorkloadInstallCommand.cs b/src/Cli/dotnet/commands/dotnet-workload/install/WorkloadInstallCommand.cs index 571665ccaf3b..edf4e72994ce 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/install/WorkloadInstallCommand.cs +++ b/src/Cli/dotnet/commands/dotnet-workload/install/WorkloadInstallCommand.cs @@ -124,13 +124,15 @@ public override int Execute() return _workloadInstaller.ExitCode; } - public void InstallWorkloads(IEnumerable workloadIds, bool skipManifestUpdate = false, bool includePreviews = false, DirectoryPath? offlineCache = null) + public void InstallWorkloads(IEnumerable workloadIdsToInstallOrUpdate, bool skipManifestUpdate = false, bool includePreviews = false, DirectoryPath? offlineCache = null) { Reporter.WriteLine(); var manifestsToUpdate = Enumerable.Empty(); var useRollback = false; + WriteSDKInstallRecordsForVSWorkloads(); + if (!skipManifestUpdate) { var installStateFilePath = Path.Combine(WorkloadInstallType.GetInstallStateFolder(_sdkFeatureBand, _dotnetPath), "default.json"); @@ -148,14 +150,17 @@ public void InstallWorkloads(IEnumerable workloadIds, bool skipManif { Reporter.WriteLine(LocalizableStrings.CheckForUpdatedWorkloadManifests); } - // Update currently installed workloads + + + // Add workload Ids that already exist to our collection to later trigger an update in those installed workloads var installedWorkloads = _workloadInstaller.GetWorkloadInstallationRecordRepository().GetInstalledWorkloads(_sdkFeatureBand); - var previouslyInstalledWorkloads = installedWorkloads.Intersect(workloadIds); + var previouslyInstalledWorkloads = installedWorkloads.Intersect(workloadIdsToInstallOrUpdate); if (previouslyInstalledWorkloads.Any()) { Reporter.WriteLine(string.Format(LocalizableStrings.WorkloadAlreadyInstalled, string.Join(" ", previouslyInstalledWorkloads)).Yellow()); } - workloadIds = workloadIds.Concat(installedWorkloads).Distinct(); + + workloadIdsToInstallOrUpdate = workloadIdsToInstallOrUpdate.Concat(installedWorkloads).Distinct(); useRollback = !string.IsNullOrWhiteSpace(_fromRollbackDefinition); @@ -163,16 +168,14 @@ public void InstallWorkloads(IEnumerable workloadIds, bool skipManif manifestsToUpdate = useRollback ? _workloadManifestUpdater.CalculateManifestRollbacks(_fromRollbackDefinition) : _workloadManifestUpdater.CalculateManifestUpdates().Select(m => m.ManifestUpdate); - - WriteSDKInstallRecordsForVSWorkloads(); } - InstallWorkloadsWithInstallRecord(_workloadInstaller, workloadIds, _sdkFeatureBand, manifestsToUpdate, offlineCache, useRollback); + InstallWorkloadsWithInstallRecord(_workloadInstaller, workloadIdsToInstallOrUpdate, _sdkFeatureBand, manifestsToUpdate, offlineCache, useRollback); TryRunGarbageCollection(_workloadInstaller, Reporter, Verbosity, workloadSetVersion => _workloadResolverFactory.CreateForWorkloadSet(_dotnetPath, _sdkVersion.ToString(), _userProfileDir, workloadSetVersion), offlineCache); Reporter.WriteLine(); - Reporter.WriteLine(string.Format(LocalizableStrings.InstallationSucceeded, string.Join(" ", workloadIds))); + Reporter.WriteLine(string.Format(LocalizableStrings.InstallationSucceeded, string.Join(" ", workloadIdsToInstallOrUpdate))); Reporter.WriteLine(); } @@ -196,7 +199,7 @@ private void WriteSDKInstallRecordsForVSWorkloads() if (OperatingSystem.IsWindows()) { // The 'workload restore' command relies on this happening through the existing chain of logic, if this is massively refactored please ensure this is called. - VisualStudioWorkloads.WriteSDKInstallRecordsForVSWorkloads(_workloadInstaller, _workloadResolver, GetInstalledWorkloads(false)); + VisualStudioWorkloads.WriteSDKInstallRecordsForVSWorkloads(_workloadInstaller, _workloadResolver, GetInstalledWorkloads(false), Reporter); } #endif } diff --git a/src/Cli/dotnet/commands/dotnet-workload/list/VisualStudioWorkloads.cs b/src/Cli/dotnet/commands/dotnet-workload/list/VisualStudioWorkloads.cs index 4ac3775cdba5..13d9e3ebdc77 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/list/VisualStudioWorkloads.cs +++ b/src/Cli/dotnet/commands/dotnet-workload/list/VisualStudioWorkloads.cs @@ -3,6 +3,7 @@ using System.Runtime.Versioning; using Microsoft.Deployment.DotNet.Releases; +using Microsoft.DotNet.Cli.Utils; using Microsoft.DotNet.Workloads.Workload.Install; using Microsoft.DotNet.Workloads.Workload.List; using Microsoft.NET.Sdk.WorkloadManifestReader; @@ -126,7 +127,7 @@ internal static void GetInstalledWorkloads(IWorkloadResolver workloadResolver, /// ... but these workloads don't have their corresponding packs installed as VS doesn't update its workloads as the CLI does. /// internal static void WriteSDKInstallRecordsForVSWorkloads(IInstaller workloadInstaller, IWorkloadResolver workloadResolver, - IEnumerable workloadsWithExistingInstallRecords) + IEnumerable workloadsWithExistingInstallRecords, IReporter reporter) { if (OperatingSystem.IsWindows()) { @@ -139,6 +140,8 @@ internal static void WriteSDKInstallRecordsForVSWorkloads(IInstaller workloadIns // Remove workloads with an SDK installation source, as we've already created install records for them, and don't need to again. var vsOnlyWorkloads = vsWorkloads.AsEnumerable().Where(w => !w.Value.Contains("SDK")).Select(w => new WorkloadId(w.Key)); var workloadsToWriteRecordsFor = vsOnlyWorkloads.Except(workloadsWithExistingInstallRecords); + + reporter.WriteLine($"Writing workload install records for Visual Studio workloads: {string.Join(", ", workloadsToWriteRecordsFor.Select(w => w.ToString()).ToArray())}"); ((NetSdkMsiInstallerClient)workloadInstaller).WriteWorkloadInstallRecords(workloadsToWriteRecordsFor); } } diff --git a/src/Cli/dotnet/commands/dotnet-workload/update/WorkloadUpdateCommand.cs b/src/Cli/dotnet/commands/dotnet-workload/update/WorkloadUpdateCommand.cs index 5bd010066914..c92023463cd3 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/update/WorkloadUpdateCommand.cs +++ b/src/Cli/dotnet/commands/dotnet-workload/update/WorkloadUpdateCommand.cs @@ -149,7 +149,7 @@ private void WriteSDKInstallRecordsForVSWorkloads() #if !DOT_NET_BUILD_FROM_SOURCE if (OperatingSystem.IsWindows()) { - VisualStudioWorkloads.WriteSDKInstallRecordsForVSWorkloads(_workloadInstaller, _workloadResolver, GetUpdatableWorkloads()); + VisualStudioWorkloads.WriteSDKInstallRecordsForVSWorkloads(_workloadInstaller, _workloadResolver, GetUpdatableWorkloads(), Reporter); } #endif } From 0be44f810fc1074a8ce19f02a5877493ebd40680 Mon Sep 17 00:00:00 2001 From: Rainer Sigwald Date: Tue, 20 Feb 2024 22:57:13 -0600 Subject: [PATCH 236/577] Don't copy MSBuild to Container outputs (#37315) --- .../Microsoft.DotNet.Cli.Utils.csproj | 4 ++-- .../Microsoft.NET.Build.Tasks.UnitTests.csproj | 6 +++--- .../Microsoft.NET.Sdk.Publish.Tasks.Tests.csproj | 2 +- .../Microsoft.NET.TestFramework.csproj | 3 ++- 4 files changed, 8 insertions(+), 7 deletions(-) diff --git a/src/Cli/Microsoft.DotNet.Cli.Utils/Microsoft.DotNet.Cli.Utils.csproj b/src/Cli/Microsoft.DotNet.Cli.Utils/Microsoft.DotNet.Cli.Utils.csproj index fffc7b1b34bf..60b3af428246 100644 --- a/src/Cli/Microsoft.DotNet.Cli.Utils/Microsoft.DotNet.Cli.Utils.csproj +++ b/src/Cli/Microsoft.DotNet.Cli.Utils/Microsoft.DotNet.Cli.Utils.csproj @@ -48,8 +48,8 @@ - - + + diff --git a/src/Tasks/Microsoft.NET.Build.Tasks.UnitTests/Microsoft.NET.Build.Tasks.UnitTests.csproj b/src/Tasks/Microsoft.NET.Build.Tasks.UnitTests/Microsoft.NET.Build.Tasks.UnitTests.csproj index 09ee2a7255f8..abcc3b523542 100644 --- a/src/Tasks/Microsoft.NET.Build.Tasks.UnitTests/Microsoft.NET.Build.Tasks.UnitTests.csproj +++ b/src/Tasks/Microsoft.NET.Build.Tasks.UnitTests/Microsoft.NET.Build.Tasks.UnitTests.csproj @@ -13,10 +13,10 @@ $(SdkTargetFramework) false - + - + @@ -42,5 +42,5 @@ - + diff --git a/src/Tests/Microsoft.NET.Sdk.Publish.Tasks.Tests/Microsoft.NET.Sdk.Publish.Tasks.Tests.csproj b/src/Tests/Microsoft.NET.Sdk.Publish.Tasks.Tests/Microsoft.NET.Sdk.Publish.Tasks.Tests.csproj index ecc90aae81fd..5607ef03dca1 100644 --- a/src/Tests/Microsoft.NET.Sdk.Publish.Tasks.Tests/Microsoft.NET.Sdk.Publish.Tasks.Tests.csproj +++ b/src/Tests/Microsoft.NET.Sdk.Publish.Tasks.Tests/Microsoft.NET.Sdk.Publish.Tasks.Tests.csproj @@ -18,7 +18,7 @@ - + diff --git a/src/Tests/Microsoft.NET.TestFramework/Microsoft.NET.TestFramework.csproj b/src/Tests/Microsoft.NET.TestFramework/Microsoft.NET.TestFramework.csproj index ab4fb9b1096b..a1ca92331c75 100644 --- a/src/Tests/Microsoft.NET.TestFramework/Microsoft.NET.TestFramework.csproj +++ b/src/Tests/Microsoft.NET.TestFramework/Microsoft.NET.TestFramework.csproj @@ -16,7 +16,7 @@ with the actual test projects that reference it. --> false - + $(SdkTargetFramework);net472 @@ -32,6 +32,7 @@ + From 4f8d18001d8617b4a5368224c33a44db05af8c14 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Wed, 21 Feb 2024 19:27:01 +0000 Subject: [PATCH 237/577] [release/8.0.3xx] Update dependencies from dotnet/msbuild (#38924) [release/8.0.3xx] Update dependencies from dotnet/msbuild --- eng/Version.Details.xml | 12 ++++++------ eng/Versions.props | 4 ++-- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index e6b6bcf3a356..75f29e43361b 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -51,17 +51,17 @@ https://github.com/dotnet/emsdk 2fc2ffd960930318f33fcaa690cbdbc55d72f52d - + https://github.com/dotnet/msbuild - 53c4f49868e88ecd7407339a3f4dab9e75c7937f + aa5b55280b9e4ba92aaf39a650b94227a44bf834 - + https://github.com/dotnet/msbuild - 53c4f49868e88ecd7407339a3f4dab9e75c7937f + aa5b55280b9e4ba92aaf39a650b94227a44bf834 - + https://github.com/dotnet/msbuild - 53c4f49868e88ecd7407339a3f4dab9e75c7937f + aa5b55280b9e4ba92aaf39a650b94227a44bf834 diff --git a/eng/Versions.props b/eng/Versions.props index 24e8a6a7e6d1..469df3c2dbc5 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -120,7 +120,7 @@ - 17.10.0-preview-24120-03 + 17.10.0-preview-24120-06 $(MicrosoftBuildPackageVersion) - 12.8.300-beta.24119.1 + 12.8.300-beta.24120.1 From 08059da317ff921edbd60accf09505248f19d950 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Wed, 21 Feb 2024 19:27:43 +0000 Subject: [PATCH 239/577] [release/8.0.3xx] Update dependencies from dotnet/razor (#38926) [release/8.0.3xx] Update dependencies from dotnet/razor --- eng/Version.Details.xml | 12 ++++++------ eng/Versions.props | 6 +++--- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 350019b0fee9..61587de3dd97 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -277,18 +277,18 @@ https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore da7e9894ce22ef8cc02e5acc56e95a6f8cf8f644 - + https://github.com/dotnet/razor - 667c05ce82ca55f15ecb4578274df4aa0af9d204 + 67bd8253e308d06bf249a02911d06317d5d7b5b9 - + https://github.com/dotnet/razor - 667c05ce82ca55f15ecb4578274df4aa0af9d204 + 67bd8253e308d06bf249a02911d06317d5d7b5b9 - + https://github.com/dotnet/razor - 667c05ce82ca55f15ecb4578274df4aa0af9d204 + 67bd8253e308d06bf249a02911d06317d5d7b5b9 https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore diff --git a/eng/Versions.props b/eng/Versions.props index 7172383f84ab..a19051bd6d58 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -175,9 +175,9 @@ - 7.0.0-preview.24119.2 - 7.0.0-preview.24119.2 - 7.0.0-preview.24119.2 + 7.0.0-preview.24120.8 + 7.0.0-preview.24120.8 + 7.0.0-preview.24120.8 From c293e7562fdeda4268080558c279355c2e25ac14 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Wed, 21 Feb 2024 20:07:54 +0000 Subject: [PATCH 240/577] [release/8.0.3xx] Update dependencies from dotnet/roslyn (#38927) [release/8.0.3xx] Update dependencies from dotnet/roslyn --- eng/Version.Details.xml | 28 ++++++++++++++-------------- eng/Versions.props | 14 +++++++------- 2 files changed, 21 insertions(+), 21 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 61587de3dd97..5508133ea0c1 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -78,34 +78,34 @@ d237e172b324021b97effa244af44d63d1a8bb7e - + https://github.com/dotnet/roslyn - 25aa74d725e801b8232dbb3e5abcda0fa72da8c5 + 3472dcbca677f86bced5a1f180ae45e83c3e8f2d - + https://github.com/dotnet/roslyn - 25aa74d725e801b8232dbb3e5abcda0fa72da8c5 + 3472dcbca677f86bced5a1f180ae45e83c3e8f2d - + https://github.com/dotnet/roslyn - 25aa74d725e801b8232dbb3e5abcda0fa72da8c5 + 3472dcbca677f86bced5a1f180ae45e83c3e8f2d - + https://github.com/dotnet/roslyn - 25aa74d725e801b8232dbb3e5abcda0fa72da8c5 + 3472dcbca677f86bced5a1f180ae45e83c3e8f2d - + https://github.com/dotnet/roslyn - 25aa74d725e801b8232dbb3e5abcda0fa72da8c5 + 3472dcbca677f86bced5a1f180ae45e83c3e8f2d - + https://github.com/dotnet/roslyn - 25aa74d725e801b8232dbb3e5abcda0fa72da8c5 + 3472dcbca677f86bced5a1f180ae45e83c3e8f2d - + https://github.com/dotnet/roslyn - 25aa74d725e801b8232dbb3e5abcda0fa72da8c5 + 3472dcbca677f86bced5a1f180ae45e83c3e8f2d https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore diff --git a/eng/Versions.props b/eng/Versions.props index a19051bd6d58..5183add1c43e 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -154,13 +154,13 @@ - 4.10.0-2.24120.1 - 4.10.0-2.24120.1 - 4.10.0-2.24120.1 - 4.10.0-2.24120.1 - 4.10.0-2.24120.1 - 4.10.0-2.24120.1 - 4.10.0-2.24120.1 + 4.10.0-2.24121.2 + 4.10.0-2.24121.2 + 4.10.0-2.24121.2 + 4.10.0-2.24121.2 + 4.10.0-2.24121.2 + 4.10.0-2.24121.2 + 4.10.0-2.24121.2 $(MicrosoftNetCompilersToolsetPackageVersion) From 8c90777be6fe0b81f723a96306ba7d69423ba7e5 Mon Sep 17 00:00:00 2001 From: Jason Zhai Date: Thu, 22 Feb 2024 00:18:06 -0800 Subject: [PATCH 241/577] Bump required MSBuild version --- .../BuildWithComponentsIntegrationTest.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Tests/Microsoft.NET.Sdk.Razor.Tests/BuildWithComponentsIntegrationTest.cs b/src/Tests/Microsoft.NET.Sdk.Razor.Tests/BuildWithComponentsIntegrationTest.cs index b7dcb6f14821..8224b7f28743 100644 --- a/src/Tests/Microsoft.NET.Sdk.Razor.Tests/BuildWithComponentsIntegrationTest.cs +++ b/src/Tests/Microsoft.NET.Sdk.Razor.Tests/BuildWithComponentsIntegrationTest.cs @@ -12,7 +12,7 @@ public BuildWithComponentsIntegrationTest(ITestOutputHelper log) : base(log) {} [CoreMSBuildOnlyFact] public void Build_Components_WithDotNetCoreMSBuild_Works() => Build_ComponentsWorks(); - [RequiresMSBuildVersionFact("17.9.2.5503")] + [RequiresMSBuildVersionFact("17.10.0.8101")] public void Build_Components_WithDesktopMSBuild_Works() => Build_ComponentsWorks(); [Fact] From 8eea5e6b3b39002eb60211447718a043985efd81 Mon Sep 17 00:00:00 2001 From: Mariana Dematte Date: Thu, 22 Feb 2024 22:23:02 +0100 Subject: [PATCH 242/577] Added test for .user file in outer build (#37192) --- ...nThatWeWantToBuildACrossTargetedLibrary.cs | 41 +++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/src/Tests/Microsoft.NET.Build.Tests/GivenThatWeWantToBuildACrossTargetedLibrary.cs b/src/Tests/Microsoft.NET.Build.Tests/GivenThatWeWantToBuildACrossTargetedLibrary.cs index 8b49b2debd89..888215e36c7d 100644 --- a/src/Tests/Microsoft.NET.Build.Tests/GivenThatWeWantToBuildACrossTargetedLibrary.cs +++ b/src/Tests/Microsoft.NET.Build.Tests/GivenThatWeWantToBuildACrossTargetedLibrary.cs @@ -140,5 +140,46 @@ public void OutputPathDoesNotHaveDuplicatedBackslashesInOuterBuild() string outputPathValue = File.ReadAllText(Path.Combine(testAsset.TestRoot, testProject.Name, "OutputPathValue.txt")); outputPathValue.Trim().Should().NotContain("\\\\"); } + + [RequiresMSBuildVersionFact("17.9.0.61803")] + public void OuterBuildImportsUserFile() + { + var testProject = new TestProject() + { + TargetFrameworks = $"{ToolsetInfo.CurrentTargetFramework};net7.0" + }; + + testProject.ProjectChanges.Add(xml => + { + var target = """ + + + + """; + + xml.Root.Add(XElement.Parse(target)); + }); + + string temp = $"{testProject.Name}.csproj.user"; + testProject.SourceFiles[temp] = """ + + + A User defined value + + + """; + + var testAsset = _testAssetsManager.CreateTestProject(testProject); + + new BuildCommand(testAsset) + .Execute() + .Should() + .Pass(); + + string outputPathValue = File.ReadAllText(Path.Combine(testAsset.TestRoot, testProject.Name, "OutputPathValue.txt")); + outputPathValue.Should().Contain("User value is: A User defined value"); + } } } From cff0933b10b3ff5f6a470045f53ee28a02cb046f Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Fri, 23 Feb 2024 00:04:27 +0000 Subject: [PATCH 243/577] [release/8.0.3xx] Update dependencies from microsoft/vstest (#38949) [release/8.0.3xx] Update dependencies from microsoft/vstest --- eng/Version.Details.xml | 12 ++++++------ eng/Versions.props | 6 +++--- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 5508133ea0c1..1ee4826554d8 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -179,18 +179,18 @@ https://github.com/nuget/nuget.client 8b658e2eee6391936887b9fd1b39f7918d16a9cb - + https://github.com/microsoft/vstest - c13b1f9b2bb6acbb9785de003be3d9ace33c9d7c + 48d8e778c871315db0bad221b00f4843b06242c3 - + https://github.com/microsoft/vstest - c13b1f9b2bb6acbb9785de003be3d9ace33c9d7c + 48d8e778c871315db0bad221b00f4843b06242c3 - + https://github.com/microsoft/vstest - c13b1f9b2bb6acbb9785de003be3d9ace33c9d7c + 48d8e778c871315db0bad221b00f4843b06242c3 https://dev.azure.com/dnceng/internal/_git/dotnet-runtime diff --git a/eng/Versions.props b/eng/Versions.props index 5183add1c43e..add881cfd4ee 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -99,9 +99,9 @@ - 17.10.0-preview-24119-01 - 17.10.0-preview-24119-01 - 17.10.0-preview-24119-01 + 17.10.0-preview-24120-01 + 17.10.0-preview-24120-01 + 17.10.0-preview-24120-01 From 0ec19bb520fb9c1213719c34a524810a06cdf63a Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Fri, 23 Feb 2024 00:29:18 +0000 Subject: [PATCH 244/577] [release/8.0.3xx] Update dependencies from dotnet/msbuild (#38948) [release/8.0.3xx] Update dependencies from dotnet/msbuild --- eng/Version.Details.xml | 12 ++++++------ eng/Versions.props | 4 ++-- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 1ee4826554d8..b70ffb8c5d46 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -51,17 +51,17 @@ https://github.com/dotnet/emsdk 2fc2ffd960930318f33fcaa690cbdbc55d72f52d - + https://github.com/dotnet/msbuild - aa5b55280b9e4ba92aaf39a650b94227a44bf834 + d4cb14fe4d2e6df0327308feab18ccbb2046246c - + https://github.com/dotnet/msbuild - aa5b55280b9e4ba92aaf39a650b94227a44bf834 + d4cb14fe4d2e6df0327308feab18ccbb2046246c - + https://github.com/dotnet/msbuild - aa5b55280b9e4ba92aaf39a650b94227a44bf834 + d4cb14fe4d2e6df0327308feab18ccbb2046246c diff --git a/eng/Versions.props b/eng/Versions.props index add881cfd4ee..068a159f9745 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -120,7 +120,7 @@ - 17.10.0-preview-24120-06 + 17.10.0-preview-24122-01 $(MicrosoftBuildPackageVersion) - 6.10.0-preview.2.32 - 6.10.0-preview.2.32 + 6.10.0-preview.2.40 + 6.10.0-preview.2.40 6.0.0-rc.278 - 6.10.0-preview.2.32 - 6.10.0-preview.2.32 - 6.10.0-preview.2.32 - 6.10.0-preview.2.32 - 6.10.0-preview.2.32 - 6.10.0-preview.2.32 - 6.10.0-preview.2.32 - 6.10.0-preview.2.32 - 6.10.0-preview.2.32 + 6.10.0-preview.2.40 + 6.10.0-preview.2.40 + 6.10.0-preview.2.40 + 6.10.0-preview.2.40 + 6.10.0-preview.2.40 + 6.10.0-preview.2.40 + 6.10.0-preview.2.40 + 6.10.0-preview.2.40 + 6.10.0-preview.2.40 $(NuGetPackagingPackageVersion) $(NuGetProjectModelPackageVersion) diff --git a/src/Tasks/Microsoft.NET.Build.Tasks.UnitTests/LockFileSnippets.cs b/src/Tasks/Microsoft.NET.Build.Tasks.UnitTests/LockFileSnippets.cs index 57c86f9b6167..c116c6560b44 100644 --- a/src/Tasks/Microsoft.NET.Build.Tasks.UnitTests/LockFileSnippets.cs +++ b/src/Tasks/Microsoft.NET.Build.Tasks.UnitTests/LockFileSnippets.cs @@ -210,7 +210,7 @@ public static string CreateProjectFileDependencyGroup(string tfm, params string[ public static string CreateLog(NuGetLogCode code, LogLevel level, string message, string filePath = null, string libraryId = null, - string warningLevel = "0", + int warningLevel = 0, string[] targetGraphs = null) { List parts = new List(); @@ -218,7 +218,7 @@ public static string CreateLog(NuGetLogCode code, LogLevel level, string message parts.Add($"\"code\": \"{code}\""); parts.Add($"\"level\": \"{level}\""); parts.Add($"\"message\": \"{message}\""); - parts.Add($"\"warningLevel\": \"{warningLevel}\""); + parts.Add($"\"warningLevel\": {warningLevel}"); if (filePath != null) parts.Add($"\"filePath\": \"{filePath}\""); if (libraryId != null) parts.Add($"\"libraryId\": \"{libraryId}\""); diff --git a/src/Tests/Microsoft.NET.Build.Tests/GivenThatWeWantDiagnosticsWhenAssetsFileCannotBeRead.cs b/src/Tests/Microsoft.NET.Build.Tests/GivenThatWeWantDiagnosticsWhenAssetsFileCannotBeRead.cs index df34864d5ee8..b9afdaf1e208 100644 --- a/src/Tests/Microsoft.NET.Build.Tests/GivenThatWeWantDiagnosticsWhenAssetsFileCannotBeRead.cs +++ b/src/Tests/Microsoft.NET.Build.Tests/GivenThatWeWantDiagnosticsWhenAssetsFileCannotBeRead.cs @@ -42,7 +42,7 @@ public void It_reports_corrupt_file() var assetsFile = Path.Combine(build.GetBaseIntermediateDirectory().FullName, "project.assets.json"); File.WriteAllText(assetsFile, "{ corrupt_file: "); - build.ExecuteWithoutRestore().Should().Fail().And.HaveStdOutMatching($"{Regex.Escape(assetsFile)}.*corrupt_file"); + build.ExecuteWithoutRestore().Should().Fail().And.HaveStdOutContaining("NETSDK1060"); } } } From d8df3998654ab7ee0cbad0f321731f063b1a71b2 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Fri, 23 Feb 2024 02:41:51 +0000 Subject: [PATCH 246/577] [release/8.0.3xx] Update dependencies from dotnet/fsharp (#38950) [release/8.0.3xx] Update dependencies from dotnet/fsharp --- eng/Version.Details.xml | 8 ++++---- eng/Versions.props | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 2e5deba4c2c5..a93b0ab60e76 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -64,13 +64,13 @@ d4cb14fe4d2e6df0327308feab18ccbb2046246c - + https://github.com/dotnet/fsharp - f2a6810476e1b589bcf56eb5f377c5214c509bc6 + b1a970dcc7631fb07ec20f2f0485ae732c3f30d7 - + https://github.com/dotnet/fsharp - f2a6810476e1b589bcf56eb5f377c5214c509bc6 + b1a970dcc7631fb07ec20f2f0485ae732c3f30d7 diff --git a/eng/Versions.props b/eng/Versions.props index 4b909487f913..2b76f6d6f1a4 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -150,7 +150,7 @@ - 12.8.300-beta.24120.1 + 12.8.300-beta.24121.3 From 195fc36bdd8193f077f8e7a09629f9080e0a563c Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Fri, 23 Feb 2024 22:19:18 +0000 Subject: [PATCH 247/577] [release/8.0.3xx] Update dependencies from nuget/nuget.client (#38972) [release/8.0.3xx] Update dependencies from nuget/nuget.client --- NuGet.config | 1 + eng/Version.Details.xml | 64 ++++++++++++++++++++--------------------- eng/Versions.props | 22 +++++++------- 3 files changed, 44 insertions(+), 43 deletions(-) diff --git a/NuGet.config b/NuGet.config index 20c9125ee569..0414c6c4926a 100644 --- a/NuGet.config +++ b/NuGet.config @@ -7,6 +7,7 @@ + diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index a93b0ab60e76..bd3b31d813fc 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -115,69 +115,69 @@ https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore da7e9894ce22ef8cc02e5acc56e95a6f8cf8f644 - + https://github.com/nuget/nuget.client - d49b8abb6b64d2a49a439380af8c62d099ba31fb + 63958aab19b7120862ff55eac32ab6a155596a59 - + https://github.com/nuget/nuget.client - d49b8abb6b64d2a49a439380af8c62d099ba31fb + 63958aab19b7120862ff55eac32ab6a155596a59 - + https://github.com/nuget/nuget.client - d49b8abb6b64d2a49a439380af8c62d099ba31fb + 63958aab19b7120862ff55eac32ab6a155596a59 - + https://github.com/nuget/nuget.client - d49b8abb6b64d2a49a439380af8c62d099ba31fb + 63958aab19b7120862ff55eac32ab6a155596a59 - + https://github.com/nuget/nuget.client - d49b8abb6b64d2a49a439380af8c62d099ba31fb + 63958aab19b7120862ff55eac32ab6a155596a59 - + https://github.com/nuget/nuget.client - d49b8abb6b64d2a49a439380af8c62d099ba31fb + 63958aab19b7120862ff55eac32ab6a155596a59 - + https://github.com/nuget/nuget.client - d49b8abb6b64d2a49a439380af8c62d099ba31fb + 63958aab19b7120862ff55eac32ab6a155596a59 - + https://github.com/nuget/nuget.client - d49b8abb6b64d2a49a439380af8c62d099ba31fb + 63958aab19b7120862ff55eac32ab6a155596a59 - + https://github.com/nuget/nuget.client - d49b8abb6b64d2a49a439380af8c62d099ba31fb + 63958aab19b7120862ff55eac32ab6a155596a59 - + https://github.com/nuget/nuget.client - d49b8abb6b64d2a49a439380af8c62d099ba31fb + 63958aab19b7120862ff55eac32ab6a155596a59 - + https://github.com/nuget/nuget.client - d49b8abb6b64d2a49a439380af8c62d099ba31fb + 63958aab19b7120862ff55eac32ab6a155596a59 - + https://github.com/nuget/nuget.client - d49b8abb6b64d2a49a439380af8c62d099ba31fb + 63958aab19b7120862ff55eac32ab6a155596a59 - + https://github.com/nuget/nuget.client - d49b8abb6b64d2a49a439380af8c62d099ba31fb + 63958aab19b7120862ff55eac32ab6a155596a59 - + https://github.com/nuget/nuget.client - d49b8abb6b64d2a49a439380af8c62d099ba31fb + 63958aab19b7120862ff55eac32ab6a155596a59 - + https://github.com/nuget/nuget.client - d49b8abb6b64d2a49a439380af8c62d099ba31fb + 63958aab19b7120862ff55eac32ab6a155596a59 - + https://github.com/nuget/nuget.client - d49b8abb6b64d2a49a439380af8c62d099ba31fb + 63958aab19b7120862ff55eac32ab6a155596a59 https://github.com/microsoft/vstest diff --git a/eng/Versions.props b/eng/Versions.props index 2b76f6d6f1a4..dd3f1b8498e3 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -82,18 +82,18 @@ - 6.10.0-preview.2.40 - 6.10.0-preview.2.40 + 6.10.0-preview.2.41 + 6.10.0-preview.2.41 6.0.0-rc.278 - 6.10.0-preview.2.40 - 6.10.0-preview.2.40 - 6.10.0-preview.2.40 - 6.10.0-preview.2.40 - 6.10.0-preview.2.40 - 6.10.0-preview.2.40 - 6.10.0-preview.2.40 - 6.10.0-preview.2.40 - 6.10.0-preview.2.40 + 6.10.0-preview.2.41 + 6.10.0-preview.2.41 + 6.10.0-preview.2.41 + 6.10.0-preview.2.41 + 6.10.0-preview.2.41 + 6.10.0-preview.2.41 + 6.10.0-preview.2.41 + 6.10.0-preview.2.41 + 6.10.0-preview.2.41 $(NuGetPackagingPackageVersion) $(NuGetProjectModelPackageVersion) From e661d6c83ae921a2bdbf2de71fe7d55a1166afb2 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" Date: Sat, 24 Feb 2024 13:27:37 +0000 Subject: [PATCH 248/577] Update dependencies from https://github.com/nuget/nuget.client build 6.10.0.44 Microsoft.Build.NuGetSdkResolver , NuGet.Build.Tasks , NuGet.Build.Tasks.Console , NuGet.Build.Tasks.Pack , NuGet.CommandLine.XPlat , NuGet.Commands , NuGet.Common , NuGet.Configuration , NuGet.Credentials , NuGet.DependencyResolver.Core , NuGet.Frameworks , NuGet.LibraryModel , NuGet.Packaging , NuGet.ProjectModel , NuGet.Protocol , NuGet.Versioning From Version 6.10.0-preview.2.41 -> To Version 6.10.0-preview.2.44 --- eng/Version.Details.xml | 64 ++++++++++++++++++++--------------------- eng/Versions.props | 22 +++++++------- 2 files changed, 43 insertions(+), 43 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index bd3b31d813fc..80d5a25147ed 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -115,69 +115,69 @@ https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore da7e9894ce22ef8cc02e5acc56e95a6f8cf8f644 - + https://github.com/nuget/nuget.client - 63958aab19b7120862ff55eac32ab6a155596a59 + 39c4f37d4baa00ee0b815fb394de7d51a58b17ab - + https://github.com/nuget/nuget.client - 63958aab19b7120862ff55eac32ab6a155596a59 + 39c4f37d4baa00ee0b815fb394de7d51a58b17ab - + https://github.com/nuget/nuget.client - 63958aab19b7120862ff55eac32ab6a155596a59 + 39c4f37d4baa00ee0b815fb394de7d51a58b17ab - + https://github.com/nuget/nuget.client - 63958aab19b7120862ff55eac32ab6a155596a59 + 39c4f37d4baa00ee0b815fb394de7d51a58b17ab - + https://github.com/nuget/nuget.client - 63958aab19b7120862ff55eac32ab6a155596a59 + 39c4f37d4baa00ee0b815fb394de7d51a58b17ab - + https://github.com/nuget/nuget.client - 63958aab19b7120862ff55eac32ab6a155596a59 + 39c4f37d4baa00ee0b815fb394de7d51a58b17ab - + https://github.com/nuget/nuget.client - 63958aab19b7120862ff55eac32ab6a155596a59 + 39c4f37d4baa00ee0b815fb394de7d51a58b17ab - + https://github.com/nuget/nuget.client - 63958aab19b7120862ff55eac32ab6a155596a59 + 39c4f37d4baa00ee0b815fb394de7d51a58b17ab - + https://github.com/nuget/nuget.client - 63958aab19b7120862ff55eac32ab6a155596a59 + 39c4f37d4baa00ee0b815fb394de7d51a58b17ab - + https://github.com/nuget/nuget.client - 63958aab19b7120862ff55eac32ab6a155596a59 + 39c4f37d4baa00ee0b815fb394de7d51a58b17ab - + https://github.com/nuget/nuget.client - 63958aab19b7120862ff55eac32ab6a155596a59 + 39c4f37d4baa00ee0b815fb394de7d51a58b17ab - + https://github.com/nuget/nuget.client - 63958aab19b7120862ff55eac32ab6a155596a59 + 39c4f37d4baa00ee0b815fb394de7d51a58b17ab - + https://github.com/nuget/nuget.client - 63958aab19b7120862ff55eac32ab6a155596a59 + 39c4f37d4baa00ee0b815fb394de7d51a58b17ab - + https://github.com/nuget/nuget.client - 63958aab19b7120862ff55eac32ab6a155596a59 + 39c4f37d4baa00ee0b815fb394de7d51a58b17ab - + https://github.com/nuget/nuget.client - 63958aab19b7120862ff55eac32ab6a155596a59 + 39c4f37d4baa00ee0b815fb394de7d51a58b17ab - + https://github.com/nuget/nuget.client - 63958aab19b7120862ff55eac32ab6a155596a59 + 39c4f37d4baa00ee0b815fb394de7d51a58b17ab https://github.com/microsoft/vstest diff --git a/eng/Versions.props b/eng/Versions.props index dd3f1b8498e3..4f098d56b93a 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -82,18 +82,18 @@ - 6.10.0-preview.2.41 - 6.10.0-preview.2.41 + 6.10.0-preview.2.44 + 6.10.0-preview.2.44 6.0.0-rc.278 - 6.10.0-preview.2.41 - 6.10.0-preview.2.41 - 6.10.0-preview.2.41 - 6.10.0-preview.2.41 - 6.10.0-preview.2.41 - 6.10.0-preview.2.41 - 6.10.0-preview.2.41 - 6.10.0-preview.2.41 - 6.10.0-preview.2.41 + 6.10.0-preview.2.44 + 6.10.0-preview.2.44 + 6.10.0-preview.2.44 + 6.10.0-preview.2.44 + 6.10.0-preview.2.44 + 6.10.0-preview.2.44 + 6.10.0-preview.2.44 + 6.10.0-preview.2.44 + 6.10.0-preview.2.44 $(NuGetPackagingPackageVersion) $(NuGetProjectModelPackageVersion) From a9d563a05e231804b58f8758cbf2552e9a62fe2c Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Sat, 24 Feb 2024 15:27:41 +0000 Subject: [PATCH 249/577] [release/8.0.3xx] Update dependencies from microsoft/vstest (#38974) [release/8.0.3xx] Update dependencies from microsoft/vstest --- eng/Version.Details.xml | 12 ++++++------ eng/Versions.props | 6 +++--- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index bd3b31d813fc..80aa483fcbbb 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -179,18 +179,18 @@ https://github.com/nuget/nuget.client 63958aab19b7120862ff55eac32ab6a155596a59 - + https://github.com/microsoft/vstest - 48d8e778c871315db0bad221b00f4843b06242c3 + f2323247155845f00166ebeca5cffdebff410b49 - + https://github.com/microsoft/vstest - 48d8e778c871315db0bad221b00f4843b06242c3 + f2323247155845f00166ebeca5cffdebff410b49 - + https://github.com/microsoft/vstest - 48d8e778c871315db0bad221b00f4843b06242c3 + f2323247155845f00166ebeca5cffdebff410b49 https://dev.azure.com/dnceng/internal/_git/dotnet-runtime diff --git a/eng/Versions.props b/eng/Versions.props index dd3f1b8498e3..3c46d16eaf90 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -99,9 +99,9 @@ - 17.10.0-preview-24120-01 - 17.10.0-preview-24120-01 - 17.10.0-preview-24120-01 + 17.10.0-preview-24123-01 + 17.10.0-preview-24123-01 + 17.10.0-preview-24123-01 From c5a6fa97195c89327f4f993fd40daafa26566fd1 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Sat, 24 Feb 2024 15:32:17 +0000 Subject: [PATCH 250/577] [release/8.0.3xx] Update dependencies from dotnet/msbuild (#38973) [release/8.0.3xx] Update dependencies from dotnet/msbuild --- eng/Version.Details.xml | 12 ++++++------ eng/Versions.props | 4 ++-- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 80aa483fcbbb..5148da924de4 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -51,17 +51,17 @@ https://github.com/dotnet/emsdk 2fc2ffd960930318f33fcaa690cbdbc55d72f52d - + https://github.com/dotnet/msbuild - d4cb14fe4d2e6df0327308feab18ccbb2046246c + 56c003594af2772b8a5f4c58023f239a431154fa - + https://github.com/dotnet/msbuild - d4cb14fe4d2e6df0327308feab18ccbb2046246c + 56c003594af2772b8a5f4c58023f239a431154fa - + https://github.com/dotnet/msbuild - d4cb14fe4d2e6df0327308feab18ccbb2046246c + 56c003594af2772b8a5f4c58023f239a431154fa diff --git a/eng/Versions.props b/eng/Versions.props index 3c46d16eaf90..248efa9346f9 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -120,7 +120,7 @@ - 17.10.0-preview-24122-01 + 17.10.0-preview-24123-01 $(MicrosoftBuildPackageVersion) - 4.10.0-2.24121.2 - 4.10.0-2.24121.2 - 4.10.0-2.24121.2 - 4.10.0-2.24121.2 - 4.10.0-2.24121.2 - 4.10.0-2.24121.2 - 4.10.0-2.24121.2 + 4.10.0-2.24123.6 + 4.10.0-2.24123.6 + 4.10.0-2.24123.6 + 4.10.0-2.24123.6 + 4.10.0-2.24123.6 + 4.10.0-2.24123.6 + 4.10.0-2.24123.6 $(MicrosoftNetCompilersToolsetPackageVersion) From 52368a7f8629b3ef0b0f9b1ad5e6289c5c1a5a63 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" Date: Sun, 25 Feb 2024 13:26:12 +0000 Subject: [PATCH 252/577] Update dependencies from https://github.com/nuget/nuget.client build 6.10.0.44 Microsoft.Build.NuGetSdkResolver , NuGet.Build.Tasks , NuGet.Build.Tasks.Console , NuGet.Build.Tasks.Pack , NuGet.CommandLine.XPlat , NuGet.Commands , NuGet.Common , NuGet.Configuration , NuGet.Credentials , NuGet.DependencyResolver.Core , NuGet.Frameworks , NuGet.LibraryModel , NuGet.Packaging , NuGet.ProjectModel , NuGet.Protocol , NuGet.Versioning From Version 6.10.0-preview.2.41 -> To Version 6.10.0-preview.2.44 From f412accbd620a84a636cd80c01911076914e2c8e Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" Date: Sun, 25 Feb 2024 13:27:41 +0000 Subject: [PATCH 253/577] Update dependencies from https://github.com/dotnet/roslyn build 20240224.2 Microsoft.CodeAnalysis , Microsoft.CodeAnalysis.CSharp , Microsoft.CodeAnalysis.CSharp.CodeStyle , Microsoft.CodeAnalysis.CSharp.Features , Microsoft.CodeAnalysis.CSharp.Workspaces , Microsoft.CodeAnalysis.Workspaces.MSBuild , Microsoft.Net.Compilers.Toolset From Version 4.10.0-2.24123.6 -> To Version 4.10.0-2.24124.2 --- eng/Version.Details.xml | 28 ++++++++++++++-------------- eng/Versions.props | 14 +++++++------- 2 files changed, 21 insertions(+), 21 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 85e161bbe972..fad17f7e4611 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -78,34 +78,34 @@ d237e172b324021b97effa244af44d63d1a8bb7e - + https://github.com/dotnet/roslyn - ae73e6a38ed37eb7b6e3a47403d290f9f51e006e + 3059a073c923ae9ee56c4ad012a0f2151583dd16 - + https://github.com/dotnet/roslyn - ae73e6a38ed37eb7b6e3a47403d290f9f51e006e + 3059a073c923ae9ee56c4ad012a0f2151583dd16 - + https://github.com/dotnet/roslyn - ae73e6a38ed37eb7b6e3a47403d290f9f51e006e + 3059a073c923ae9ee56c4ad012a0f2151583dd16 - + https://github.com/dotnet/roslyn - ae73e6a38ed37eb7b6e3a47403d290f9f51e006e + 3059a073c923ae9ee56c4ad012a0f2151583dd16 - + https://github.com/dotnet/roslyn - ae73e6a38ed37eb7b6e3a47403d290f9f51e006e + 3059a073c923ae9ee56c4ad012a0f2151583dd16 - + https://github.com/dotnet/roslyn - ae73e6a38ed37eb7b6e3a47403d290f9f51e006e + 3059a073c923ae9ee56c4ad012a0f2151583dd16 - + https://github.com/dotnet/roslyn - ae73e6a38ed37eb7b6e3a47403d290f9f51e006e + 3059a073c923ae9ee56c4ad012a0f2151583dd16 https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore diff --git a/eng/Versions.props b/eng/Versions.props index f7f27936570a..c0169dbb8c38 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -154,13 +154,13 @@ - 4.10.0-2.24123.6 - 4.10.0-2.24123.6 - 4.10.0-2.24123.6 - 4.10.0-2.24123.6 - 4.10.0-2.24123.6 - 4.10.0-2.24123.6 - 4.10.0-2.24123.6 + 4.10.0-2.24124.2 + 4.10.0-2.24124.2 + 4.10.0-2.24124.2 + 4.10.0-2.24124.2 + 4.10.0-2.24124.2 + 4.10.0-2.24124.2 + 4.10.0-2.24124.2 $(MicrosoftNetCompilersToolsetPackageVersion) From a9e54e3d90e4292eb4f6ce4984d92399c2e8331b Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Sun, 25 Feb 2024 15:29:53 +0000 Subject: [PATCH 254/577] [release/8.0.3xx] Update dependencies from dotnet/fsharp (#38975) [release/8.0.3xx] Update dependencies from dotnet/fsharp --- eng/Version.Details.xml | 8 ++++---- eng/Versions.props | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 85e161bbe972..894a8c55cb2f 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -64,13 +64,13 @@ 56c003594af2772b8a5f4c58023f239a431154fa - + https://github.com/dotnet/fsharp - b1a970dcc7631fb07ec20f2f0485ae732c3f30d7 + 02bb351b606468bce98688fccda9d0c8adcd964d - + https://github.com/dotnet/fsharp - b1a970dcc7631fb07ec20f2f0485ae732c3f30d7 + 02bb351b606468bce98688fccda9d0c8adcd964d diff --git a/eng/Versions.props b/eng/Versions.props index f7f27936570a..cdb1f34a2553 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -150,7 +150,7 @@ - 12.8.300-beta.24121.3 + 12.8.300-beta.24122.3 From 1afe63bff1af6ee2daead33ba732806e59e14f92 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Mon, 26 Feb 2024 12:25:34 +0000 Subject: [PATCH 255/577] [release/8.0.3xx] Update dependencies from dotnet/razor (#38951) [release/8.0.3xx] Update dependencies from dotnet/razor - Use merged Razor compiler DLL - Exempt ObjectPool dependency of the Razor compiler - Fix extension loading --- eng/Version.Details.xml | 12 ++++----- eng/Versions.props | 6 ++--- ...rosoft.NET.Sdk.Razor.Configuration.targets | 4 +-- .../Tool/DefaultExtensionDependencyChecker.cs | 1 + src/RazorSdk/Tool/DiscoverCommand.cs | 25 ++++++++++--------- src/RazorSdk/Tool/GenerateCommand.cs | 11 +++++++- .../ScopedCssIntegrationTests.cs | 4 +-- 7 files changed, 37 insertions(+), 26 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index f3d0eb343084..0eed15968b4a 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -277,18 +277,18 @@ https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore da7e9894ce22ef8cc02e5acc56e95a6f8cf8f644 - + https://github.com/dotnet/razor - 67bd8253e308d06bf249a02911d06317d5d7b5b9 + dbb0fb5c0b742887931ba5e78ebf49998096a748 - + https://github.com/dotnet/razor - 67bd8253e308d06bf249a02911d06317d5d7b5b9 + dbb0fb5c0b742887931ba5e78ebf49998096a748 - + https://github.com/dotnet/razor - 67bd8253e308d06bf249a02911d06317d5d7b5b9 + dbb0fb5c0b742887931ba5e78ebf49998096a748 https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore diff --git a/eng/Versions.props b/eng/Versions.props index cc070a8bc79e..94ccc2ee9722 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -175,9 +175,9 @@ - 7.0.0-preview.24120.8 - 7.0.0-preview.24120.8 - 7.0.0-preview.24120.8 + 7.0.0-preview.24123.5 + 7.0.0-preview.24123.5 + 7.0.0-preview.24123.5 diff --git a/src/RazorSdk/Targets/Microsoft.NET.Sdk.Razor.Configuration.targets b/src/RazorSdk/Targets/Microsoft.NET.Sdk.Razor.Configuration.targets index 8f0fa59ba967..29f55239ee41 100644 --- a/src/RazorSdk/Targets/Microsoft.NET.Sdk.Razor.Configuration.targets +++ b/src/RazorSdk/Targets/Microsoft.NET.Sdk.Razor.Configuration.targets @@ -93,8 +93,8 @@ Copyright (c) .NET Foundation. All rights reserved. - Microsoft.CodeAnalysis.Razor.Compiler.Mvc - $(RazorSdkDirectoryRoot)tools\Microsoft.CodeAnalysis.Razor.Compiler.Mvc.dll + Microsoft.CodeAnalysis.Razor.Compiler + $(RazorSdkDirectoryRoot)tools\Microsoft.CodeAnalysis.Razor.Compiler.dll diff --git a/src/RazorSdk/Tool/DefaultExtensionDependencyChecker.cs b/src/RazorSdk/Tool/DefaultExtensionDependencyChecker.cs index d47f0cb0e7ab..774c3caadc58 100644 --- a/src/RazorSdk/Tool/DefaultExtensionDependencyChecker.cs +++ b/src/RazorSdk/Tool/DefaultExtensionDependencyChecker.cs @@ -18,6 +18,7 @@ internal class DefaultExtensionDependencyChecker : ExtensionDependencyChecker "System", "Microsoft.CodeAnalysis", "Microsoft.AspNetCore.Razor", + "Microsoft.Extensions.ObjectPool" }; private readonly ExtensionAssemblyLoader _loader; diff --git a/src/RazorSdk/Tool/DiscoverCommand.cs b/src/RazorSdk/Tool/DiscoverCommand.cs index fd67bdabc4bb..41b6248bec5f 100644 --- a/src/RazorSdk/Tool/DiscoverCommand.cs +++ b/src/RazorSdk/Tool/DiscoverCommand.cs @@ -94,8 +94,13 @@ protected override bool ValidateArguments() return true; } + private const string RazorCompilerFileName = "Microsoft.CodeAnalysis.Razor.Compiler.dll"; + + internal static string GetRazorCompilerPath() + => Path.Combine(Path.GetDirectoryName(typeof(Application).Assembly.Location), RazorCompilerFileName); + /// - /// Replaces the assembly for MVC extension v1 or v2 with the one shipped alongside SDK (as opposed to the one from NuGet). + /// Replaces the assembly for MVC extension with the one shipped alongside SDK (as opposed to the one from NuGet). /// /// /// Needed so the Razor compiler can change its APIs without breaking legacy MVC scenarios. @@ -107,32 +112,28 @@ internal static void PatchExtensions(CommandOption extensionNames, CommandOption for (int i = 0; i < extensionNames.Values.Count; i++) { var extensionName = extensionNames.Values[i]; - var replacementFileName = extensionName switch + + string expectedOriginalPath = extensionName switch { - "MVC-1.0" or "MVC-1.1" => "Microsoft.CodeAnalysis.Razor.Compiler.Mvc.Version1_X.dll", - "MVC-2.0" or "MVC-2.1" => "Microsoft.CodeAnalysis.Razor.Compiler.Mvc.Version2_X.dll", + "MVC-1.0" or "MVC-1.1" or "MVC-2.0" or "MVC-2.1" => "Microsoft.AspNetCore.Mvc.Razor.Extensions", + "MVC-3.0" => "Microsoft.CodeAnalysis.Razor.Compiler", _ => null, }; - if (replacementFileName != null) + if (expectedOriginalPath is not null) { var extensionFilePath = extensionFilePaths.Values[i]; - if (!HasExpectedFileName(extensionFilePath)) + if (!string.Equals(expectedOriginalPath, Path.GetFileNameWithoutExtension(extensionFilePath), StringComparison.OrdinalIgnoreCase)) { error.WriteLine($"Extension '{extensionName}' has unexpected path '{extensionFilePath}'."); } else { currentDirectory ??= Path.GetDirectoryName(typeof(Application).Assembly.Location); - extensionFilePaths.Values[i] = Path.Combine(currentDirectory, replacementFileName); + extensionFilePaths.Values[i] = Path.Combine(currentDirectory, RazorCompilerFileName); } } } - - static bool HasExpectedFileName(string filePath) - { - return "Microsoft.AspNetCore.Mvc.Razor.Extensions".Equals(Path.GetFileNameWithoutExtension(filePath), StringComparison.OrdinalIgnoreCase); - } } protected override Task ExecuteCoreAsync() diff --git a/src/RazorSdk/Tool/GenerateCommand.cs b/src/RazorSdk/Tool/GenerateCommand.cs index 6383ec075434..d2280d7353f6 100644 --- a/src/RazorSdk/Tool/GenerateCommand.cs +++ b/src/RazorSdk/Tool/GenerateCommand.cs @@ -77,9 +77,18 @@ protected override Task ExecuteCoreAsync() // Loading all of the extensions should succeed as the dependency checker will have already // loaded them. var extensions = new RazorExtension[ExtensionNames.Values.Count]; + string razorCompilerPath = null; for (var i = 0; i < ExtensionNames.Values.Count; i++) { - extensions[i] = new AssemblyExtension(ExtensionNames.Values[i], Parent.Loader.LoadFromPath(ExtensionFilePaths.Values[i])); + // If the extension is the Razor compiler, we'll use the referenced assembly (instead of the SDK one). + // Otherwise the extension's ProvideRazorExtensionInitializerAttribute would be different from the AssemblyExtension's one, + // hence the extension would not be loaded properly. + razorCompilerPath ??= DiscoverCommand.GetRazorCompilerPath(); + var assembly = string.Equals(ExtensionFilePaths.Values[i], razorCompilerPath, StringComparison.OrdinalIgnoreCase) + ? typeof(AssemblyExtension).Assembly + : Parent.Loader.LoadFromPath(ExtensionFilePaths.Values[i]); + + extensions[i] = new AssemblyExtension(ExtensionNames.Values[i], assembly); } var version = RazorLanguageVersion.Parse(Version.Value()); diff --git a/src/Tests/Microsoft.NET.Sdk.Razor.Tests/ScopedCssIntegrationTests.cs b/src/Tests/Microsoft.NET.Sdk.Razor.Tests/ScopedCssIntegrationTests.cs index 8469b0a9f7d5..b68fd5bb46d1 100644 --- a/src/Tests/Microsoft.NET.Sdk.Razor.Tests/ScopedCssIntegrationTests.cs +++ b/src/Tests/Microsoft.NET.Sdk.Razor.Tests/ScopedCssIntegrationTests.cs @@ -90,7 +90,7 @@ public void CanOverrideScopeIdentifiers() var scoped = Path.Combine(intermediateOutputPath, "scopedcss", "Styles", "Pages", "Counter.rz.scp.css"); new FileInfo(scoped).Should().Exist(); new FileInfo(scoped).Should().Contain("b-overriden"); - var generated = Path.Combine(intermediateOutputPath, "generated", "Microsoft.CodeAnalysis.Razor.Compiler.SourceGenerators", "Microsoft.NET.Sdk.Razor.SourceGenerators.RazorSourceGenerator", "Components_Pages_Counter_razor.g.cs"); + var generated = Path.Combine(intermediateOutputPath, "generated", "Microsoft.CodeAnalysis.Razor.Compiler", "Microsoft.NET.Sdk.Razor.SourceGenerators.RazorSourceGenerator", "Components_Pages_Counter_razor.g.cs"); new FileInfo(generated).Should().Exist(); new FileInfo(generated).Should().Contain("b-overriden"); new FileInfo(Path.Combine(intermediateOutputPath, "scopedcss", "Components", "Pages", "Index.razor.rz.scp.css")).Should().NotExist(); @@ -319,7 +319,7 @@ public void Build_RemovingScopedCssAndBuilding_UpdatesGeneratedCodeAndBundle() new FileInfo(generatedBundle).Should().Exist(); var generatedProjectBundle = Path.Combine(intermediateOutputPath, "scopedcss", "projectbundle", "ComponentApp.bundle.scp.css"); new FileInfo(generatedProjectBundle).Should().Exist(); - var generatedCounter = Path.Combine(intermediateOutputPath, "generated", "Microsoft.CodeAnalysis.Razor.Compiler.SourceGenerators", "Microsoft.NET.Sdk.Razor.SourceGenerators.RazorSourceGenerator", "Components_Pages_Counter_razor.g.cs"); + var generatedCounter = Path.Combine(intermediateOutputPath, "generated", "Microsoft.CodeAnalysis.Razor.Compiler", "Microsoft.NET.Sdk.Razor.SourceGenerators.RazorSourceGenerator", "Components_Pages_Counter_razor.g.cs"); new FileInfo(generatedCounter).Should().Exist(); var componentThumbprint = FileThumbPrint.Create(generatedCounter); From 1756fb13130ec230e56c5db29a12389d29a5be19 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" Date: Mon, 26 Feb 2024 13:23:32 +0000 Subject: [PATCH 256/577] Update dependencies from https://github.com/dotnet/roslyn build 20240222.4 Microsoft.CodeAnalysis , Microsoft.CodeAnalysis.CSharp , Microsoft.CodeAnalysis.CSharp.CodeStyle , Microsoft.CodeAnalysis.CSharp.Features , Microsoft.CodeAnalysis.CSharp.Workspaces , Microsoft.CodeAnalysis.Workspaces.MSBuild , Microsoft.Net.Compilers.Toolset From Version 4.10.0-2.24124.2 -> To Version 4.10.0-2.24122.4 --- eng/Version.Details.xml | 28 ++++++++++++++-------------- eng/Versions.props | 14 +++++++------- 2 files changed, 21 insertions(+), 21 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 0eed15968b4a..67851419c2a8 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -78,34 +78,34 @@ d237e172b324021b97effa244af44d63d1a8bb7e - + https://github.com/dotnet/roslyn - 3059a073c923ae9ee56c4ad012a0f2151583dd16 + e1e80baced0414568955fb8925cfe710b9d5f009 - + https://github.com/dotnet/roslyn - 3059a073c923ae9ee56c4ad012a0f2151583dd16 + e1e80baced0414568955fb8925cfe710b9d5f009 - + https://github.com/dotnet/roslyn - 3059a073c923ae9ee56c4ad012a0f2151583dd16 + e1e80baced0414568955fb8925cfe710b9d5f009 - + https://github.com/dotnet/roslyn - 3059a073c923ae9ee56c4ad012a0f2151583dd16 + e1e80baced0414568955fb8925cfe710b9d5f009 - + https://github.com/dotnet/roslyn - 3059a073c923ae9ee56c4ad012a0f2151583dd16 + e1e80baced0414568955fb8925cfe710b9d5f009 - + https://github.com/dotnet/roslyn - 3059a073c923ae9ee56c4ad012a0f2151583dd16 + e1e80baced0414568955fb8925cfe710b9d5f009 - + https://github.com/dotnet/roslyn - 3059a073c923ae9ee56c4ad012a0f2151583dd16 + e1e80baced0414568955fb8925cfe710b9d5f009 https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore diff --git a/eng/Versions.props b/eng/Versions.props index 94ccc2ee9722..8497c86797d6 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -154,13 +154,13 @@ - 4.10.0-2.24124.2 - 4.10.0-2.24124.2 - 4.10.0-2.24124.2 - 4.10.0-2.24124.2 - 4.10.0-2.24124.2 - 4.10.0-2.24124.2 - 4.10.0-2.24124.2 + 4.10.0-2.24122.4 + 4.10.0-2.24122.4 + 4.10.0-2.24122.4 + 4.10.0-2.24122.4 + 4.10.0-2.24122.4 + 4.10.0-2.24122.4 + 4.10.0-2.24122.4 $(MicrosoftNetCompilersToolsetPackageVersion) From ae77f375c524f0845d986e24256b3ff0e085e115 Mon Sep 17 00:00:00 2001 From: Chet Husk Date: Mon, 26 Feb 2024 09:26:33 -0600 Subject: [PATCH 257/577] Backport #38882 to release/8.0.3xx (#38960) Co-authored-by: Jeff Brown <375987+jeffpardy@users.noreply.github.com> Co-authored-by: Tom Deseyn --- .../ContainerBuilder.cs | 2 +- .../Microsoft.NET.Build.Containers/ImageBuilder.cs | 5 +++++ .../Microsoft.NET.Build.Containers/Layer.cs | 13 +++++++++++-- .../Registry/DefaultManifestOperations.cs | 2 +- .../Registry/SchemaTypes.cs | 2 ++ .../Tasks/CreateNewImage.cs | 2 +- .../EndToEndTests.cs | 8 ++++---- .../LayerEndToEndTests.cs | 4 ++-- 8 files changed, 27 insertions(+), 11 deletions(-) diff --git a/src/Containers/Microsoft.NET.Build.Containers/ContainerBuilder.cs b/src/Containers/Microsoft.NET.Build.Containers/ContainerBuilder.cs index 4a0ae6848596..c9a84b8a95d4 100644 --- a/src/Containers/Microsoft.NET.Build.Containers/ContainerBuilder.cs +++ b/src/Containers/Microsoft.NET.Build.Containers/ContainerBuilder.cs @@ -95,7 +95,7 @@ public static async Task ContainerizeAsync( logger.LogInformation(Strings.ContainerBuilder_StartBuildingImage, imageName, string.Join(",", imageName), sourceImageReference); cancellationToken.ThrowIfCancellationRequested(); - Layer newLayer = Layer.FromDirectory(publishDirectory.FullName, workingDir, imageBuilder.IsWindows); + Layer newLayer = Layer.FromDirectory(publishDirectory.FullName, workingDir, imageBuilder.IsWindows, imageBuilder.ManifestMediaType); imageBuilder.AddLayer(newLayer); imageBuilder.SetWorkingDirectory(workingDir); diff --git a/src/Containers/Microsoft.NET.Build.Containers/ImageBuilder.cs b/src/Containers/Microsoft.NET.Build.Containers/ImageBuilder.cs index ce76c4060eb2..7bfdcb809962 100644 --- a/src/Containers/Microsoft.NET.Build.Containers/ImageBuilder.cs +++ b/src/Containers/Microsoft.NET.Build.Containers/ImageBuilder.cs @@ -26,6 +26,11 @@ internal sealed class ImageBuilder public ImageConfig BaseImageConfig => _baseImageConfig; + /// + /// MediaType of the output manifest. + /// + public string ManifestMediaType => _manifest.MediaType; // output the same media type as the base image manifest. + internal ImageBuilder(ManifestV2 manifest, ImageConfig baseImageConfig, ILogger logger) { _manifest = manifest; diff --git a/src/Containers/Microsoft.NET.Build.Containers/Layer.cs b/src/Containers/Microsoft.NET.Build.Containers/Layer.cs index 757cec422bbf..35af24bd1d56 100644 --- a/src/Containers/Microsoft.NET.Build.Containers/Layer.cs +++ b/src/Containers/Microsoft.NET.Build.Containers/Layer.cs @@ -6,6 +6,7 @@ using System.IO.Compression; using System.Security.Cryptography; using System.IO.Enumeration; +using Microsoft.NET.Build.Containers.Resources; namespace Microsoft.NET.Build.Containers; @@ -49,7 +50,7 @@ public static Layer FromDescriptor(Descriptor descriptor) return new(ContentStore.PathForDescriptor(descriptor), descriptor); } - public static Layer FromDirectory(string directory, string containerPath, bool isWindowsLayer) + public static Layer FromDirectory(string directory, string containerPath, bool isWindowsLayer, string manifestMediaType) { long fileSize; Span hash = stackalloc byte[SHA256.HashSizeInBytes]; @@ -186,9 +187,17 @@ static UnixFileMode DetermineFileMode(FileSystemInfo file) string contentHash = Convert.ToHexString(hash).ToLowerInvariant(); string uncompressedContentHash = Convert.ToHexString(uncompressedHash).ToLowerInvariant(); + string layerMediaType = manifestMediaType switch + { + // TODO: configurable? gzip always? + SchemaTypes.DockerManifestV2 => SchemaTypes.DockerLayerGzip, + SchemaTypes.OciManifestV1 => SchemaTypes.OciLayerGzipV1, + _ => throw new ArgumentException(Resource.FormatString(nameof(Strings.UnrecognizedMediaType), manifestMediaType)) + }; + Descriptor descriptor = new() { - MediaType = "application/vnd.docker.image.rootfs.diff.tar.gzip", // TODO: configurable? gzip always? + MediaType = layerMediaType, Size = fileSize, Digest = $"sha256:{contentHash}", UncompressedDigest = $"sha256:{uncompressedContentHash}", diff --git a/src/Containers/Microsoft.NET.Build.Containers/Registry/DefaultManifestOperations.cs b/src/Containers/Microsoft.NET.Build.Containers/Registry/DefaultManifestOperations.cs index c34426d10af3..994f97162551 100644 --- a/src/Containers/Microsoft.NET.Build.Containers/Registry/DefaultManifestOperations.cs +++ b/src/Containers/Microsoft.NET.Build.Containers/Registry/DefaultManifestOperations.cs @@ -42,7 +42,7 @@ public async Task PutAsync(string repositoryName, string reference, ManifestV2 m { string jsonString = JsonSerializer.SerializeToNode(manifest)?.ToJsonString() ?? ""; HttpContent manifestUploadContent = new StringContent(jsonString); - manifestUploadContent.Headers.ContentType = new MediaTypeHeaderValue(SchemaTypes.DockerManifestV2); + manifestUploadContent.Headers.ContentType = new MediaTypeHeaderValue(manifest.MediaType); HttpResponseMessage putResponse = await _client.PutAsync(new Uri(_baseUri, $"/v2/{repositoryName}/manifests/{reference}"), manifestUploadContent, cancellationToken).ConfigureAwait(false); diff --git a/src/Containers/Microsoft.NET.Build.Containers/Registry/SchemaTypes.cs b/src/Containers/Microsoft.NET.Build.Containers/Registry/SchemaTypes.cs index 4e001e0aaed7..d740c7621ecc 100644 --- a/src/Containers/Microsoft.NET.Build.Containers/Registry/SchemaTypes.cs +++ b/src/Containers/Microsoft.NET.Build.Containers/Registry/SchemaTypes.cs @@ -10,4 +10,6 @@ internal class SchemaTypes internal const string DockerManifestListV2 = "application/vnd.docker.distribution.manifest.list.v2+json"; internal const string DockerManifestV2 = "application/vnd.docker.distribution.manifest.v2+json"; internal const string OciManifestV1 = "application/vnd.oci.image.manifest.v1+json"; // https://containers.gitbook.io/build-containers-the-hard-way/#registry-format-oci-image-manifest + internal const string DockerLayerGzip = "application/vnd.docker.image.rootfs.diff.tar.gzip"; + internal const string OciLayerGzipV1 = "application/vnd.oci.image.layer.v1.tar+gzip"; } diff --git a/src/Containers/Microsoft.NET.Build.Containers/Tasks/CreateNewImage.cs b/src/Containers/Microsoft.NET.Build.Containers/Tasks/CreateNewImage.cs index 3ede1d5be098..3779a49f1112 100644 --- a/src/Containers/Microsoft.NET.Build.Containers/Tasks/CreateNewImage.cs +++ b/src/Containers/Microsoft.NET.Build.Containers/Tasks/CreateNewImage.cs @@ -113,7 +113,7 @@ internal async Task ExecuteAsync(CancellationToken cancellationToken) SafeLog(Strings.ContainerBuilder_StartBuildingImage, Repository, String.Join(",", ImageTags), sourceImageReference); - Layer newLayer = Layer.FromDirectory(PublishDirectory, WorkingDirectory, imageBuilder.IsWindows); + Layer newLayer = Layer.FromDirectory(PublishDirectory, WorkingDirectory, imageBuilder.IsWindows, imageBuilder.ManifestMediaType); imageBuilder.AddLayer(newLayer); imageBuilder.SetWorkingDirectory(WorkingDirectory); diff --git a/src/Tests/Microsoft.NET.Build.Containers.IntegrationTests/EndToEndTests.cs b/src/Tests/Microsoft.NET.Build.Containers.IntegrationTests/EndToEndTests.cs index c0050a9ee053..24c4f202d07d 100644 --- a/src/Tests/Microsoft.NET.Build.Containers.IntegrationTests/EndToEndTests.cs +++ b/src/Tests/Microsoft.NET.Build.Containers.IntegrationTests/EndToEndTests.cs @@ -57,7 +57,7 @@ public async Task ApiEndToEndWithRegistryPushAndPull() Assert.NotNull(imageBuilder); - Layer l = Layer.FromDirectory(publishDirectory, "/app", false); + Layer l = Layer.FromDirectory(publishDirectory, "/app", false, imageBuilder.ManifestMediaType); imageBuilder.AddLayer(l); @@ -103,7 +103,7 @@ public async Task ApiEndToEndWithLocalLoad() cancellationToken: default).ConfigureAwait(false); Assert.NotNull(imageBuilder); - Layer l = Layer.FromDirectory(publishDirectory, "/app", false); + Layer l = Layer.FromDirectory(publishDirectory, "/app", false, imageBuilder.ManifestMediaType); imageBuilder.AddLayer(l); @@ -144,7 +144,7 @@ public async Task ApiEndToEndWithArchiveWritingAndLoad() cancellationToken: default).ConfigureAwait(false); Assert.NotNull(imageBuilder); - Layer l = Layer.FromDirectory(publishDirectory, "/app", false); + Layer l = Layer.FromDirectory(publishDirectory, "/app", false, imageBuilder.ManifestMediaType); imageBuilder.AddLayer(l); @@ -564,7 +564,7 @@ public async Task CanPackageForAllSupportedContainerRIDs(string dockerPlatform, cancellationToken: default).ConfigureAwait(false); Assert.NotNull(imageBuilder); - Layer l = Layer.FromDirectory(publishDirectory, isWin ? "C:\\app" : "/app", isWin); + Layer l = Layer.FromDirectory(publishDirectory, isWin ? "C:\\app" : "/app", isWin, imageBuilder.ManifestMediaType); imageBuilder.AddLayer(l); imageBuilder.SetWorkingDirectory(workingDir); diff --git a/src/Tests/Microsoft.NET.Build.Containers.IntegrationTests/LayerEndToEndTests.cs b/src/Tests/Microsoft.NET.Build.Containers.IntegrationTests/LayerEndToEndTests.cs index 0ac2938c1d18..68d0a20e2c12 100644 --- a/src/Tests/Microsoft.NET.Build.Containers.IntegrationTests/LayerEndToEndTests.cs +++ b/src/Tests/Microsoft.NET.Build.Containers.IntegrationTests/LayerEndToEndTests.cs @@ -29,7 +29,7 @@ public void SingleFileInFolder() File.WriteAllText(testFilePath, testString); - Layer l = Layer.FromDirectory(directory: folder.Path, containerPath: "/app", false); + Layer l = Layer.FromDirectory(directory: folder.Path, containerPath: "/app", false, SchemaTypes.DockerManifestV2); Console.WriteLine(l.Descriptor); @@ -54,7 +54,7 @@ public void SingleFileInFolderWindows() File.WriteAllText(testFilePath, testString); - Layer l = Layer.FromDirectory(directory: folder.Path, containerPath: "C:\\app", true); + Layer l = Layer.FromDirectory(directory: folder.Path, containerPath: "C:\\app", true, SchemaTypes.DockerManifestV2); var allEntries = LoadAllTarEntries(l.BackingFile); Assert.True(allEntries.TryGetValue("Files", out var filesEntry) && filesEntry.EntryType == TarEntryType.Directory, "Missing Files directory entry"); From 73eeefb4fa0f07c5fc9feaaf24dfd417d0f242d0 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" Date: Tue, 27 Feb 2024 13:51:10 +0000 Subject: [PATCH 258/577] Update dependencies from https://github.com/nuget/nuget.client build 6.10.0.47 Microsoft.Build.NuGetSdkResolver , NuGet.Build.Tasks , NuGet.Build.Tasks.Console , NuGet.Build.Tasks.Pack , NuGet.CommandLine.XPlat , NuGet.Commands , NuGet.Common , NuGet.Configuration , NuGet.Credentials , NuGet.DependencyResolver.Core , NuGet.Frameworks , NuGet.LibraryModel , NuGet.Packaging , NuGet.ProjectModel , NuGet.Protocol , NuGet.Versioning From Version 6.10.0-preview.2.44 -> To Version 6.10.0-preview.2.47 --- eng/Version.Details.xml | 64 ++++++++++++++++++++--------------------- eng/Versions.props | 22 +++++++------- 2 files changed, 43 insertions(+), 43 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 0eed15968b4a..1cdfebe1c6c7 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -115,69 +115,69 @@ https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore da7e9894ce22ef8cc02e5acc56e95a6f8cf8f644 - + https://github.com/nuget/nuget.client - 39c4f37d4baa00ee0b815fb394de7d51a58b17ab + b49d8914861cf18287302ab311fc9d2566e06fe1 - + https://github.com/nuget/nuget.client - 39c4f37d4baa00ee0b815fb394de7d51a58b17ab + b49d8914861cf18287302ab311fc9d2566e06fe1 - + https://github.com/nuget/nuget.client - 39c4f37d4baa00ee0b815fb394de7d51a58b17ab + b49d8914861cf18287302ab311fc9d2566e06fe1 - + https://github.com/nuget/nuget.client - 39c4f37d4baa00ee0b815fb394de7d51a58b17ab + b49d8914861cf18287302ab311fc9d2566e06fe1 - + https://github.com/nuget/nuget.client - 39c4f37d4baa00ee0b815fb394de7d51a58b17ab + b49d8914861cf18287302ab311fc9d2566e06fe1 - + https://github.com/nuget/nuget.client - 39c4f37d4baa00ee0b815fb394de7d51a58b17ab + b49d8914861cf18287302ab311fc9d2566e06fe1 - + https://github.com/nuget/nuget.client - 39c4f37d4baa00ee0b815fb394de7d51a58b17ab + b49d8914861cf18287302ab311fc9d2566e06fe1 - + https://github.com/nuget/nuget.client - 39c4f37d4baa00ee0b815fb394de7d51a58b17ab + b49d8914861cf18287302ab311fc9d2566e06fe1 - + https://github.com/nuget/nuget.client - 39c4f37d4baa00ee0b815fb394de7d51a58b17ab + b49d8914861cf18287302ab311fc9d2566e06fe1 - + https://github.com/nuget/nuget.client - 39c4f37d4baa00ee0b815fb394de7d51a58b17ab + b49d8914861cf18287302ab311fc9d2566e06fe1 - + https://github.com/nuget/nuget.client - 39c4f37d4baa00ee0b815fb394de7d51a58b17ab + b49d8914861cf18287302ab311fc9d2566e06fe1 - + https://github.com/nuget/nuget.client - 39c4f37d4baa00ee0b815fb394de7d51a58b17ab + b49d8914861cf18287302ab311fc9d2566e06fe1 - + https://github.com/nuget/nuget.client - 39c4f37d4baa00ee0b815fb394de7d51a58b17ab + b49d8914861cf18287302ab311fc9d2566e06fe1 - + https://github.com/nuget/nuget.client - 39c4f37d4baa00ee0b815fb394de7d51a58b17ab + b49d8914861cf18287302ab311fc9d2566e06fe1 - + https://github.com/nuget/nuget.client - 39c4f37d4baa00ee0b815fb394de7d51a58b17ab + b49d8914861cf18287302ab311fc9d2566e06fe1 - + https://github.com/nuget/nuget.client - 39c4f37d4baa00ee0b815fb394de7d51a58b17ab + b49d8914861cf18287302ab311fc9d2566e06fe1 https://github.com/microsoft/vstest diff --git a/eng/Versions.props b/eng/Versions.props index 94ccc2ee9722..b3f721711556 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -82,18 +82,18 @@ - 6.10.0-preview.2.44 - 6.10.0-preview.2.44 + 6.10.0-preview.2.47 + 6.10.0-preview.2.47 6.0.0-rc.278 - 6.10.0-preview.2.44 - 6.10.0-preview.2.44 - 6.10.0-preview.2.44 - 6.10.0-preview.2.44 - 6.10.0-preview.2.44 - 6.10.0-preview.2.44 - 6.10.0-preview.2.44 - 6.10.0-preview.2.44 - 6.10.0-preview.2.44 + 6.10.0-preview.2.47 + 6.10.0-preview.2.47 + 6.10.0-preview.2.47 + 6.10.0-preview.2.47 + 6.10.0-preview.2.47 + 6.10.0-preview.2.47 + 6.10.0-preview.2.47 + 6.10.0-preview.2.47 + 6.10.0-preview.2.47 $(NuGetPackagingPackageVersion) $(NuGetProjectModelPackageVersion) From 50c02963a592f5bb914860e3eae45381b6409f7d Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" Date: Tue, 27 Feb 2024 13:53:25 +0000 Subject: [PATCH 259/577] Update dependencies from https://github.com/dotnet/msbuild build 20240227.3 Microsoft.SourceBuild.Intermediate.msbuild , Microsoft.Build , Microsoft.Build.Localization From Version 17.10.0-preview-24123-01 -> To Version 17.10.0-preview-24127-03 --- eng/Version.Details.xml | 12 ++++++------ eng/Versions.props | 4 ++-- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 0eed15968b4a..8d59ccfcde7f 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -51,17 +51,17 @@ https://github.com/dotnet/emsdk 2fc2ffd960930318f33fcaa690cbdbc55d72f52d - + https://github.com/dotnet/msbuild - 56c003594af2772b8a5f4c58023f239a431154fa + 6f44380e4fdea6ddf5c11f48efeb25c2bf181e62 - + https://github.com/dotnet/msbuild - 56c003594af2772b8a5f4c58023f239a431154fa + 6f44380e4fdea6ddf5c11f48efeb25c2bf181e62 - + https://github.com/dotnet/msbuild - 56c003594af2772b8a5f4c58023f239a431154fa + 6f44380e4fdea6ddf5c11f48efeb25c2bf181e62 diff --git a/eng/Versions.props b/eng/Versions.props index 94ccc2ee9722..39dbf33bf469 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -120,7 +120,7 @@ - 17.10.0-preview-24123-01 + 17.10.0-preview-24127-03 $(MicrosoftBuildPackageVersion) - 12.8.300-beta.24122.3 + 12.8.300-beta.24126.2 From c705a7b22801812e08a398fb3ff9fa8b555c35a1 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" Date: Tue, 27 Feb 2024 13:54:11 +0000 Subject: [PATCH 261/577] Update dependencies from https://github.com/dotnet/razor build 20240227.2 Microsoft.AspNetCore.Mvc.Razor.Extensions.Tooling.Internal , Microsoft.CodeAnalysis.Razor.Tooling.Internal , Microsoft.NET.Sdk.Razor.SourceGenerators.Transport From Version 7.0.0-preview.24123.5 -> To Version 7.0.0-preview.24127.2 --- eng/Version.Details.xml | 12 ++++++------ eng/Versions.props | 6 +++--- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 0eed15968b4a..7bbb7d71806c 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -277,18 +277,18 @@ https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore da7e9894ce22ef8cc02e5acc56e95a6f8cf8f644 - + https://github.com/dotnet/razor - dbb0fb5c0b742887931ba5e78ebf49998096a748 + b3ad9608a3f57dccb13c415a0f752e32a57db2b6 - + https://github.com/dotnet/razor - dbb0fb5c0b742887931ba5e78ebf49998096a748 + b3ad9608a3f57dccb13c415a0f752e32a57db2b6 - + https://github.com/dotnet/razor - dbb0fb5c0b742887931ba5e78ebf49998096a748 + b3ad9608a3f57dccb13c415a0f752e32a57db2b6 https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore diff --git a/eng/Versions.props b/eng/Versions.props index 94ccc2ee9722..5bf3fcb93590 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -175,9 +175,9 @@ - 7.0.0-preview.24123.5 - 7.0.0-preview.24123.5 - 7.0.0-preview.24123.5 + 7.0.0-preview.24127.2 + 7.0.0-preview.24127.2 + 7.0.0-preview.24127.2 From b15f9e5dfb1301d6359708cf955d100e7da42815 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" Date: Tue, 27 Feb 2024 13:55:40 +0000 Subject: [PATCH 262/577] Update dependencies from https://github.com/dotnet/roslyn build 20240227.1 Microsoft.CodeAnalysis , Microsoft.CodeAnalysis.CSharp , Microsoft.CodeAnalysis.CSharp.CodeStyle , Microsoft.CodeAnalysis.CSharp.Features , Microsoft.CodeAnalysis.CSharp.Workspaces , Microsoft.CodeAnalysis.Workspaces.MSBuild , Microsoft.Net.Compilers.Toolset From Version 4.10.0-2.24124.2 -> To Version 4.10.0-2.24127.1 --- eng/Version.Details.xml | 28 ++++++++++++++-------------- eng/Versions.props | 14 +++++++------- 2 files changed, 21 insertions(+), 21 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 67851419c2a8..6e08a12f4d11 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -78,34 +78,34 @@ d237e172b324021b97effa244af44d63d1a8bb7e - + https://github.com/dotnet/roslyn - e1e80baced0414568955fb8925cfe710b9d5f009 + b701a39ca8ccec581a7949d3bcc9931a2088deee - + https://github.com/dotnet/roslyn - e1e80baced0414568955fb8925cfe710b9d5f009 + b701a39ca8ccec581a7949d3bcc9931a2088deee - + https://github.com/dotnet/roslyn - e1e80baced0414568955fb8925cfe710b9d5f009 + b701a39ca8ccec581a7949d3bcc9931a2088deee - + https://github.com/dotnet/roslyn - e1e80baced0414568955fb8925cfe710b9d5f009 + b701a39ca8ccec581a7949d3bcc9931a2088deee - + https://github.com/dotnet/roslyn - e1e80baced0414568955fb8925cfe710b9d5f009 + b701a39ca8ccec581a7949d3bcc9931a2088deee - + https://github.com/dotnet/roslyn - e1e80baced0414568955fb8925cfe710b9d5f009 + b701a39ca8ccec581a7949d3bcc9931a2088deee - + https://github.com/dotnet/roslyn - e1e80baced0414568955fb8925cfe710b9d5f009 + b701a39ca8ccec581a7949d3bcc9931a2088deee https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore diff --git a/eng/Versions.props b/eng/Versions.props index 8497c86797d6..c77631ffca77 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -154,13 +154,13 @@ - 4.10.0-2.24122.4 - 4.10.0-2.24122.4 - 4.10.0-2.24122.4 - 4.10.0-2.24122.4 - 4.10.0-2.24122.4 - 4.10.0-2.24122.4 - 4.10.0-2.24122.4 + 4.10.0-2.24127.1 + 4.10.0-2.24127.1 + 4.10.0-2.24127.1 + 4.10.0-2.24127.1 + 4.10.0-2.24127.1 + 4.10.0-2.24127.1 + 4.10.0-2.24127.1 $(MicrosoftNetCompilersToolsetPackageVersion) From 7f6c196d3c16f12d9a442683212559c365ff71b7 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" Date: Tue, 27 Feb 2024 13:57:45 +0000 Subject: [PATCH 263/577] Update dependencies from https://github.com/dotnet/arcade build 20240223.1 Microsoft.DotNet.Arcade.Sdk , Microsoft.DotNet.Helix.Sdk , Microsoft.DotNet.SignTool , Microsoft.DotNet.XUnitExtensions From Version 8.0.0-beta.24113.2 -> To Version 8.0.0-beta.24123.1 --- eng/Version.Details.xml | 16 ++++++++-------- eng/Versions.props | 4 ++-- eng/common/templates/steps/generate-sbom.yml | 2 +- global.json | 4 ++-- 4 files changed, 13 insertions(+), 13 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 0eed15968b4a..67b9e6dfcdbc 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -475,22 +475,22 @@ - + https://github.com/dotnet/arcade - da98edc4c3ea539f109ea320672136ceb32591a7 + 042763a811fd94dc3556253d4c64118dd665216e - + https://github.com/dotnet/arcade - da98edc4c3ea539f109ea320672136ceb32591a7 + 042763a811fd94dc3556253d4c64118dd665216e - + https://github.com/dotnet/arcade - da98edc4c3ea539f109ea320672136ceb32591a7 + 042763a811fd94dc3556253d4c64118dd665216e - + https://github.com/dotnet/arcade - da98edc4c3ea539f109ea320672136ceb32591a7 + 042763a811fd94dc3556253d4c64118dd665216e https://dev.azure.com/dnceng/internal/_git/dotnet-runtime diff --git a/eng/Versions.props b/eng/Versions.props index 94ccc2ee9722..b3fa776a267f 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -34,7 +34,7 @@ 7.0.0 4.0.0 7.0.0 - 8.0.0-beta.24113.2 + 8.0.0-beta.24123.1 7.0.0-preview.22423.2 8.0.0 4.3.0 @@ -209,7 +209,7 @@ 6.12.0 6.1.0 - 8.0.0-beta.24113.2 + 8.0.0-beta.24123.1 4.18.4 1.3.2 8.0.0-beta.23607.1 diff --git a/eng/common/templates/steps/generate-sbom.yml b/eng/common/templates/steps/generate-sbom.yml index a06373f38fa5..2b21eae42732 100644 --- a/eng/common/templates/steps/generate-sbom.yml +++ b/eng/common/templates/steps/generate-sbom.yml @@ -5,7 +5,7 @@ # IgnoreDirectories - Directories to ignore for SBOM generation. This will be passed through to the CG component detector. parameters: - PackageVersion: 7.0.0 + PackageVersion: 8.0.0 BuildDropPath: '$(Build.SourcesDirectory)/artifacts' PackageName: '.NET' ManifestDirPath: $(Build.ArtifactStagingDirectory)/sbom diff --git a/global.json b/global.json index e4a4db23631d..882ac53f0b68 100644 --- a/global.json +++ b/global.json @@ -14,7 +14,7 @@ } }, "msbuild-sdks": { - "Microsoft.DotNet.Arcade.Sdk": "8.0.0-beta.24113.2", - "Microsoft.DotNet.Helix.Sdk": "8.0.0-beta.24113.2" + "Microsoft.DotNet.Arcade.Sdk": "8.0.0-beta.24123.1", + "Microsoft.DotNet.Helix.Sdk": "8.0.0-beta.24123.1" } } From 813d5beca4421d9e255a391533cc08cfcde93d11 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" Date: Tue, 27 Feb 2024 13:58:12 +0000 Subject: [PATCH 264/577] Update dependencies from https://github.com/dotnet/format build 20240227.3 dotnet-format From Version 8.0.511601 -> To Version 8.0.512703 --- NuGet.config | 4 +--- eng/Version.Details.xml | 4 ++-- eng/Versions.props | 2 +- 3 files changed, 4 insertions(+), 6 deletions(-) diff --git a/NuGet.config b/NuGet.config index 0414c6c4926a..324130e31c31 100644 --- a/NuGet.config +++ b/NuGet.config @@ -6,9 +6,7 @@ - - - + diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 0eed15968b4a..5243ceaca045 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -73,9 +73,9 @@ 02bb351b606468bce98688fccda9d0c8adcd964d - + https://github.com/dotnet/format - d237e172b324021b97effa244af44d63d1a8bb7e + ac0d85557969d51bca72181514ddb7d5796fbbe2 diff --git a/eng/Versions.props b/eng/Versions.props index 94ccc2ee9722..4b3e5b15e015 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -111,7 +111,7 @@ - 8.0.511601 + 8.0.512703 From c4f15959182fed1b8c69fd24a31daf0203e1f1be Mon Sep 17 00:00:00 2001 From: Chet Husk Date: Tue, 27 Feb 2024 21:54:37 -0600 Subject: [PATCH 265/577] Cherry-pick #38956 to release/8.0.3xx (#39070) --- src/Cli/dotnet/commands/RestoringCommand.cs | 102 +++++++++++++++--- .../GivenDotnetBuildInvocation.cs | 1 + 2 files changed, 91 insertions(+), 12 deletions(-) diff --git a/src/Cli/dotnet/commands/RestoringCommand.cs b/src/Cli/dotnet/commands/RestoringCommand.cs index 32b1d0cb65e7..92d35eab6ece 100644 --- a/src/Cli/dotnet/commands/RestoringCommand.cs +++ b/src/Cli/dotnet/commands/RestoringCommand.cs @@ -37,7 +37,7 @@ private static IEnumerable GetCommandArguments( IEnumerable arguments, bool noRestore) { - if (noRestore) + if (noRestore) { return arguments; } @@ -60,11 +60,11 @@ private static RestoreCommand GetSeparateRestoreCommand( return null; } - IEnumerable restoreArguments = new string[] { "-target:Restore" }; + IEnumerable restoreArguments = ["-target:Restore"]; if (arguments != null) { - restoreArguments = restoreArguments.Concat(arguments.Where( - a => !IsExcludedFromRestore(a) && !IsExcludedFromSeparateRestore(a))); + (var newArgumentsToAdd, var existingArgumentsToForward) = ProcessForwardedArgumentsForSeparateRestore(arguments); + restoreArguments = [.. restoreArguments, .. newArgumentsToAdd, .. existingArgumentsToForward]; } return new RestoreCommand(restoreArguments, msbuildPath); @@ -76,19 +76,97 @@ private static IEnumerable Prepend(string argument, IEnumerable private static bool HasArgumentToExcludeFromRestore(IEnumerable arguments) => arguments.Any(a => IsExcludedFromRestore(a)); - private static readonly string[] propertyPrefixes = new string[]{ "-", "/", "--" }; + private static readonly string[] switchPrefixes = ["-", "/", "--"]; - private static bool IsExcludedFromRestore(string argument) - => propertyPrefixes.Any(prefix => argument.StartsWith($"{prefix}property:TargetFramework=", StringComparison.Ordinal)) || - propertyPrefixes.Any(prefix => argument.StartsWith($"{prefix}p:TargetFramework=", StringComparison.Ordinal)); + // these properties trigger a separate restore + private static readonly string[] PropertiesToExcludeFromRestore = + [ + "TargetFramework" + ]; + + private static readonly string[] FlagsThatTriggerSilentRestore = + [ + "getProperty", + "getItem", + "getTargetResult" + ]; // These arguments don't by themselves require that restore be run in a separate process, // but if there is a separate restore process they shouldn't be passed to it + private static readonly string[] FlagsToExcludeFromRestore = + [ + ..FlagsThatTriggerSilentRestore, + "t", + "target", + "consoleloggerparameters", + "clp" + ]; + + private static List FlagsToExcludeFromSeparateRestore = + ComputeFlags(FlagsToExcludeFromRestore).ToList(); + + private static List FlagsThatTriggerSilentSeparateRestore = + ComputeFlags(FlagsThatTriggerSilentRestore).ToList(); + + private static List PropertiesToExcludeFromSeparateRestore = + ComputePropertySwitches(PropertiesToExcludeFromRestore).ToList(); + + // We investigate the arguments we're about to send to a separate restore call and filter out + // arguments that negatively influence the restore. In addition, some flags signal different modes of execution + // that we need to compensate for, so we might yield new arguments that should be included in the overall restore call. + private static (string[] newArgumentsToAdd, string[] existingArgumentsToForward) ProcessForwardedArgumentsForSeparateRestore(IEnumerable forwardedArguments) + { + HashSet newArgumentsToAdd = new(); + List existingArgumentsToForward = new(); + + foreach (var argument in forwardedArguments) + { + + if (!IsExcludedFromSeparateRestore(argument) && !IsExcludedFromRestore(argument)) + { + existingArgumentsToForward.Add(argument); + } + + if (TriggersSilentSeparateRestore(argument)) + { + newArgumentsToAdd.Add("-nologo"); + newArgumentsToAdd.Add("-verbosity:quiet"); + } + } + return (newArgumentsToAdd.ToArray(), existingArgumentsToForward.ToArray()); + } + private static IEnumerable ComputePropertySwitches(string[] properties) + { + foreach (var prefix in switchPrefixes) + { + foreach (var property in properties) + { + yield return $"{prefix}property:{property}="; + yield return $"{prefix}p:{property}="; + } + } + } + + private static IEnumerable ComputeFlags(string[] flags) + { + foreach (var prefix in switchPrefixes) + { + foreach (var flag in flags) + { + yield return $"{prefix}{flag}:"; + } + } + } + + private static bool IsExcludedFromRestore(string argument) + => PropertiesToExcludeFromSeparateRestore.Any(flag => argument.StartsWith(flag, StringComparison.OrdinalIgnoreCase)); + + private static bool IsExcludedFromSeparateRestore(string argument) - => propertyPrefixes.Any(prefix => argument.StartsWith($"{prefix}t:", StringComparison.Ordinal)) || - propertyPrefixes.Any(prefix => argument.StartsWith($"{prefix}target:", StringComparison.Ordinal)) || - propertyPrefixes.Any(prefix => argument.StartsWith($"{prefix}consoleloggerparameters:", StringComparison.Ordinal)) || - propertyPrefixes.Any(prefix => argument.StartsWith($"{prefix}clp:", StringComparison.Ordinal)); + => FlagsToExcludeFromSeparateRestore.Any(p => argument.StartsWith(p, StringComparison.OrdinalIgnoreCase)); + + private static bool TriggersSilentSeparateRestore(string argument) + => FlagsThatTriggerSilentSeparateRestore.Any(p => argument.StartsWith(p, StringComparison.OrdinalIgnoreCase)); public override int Execute() { diff --git a/src/Tests/dotnet.Tests/dotnet-msbuild/GivenDotnetBuildInvocation.cs b/src/Tests/dotnet.Tests/dotnet-msbuild/GivenDotnetBuildInvocation.cs index 0b2f0abebca4..cb1500a4738d 100644 --- a/src/Tests/dotnet.Tests/dotnet-msbuild/GivenDotnetBuildInvocation.cs +++ b/src/Tests/dotnet.Tests/dotnet-msbuild/GivenDotnetBuildInvocation.cs @@ -64,6 +64,7 @@ public void MsbuildInvocationIsCorrect(string[] args, string expectedAdditionalA [InlineData(new string[] { "-o", "myoutput", "-f", "tfm", "-v", "diag", "/ArbitrarySwitchForMSBuild" }, "-target:Restore -verbosity:diag -property:OutputPath=myoutput -property:_CommandLineDefinedOutputPath=true /ArbitrarySwitchForMSBuild", "-property:TargetFramework=tfm -verbosity:diag -property:OutputPath=myoutput -property:_CommandLineDefinedOutputPath=true /ArbitrarySwitchForMSBuild")] + [InlineData(new string[] { "-f", "tfm", "-getItem:Compile", "-getProperty:TargetFramework", "-getTargetResult:Build" }, "-target:Restore -nologo -verbosity:quiet", "-property:TargetFramework=tfm -getItem:Compile -getProperty:TargetFramework -getTargetResult:Build")] public void MsbuildInvocationIsCorrectForSeparateRestore( string[] args, string expectedAdditionalArgsForRestore, From b04d9c17772f7d0b27621a7bc389d3c5d1ecb8db Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" Date: Wed, 28 Feb 2024 13:51:15 +0000 Subject: [PATCH 266/577] Update dependencies from https://github.com/nuget/nuget.client build 6.10.0.49 Microsoft.Build.NuGetSdkResolver , NuGet.Build.Tasks , NuGet.Build.Tasks.Console , NuGet.Build.Tasks.Pack , NuGet.CommandLine.XPlat , NuGet.Commands , NuGet.Common , NuGet.Configuration , NuGet.Credentials , NuGet.DependencyResolver.Core , NuGet.Frameworks , NuGet.LibraryModel , NuGet.Packaging , NuGet.ProjectModel , NuGet.Protocol , NuGet.Versioning From Version 6.10.0-preview.2.47 -> To Version 6.10.0-preview.2.49 --- eng/Version.Details.xml | 64 ++++++++++++++++++++--------------------- eng/Versions.props | 22 +++++++------- 2 files changed, 43 insertions(+), 43 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 07b37d841d9e..0a9f8b5220da 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -115,69 +115,69 @@ https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore da7e9894ce22ef8cc02e5acc56e95a6f8cf8f644 - + https://github.com/nuget/nuget.client - b49d8914861cf18287302ab311fc9d2566e06fe1 + 5ecd0be8cb73db807189427eb8e0f7bfd334c1e0 - + https://github.com/nuget/nuget.client - b49d8914861cf18287302ab311fc9d2566e06fe1 + 5ecd0be8cb73db807189427eb8e0f7bfd334c1e0 - + https://github.com/nuget/nuget.client - b49d8914861cf18287302ab311fc9d2566e06fe1 + 5ecd0be8cb73db807189427eb8e0f7bfd334c1e0 - + https://github.com/nuget/nuget.client - b49d8914861cf18287302ab311fc9d2566e06fe1 + 5ecd0be8cb73db807189427eb8e0f7bfd334c1e0 - + https://github.com/nuget/nuget.client - b49d8914861cf18287302ab311fc9d2566e06fe1 + 5ecd0be8cb73db807189427eb8e0f7bfd334c1e0 - + https://github.com/nuget/nuget.client - b49d8914861cf18287302ab311fc9d2566e06fe1 + 5ecd0be8cb73db807189427eb8e0f7bfd334c1e0 - + https://github.com/nuget/nuget.client - b49d8914861cf18287302ab311fc9d2566e06fe1 + 5ecd0be8cb73db807189427eb8e0f7bfd334c1e0 - + https://github.com/nuget/nuget.client - b49d8914861cf18287302ab311fc9d2566e06fe1 + 5ecd0be8cb73db807189427eb8e0f7bfd334c1e0 - + https://github.com/nuget/nuget.client - b49d8914861cf18287302ab311fc9d2566e06fe1 + 5ecd0be8cb73db807189427eb8e0f7bfd334c1e0 - + https://github.com/nuget/nuget.client - b49d8914861cf18287302ab311fc9d2566e06fe1 + 5ecd0be8cb73db807189427eb8e0f7bfd334c1e0 - + https://github.com/nuget/nuget.client - b49d8914861cf18287302ab311fc9d2566e06fe1 + 5ecd0be8cb73db807189427eb8e0f7bfd334c1e0 - + https://github.com/nuget/nuget.client - b49d8914861cf18287302ab311fc9d2566e06fe1 + 5ecd0be8cb73db807189427eb8e0f7bfd334c1e0 - + https://github.com/nuget/nuget.client - b49d8914861cf18287302ab311fc9d2566e06fe1 + 5ecd0be8cb73db807189427eb8e0f7bfd334c1e0 - + https://github.com/nuget/nuget.client - b49d8914861cf18287302ab311fc9d2566e06fe1 + 5ecd0be8cb73db807189427eb8e0f7bfd334c1e0 - + https://github.com/nuget/nuget.client - b49d8914861cf18287302ab311fc9d2566e06fe1 + 5ecd0be8cb73db807189427eb8e0f7bfd334c1e0 - + https://github.com/nuget/nuget.client - b49d8914861cf18287302ab311fc9d2566e06fe1 + 5ecd0be8cb73db807189427eb8e0f7bfd334c1e0 https://github.com/microsoft/vstest diff --git a/eng/Versions.props b/eng/Versions.props index 3a8976509a87..cc8f69a7ff12 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -82,18 +82,18 @@ - 6.10.0-preview.2.47 - 6.10.0-preview.2.47 + 6.10.0-preview.2.49 + 6.10.0-preview.2.49 6.0.0-rc.278 - 6.10.0-preview.2.47 - 6.10.0-preview.2.47 - 6.10.0-preview.2.47 - 6.10.0-preview.2.47 - 6.10.0-preview.2.47 - 6.10.0-preview.2.47 - 6.10.0-preview.2.47 - 6.10.0-preview.2.47 - 6.10.0-preview.2.47 + 6.10.0-preview.2.49 + 6.10.0-preview.2.49 + 6.10.0-preview.2.49 + 6.10.0-preview.2.49 + 6.10.0-preview.2.49 + 6.10.0-preview.2.49 + 6.10.0-preview.2.49 + 6.10.0-preview.2.49 + 6.10.0-preview.2.49 $(NuGetPackagingPackageVersion) $(NuGetProjectModelPackageVersion) From f1001e45eb78287c35c714885835a7118f548363 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" Date: Wed, 28 Feb 2024 13:51:58 +0000 Subject: [PATCH 267/577] Update dependencies from https://github.com/dotnet/msbuild build 20240228.3 Microsoft.SourceBuild.Intermediate.msbuild , Microsoft.Build , Microsoft.Build.Localization From Version 17.10.0-preview-24127-03 -> To Version 17.10.0-preview-24128-03 --- eng/Version.Details.xml | 12 ++++++------ eng/Versions.props | 4 ++-- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 07b37d841d9e..903126098432 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -51,17 +51,17 @@ https://github.com/dotnet/emsdk 2fc2ffd960930318f33fcaa690cbdbc55d72f52d - + https://github.com/dotnet/msbuild - 6f44380e4fdea6ddf5c11f48efeb25c2bf181e62 + 986f8ec32c74b7425e9ecf313e3a1afdf2d4f672 - + https://github.com/dotnet/msbuild - 6f44380e4fdea6ddf5c11f48efeb25c2bf181e62 + 986f8ec32c74b7425e9ecf313e3a1afdf2d4f672 - + https://github.com/dotnet/msbuild - 6f44380e4fdea6ddf5c11f48efeb25c2bf181e62 + 986f8ec32c74b7425e9ecf313e3a1afdf2d4f672 diff --git a/eng/Versions.props b/eng/Versions.props index 3a8976509a87..24ac3b0f8f78 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -120,7 +120,7 @@ - 17.10.0-preview-24127-03 + 17.10.0-preview-24128-03 $(MicrosoftBuildPackageVersion) - 12.8.300-beta.24126.2 + 12.8.300-beta.24127.3 From b52803382b27bfafdeece062136f0a3d483d9c59 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" Date: Wed, 28 Feb 2024 13:53:15 +0000 Subject: [PATCH 269/577] Update dependencies from https://github.com/dotnet/razor build 20240228.1 Microsoft.AspNetCore.Mvc.Razor.Extensions.Tooling.Internal , Microsoft.CodeAnalysis.Razor.Tooling.Internal , Microsoft.NET.Sdk.Razor.SourceGenerators.Transport From Version 7.0.0-preview.24127.2 -> To Version 7.0.0-preview.24128.1 --- eng/Version.Details.xml | 12 ++++++------ eng/Versions.props | 6 +++--- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 07b37d841d9e..1e64f1d89bcc 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -277,18 +277,18 @@ https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore da7e9894ce22ef8cc02e5acc56e95a6f8cf8f644 - + https://github.com/dotnet/razor - b3ad9608a3f57dccb13c415a0f752e32a57db2b6 + 3fc5548e17906494a8b93dda256cd16c31d70021 - + https://github.com/dotnet/razor - b3ad9608a3f57dccb13c415a0f752e32a57db2b6 + 3fc5548e17906494a8b93dda256cd16c31d70021 - + https://github.com/dotnet/razor - b3ad9608a3f57dccb13c415a0f752e32a57db2b6 + 3fc5548e17906494a8b93dda256cd16c31d70021 https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore diff --git a/eng/Versions.props b/eng/Versions.props index 3a8976509a87..d04e4fd649c9 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -175,9 +175,9 @@ - 7.0.0-preview.24127.2 - 7.0.0-preview.24127.2 - 7.0.0-preview.24127.2 + 7.0.0-preview.24128.1 + 7.0.0-preview.24128.1 + 7.0.0-preview.24128.1 From f1187991849f216862c04fbf2b256979b3099035 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" Date: Wed, 28 Feb 2024 13:53:38 +0000 Subject: [PATCH 270/577] Update dependencies from https://github.com/dotnet/roslyn build 20240227.10 Microsoft.CodeAnalysis , Microsoft.CodeAnalysis.CSharp , Microsoft.CodeAnalysis.CSharp.CodeStyle , Microsoft.CodeAnalysis.CSharp.Features , Microsoft.CodeAnalysis.CSharp.Workspaces , Microsoft.CodeAnalysis.Workspaces.MSBuild , Microsoft.Net.Compilers.Toolset From Version 4.10.0-2.24127.1 -> To Version 4.10.0-3.24127.10 --- eng/Version.Details.xml | 28 ++++++++++++++-------------- eng/Versions.props | 14 +++++++------- 2 files changed, 21 insertions(+), 21 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 07b37d841d9e..42bf76c07578 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -78,34 +78,34 @@ ac0d85557969d51bca72181514ddb7d5796fbbe2 - + https://github.com/dotnet/roslyn - b701a39ca8ccec581a7949d3bcc9931a2088deee + 5e6349e1c07c535ec698b00075d8b4f5babfd2b6 - + https://github.com/dotnet/roslyn - b701a39ca8ccec581a7949d3bcc9931a2088deee + 5e6349e1c07c535ec698b00075d8b4f5babfd2b6 - + https://github.com/dotnet/roslyn - b701a39ca8ccec581a7949d3bcc9931a2088deee + 5e6349e1c07c535ec698b00075d8b4f5babfd2b6 - + https://github.com/dotnet/roslyn - b701a39ca8ccec581a7949d3bcc9931a2088deee + 5e6349e1c07c535ec698b00075d8b4f5babfd2b6 - + https://github.com/dotnet/roslyn - b701a39ca8ccec581a7949d3bcc9931a2088deee + 5e6349e1c07c535ec698b00075d8b4f5babfd2b6 - + https://github.com/dotnet/roslyn - b701a39ca8ccec581a7949d3bcc9931a2088deee + 5e6349e1c07c535ec698b00075d8b4f5babfd2b6 - + https://github.com/dotnet/roslyn - b701a39ca8ccec581a7949d3bcc9931a2088deee + 5e6349e1c07c535ec698b00075d8b4f5babfd2b6 https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore diff --git a/eng/Versions.props b/eng/Versions.props index 3a8976509a87..5a8f47c9bd52 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -154,13 +154,13 @@ - 4.10.0-2.24127.1 - 4.10.0-2.24127.1 - 4.10.0-2.24127.1 - 4.10.0-2.24127.1 - 4.10.0-2.24127.1 - 4.10.0-2.24127.1 - 4.10.0-2.24127.1 + 4.10.0-3.24127.10 + 4.10.0-3.24127.10 + 4.10.0-3.24127.10 + 4.10.0-3.24127.10 + 4.10.0-3.24127.10 + 4.10.0-3.24127.10 + 4.10.0-3.24127.10 $(MicrosoftNetCompilersToolsetPackageVersion) From 1f4b7272163ab4f4eb26c7c21681c94496282972 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" Date: Wed, 28 Feb 2024 13:54:19 +0000 Subject: [PATCH 271/577] Update dependencies from https://github.com/dotnet/templating build 20240227.3 Microsoft.TemplateEngine.Abstractions , Microsoft.TemplateEngine.Mocks From Version 8.0.300-preview.24115.30 -> To Version 8.0.300-preview.24127.3 --- eng/Version.Details.xml | 8 ++++---- eng/Versions.props | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 07b37d841d9e..d869f1529f85 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -1,14 +1,14 @@ - + https://github.com/dotnet/templating - 82f5e89616d0c7a6f2f6f21d02181ef49de26b52 + 99a0910a071fb797f4d92a8d34e8d862003c76f2 - + https://github.com/dotnet/templating - 82f5e89616d0c7a6f2f6f21d02181ef49de26b52 + 99a0910a071fb797f4d92a8d34e8d862003c76f2 https://dev.azure.com/dnceng/internal/_git/dotnet-runtime diff --git a/eng/Versions.props b/eng/Versions.props index 3a8976509a87..e6852699dea8 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -137,13 +137,13 @@ - 8.0.300-preview.24115.30 + 8.0.300-preview.24127.3 $(MicrosoftTemplateEngineAbstractionsPackageVersion) $(MicrosoftTemplateEngineAbstractionsPackageVersion) $(MicrosoftTemplateEngineAbstractionsPackageVersion) $(MicrosoftTemplateEngineAbstractionsPackageVersion) - 8.0.300-preview.24115.30 + 8.0.300-preview.24127.3 $(MicrosoftTemplateEngineMocksPackageVersion) $(MicrosoftTemplateEngineAbstractionsPackageVersion) $(MicrosoftTemplateEngineMocksPackageVersion) From da566e1a5af363c163c1f3445c50b236cdf938f2 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Thu, 29 Feb 2024 05:44:13 +0000 Subject: [PATCH 272/577] [release/8.0.3xx] Update dependencies from microsoft/vstest (#39094) [release/8.0.3xx] Update dependencies from microsoft/vstest --- eng/Version.Details.xml | 12 ++++++------ eng/Versions.props | 6 +++--- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index efda57fed476..473ae9926fb2 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -179,18 +179,18 @@ https://github.com/nuget/nuget.client 5ecd0be8cb73db807189427eb8e0f7bfd334c1e0 - + https://github.com/microsoft/vstest - f2323247155845f00166ebeca5cffdebff410b49 + 39c7dd12c7ec24d0552513e84d95476f2077ca33 - + https://github.com/microsoft/vstest - f2323247155845f00166ebeca5cffdebff410b49 + 39c7dd12c7ec24d0552513e84d95476f2077ca33 - + https://github.com/microsoft/vstest - f2323247155845f00166ebeca5cffdebff410b49 + 39c7dd12c7ec24d0552513e84d95476f2077ca33 https://dev.azure.com/dnceng/internal/_git/dotnet-runtime diff --git a/eng/Versions.props b/eng/Versions.props index 17fb20af7976..53ba4807a17e 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -99,9 +99,9 @@ - 17.10.0-preview-24123-01 - 17.10.0-preview-24123-01 - 17.10.0-preview-24123-01 + 17.10.0-preview-24126-02 + 17.10.0-preview-24126-02 + 17.10.0-preview-24126-02 From fdaa019d3c42e3d22c7c40d64fb25122f6ec6d3e Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" Date: Thu, 29 Feb 2024 13:45:22 +0000 Subject: [PATCH 273/577] Update dependencies from https://github.com/nuget/nuget.client build 6.10.0.52 Microsoft.Build.NuGetSdkResolver , NuGet.Build.Tasks , NuGet.Build.Tasks.Console , NuGet.Build.Tasks.Pack , NuGet.CommandLine.XPlat , NuGet.Commands , NuGet.Common , NuGet.Configuration , NuGet.Credentials , NuGet.DependencyResolver.Core , NuGet.Frameworks , NuGet.LibraryModel , NuGet.Packaging , NuGet.ProjectModel , NuGet.Protocol , NuGet.Versioning From Version 6.10.0-preview.2.49 -> To Version 6.10.0-preview.2.52 --- eng/Version.Details.xml | 64 ++++++++++++++++++++--------------------- eng/Versions.props | 22 +++++++------- 2 files changed, 43 insertions(+), 43 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 1cc557238957..84d29ff9868e 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -115,69 +115,69 @@ https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore da7e9894ce22ef8cc02e5acc56e95a6f8cf8f644 - + https://github.com/nuget/nuget.client - 5ecd0be8cb73db807189427eb8e0f7bfd334c1e0 + 6009531090c927a8e61da9a0f97bdd5eb6f01a47 - + https://github.com/nuget/nuget.client - 5ecd0be8cb73db807189427eb8e0f7bfd334c1e0 + 6009531090c927a8e61da9a0f97bdd5eb6f01a47 - + https://github.com/nuget/nuget.client - 5ecd0be8cb73db807189427eb8e0f7bfd334c1e0 + 6009531090c927a8e61da9a0f97bdd5eb6f01a47 - + https://github.com/nuget/nuget.client - 5ecd0be8cb73db807189427eb8e0f7bfd334c1e0 + 6009531090c927a8e61da9a0f97bdd5eb6f01a47 - + https://github.com/nuget/nuget.client - 5ecd0be8cb73db807189427eb8e0f7bfd334c1e0 + 6009531090c927a8e61da9a0f97bdd5eb6f01a47 - + https://github.com/nuget/nuget.client - 5ecd0be8cb73db807189427eb8e0f7bfd334c1e0 + 6009531090c927a8e61da9a0f97bdd5eb6f01a47 - + https://github.com/nuget/nuget.client - 5ecd0be8cb73db807189427eb8e0f7bfd334c1e0 + 6009531090c927a8e61da9a0f97bdd5eb6f01a47 - + https://github.com/nuget/nuget.client - 5ecd0be8cb73db807189427eb8e0f7bfd334c1e0 + 6009531090c927a8e61da9a0f97bdd5eb6f01a47 - + https://github.com/nuget/nuget.client - 5ecd0be8cb73db807189427eb8e0f7bfd334c1e0 + 6009531090c927a8e61da9a0f97bdd5eb6f01a47 - + https://github.com/nuget/nuget.client - 5ecd0be8cb73db807189427eb8e0f7bfd334c1e0 + 6009531090c927a8e61da9a0f97bdd5eb6f01a47 - + https://github.com/nuget/nuget.client - 5ecd0be8cb73db807189427eb8e0f7bfd334c1e0 + 6009531090c927a8e61da9a0f97bdd5eb6f01a47 - + https://github.com/nuget/nuget.client - 5ecd0be8cb73db807189427eb8e0f7bfd334c1e0 + 6009531090c927a8e61da9a0f97bdd5eb6f01a47 - + https://github.com/nuget/nuget.client - 5ecd0be8cb73db807189427eb8e0f7bfd334c1e0 + 6009531090c927a8e61da9a0f97bdd5eb6f01a47 - + https://github.com/nuget/nuget.client - 5ecd0be8cb73db807189427eb8e0f7bfd334c1e0 + 6009531090c927a8e61da9a0f97bdd5eb6f01a47 - + https://github.com/nuget/nuget.client - 5ecd0be8cb73db807189427eb8e0f7bfd334c1e0 + 6009531090c927a8e61da9a0f97bdd5eb6f01a47 - + https://github.com/nuget/nuget.client - 5ecd0be8cb73db807189427eb8e0f7bfd334c1e0 + 6009531090c927a8e61da9a0f97bdd5eb6f01a47 https://github.com/microsoft/vstest diff --git a/eng/Versions.props b/eng/Versions.props index 5b2ef745abdd..3d7b63c2ee3b 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -82,18 +82,18 @@ - 6.10.0-preview.2.49 - 6.10.0-preview.2.49 + 6.10.0-preview.2.52 + 6.10.0-preview.2.52 6.0.0-rc.278 - 6.10.0-preview.2.49 - 6.10.0-preview.2.49 - 6.10.0-preview.2.49 - 6.10.0-preview.2.49 - 6.10.0-preview.2.49 - 6.10.0-preview.2.49 - 6.10.0-preview.2.49 - 6.10.0-preview.2.49 - 6.10.0-preview.2.49 + 6.10.0-preview.2.52 + 6.10.0-preview.2.52 + 6.10.0-preview.2.52 + 6.10.0-preview.2.52 + 6.10.0-preview.2.52 + 6.10.0-preview.2.52 + 6.10.0-preview.2.52 + 6.10.0-preview.2.52 + 6.10.0-preview.2.52 $(NuGetPackagingPackageVersion) $(NuGetProjectModelPackageVersion) From 8cd25e6c123ed6311e8b1c9278a51eecc24bc014 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" Date: Thu, 29 Feb 2024 13:46:11 +0000 Subject: [PATCH 274/577] Update dependencies from https://github.com/dotnet/msbuild build 20240228.4 Microsoft.SourceBuild.Intermediate.msbuild , Microsoft.Build , Microsoft.Build.Localization From Version 17.10.0-preview-24127-03 -> To Version 17.10.0-preview-24128-04 --- eng/Version.Details.xml | 12 ++++++------ eng/Versions.props | 4 ++-- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 903126098432..524e1d3ffa5c 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -51,17 +51,17 @@ https://github.com/dotnet/emsdk 2fc2ffd960930318f33fcaa690cbdbc55d72f52d - + https://github.com/dotnet/msbuild - 986f8ec32c74b7425e9ecf313e3a1afdf2d4f672 + 9d0238fe435615c5ec96f89a62aedd92242380df - + https://github.com/dotnet/msbuild - 986f8ec32c74b7425e9ecf313e3a1afdf2d4f672 + 9d0238fe435615c5ec96f89a62aedd92242380df - + https://github.com/dotnet/msbuild - 986f8ec32c74b7425e9ecf313e3a1afdf2d4f672 + 9d0238fe435615c5ec96f89a62aedd92242380df diff --git a/eng/Versions.props b/eng/Versions.props index 24ac3b0f8f78..6567c8de418d 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -120,7 +120,7 @@ - 17.10.0-preview-24128-03 + 17.10.0-preview-24128-04 $(MicrosoftBuildPackageVersion) - 4.10.0-3.24127.10 - 4.10.0-3.24127.10 - 4.10.0-3.24127.10 - 4.10.0-3.24127.10 - 4.10.0-3.24127.10 - 4.10.0-3.24127.10 - 4.10.0-3.24127.10 + 4.10.0-3.24128.4 + 4.10.0-3.24128.4 + 4.10.0-3.24128.4 + 4.10.0-3.24128.4 + 4.10.0-3.24128.4 + 4.10.0-3.24128.4 + 4.10.0-3.24128.4 $(MicrosoftNetCompilersToolsetPackageVersion) From 5cc5fe81e7587b2925c1478dbe980e30b73287f4 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Fri, 1 Mar 2024 07:39:14 +0000 Subject: [PATCH 276/577] [release/8.0.3xx] Update dependencies from dotnet/razor (#39121) [release/8.0.3xx] Update dependencies from dotnet/razor --- eng/Version.Details.xml | 12 ++++++------ eng/Versions.props | 6 +++--- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index f773d3048d65..1da5e5729248 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -277,18 +277,18 @@ https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore da7e9894ce22ef8cc02e5acc56e95a6f8cf8f644 - + https://github.com/dotnet/razor - 3fc5548e17906494a8b93dda256cd16c31d70021 + 58db8425a9918619f4f60ca23be7047d0036867d - + https://github.com/dotnet/razor - 3fc5548e17906494a8b93dda256cd16c31d70021 + 58db8425a9918619f4f60ca23be7047d0036867d - + https://github.com/dotnet/razor - 3fc5548e17906494a8b93dda256cd16c31d70021 + 58db8425a9918619f4f60ca23be7047d0036867d https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore diff --git a/eng/Versions.props b/eng/Versions.props index c2e212304b5e..609aef53486a 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -175,9 +175,9 @@ - 7.0.0-preview.24128.1 - 7.0.0-preview.24128.1 - 7.0.0-preview.24128.1 + 7.0.0-preview.24129.1 + 7.0.0-preview.24129.1 + 7.0.0-preview.24129.1 From 38f11b6b9dd971993311359fa5653208d0fb0cba Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" Date: Fri, 1 Mar 2024 13:53:43 +0000 Subject: [PATCH 277/577] Update dependencies from https://github.com/dotnet/msbuild build 20240228.4 Microsoft.SourceBuild.Intermediate.msbuild , Microsoft.Build , Microsoft.Build.Localization From Version 17.10.0-preview-24127-03 -> To Version 17.10.0-preview-24128-04 From 013b8a6eb84022d6723a0d0e76f5ed31e328c0bf Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" Date: Fri, 1 Mar 2024 13:54:05 +0000 Subject: [PATCH 278/577] Update dependencies from https://github.com/dotnet/razor build 20240229.6 Microsoft.AspNetCore.Mvc.Razor.Extensions.Tooling.Internal , Microsoft.CodeAnalysis.Razor.Tooling.Internal , Microsoft.NET.Sdk.Razor.SourceGenerators.Transport From Version 7.0.0-preview.24129.1 -> To Version 7.0.0-preview.24129.6 --- eng/Version.Details.xml | 12 ++++++------ eng/Versions.props | 6 +++--- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 1da5e5729248..cee98bec22ae 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -277,18 +277,18 @@ https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore da7e9894ce22ef8cc02e5acc56e95a6f8cf8f644 - + https://github.com/dotnet/razor - 58db8425a9918619f4f60ca23be7047d0036867d + c5c96a26b1e0bd202dfd0941815dc44711e2abfd - + https://github.com/dotnet/razor - 58db8425a9918619f4f60ca23be7047d0036867d + c5c96a26b1e0bd202dfd0941815dc44711e2abfd - + https://github.com/dotnet/razor - 58db8425a9918619f4f60ca23be7047d0036867d + c5c96a26b1e0bd202dfd0941815dc44711e2abfd https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore diff --git a/eng/Versions.props b/eng/Versions.props index 609aef53486a..0923c135f55b 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -175,9 +175,9 @@ - 7.0.0-preview.24129.1 - 7.0.0-preview.24129.1 - 7.0.0-preview.24129.1 + 7.0.0-preview.24129.6 + 7.0.0-preview.24129.6 + 7.0.0-preview.24129.6 From 6615f7dc5c35144bc1d7427da045f2b40344659c Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" Date: Fri, 1 Mar 2024 13:54:30 +0000 Subject: [PATCH 279/577] Update dependencies from https://github.com/dotnet/roslyn build 20240301.3 Microsoft.CodeAnalysis , Microsoft.CodeAnalysis.CSharp , Microsoft.CodeAnalysis.CSharp.CodeStyle , Microsoft.CodeAnalysis.CSharp.Features , Microsoft.CodeAnalysis.CSharp.Workspaces , Microsoft.CodeAnalysis.Workspaces.MSBuild , Microsoft.Net.Compilers.Toolset From Version 4.10.0-3.24128.4 -> To Version 4.10.0-3.24151.3 --- eng/Version.Details.xml | 28 ++++++++++++++-------------- eng/Versions.props | 14 +++++++------- 2 files changed, 21 insertions(+), 21 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 1da5e5729248..7f0f1630d305 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -78,34 +78,34 @@ ac0d85557969d51bca72181514ddb7d5796fbbe2 - + https://github.com/dotnet/roslyn - 1d9ee7f5e9b3b6d681ce8d89d4b252619b704088 + 06d3f153ed6af6f2b78028a1e1e6ecc55c8ff101 - + https://github.com/dotnet/roslyn - 1d9ee7f5e9b3b6d681ce8d89d4b252619b704088 + 06d3f153ed6af6f2b78028a1e1e6ecc55c8ff101 - + https://github.com/dotnet/roslyn - 1d9ee7f5e9b3b6d681ce8d89d4b252619b704088 + 06d3f153ed6af6f2b78028a1e1e6ecc55c8ff101 - + https://github.com/dotnet/roslyn - 1d9ee7f5e9b3b6d681ce8d89d4b252619b704088 + 06d3f153ed6af6f2b78028a1e1e6ecc55c8ff101 - + https://github.com/dotnet/roslyn - 1d9ee7f5e9b3b6d681ce8d89d4b252619b704088 + 06d3f153ed6af6f2b78028a1e1e6ecc55c8ff101 - + https://github.com/dotnet/roslyn - 1d9ee7f5e9b3b6d681ce8d89d4b252619b704088 + 06d3f153ed6af6f2b78028a1e1e6ecc55c8ff101 - + https://github.com/dotnet/roslyn - 1d9ee7f5e9b3b6d681ce8d89d4b252619b704088 + 06d3f153ed6af6f2b78028a1e1e6ecc55c8ff101 https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore diff --git a/eng/Versions.props b/eng/Versions.props index 609aef53486a..112c47a4d55b 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -154,13 +154,13 @@ - 4.10.0-3.24128.4 - 4.10.0-3.24128.4 - 4.10.0-3.24128.4 - 4.10.0-3.24128.4 - 4.10.0-3.24128.4 - 4.10.0-3.24128.4 - 4.10.0-3.24128.4 + 4.10.0-3.24151.3 + 4.10.0-3.24151.3 + 4.10.0-3.24151.3 + 4.10.0-3.24151.3 + 4.10.0-3.24151.3 + 4.10.0-3.24151.3 + 4.10.0-3.24151.3 $(MicrosoftNetCompilersToolsetPackageVersion) From 20c36d2cdf0f442a83815861dcd5cfd5799eb20c Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" Date: Sat, 2 Mar 2024 14:00:59 +0000 Subject: [PATCH 280/577] Update dependencies from https://github.com/dotnet/msbuild build 20240228.4 Microsoft.SourceBuild.Intermediate.msbuild , Microsoft.Build , Microsoft.Build.Localization From Version 17.10.0-preview-24127-03 -> To Version 17.10.0-preview-24128-04 From 8276d8368631753b1ee234a2bc5d634fc9f69ec2 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" Date: Sat, 2 Mar 2024 14:01:22 +0000 Subject: [PATCH 281/577] Update dependencies from https://github.com/dotnet/fsharp build 20240302.1 Microsoft.SourceBuild.Intermediate.fsharp , Microsoft.FSharp.Compiler From Version 8.0.300-beta.24127.3 -> To Version 8.0.300-beta.24152.1 --- eng/Version.Details.xml | 8 ++++---- eng/Versions.props | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 1da5e5729248..2570eb5879d0 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -64,13 +64,13 @@ 6f44380e4fdea6ddf5c11f48efeb25c2bf181e62 - + https://github.com/dotnet/fsharp - b57dee7cec971021547a7b8a36a46d7271fea99e + ea8ef6edee63929f44026c79f94c9e6ffe6dcd62 - + https://github.com/dotnet/fsharp - b57dee7cec971021547a7b8a36a46d7271fea99e + ea8ef6edee63929f44026c79f94c9e6ffe6dcd62 diff --git a/eng/Versions.props b/eng/Versions.props index 609aef53486a..4fe2773db8c3 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -150,7 +150,7 @@ - 12.8.300-beta.24127.3 + 12.8.300-beta.24152.1 From 8b411fea03add5fe9b5f1b5b34b0207b5358930c Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" Date: Sat, 2 Mar 2024 14:01:47 +0000 Subject: [PATCH 282/577] Update dependencies from https://github.com/dotnet/razor build 20240301.1 Microsoft.AspNetCore.Mvc.Razor.Extensions.Tooling.Internal , Microsoft.CodeAnalysis.Razor.Tooling.Internal , Microsoft.NET.Sdk.Razor.SourceGenerators.Transport From Version 7.0.0-preview.24129.1 -> To Version 7.0.0-preview.24151.1 --- eng/Version.Details.xml | 12 ++++++------ eng/Versions.props | 6 +++--- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index cee98bec22ae..1aaf282876dc 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -277,18 +277,18 @@ https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore da7e9894ce22ef8cc02e5acc56e95a6f8cf8f644 - + https://github.com/dotnet/razor - c5c96a26b1e0bd202dfd0941815dc44711e2abfd + d4c396a9c9e31d027789a55a61f5509cadc6e0e0 - + https://github.com/dotnet/razor - c5c96a26b1e0bd202dfd0941815dc44711e2abfd + d4c396a9c9e31d027789a55a61f5509cadc6e0e0 - + https://github.com/dotnet/razor - c5c96a26b1e0bd202dfd0941815dc44711e2abfd + d4c396a9c9e31d027789a55a61f5509cadc6e0e0 https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore diff --git a/eng/Versions.props b/eng/Versions.props index 0923c135f55b..dbbbe6e45f99 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -175,9 +175,9 @@ - 7.0.0-preview.24129.6 - 7.0.0-preview.24129.6 - 7.0.0-preview.24129.6 + 7.0.0-preview.24151.1 + 7.0.0-preview.24151.1 + 7.0.0-preview.24151.1 From 7afde4ce4071eb2541dcf78b7db21f4ea3f9df0a Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" Date: Sat, 2 Mar 2024 14:03:26 +0000 Subject: [PATCH 283/577] Update dependencies from https://github.com/dotnet/roslyn build 20240301.8 Microsoft.CodeAnalysis , Microsoft.CodeAnalysis.CSharp , Microsoft.CodeAnalysis.CSharp.CodeStyle , Microsoft.CodeAnalysis.CSharp.Features , Microsoft.CodeAnalysis.CSharp.Workspaces , Microsoft.CodeAnalysis.Workspaces.MSBuild , Microsoft.Net.Compilers.Toolset From Version 4.10.0-3.24128.4 -> To Version 4.10.0-3.24151.8 --- eng/Version.Details.xml | 28 ++++++++++++++-------------- eng/Versions.props | 14 +++++++------- 2 files changed, 21 insertions(+), 21 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 7f0f1630d305..e1cd6ad38c8b 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -78,34 +78,34 @@ ac0d85557969d51bca72181514ddb7d5796fbbe2 - + https://github.com/dotnet/roslyn - 06d3f153ed6af6f2b78028a1e1e6ecc55c8ff101 + 8537440d8c831b8533a18f6530945ee91c243e1b - + https://github.com/dotnet/roslyn - 06d3f153ed6af6f2b78028a1e1e6ecc55c8ff101 + 8537440d8c831b8533a18f6530945ee91c243e1b - + https://github.com/dotnet/roslyn - 06d3f153ed6af6f2b78028a1e1e6ecc55c8ff101 + 8537440d8c831b8533a18f6530945ee91c243e1b - + https://github.com/dotnet/roslyn - 06d3f153ed6af6f2b78028a1e1e6ecc55c8ff101 + 8537440d8c831b8533a18f6530945ee91c243e1b - + https://github.com/dotnet/roslyn - 06d3f153ed6af6f2b78028a1e1e6ecc55c8ff101 + 8537440d8c831b8533a18f6530945ee91c243e1b - + https://github.com/dotnet/roslyn - 06d3f153ed6af6f2b78028a1e1e6ecc55c8ff101 + 8537440d8c831b8533a18f6530945ee91c243e1b - + https://github.com/dotnet/roslyn - 06d3f153ed6af6f2b78028a1e1e6ecc55c8ff101 + 8537440d8c831b8533a18f6530945ee91c243e1b https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore diff --git a/eng/Versions.props b/eng/Versions.props index 112c47a4d55b..0e211d19ac4b 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -154,13 +154,13 @@ - 4.10.0-3.24151.3 - 4.10.0-3.24151.3 - 4.10.0-3.24151.3 - 4.10.0-3.24151.3 - 4.10.0-3.24151.3 - 4.10.0-3.24151.3 - 4.10.0-3.24151.3 + 4.10.0-3.24151.8 + 4.10.0-3.24151.8 + 4.10.0-3.24151.8 + 4.10.0-3.24151.8 + 4.10.0-3.24151.8 + 4.10.0-3.24151.8 + 4.10.0-3.24151.8 $(MicrosoftNetCompilersToolsetPackageVersion) From cc589fbf38570afd6df14787207724d8f82ccb1b Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" Date: Sat, 2 Mar 2024 14:05:45 +0000 Subject: [PATCH 284/577] Update dependencies from https://github.com/dotnet/arcade build 20240301.4 Microsoft.DotNet.Arcade.Sdk , Microsoft.DotNet.Helix.Sdk , Microsoft.DotNet.SignTool , Microsoft.DotNet.XUnitExtensions From Version 8.0.0-beta.24123.1 -> To Version 8.0.0-beta.24151.4 --- eng/Version.Details.xml | 16 +- eng/Versions.props | 4 +- eng/common/templates-official/job/job.yml | 255 ++++++++++++++++ .../templates-official/job/onelocbuild.yml | 112 +++++++ .../job/publish-build-assets.yml | 153 ++++++++++ .../templates-official/job/source-build.yml | 67 ++++ .../job/source-index-stage1.yml | 68 +++++ .../templates-official/jobs/codeql-build.yml | 31 ++ eng/common/templates-official/jobs/jobs.yml | 97 ++++++ .../templates-official/jobs/source-build.yml | 46 +++ .../post-build/common-variables.yml | 22 ++ .../post-build/post-build.yml | 285 ++++++++++++++++++ .../post-build/setup-maestro-vars.yml | 70 +++++ .../post-build/trigger-subscription.yml | 13 + .../steps/add-build-to-channel.yml | 13 + .../templates-official/steps/build-reason.yml | 12 + .../steps/component-governance.yml | 13 + .../steps/execute-codeql.yml | 32 ++ .../templates-official/steps/execute-sdl.yml | 88 ++++++ .../steps/generate-sbom.yml | 48 +++ .../templates-official/steps/publish-logs.yml | 23 ++ .../templates-official/steps/retain-build.yml | 28 ++ .../steps/send-to-helix.yml | 91 ++++++ .../templates-official/steps/source-build.yml | 129 ++++++++ .../variables/pool-providers.yml | 45 +++ .../variables/sdl-variables.yml | 7 + global.json | 4 +- 27 files changed, 1760 insertions(+), 12 deletions(-) create mode 100644 eng/common/templates-official/job/job.yml create mode 100644 eng/common/templates-official/job/onelocbuild.yml create mode 100644 eng/common/templates-official/job/publish-build-assets.yml create mode 100644 eng/common/templates-official/job/source-build.yml create mode 100644 eng/common/templates-official/job/source-index-stage1.yml create mode 100644 eng/common/templates-official/jobs/codeql-build.yml create mode 100644 eng/common/templates-official/jobs/jobs.yml create mode 100644 eng/common/templates-official/jobs/source-build.yml create mode 100644 eng/common/templates-official/post-build/common-variables.yml create mode 100644 eng/common/templates-official/post-build/post-build.yml create mode 100644 eng/common/templates-official/post-build/setup-maestro-vars.yml create mode 100644 eng/common/templates-official/post-build/trigger-subscription.yml create mode 100644 eng/common/templates-official/steps/add-build-to-channel.yml create mode 100644 eng/common/templates-official/steps/build-reason.yml create mode 100644 eng/common/templates-official/steps/component-governance.yml create mode 100644 eng/common/templates-official/steps/execute-codeql.yml create mode 100644 eng/common/templates-official/steps/execute-sdl.yml create mode 100644 eng/common/templates-official/steps/generate-sbom.yml create mode 100644 eng/common/templates-official/steps/publish-logs.yml create mode 100644 eng/common/templates-official/steps/retain-build.yml create mode 100644 eng/common/templates-official/steps/send-to-helix.yml create mode 100644 eng/common/templates-official/steps/source-build.yml create mode 100644 eng/common/templates-official/variables/pool-providers.yml create mode 100644 eng/common/templates-official/variables/sdl-variables.yml diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 1da5e5729248..881260c6a85f 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -475,22 +475,22 @@ - + https://github.com/dotnet/arcade - 042763a811fd94dc3556253d4c64118dd665216e + cbb61c3a9a42e7c3cce17ee453ff5ecdc7f69282 - + https://github.com/dotnet/arcade - 042763a811fd94dc3556253d4c64118dd665216e + cbb61c3a9a42e7c3cce17ee453ff5ecdc7f69282 - + https://github.com/dotnet/arcade - 042763a811fd94dc3556253d4c64118dd665216e + cbb61c3a9a42e7c3cce17ee453ff5ecdc7f69282 - + https://github.com/dotnet/arcade - 042763a811fd94dc3556253d4c64118dd665216e + cbb61c3a9a42e7c3cce17ee453ff5ecdc7f69282 https://dev.azure.com/dnceng/internal/_git/dotnet-runtime diff --git a/eng/Versions.props b/eng/Versions.props index 609aef53486a..bd2103e2efea 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -34,7 +34,7 @@ 7.0.0 4.0.0 7.0.0 - 8.0.0-beta.24123.1 + 8.0.0-beta.24151.4 7.0.0-preview.22423.2 8.0.0 4.3.0 @@ -209,7 +209,7 @@ 6.12.0 6.1.0 - 8.0.0-beta.24123.1 + 8.0.0-beta.24151.4 4.18.4 1.3.2 8.0.0-beta.23607.1 diff --git a/eng/common/templates-official/job/job.yml b/eng/common/templates-official/job/job.yml new file mode 100644 index 000000000000..9e7bebe9af89 --- /dev/null +++ b/eng/common/templates-official/job/job.yml @@ -0,0 +1,255 @@ +# Internal resources (telemetry, microbuild) can only be accessed from non-public projects, +# and some (Microbuild) should only be applied to non-PR cases for internal builds. + +parameters: +# Job schema parameters - https://docs.microsoft.com/en-us/azure/devops/pipelines/yaml-schema?view=vsts&tabs=schema#job + cancelTimeoutInMinutes: '' + condition: '' + container: '' + continueOnError: false + dependsOn: '' + displayName: '' + pool: '' + steps: [] + strategy: '' + timeoutInMinutes: '' + variables: [] + workspace: '' + +# Job base template specific parameters + # See schema documentation - https://github.com/dotnet/arcade/blob/master/Documentation/AzureDevOps/TemplateSchema.md + artifacts: '' + enableMicrobuild: false + enablePublishBuildArtifacts: false + enablePublishBuildAssets: false + enablePublishTestResults: false + enablePublishUsingPipelines: false + enableBuildRetry: false + disableComponentGovernance: '' + componentGovernanceIgnoreDirectories: '' + mergeTestResults: false + testRunTitle: '' + testResultsFormat: '' + name: '' + preSteps: [] + runAsPublic: false +# Sbom related params + enableSbom: true + PackageVersion: 7.0.0 + BuildDropPath: '$(Build.SourcesDirectory)/artifacts' + +jobs: +- job: ${{ parameters.name }} + + ${{ if ne(parameters.cancelTimeoutInMinutes, '') }}: + cancelTimeoutInMinutes: ${{ parameters.cancelTimeoutInMinutes }} + + ${{ if ne(parameters.condition, '') }}: + condition: ${{ parameters.condition }} + + ${{ if ne(parameters.container, '') }}: + container: ${{ parameters.container }} + + ${{ if ne(parameters.continueOnError, '') }}: + continueOnError: ${{ parameters.continueOnError }} + + ${{ if ne(parameters.dependsOn, '') }}: + dependsOn: ${{ parameters.dependsOn }} + + ${{ if ne(parameters.displayName, '') }}: + displayName: ${{ parameters.displayName }} + + ${{ if ne(parameters.pool, '') }}: + pool: ${{ parameters.pool }} + + ${{ if ne(parameters.strategy, '') }}: + strategy: ${{ parameters.strategy }} + + ${{ if ne(parameters.timeoutInMinutes, '') }}: + timeoutInMinutes: ${{ parameters.timeoutInMinutes }} + + variables: + - ${{ if ne(parameters.enableTelemetry, 'false') }}: + - name: DOTNET_CLI_TELEMETRY_PROFILE + value: '$(Build.Repository.Uri)' + - ${{ if eq(parameters.enableRichCodeNavigation, 'true') }}: + - name: EnableRichCodeNavigation + value: 'true' + # Retry signature validation up to three times, waiting 2 seconds between attempts. + # See https://learn.microsoft.com/en-us/nuget/reference/errors-and-warnings/nu3028#retry-untrusted-root-failures + - name: NUGET_EXPERIMENTAL_CHAIN_BUILD_RETRY_POLICY + value: 3,2000 + - ${{ each variable in parameters.variables }}: + # handle name-value variable syntax + # example: + # - name: [key] + # value: [value] + - ${{ if ne(variable.name, '') }}: + - name: ${{ variable.name }} + value: ${{ variable.value }} + + # handle variable groups + - ${{ if ne(variable.group, '') }}: + - group: ${{ variable.group }} + + # handle template variable syntax + # example: + # - template: path/to/template.yml + # parameters: + # [key]: [value] + - ${{ if ne(variable.template, '') }}: + - template: ${{ variable.template }} + ${{ if ne(variable.parameters, '') }}: + parameters: ${{ variable.parameters }} + + # handle key-value variable syntax. + # example: + # - [key]: [value] + - ${{ if and(eq(variable.name, ''), eq(variable.group, ''), eq(variable.template, '')) }}: + - ${{ each pair in variable }}: + - name: ${{ pair.key }} + value: ${{ pair.value }} + + # DotNet-HelixApi-Access provides 'HelixApiAccessToken' for internal builds + - ${{ if and(eq(parameters.enableTelemetry, 'true'), eq(parameters.runAsPublic, 'false'), ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest')) }}: + - group: DotNet-HelixApi-Access + + ${{ if ne(parameters.workspace, '') }}: + workspace: ${{ parameters.workspace }} + + steps: + - ${{ if ne(parameters.preSteps, '') }}: + - ${{ each preStep in parameters.preSteps }}: + - ${{ preStep }} + + - ${{ if and(eq(parameters.runAsPublic, 'false'), ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest')) }}: + - ${{ if eq(parameters.enableMicrobuild, 'true') }}: + - task: MicroBuildSigningPlugin@3 + displayName: Install MicroBuild plugin + inputs: + signType: $(_SignType) + zipSources: false + feedSource: https://dnceng.pkgs.visualstudio.com/_packaging/MicroBuildToolset/nuget/v3/index.json + env: + TeamName: $(_TeamName) + continueOnError: ${{ parameters.continueOnError }} + condition: and(succeeded(), in(variables['_SignType'], 'real', 'test'), eq(variables['Agent.Os'], 'Windows_NT')) + + - ${{ if and(eq(parameters.runAsPublic, 'false'), eq(variables['System.TeamProject'], 'internal')) }}: + - task: NuGetAuthenticate@1 + + - ${{ if and(ne(parameters.artifacts.download, 'false'), ne(parameters.artifacts.download, '')) }}: + - task: DownloadPipelineArtifact@2 + inputs: + buildType: current + artifactName: ${{ coalesce(parameters.artifacts.download.name, 'Artifacts_$(Agent.OS)_$(_BuildConfig)') }} + targetPath: ${{ coalesce(parameters.artifacts.download.path, 'artifacts') }} + itemPattern: ${{ coalesce(parameters.artifacts.download.pattern, '**') }} + + - ${{ each step in parameters.steps }}: + - ${{ step }} + + - ${{ if eq(parameters.enableRichCodeNavigation, true) }}: + - task: RichCodeNavIndexer@0 + displayName: RichCodeNav Upload + inputs: + languages: ${{ coalesce(parameters.richCodeNavigationLanguage, 'csharp') }} + environment: ${{ coalesce(parameters.richCodeNavigationEnvironment, 'production') }} + richNavLogOutputDirectory: $(Build.SourcesDirectory)/artifacts/bin + uploadRichNavArtifacts: ${{ coalesce(parameters.richCodeNavigationUploadArtifacts, false) }} + continueOnError: true + + - template: /eng/common/templates-official/steps/component-governance.yml + parameters: + ${{ if eq(parameters.disableComponentGovernance, '') }}: + ${{ if and(ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest'), eq(parameters.runAsPublic, 'false'), or(startsWith(variables['Build.SourceBranch'], 'refs/heads/release/'), startsWith(variables['Build.SourceBranch'], 'refs/heads/dotnet/'), startsWith(variables['Build.SourceBranch'], 'refs/heads/microsoft/'), eq(variables['Build.SourceBranch'], 'refs/heads/main'))) }}: + disableComponentGovernance: false + ${{ else }}: + disableComponentGovernance: true + ${{ else }}: + disableComponentGovernance: ${{ parameters.disableComponentGovernance }} + componentGovernanceIgnoreDirectories: ${{ parameters.componentGovernanceIgnoreDirectories }} + + - ${{ if eq(parameters.enableMicrobuild, 'true') }}: + - ${{ if and(eq(parameters.runAsPublic, 'false'), ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest')) }}: + - task: MicroBuildCleanup@1 + displayName: Execute Microbuild cleanup tasks + condition: and(always(), in(variables['_SignType'], 'real', 'test'), eq(variables['Agent.Os'], 'Windows_NT')) + continueOnError: ${{ parameters.continueOnError }} + env: + TeamName: $(_TeamName) + + - ${{ if ne(parameters.artifacts.publish, '') }}: + - ${{ if and(ne(parameters.artifacts.publish.artifacts, 'false'), ne(parameters.artifacts.publish.artifacts, '')) }}: + - task: CopyFiles@2 + displayName: Gather binaries for publish to artifacts + inputs: + SourceFolder: 'artifacts/bin' + Contents: '**' + TargetFolder: '$(Build.ArtifactStagingDirectory)/artifacts/bin' + - task: CopyFiles@2 + displayName: Gather packages for publish to artifacts + inputs: + SourceFolder: 'artifacts/packages' + Contents: '**' + TargetFolder: '$(Build.ArtifactStagingDirectory)/artifacts/packages' + - task: 1ES.PublishBuildArtifacts@1 + displayName: Publish pipeline artifacts + inputs: + PathtoPublish: '$(Build.ArtifactStagingDirectory)/artifacts' + PublishLocation: Container + ArtifactName: ${{ coalesce(parameters.artifacts.publish.artifacts.name , 'Artifacts_$(Agent.Os)_$(_BuildConfig)') }} + continueOnError: true + condition: always() + - ${{ if and(ne(parameters.artifacts.publish.logs, 'false'), ne(parameters.artifacts.publish.logs, '')) }}: + - publish: artifacts/log + artifact: ${{ coalesce(parameters.artifacts.publish.logs.name, 'Logs_Build_$(Agent.Os)_$(_BuildConfig)') }} + displayName: Publish logs + continueOnError: true + condition: always() + + - ${{ if ne(parameters.enablePublishBuildArtifacts, 'false') }}: + - task: 1ES.PublishBuildArtifacts@1 + displayName: Publish Logs + inputs: + PathtoPublish: '$(Build.SourcesDirectory)/artifacts/log/$(_BuildConfig)' + PublishLocation: Container + ArtifactName: ${{ coalesce(parameters.enablePublishBuildArtifacts.artifactName, '$(Agent.Os)_$(Agent.JobName)' ) }} + continueOnError: true + condition: always() + + - ${{ if or(and(eq(parameters.enablePublishTestResults, 'true'), eq(parameters.testResultsFormat, '')), eq(parameters.testResultsFormat, 'xunit')) }}: + - task: PublishTestResults@2 + displayName: Publish XUnit Test Results + inputs: + testResultsFormat: 'xUnit' + testResultsFiles: '*.xml' + searchFolder: '$(Build.SourcesDirectory)/artifacts/TestResults/$(_BuildConfig)' + testRunTitle: ${{ coalesce(parameters.testRunTitle, parameters.name, '$(System.JobName)') }}-xunit + mergeTestResults: ${{ parameters.mergeTestResults }} + continueOnError: true + condition: always() + - ${{ if or(and(eq(parameters.enablePublishTestResults, 'true'), eq(parameters.testResultsFormat, '')), eq(parameters.testResultsFormat, 'vstest')) }}: + - task: PublishTestResults@2 + displayName: Publish TRX Test Results + inputs: + testResultsFormat: 'VSTest' + testResultsFiles: '*.trx' + searchFolder: '$(Build.SourcesDirectory)/artifacts/TestResults/$(_BuildConfig)' + testRunTitle: ${{ coalesce(parameters.testRunTitle, parameters.name, '$(System.JobName)') }}-trx + mergeTestResults: ${{ parameters.mergeTestResults }} + continueOnError: true + condition: always() + + - ${{ if and(eq(parameters.runAsPublic, 'false'), ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest'), eq(parameters.enableSbom, 'true')) }}: + - template: /eng/common/templates-official/steps/generate-sbom.yml + parameters: + PackageVersion: ${{ parameters.packageVersion}} + BuildDropPath: ${{ parameters.buildDropPath }} + IgnoreDirectories: ${{ parameters.componentGovernanceIgnoreDirectories }} + + - ${{ if eq(parameters.enableBuildRetry, 'true') }}: + - publish: $(Build.SourcesDirectory)\eng\common\BuildConfiguration + artifact: BuildConfiguration + displayName: Publish build retry configuration + continueOnError: true diff --git a/eng/common/templates-official/job/onelocbuild.yml b/eng/common/templates-official/job/onelocbuild.yml new file mode 100644 index 000000000000..ba9ba4930329 --- /dev/null +++ b/eng/common/templates-official/job/onelocbuild.yml @@ -0,0 +1,112 @@ +parameters: + # Optional: dependencies of the job + dependsOn: '' + + # Optional: A defined YAML pool - https://docs.microsoft.com/en-us/azure/devops/pipelines/yaml-schema?view=vsts&tabs=schema#pool + pool: '' + + CeapexPat: $(dn-bot-ceapex-package-r) # PAT for the loc AzDO instance https://dev.azure.com/ceapex + GithubPat: $(BotAccount-dotnet-bot-repo-PAT) + + SourcesDirectory: $(Build.SourcesDirectory) + CreatePr: true + AutoCompletePr: false + ReusePr: true + UseLfLineEndings: true + UseCheckedInLocProjectJson: false + SkipLocProjectJsonGeneration: false + LanguageSet: VS_Main_Languages + LclSource: lclFilesInRepo + LclPackageId: '' + RepoType: gitHub + GitHubOrg: dotnet + MirrorRepo: '' + MirrorBranch: main + condition: '' + JobNameSuffix: '' + +jobs: +- job: OneLocBuild${{ parameters.JobNameSuffix }} + + dependsOn: ${{ parameters.dependsOn }} + + displayName: OneLocBuild${{ parameters.JobNameSuffix }} + + variables: + - group: OneLocBuildVariables # Contains the CeapexPat and GithubPat + - name: _GenerateLocProjectArguments + value: -SourcesDirectory ${{ parameters.SourcesDirectory }} + -LanguageSet "${{ parameters.LanguageSet }}" + -CreateNeutralXlfs + - ${{ if eq(parameters.UseCheckedInLocProjectJson, 'true') }}: + - name: _GenerateLocProjectArguments + value: ${{ variables._GenerateLocProjectArguments }} -UseCheckedInLocProjectJson + - template: /eng/common/templates-official/variables/pool-providers.yml + + ${{ if ne(parameters.pool, '') }}: + pool: ${{ parameters.pool }} + ${{ if eq(parameters.pool, '') }}: + pool: + # We don't use the collection uri here because it might vary (.visualstudio.com vs. dev.azure.com) + ${{ if eq(variables['System.TeamProject'], 'DevDiv') }}: + name: AzurePipelines-EO + image: 1ESPT-Windows2022 + demands: Cmd + os: windows + # If it's not devdiv, it's dnceng + ${{ if ne(variables['System.TeamProject'], 'DevDiv') }}: + name: $(DncEngInternalBuildPool) + image: 1es-windows-2022-pt + os: windows + + steps: + - ${{ if ne(parameters.SkipLocProjectJsonGeneration, 'true') }}: + - task: Powershell@2 + inputs: + filePath: $(Build.SourcesDirectory)/eng/common/generate-locproject.ps1 + arguments: $(_GenerateLocProjectArguments) + displayName: Generate LocProject.json + condition: ${{ parameters.condition }} + + - task: OneLocBuild@2 + displayName: OneLocBuild + env: + SYSTEM_ACCESSTOKEN: $(System.AccessToken) + inputs: + locProj: eng/Localize/LocProject.json + outDir: $(Build.ArtifactStagingDirectory) + lclSource: ${{ parameters.LclSource }} + lclPackageId: ${{ parameters.LclPackageId }} + isCreatePrSelected: ${{ parameters.CreatePr }} + isAutoCompletePrSelected: ${{ parameters.AutoCompletePr }} + ${{ if eq(parameters.CreatePr, true) }}: + isUseLfLineEndingsSelected: ${{ parameters.UseLfLineEndings }} + ${{ if eq(parameters.RepoType, 'gitHub') }}: + isShouldReusePrSelected: ${{ parameters.ReusePr }} + packageSourceAuth: patAuth + patVariable: ${{ parameters.CeapexPat }} + ${{ if eq(parameters.RepoType, 'gitHub') }}: + repoType: ${{ parameters.RepoType }} + gitHubPatVariable: "${{ parameters.GithubPat }}" + ${{ if ne(parameters.MirrorRepo, '') }}: + isMirrorRepoSelected: true + gitHubOrganization: ${{ parameters.GitHubOrg }} + mirrorRepo: ${{ parameters.MirrorRepo }} + mirrorBranch: ${{ parameters.MirrorBranch }} + condition: ${{ parameters.condition }} + + - task: 1ES.PublishBuildArtifacts@1 + displayName: Publish Localization Files + inputs: + PathtoPublish: '$(Build.ArtifactStagingDirectory)/loc' + PublishLocation: Container + ArtifactName: Loc + condition: ${{ parameters.condition }} + + - task: 1ES.PublishBuildArtifacts@1 + displayName: Publish LocProject.json + inputs: + PathtoPublish: '$(Build.SourcesDirectory)/eng/Localize/' + PublishLocation: Container + ArtifactName: Loc + condition: ${{ parameters.condition }} \ No newline at end of file diff --git a/eng/common/templates-official/job/publish-build-assets.yml b/eng/common/templates-official/job/publish-build-assets.yml new file mode 100644 index 000000000000..ea5104625fac --- /dev/null +++ b/eng/common/templates-official/job/publish-build-assets.yml @@ -0,0 +1,153 @@ +parameters: + configuration: 'Debug' + + # Optional: condition for the job to run + condition: '' + + # Optional: 'true' if future jobs should run even if this job fails + continueOnError: false + + # Optional: dependencies of the job + dependsOn: '' + + # Optional: Include PublishBuildArtifacts task + enablePublishBuildArtifacts: false + + # Optional: A defined YAML pool - https://docs.microsoft.com/en-us/azure/devops/pipelines/yaml-schema?view=vsts&tabs=schema#pool + pool: {} + + # Optional: should run as a public build even in the internal project + # if 'true', the build won't run any of the internal only steps, even if it is running in non-public projects. + runAsPublic: false + + # Optional: whether the build's artifacts will be published using release pipelines or direct feed publishing + publishUsingPipelines: false + + # Optional: whether the build's artifacts will be published using release pipelines or direct feed publishing + publishAssetsImmediately: false + + artifactsPublishingAdditionalParameters: '' + + signingValidationAdditionalParameters: '' + +jobs: +- job: Asset_Registry_Publish + + dependsOn: ${{ parameters.dependsOn }} + timeoutInMinutes: 150 + + ${{ if eq(parameters.publishAssetsImmediately, 'true') }}: + displayName: Publish Assets + ${{ else }}: + displayName: Publish to Build Asset Registry + + variables: + - template: /eng/common/templates-official/variables/pool-providers.yml + - ${{ if and(eq(parameters.runAsPublic, 'false'), ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest')) }}: + - group: Publish-Build-Assets + - group: AzureDevOps-Artifact-Feeds-Pats + - name: runCodesignValidationInjection + value: false + - ${{ if eq(parameters.publishAssetsImmediately, 'true') }}: + - template: /eng/common/templates-official/post-build/common-variables.yml + + pool: + # We don't use the collection uri here because it might vary (.visualstudio.com vs. dev.azure.com) + ${{ if eq(variables['System.TeamProject'], 'DevDiv') }}: + name: AzurePipelines-EO + image: 1ESPT-Windows2022 + demands: Cmd + os: windows + # If it's not devdiv, it's dnceng + ${{ if ne(variables['System.TeamProject'], 'DevDiv') }}: + name: $(DncEngInternalBuildPool) + image: 1es-windows-2022-pt + os: windows + steps: + - ${{ if and(eq(parameters.runAsPublic, 'false'), ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest')) }}: + - task: DownloadBuildArtifacts@0 + displayName: Download artifact + inputs: + artifactName: AssetManifests + downloadPath: '$(Build.StagingDirectory)/Download' + checkDownloadedFiles: true + condition: ${{ parameters.condition }} + continueOnError: ${{ parameters.continueOnError }} + + - task: NuGetAuthenticate@1 + + - task: PowerShell@2 + displayName: Publish Build Assets + inputs: + filePath: eng\common\sdk-task.ps1 + arguments: -task PublishBuildAssets -restore -msbuildEngine dotnet + /p:ManifestsPath='$(Build.StagingDirectory)/Download/AssetManifests' + /p:BuildAssetRegistryToken=$(MaestroAccessToken) + /p:MaestroApiEndpoint=https://maestro-prod.westus2.cloudapp.azure.com + /p:PublishUsingPipelines=${{ parameters.publishUsingPipelines }} + /p:OfficialBuildId=$(Build.BuildNumber) + condition: ${{ parameters.condition }} + continueOnError: ${{ parameters.continueOnError }} + + - task: powershell@2 + displayName: Create ReleaseConfigs Artifact + inputs: + targetType: inline + script: | + Add-Content -Path "$(Build.StagingDirectory)/ReleaseConfigs.txt" -Value $(BARBuildId) + Add-Content -Path "$(Build.StagingDirectory)/ReleaseConfigs.txt" -Value "$(DefaultChannels)" + Add-Content -Path "$(Build.StagingDirectory)/ReleaseConfigs.txt" -Value $(IsStableBuild) + + - task: 1ES.PublishBuildArtifacts@1 + displayName: Publish ReleaseConfigs Artifact + inputs: + PathtoPublish: '$(Build.StagingDirectory)/ReleaseConfigs.txt' + PublishLocation: Container + ArtifactName: ReleaseConfigs + + - task: powershell@2 + displayName: Check if SymbolPublishingExclusionsFile.txt exists + inputs: + targetType: inline + script: | + $symbolExclusionfile = "$(Build.SourcesDirectory)/eng/SymbolPublishingExclusionsFile.txt" + if(Test-Path -Path $symbolExclusionfile) + { + Write-Host "SymbolExclusionFile exists" + Write-Host "##vso[task.setvariable variable=SymbolExclusionFile]true" + } + else{ + Write-Host "Symbols Exclusion file does not exists" + Write-Host "##vso[task.setvariable variable=SymbolExclusionFile]false" + } + + - task: 1ES.PublishBuildArtifacts@1 + displayName: Publish SymbolPublishingExclusionsFile Artifact + condition: eq(variables['SymbolExclusionFile'], 'true') + inputs: + PathtoPublish: '$(Build.SourcesDirectory)/eng/SymbolPublishingExclusionsFile.txt' + PublishLocation: Container + ArtifactName: ReleaseConfigs + + - ${{ if eq(parameters.publishAssetsImmediately, 'true') }}: + - template: /eng/common/templates-official/post-build/setup-maestro-vars.yml + parameters: + BARBuildId: ${{ parameters.BARBuildId }} + PromoteToChannelIds: ${{ parameters.PromoteToChannelIds }} + + - task: PowerShell@2 + displayName: Publish Using Darc + inputs: + filePath: $(Build.SourcesDirectory)/eng/common/post-build/publish-using-darc.ps1 + arguments: -BuildId $(BARBuildId) + -PublishingInfraVersion 3 + -AzdoToken '$(publishing-dnceng-devdiv-code-r-build-re)' + -MaestroToken '$(MaestroApiAccessToken)' + -WaitPublishingFinish true + -ArtifactsPublishingAdditionalParameters '${{ parameters.artifactsPublishingAdditionalParameters }}' + -SymbolPublishingAdditionalParameters '${{ parameters.symbolPublishingAdditionalParameters }}' + + - ${{ if eq(parameters.enablePublishBuildArtifacts, 'true') }}: + - template: /eng/common/templates-official/steps/publish-logs.yml + parameters: + JobLabel: 'Publish_Artifacts_Logs' diff --git a/eng/common/templates-official/job/source-build.yml b/eng/common/templates-official/job/source-build.yml new file mode 100644 index 000000000000..8aba3b44bb25 --- /dev/null +++ b/eng/common/templates-official/job/source-build.yml @@ -0,0 +1,67 @@ +parameters: + # This template adds arcade-powered source-build to CI. The template produces a server job with a + # default ID 'Source_Build_Complete' to put in a dependency list if necessary. + + # Specifies the prefix for source-build jobs added to pipeline. Use this if disambiguation needed. + jobNamePrefix: 'Source_Build' + + # Defines the platform on which to run the job. By default, a linux-x64 machine, suitable for + # managed-only repositories. This is an object with these properties: + # + # name: '' + # The name of the job. This is included in the job ID. + # targetRID: '' + # The name of the target RID to use, instead of the one auto-detected by Arcade. + # nonPortable: false + # Enables non-portable mode. This means a more specific RID (e.g. fedora.32-x64 rather than + # linux-x64), and compiling against distro-provided packages rather than portable ones. + # skipPublishValidation: false + # Disables publishing validation. By default, a check is performed to ensure no packages are + # published by source-build. + # container: '' + # A container to use. Runs in docker. + # pool: {} + # A pool to use. Runs directly on an agent. + # buildScript: '' + # Specifies the build script to invoke to perform the build in the repo. The default + # './build.sh' should work for typical Arcade repositories, but this is customizable for + # difficult situations. + # jobProperties: {} + # A list of job properties to inject at the top level, for potential extensibility beyond + # container and pool. + platform: {} + +jobs: +- job: ${{ parameters.jobNamePrefix }}_${{ parameters.platform.name }} + displayName: Source-Build (${{ parameters.platform.name }}) + + ${{ each property in parameters.platform.jobProperties }}: + ${{ property.key }}: ${{ property.value }} + + ${{ if ne(parameters.platform.container, '') }}: + container: ${{ parameters.platform.container }} + + ${{ if eq(parameters.platform.pool, '') }}: + # The default VM host AzDO pool. This should be capable of running Docker containers: almost all + # source-build builds run in Docker, including the default managed platform. + # /eng/common/templates-official/variables/pool-providers.yml can't be used here (some customers declare variables already), so duplicate its logic + pool: + ${{ if eq(variables['System.TeamProject'], 'public') }}: + name: $[replace(replace(eq(contains(coalesce(variables['System.PullRequest.TargetBranch'], variables['Build.SourceBranch'], 'refs/heads/main'), 'release'), 'true'), True, 'NetCore-Svc-Public' ), False, 'NetCore-Public')] + demands: ImageOverride -equals Build.Ubuntu.1804.Amd64.Open + + ${{ if eq(variables['System.TeamProject'], 'internal') }}: + name: $[replace(replace(eq(contains(coalesce(variables['System.PullRequest.TargetBranch'], variables['Build.SourceBranch'], 'refs/heads/main'), 'release'), 'true'), True, 'NetCore1ESPool-Svc-Internal'), False, 'NetCore1ESPool-Internal')] + image: 1es-mariner-2-pt + os: linux + + ${{ if ne(parameters.platform.pool, '') }}: + pool: ${{ parameters.platform.pool }} + + workspace: + clean: all + + steps: + - template: /eng/common/templates-official/steps/source-build.yml + parameters: + platform: ${{ parameters.platform }} diff --git a/eng/common/templates-official/job/source-index-stage1.yml b/eng/common/templates-official/job/source-index-stage1.yml new file mode 100644 index 000000000000..4b6337391708 --- /dev/null +++ b/eng/common/templates-official/job/source-index-stage1.yml @@ -0,0 +1,68 @@ +parameters: + runAsPublic: false + sourceIndexPackageVersion: 1.0.1-20230228.2 + sourceIndexPackageSource: https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-tools/nuget/v3/index.json + sourceIndexBuildCommand: powershell -NoLogo -NoProfile -ExecutionPolicy Bypass -Command "eng/common/build.ps1 -restore -build -binarylog -ci" + preSteps: [] + binlogPath: artifacts/log/Debug/Build.binlog + condition: '' + dependsOn: '' + pool: '' + +jobs: +- job: SourceIndexStage1 + dependsOn: ${{ parameters.dependsOn }} + condition: ${{ parameters.condition }} + variables: + - name: SourceIndexPackageVersion + value: ${{ parameters.sourceIndexPackageVersion }} + - name: SourceIndexPackageSource + value: ${{ parameters.sourceIndexPackageSource }} + - name: BinlogPath + value: ${{ parameters.binlogPath }} + - ${{ if and(eq(parameters.runAsPublic, 'false'), ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest')) }}: + - group: source-dot-net stage1 variables + - template: /eng/common/templates-official/variables/pool-providers.yml + + ${{ if ne(parameters.pool, '') }}: + pool: ${{ parameters.pool }} + ${{ if eq(parameters.pool, '') }}: + pool: + ${{ if eq(variables['System.TeamProject'], 'public') }}: + name: $(DncEngPublicBuildPool) + demands: ImageOverride -equals windows.vs2019.amd64.open + ${{ if eq(variables['System.TeamProject'], 'internal') }}: + name: $(DncEngInternalBuildPool) + image: 1es-windows-2022-pt + os: windows + + steps: + - ${{ each preStep in parameters.preSteps }}: + - ${{ preStep }} + + - task: UseDotNet@2 + displayName: Use .NET Core SDK 6 + inputs: + packageType: sdk + version: 6.0.x + installationPath: $(Agent.TempDirectory)/dotnet + workingDirectory: $(Agent.TempDirectory) + + - script: | + $(Agent.TempDirectory)/dotnet/dotnet tool install BinLogToSln --version $(SourceIndexPackageVersion) --add-source $(SourceIndexPackageSource) --tool-path $(Agent.TempDirectory)/.source-index/tools + $(Agent.TempDirectory)/dotnet/dotnet tool install UploadIndexStage1 --version $(SourceIndexPackageVersion) --add-source $(SourceIndexPackageSource) --tool-path $(Agent.TempDirectory)/.source-index/tools + displayName: Download Tools + # Set working directory to temp directory so 'dotnet' doesn't try to use global.json and use the repo's sdk. + workingDirectory: $(Agent.TempDirectory) + + - script: ${{ parameters.sourceIndexBuildCommand }} + displayName: Build Repository + + - script: $(Agent.TempDirectory)/.source-index/tools/BinLogToSln -i $(BinlogPath) -r $(Build.SourcesDirectory) -n $(Build.Repository.Name) -o .source-index/stage1output + displayName: Process Binlog into indexable sln + + - ${{ if and(eq(parameters.runAsPublic, 'false'), ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest')) }}: + - script: $(Agent.TempDirectory)/.source-index/tools/UploadIndexStage1 -i .source-index/stage1output -n $(Build.Repository.Name) + displayName: Upload stage1 artifacts to source index + env: + BLOB_CONTAINER_URL: $(source-dot-net-stage1-blob-container-url) diff --git a/eng/common/templates-official/jobs/codeql-build.yml b/eng/common/templates-official/jobs/codeql-build.yml new file mode 100644 index 000000000000..b68d3c2f3199 --- /dev/null +++ b/eng/common/templates-official/jobs/codeql-build.yml @@ -0,0 +1,31 @@ +parameters: + # See schema documentation in /Documentation/AzureDevOps/TemplateSchema.md + continueOnError: false + # Required: A collection of jobs to run - https://docs.microsoft.com/en-us/azure/devops/pipelines/yaml-schema?view=vsts&tabs=schema#job + jobs: [] + # Optional: if specified, restore and use this version of Guardian instead of the default. + overrideGuardianVersion: '' + +jobs: +- template: /eng/common/templates-official/jobs/jobs.yml + parameters: + enableMicrobuild: false + enablePublishBuildArtifacts: false + enablePublishTestResults: false + enablePublishBuildAssets: false + enablePublishUsingPipelines: false + enableTelemetry: true + + variables: + - group: Publish-Build-Assets + # The Guardian version specified in 'eng/common/sdl/packages.config'. This value must be kept in + # sync with the packages.config file. + - name: DefaultGuardianVersion + value: 0.109.0 + - name: GuardianPackagesConfigFile + value: $(Build.SourcesDirectory)\eng\common\sdl\packages.config + - name: GuardianVersion + value: ${{ coalesce(parameters.overrideGuardianVersion, '$(DefaultGuardianVersion)') }} + + jobs: ${{ parameters.jobs }} + diff --git a/eng/common/templates-official/jobs/jobs.yml b/eng/common/templates-official/jobs/jobs.yml new file mode 100644 index 000000000000..857a0f8ba43e --- /dev/null +++ b/eng/common/templates-official/jobs/jobs.yml @@ -0,0 +1,97 @@ +parameters: + # See schema documentation in /Documentation/AzureDevOps/TemplateSchema.md + continueOnError: false + + # Optional: Include PublishBuildArtifacts task + enablePublishBuildArtifacts: false + + # Optional: Enable publishing using release pipelines + enablePublishUsingPipelines: false + + # Optional: Enable running the source-build jobs to build repo from source + enableSourceBuild: false + + # Optional: Parameters for source-build template. + # See /eng/common/templates-official/jobs/source-build.yml for options + sourceBuildParameters: [] + + graphFileGeneration: + # Optional: Enable generating the graph files at the end of the build + enabled: false + # Optional: Include toolset dependencies in the generated graph files + includeToolset: false + + # Required: A collection of jobs to run - https://docs.microsoft.com/en-us/azure/devops/pipelines/yaml-schema?view=vsts&tabs=schema#job + jobs: [] + + # Optional: Override automatically derived dependsOn value for "publish build assets" job + publishBuildAssetsDependsOn: '' + + # Optional: Publish the assets as soon as the publish to BAR stage is complete, rather doing so in a separate stage. + publishAssetsImmediately: false + + # Optional: If using publishAssetsImmediately and additional parameters are needed, can be used to send along additional parameters (normally sent to post-build.yml) + artifactsPublishingAdditionalParameters: '' + signingValidationAdditionalParameters: '' + + # Optional: should run as a public build even in the internal project + # if 'true', the build won't run any of the internal only steps, even if it is running in non-public projects. + runAsPublic: false + + enableSourceIndex: false + sourceIndexParams: {} + +# Internal resources (telemetry, microbuild) can only be accessed from non-public projects, +# and some (Microbuild) should only be applied to non-PR cases for internal builds. + +jobs: +- ${{ each job in parameters.jobs }}: + - template: ../job/job.yml + parameters: + # pass along parameters + ${{ each parameter in parameters }}: + ${{ if ne(parameter.key, 'jobs') }}: + ${{ parameter.key }}: ${{ parameter.value }} + + # pass along job properties + ${{ each property in job }}: + ${{ if ne(property.key, 'job') }}: + ${{ property.key }}: ${{ property.value }} + + name: ${{ job.job }} + +- ${{ if eq(parameters.enableSourceBuild, true) }}: + - template: /eng/common/templates-official/jobs/source-build.yml + parameters: + allCompletedJobId: Source_Build_Complete + ${{ each parameter in parameters.sourceBuildParameters }}: + ${{ parameter.key }}: ${{ parameter.value }} + +- ${{ if eq(parameters.enableSourceIndex, 'true') }}: + - template: ../job/source-index-stage1.yml + parameters: + runAsPublic: ${{ parameters.runAsPublic }} + ${{ each parameter in parameters.sourceIndexParams }}: + ${{ parameter.key }}: ${{ parameter.value }} + +- ${{ if and(eq(parameters.runAsPublic, 'false'), ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest')) }}: + - ${{ if or(eq(parameters.enablePublishBuildAssets, true), eq(parameters.artifacts.publish.manifests, 'true'), ne(parameters.artifacts.publish.manifests, '')) }}: + - template: ../job/publish-build-assets.yml + parameters: + continueOnError: ${{ parameters.continueOnError }} + dependsOn: + - ${{ if ne(parameters.publishBuildAssetsDependsOn, '') }}: + - ${{ each job in parameters.publishBuildAssetsDependsOn }}: + - ${{ job.job }} + - ${{ if eq(parameters.publishBuildAssetsDependsOn, '') }}: + - ${{ each job in parameters.jobs }}: + - ${{ job.job }} + - ${{ if eq(parameters.enableSourceBuild, true) }}: + - Source_Build_Complete + + runAsPublic: ${{ parameters.runAsPublic }} + publishUsingPipelines: ${{ parameters.enablePublishUsingPipelines }} + publishAssetsImmediately: ${{ parameters.publishAssetsImmediately }} + enablePublishBuildArtifacts: ${{ parameters.enablePublishBuildArtifacts }} + artifactsPublishingAdditionalParameters: ${{ parameters.artifactsPublishingAdditionalParameters }} + signingValidationAdditionalParameters: ${{ parameters.signingValidationAdditionalParameters }} diff --git a/eng/common/templates-official/jobs/source-build.yml b/eng/common/templates-official/jobs/source-build.yml new file mode 100644 index 000000000000..08e5db9bb116 --- /dev/null +++ b/eng/common/templates-official/jobs/source-build.yml @@ -0,0 +1,46 @@ +parameters: + # This template adds arcade-powered source-build to CI. A job is created for each platform, as + # well as an optional server job that completes when all platform jobs complete. + + # The name of the "join" job for all source-build platforms. If set to empty string, the job is + # not included. Existing repo pipelines can use this job depend on all source-build jobs + # completing without maintaining a separate list of every single job ID: just depend on this one + # server job. By default, not included. Recommended name if used: 'Source_Build_Complete'. + allCompletedJobId: '' + + # See /eng/common/templates-official/job/source-build.yml + jobNamePrefix: 'Source_Build' + + # This is the default platform provided by Arcade, intended for use by a managed-only repo. + defaultManagedPlatform: + name: 'Managed' + container: 'mcr.microsoft.com/dotnet-buildtools/prereqs:centos-stream8' + + # Defines the platforms on which to run build jobs. One job is created for each platform, and the + # object in this array is sent to the job template as 'platform'. If no platforms are specified, + # one job runs on 'defaultManagedPlatform'. + platforms: [] + +jobs: + +- ${{ if ne(parameters.allCompletedJobId, '') }}: + - job: ${{ parameters.allCompletedJobId }} + displayName: Source-Build Complete + pool: server + dependsOn: + - ${{ each platform in parameters.platforms }}: + - ${{ parameters.jobNamePrefix }}_${{ platform.name }} + - ${{ if eq(length(parameters.platforms), 0) }}: + - ${{ parameters.jobNamePrefix }}_${{ parameters.defaultManagedPlatform.name }} + +- ${{ each platform in parameters.platforms }}: + - template: /eng/common/templates-official/job/source-build.yml + parameters: + jobNamePrefix: ${{ parameters.jobNamePrefix }} + platform: ${{ platform }} + +- ${{ if eq(length(parameters.platforms), 0) }}: + - template: /eng/common/templates-official/job/source-build.yml + parameters: + jobNamePrefix: ${{ parameters.jobNamePrefix }} + platform: ${{ parameters.defaultManagedPlatform }} diff --git a/eng/common/templates-official/post-build/common-variables.yml b/eng/common/templates-official/post-build/common-variables.yml new file mode 100644 index 000000000000..c24193acfc98 --- /dev/null +++ b/eng/common/templates-official/post-build/common-variables.yml @@ -0,0 +1,22 @@ +variables: + - group: Publish-Build-Assets + + # Whether the build is internal or not + - name: IsInternalBuild + value: ${{ and(ne(variables['System.TeamProject'], 'public'), contains(variables['Build.SourceBranch'], 'internal')) }} + + # Default Maestro++ API Endpoint and API Version + - name: MaestroApiEndPoint + value: "https://maestro-prod.westus2.cloudapp.azure.com" + - name: MaestroApiAccessToken + value: $(MaestroAccessToken) + - name: MaestroApiVersion + value: "2020-02-20" + + - name: SourceLinkCLIVersion + value: 3.0.0 + - name: SymbolToolVersion + value: 1.0.1 + + - name: runCodesignValidationInjection + value: false diff --git a/eng/common/templates-official/post-build/post-build.yml b/eng/common/templates-official/post-build/post-build.yml new file mode 100644 index 000000000000..5c98fe1c0f3a --- /dev/null +++ b/eng/common/templates-official/post-build/post-build.yml @@ -0,0 +1,285 @@ +parameters: + # Which publishing infra should be used. THIS SHOULD MATCH THE VERSION ON THE BUILD MANIFEST. + # Publishing V1 is no longer supported + # Publishing V2 is no longer supported + # Publishing V3 is the default + - name: publishingInfraVersion + displayName: Which version of publishing should be used to promote the build definition? + type: number + default: 3 + values: + - 3 + + - name: BARBuildId + displayName: BAR Build Id + type: number + default: 0 + + - name: PromoteToChannelIds + displayName: Channel to promote BARBuildId to + type: string + default: '' + + - name: enableSourceLinkValidation + displayName: Enable SourceLink validation + type: boolean + default: false + + - name: enableSigningValidation + displayName: Enable signing validation + type: boolean + default: true + + - name: enableSymbolValidation + displayName: Enable symbol validation + type: boolean + default: false + + - name: enableNugetValidation + displayName: Enable NuGet validation + type: boolean + default: true + + - name: publishInstallersAndChecksums + displayName: Publish installers and checksums + type: boolean + default: true + + - name: SDLValidationParameters + type: object + default: + enable: false + publishGdn: false + continueOnError: false + params: '' + artifactNames: '' + downloadArtifacts: true + + # These parameters let the user customize the call to sdk-task.ps1 for publishing + # symbols & general artifacts as well as for signing validation + - name: symbolPublishingAdditionalParameters + displayName: Symbol publishing additional parameters + type: string + default: '' + + - name: artifactsPublishingAdditionalParameters + displayName: Artifact publishing additional parameters + type: string + default: '' + + - name: signingValidationAdditionalParameters + displayName: Signing validation additional parameters + type: string + default: '' + + # Which stages should finish execution before post-build stages start + - name: validateDependsOn + type: object + default: + - build + + - name: publishDependsOn + type: object + default: + - Validate + + # Optional: Call asset publishing rather than running in a separate stage + - name: publishAssetsImmediately + type: boolean + default: false + +stages: +- ${{ if or(eq( parameters.enableNugetValidation, 'true'), eq(parameters.enableSigningValidation, 'true'), eq(parameters.enableSourceLinkValidation, 'true'), eq(parameters.SDLValidationParameters.enable, 'true')) }}: + - stage: Validate + dependsOn: ${{ parameters.validateDependsOn }} + displayName: Validate Build Assets + variables: + - template: common-variables.yml + - template: /eng/common/templates-official/variables/pool-providers.yml + jobs: + - job: + displayName: NuGet Validation + condition: and(succeededOrFailed(), eq( ${{ parameters.enableNugetValidation }}, 'true')) + pool: + # We don't use the collection uri here because it might vary (.visualstudio.com vs. dev.azure.com) + ${{ if eq(variables['System.TeamProject'], 'DevDiv') }}: + name: AzurePipelines-EO + image: 1ESPT-Windows2022 + demands: Cmd + os: windows + # If it's not devdiv, it's dnceng + ${{ else }}: + name: $(DncEngInternalBuildPool) + image: 1es-windows-2022-pt + os: windows + + steps: + - template: setup-maestro-vars.yml + parameters: + BARBuildId: ${{ parameters.BARBuildId }} + PromoteToChannelIds: ${{ parameters.PromoteToChannelIds }} + + - task: DownloadBuildArtifacts@0 + displayName: Download Package Artifacts + inputs: + buildType: specific + buildVersionToDownload: specific + project: $(AzDOProjectName) + pipeline: $(AzDOPipelineId) + buildId: $(AzDOBuildId) + artifactName: PackageArtifacts + checkDownloadedFiles: true + + - task: PowerShell@2 + displayName: Validate + inputs: + filePath: $(Build.SourcesDirectory)/eng/common/post-build/nuget-validation.ps1 + arguments: -PackagesPath $(Build.ArtifactStagingDirectory)/PackageArtifacts/ + -ToolDestinationPath $(Agent.BuildDirectory)/Extract/ + + - job: + displayName: Signing Validation + condition: and( eq( ${{ parameters.enableSigningValidation }}, 'true'), ne( variables['PostBuildSign'], 'true')) + pool: + # We don't use the collection uri here because it might vary (.visualstudio.com vs. dev.azure.com) + ${{ if eq(variables['System.TeamProject'], 'DevDiv') }}: + name: AzurePipelines-EO + image: 1ESPT-Windows2022 + demands: Cmd + os: windows + # If it's not devdiv, it's dnceng + ${{ else }}: + name: $(DncEngInternalBuildPool) + image: 1es-windows-2022-pt + os: windows + steps: + - template: setup-maestro-vars.yml + parameters: + BARBuildId: ${{ parameters.BARBuildId }} + PromoteToChannelIds: ${{ parameters.PromoteToChannelIds }} + + - task: DownloadBuildArtifacts@0 + displayName: Download Package Artifacts + inputs: + buildType: specific + buildVersionToDownload: specific + project: $(AzDOProjectName) + pipeline: $(AzDOPipelineId) + buildId: $(AzDOBuildId) + artifactName: PackageArtifacts + checkDownloadedFiles: true + itemPattern: | + ** + !**/Microsoft.SourceBuild.Intermediate.*.nupkg + + # This is necessary whenever we want to publish/restore to an AzDO private feed + # Since sdk-task.ps1 tries to restore packages we need to do this authentication here + # otherwise it'll complain about accessing a private feed. + - task: NuGetAuthenticate@1 + displayName: 'Authenticate to AzDO Feeds' + + # Signing validation will optionally work with the buildmanifest file which is downloaded from + # Azure DevOps above. + - task: PowerShell@2 + displayName: Validate + inputs: + filePath: eng\common\sdk-task.ps1 + arguments: -task SigningValidation -restore -msbuildEngine vs + /p:PackageBasePath='$(Build.ArtifactStagingDirectory)/PackageArtifacts' + /p:SignCheckExclusionsFile='$(Build.SourcesDirectory)/eng/SignCheckExclusionsFile.txt' + ${{ parameters.signingValidationAdditionalParameters }} + + - template: ../steps/publish-logs.yml + parameters: + StageLabel: 'Validation' + JobLabel: 'Signing' + BinlogToolVersion: $(BinlogToolVersion) + + - job: + displayName: SourceLink Validation + condition: eq( ${{ parameters.enableSourceLinkValidation }}, 'true') + pool: + # We don't use the collection uri here because it might vary (.visualstudio.com vs. dev.azure.com) + ${{ if eq(variables['System.TeamProject'], 'DevDiv') }}: + name: AzurePipelines-EO + image: 1ESPT-Windows2022 + demands: Cmd + os: windows + # If it's not devdiv, it's dnceng + ${{ else }}: + name: $(DncEngInternalBuildPool) + image: 1es-windows-2022-pt + os: windows + steps: + - template: setup-maestro-vars.yml + parameters: + BARBuildId: ${{ parameters.BARBuildId }} + PromoteToChannelIds: ${{ parameters.PromoteToChannelIds }} + + - task: DownloadBuildArtifacts@0 + displayName: Download Blob Artifacts + inputs: + buildType: specific + buildVersionToDownload: specific + project: $(AzDOProjectName) + pipeline: $(AzDOPipelineId) + buildId: $(AzDOBuildId) + artifactName: BlobArtifacts + checkDownloadedFiles: true + + - task: PowerShell@2 + displayName: Validate + inputs: + filePath: $(Build.SourcesDirectory)/eng/common/post-build/sourcelink-validation.ps1 + arguments: -InputPath $(Build.ArtifactStagingDirectory)/BlobArtifacts/ + -ExtractPath $(Agent.BuildDirectory)/Extract/ + -GHRepoName $(Build.Repository.Name) + -GHCommit $(Build.SourceVersion) + -SourcelinkCliVersion $(SourceLinkCLIVersion) + continueOnError: true + +- ${{ if ne(parameters.publishAssetsImmediately, 'true') }}: + - stage: publish_using_darc + ${{ if or(eq(parameters.enableNugetValidation, 'true'), eq(parameters.enableSigningValidation, 'true'), eq(parameters.enableSourceLinkValidation, 'true'), eq(parameters.SDLValidationParameters.enable, 'true')) }}: + dependsOn: ${{ parameters.publishDependsOn }} + ${{ else }}: + dependsOn: ${{ parameters.validateDependsOn }} + displayName: Publish using Darc + variables: + - template: common-variables.yml + - template: /eng/common/templates-official/variables/pool-providers.yml + jobs: + - job: + displayName: Publish Using Darc + timeoutInMinutes: 120 + pool: + # We don't use the collection uri here because it might vary (.visualstudio.com vs. dev.azure.com) + ${{ if eq(variables['System.TeamProject'], 'DevDiv') }}: + name: AzurePipelines-EO + image: 1ESPT-Windows2022 + demands: Cmd + os: windows + # If it's not devdiv, it's dnceng + ${{ else }}: + name: $(DncEngInternalBuildPool) + image: 1es-windows-2022-pt + os: windows + steps: + - template: setup-maestro-vars.yml + parameters: + BARBuildId: ${{ parameters.BARBuildId }} + PromoteToChannelIds: ${{ parameters.PromoteToChannelIds }} + + - task: NuGetAuthenticate@1 + + - task: PowerShell@2 + displayName: Publish Using Darc + inputs: + filePath: $(Build.SourcesDirectory)/eng/common/post-build/publish-using-darc.ps1 + arguments: -BuildId $(BARBuildId) + -PublishingInfraVersion ${{ parameters.publishingInfraVersion }} + -AzdoToken '$(publishing-dnceng-devdiv-code-r-build-re)' + -MaestroToken '$(MaestroApiAccessToken)' + -WaitPublishingFinish true + -ArtifactsPublishingAdditionalParameters '${{ parameters.artifactsPublishingAdditionalParameters }}' + -SymbolPublishingAdditionalParameters '${{ parameters.symbolPublishingAdditionalParameters }}' diff --git a/eng/common/templates-official/post-build/setup-maestro-vars.yml b/eng/common/templates-official/post-build/setup-maestro-vars.yml new file mode 100644 index 000000000000..0c87f149a4ad --- /dev/null +++ b/eng/common/templates-official/post-build/setup-maestro-vars.yml @@ -0,0 +1,70 @@ +parameters: + BARBuildId: '' + PromoteToChannelIds: '' + +steps: + - ${{ if eq(coalesce(parameters.PromoteToChannelIds, 0), 0) }}: + - task: DownloadBuildArtifacts@0 + displayName: Download Release Configs + inputs: + buildType: current + artifactName: ReleaseConfigs + checkDownloadedFiles: true + + - task: PowerShell@2 + name: setReleaseVars + displayName: Set Release Configs Vars + inputs: + targetType: inline + pwsh: true + script: | + try { + if (!$Env:PromoteToMaestroChannels -or $Env:PromoteToMaestroChannels.Trim() -eq '') { + $Content = Get-Content $(Build.StagingDirectory)/ReleaseConfigs/ReleaseConfigs.txt + + $BarId = $Content | Select -Index 0 + $Channels = $Content | Select -Index 1 + $IsStableBuild = $Content | Select -Index 2 + + $AzureDevOpsProject = $Env:System_TeamProject + $AzureDevOpsBuildDefinitionId = $Env:System_DefinitionId + $AzureDevOpsBuildId = $Env:Build_BuildId + } + else { + $buildApiEndpoint = "${Env:MaestroApiEndPoint}/api/builds/${Env:BARBuildId}?api-version=${Env:MaestroApiVersion}" + + $apiHeaders = New-Object 'System.Collections.Generic.Dictionary[[String],[String]]' + $apiHeaders.Add('Accept', 'application/json') + $apiHeaders.Add('Authorization',"Bearer ${Env:MAESTRO_API_TOKEN}") + + $buildInfo = try { Invoke-WebRequest -Method Get -Uri $buildApiEndpoint -Headers $apiHeaders | ConvertFrom-Json } catch { Write-Host "Error: $_" } + + $BarId = $Env:BARBuildId + $Channels = $Env:PromoteToMaestroChannels -split "," + $Channels = $Channels -join "][" + $Channels = "[$Channels]" + + $IsStableBuild = $buildInfo.stable + $AzureDevOpsProject = $buildInfo.azureDevOpsProject + $AzureDevOpsBuildDefinitionId = $buildInfo.azureDevOpsBuildDefinitionId + $AzureDevOpsBuildId = $buildInfo.azureDevOpsBuildId + } + + Write-Host "##vso[task.setvariable variable=BARBuildId]$BarId" + Write-Host "##vso[task.setvariable variable=TargetChannels]$Channels" + Write-Host "##vso[task.setvariable variable=IsStableBuild]$IsStableBuild" + + Write-Host "##vso[task.setvariable variable=AzDOProjectName]$AzureDevOpsProject" + Write-Host "##vso[task.setvariable variable=AzDOPipelineId]$AzureDevOpsBuildDefinitionId" + Write-Host "##vso[task.setvariable variable=AzDOBuildId]$AzureDevOpsBuildId" + } + catch { + Write-Host $_ + Write-Host $_.Exception + Write-Host $_.ScriptStackTrace + exit 1 + } + env: + MAESTRO_API_TOKEN: $(MaestroApiAccessToken) + BARBuildId: ${{ parameters.BARBuildId }} + PromoteToMaestroChannels: ${{ parameters.PromoteToChannelIds }} diff --git a/eng/common/templates-official/post-build/trigger-subscription.yml b/eng/common/templates-official/post-build/trigger-subscription.yml new file mode 100644 index 000000000000..da669030daf6 --- /dev/null +++ b/eng/common/templates-official/post-build/trigger-subscription.yml @@ -0,0 +1,13 @@ +parameters: + ChannelId: 0 + +steps: +- task: PowerShell@2 + displayName: Triggering subscriptions + inputs: + filePath: $(Build.SourcesDirectory)/eng/common/post-build/trigger-subscriptions.ps1 + arguments: -SourceRepo $(Build.Repository.Uri) + -ChannelId ${{ parameters.ChannelId }} + -MaestroApiAccessToken $(MaestroAccessToken) + -MaestroApiEndPoint $(MaestroApiEndPoint) + -MaestroApiVersion $(MaestroApiVersion) diff --git a/eng/common/templates-official/steps/add-build-to-channel.yml b/eng/common/templates-official/steps/add-build-to-channel.yml new file mode 100644 index 000000000000..f67a210d62f3 --- /dev/null +++ b/eng/common/templates-official/steps/add-build-to-channel.yml @@ -0,0 +1,13 @@ +parameters: + ChannelId: 0 + +steps: +- task: PowerShell@2 + displayName: Add Build to Channel + inputs: + filePath: $(Build.SourcesDirectory)/eng/common/post-build/add-build-to-channel.ps1 + arguments: -BuildId $(BARBuildId) + -ChannelId ${{ parameters.ChannelId }} + -MaestroApiAccessToken $(MaestroApiAccessToken) + -MaestroApiEndPoint $(MaestroApiEndPoint) + -MaestroApiVersion $(MaestroApiVersion) diff --git a/eng/common/templates-official/steps/build-reason.yml b/eng/common/templates-official/steps/build-reason.yml new file mode 100644 index 000000000000..eba58109b52c --- /dev/null +++ b/eng/common/templates-official/steps/build-reason.yml @@ -0,0 +1,12 @@ +# build-reason.yml +# Description: runs steps if build.reason condition is valid. conditions is a string of valid build reasons +# to include steps (',' separated). +parameters: + conditions: '' + steps: [] + +steps: + - ${{ if and( not(startsWith(parameters.conditions, 'not')), contains(parameters.conditions, variables['build.reason'])) }}: + - ${{ parameters.steps }} + - ${{ if and( startsWith(parameters.conditions, 'not'), not(contains(parameters.conditions, variables['build.reason']))) }}: + - ${{ parameters.steps }} diff --git a/eng/common/templates-official/steps/component-governance.yml b/eng/common/templates-official/steps/component-governance.yml new file mode 100644 index 000000000000..0ecec47b0c91 --- /dev/null +++ b/eng/common/templates-official/steps/component-governance.yml @@ -0,0 +1,13 @@ +parameters: + disableComponentGovernance: false + componentGovernanceIgnoreDirectories: '' + +steps: +- ${{ if eq(parameters.disableComponentGovernance, 'true') }}: + - script: "echo ##vso[task.setvariable variable=skipComponentGovernanceDetection]true" + displayName: Set skipComponentGovernanceDetection variable +- ${{ if ne(parameters.disableComponentGovernance, 'true') }}: + - task: ComponentGovernanceComponentDetection@0 + continueOnError: true + inputs: + ignoreDirectories: ${{ parameters.componentGovernanceIgnoreDirectories }} \ No newline at end of file diff --git a/eng/common/templates-official/steps/execute-codeql.yml b/eng/common/templates-official/steps/execute-codeql.yml new file mode 100644 index 000000000000..9b4a5ffa30a7 --- /dev/null +++ b/eng/common/templates-official/steps/execute-codeql.yml @@ -0,0 +1,32 @@ +parameters: + # Language that should be analyzed. Defaults to csharp + language: csharp + # Build Commands + buildCommands: '' + overrideParameters: '' # Optional: to override values for parameters. + additionalParameters: '' # Optional: parameters that need user specific values eg: '-SourceToolsList @("abc","def") -ArtifactToolsList @("ghi","jkl")' + # Optional: if specified, restore and use this version of Guardian instead of the default. + overrideGuardianVersion: '' + # Optional: if true, publish the '.gdn' folder as a pipeline artifact. This can help with in-depth + # diagnosis of problems with specific tool configurations. + publishGuardianDirectoryToPipeline: false + # The script to run to execute all SDL tools. Use this if you want to use a script to define SDL + # parameters rather than relying on YAML. It may be better to use a local script, because you can + # reproduce results locally without piecing together a command based on the YAML. + executeAllSdlToolsScript: 'eng/common/sdl/execute-all-sdl-tools.ps1' + # There is some sort of bug (has been reported) in Azure DevOps where if this parameter is named + # 'continueOnError', the parameter value is not correctly picked up. + # This can also be remedied by the caller (post-build.yml) if it does not use a nested parameter + # optional: determines whether to continue the build if the step errors; + sdlContinueOnError: false + +steps: +- template: /eng/common/templates-official/steps/execute-sdl.yml + parameters: + overrideGuardianVersion: ${{ parameters.overrideGuardianVersion }} + executeAllSdlToolsScript: ${{ parameters.executeAllSdlToolsScript }} + overrideParameters: ${{ parameters.overrideParameters }} + additionalParameters: '${{ parameters.additionalParameters }} + -CodeQLAdditionalRunConfigParams @("BuildCommands < ${{ parameters.buildCommands }}", "Language < ${{ parameters.language }}")' + publishGuardianDirectoryToPipeline: ${{ parameters.publishGuardianDirectoryToPipeline }} + sdlContinueOnError: ${{ parameters.sdlContinueOnError }} \ No newline at end of file diff --git a/eng/common/templates-official/steps/execute-sdl.yml b/eng/common/templates-official/steps/execute-sdl.yml new file mode 100644 index 000000000000..07426fde05d8 --- /dev/null +++ b/eng/common/templates-official/steps/execute-sdl.yml @@ -0,0 +1,88 @@ +parameters: + overrideGuardianVersion: '' + executeAllSdlToolsScript: '' + overrideParameters: '' + additionalParameters: '' + publishGuardianDirectoryToPipeline: false + sdlContinueOnError: false + condition: '' + +steps: +- task: NuGetAuthenticate@1 + inputs: + nuGetServiceConnections: GuardianConnect + +- task: NuGetToolInstaller@1 + displayName: 'Install NuGet.exe' + +- ${{ if ne(parameters.overrideGuardianVersion, '') }}: + - pwsh: | + Set-Location -Path $(Build.SourcesDirectory)\eng\common\sdl + . .\sdl.ps1 + $guardianCliLocation = Install-Gdn -Path $(Build.SourcesDirectory)\.artifacts -Version ${{ parameters.overrideGuardianVersion }} + Write-Host "##vso[task.setvariable variable=GuardianCliLocation]$guardianCliLocation" + displayName: Install Guardian (Overridden) + +- ${{ if eq(parameters.overrideGuardianVersion, '') }}: + - pwsh: | + Set-Location -Path $(Build.SourcesDirectory)\eng\common\sdl + . .\sdl.ps1 + $guardianCliLocation = Install-Gdn -Path $(Build.SourcesDirectory)\.artifacts + Write-Host "##vso[task.setvariable variable=GuardianCliLocation]$guardianCliLocation" + displayName: Install Guardian + +- ${{ if ne(parameters.overrideParameters, '') }}: + - powershell: ${{ parameters.executeAllSdlToolsScript }} ${{ parameters.overrideParameters }} + displayName: Execute SDL (Overridden) + continueOnError: ${{ parameters.sdlContinueOnError }} + condition: ${{ parameters.condition }} + +- ${{ if eq(parameters.overrideParameters, '') }}: + - powershell: ${{ parameters.executeAllSdlToolsScript }} + -GuardianCliLocation $(GuardianCliLocation) + -NugetPackageDirectory $(Build.SourcesDirectory)\.packages + -AzureDevOpsAccessToken $(dn-bot-dotnet-build-rw-code-rw) + ${{ parameters.additionalParameters }} + displayName: Execute SDL + continueOnError: ${{ parameters.sdlContinueOnError }} + condition: ${{ parameters.condition }} + +- ${{ if ne(parameters.publishGuardianDirectoryToPipeline, 'false') }}: + # We want to publish the Guardian results and configuration for easy diagnosis. However, the + # '.gdn' dir is a mix of configuration, results, extracted dependencies, and Guardian default + # tooling files. Some of these files are large and aren't useful during an investigation, so + # exclude them by simply deleting them before publishing. (As of writing, there is no documented + # way to selectively exclude a dir from the pipeline artifact publish task.) + - task: DeleteFiles@1 + displayName: Delete Guardian dependencies to avoid uploading + inputs: + SourceFolder: $(Agent.BuildDirectory)/.gdn + Contents: | + c + i + condition: succeededOrFailed() + + - publish: $(Agent.BuildDirectory)/.gdn + artifact: GuardianConfiguration + displayName: Publish GuardianConfiguration + condition: succeededOrFailed() + + # Publish the SARIF files in a container named CodeAnalysisLogs to enable integration + # with the "SARIF SAST Scans Tab" Azure DevOps extension + - task: CopyFiles@2 + displayName: Copy SARIF files + inputs: + flattenFolders: true + sourceFolder: $(Agent.BuildDirectory)/.gdn/rc/ + contents: '**/*.sarif' + targetFolder: $(Build.SourcesDirectory)/CodeAnalysisLogs + condition: succeededOrFailed() + + # Use PublishBuildArtifacts because the SARIF extension only checks this case + # see microsoft/sarif-azuredevops-extension#4 + - task: PublishBuildArtifacts@1 + displayName: Publish SARIF files to CodeAnalysisLogs container + inputs: + pathToPublish: $(Build.SourcesDirectory)/CodeAnalysisLogs + artifactName: CodeAnalysisLogs + condition: succeededOrFailed() \ No newline at end of file diff --git a/eng/common/templates-official/steps/generate-sbom.yml b/eng/common/templates-official/steps/generate-sbom.yml new file mode 100644 index 000000000000..1bf43bf807af --- /dev/null +++ b/eng/common/templates-official/steps/generate-sbom.yml @@ -0,0 +1,48 @@ +# BuildDropPath - The root folder of the drop directory for which the manifest file will be generated. +# PackageName - The name of the package this SBOM represents. +# PackageVersion - The version of the package this SBOM represents. +# ManifestDirPath - The path of the directory where the generated manifest files will be placed +# IgnoreDirectories - Directories to ignore for SBOM generation. This will be passed through to the CG component detector. + +parameters: + PackageVersion: 8.0.0 + BuildDropPath: '$(Build.SourcesDirectory)/artifacts' + PackageName: '.NET' + ManifestDirPath: $(Build.ArtifactStagingDirectory)/sbom + IgnoreDirectories: '' + sbomContinueOnError: true + +steps: +- task: PowerShell@2 + displayName: Prep for SBOM generation in (Non-linux) + condition: or(eq(variables['Agent.Os'], 'Windows_NT'), eq(variables['Agent.Os'], 'Darwin')) + inputs: + filePath: ./eng/common/generate-sbom-prep.ps1 + arguments: ${{parameters.manifestDirPath}} + +# Chmodding is a workaround for https://github.com/dotnet/arcade/issues/8461 +- script: | + chmod +x ./eng/common/generate-sbom-prep.sh + ./eng/common/generate-sbom-prep.sh ${{parameters.manifestDirPath}} + displayName: Prep for SBOM generation in (Linux) + condition: eq(variables['Agent.Os'], 'Linux') + continueOnError: ${{ parameters.sbomContinueOnError }} + +- task: AzureArtifacts.manifest-generator-task.manifest-generator-task.ManifestGeneratorTask@0 + displayName: 'Generate SBOM manifest' + continueOnError: ${{ parameters.sbomContinueOnError }} + inputs: + PackageName: ${{ parameters.packageName }} + BuildDropPath: ${{ parameters.buildDropPath }} + PackageVersion: ${{ parameters.packageVersion }} + ManifestDirPath: ${{ parameters.manifestDirPath }} + ${{ if ne(parameters.IgnoreDirectories, '') }}: + AdditionalComponentDetectorArgs: '--IgnoreDirectories ${{ parameters.IgnoreDirectories }}' + +- task: 1ES.PublishPipelineArtifact@1 + displayName: Publish SBOM manifest + continueOnError: ${{parameters.sbomContinueOnError}} + inputs: + targetPath: '${{parameters.manifestDirPath}}' + artifactName: $(ARTIFACT_NAME) + diff --git a/eng/common/templates-official/steps/publish-logs.yml b/eng/common/templates-official/steps/publish-logs.yml new file mode 100644 index 000000000000..04012fed182a --- /dev/null +++ b/eng/common/templates-official/steps/publish-logs.yml @@ -0,0 +1,23 @@ +parameters: + StageLabel: '' + JobLabel: '' + +steps: +- task: Powershell@2 + displayName: Prepare Binlogs to Upload + inputs: + targetType: inline + script: | + New-Item -ItemType Directory $(Build.SourcesDirectory)/PostBuildLogs/${{parameters.StageLabel}}/${{parameters.JobLabel}}/ + Move-Item -Path $(Build.SourcesDirectory)/artifacts/log/Debug/* $(Build.SourcesDirectory)/PostBuildLogs/${{parameters.StageLabel}}/${{parameters.JobLabel}}/ + continueOnError: true + condition: always() + +- task: 1ES.PublishBuildArtifacts@1 + displayName: Publish Logs + inputs: + PathtoPublish: '$(Build.SourcesDirectory)/PostBuildLogs' + PublishLocation: Container + ArtifactName: PostBuildLogs + continueOnError: true + condition: always() diff --git a/eng/common/templates-official/steps/retain-build.yml b/eng/common/templates-official/steps/retain-build.yml new file mode 100644 index 000000000000..83d97a26a01f --- /dev/null +++ b/eng/common/templates-official/steps/retain-build.yml @@ -0,0 +1,28 @@ +parameters: + # Optional azure devops PAT with build execute permissions for the build's organization, + # only needed if the build that should be retained ran on a different organization than + # the pipeline where this template is executing from + Token: '' + # Optional BuildId to retain, defaults to the current running build + BuildId: '' + # Azure devops Organization URI for the build in the https://dev.azure.com/ format. + # Defaults to the organization the current pipeline is running on + AzdoOrgUri: '$(System.CollectionUri)' + # Azure devops project for the build. Defaults to the project the current pipeline is running on + AzdoProject: '$(System.TeamProject)' + +steps: + - task: powershell@2 + inputs: + targetType: 'filePath' + filePath: eng/common/retain-build.ps1 + pwsh: true + arguments: > + -AzdoOrgUri: ${{parameters.AzdoOrgUri}} + -AzdoProject ${{parameters.AzdoProject}} + -Token ${{coalesce(parameters.Token, '$env:SYSTEM_ACCESSTOKEN') }} + -BuildId ${{coalesce(parameters.BuildId, '$env:BUILD_ID')}} + displayName: Enable permanent build retention + env: + SYSTEM_ACCESSTOKEN: $(System.AccessToken) + BUILD_ID: $(Build.BuildId) \ No newline at end of file diff --git a/eng/common/templates-official/steps/send-to-helix.yml b/eng/common/templates-official/steps/send-to-helix.yml new file mode 100644 index 000000000000..3eb7e2d5f840 --- /dev/null +++ b/eng/common/templates-official/steps/send-to-helix.yml @@ -0,0 +1,91 @@ +# Please remember to update the documentation if you make changes to these parameters! +parameters: + HelixSource: 'pr/default' # required -- sources must start with pr/, official/, prodcon/, or agent/ + HelixType: 'tests/default/' # required -- Helix telemetry which identifies what type of data this is; should include "test" for clarity and must end in '/' + HelixBuild: $(Build.BuildNumber) # required -- the build number Helix will use to identify this -- automatically set to the AzDO build number + HelixTargetQueues: '' # required -- semicolon-delimited list of Helix queues to test on; see https://helix.dot.net/ for a list of queues + HelixAccessToken: '' # required -- access token to make Helix API requests; should be provided by the appropriate variable group + HelixConfiguration: '' # optional -- additional property attached to a job + HelixPreCommands: '' # optional -- commands to run before Helix work item execution + HelixPostCommands: '' # optional -- commands to run after Helix work item execution + WorkItemDirectory: '' # optional -- a payload directory to zip up and send to Helix; requires WorkItemCommand; incompatible with XUnitProjects + WorkItemCommand: '' # optional -- a command to execute on the payload; requires WorkItemDirectory; incompatible with XUnitProjects + WorkItemTimeout: '' # optional -- a timeout in TimeSpan.Parse-ready value (e.g. 00:02:00) for the work item command; requires WorkItemDirectory; incompatible with XUnitProjects + CorrelationPayloadDirectory: '' # optional -- a directory to zip up and send to Helix as a correlation payload + XUnitProjects: '' # optional -- semicolon-delimited list of XUnitProjects to parse and send to Helix; requires XUnitRuntimeTargetFramework, XUnitPublishTargetFramework, XUnitRunnerVersion, and IncludeDotNetCli=true + XUnitWorkItemTimeout: '' # optional -- the workitem timeout in seconds for all workitems created from the xUnit projects specified by XUnitProjects + XUnitPublishTargetFramework: '' # optional -- framework to use to publish your xUnit projects + XUnitRuntimeTargetFramework: '' # optional -- framework to use for the xUnit console runner + XUnitRunnerVersion: '' # optional -- version of the xUnit nuget package you wish to use on Helix; required for XUnitProjects + IncludeDotNetCli: false # optional -- true will download a version of the .NET CLI onto the Helix machine as a correlation payload; requires DotNetCliPackageType and DotNetCliVersion + DotNetCliPackageType: '' # optional -- either 'sdk', 'runtime' or 'aspnetcore-runtime'; determines whether the sdk or runtime will be sent to Helix; see https://raw.githubusercontent.com/dotnet/core/main/release-notes/releases-index.json + DotNetCliVersion: '' # optional -- version of the CLI to send to Helix; based on this: https://raw.githubusercontent.com/dotnet/core/main/release-notes/releases-index.json + WaitForWorkItemCompletion: true # optional -- true will make the task wait until work items have been completed and fail the build if work items fail. False is "fire and forget." + IsExternal: false # [DEPRECATED] -- doesn't do anything, jobs are external if HelixAccessToken is empty and Creator is set + HelixBaseUri: 'https://helix.dot.net/' # optional -- sets the Helix API base URI (allows targeting https://helix.int-dot.net ) + Creator: '' # optional -- if the build is external, use this to specify who is sending the job + DisplayNamePrefix: 'Run Tests' # optional -- rename the beginning of the displayName of the steps in AzDO + condition: succeeded() # optional -- condition for step to execute; defaults to succeeded() + continueOnError: false # optional -- determines whether to continue the build if the step errors; defaults to false + +steps: + - powershell: 'powershell "$env:BUILD_SOURCESDIRECTORY\eng\common\msbuild.ps1 $env:BUILD_SOURCESDIRECTORY\eng\common\helixpublish.proj /restore /p:TreatWarningsAsErrors=false /t:Test /bl:$env:BUILD_SOURCESDIRECTORY\artifacts\log\$env:BuildConfig\SendToHelix.binlog"' + displayName: ${{ parameters.DisplayNamePrefix }} (Windows) + env: + BuildConfig: $(_BuildConfig) + HelixSource: ${{ parameters.HelixSource }} + HelixType: ${{ parameters.HelixType }} + HelixBuild: ${{ parameters.HelixBuild }} + HelixConfiguration: ${{ parameters.HelixConfiguration }} + HelixTargetQueues: ${{ parameters.HelixTargetQueues }} + HelixAccessToken: ${{ parameters.HelixAccessToken }} + HelixPreCommands: ${{ parameters.HelixPreCommands }} + HelixPostCommands: ${{ parameters.HelixPostCommands }} + WorkItemDirectory: ${{ parameters.WorkItemDirectory }} + WorkItemCommand: ${{ parameters.WorkItemCommand }} + WorkItemTimeout: ${{ parameters.WorkItemTimeout }} + CorrelationPayloadDirectory: ${{ parameters.CorrelationPayloadDirectory }} + XUnitProjects: ${{ parameters.XUnitProjects }} + XUnitWorkItemTimeout: ${{ parameters.XUnitWorkItemTimeout }} + XUnitPublishTargetFramework: ${{ parameters.XUnitPublishTargetFramework }} + XUnitRuntimeTargetFramework: ${{ parameters.XUnitRuntimeTargetFramework }} + XUnitRunnerVersion: ${{ parameters.XUnitRunnerVersion }} + IncludeDotNetCli: ${{ parameters.IncludeDotNetCli }} + DotNetCliPackageType: ${{ parameters.DotNetCliPackageType }} + DotNetCliVersion: ${{ parameters.DotNetCliVersion }} + WaitForWorkItemCompletion: ${{ parameters.WaitForWorkItemCompletion }} + HelixBaseUri: ${{ parameters.HelixBaseUri }} + Creator: ${{ parameters.Creator }} + SYSTEM_ACCESSTOKEN: $(System.AccessToken) + condition: and(${{ parameters.condition }}, eq(variables['Agent.Os'], 'Windows_NT')) + continueOnError: ${{ parameters.continueOnError }} + - script: $BUILD_SOURCESDIRECTORY/eng/common/msbuild.sh $BUILD_SOURCESDIRECTORY/eng/common/helixpublish.proj /restore /p:TreatWarningsAsErrors=false /t:Test /bl:$BUILD_SOURCESDIRECTORY/artifacts/log/$BuildConfig/SendToHelix.binlog + displayName: ${{ parameters.DisplayNamePrefix }} (Unix) + env: + BuildConfig: $(_BuildConfig) + HelixSource: ${{ parameters.HelixSource }} + HelixType: ${{ parameters.HelixType }} + HelixBuild: ${{ parameters.HelixBuild }} + HelixConfiguration: ${{ parameters.HelixConfiguration }} + HelixTargetQueues: ${{ parameters.HelixTargetQueues }} + HelixAccessToken: ${{ parameters.HelixAccessToken }} + HelixPreCommands: ${{ parameters.HelixPreCommands }} + HelixPostCommands: ${{ parameters.HelixPostCommands }} + WorkItemDirectory: ${{ parameters.WorkItemDirectory }} + WorkItemCommand: ${{ parameters.WorkItemCommand }} + WorkItemTimeout: ${{ parameters.WorkItemTimeout }} + CorrelationPayloadDirectory: ${{ parameters.CorrelationPayloadDirectory }} + XUnitProjects: ${{ parameters.XUnitProjects }} + XUnitWorkItemTimeout: ${{ parameters.XUnitWorkItemTimeout }} + XUnitPublishTargetFramework: ${{ parameters.XUnitPublishTargetFramework }} + XUnitRuntimeTargetFramework: ${{ parameters.XUnitRuntimeTargetFramework }} + XUnitRunnerVersion: ${{ parameters.XUnitRunnerVersion }} + IncludeDotNetCli: ${{ parameters.IncludeDotNetCli }} + DotNetCliPackageType: ${{ parameters.DotNetCliPackageType }} + DotNetCliVersion: ${{ parameters.DotNetCliVersion }} + WaitForWorkItemCompletion: ${{ parameters.WaitForWorkItemCompletion }} + HelixBaseUri: ${{ parameters.HelixBaseUri }} + Creator: ${{ parameters.Creator }} + SYSTEM_ACCESSTOKEN: $(System.AccessToken) + condition: and(${{ parameters.condition }}, ne(variables['Agent.Os'], 'Windows_NT')) + continueOnError: ${{ parameters.continueOnError }} diff --git a/eng/common/templates-official/steps/source-build.yml b/eng/common/templates-official/steps/source-build.yml new file mode 100644 index 000000000000..829f17c34d11 --- /dev/null +++ b/eng/common/templates-official/steps/source-build.yml @@ -0,0 +1,129 @@ +parameters: + # This template adds arcade-powered source-build to CI. + + # This is a 'steps' template, and is intended for advanced scenarios where the existing build + # infra has a careful build methodology that must be followed. For example, a repo + # (dotnet/runtime) might choose to clone the GitHub repo only once and store it as a pipeline + # artifact for all subsequent jobs to use, to reduce dependence on a strong network connection to + # GitHub. Using this steps template leaves room for that infra to be included. + + # Defines the platform on which to run the steps. See 'eng/common/templates-official/job/source-build.yml' + # for details. The entire object is described in the 'job' template for simplicity, even though + # the usage of the properties on this object is split between the 'job' and 'steps' templates. + platform: {} + +steps: +# Build. Keep it self-contained for simple reusability. (No source-build-specific job variables.) +- script: | + set -x + df -h + + # If building on the internal project, the artifact feeds variable may be available (usually only if needed) + # In that case, call the feed setup script to add internal feeds corresponding to public ones. + # In addition, add an msbuild argument to copy the WIP from the repo to the target build location. + # This is because SetupNuGetSources.sh will alter the current NuGet.config file, and we need to preserve those + # changes. + internalRestoreArgs= + if [ '$(dn-bot-dnceng-artifact-feeds-rw)' != '$''(dn-bot-dnceng-artifact-feeds-rw)' ]; then + # Temporarily work around https://github.com/dotnet/arcade/issues/7709 + chmod +x $(Build.SourcesDirectory)/eng/common/SetupNugetSources.sh + $(Build.SourcesDirectory)/eng/common/SetupNugetSources.sh $(Build.SourcesDirectory)/NuGet.config $(dn-bot-dnceng-artifact-feeds-rw) + internalRestoreArgs='/p:CopyWipIntoInnerSourceBuildRepo=true' + + # The 'Copy WIP' feature of source build uses git stash to apply changes from the original repo. + # This only works if there is a username/email configured, which won't be the case in most CI runs. + git config --get user.email + if [ $? -ne 0 ]; then + git config user.email dn-bot@microsoft.com + git config user.name dn-bot + fi + fi + + # If building on the internal project, the internal storage variable may be available (usually only if needed) + # In that case, add variables to allow the download of internal runtimes if the specified versions are not found + # in the default public locations. + internalRuntimeDownloadArgs= + if [ '$(dotnetbuilds-internal-container-read-token-base64)' != '$''(dotnetbuilds-internal-container-read-token-base64)' ]; then + internalRuntimeDownloadArgs='/p:DotNetRuntimeSourceFeed=https://dotnetbuilds.blob.core.windows.net/internal /p:DotNetRuntimeSourceFeedKey=$(dotnetbuilds-internal-container-read-token-base64) --runtimesourcefeed https://dotnetbuilds.blob.core.windows.net/internal --runtimesourcefeedkey $(dotnetbuilds-internal-container-read-token-base64)' + fi + + buildConfig=Release + # Check if AzDO substitutes in a build config from a variable, and use it if so. + if [ '$(_BuildConfig)' != '$''(_BuildConfig)' ]; then + buildConfig='$(_BuildConfig)' + fi + + officialBuildArgs= + if [ '${{ and(ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest')) }}' = 'True' ]; then + officialBuildArgs='/p:DotNetPublishUsingPipelines=true /p:OfficialBuildId=$(BUILD.BUILDNUMBER)' + fi + + targetRidArgs= + if [ '${{ parameters.platform.targetRID }}' != '' ]; then + targetRidArgs='/p:TargetRid=${{ parameters.platform.targetRID }}' + fi + + runtimeOsArgs= + if [ '${{ parameters.platform.runtimeOS }}' != '' ]; then + runtimeOsArgs='/p:RuntimeOS=${{ parameters.platform.runtimeOS }}' + fi + + baseOsArgs= + if [ '${{ parameters.platform.baseOS }}' != '' ]; then + baseOsArgs='/p:BaseOS=${{ parameters.platform.baseOS }}' + fi + + publishArgs= + if [ '${{ parameters.platform.skipPublishValidation }}' != 'true' ]; then + publishArgs='--publish' + fi + + assetManifestFileName=SourceBuild_RidSpecific.xml + if [ '${{ parameters.platform.name }}' != '' ]; then + assetManifestFileName=SourceBuild_${{ parameters.platform.name }}.xml + fi + + ${{ coalesce(parameters.platform.buildScript, './build.sh') }} --ci \ + --configuration $buildConfig \ + --restore --build --pack $publishArgs -bl \ + $officialBuildArgs \ + $internalRuntimeDownloadArgs \ + $internalRestoreArgs \ + $targetRidArgs \ + $runtimeOsArgs \ + $baseOsArgs \ + /p:SourceBuildNonPortable=${{ parameters.platform.nonPortable }} \ + /p:ArcadeBuildFromSource=true \ + /p:AssetManifestFileName=$assetManifestFileName + displayName: Build + +# Upload build logs for diagnosis. +- task: CopyFiles@2 + displayName: Prepare BuildLogs staging directory + inputs: + SourceFolder: '$(Build.SourcesDirectory)' + Contents: | + **/*.log + **/*.binlog + artifacts/source-build/self/prebuilt-report/** + TargetFolder: '$(Build.StagingDirectory)/BuildLogs' + CleanTargetFolder: true + continueOnError: true + condition: succeededOrFailed() + +- task: 1ES.PublishPipelineArtifact@1 + displayName: Publish BuildLogs + inputs: + targetPath: '$(Build.StagingDirectory)/BuildLogs' + artifactName: BuildLogs_SourceBuild_${{ parameters.platform.name }}_Attempt$(System.JobAttempt) + continueOnError: true + condition: succeededOrFailed() + +# Manually inject component detection so that we can ignore the source build upstream cache, which contains +# a nupkg cache of input packages (a local feed). +# This path must match the upstream cache path in property 'CurrentRepoSourceBuiltNupkgCacheDir' +# in src\Microsoft.DotNet.Arcade.Sdk\tools\SourceBuild\SourceBuildArcade.targets +- task: ComponentGovernanceComponentDetection@0 + displayName: Component Detection (Exclude upstream cache) + inputs: + ignoreDirectories: '$(Build.SourcesDirectory)/artifacts/source-build/self/src/artifacts/obj/source-built-upstream-cache' diff --git a/eng/common/templates-official/variables/pool-providers.yml b/eng/common/templates-official/variables/pool-providers.yml new file mode 100644 index 000000000000..beab7d1bfba0 --- /dev/null +++ b/eng/common/templates-official/variables/pool-providers.yml @@ -0,0 +1,45 @@ +# Select a pool provider based off branch name. Anything with branch name containing 'release' must go into an -Svc pool, +# otherwise it should go into the "normal" pools. This separates out the queueing and billing of released branches. + +# Motivation: +# Once a given branch of a repository's output has been officially "shipped" once, it is then considered to be COGS +# (Cost of goods sold) and should be moved to a servicing pool provider. This allows both separation of queueing +# (allowing release builds and main PR builds to not intefere with each other) and billing (required for COGS. +# Additionally, the pool provider name itself may be subject to change when the .NET Core Engineering Services +# team needs to move resources around and create new and potentially differently-named pools. Using this template +# file from an Arcade-ified repo helps guard against both having to update one's release/* branches and renaming. + +# How to use: +# This yaml assumes your shipped product branches use the naming convention "release/..." (which many do). +# If we find alternate naming conventions in broad usage it can be added to the condition below. +# +# First, import the template in an arcade-ified repo to pick up the variables, e.g.: +# +# variables: +# - template: /eng/common/templates-official/variables/pool-providers.yml +# +# ... then anywhere specifying the pool provider use the runtime variables, +# $(DncEngInternalBuildPool) +# +# pool: +# name: $(DncEngInternalBuildPool) +# image: 1es-windows-2022-pt + +variables: + # Coalesce the target and source branches so we know when a PR targets a release branch + # If these variables are somehow missing, fall back to main (tends to have more capacity) + + # Any new -Svc alternative pools should have variables added here to allow for splitting work + + - name: DncEngInternalBuildPool + value: $[ + replace( + replace( + eq(contains(coalesce(variables['System.PullRequest.TargetBranch'], variables['Build.SourceBranch'], 'refs/heads/main'), 'release'), 'true'), + True, + 'NetCore1ESPool-Svc-Internal' + ), + False, + 'NetCore1ESPool-Internal' + ) + ] \ No newline at end of file diff --git a/eng/common/templates-official/variables/sdl-variables.yml b/eng/common/templates-official/variables/sdl-variables.yml new file mode 100644 index 000000000000..dbdd66d4a4b3 --- /dev/null +++ b/eng/common/templates-official/variables/sdl-variables.yml @@ -0,0 +1,7 @@ +variables: +# The Guardian version specified in 'eng/common/sdl/packages.config'. This value must be kept in +# sync with the packages.config file. +- name: DefaultGuardianVersion + value: 0.109.0 +- name: GuardianPackagesConfigFile + value: $(Build.SourcesDirectory)\eng\common\sdl\packages.config \ No newline at end of file diff --git a/global.json b/global.json index 882ac53f0b68..02d788dd3799 100644 --- a/global.json +++ b/global.json @@ -14,7 +14,7 @@ } }, "msbuild-sdks": { - "Microsoft.DotNet.Arcade.Sdk": "8.0.0-beta.24123.1", - "Microsoft.DotNet.Helix.Sdk": "8.0.0-beta.24123.1" + "Microsoft.DotNet.Arcade.Sdk": "8.0.0-beta.24151.4", + "Microsoft.DotNet.Helix.Sdk": "8.0.0-beta.24151.4" } } From 539e995f0ab47ea4bc42e08df5fe7be944b12d9d Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" Date: Sun, 3 Mar 2024 13:52:10 +0000 Subject: [PATCH 285/577] Update dependencies from https://github.com/dotnet/msbuild build 20240228.4 Microsoft.SourceBuild.Intermediate.msbuild , Microsoft.Build , Microsoft.Build.Localization From Version 17.10.0-preview-24127-03 -> To Version 17.10.0-preview-24128-04 From a54ba68e21176824a61e7784b9b9a8670dfb6ee3 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" Date: Sun, 3 Mar 2024 13:52:37 +0000 Subject: [PATCH 286/577] Update dependencies from https://github.com/dotnet/fsharp build 20240302.1 Microsoft.SourceBuild.Intermediate.fsharp , Microsoft.FSharp.Compiler From Version 8.0.300-beta.24127.3 -> To Version 8.0.300-beta.24152.1 From c503977197234e23bb49a8f6dc6feb474b18c477 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" Date: Sun, 3 Mar 2024 13:53:03 +0000 Subject: [PATCH 287/577] Update dependencies from https://github.com/dotnet/razor build 20240301.1 Microsoft.AspNetCore.Mvc.Razor.Extensions.Tooling.Internal , Microsoft.CodeAnalysis.Razor.Tooling.Internal , Microsoft.NET.Sdk.Razor.SourceGenerators.Transport From Version 7.0.0-preview.24129.1 -> To Version 7.0.0-preview.24151.1 From a8ade550ebd961f2084bb4de1d923afcfbaef1eb Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" Date: Sun, 3 Mar 2024 13:54:42 +0000 Subject: [PATCH 288/577] Update dependencies from https://github.com/dotnet/roslyn build 20240301.8 Microsoft.CodeAnalysis , Microsoft.CodeAnalysis.CSharp , Microsoft.CodeAnalysis.CSharp.CodeStyle , Microsoft.CodeAnalysis.CSharp.Features , Microsoft.CodeAnalysis.CSharp.Workspaces , Microsoft.CodeAnalysis.Workspaces.MSBuild , Microsoft.Net.Compilers.Toolset From Version 4.10.0-3.24128.4 -> To Version 4.10.0-3.24151.8 From 98d1c55961f386fbc160bbe50c9cfb8a48caca63 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" Date: Sun, 3 Mar 2024 13:56:54 +0000 Subject: [PATCH 289/577] Update dependencies from https://github.com/dotnet/arcade build 20240301.4 Microsoft.DotNet.Arcade.Sdk , Microsoft.DotNet.Helix.Sdk , Microsoft.DotNet.SignTool , Microsoft.DotNet.XUnitExtensions From Version 8.0.0-beta.24123.1 -> To Version 8.0.0-beta.24151.4 From 62ddeec28b616c904e91d761de9f289a8363cc2a Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" Date: Mon, 4 Mar 2024 13:45:02 +0000 Subject: [PATCH 290/577] Update dependencies from https://github.com/dotnet/msbuild build 20240304.1 Microsoft.SourceBuild.Intermediate.msbuild , Microsoft.Build , Microsoft.Build.Localization From Version 17.10.0-preview-24127-03 -> To Version 17.10.0-preview-24154-01 --- eng/Version.Details.xml | 12 ++++++------ eng/Versions.props | 4 ++-- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 524e1d3ffa5c..e0e19a488617 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -51,17 +51,17 @@ https://github.com/dotnet/emsdk 2fc2ffd960930318f33fcaa690cbdbc55d72f52d - + https://github.com/dotnet/msbuild - 9d0238fe435615c5ec96f89a62aedd92242380df + 67f702b535a02be05a696376883bd9cd6d576e38 - + https://github.com/dotnet/msbuild - 9d0238fe435615c5ec96f89a62aedd92242380df + 67f702b535a02be05a696376883bd9cd6d576e38 - + https://github.com/dotnet/msbuild - 9d0238fe435615c5ec96f89a62aedd92242380df + 67f702b535a02be05a696376883bd9cd6d576e38 diff --git a/eng/Versions.props b/eng/Versions.props index 6567c8de418d..88f7c1e6729e 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -120,7 +120,7 @@ - 17.10.0-preview-24128-04 + 17.10.0-preview-24154-01 $(MicrosoftBuildPackageVersion) - 7.0.0-preview.24151.1 - 7.0.0-preview.24151.1 - 7.0.0-preview.24151.1 + 7.0.0-preview.24154.2 + 7.0.0-preview.24154.2 + 7.0.0-preview.24154.2 From 3e658dae5571e3bd18e96163f67e9fe3529784ac Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" Date: Mon, 4 Mar 2024 13:46:04 +0000 Subject: [PATCH 292/577] Update dependencies from https://github.com/dotnet/templating build 20240303.1 Microsoft.TemplateEngine.Abstractions , Microsoft.TemplateEngine.Mocks From Version 8.0.300-preview.24127.3 -> To Version 8.0.300-preview.24153.1 --- eng/Version.Details.xml | 8 ++++---- eng/Versions.props | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 682d5853b6d7..bbabec48cf7f 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -1,14 +1,14 @@ - + https://github.com/dotnet/templating - 99a0910a071fb797f4d92a8d34e8d862003c76f2 + a63f333eb83176754b5023bfa20b2edda8f74798 - + https://github.com/dotnet/templating - 99a0910a071fb797f4d92a8d34e8d862003c76f2 + a63f333eb83176754b5023bfa20b2edda8f74798 https://dev.azure.com/dnceng/internal/_git/dotnet-runtime diff --git a/eng/Versions.props b/eng/Versions.props index 0004647d1240..5de4b472cbb2 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -137,13 +137,13 @@ - 8.0.300-preview.24127.3 + 8.0.300-preview.24153.1 $(MicrosoftTemplateEngineAbstractionsPackageVersion) $(MicrosoftTemplateEngineAbstractionsPackageVersion) $(MicrosoftTemplateEngineAbstractionsPackageVersion) $(MicrosoftTemplateEngineAbstractionsPackageVersion) - 8.0.300-preview.24127.3 + 8.0.300-preview.24153.1 $(MicrosoftTemplateEngineMocksPackageVersion) $(MicrosoftTemplateEngineAbstractionsPackageVersion) $(MicrosoftTemplateEngineMocksPackageVersion) From 5e6f737e8412c59c2b57c854838191a87115a007 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Mon, 4 Mar 2024 21:01:05 +0000 Subject: [PATCH 293/577] [release/8.0.3xx] Disable package aliasing tests (#39183) Co-authored-by: Daniel Plaisted --- eng/build.yml | 3 +++ ...nThatWeHaveAPackageReferenceWithAliases.cs | 25 +++++++++++-------- 2 files changed, 17 insertions(+), 11 deletions(-) diff --git a/eng/build.yml b/eng/build.yml index c4a368faad54..4dac64e70bd4 100644 --- a/eng/build.yml +++ b/eng/build.yml @@ -190,6 +190,7 @@ jobs: log/$(_BuildConfig)/**/* TestResults/$(_BuildConfig)/**/* SymStore/$(_BuildConfig)/**/* + tmp/$(_BuildConfig)/**/*.binlog TargetFolder: '$(Build.ArtifactStagingDirectory)' continueOnError: true condition: always() @@ -321,6 +322,7 @@ jobs: log/$(_BuildConfig)/**/* TestResults/$(_BuildConfig)/**/* SymStore/$(_BuildConfig)/**/* + tmp/$(_BuildConfig)/**/*.binlog TargetFolder: '$(Build.ArtifactStagingDirectory)' continueOnError: true condition: always() @@ -463,6 +465,7 @@ jobs: log/$(_BuildConfig)/**/* TestResults/$(_BuildConfig)/**/* SymStore/$(_BuildConfig)/**/* + tmp/$(_BuildConfig)/**/*.binlog TargetFolder: '$(Build.ArtifactStagingDirectory)' continueOnError: true condition: always() diff --git a/src/Tests/Microsoft.NET.Build.Tests/GivenThatWeHaveAPackageReferenceWithAliases.cs b/src/Tests/Microsoft.NET.Build.Tests/GivenThatWeHaveAPackageReferenceWithAliases.cs index b20f0bcb70df..63ba728b5084 100644 --- a/src/Tests/Microsoft.NET.Build.Tests/GivenThatWeHaveAPackageReferenceWithAliases.cs +++ b/src/Tests/Microsoft.NET.Build.Tests/GivenThatWeHaveAPackageReferenceWithAliases.cs @@ -11,11 +11,11 @@ public class GivenThatWeHaveAPackageReferenceWithAliases : SdkTest public GivenThatWeHaveAPackageReferenceWithAliases(ITestOutputHelper log) : base(log) { } - [RequiresMSBuildVersionFact("16.8.0")] + [RequiresMSBuildVersionFact("16.8.0", Skip = "https://github.com/dotnet/sdk/issues/39172")] public void CanBuildProjectWithPackageReferencesWithConflictingTypes() { var targetFramework = ToolsetInfo.CurrentTargetFramework; - var packageReferences = GetPackageReferencesWithConflictingTypes(targetFramework, packageNames: new string[] { "A", "B" }); + var packageReferences = GetPackageReferencesWithConflictingTypes(targetFramework, packageNames: new string[] { "ConflictingA", "ConflictingB" }); TestProject testProject = new TestProject() { @@ -43,13 +43,14 @@ public void CanBuildProjectWithPackageReferencesWithConflictingTypes() sources.AddRange(packagesPaths); NuGetConfigWriter.Write(testAsset.TestRoot, sources); - var buildCommand = new BuildCommand(testAsset); - buildCommand.Execute() + var buildCommand = new BuildCommand(testAsset) + .WithWorkingDirectory(testAsset.Path); + buildCommand.Execute("-bl") .Should() .Pass(); } - [RequiresMSBuildVersionFact("16.8.0", Skip = "https://github.com/dotnet/sdk/issues/38268")] + [RequiresMSBuildVersionFact("16.8.0", Skip = "https://github.com/dotnet/sdk/issues/39172")] public void CanBuildProjectWithMultiplePackageReferencesWithAliases() { var targetFramework = ToolsetInfo.CurrentTargetFramework; @@ -87,18 +88,19 @@ public void CanBuildProjectWithMultiplePackageReferencesWithAliases() List sources = new List() { NuGetConfigWriter.DotnetCoreBlobFeed, Path.GetDirectoryName(packageReferenceA.NupkgPath), Path.GetDirectoryName(packageReferenceB.NupkgPath) }; NuGetConfigWriter.Write(testAsset.TestRoot, sources); - var buildCommand = new BuildCommand(testAsset); - buildCommand.Execute() + var buildCommand = new BuildCommand(testAsset) + .WithWorkingDirectory(testAsset.Path); + buildCommand.Execute("-bl") .Should() .Pass(); } - [RequiresMSBuildVersionFact("16.8.0")] + [RequiresMSBuildVersionFact("16.8.0", Skip = "https://github.com/dotnet/sdk/issues/39172")] public void CanBuildProjectWithAPackageReferenceWithMultipleAliases() { var targetFramework = ToolsetInfo.CurrentTargetFramework; - var packageReferenceA = GetPackageReference(targetFramework, "A", ClassLibMultipleClasses); + var packageReferenceA = GetPackageReference(targetFramework, "MultipleClasses", ClassLibMultipleClasses); TestProject testProject = new TestProject() { @@ -123,8 +125,9 @@ public void CanBuildProjectWithAPackageReferenceWithMultipleAliases() List sources = new List() { NuGetConfigWriter.DotnetCoreBlobFeed, Path.GetDirectoryName(packageReferenceA.NupkgPath) }; NuGetConfigWriter.Write(testAsset.TestRoot, sources); - var buildCommand = new BuildCommand(testAsset); - buildCommand.Execute() + var buildCommand = new BuildCommand(testAsset) + .WithWorkingDirectory(testAsset.Path); + buildCommand.Execute("-bl") .Should() .Pass(); } From edcf1972a6e237c8e93bd225125d5262f9e864d3 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" Date: Tue, 5 Mar 2024 13:54:16 +0000 Subject: [PATCH 294/577] Update dependencies from https://github.com/dotnet/msbuild build 20240305.2 Microsoft.SourceBuild.Intermediate.msbuild , Microsoft.Build , Microsoft.Build.Localization From Version 17.10.0-preview-24127-03 -> To Version 17.10.0-preview-24155-02 --- eng/Version.Details.xml | 12 ++++++------ eng/Versions.props | 4 ++-- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index e0e19a488617..3e8e9eb10983 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -51,17 +51,17 @@ https://github.com/dotnet/emsdk 2fc2ffd960930318f33fcaa690cbdbc55d72f52d - + https://github.com/dotnet/msbuild - 67f702b535a02be05a696376883bd9cd6d576e38 + 936d9316dbeaab79eec4df06924113c17e385590 - + https://github.com/dotnet/msbuild - 67f702b535a02be05a696376883bd9cd6d576e38 + 936d9316dbeaab79eec4df06924113c17e385590 - + https://github.com/dotnet/msbuild - 67f702b535a02be05a696376883bd9cd6d576e38 + 936d9316dbeaab79eec4df06924113c17e385590 diff --git a/eng/Versions.props b/eng/Versions.props index 88f7c1e6729e..46c3d11ee7fb 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -120,7 +120,7 @@ - 17.10.0-preview-24154-01 + 17.10.0-preview-24155-02 $(MicrosoftBuildPackageVersion) - 12.8.300-beta.24152.1 + 12.8.300-beta.24154.4 From b30973704923f287cedb5512f4a4175c6f7cbaac Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Wed, 6 Mar 2024 00:39:03 +0000 Subject: [PATCH 304/577] [release/8.0.3xx] Update dependencies from dotnet/razor (#39210) [release/8.0.3xx] Update dependencies from dotnet/razor --- eng/Version.Details.xml | 12 ++++++------ eng/Versions.props | 6 +++--- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index e5c0f6c152dc..cb3421805973 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -277,18 +277,18 @@ https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore da7e9894ce22ef8cc02e5acc56e95a6f8cf8f644 - + https://github.com/dotnet/razor - 6256b82c2cacd2a46cf9fdc8e3de6fa4fabe64f4 + c126dfc208bca863b378ae32f8c5cd3f271cbff6 - + https://github.com/dotnet/razor - 6256b82c2cacd2a46cf9fdc8e3de6fa4fabe64f4 + c126dfc208bca863b378ae32f8c5cd3f271cbff6 - + https://github.com/dotnet/razor - 6256b82c2cacd2a46cf9fdc8e3de6fa4fabe64f4 + c126dfc208bca863b378ae32f8c5cd3f271cbff6 https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore diff --git a/eng/Versions.props b/eng/Versions.props index 8f059e1e3d76..6d32b3ef8a69 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -175,9 +175,9 @@ - 7.0.0-preview.24154.2 - 7.0.0-preview.24154.2 - 7.0.0-preview.24154.2 + 7.0.0-preview.24154.9 + 7.0.0-preview.24154.9 + 7.0.0-preview.24154.9 From ea5aa246199e66d74b7c6b9c77ff4708f24e5b9b Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Wed, 6 Mar 2024 00:39:17 +0000 Subject: [PATCH 305/577] [release/8.0.3xx] Update dependencies from dotnet/roslyn (#39211) [release/8.0.3xx] Update dependencies from dotnet/roslyn --- eng/Version.Details.xml | 28 ++++++++++++++-------------- eng/Versions.props | 14 +++++++------- 2 files changed, 21 insertions(+), 21 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index cb3421805973..7bdd0b30614a 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -78,34 +78,34 @@ ac0d85557969d51bca72181514ddb7d5796fbbe2 - + https://github.com/dotnet/roslyn - 8537440d8c831b8533a18f6530945ee91c243e1b + c88057e6c3be0d2b85b33e8e3cfb481f5d1d504b - + https://github.com/dotnet/roslyn - 8537440d8c831b8533a18f6530945ee91c243e1b + c88057e6c3be0d2b85b33e8e3cfb481f5d1d504b - + https://github.com/dotnet/roslyn - 8537440d8c831b8533a18f6530945ee91c243e1b + c88057e6c3be0d2b85b33e8e3cfb481f5d1d504b - + https://github.com/dotnet/roslyn - 8537440d8c831b8533a18f6530945ee91c243e1b + c88057e6c3be0d2b85b33e8e3cfb481f5d1d504b - + https://github.com/dotnet/roslyn - 8537440d8c831b8533a18f6530945ee91c243e1b + c88057e6c3be0d2b85b33e8e3cfb481f5d1d504b - + https://github.com/dotnet/roslyn - 8537440d8c831b8533a18f6530945ee91c243e1b + c88057e6c3be0d2b85b33e8e3cfb481f5d1d504b - + https://github.com/dotnet/roslyn - 8537440d8c831b8533a18f6530945ee91c243e1b + c88057e6c3be0d2b85b33e8e3cfb481f5d1d504b https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore diff --git a/eng/Versions.props b/eng/Versions.props index 6d32b3ef8a69..7c4e8fe9e50f 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -154,13 +154,13 @@ - 4.10.0-3.24151.8 - 4.10.0-3.24151.8 - 4.10.0-3.24151.8 - 4.10.0-3.24151.8 - 4.10.0-3.24151.8 - 4.10.0-3.24151.8 - 4.10.0-3.24151.8 + 4.10.0-3.24155.1 + 4.10.0-3.24155.1 + 4.10.0-3.24155.1 + 4.10.0-3.24155.1 + 4.10.0-3.24155.1 + 4.10.0-3.24155.1 + 4.10.0-3.24155.1 $(MicrosoftNetCompilersToolsetPackageVersion) From cfbab3f0bb1e44a6a60091d222521ae05cd06c93 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" Date: Wed, 6 Mar 2024 13:46:45 +0000 Subject: [PATCH 306/577] Update dependencies from https://github.com/dotnet/msbuild build 20240306.1 Microsoft.SourceBuild.Intermediate.msbuild , Microsoft.Build , Microsoft.Build.Localization From Version 17.10.0-preview-24127-03 -> To Version 17.10.0-preview-24156-01 --- eng/Version.Details.xml | 12 ++++++------ eng/Versions.props | 4 ++-- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 3e8e9eb10983..b580912e9296 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -51,17 +51,17 @@ https://github.com/dotnet/emsdk 2fc2ffd960930318f33fcaa690cbdbc55d72f52d - + https://github.com/dotnet/msbuild - 936d9316dbeaab79eec4df06924113c17e385590 + 5089df85a739c170a6c3ab0493bd2c17b36d81d4 - + https://github.com/dotnet/msbuild - 936d9316dbeaab79eec4df06924113c17e385590 + 5089df85a739c170a6c3ab0493bd2c17b36d81d4 - + https://github.com/dotnet/msbuild - 936d9316dbeaab79eec4df06924113c17e385590 + 5089df85a739c170a6c3ab0493bd2c17b36d81d4 diff --git a/eng/Versions.props b/eng/Versions.props index 46c3d11ee7fb..113be455f8c6 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -120,7 +120,7 @@ - 17.10.0-preview-24155-02 + 17.10.0-preview-24156-01 $(MicrosoftBuildPackageVersion) - 4.10.0-3.24155.1 - 4.10.0-3.24155.1 - 4.10.0-3.24155.1 - 4.10.0-3.24155.1 - 4.10.0-3.24155.1 - 4.10.0-3.24155.1 - 4.10.0-3.24155.1 + 4.10.0-3.24155.13 + 4.10.0-3.24155.13 + 4.10.0-3.24155.13 + 4.10.0-3.24155.13 + 4.10.0-3.24155.13 + 4.10.0-3.24155.13 + 4.10.0-3.24155.13 $(MicrosoftNetCompilersToolsetPackageVersion) From 6c1ba2f2a0abedfd5969afc38bc4ebc16531336d Mon Sep 17 00:00:00 2001 From: Chet Husk Date: Wed, 6 Mar 2024 09:59:55 -0600 Subject: [PATCH 308/577] Trim trailing .git from sourcelink repo urls in container generation (#39161) --- .../Microsoft.NET.Build.Containers.targets | 11 +++++--- .../TargetsTests.cs | 25 +++++++++++++++++++ 2 files changed, 33 insertions(+), 3 deletions(-) diff --git a/src/Containers/packaging/build/Microsoft.NET.Build.Containers.targets b/src/Containers/packaging/build/Microsoft.NET.Build.Containers.targets index ff0b034dba94..ecb8dee489c7 100644 --- a/src/Containers/packaging/build/Microsoft.NET.Build.Containers.targets +++ b/src/Containers/packaging/build/Microsoft.NET.Build.Containers.targets @@ -35,13 +35,13 @@ Returns="$(ContainerBaseImage)"> + For builds that have a RID, we default to that RID. Otherwise, we default to the Linux RID matching the architecture of the currently-executing SDK. --> $(RuntimeIdentifier) linux-$(NETCoreSdkPortableRuntimeIdentifier.Split('-')[1]) <_ContainerIsUsingMicrosoftDefaultImages Condition="'$(ContainerBaseImage)' == ''">true <_ContainerIsUsingMicrosoftDefaultImages Condition="'$(ContainerBaseImage)' != ''">false - + + + + <_TrimmedRepositoryUrl Condition="'$(RepositoryType)' == 'git' and '$(PrivateRepositoryUrl)' != '' and $(PrivateRepositoryUrl.EndsWith('.git'))">$(PrivateRepositoryUrl.Substring(0, $(PrivateRepositoryUrl.LastIndexOf('.git')))) + <_TrimmedRepositoryUrl Condition="'$(_TrimmedRepositoryUrl)' == '' and '$(PrivateRepositoryUrl)' != ''">$(PrivateRepositoryUrl) + - + diff --git a/src/Tests/Microsoft.NET.Build.Containers.IntegrationTests/TargetsTests.cs b/src/Tests/Microsoft.NET.Build.Containers.IntegrationTests/TargetsTests.cs index 88aa4498356d..a00f2fd47554 100644 --- a/src/Tests/Microsoft.NET.Build.Containers.IntegrationTests/TargetsTests.cs +++ b/src/Tests/Microsoft.NET.Build.Containers.IntegrationTests/TargetsTests.cs @@ -150,6 +150,31 @@ public void ShouldNotIncludeSourceControlLabelsUnlessUserOptsIn(bool includeSour }; } + [InlineData("https://git.cosmere.com/shard/whimsy.git", "https://git.cosmere.com/shard/whimsy")] + [InlineData("https://repos.git.cosmere.com/shard/whimsy.git", "https://repos.git.cosmere.com/shard/whimsy")] + [Theory] + public void ShouldTrimTrailingGitSuffixFromRepoUrls(string repoUrl, string expectedLabel) + { + var commitHash = "abcdef"; + + static string NormalizeString(string s) => s.Replace(':', '_').Replace('/', '_'); + + var (project, logger, d) = ProjectInitializer.InitProject(new() + { + ["PublishRepositoryUrl"] = true.ToString(), + ["PrivateRepositoryUrl"] = repoUrl, + ["SourceRevisionId"] = commitHash, + ["RepositoryType"] = "git" + }, projectName: $"{nameof(ShouldNotIncludeSourceControlLabelsUnlessUserOptsIn)}_{NormalizeString(repoUrl)}_{NormalizeString(expectedLabel)}"); + using var _ = d; + var instance = project.CreateProjectInstance(global::Microsoft.Build.Execution.ProjectInstanceSettings.None); + instance.Build(new[] { ComputeContainerConfig }, new[] { logger }, null, out var outputs).Should().BeTrue("Build should have succeeded but failed due to {0}", String.Join("\n", logger.AllMessages)); + var labels = instance.GetItems(ContainerLabel); + + labels.Should().NotBeEmpty("Should have evaluated some labels by default") + .And.ContainSingle(label => LabelMatch("org.opencontainers.image.source", expectedLabel, label), String.Join(",", logger.AllMessages)); + } + [InlineData("7.0.100", "v7.0", "7.0")] [InlineData("7.0.100-preview.7", "v7.0", "7.0")] [InlineData("7.0.100-rc.1", "v7.0", "7.0")] From c1376fe68070236da2e36d472ed96090f4e73609 Mon Sep 17 00:00:00 2001 From: Chet Husk Date: Sat, 2 Mar 2024 21:42:28 -0600 Subject: [PATCH 309/577] Create a new label with the base image's digest when publishing --- .../ContainerBuilder.cs | 17 +++++++++-- .../ImageBuilder.cs | 5 ++++ .../PublicAPI/net472/PublicAPI.Unshipped.txt | 4 +++ .../PublicAPI/net8.0/PublicAPI.Unshipped.txt | 6 +++- .../Tasks/CreateNewImage.Interface.cs | 18 ++++++++++++ .../Tasks/CreateNewImage.cs | 12 ++++++-- .../Tasks/CreateNewImageToolTask.cs | 22 +++++++++++---- .../containerize/ContainerizeCommand.cs | 20 ++++++++++++- .../Microsoft.NET.Build.Containers.targets | 4 ++- .../CreateNewImageToolTaskTests.cs | 28 +++++++++++++++++++ 10 files changed, 122 insertions(+), 14 deletions(-) diff --git a/src/Containers/Microsoft.NET.Build.Containers/ContainerBuilder.cs b/src/Containers/Microsoft.NET.Build.Containers/ContainerBuilder.cs index c9a84b8a95d4..55a8af83ccff 100644 --- a/src/Containers/Microsoft.NET.Build.Containers/ContainerBuilder.cs +++ b/src/Containers/Microsoft.NET.Build.Containers/ContainerBuilder.cs @@ -31,6 +31,8 @@ public static async Task ContainerizeAsync( string localRegistry, string? containerUser, string? archiveOutputPath, + bool generateLabels, + bool generateDigestLabel, ILoggerFactory loggerFactory, CancellationToken cancellationToken) { @@ -124,11 +126,20 @@ public static async Task ContainerizeAsync( } imageBuilder.SetEntrypointAndCmd(imageEntrypoint, imageCmd); - foreach (KeyValuePair label in labels) + if (generateLabels) { - // labels are validated by System.CommandLine API - imageBuilder.AddLabel(label.Key, label.Value); + foreach (KeyValuePair label in labels) + { + // labels are validated by System.CommandLine API + imageBuilder.AddLabel(label.Key, label.Value); + } + + if (generateDigestLabel) + { + imageBuilder.AddBaseImageDigestLabel(); + } } + foreach (KeyValuePair envVar in envVars) { imageBuilder.AddEnvironmentVariable(envVar.Key, envVar.Value); diff --git a/src/Containers/Microsoft.NET.Build.Containers/ImageBuilder.cs b/src/Containers/Microsoft.NET.Build.Containers/ImageBuilder.cs index 7bfdcb809962..3a8d8a50315e 100644 --- a/src/Containers/Microsoft.NET.Build.Containers/ImageBuilder.cs +++ b/src/Containers/Microsoft.NET.Build.Containers/ImageBuilder.cs @@ -87,6 +87,11 @@ internal void AddLayer(Layer l) _baseImageConfig.AddLayer(l); } + internal void AddBaseImageDigestLabel() + { + AddLabel("org.opencontainers.image.base.digest", _manifest.GetDigest()); + } + /// /// Adds a label to a base image. /// 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 index 89caa7583181..dbe4406eb596 100644 --- a/src/Containers/Microsoft.NET.Build.Containers/PublicAPI/net472/PublicAPI.Unshipped.txt +++ b/src/Containers/Microsoft.NET.Build.Containers/PublicAPI/net472/PublicAPI.Unshipped.txt @@ -77,6 +77,10 @@ Microsoft.NET.Build.Containers.Tasks.CreateNewImage.RuntimeIdentifierGraphPath.g 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 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! diff --git a/src/Containers/Microsoft.NET.Build.Containers/PublicAPI/net8.0/PublicAPI.Unshipped.txt b/src/Containers/Microsoft.NET.Build.Containers/PublicAPI/net8.0/PublicAPI.Unshipped.txt index 3b6d27ca2c1e..77eb129a0421 100644 --- a/src/Containers/Microsoft.NET.Build.Containers/PublicAPI/net8.0/PublicAPI.Unshipped.txt +++ b/src/Containers/Microsoft.NET.Build.Containers/PublicAPI/net8.0/PublicAPI.Unshipped.txt @@ -13,7 +13,7 @@ Microsoft.NET.Build.Containers.Tasks.ComputeDotnetBaseImageAndTag.TargetRuntimeI Microsoft.NET.Build.Containers.Tasks.ComputeDotnetBaseImageAndTag.TargetRuntimeIdentifier.set -> void Microsoft.NET.Build.Containers.Tasks.ComputeDotnetBaseImageAndTag.UsesInvariantGlobalization.get -> bool Microsoft.NET.Build.Containers.Tasks.ComputeDotnetBaseImageAndTag.UsesInvariantGlobalization.set -> void -static Microsoft.NET.Build.Containers.ContainerBuilder.ContainerizeAsync(System.IO.DirectoryInfo! publishDirectory, string! workingDir, string! baseRegistry, string! baseImageName, string! baseImageTag, string![]! entrypoint, string![]! entrypointArgs, string![]! defaultArgs, string![]! appCommand, string![]! appCommandArgs, string! appCommandInstruction, string! imageName, string![]! imageTags, string? outputRegistry, System.Collections.Generic.Dictionary! labels, Microsoft.NET.Build.Containers.Port[]? exposedPorts, System.Collections.Generic.Dictionary! envVars, string! containerRuntimeIdentifier, string! ridGraphPath, string! localRegistry, string? containerUser, string? archiveOutputPath, Microsoft.Extensions.Logging.ILoggerFactory! loggerFactory, System.Threading.CancellationToken cancellationToken) -> System.Threading.Tasks.Task! +static Microsoft.NET.Build.Containers.ContainerBuilder.ContainerizeAsync(System.IO.DirectoryInfo! publishDirectory, string! workingDir, string! baseRegistry, string! baseImageName, string! baseImageTag, string![]! entrypoint, string![]! entrypointArgs, string![]! defaultArgs, string![]! appCommand, string![]! appCommandArgs, string! appCommandInstruction, string! imageName, string![]! imageTags, string? outputRegistry, System.Collections.Generic.Dictionary! labels, Microsoft.NET.Build.Containers.Port[]? exposedPorts, System.Collections.Generic.Dictionary! envVars, string! containerRuntimeIdentifier, string! ridGraphPath, string! localRegistry, string? containerUser, string? archiveOutputPath, bool generateLabels, bool generateDigestLabel, Microsoft.Extensions.Logging.ILoggerFactory! loggerFactory, System.Threading.CancellationToken cancellationToken) -> System.Threading.Tasks.Task! static readonly Microsoft.NET.Build.Containers.Constants.Version -> string! Microsoft.NET.Build.Containers.ContainerBuilder Microsoft.NET.Build.Containers.ContainerHelpers @@ -192,6 +192,10 @@ 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 +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.ParseContainerProperties Microsoft.NET.Build.Containers.Tasks.ParseContainerProperties.ContainerEnvironmentVariables.get -> Microsoft.Build.Framework.ITaskItem![]! Microsoft.NET.Build.Containers.Tasks.ParseContainerProperties.ContainerEnvironmentVariables.set -> void 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 51944549cba4..4c806dba08b6 100644 --- a/src/Containers/Microsoft.NET.Build.Containers/Tasks/CreateNewImage.Interface.cs +++ b/src/Containers/Microsoft.NET.Build.Containers/Tasks/CreateNewImage.Interface.cs @@ -146,6 +146,21 @@ partial class CreateNewImage /// public string ContainerUser { get; set; } + /// + /// If true, the tooling may create labels on the generated images. + /// + [Required] + public bool GenerateLabels { get; set; } + + /// + /// If true, the tooling will generate an 'org.opencontainers.image.base.digest' label on the generated images containing the digest of the chosen base image. + /// + /// + /// Normally this would have been handled in the container targets, but we do not currently _fetch_ the digest of the base image in pure MSBuild, so we do it during generation-time. + /// + [Required] + public bool GenerateDigestLabel { get; set; } + [Output] public string GeneratedContainerManifest { get; set; } @@ -191,6 +206,9 @@ public CreateNewImage() GeneratedContainerDigest = ""; GeneratedArchiveOutputPath = ""; + GenerateLabels = false; + GenerateDigestLabel = false; + TaskResources = Resource.Manager; } } diff --git a/src/Containers/Microsoft.NET.Build.Containers/Tasks/CreateNewImage.cs b/src/Containers/Microsoft.NET.Build.Containers/Tasks/CreateNewImage.cs index 3779a49f1112..d680e3246ab4 100644 --- a/src/Containers/Microsoft.NET.Build.Containers/Tasks/CreateNewImage.cs +++ b/src/Containers/Microsoft.NET.Build.Containers/Tasks/CreateNewImage.cs @@ -120,9 +120,17 @@ internal async Task ExecuteAsync(CancellationToken cancellationToken) (string[] entrypoint, string[] cmd) = DetermineEntrypointAndCmd(baseImageEntrypoint: imageBuilder.BaseImageConfig.GetEntrypoint()); imageBuilder.SetEntrypointAndCmd(entrypoint, cmd); - foreach (ITaskItem label in Labels) + if (GenerateLabels) { - imageBuilder.AddLabel(label.ItemSpec, label.GetMetadata("Value")); + foreach (ITaskItem label in Labels) + { + imageBuilder.AddLabel(label.ItemSpec, label.GetMetadata("Value")); + } + + if (GenerateDigestLabel) + { + imageBuilder.AddBaseImageDigestLabel(); + } } SetEnvironmentVariables(imageBuilder, ContainerEnvironmentVariables); diff --git a/src/Containers/Microsoft.NET.Build.Containers/Tasks/CreateNewImageToolTask.cs b/src/Containers/Microsoft.NET.Build.Containers/Tasks/CreateNewImageToolTask.cs index 6189d3d74d4e..51869ccb6c54 100644 --- a/src/Containers/Microsoft.NET.Build.Containers/Tasks/CreateNewImageToolTask.cs +++ b/src/Containers/Microsoft.NET.Build.Containers/Tasks/CreateNewImageToolTask.cs @@ -120,11 +120,11 @@ internal string GenerateCommandLineCommandsInt() builder.AppendSwitchIfNotNull("--appcommandinstruction ", AppCommandInstruction); } - AppendSwitchIfNotNullSantized(builder, "--entrypoint ", nameof(Entrypoint), Entrypoint); - AppendSwitchIfNotNullSantized(builder, "--entrypointargs ", nameof(EntrypointArgs), EntrypointArgs); - AppendSwitchIfNotNullSantized(builder, "--defaultargs ", nameof(DefaultArgs), DefaultArgs); - AppendSwitchIfNotNullSantized(builder, "--appcommand ", nameof(AppCommand), AppCommand); - AppendSwitchIfNotNullSantized(builder, "--appcommandargs ", nameof(AppCommandArgs), AppCommandArgs); + 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))) { @@ -192,9 +192,19 @@ internal string GenerateCommandLineCommandsInt() builder.AppendSwitchIfNotNull("--archiveoutputpath ", ArchiveOutputPath); } + if (GenerateLabels) + { + builder.AppendSwitch("--generate-labels"); + } + + if (GenerateDigestLabel) + { + builder.AppendSwitch("--generate-digest-label"); + } + return builder.ToString(); - void AppendSwitchIfNotNullSantized(CommandLineBuilder builder, string commandArgName, string propertyName, ITaskItem[] value) + 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) diff --git a/src/Containers/containerize/ContainerizeCommand.cs b/src/Containers/containerize/ContainerizeCommand.cs index 7a64e403a0e7..52b7e390b503 100644 --- a/src/Containers/containerize/ContainerizeCommand.cs +++ b/src/Containers/containerize/ContainerizeCommand.cs @@ -23,7 +23,7 @@ internal class ContainerizeCommand : CliRootCommand Required = true }; - internal CliOption BaseImageNameOption { get; } = new("--baseimagename") + internal CliOption BaseImageNameOption { get; } = new("--baseimagename") { Description = "The base image to pull.", Required = true @@ -185,6 +185,18 @@ internal class ContainerizeCommand : CliRootCommand internal CliOption ContainerUserOption { get; } = new("--container-user") { Description = "User to run the container as." }; + internal CliOption GenerateLabelsOption { get; } = new("--generate-labels") + { + Description = "If true, the tooling may create labels on the generated images.", + Arity = ArgumentArity.Zero + }; + + internal CliOption GenerateDigestLabelOption { get; } = new("--generate-digest-label") + { + Description = "If true, the tooling will generate an 'org.opencontainers.image.base.digest' label on the generated images containing the digest of the chosen base image.", + Arity = ArgumentArity.Zero + }; + internal ContainerizeCommand() : base("Containerize an application without Docker.") { PublishDirectoryArgument.AcceptLegalFilePathsOnly(); @@ -211,6 +223,8 @@ internal ContainerizeCommand() : base("Containerize an application without Docke LocalRegistryOption.AcceptOnlyFromAmong(KnownLocalRegistryTypes.SupportedLocalRegistryTypes); this.Options.Add(LocalRegistryOption); this.Options.Add(ContainerUserOption); + this.Options.Add(GenerateLabelsOption); + this.Options.Add(GenerateDigestLabelOption); this.SetAction(async (parseResult, cancellationToken) => { @@ -236,6 +250,8 @@ internal ContainerizeCommand() : base("Containerize an application without Docke string _ridGraphPath = parseResult.GetValue(RidGraphPathOption)!; string _localContainerDaemon = parseResult.GetValue(LocalRegistryOption)!; string? _containerUser = parseResult.GetValue(ContainerUserOption); + bool _generateLabels = parseResult.GetValue(GenerateLabelsOption); + bool _generateDigestLabel = parseResult.GetValue(GenerateDigestLabelOption); //setup basic logging bool traceEnabled = Env.GetEnvironmentVariableAsBool("CONTAINERIZE_TRACE_LOGGING_ENABLED"); @@ -265,6 +281,8 @@ await ContainerBuilder.ContainerizeAsync( _localContainerDaemon, _containerUser, _archiveOutputPath, + _generateLabels, + _generateDigestLabel, loggerFactory, cancellationToken).ConfigureAwait(false); }); diff --git a/src/Containers/packaging/build/Microsoft.NET.Build.Containers.targets b/src/Containers/packaging/build/Microsoft.NET.Build.Containers.targets index ecb8dee489c7..15af224f67e0 100644 --- a/src/Containers/packaging/build/Microsoft.NET.Build.Containers.targets +++ b/src/Containers/packaging/build/Microsoft.NET.Build.Containers.targets @@ -236,7 +236,9 @@ ContainerEnvironmentVariables="@(ContainerEnvironmentVariables)" ContainerRuntimeIdentifier="$(ContainerRuntimeIdentifier)" ContainerUser="$(ContainerUser)" - RuntimeIdentifierGraphPath="$(RuntimeIdentifierGraphPath)"> + RuntimeIdentifierGraphPath="$(RuntimeIdentifierGraphPath)" + GenerateLabels="$(ContainerGenerateLabels)" + GenerateDigestLabel="$(ContainerGenerateLabelsImageBaseDigest)"> diff --git a/src/Tests/Microsoft.NET.Build.Containers.IntegrationTests/FullFramework/CreateNewImageToolTaskTests.cs b/src/Tests/Microsoft.NET.Build.Containers.IntegrationTests/FullFramework/CreateNewImageToolTaskTests.cs index ba6ff51fdbd4..e09946d14fc2 100644 --- a/src/Tests/Microsoft.NET.Build.Containers.IntegrationTests/FullFramework/CreateNewImageToolTaskTests.cs +++ b/src/Tests/Microsoft.NET.Build.Containers.IntegrationTests/FullFramework/CreateNewImageToolTaskTests.cs @@ -551,6 +551,34 @@ public void Logging_TraceLoggingIsDisabledByDefault() .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(TestContext.Current.TestExecutionDirectory, "Container", "containerize"); From b3ae2772f1e1c740222853644b655f6d6d5983f1 Mon Sep 17 00:00:00 2001 From: Chet Husk Date: Sun, 3 Mar 2024 12:32:58 -0600 Subject: [PATCH 310/577] Add test to confirm behavior --- .../TargetsTests.cs | 28 +++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/src/Tests/Microsoft.NET.Build.Containers.IntegrationTests/TargetsTests.cs b/src/Tests/Microsoft.NET.Build.Containers.IntegrationTests/TargetsTests.cs index a00f2fd47554..687e0b8745c1 100644 --- a/src/Tests/Microsoft.NET.Build.Containers.IntegrationTests/TargetsTests.cs +++ b/src/Tests/Microsoft.NET.Build.Containers.IntegrationTests/TargetsTests.cs @@ -175,6 +175,34 @@ public void ShouldTrimTrailingGitSuffixFromRepoUrls(string repoUrl, string expec .And.ContainSingle(label => LabelMatch("org.opencontainers.image.source", expectedLabel, label), String.Join(",", logger.AllMessages)); } + [InlineData(true)] + [InlineData(false)] + [Theory] + public void ShouldIncludeBaseImageLabelsUnlessUserOptsOut(bool includeBaseImageLabels) + { + var expectedBaseImage = "mcr.microsoft.com/dotnet/runtime:7.0"; + var (project, logger, d) = ProjectInitializer.InitProject(new() + { + ["ContainerGenerateLabelsImageBaseName"] = includeBaseImageLabels.ToString(), + ["ContainerBaseImage"] = expectedBaseImage, + ["ContainerGenerateLabels"] = includeBaseImageLabels.ToString() + }, projectName: $"{nameof(ShouldIncludeBaseImageLabelsUnlessUserOptsOut)}_{includeBaseImageLabels}"); + using var _ = d; + var instance = project.CreateProjectInstance(global::Microsoft.Build.Execution.ProjectInstanceSettings.None); + instance.Build(new[] { ComputeContainerConfig }, new[] { logger }, null, out var outputs).Should().BeTrue("Build should have succeeded but failed due to {0}", String.Join("\n", logger.AllMessages)); + var labels = instance.GetItems(ContainerLabel); + if (includeBaseImageLabels) + { + labels.Should().NotBeEmpty("Should have evaluated some labels by default") + .And.ContainSingle(label => LabelMatch("org.opencontainers.image.base.name", expectedBaseImage, label)); + } + else + { + labels.Should().NotBeEmpty("Should have evaluated some labels by default") + .And.NotContain(label => LabelMatch("org.opencontainers.image.base.source", expectedBaseImage, label)); + }; + } + [InlineData("7.0.100", "v7.0", "7.0")] [InlineData("7.0.100-preview.7", "v7.0", "7.0")] [InlineData("7.0.100-rc.1", "v7.0", "7.0")] From 3a2a80e017f174db938ca7edd8feb1f01a34b326 Mon Sep 17 00:00:00 2001 From: Chet Husk Date: Sun, 3 Mar 2024 12:52:03 -0600 Subject: [PATCH 311/577] Add test to confirm digest behavior --- .../ImageBuilderTests.cs | 51 +++++++++++++++++-- 1 file changed, 46 insertions(+), 5 deletions(-) diff --git a/src/Tests/Microsoft.NET.Build.Containers.UnitTests/ImageBuilderTests.cs b/src/Tests/Microsoft.NET.Build.Containers.UnitTests/ImageBuilderTests.cs index 559bd7d33c86..708f91aa797b 100644 --- a/src/Tests/Microsoft.NET.Build.Containers.UnitTests/ImageBuilderTests.cs +++ b/src/Tests/Microsoft.NET.Build.Containers.UnitTests/ImageBuilderTests.cs @@ -566,8 +566,8 @@ public void CanSetPortFromEnvVarFromUser(string envVar, string envValue, params [Fact] public void CanSetContainerUserAndOverrideAppUID() { - var userId = "1646"; - var baseConfigBuilder = FromBaseImageConfig($$""" + var userId = "1646"; + var baseConfigBuilder = FromBaseImageConfig($$""" { "architecture": "amd64", "config": { @@ -597,9 +597,9 @@ public void CanSetContainerUserAndOverrideAppUID() } """); - baseConfigBuilder.SetUser(userId); - var config = JsonNode.Parse(baseConfigBuilder.Build().Config); - config!["config"]?["User"]?.GetValue().Should().Be(expected: userId, because: "The precedence of SetUser should override inferred user ids"); + baseConfigBuilder.SetUser(userId); + var config = JsonNode.Parse(baseConfigBuilder.Build().Config); + config!["config"]?["User"]?.GetValue().Should().Be(expected: userId, because: "The precedence of SetUser should override inferred user ids"); } [Fact] @@ -644,6 +644,47 @@ public void WhenMultipleUrlSourcesAreSetOnlyAspnetcoreUrlsIsUsed() Assert.Equal([12345], assignedPorts); } + [Fact] + public void CanSetBaseImageDigestLabel() + { + var builder = FromBaseImageConfig($$""" + { + "architecture": "amd64", + "config": { + "Hostname": "", + "Domainname": "", + "User": "", + "Env": [ + "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" + ], + "Cmd": ["bash"], + "Image": "sha256:d772d27ebeec80393349a4770dc37f977be2c776a01c88b624d43f93fa369d69", + "WorkingDir": "" + }, + "created": "2023-02-04T08:14:52.000901321Z", + "os": "linux", + "rootfs": { + "type": "layers", + "diff_ids": [ + "sha256:bd2fe8b74db65d82ea10db97368d35b92998d4ea0e7e7dc819481fe4a68f64cf", + "sha256:94100d1041b650c6f7d7848c550cd98c25d0bdc193d30692e5ea5474d7b3b085", + "sha256:53c2a75a33c8f971b4b5036d34764373e134f91ee01d8053b4c3573c42e1cf5d", + "sha256:49a61320e585180286535a2545be5722b09e40ad44c7c190b20ec96c9e42e4a3", + "sha256:8a379cce2ac272aa71aa029a7bbba85c852ba81711d9f90afaefd3bf5036dc48" + ] + } + } + """); + + builder.AddBaseImageDigestLabel(); + var builtImage = builder.Build(); + JsonNode? result = JsonNode.Parse(builtImage.Config); + Assert.NotNull(result); + var labels = result["config"]?["Labels"]?.AsObject(); + var digest = labels?.AsEnumerable().First(label => label.Key == "org.opencontainers.image.base.digest"); + digest?.Value.Should().NotBeNull(); + } + private ImageBuilder FromBaseImageConfig(string baseImageConfig, [CallerMemberName] string testName = "") { var manifest = new ManifestV2() From b7273ed83686d301f3627ccdfd0edc4913596b84 Mon Sep 17 00:00:00 2001 From: Chet Husk Date: Mon, 4 Mar 2024 13:20:50 -0600 Subject: [PATCH 312/577] fix incorrect string value --- .../TargetsTests.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Tests/Microsoft.NET.Build.Containers.IntegrationTests/TargetsTests.cs b/src/Tests/Microsoft.NET.Build.Containers.IntegrationTests/TargetsTests.cs index 687e0b8745c1..4246d8351e39 100644 --- a/src/Tests/Microsoft.NET.Build.Containers.IntegrationTests/TargetsTests.cs +++ b/src/Tests/Microsoft.NET.Build.Containers.IntegrationTests/TargetsTests.cs @@ -199,7 +199,7 @@ public void ShouldIncludeBaseImageLabelsUnlessUserOptsOut(bool includeBaseImageL else { labels.Should().NotBeEmpty("Should have evaluated some labels by default") - .And.NotContain(label => LabelMatch("org.opencontainers.image.base.source", expectedBaseImage, label)); + .And.NotContain(label => LabelMatch("org.opencontainers.image.base.name", expectedBaseImage, label)); }; } From a743b972bd433ab3c27061d419ada62473c5b481 Mon Sep 17 00:00:00 2001 From: Chet Husk Date: Mon, 4 Mar 2024 21:42:52 -0600 Subject: [PATCH 313/577] fix test baseline --- .../TargetsTests.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Tests/Microsoft.NET.Build.Containers.IntegrationTests/TargetsTests.cs b/src/Tests/Microsoft.NET.Build.Containers.IntegrationTests/TargetsTests.cs index 4246d8351e39..1606e26f5bc6 100644 --- a/src/Tests/Microsoft.NET.Build.Containers.IntegrationTests/TargetsTests.cs +++ b/src/Tests/Microsoft.NET.Build.Containers.IntegrationTests/TargetsTests.cs @@ -185,7 +185,7 @@ public void ShouldIncludeBaseImageLabelsUnlessUserOptsOut(bool includeBaseImageL { ["ContainerGenerateLabelsImageBaseName"] = includeBaseImageLabels.ToString(), ["ContainerBaseImage"] = expectedBaseImage, - ["ContainerGenerateLabels"] = includeBaseImageLabels.ToString() + ["ContainerGenerateLabels"] = true.ToString() }, projectName: $"{nameof(ShouldIncludeBaseImageLabelsUnlessUserOptsOut)}_{includeBaseImageLabels}"); using var _ = d; var instance = project.CreateProjectInstance(global::Microsoft.Build.Execution.ProjectInstanceSettings.None); From abac232c902eb8f67c435c59f7c3afc6be2cb490 Mon Sep 17 00:00:00 2001 From: Chet Husk Date: Tue, 5 Mar 2024 08:53:16 -0600 Subject: [PATCH 314/577] Update src/Containers/Microsoft.NET.Build.Containers/Tasks/CreateNewImage.Interface.cs Co-authored-by: Rainer Sigwald --- .../Tasks/CreateNewImage.Interface.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 4c806dba08b6..19cf905128a3 100644 --- a/src/Containers/Microsoft.NET.Build.Containers/Tasks/CreateNewImage.Interface.cs +++ b/src/Containers/Microsoft.NET.Build.Containers/Tasks/CreateNewImage.Interface.cs @@ -153,7 +153,7 @@ partial class CreateNewImage public bool GenerateLabels { get; set; } /// - /// If true, the tooling will generate an 'org.opencontainers.image.base.digest' label on the generated images containing the digest of the chosen base image. + /// If true, the tooling will generate an org.opencontainers.image.base.digest label on the generated images containing the digest of the chosen base image. /// /// /// Normally this would have been handled in the container targets, but we do not currently _fetch_ the digest of the base image in pure MSBuild, so we do it during generation-time. From 1adff27c4bafa8eac169a87e603e2ae1c791a584 Mon Sep 17 00:00:00 2001 From: Chet Husk Date: Tue, 5 Mar 2024 13:28:36 -0600 Subject: [PATCH 315/577] detect and flow through the manifest digest from the registry or manifest list --- .../ImageBuilder.cs | 16 ++++-- .../ManifestV2.cs | 9 ++-- .../PublicAPI/net8.0/PublicAPI.Unshipped.txt | 8 +-- .../Registry/Registry.cs | 51 +++++++++++++------ 4 files changed, 55 insertions(+), 29 deletions(-) diff --git a/src/Containers/Microsoft.NET.Build.Containers/ImageBuilder.cs b/src/Containers/Microsoft.NET.Build.Containers/ImageBuilder.cs index 3a8d8a50315e..92d81fc8813a 100644 --- a/src/Containers/Microsoft.NET.Build.Containers/ImageBuilder.cs +++ b/src/Containers/Microsoft.NET.Build.Containers/ImageBuilder.cs @@ -14,6 +14,10 @@ namespace Microsoft.NET.Build.Containers; /// internal sealed class ImageBuilder { + // a snapshot of the manifest that this builder is based on + private readonly ManifestV2 _baseImageManifest; + + // the mutable internal manifest that we're building by modifying the base and applying customizations private readonly ManifestV2 _manifest; private readonly ImageConfig _baseImageConfig; private readonly ILogger _logger; @@ -33,7 +37,8 @@ internal sealed class ImageBuilder internal ImageBuilder(ManifestV2 manifest, ImageConfig baseImageConfig, ILogger logger) { - _manifest = manifest; + _baseImageManifest = manifest; + _manifest = new ManifestV2() { SchemaVersion = manifest.SchemaVersion, Config = manifest.Config, Layers = new(manifest.Layers), MediaType = manifest.MediaType }; _baseImageConfig = baseImageConfig; _logger = logger; } @@ -63,9 +68,12 @@ internal BuiltImage Build() size = imageSize }; - ManifestV2 newManifest = _manifest with + ManifestV2 newManifest = new ManifestV2() { - Config = newManifestConfig + Config = newManifestConfig, + SchemaVersion = _manifest.SchemaVersion, + MediaType = _manifest.MediaType, + Layers = _manifest.Layers }; return new BuiltImage() @@ -89,7 +97,7 @@ internal void AddLayer(Layer l) internal void AddBaseImageDigestLabel() { - AddLabel("org.opencontainers.image.base.digest", _manifest.GetDigest()); + AddLabel("org.opencontainers.image.base.digest", _baseImageManifest.GetDigest()); } /// diff --git a/src/Containers/Microsoft.NET.Build.Containers/ManifestV2.cs b/src/Containers/Microsoft.NET.Build.Containers/ManifestV2.cs index eb00143665c6..38b4019a257b 100644 --- a/src/Containers/Microsoft.NET.Build.Containers/ManifestV2.cs +++ b/src/Containers/Microsoft.NET.Build.Containers/ManifestV2.cs @@ -12,8 +12,11 @@ namespace Microsoft.NET.Build.Containers; /// /// https://github.com/opencontainers/image-spec/blob/main/manifest.md /// -public readonly record struct ManifestV2 +public class ManifestV2 { + [JsonIgnore] + public string? KnownDigest { get; set; } + /// /// This REQUIRED property specifies the image manifest schema version. /// For this version of the specification, this MUST be 2 to ensure backward compatibility with older versions of Docker. @@ -47,9 +50,9 @@ public readonly record struct ManifestV2 /// /// Gets the digest for this manifest. /// - public string GetDigest() => DigestUtils.GetDigest(JsonSerializer.SerializeToNode(this)?.ToJsonString() ?? string.Empty); + public string GetDigest() => KnownDigest ??= DigestUtils.GetDigest(JsonSerializer.SerializeToNode(this)?.ToJsonString(new JsonSerializerOptions() { WriteIndented = true }).ReplaceLineEndings("\r") ?? string.Empty); } public record struct ManifestConfig(string mediaType, long size, string digest); -public record struct ManifestLayer(string mediaType, long size, string digest, string[]? urls); +public record struct ManifestLayer(string mediaType, long size, string digest, [property: JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)][field: JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] string[]? urls); diff --git a/src/Containers/Microsoft.NET.Build.Containers/PublicAPI/net8.0/PublicAPI.Unshipped.txt b/src/Containers/Microsoft.NET.Build.Containers/PublicAPI/net8.0/PublicAPI.Unshipped.txt index 77eb129a0421..5ffe98fd647c 100644 --- a/src/Containers/Microsoft.NET.Build.Containers/PublicAPI/net8.0/PublicAPI.Unshipped.txt +++ b/src/Containers/Microsoft.NET.Build.Containers/PublicAPI/net8.0/PublicAPI.Unshipped.txt @@ -73,6 +73,8 @@ Microsoft.NET.Build.Containers.ManifestV2 Microsoft.NET.Build.Containers.ManifestV2.Config.get -> Microsoft.NET.Build.Containers.ManifestConfig Microsoft.NET.Build.Containers.ManifestV2.Config.init -> void Microsoft.NET.Build.Containers.ManifestV2.GetDigest() -> string! +Microsoft.NET.Build.Containers.ManifestV2.KnownDigest.get -> string? +Microsoft.NET.Build.Containers.ManifestV2.KnownDigest.set -> void Microsoft.NET.Build.Containers.ManifestV2.Layers.get -> System.Collections.Generic.List! Microsoft.NET.Build.Containers.ManifestV2.Layers.init -> void Microsoft.NET.Build.Containers.ManifestV2.ManifestV2() -> void @@ -256,12 +258,6 @@ Microsoft.NET.Build.Containers.ManifestLayer.Equals(Microsoft.NET.Build.Containe ~override Microsoft.NET.Build.Containers.Descriptor.Equals(object obj) -> bool Microsoft.NET.Build.Containers.ManifestLayer.Deconstruct(out string! mediaType, out long size, out string! digest, out string![]? urls) -> void Microsoft.NET.Build.Containers.Descriptor.Equals(Microsoft.NET.Build.Containers.Descriptor other) -> bool -~override Microsoft.NET.Build.Containers.ManifestV2.ToString() -> string -static Microsoft.NET.Build.Containers.ManifestV2.operator !=(Microsoft.NET.Build.Containers.ManifestV2 left, Microsoft.NET.Build.Containers.ManifestV2 right) -> bool -static Microsoft.NET.Build.Containers.ManifestV2.operator ==(Microsoft.NET.Build.Containers.ManifestV2 left, Microsoft.NET.Build.Containers.ManifestV2 right) -> bool -override Microsoft.NET.Build.Containers.ManifestV2.GetHashCode() -> int -~override Microsoft.NET.Build.Containers.ManifestV2.Equals(object obj) -> bool -Microsoft.NET.Build.Containers.ManifestV2.Equals(Microsoft.NET.Build.Containers.ManifestV2 other) -> bool ~override Microsoft.NET.Build.Containers.ManifestListV2.ToString() -> string static Microsoft.NET.Build.Containers.ManifestListV2.operator !=(Microsoft.NET.Build.Containers.ManifestListV2 left, Microsoft.NET.Build.Containers.ManifestListV2 right) -> bool static Microsoft.NET.Build.Containers.ManifestListV2.operator ==(Microsoft.NET.Build.Containers.ManifestListV2 left, Microsoft.NET.Build.Containers.ManifestListV2 right) -> bool diff --git a/src/Containers/Microsoft.NET.Build.Containers/Registry/Registry.cs b/src/Containers/Microsoft.NET.Build.Containers/Registry/Registry.cs index 68456fa71bfa..9f8a771f1033 100644 --- a/src/Containers/Microsoft.NET.Build.Containers/Registry/Registry.cs +++ b/src/Containers/Microsoft.NET.Build.Containers/Registry/Registry.cs @@ -6,12 +6,14 @@ using NuGet.RuntimeModel; using System.Diagnostics; using System.Net.Http.Json; +using System.Text.Json; using System.Text.Json.Nodes; using System.Text.RegularExpressions; namespace Microsoft.NET.Build.Containers; -internal interface IManifestPicker { +internal interface IManifestPicker +{ public PlatformSpecificManifest? PickBestManifestForRid(IReadOnlyDictionary manifestList, string runtimeIdentifier); } @@ -26,7 +28,8 @@ public RidGraphManifestPicker(string runtimeIdentifierGraphPath) public PlatformSpecificManifest? PickBestManifestForRid(IReadOnlyDictionary ridManifestDict, string runtimeIdentifier) { var bestManifestRid = GetBestMatchingRid(_runtimeGraph, runtimeIdentifier, ridManifestDict.Keys); - if (bestManifestRid is null) { + if (bestManifestRid is null) + { return null; } return ridManifestDict[bestManifestRid]; @@ -132,7 +135,8 @@ private static string DeriveRegistryName(Uri baseUri) /// /// Google Artifact Registry locations (one for each availability zone) are of the form "ZONE-docker.pkg.dev". /// - public bool IsGoogleArtifactRegistry { + public bool IsGoogleArtifactRegistry + { get => RegistryName.EndsWith("-docker.pkg.dev", StringComparison.Ordinal); } @@ -151,7 +155,7 @@ public async Task GetImageManifestAsync(string repositoryName, str { SchemaTypes.DockerManifestV2 or SchemaTypes.OciManifestV1 => await ReadSingleImageAsync( repositoryName, - await initialManifestResponse.Content.ReadFromJsonAsync(cancellationToken: cancellationToken).ConfigureAwait(false), + await ReadManifest().ConfigureAwait(false), cancellationToken).ConfigureAwait(false), SchemaTypes.DockerManifestListV2 => await PickBestImageFromManifestListAsync( repositoryName, @@ -167,6 +171,17 @@ await initialManifestResponse.Content.ReadFromJsonAsync(cancella BaseUri, unknownMediaType)) }; + + async Task ReadManifest() + { + initialManifestResponse.Headers.TryGetValues("Docker-Content-Digest", out var knownDigest); + var manifest = (await initialManifestResponse.Content.ReadFromJsonAsync(cancellationToken: cancellationToken).ConfigureAwait(false))!; + if (knownDigest?.FirstOrDefault() is string knownDigestValue) + { + manifest.KnownDigest = knownDigestValue; + } + return manifest; + } } internal async Task GetManifestListAsync(string repositoryName, string reference, CancellationToken cancellationToken) @@ -193,11 +208,12 @@ private async Task ReadSingleImageAsync(string repositoryName, Man return new ImageBuilder(manifest, new ImageConfig(configDoc), _logger); } - + private static IReadOnlyDictionary GetManifestsByRid(ManifestListV2 manifestList) { var ridDict = new Dictionary(); - foreach (var manifest in manifestList.manifests) { + foreach (var manifest in manifestList.manifests) + { if (CreateRidForPlatform(manifest.platform) is { } rid) { ridDict.TryAdd(rid, manifest); @@ -206,7 +222,7 @@ private static IReadOnlyDictionary GetManifest return ridDict; } - + private static string? CreateRidForPlatform(PlatformInformation platform) { // we only support linux and windows containers explicitly, so anything else we should skip past. @@ -220,7 +236,7 @@ private static IReadOnlyDictionary GetManifest // TODO: we _may_ need OS-specific version parsing. Need to do more research on what the field looks like across more manifest lists. var versionPart = platform.version?.Split('.') switch { - [var major, .. ] => major, + [var major, ..] => major, _ => null }; var platformPart = platform.architecture switch @@ -254,12 +270,14 @@ private async Task PickBestImageFromManifestListAsync( using HttpResponseMessage manifestResponse = await _registryAPI.Manifest.GetAsync(repositoryName, matchingManifest.digest, cancellationToken).ConfigureAwait(false); cancellationToken.ThrowIfCancellationRequested(); - + var manifest = await manifestResponse.Content.ReadAsJsonAsync(cancellationToken: cancellationToken).ConfigureAwait(false); + manifest.KnownDigest = matchingManifest.digest; return await ReadSingleImageAsync( repositoryName, - await manifestResponse.Content.ReadFromJsonAsync(cancellationToken: cancellationToken).ConfigureAwait(false), + manifest, cancellationToken).ConfigureAwait(false); - } else + } + else { throw new BaseImageNotFoundException(runtimeIdentifier, repositoryName, reference, ridManifestDict.Keys); } @@ -332,13 +350,13 @@ internal async Task UploadBlobChunkedAsync(Stream con int bytesRead = await contents.ReadAsync(chunkBackingStore, cancellationToken).ConfigureAwait(false); - ByteArrayContent content = new (chunkBackingStore, offset: 0, count: bytesRead); + ByteArrayContent content = new(chunkBackingStore, offset: 0, count: bytesRead); content.Headers.ContentLength = bytesRead; // manual because ACR throws an error with the .NET type {"Range":"bytes 0-84521/*","Reason":"the Content-Range header format is invalid"} // content.Headers.Add("Content-Range", $"0-{contents.Length - 1}"); Debug.Assert(content.Headers.TryAddWithoutValidation("Content-Range", $"{chunkStart}-{chunkStart + bytesRead - 1}")); - + NextChunkUploadInformation nextChunk = await _registryAPI.Blob.Upload.UploadChunkAsync(patchUri, content, cancellationToken).ConfigureAwait(false); patchUri = nextChunk.UploadUri; @@ -420,7 +438,7 @@ private async Task PushAsync(BuiltImage builtImage, SourceImageReference source, } // Blob wasn't there; can we tell the server to get it from the base image? - if (! await _registryAPI.Blob.Upload.TryMountAsync(destination.Repository, source.Repository, digest, cancellationToken).ConfigureAwait(false)) + if (!await _registryAPI.Blob.Upload.TryMountAsync(destination.Repository, source.Repository, digest, cancellationToken).ConfigureAwait(false)) { // The blob wasn't already available in another namespace, so fall back to explicitly uploading it @@ -432,7 +450,8 @@ private async Task PushAsync(BuiltImage builtImage, SourceImageReference source, await destinationRegistry.PushLayerAsync(Layer.FromDescriptor(descriptor), destination.Repository, cancellationToken).ConfigureAwait(false); _logger.LogInformation(Strings.Registry_LayerUploaded, digest, destinationRegistry.RegistryName); } - else { + else + { throw new NotImplementedException(Resource.GetString(nameof(Strings.MissingLinkToRegistry))); } } @@ -444,7 +463,7 @@ private async Task PushAsync(BuiltImage builtImage, SourceImageReference source, } else { - foreach(var descriptor in builtImage.LayerDescriptors) + foreach (var descriptor in builtImage.LayerDescriptors) { await uploadLayerFunc(descriptor).ConfigureAwait(false); } From ad133d5b1858d02b4b97364446025504c4d08f64 Mon Sep 17 00:00:00 2001 From: Chet Husk Date: Tue, 5 Mar 2024 13:35:07 -0600 Subject: [PATCH 316/577] remove unused serialization changes --- src/Containers/Microsoft.NET.Build.Containers/ManifestV2.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Containers/Microsoft.NET.Build.Containers/ManifestV2.cs b/src/Containers/Microsoft.NET.Build.Containers/ManifestV2.cs index 38b4019a257b..30937d782a4b 100644 --- a/src/Containers/Microsoft.NET.Build.Containers/ManifestV2.cs +++ b/src/Containers/Microsoft.NET.Build.Containers/ManifestV2.cs @@ -50,7 +50,7 @@ public class ManifestV2 /// /// Gets the digest for this manifest. /// - public string GetDigest() => KnownDigest ??= DigestUtils.GetDigest(JsonSerializer.SerializeToNode(this)?.ToJsonString(new JsonSerializerOptions() { WriteIndented = true }).ReplaceLineEndings("\r") ?? string.Empty); + public string GetDigest() => KnownDigest ??= DigestUtils.GetDigest(JsonSerializer.SerializeToNode(this)?.ToJsonString() ?? string.Empty); } public record struct ManifestConfig(string mediaType, long size, string digest); From 919385eb5f8407b4b9ccb3b02482d79b7a7b404b Mon Sep 17 00:00:00 2001 From: Chet Husk Date: Tue, 5 Mar 2024 13:44:14 -0600 Subject: [PATCH 317/577] address ContainerBuilder visibility --- .../Microsoft.NET.Build.Containers/ContainerBuilder.cs | 4 ++-- .../PublicAPI/net8.0/PublicAPI.Unshipped.txt | 2 -- .../Microsoft.NET.Build.Containers/Registry/Registry.cs | 3 ++- 3 files changed, 4 insertions(+), 5 deletions(-) diff --git a/src/Containers/Microsoft.NET.Build.Containers/ContainerBuilder.cs b/src/Containers/Microsoft.NET.Build.Containers/ContainerBuilder.cs index 55a8af83ccff..c63227808ca1 100644 --- a/src/Containers/Microsoft.NET.Build.Containers/ContainerBuilder.cs +++ b/src/Containers/Microsoft.NET.Build.Containers/ContainerBuilder.cs @@ -6,9 +6,9 @@ namespace Microsoft.NET.Build.Containers; -public static class ContainerBuilder +internal static class ContainerBuilder { - public static async Task ContainerizeAsync( + internal static async Task ContainerizeAsync( DirectoryInfo publishDirectory, string workingDir, string baseRegistry, diff --git a/src/Containers/Microsoft.NET.Build.Containers/PublicAPI/net8.0/PublicAPI.Unshipped.txt b/src/Containers/Microsoft.NET.Build.Containers/PublicAPI/net8.0/PublicAPI.Unshipped.txt index 5ffe98fd647c..f4c70d1e7a8b 100644 --- a/src/Containers/Microsoft.NET.Build.Containers/PublicAPI/net8.0/PublicAPI.Unshipped.txt +++ b/src/Containers/Microsoft.NET.Build.Containers/PublicAPI/net8.0/PublicAPI.Unshipped.txt @@ -13,9 +13,7 @@ Microsoft.NET.Build.Containers.Tasks.ComputeDotnetBaseImageAndTag.TargetRuntimeI Microsoft.NET.Build.Containers.Tasks.ComputeDotnetBaseImageAndTag.TargetRuntimeIdentifier.set -> void Microsoft.NET.Build.Containers.Tasks.ComputeDotnetBaseImageAndTag.UsesInvariantGlobalization.get -> bool Microsoft.NET.Build.Containers.Tasks.ComputeDotnetBaseImageAndTag.UsesInvariantGlobalization.set -> void -static Microsoft.NET.Build.Containers.ContainerBuilder.ContainerizeAsync(System.IO.DirectoryInfo! publishDirectory, string! workingDir, string! baseRegistry, string! baseImageName, string! baseImageTag, string![]! entrypoint, string![]! entrypointArgs, string![]! defaultArgs, string![]! appCommand, string![]! appCommandArgs, string! appCommandInstruction, string! imageName, string![]! imageTags, string? outputRegistry, System.Collections.Generic.Dictionary! labels, Microsoft.NET.Build.Containers.Port[]? exposedPorts, System.Collections.Generic.Dictionary! envVars, string! containerRuntimeIdentifier, string! ridGraphPath, string! localRegistry, string? containerUser, string? archiveOutputPath, bool generateLabels, bool generateDigestLabel, Microsoft.Extensions.Logging.ILoggerFactory! loggerFactory, System.Threading.CancellationToken cancellationToken) -> System.Threading.Tasks.Task! static readonly Microsoft.NET.Build.Containers.Constants.Version -> string! -Microsoft.NET.Build.Containers.ContainerBuilder Microsoft.NET.Build.Containers.ContainerHelpers Microsoft.NET.Build.Containers.ContainerHelpers.ParsePortError Microsoft.NET.Build.Containers.ContainerHelpers.ParsePortError.InvalidPortNumber = 1 -> Microsoft.NET.Build.Containers.ContainerHelpers.ParsePortError diff --git a/src/Containers/Microsoft.NET.Build.Containers/Registry/Registry.cs b/src/Containers/Microsoft.NET.Build.Containers/Registry/Registry.cs index 9f8a771f1033..21ba5d8c9271 100644 --- a/src/Containers/Microsoft.NET.Build.Containers/Registry/Registry.cs +++ b/src/Containers/Microsoft.NET.Build.Containers/Registry/Registry.cs @@ -270,7 +270,8 @@ private async Task PickBestImageFromManifestListAsync( using HttpResponseMessage manifestResponse = await _registryAPI.Manifest.GetAsync(repositoryName, matchingManifest.digest, cancellationToken).ConfigureAwait(false); cancellationToken.ThrowIfCancellationRequested(); - var manifest = await manifestResponse.Content.ReadAsJsonAsync(cancellationToken: cancellationToken).ConfigureAwait(false); + var manifest = await manifestResponse.Content.ReadFromJsonAsync(cancellationToken: cancellationToken).ConfigureAwait(false); + if (manifest is null) throw new BaseImageNotFoundException(runtimeIdentifier, repositoryName, reference, ridManifestDict.Keys); manifest.KnownDigest = matchingManifest.digest; return await ReadSingleImageAsync( repositoryName, From 511c121de5aed91d455ef512dc83cf83e125965b Mon Sep 17 00:00:00 2001 From: Chet Husk Date: Wed, 6 Mar 2024 15:16:00 -0600 Subject: [PATCH 318/577] make globalized, AOT apps no longer require nightly (#39195) Co-authored-by: Rainer Sigwald --- .../Tasks/ComputeDotnetBaseImageAndTag.cs | 4 +++- .../TargetsTests.cs | 4 ++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/Containers/Microsoft.NET.Build.Containers/Tasks/ComputeDotnetBaseImageAndTag.cs b/src/Containers/Microsoft.NET.Build.Containers/Tasks/ComputeDotnetBaseImageAndTag.cs index f4eab184e1e8..ecf5190653da 100644 --- a/src/Containers/Microsoft.NET.Build.Containers/Tasks/ComputeDotnetBaseImageAndTag.cs +++ b/src/Containers/Microsoft.NET.Build.Containers/Tasks/ComputeDotnetBaseImageAndTag.cs @@ -80,7 +80,9 @@ public sealed class ComputeDotnetBaseImageAndTag : Microsoft.Build.Utilities.Tas private bool IsMuslRid => TargetRuntimeIdentifier.StartsWith("linux-musl", StringComparison.Ordinal); private bool IsBundledRuntime => IsSelfContained; - private bool NeedsNightlyImages => IsAotPublished; + + // as of March 2024, the -extra images are on stable MCR, but the -aot images are still on nightly. This means AOT, invariant apps need the /nightly/ base. + private bool NeedsNightlyImages => IsAotPublished && UsesInvariantGlobalization; private bool AllowsExperimentalTagInference => String.IsNullOrEmpty(ContainerFamily); public ComputeDotnetBaseImageAndTag() diff --git a/src/Tests/Microsoft.NET.Build.Containers.IntegrationTests/TargetsTests.cs b/src/Tests/Microsoft.NET.Build.Containers.IntegrationTests/TargetsTests.cs index a00f2fd47554..cca5b68a448f 100644 --- a/src/Tests/Microsoft.NET.Build.Containers.IntegrationTests/TargetsTests.cs +++ b/src/Tests/Microsoft.NET.Build.Containers.IntegrationTests/TargetsTests.cs @@ -320,8 +320,8 @@ public void AOTAppsGetAOTImages(string rid, string expectedImage) computedBaseImageTag.Should().BeEquivalentTo(expectedImage); } - [InlineData("linux-musl-x64", "mcr.microsoft.com/dotnet/nightly/runtime-deps:8.0-alpine-extra")] - [InlineData("linux-x64", "mcr.microsoft.com/dotnet/nightly/runtime-deps:8.0-jammy-chiseled-extra")] + [InlineData("linux-musl-x64", "mcr.microsoft.com/dotnet/runtime-deps:8.0-alpine-extra")] + [InlineData("linux-x64", "mcr.microsoft.com/dotnet/runtime-deps:8.0-jammy-chiseled-extra")] [Theory] public void AOTAppsWithCulturesGetExtraImages(string rid, string expectedImage) { From c4ad01672fd1f8370655810c9fa540a0f2d3a71d Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Thu, 7 Mar 2024 07:19:31 +0000 Subject: [PATCH 319/577] [release/8.0.3xx] Update dependencies from dotnet/fsharp (#39255) [release/8.0.3xx] Update dependencies from dotnet/fsharp - Merge branch 'release/8.0.3xx' of https://github.com/dotnet/sdk into darc-release/8.0.3xx-3de6fd6b-e225-47c2-9bd0-73a2ae2c6bf0 --- eng/Version.Details.xml | 8 ++++---- eng/Versions.props | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 7bdd0b30614a..92a7b6233a3a 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -64,13 +64,13 @@ 6f44380e4fdea6ddf5c11f48efeb25c2bf181e62 - + https://github.com/dotnet/fsharp - ca66024e6da7cced9921216763386bd43f400fbf + 641c6a0e65bac6f7809e4e2415b9d60c11dcf493 - + https://github.com/dotnet/fsharp - ca66024e6da7cced9921216763386bd43f400fbf + 641c6a0e65bac6f7809e4e2415b9d60c11dcf493 diff --git a/eng/Versions.props b/eng/Versions.props index 7c4e8fe9e50f..f9c40a85131c 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -150,7 +150,7 @@ - 12.8.300-beta.24154.4 + 12.8.300-beta.24155.6 From a95845691c67328399626fdb31b8f4d5eafd5879 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" Date: Thu, 7 Mar 2024 13:59:05 +0000 Subject: [PATCH 320/577] Update dependencies from https://github.com/nuget/nuget.client build 6.10.0.73 Microsoft.Build.NuGetSdkResolver , NuGet.Build.Tasks , NuGet.Build.Tasks.Console , NuGet.Build.Tasks.Pack , NuGet.CommandLine.XPlat , NuGet.Commands , NuGet.Common , NuGet.Configuration , NuGet.Credentials , NuGet.DependencyResolver.Core , NuGet.Frameworks , NuGet.LibraryModel , NuGet.Packaging , NuGet.ProjectModel , NuGet.Protocol , NuGet.Versioning From Version 6.10.0-preview.2.52 -> To Version 6.10.0-preview.2.73 --- eng/Version.Details.xml | 64 ++++++++++++++++++++--------------------- eng/Versions.props | 22 +++++++------- 2 files changed, 43 insertions(+), 43 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 387a196201f3..3a254e96e3cf 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -115,69 +115,69 @@ https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore da7e9894ce22ef8cc02e5acc56e95a6f8cf8f644 - + https://github.com/nuget/nuget.client - 6009531090c927a8e61da9a0f97bdd5eb6f01a47 + e49fa71580778b8d9c3352ea5ed15ef204f0389f - + https://github.com/nuget/nuget.client - 6009531090c927a8e61da9a0f97bdd5eb6f01a47 + e49fa71580778b8d9c3352ea5ed15ef204f0389f - + https://github.com/nuget/nuget.client - 6009531090c927a8e61da9a0f97bdd5eb6f01a47 + e49fa71580778b8d9c3352ea5ed15ef204f0389f - + https://github.com/nuget/nuget.client - 6009531090c927a8e61da9a0f97bdd5eb6f01a47 + e49fa71580778b8d9c3352ea5ed15ef204f0389f - + https://github.com/nuget/nuget.client - 6009531090c927a8e61da9a0f97bdd5eb6f01a47 + e49fa71580778b8d9c3352ea5ed15ef204f0389f - + https://github.com/nuget/nuget.client - 6009531090c927a8e61da9a0f97bdd5eb6f01a47 + e49fa71580778b8d9c3352ea5ed15ef204f0389f - + https://github.com/nuget/nuget.client - 6009531090c927a8e61da9a0f97bdd5eb6f01a47 + e49fa71580778b8d9c3352ea5ed15ef204f0389f - + https://github.com/nuget/nuget.client - 6009531090c927a8e61da9a0f97bdd5eb6f01a47 + e49fa71580778b8d9c3352ea5ed15ef204f0389f - + https://github.com/nuget/nuget.client - 6009531090c927a8e61da9a0f97bdd5eb6f01a47 + e49fa71580778b8d9c3352ea5ed15ef204f0389f - + https://github.com/nuget/nuget.client - 6009531090c927a8e61da9a0f97bdd5eb6f01a47 + e49fa71580778b8d9c3352ea5ed15ef204f0389f - + https://github.com/nuget/nuget.client - 6009531090c927a8e61da9a0f97bdd5eb6f01a47 + e49fa71580778b8d9c3352ea5ed15ef204f0389f - + https://github.com/nuget/nuget.client - 6009531090c927a8e61da9a0f97bdd5eb6f01a47 + e49fa71580778b8d9c3352ea5ed15ef204f0389f - + https://github.com/nuget/nuget.client - 6009531090c927a8e61da9a0f97bdd5eb6f01a47 + e49fa71580778b8d9c3352ea5ed15ef204f0389f - + https://github.com/nuget/nuget.client - 6009531090c927a8e61da9a0f97bdd5eb6f01a47 + e49fa71580778b8d9c3352ea5ed15ef204f0389f - + https://github.com/nuget/nuget.client - 6009531090c927a8e61da9a0f97bdd5eb6f01a47 + e49fa71580778b8d9c3352ea5ed15ef204f0389f - + https://github.com/nuget/nuget.client - 6009531090c927a8e61da9a0f97bdd5eb6f01a47 + e49fa71580778b8d9c3352ea5ed15ef204f0389f https://github.com/microsoft/vstest diff --git a/eng/Versions.props b/eng/Versions.props index ed8ebb6ba058..e996087b14c5 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -82,18 +82,18 @@ - 6.10.0-preview.2.52 - 6.10.0-preview.2.52 + 6.10.0-preview.2.73 + 6.10.0-preview.2.73 6.0.0-rc.278 - 6.10.0-preview.2.52 - 6.10.0-preview.2.52 - 6.10.0-preview.2.52 - 6.10.0-preview.2.52 - 6.10.0-preview.2.52 - 6.10.0-preview.2.52 - 6.10.0-preview.2.52 - 6.10.0-preview.2.52 - 6.10.0-preview.2.52 + 6.10.0-preview.2.73 + 6.10.0-preview.2.73 + 6.10.0-preview.2.73 + 6.10.0-preview.2.73 + 6.10.0-preview.2.73 + 6.10.0-preview.2.73 + 6.10.0-preview.2.73 + 6.10.0-preview.2.73 + 6.10.0-preview.2.73 $(NuGetPackagingPackageVersion) $(NuGetProjectModelPackageVersion) From fd16bb1dba5c1f5a46fc65f04bdd2c5aee9f7a61 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" Date: Thu, 7 Mar 2024 14:01:38 +0000 Subject: [PATCH 321/577] Update dependencies from https://github.com/dotnet/msbuild build 20240307.1 Microsoft.SourceBuild.Intermediate.msbuild , Microsoft.Build , Microsoft.Build.Localization From Version 17.10.0-preview-24127-03 -> To Version 17.10.0-preview-24157-01 --- eng/Version.Details.xml | 12 ++++++------ eng/Versions.props | 4 ++-- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index b580912e9296..aba5e82e2230 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -51,17 +51,17 @@ https://github.com/dotnet/emsdk 2fc2ffd960930318f33fcaa690cbdbc55d72f52d - + https://github.com/dotnet/msbuild - 5089df85a739c170a6c3ab0493bd2c17b36d81d4 + 9af8ff2f951017996172e5b805651ebf957e97f4 - + https://github.com/dotnet/msbuild - 5089df85a739c170a6c3ab0493bd2c17b36d81d4 + 9af8ff2f951017996172e5b805651ebf957e97f4 - + https://github.com/dotnet/msbuild - 5089df85a739c170a6c3ab0493bd2c17b36d81d4 + 9af8ff2f951017996172e5b805651ebf957e97f4 diff --git a/eng/Versions.props b/eng/Versions.props index 113be455f8c6..bbaf0e711766 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -120,7 +120,7 @@ - 17.10.0-preview-24156-01 + 17.10.0-preview-24157-01 $(MicrosoftBuildPackageVersion) - 12.8.300-beta.24155.6 + 12.8.300-beta.24157.2 From 3f92de7c88b82a771b477a7890d7a27e48656125 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" Date: Thu, 7 Mar 2024 14:05:21 +0000 Subject: [PATCH 323/577] Update dependencies from https://github.com/dotnet/roslyn build 20240306.11 Microsoft.CodeAnalysis , Microsoft.CodeAnalysis.CSharp , Microsoft.CodeAnalysis.CSharp.CodeStyle , Microsoft.CodeAnalysis.CSharp.Features , Microsoft.CodeAnalysis.CSharp.Workspaces , Microsoft.CodeAnalysis.Workspaces.MSBuild , Microsoft.Net.Compilers.Toolset From Version 4.10.0-3.24155.13 -> To Version 4.10.0-3.24156.11 --- eng/Version.Details.xml | 28 ++++++++++++++-------------- eng/Versions.props | 14 +++++++------- 2 files changed, 21 insertions(+), 21 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 387a196201f3..aec8ef581a1d 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -78,34 +78,34 @@ ac0d85557969d51bca72181514ddb7d5796fbbe2 - + https://github.com/dotnet/roslyn - 99fbf1bddce825ee6b146cf5591c143b216ed88b + d24b5bb8debd2e89df8db13c84694f2982cc41b1 - + https://github.com/dotnet/roslyn - 99fbf1bddce825ee6b146cf5591c143b216ed88b + d24b5bb8debd2e89df8db13c84694f2982cc41b1 - + https://github.com/dotnet/roslyn - 99fbf1bddce825ee6b146cf5591c143b216ed88b + d24b5bb8debd2e89df8db13c84694f2982cc41b1 - + https://github.com/dotnet/roslyn - 99fbf1bddce825ee6b146cf5591c143b216ed88b + d24b5bb8debd2e89df8db13c84694f2982cc41b1 - + https://github.com/dotnet/roslyn - 99fbf1bddce825ee6b146cf5591c143b216ed88b + d24b5bb8debd2e89df8db13c84694f2982cc41b1 - + https://github.com/dotnet/roslyn - 99fbf1bddce825ee6b146cf5591c143b216ed88b + d24b5bb8debd2e89df8db13c84694f2982cc41b1 - + https://github.com/dotnet/roslyn - 99fbf1bddce825ee6b146cf5591c143b216ed88b + d24b5bb8debd2e89df8db13c84694f2982cc41b1 https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore diff --git a/eng/Versions.props b/eng/Versions.props index ed8ebb6ba058..c5db3e42fb3c 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -154,13 +154,13 @@ - 4.10.0-3.24155.13 - 4.10.0-3.24155.13 - 4.10.0-3.24155.13 - 4.10.0-3.24155.13 - 4.10.0-3.24155.13 - 4.10.0-3.24155.13 - 4.10.0-3.24155.13 + 4.10.0-3.24156.11 + 4.10.0-3.24156.11 + 4.10.0-3.24156.11 + 4.10.0-3.24156.11 + 4.10.0-3.24156.11 + 4.10.0-3.24156.11 + 4.10.0-3.24156.11 $(MicrosoftNetCompilersToolsetPackageVersion) From bd03947668b1a008935c997a397c281a6c91bd67 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" Date: Thu, 7 Mar 2024 14:10:22 +0000 Subject: [PATCH 324/577] Update dependencies from https://github.com/dotnet/arcade build 20240305.2 Microsoft.DotNet.Arcade.Sdk , Microsoft.DotNet.Helix.Sdk , Microsoft.DotNet.SignTool , Microsoft.DotNet.XUnitExtensions From Version 8.0.0-beta.24151.4 -> To Version 8.0.0-beta.24155.2 --- eng/Version.Details.xml | 16 ++++++++-------- eng/Versions.props | 4 ++-- global.json | 4 ++-- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 387a196201f3..cf9813e0854e 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -475,22 +475,22 @@ - + https://github.com/dotnet/arcade - cbb61c3a9a42e7c3cce17ee453ff5ecdc7f69282 + fb20e40883718b93d6d60eb0a2446e876ffa3d32 - + https://github.com/dotnet/arcade - cbb61c3a9a42e7c3cce17ee453ff5ecdc7f69282 + fb20e40883718b93d6d60eb0a2446e876ffa3d32 - + https://github.com/dotnet/arcade - cbb61c3a9a42e7c3cce17ee453ff5ecdc7f69282 + fb20e40883718b93d6d60eb0a2446e876ffa3d32 - + https://github.com/dotnet/arcade - cbb61c3a9a42e7c3cce17ee453ff5ecdc7f69282 + fb20e40883718b93d6d60eb0a2446e876ffa3d32 https://dev.azure.com/dnceng/internal/_git/dotnet-runtime diff --git a/eng/Versions.props b/eng/Versions.props index ed8ebb6ba058..61386fc4041f 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -34,7 +34,7 @@ 7.0.0 4.0.0 7.0.0 - 8.0.0-beta.24151.4 + 8.0.0-beta.24155.2 7.0.0-preview.22423.2 8.0.0 4.3.0 @@ -209,7 +209,7 @@ 6.12.0 6.1.0 - 8.0.0-beta.24151.4 + 8.0.0-beta.24155.2 4.18.4 1.3.2 8.0.0-beta.23607.1 diff --git a/global.json b/global.json index 02d788dd3799..627302be1b37 100644 --- a/global.json +++ b/global.json @@ -14,7 +14,7 @@ } }, "msbuild-sdks": { - "Microsoft.DotNet.Arcade.Sdk": "8.0.0-beta.24151.4", - "Microsoft.DotNet.Helix.Sdk": "8.0.0-beta.24151.4" + "Microsoft.DotNet.Arcade.Sdk": "8.0.0-beta.24155.2", + "Microsoft.DotNet.Helix.Sdk": "8.0.0-beta.24155.2" } } From 9eda7b302f8ae230123bd0e0924d7094adf04c37 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 7 Mar 2024 06:42:51 -0800 Subject: [PATCH 325/577] [release/8.0.3xx] Set ProducesDotNetReleaseShippingAssets property in Publishing.props (#39036) Co-authored-by: MilenaHristova --- eng/Publishing.props | 1 + 1 file changed, 1 insertion(+) diff --git a/eng/Publishing.props b/eng/Publishing.props index c36e1cf4f357..0e6e2ec2fbd0 100644 --- a/eng/Publishing.props +++ b/eng/Publishing.props @@ -5,6 +5,7 @@ 3 false + true From bd63619f5038fc0a5130111fae042f29ceef3654 Mon Sep 17 00:00:00 2001 From: Chet Husk Date: Thu, 7 Mar 2024 09:47:23 -0600 Subject: [PATCH 326/577] log message in confusing resource state --- .../Resources/Strings.resx | 98 +++++++++++-------- .../Resources/xlf/Strings.cs.xlf | 5 + .../Resources/xlf/Strings.de.xlf | 5 + .../Resources/xlf/Strings.es.xlf | 5 + .../Resources/xlf/Strings.fr.xlf | 5 + .../Resources/xlf/Strings.it.xlf | 5 + .../Resources/xlf/Strings.ja.xlf | 5 + .../Resources/xlf/Strings.ko.xlf | 5 + .../Resources/xlf/Strings.pl.xlf | 5 + .../Resources/xlf/Strings.pt-BR.xlf | 5 + .../Resources/xlf/Strings.ru.xlf | 5 + .../Resources/xlf/Strings.tr.xlf | 5 + .../Resources/xlf/Strings.zh-Hans.xlf | 5 + .../Resources/xlf/Strings.zh-Hant.xlf | 5 + .../Tasks/CreateNewImage.cs | 7 ++ 15 files changed, 127 insertions(+), 43 deletions(-) diff --git a/src/Containers/Microsoft.NET.Build.Containers/Resources/Strings.resx b/src/Containers/Microsoft.NET.Build.Containers/Resources/Strings.resx index 52f220d00d05..62fd45178f24 100644 --- a/src/Containers/Microsoft.NET.Build.Containers/Resources/Strings.resx +++ b/src/Containers/Microsoft.NET.Build.Containers/Resources/Strings.resx @@ -1,17 +1,17 @@  - - + - + - - - - + + + + - - + + - - + + - - - - + + + + - + - + @@ -183,6 +183,7 @@ No host object detected. + CONTAINER1009: Failed to load image from local registry. stdout: {0} @@ -250,6 +251,7 @@ '{0}' was not a valid container image name, it was normalized to '{1}' + CONTAINER2011: {0} '{1}' does not exist @@ -333,12 +335,15 @@ Pushed image '{0}' to {1}. + Pushed image '{0}' to registry '{1}'. + Building image '{0}' with tags '{1}' on top of base image '{2}'. + Error while reading daemon config: {0} @@ -350,12 +355,15 @@ Uploaded config to registry. + Uploading config to registry at blob '{0}', + Layer '{0}' already exists. + Finished uploading layer '{0}' to '{1}'. @@ -409,4 +417,8 @@ local registry via '{0}' {0} is the command used + + CONTAINER20030: GenerateLabels was disabled but GenerateDigestLabel was enabled - no digest label will be created. + {StrBegin="CONTAINER2030: "} + diff --git a/src/Containers/Microsoft.NET.Build.Containers/Resources/xlf/Strings.cs.xlf b/src/Containers/Microsoft.NET.Build.Containers/Resources/xlf/Strings.cs.xlf index f9f553aaf43a..a947e0d10743 100644 --- a/src/Containers/Microsoft.NET.Build.Containers/Resources/xlf/Strings.cs.xlf +++ b/src/Containers/Microsoft.NET.Build.Containers/Resources/xlf/Strings.cs.xlf @@ -142,6 +142,11 @@ CONTAINER1008: Načtení přihlašovacích údajů pro „{0}“ se nezdařilo: {1} {StrBegin="CONTAINER1008: "} + + CONTAINER20030: GenerateLabels was disabled but GenerateDigestLabel was enabled - no digest label will be created. + CONTAINER20030: GenerateLabels was disabled but GenerateDigestLabel was enabled - no digest label will be created. + {StrBegin="CONTAINER2030: "} + No host object detected. Nebyl zjištěn žádný objekt hostitele. diff --git a/src/Containers/Microsoft.NET.Build.Containers/Resources/xlf/Strings.de.xlf b/src/Containers/Microsoft.NET.Build.Containers/Resources/xlf/Strings.de.xlf index 6e44d62a3cd2..4ed4e238fb26 100644 --- a/src/Containers/Microsoft.NET.Build.Containers/Resources/xlf/Strings.de.xlf +++ b/src/Containers/Microsoft.NET.Build.Containers/Resources/xlf/Strings.de.xlf @@ -142,6 +142,11 @@ CONTAINER1008: Fehler beim Abrufen der Anmeldeinformationen für „{0}“: {1} {StrBegin="CONTAINER1008: "} + + CONTAINER20030: GenerateLabels was disabled but GenerateDigestLabel was enabled - no digest label will be created. + CONTAINER20030: GenerateLabels was disabled but GenerateDigestLabel was enabled - no digest label will be created. + {StrBegin="CONTAINER2030: "} + No host object detected. Es wurde kein Hostobjekt erkannt. diff --git a/src/Containers/Microsoft.NET.Build.Containers/Resources/xlf/Strings.es.xlf b/src/Containers/Microsoft.NET.Build.Containers/Resources/xlf/Strings.es.xlf index 0f6db91cd0c5..c088693a33e9 100644 --- a/src/Containers/Microsoft.NET.Build.Containers/Resources/xlf/Strings.es.xlf +++ b/src/Containers/Microsoft.NET.Build.Containers/Resources/xlf/Strings.es.xlf @@ -142,6 +142,11 @@ CONTAINER1008: No se pudieron recuperar las credenciales de "{0}": {1} {StrBegin="CONTAINER1008: "} + + CONTAINER20030: GenerateLabels was disabled but GenerateDigestLabel was enabled - no digest label will be created. + CONTAINER20030: GenerateLabels was disabled but GenerateDigestLabel was enabled - no digest label will be created. + {StrBegin="CONTAINER2030: "} + No host object detected. No se detectó ningún objeto host. diff --git a/src/Containers/Microsoft.NET.Build.Containers/Resources/xlf/Strings.fr.xlf b/src/Containers/Microsoft.NET.Build.Containers/Resources/xlf/Strings.fr.xlf index e956008b1359..980371788b00 100644 --- a/src/Containers/Microsoft.NET.Build.Containers/Resources/xlf/Strings.fr.xlf +++ b/src/Containers/Microsoft.NET.Build.Containers/Resources/xlf/Strings.fr.xlf @@ -142,6 +142,11 @@ CONTAINER1008: échec de la récupération des informations d’identification pour «{0}» : {1} {StrBegin="CONTAINER1008: "} + + CONTAINER20030: GenerateLabels was disabled but GenerateDigestLabel was enabled - no digest label will be created. + CONTAINER20030: GenerateLabels was disabled but GenerateDigestLabel was enabled - no digest label will be created. + {StrBegin="CONTAINER2030: "} + No host object detected. Aucun objet hôte détecté. diff --git a/src/Containers/Microsoft.NET.Build.Containers/Resources/xlf/Strings.it.xlf b/src/Containers/Microsoft.NET.Build.Containers/Resources/xlf/Strings.it.xlf index 0aea78393d0c..93e605c2f61b 100644 --- a/src/Containers/Microsoft.NET.Build.Containers/Resources/xlf/Strings.it.xlf +++ b/src/Containers/Microsoft.NET.Build.Containers/Resources/xlf/Strings.it.xlf @@ -142,6 +142,11 @@ CONTAINER1008: non è stato possibile recuperare le credenziali per "{0}": {1} {StrBegin="CONTAINER1008: "} + + CONTAINER20030: GenerateLabels was disabled but GenerateDigestLabel was enabled - no digest label will be created. + CONTAINER20030: GenerateLabels was disabled but GenerateDigestLabel was enabled - no digest label will be created. + {StrBegin="CONTAINER2030: "} + No host object detected. Nessun oggetto host rilevato. diff --git a/src/Containers/Microsoft.NET.Build.Containers/Resources/xlf/Strings.ja.xlf b/src/Containers/Microsoft.NET.Build.Containers/Resources/xlf/Strings.ja.xlf index f6bdc23de4a9..59294b2b119e 100644 --- a/src/Containers/Microsoft.NET.Build.Containers/Resources/xlf/Strings.ja.xlf +++ b/src/Containers/Microsoft.NET.Build.Containers/Resources/xlf/Strings.ja.xlf @@ -142,6 +142,11 @@ CONTAINER1008: "{0}" の資格情報を取得できませんでした: {1} {StrBegin="CONTAINER1008: "} + + CONTAINER20030: GenerateLabels was disabled but GenerateDigestLabel was enabled - no digest label will be created. + CONTAINER20030: GenerateLabels was disabled but GenerateDigestLabel was enabled - no digest label will be created. + {StrBegin="CONTAINER2030: "} + No host object detected. ホスト オブジェクトが検出されませんでした。 diff --git a/src/Containers/Microsoft.NET.Build.Containers/Resources/xlf/Strings.ko.xlf b/src/Containers/Microsoft.NET.Build.Containers/Resources/xlf/Strings.ko.xlf index 71a564a7cc8d..6064f1c52985 100644 --- a/src/Containers/Microsoft.NET.Build.Containers/Resources/xlf/Strings.ko.xlf +++ b/src/Containers/Microsoft.NET.Build.Containers/Resources/xlf/Strings.ko.xlf @@ -142,6 +142,11 @@ CONTAINER1008: "{0}"에 대한 자격 증명 검색 실패: {1} {StrBegin="CONTAINER1008: "} + + CONTAINER20030: GenerateLabels was disabled but GenerateDigestLabel was enabled - no digest label will be created. + CONTAINER20030: GenerateLabels was disabled but GenerateDigestLabel was enabled - no digest label will be created. + {StrBegin="CONTAINER2030: "} + No host object detected. 호스트 개체가 검색되지 않았습니다. diff --git a/src/Containers/Microsoft.NET.Build.Containers/Resources/xlf/Strings.pl.xlf b/src/Containers/Microsoft.NET.Build.Containers/Resources/xlf/Strings.pl.xlf index 7131b49d1249..a613da51239e 100644 --- a/src/Containers/Microsoft.NET.Build.Containers/Resources/xlf/Strings.pl.xlf +++ b/src/Containers/Microsoft.NET.Build.Containers/Resources/xlf/Strings.pl.xlf @@ -142,6 +142,11 @@ CONTAINER1008: nie można pobrać poświadczeń dla „{0}”: {1} {StrBegin="CONTAINER1008: "} + + CONTAINER20030: GenerateLabels was disabled but GenerateDigestLabel was enabled - no digest label will be created. + CONTAINER20030: GenerateLabels was disabled but GenerateDigestLabel was enabled - no digest label will be created. + {StrBegin="CONTAINER2030: "} + No host object detected. Nie wykryto obiektu hosta. diff --git a/src/Containers/Microsoft.NET.Build.Containers/Resources/xlf/Strings.pt-BR.xlf b/src/Containers/Microsoft.NET.Build.Containers/Resources/xlf/Strings.pt-BR.xlf index c79987338301..d04206a455c9 100644 --- a/src/Containers/Microsoft.NET.Build.Containers/Resources/xlf/Strings.pt-BR.xlf +++ b/src/Containers/Microsoft.NET.Build.Containers/Resources/xlf/Strings.pt-BR.xlf @@ -142,6 +142,11 @@ CONTAINER1008: Falha ao recuperar credenciais para "{0}": {1} {StrBegin="CONTAINER1008: "} + + CONTAINER20030: GenerateLabels was disabled but GenerateDigestLabel was enabled - no digest label will be created. + CONTAINER20030: GenerateLabels was disabled but GenerateDigestLabel was enabled - no digest label will be created. + {StrBegin="CONTAINER2030: "} + No host object detected. Nenhum objeto de host detectado. diff --git a/src/Containers/Microsoft.NET.Build.Containers/Resources/xlf/Strings.ru.xlf b/src/Containers/Microsoft.NET.Build.Containers/Resources/xlf/Strings.ru.xlf index b33f10b9cc61..8ea7fd659b7b 100644 --- a/src/Containers/Microsoft.NET.Build.Containers/Resources/xlf/Strings.ru.xlf +++ b/src/Containers/Microsoft.NET.Build.Containers/Resources/xlf/Strings.ru.xlf @@ -142,6 +142,11 @@ CONTAINER1008: Не удалось получить учетные данные для "{0}": {1} {StrBegin="CONTAINER1008: "} + + CONTAINER20030: GenerateLabels was disabled but GenerateDigestLabel was enabled - no digest label will be created. + CONTAINER20030: GenerateLabels was disabled but GenerateDigestLabel was enabled - no digest label will be created. + {StrBegin="CONTAINER2030: "} + No host object detected. Объект узла не обнаружен. diff --git a/src/Containers/Microsoft.NET.Build.Containers/Resources/xlf/Strings.tr.xlf b/src/Containers/Microsoft.NET.Build.Containers/Resources/xlf/Strings.tr.xlf index aaa79eda3d82..b78f4de616cb 100644 --- a/src/Containers/Microsoft.NET.Build.Containers/Resources/xlf/Strings.tr.xlf +++ b/src/Containers/Microsoft.NET.Build.Containers/Resources/xlf/Strings.tr.xlf @@ -142,6 +142,11 @@ CONTAINER1008: "{0}" için kimlik bilgileri alınamadı: {1} {StrBegin="CONTAINER1008: "} + + CONTAINER20030: GenerateLabels was disabled but GenerateDigestLabel was enabled - no digest label will be created. + CONTAINER20030: GenerateLabels was disabled but GenerateDigestLabel was enabled - no digest label will be created. + {StrBegin="CONTAINER2030: "} + No host object detected. Ana bilgisayar nesnesi algılanmadı. diff --git a/src/Containers/Microsoft.NET.Build.Containers/Resources/xlf/Strings.zh-Hans.xlf b/src/Containers/Microsoft.NET.Build.Containers/Resources/xlf/Strings.zh-Hans.xlf index 06dfd0303418..90269a19de29 100644 --- a/src/Containers/Microsoft.NET.Build.Containers/Resources/xlf/Strings.zh-Hans.xlf +++ b/src/Containers/Microsoft.NET.Build.Containers/Resources/xlf/Strings.zh-Hans.xlf @@ -142,6 +142,11 @@ CONTAINER1008: 检索“{0}”的凭据失败: {1} {StrBegin="CONTAINER1008: "} + + CONTAINER20030: GenerateLabels was disabled but GenerateDigestLabel was enabled - no digest label will be created. + CONTAINER20030: GenerateLabels was disabled but GenerateDigestLabel was enabled - no digest label will be created. + {StrBegin="CONTAINER2030: "} + No host object detected. 未检测到主机对象。 diff --git a/src/Containers/Microsoft.NET.Build.Containers/Resources/xlf/Strings.zh-Hant.xlf b/src/Containers/Microsoft.NET.Build.Containers/Resources/xlf/Strings.zh-Hant.xlf index 6718c93391b2..53e362e2ec48 100644 --- a/src/Containers/Microsoft.NET.Build.Containers/Resources/xlf/Strings.zh-Hant.xlf +++ b/src/Containers/Microsoft.NET.Build.Containers/Resources/xlf/Strings.zh-Hant.xlf @@ -142,6 +142,11 @@ CONTAINER1008: 無法擷取 "{0}" 的認證: {1} {StrBegin="CONTAINER1008: "} + + CONTAINER20030: GenerateLabels was disabled but GenerateDigestLabel was enabled - no digest label will be created. + CONTAINER20030: GenerateLabels was disabled but GenerateDigestLabel was enabled - no digest label will be created. + {StrBegin="CONTAINER2030: "} + No host object detected. 未偵測到主機物件。 diff --git a/src/Containers/Microsoft.NET.Build.Containers/Tasks/CreateNewImage.cs b/src/Containers/Microsoft.NET.Build.Containers/Tasks/CreateNewImage.cs index d680e3246ab4..ced4b0646988 100644 --- a/src/Containers/Microsoft.NET.Build.Containers/Tasks/CreateNewImage.cs +++ b/src/Containers/Microsoft.NET.Build.Containers/Tasks/CreateNewImage.cs @@ -132,6 +132,13 @@ internal async Task ExecuteAsync(CancellationToken cancellationToken) imageBuilder.AddBaseImageDigestLabel(); } } + else + { + if (GenerateDigestLabel) + { + Log.LogMessageFromResources(nameof(Strings.GenerateDigestLabelWithoutGenerateLabels)); + } + } SetEnvironmentVariables(imageBuilder, ContainerEnvironmentVariables); From 7c710cbcdad284291cdfddb12af2d3741873a54e Mon Sep 17 00:00:00 2001 From: Chet Husk Date: Thu, 7 Mar 2024 13:47:06 -0600 Subject: [PATCH 327/577] fix test --- .../Resources/Strings.Designer.cs | 11 +++++++++++ .../ImageBuilderTests.cs | 11 +++++++---- 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/src/Containers/Microsoft.NET.Build.Containers/Resources/Strings.Designer.cs b/src/Containers/Microsoft.NET.Build.Containers/Resources/Strings.Designer.cs index 10966e412937..16344e631b5a 100644 --- a/src/Containers/Microsoft.NET.Build.Containers/Resources/Strings.Designer.cs +++ b/src/Containers/Microsoft.NET.Build.Containers/Resources/Strings.Designer.cs @@ -893,5 +893,16 @@ internal static string UnrecognizedMediaType return ResourceManager.GetString("UnrecognizedMediaType", resourceCulture); } } + + /// + /// Looks up a localized string similar to CONTAINER20030: GenerateLabels was disabled but GenerateDigestLabel was enabled - no digest label will be created.. + /// + internal static string GenerateDigestLabelWithoutGenerateLabels + { + get + { + return ResourceManager.GetString("GenerateDigestLabelWithoutGenerateLabels", resourceCulture); + } + } } } diff --git a/src/Tests/Microsoft.NET.Build.Containers.UnitTests/ImageBuilderTests.cs b/src/Tests/Microsoft.NET.Build.Containers.UnitTests/ImageBuilderTests.cs index 708f91aa797b..c353c4b28565 100644 --- a/src/Tests/Microsoft.NET.Build.Containers.UnitTests/ImageBuilderTests.cs +++ b/src/Tests/Microsoft.NET.Build.Containers.UnitTests/ImageBuilderTests.cs @@ -13,6 +13,8 @@ public class ImageBuilderTests { private readonly TestLoggerFactory _loggerFactory; + private static readonly string StaticKnownDigestValue = "sha256:338c0b702da88157ba4bb706678e43346ece2e4397b888d59fb2d9f6113c8070"; + public ImageBuilderTests(ITestOutputHelper output) { _loggerFactory = new TestLoggerFactory(output); @@ -681,8 +683,8 @@ public void CanSetBaseImageDigestLabel() JsonNode? result = JsonNode.Parse(builtImage.Config); Assert.NotNull(result); var labels = result["config"]?["Labels"]?.AsObject(); - var digest = labels?.AsEnumerable().First(label => label.Key == "org.opencontainers.image.base.digest"); - digest?.Value.Should().NotBeNull(); + var digest = labels?.AsEnumerable().First(label => label.Key == "org.opencontainers.image.base.digest").Value!; + digest.GetValue().Should().Be(StaticKnownDigestValue); } private ImageBuilder FromBaseImageConfig(string baseImageConfig, [CallerMemberName] string testName = "") @@ -695,9 +697,10 @@ private ImageBuilder FromBaseImageConfig(string baseImageConfig, [CallerMemberNa { mediaType = "", size = 0, - digest = "sha256:0" + digest = "sha256:" }, - Layers = new List() + Layers = new List(), + KnownDigest = StaticKnownDigestValue }; return new ImageBuilder(manifest, new ImageConfig(baseImageConfig), _loggerFactory.CreateLogger(testName)); } From c55692caed0dd7b561a688e620b696a28d2220b8 Mon Sep 17 00:00:00 2001 From: Chet Husk Date: Thu, 7 Mar 2024 17:28:22 -0600 Subject: [PATCH 328/577] fix numbering typo --- .../Resources/Strings.Designer.cs | 2 +- .../Microsoft.NET.Build.Containers/Resources/Strings.resx | 2 +- .../Resources/xlf/Strings.cs.xlf | 4 ++-- .../Resources/xlf/Strings.de.xlf | 4 ++-- .../Resources/xlf/Strings.es.xlf | 4 ++-- .../Resources/xlf/Strings.fr.xlf | 4 ++-- .../Resources/xlf/Strings.it.xlf | 4 ++-- .../Resources/xlf/Strings.ja.xlf | 4 ++-- .../Resources/xlf/Strings.ko.xlf | 4 ++-- .../Resources/xlf/Strings.pl.xlf | 4 ++-- .../Resources/xlf/Strings.pt-BR.xlf | 4 ++-- .../Resources/xlf/Strings.ru.xlf | 4 ++-- .../Resources/xlf/Strings.tr.xlf | 4 ++-- .../Resources/xlf/Strings.zh-Hans.xlf | 4 ++-- .../Resources/xlf/Strings.zh-Hant.xlf | 4 ++-- 15 files changed, 28 insertions(+), 28 deletions(-) diff --git a/src/Containers/Microsoft.NET.Build.Containers/Resources/Strings.Designer.cs b/src/Containers/Microsoft.NET.Build.Containers/Resources/Strings.Designer.cs index 16344e631b5a..7d9ee2b0048d 100644 --- a/src/Containers/Microsoft.NET.Build.Containers/Resources/Strings.Designer.cs +++ b/src/Containers/Microsoft.NET.Build.Containers/Resources/Strings.Designer.cs @@ -895,7 +895,7 @@ internal static string UnrecognizedMediaType } /// - /// Looks up a localized string similar to CONTAINER20030: GenerateLabels was disabled but GenerateDigestLabel was enabled - no digest label will be created.. + /// Looks up a localized string similar to CONTAINER2030: GenerateLabels was disabled but GenerateDigestLabel was enabled - no digest label will be created.. /// internal static string GenerateDigestLabelWithoutGenerateLabels { diff --git a/src/Containers/Microsoft.NET.Build.Containers/Resources/Strings.resx b/src/Containers/Microsoft.NET.Build.Containers/Resources/Strings.resx index 62fd45178f24..97764561ee6b 100644 --- a/src/Containers/Microsoft.NET.Build.Containers/Resources/Strings.resx +++ b/src/Containers/Microsoft.NET.Build.Containers/Resources/Strings.resx @@ -418,7 +418,7 @@ {0} is the command used - CONTAINER20030: GenerateLabels was disabled but GenerateDigestLabel was enabled - no digest label will be created. + CONTAINER2030: GenerateLabels was disabled but GenerateDigestLabel was enabled - no digest label will be created. {StrBegin="CONTAINER2030: "} diff --git a/src/Containers/Microsoft.NET.Build.Containers/Resources/xlf/Strings.cs.xlf b/src/Containers/Microsoft.NET.Build.Containers/Resources/xlf/Strings.cs.xlf index a947e0d10743..055a9be19bd8 100644 --- a/src/Containers/Microsoft.NET.Build.Containers/Resources/xlf/Strings.cs.xlf +++ b/src/Containers/Microsoft.NET.Build.Containers/Resources/xlf/Strings.cs.xlf @@ -143,8 +143,8 @@ {StrBegin="CONTAINER1008: "} - CONTAINER20030: GenerateLabels was disabled but GenerateDigestLabel was enabled - no digest label will be created. - CONTAINER20030: GenerateLabels was disabled but GenerateDigestLabel was enabled - no digest label will be created. + CONTAINER2030: GenerateLabels was disabled but GenerateDigestLabel was enabled - no digest label will be created. + CONTAINER2030: GenerateLabels was disabled but GenerateDigestLabel was enabled - no digest label will be created. {StrBegin="CONTAINER2030: "} diff --git a/src/Containers/Microsoft.NET.Build.Containers/Resources/xlf/Strings.de.xlf b/src/Containers/Microsoft.NET.Build.Containers/Resources/xlf/Strings.de.xlf index 4ed4e238fb26..fbed5b0d3e1c 100644 --- a/src/Containers/Microsoft.NET.Build.Containers/Resources/xlf/Strings.de.xlf +++ b/src/Containers/Microsoft.NET.Build.Containers/Resources/xlf/Strings.de.xlf @@ -143,8 +143,8 @@ {StrBegin="CONTAINER1008: "} - CONTAINER20030: GenerateLabels was disabled but GenerateDigestLabel was enabled - no digest label will be created. - CONTAINER20030: GenerateLabels was disabled but GenerateDigestLabel was enabled - no digest label will be created. + CONTAINER2030: GenerateLabels was disabled but GenerateDigestLabel was enabled - no digest label will be created. + CONTAINER2030: GenerateLabels was disabled but GenerateDigestLabel was enabled - no digest label will be created. {StrBegin="CONTAINER2030: "} diff --git a/src/Containers/Microsoft.NET.Build.Containers/Resources/xlf/Strings.es.xlf b/src/Containers/Microsoft.NET.Build.Containers/Resources/xlf/Strings.es.xlf index c088693a33e9..7364cbdbfe7b 100644 --- a/src/Containers/Microsoft.NET.Build.Containers/Resources/xlf/Strings.es.xlf +++ b/src/Containers/Microsoft.NET.Build.Containers/Resources/xlf/Strings.es.xlf @@ -143,8 +143,8 @@ {StrBegin="CONTAINER1008: "} - CONTAINER20030: GenerateLabels was disabled but GenerateDigestLabel was enabled - no digest label will be created. - CONTAINER20030: GenerateLabels was disabled but GenerateDigestLabel was enabled - no digest label will be created. + CONTAINER2030: GenerateLabels was disabled but GenerateDigestLabel was enabled - no digest label will be created. + CONTAINER2030: GenerateLabels was disabled but GenerateDigestLabel was enabled - no digest label will be created. {StrBegin="CONTAINER2030: "} diff --git a/src/Containers/Microsoft.NET.Build.Containers/Resources/xlf/Strings.fr.xlf b/src/Containers/Microsoft.NET.Build.Containers/Resources/xlf/Strings.fr.xlf index 980371788b00..8afbdbf783fc 100644 --- a/src/Containers/Microsoft.NET.Build.Containers/Resources/xlf/Strings.fr.xlf +++ b/src/Containers/Microsoft.NET.Build.Containers/Resources/xlf/Strings.fr.xlf @@ -143,8 +143,8 @@ {StrBegin="CONTAINER1008: "} - CONTAINER20030: GenerateLabels was disabled but GenerateDigestLabel was enabled - no digest label will be created. - CONTAINER20030: GenerateLabels was disabled but GenerateDigestLabel was enabled - no digest label will be created. + CONTAINER2030: GenerateLabels was disabled but GenerateDigestLabel was enabled - no digest label will be created. + CONTAINER2030: GenerateLabels was disabled but GenerateDigestLabel was enabled - no digest label will be created. {StrBegin="CONTAINER2030: "} diff --git a/src/Containers/Microsoft.NET.Build.Containers/Resources/xlf/Strings.it.xlf b/src/Containers/Microsoft.NET.Build.Containers/Resources/xlf/Strings.it.xlf index 93e605c2f61b..a730bd5e1543 100644 --- a/src/Containers/Microsoft.NET.Build.Containers/Resources/xlf/Strings.it.xlf +++ b/src/Containers/Microsoft.NET.Build.Containers/Resources/xlf/Strings.it.xlf @@ -143,8 +143,8 @@ {StrBegin="CONTAINER1008: "} - CONTAINER20030: GenerateLabels was disabled but GenerateDigestLabel was enabled - no digest label will be created. - CONTAINER20030: GenerateLabels was disabled but GenerateDigestLabel was enabled - no digest label will be created. + CONTAINER2030: GenerateLabels was disabled but GenerateDigestLabel was enabled - no digest label will be created. + CONTAINER2030: GenerateLabels was disabled but GenerateDigestLabel was enabled - no digest label will be created. {StrBegin="CONTAINER2030: "} diff --git a/src/Containers/Microsoft.NET.Build.Containers/Resources/xlf/Strings.ja.xlf b/src/Containers/Microsoft.NET.Build.Containers/Resources/xlf/Strings.ja.xlf index 59294b2b119e..34b1388a710d 100644 --- a/src/Containers/Microsoft.NET.Build.Containers/Resources/xlf/Strings.ja.xlf +++ b/src/Containers/Microsoft.NET.Build.Containers/Resources/xlf/Strings.ja.xlf @@ -143,8 +143,8 @@ {StrBegin="CONTAINER1008: "} - CONTAINER20030: GenerateLabels was disabled but GenerateDigestLabel was enabled - no digest label will be created. - CONTAINER20030: GenerateLabels was disabled but GenerateDigestLabel was enabled - no digest label will be created. + CONTAINER2030: GenerateLabels was disabled but GenerateDigestLabel was enabled - no digest label will be created. + CONTAINER2030: GenerateLabels was disabled but GenerateDigestLabel was enabled - no digest label will be created. {StrBegin="CONTAINER2030: "} diff --git a/src/Containers/Microsoft.NET.Build.Containers/Resources/xlf/Strings.ko.xlf b/src/Containers/Microsoft.NET.Build.Containers/Resources/xlf/Strings.ko.xlf index 6064f1c52985..c91c2674d3fe 100644 --- a/src/Containers/Microsoft.NET.Build.Containers/Resources/xlf/Strings.ko.xlf +++ b/src/Containers/Microsoft.NET.Build.Containers/Resources/xlf/Strings.ko.xlf @@ -143,8 +143,8 @@ {StrBegin="CONTAINER1008: "} - CONTAINER20030: GenerateLabels was disabled but GenerateDigestLabel was enabled - no digest label will be created. - CONTAINER20030: GenerateLabels was disabled but GenerateDigestLabel was enabled - no digest label will be created. + CONTAINER2030: GenerateLabels was disabled but GenerateDigestLabel was enabled - no digest label will be created. + CONTAINER2030: GenerateLabels was disabled but GenerateDigestLabel was enabled - no digest label will be created. {StrBegin="CONTAINER2030: "} diff --git a/src/Containers/Microsoft.NET.Build.Containers/Resources/xlf/Strings.pl.xlf b/src/Containers/Microsoft.NET.Build.Containers/Resources/xlf/Strings.pl.xlf index a613da51239e..88ed0a462dcd 100644 --- a/src/Containers/Microsoft.NET.Build.Containers/Resources/xlf/Strings.pl.xlf +++ b/src/Containers/Microsoft.NET.Build.Containers/Resources/xlf/Strings.pl.xlf @@ -143,8 +143,8 @@ {StrBegin="CONTAINER1008: "} - CONTAINER20030: GenerateLabels was disabled but GenerateDigestLabel was enabled - no digest label will be created. - CONTAINER20030: GenerateLabels was disabled but GenerateDigestLabel was enabled - no digest label will be created. + CONTAINER2030: GenerateLabels was disabled but GenerateDigestLabel was enabled - no digest label will be created. + CONTAINER2030: GenerateLabels was disabled but GenerateDigestLabel was enabled - no digest label will be created. {StrBegin="CONTAINER2030: "} diff --git a/src/Containers/Microsoft.NET.Build.Containers/Resources/xlf/Strings.pt-BR.xlf b/src/Containers/Microsoft.NET.Build.Containers/Resources/xlf/Strings.pt-BR.xlf index d04206a455c9..c42f53aa4e90 100644 --- a/src/Containers/Microsoft.NET.Build.Containers/Resources/xlf/Strings.pt-BR.xlf +++ b/src/Containers/Microsoft.NET.Build.Containers/Resources/xlf/Strings.pt-BR.xlf @@ -143,8 +143,8 @@ {StrBegin="CONTAINER1008: "} - CONTAINER20030: GenerateLabels was disabled but GenerateDigestLabel was enabled - no digest label will be created. - CONTAINER20030: GenerateLabels was disabled but GenerateDigestLabel was enabled - no digest label will be created. + CONTAINER2030: GenerateLabels was disabled but GenerateDigestLabel was enabled - no digest label will be created. + CONTAINER2030: GenerateLabels was disabled but GenerateDigestLabel was enabled - no digest label will be created. {StrBegin="CONTAINER2030: "} diff --git a/src/Containers/Microsoft.NET.Build.Containers/Resources/xlf/Strings.ru.xlf b/src/Containers/Microsoft.NET.Build.Containers/Resources/xlf/Strings.ru.xlf index 8ea7fd659b7b..8c7e84485486 100644 --- a/src/Containers/Microsoft.NET.Build.Containers/Resources/xlf/Strings.ru.xlf +++ b/src/Containers/Microsoft.NET.Build.Containers/Resources/xlf/Strings.ru.xlf @@ -143,8 +143,8 @@ {StrBegin="CONTAINER1008: "} - CONTAINER20030: GenerateLabels was disabled but GenerateDigestLabel was enabled - no digest label will be created. - CONTAINER20030: GenerateLabels was disabled but GenerateDigestLabel was enabled - no digest label will be created. + CONTAINER2030: GenerateLabels was disabled but GenerateDigestLabel was enabled - no digest label will be created. + CONTAINER2030: GenerateLabels was disabled but GenerateDigestLabel was enabled - no digest label will be created. {StrBegin="CONTAINER2030: "} diff --git a/src/Containers/Microsoft.NET.Build.Containers/Resources/xlf/Strings.tr.xlf b/src/Containers/Microsoft.NET.Build.Containers/Resources/xlf/Strings.tr.xlf index b78f4de616cb..961fcff03a61 100644 --- a/src/Containers/Microsoft.NET.Build.Containers/Resources/xlf/Strings.tr.xlf +++ b/src/Containers/Microsoft.NET.Build.Containers/Resources/xlf/Strings.tr.xlf @@ -143,8 +143,8 @@ {StrBegin="CONTAINER1008: "} - CONTAINER20030: GenerateLabels was disabled but GenerateDigestLabel was enabled - no digest label will be created. - CONTAINER20030: GenerateLabels was disabled but GenerateDigestLabel was enabled - no digest label will be created. + CONTAINER2030: GenerateLabels was disabled but GenerateDigestLabel was enabled - no digest label will be created. + CONTAINER2030: GenerateLabels was disabled but GenerateDigestLabel was enabled - no digest label will be created. {StrBegin="CONTAINER2030: "} diff --git a/src/Containers/Microsoft.NET.Build.Containers/Resources/xlf/Strings.zh-Hans.xlf b/src/Containers/Microsoft.NET.Build.Containers/Resources/xlf/Strings.zh-Hans.xlf index 90269a19de29..fadd6de7ab1c 100644 --- a/src/Containers/Microsoft.NET.Build.Containers/Resources/xlf/Strings.zh-Hans.xlf +++ b/src/Containers/Microsoft.NET.Build.Containers/Resources/xlf/Strings.zh-Hans.xlf @@ -143,8 +143,8 @@ {StrBegin="CONTAINER1008: "} - CONTAINER20030: GenerateLabels was disabled but GenerateDigestLabel was enabled - no digest label will be created. - CONTAINER20030: GenerateLabels was disabled but GenerateDigestLabel was enabled - no digest label will be created. + CONTAINER2030: GenerateLabels was disabled but GenerateDigestLabel was enabled - no digest label will be created. + CONTAINER2030: GenerateLabels was disabled but GenerateDigestLabel was enabled - no digest label will be created. {StrBegin="CONTAINER2030: "} diff --git a/src/Containers/Microsoft.NET.Build.Containers/Resources/xlf/Strings.zh-Hant.xlf b/src/Containers/Microsoft.NET.Build.Containers/Resources/xlf/Strings.zh-Hant.xlf index 53e362e2ec48..901f86ed7c37 100644 --- a/src/Containers/Microsoft.NET.Build.Containers/Resources/xlf/Strings.zh-Hant.xlf +++ b/src/Containers/Microsoft.NET.Build.Containers/Resources/xlf/Strings.zh-Hant.xlf @@ -143,8 +143,8 @@ {StrBegin="CONTAINER1008: "} - CONTAINER20030: GenerateLabels was disabled but GenerateDigestLabel was enabled - no digest label will be created. - CONTAINER20030: GenerateLabels was disabled but GenerateDigestLabel was enabled - no digest label will be created. + CONTAINER2030: GenerateLabels was disabled but GenerateDigestLabel was enabled - no digest label will be created. + CONTAINER2030: GenerateLabels was disabled but GenerateDigestLabel was enabled - no digest label will be created. {StrBegin="CONTAINER2030: "} From bd03e2f084339d3d4096762cf438b89b97eda04c Mon Sep 17 00:00:00 2001 From: Chet Husk Date: Thu, 7 Mar 2024 21:40:49 -0600 Subject: [PATCH 329/577] trimmed applications can use -extras images too --- .../KnownStrings.cs | 3 ++- .../PublicAPI/net472/PublicAPI.Unshipped.txt | 2 ++ .../PublicAPI/net8.0/PublicAPI.Unshipped.txt | 2 ++ .../Tasks/ComputeDotnetBaseImageAndTag.cs | 14 ++++++----- .../Microsoft.NET.Build.Containers.targets | 1 + .../ProjectInitializer.cs | 1 + .../TargetsTests.cs | 23 ++++++++++++++++++- 7 files changed, 38 insertions(+), 8 deletions(-) diff --git a/src/Containers/Microsoft.NET.Build.Containers/KnownStrings.cs b/src/Containers/Microsoft.NET.Build.Containers/KnownStrings.cs index be334ac7d271..82df9dc64404 100644 --- a/src/Containers/Microsoft.NET.Build.Containers/KnownStrings.cs +++ b/src/Containers/Microsoft.NET.Build.Containers/KnownStrings.cs @@ -36,6 +36,7 @@ public static class Properties public static readonly string ContainerRuntimeIdentifier = nameof(ContainerRuntimeIdentifier); public static readonly string RuntimeIdentifier = nameof(RuntimeIdentifier); public static readonly string PublishAot = nameof(PublishAot); + public static readonly string PublishTrimmed = nameof(PublishTrimmed); public static readonly string PublishSelfContained = nameof(PublishSelfContained); public static readonly string InvariantGlobalization = nameof(InvariantGlobalization); } @@ -52,7 +53,7 @@ public static class ErrorCodes public static readonly string CONTAINER1011 = nameof(CONTAINER1011); public static readonly string CONTAINER1012 = nameof(CONTAINER1012); public static readonly string CONTAINER1013 = nameof(CONTAINER1013); - + public static readonly string CONTAINER2005 = nameof(CONTAINER2005); public static readonly string CONTAINER2007 = nameof(CONTAINER2007); public static readonly string CONTAINER2008 = nameof(CONTAINER2008); 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 index 89caa7583181..cd5286d426a8 100644 --- a/src/Containers/Microsoft.NET.Build.Containers/PublicAPI/net472/PublicAPI.Unshipped.txt +++ b/src/Containers/Microsoft.NET.Build.Containers/PublicAPI/net472/PublicAPI.Unshipped.txt @@ -110,6 +110,8 @@ Microsoft.NET.Build.Containers.Tasks.ComputeDotnetBaseImageAndTag.FrameworkRefer 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.TargetRuntimeIdentifier.get -> string! diff --git a/src/Containers/Microsoft.NET.Build.Containers/PublicAPI/net8.0/PublicAPI.Unshipped.txt b/src/Containers/Microsoft.NET.Build.Containers/PublicAPI/net8.0/PublicAPI.Unshipped.txt index 3b6d27ca2c1e..c373c4cb4d33 100644 --- a/src/Containers/Microsoft.NET.Build.Containers/PublicAPI/net8.0/PublicAPI.Unshipped.txt +++ b/src/Containers/Microsoft.NET.Build.Containers/PublicAPI/net8.0/PublicAPI.Unshipped.txt @@ -7,6 +7,8 @@ Microsoft.NET.Build.Containers.Tasks.ComputeDotnetBaseImageAndTag.FrameworkRefer 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.TargetRuntimeIdentifier.get -> string! diff --git a/src/Containers/Microsoft.NET.Build.Containers/Tasks/ComputeDotnetBaseImageAndTag.cs b/src/Containers/Microsoft.NET.Build.Containers/Tasks/ComputeDotnetBaseImageAndTag.cs index ecf5190653da..0022dbe30d80 100644 --- a/src/Containers/Microsoft.NET.Build.Containers/Tasks/ComputeDotnetBaseImageAndTag.cs +++ b/src/Containers/Microsoft.NET.Build.Containers/Tasks/ComputeDotnetBaseImageAndTag.cs @@ -46,7 +46,6 @@ public sealed class ComputeDotnetBaseImageAndTag : Microsoft.Build.Utilities.Tas [Required] public string TargetRuntimeIdentifier { get; set; } - /// /// If a project is self-contained then it includes a runtime, and so the runtime-deps image should be used. /// @@ -57,6 +56,8 @@ public sealed class ComputeDotnetBaseImageAndTag : Microsoft.Build.Utilities.Tas /// public bool IsAotPublished { get; set; } + public bool IsTrimmed { get; set; } + /// /// If the project is AOT'd the aot image variant doesn't contain ICU and TZData, so we use this flag to see if we need to use the `-extra` variant that does contain those packages. /// @@ -141,7 +142,7 @@ private bool ComputeRepositoryAndTag([NotNullWhen(true)] out string? repository, tag += IsMuslRid switch { true => "-alpine", - false => "" // TODO: should we default here to chiseled iamges for < 8 apps? + false => "" // TODO: should we default here to chiseled images for < 8 apps? }; Log.LogMessage("Selected base image tag {0}", tag); return true; @@ -153,16 +154,17 @@ private bool ComputeRepositoryAndTag([NotNullWhen(true)] out string? repository, { true => "-alpine", // default to chiseled for AOT, non-musl Apps - false when IsAotPublished => "-jammy-chiseled", // TODO: should we default here to jammy-chiseled for non-musl RIDs? + false when IsAotPublished || IsTrimmed => "-jammy-chiseled", // TODO: should we default here to jammy-chiseled for non-musl RIDs? // default to jammy for non-AOT, non-musl Apps false => "" }; // now choose the variant, if any - if globalization then -extra, else -aot - tag += (IsAotPublished, UsesInvariantGlobalization) switch + tag += (IsAotPublished, IsTrimmed, UsesInvariantGlobalization) switch { - (true, false) => "-extra", - (true, true) => "-aot", + (true, _, false) => "-extra", + (_, true, false) => "-extra", + (true, _, true) => "-aot", _ => "" }; Log.LogMessage("Selected base image tag {0}", tag); diff --git a/src/Containers/packaging/build/Microsoft.NET.Build.Containers.targets b/src/Containers/packaging/build/Microsoft.NET.Build.Containers.targets index ecb8dee489c7..78f3d8ba87dd 100644 --- a/src/Containers/packaging/build/Microsoft.NET.Build.Containers.targets +++ b/src/Containers/packaging/build/Microsoft.NET.Build.Containers.targets @@ -49,6 +49,7 @@ FrameworkReferences="@(FrameworkReference)" IsSelfContained="$(_ContainerIsSelfContained)" IsAotPublished="$(PublishAot)" + IsTrimmed="$(PublishTrimmed)" UsesInvariantGlobalization="$(InvariantGlobalization)" TargetRuntimeIdentifier="$(ContainerRuntimeIdentifier)" ContainerFamily="$(ContainerFamily)"> diff --git a/src/Tests/Microsoft.NET.Build.Containers.IntegrationTests/ProjectInitializer.cs b/src/Tests/Microsoft.NET.Build.Containers.IntegrationTests/ProjectInitializer.cs index 1e19bbb4f7e0..ab2ae0c849c5 100644 --- a/src/Tests/Microsoft.NET.Build.Containers.IntegrationTests/ProjectInitializer.cs +++ b/src/Tests/Microsoft.NET.Build.Containers.IntegrationTests/ProjectInitializer.cs @@ -41,6 +41,7 @@ public static (Project, CapturingLogger, IDisposable) InitProject(Dictionary Date: Thu, 7 Mar 2024 22:28:09 -0600 Subject: [PATCH 330/577] FDD jammy apps with globalization that opt into chiseled need -extra --- .../Tasks/ComputeDotnetBaseImageAndTag.cs | 24 +++++++++-- .../TargetsTests.cs | 43 ++++++++++++++++++- 2 files changed, 62 insertions(+), 5 deletions(-) diff --git a/src/Containers/Microsoft.NET.Build.Containers/Tasks/ComputeDotnetBaseImageAndTag.cs b/src/Containers/Microsoft.NET.Build.Containers/Tasks/ComputeDotnetBaseImageAndTag.cs index 0022dbe30d80..3269886d01ad 100644 --- a/src/Containers/Microsoft.NET.Build.Containers/Tasks/ComputeDotnetBaseImageAndTag.cs +++ b/src/Containers/Microsoft.NET.Build.Containers/Tasks/ComputeDotnetBaseImageAndTag.cs @@ -107,7 +107,7 @@ public override bool Execute() private bool ComputeRepositoryAndTag([NotNullWhen(true)] out string? repository, [NotNullWhen(true)] out string? tag) { - if (ComputeVersionPart() is (string baseVersionPart, bool versionAllowsUsingAOTAndExtrasImages)) + if (ComputeVersionPart() is (string baseVersionPart, SemanticVersion parsedVersion, bool versionAllowsUsingAOTAndExtrasImages)) { Log.LogMessage("Computed base version tag of {0} from TFM {1} and SDK {2}", baseVersionPart, TargetFrameworkVersion, SdkVersion); if (baseVersionPart is null) @@ -133,6 +133,22 @@ private bool ComputeRepositoryAndTag([NotNullWhen(true)] out string? repository, // for the inferred image tags, 'family' aka 'flavor' comes after the 'version' portion (including any preview/rc segments). // so it's safe to just append here tag += $"-{ContainerFamily}"; + Log.LogMessage("Using user-provided ContainerFamily"); + + // we can do one final check here: if the containerfamily is the 'default' for the RID + // in question, and the app is globalized, we can help and add -extra so the app will actually run + + if ( + (!IsMuslRid && ContainerFamily == "jammy-chiseled") // default for linux RID + && !UsesInvariantGlobalization + && versionAllowsUsingAOTAndExtrasImages + // the extras only became available on the stable tags of the FirstVersionWithNewTaggingScheme + && (!parsedVersion.IsPrerelease && parsedVersion.Major == FirstVersionWithNewTaggingScheme)) + { + Log.LogMessage("Using extra variant because the application needs globalization"); + tag += "-extra"; + } + return true; } else @@ -180,18 +196,18 @@ private bool ComputeRepositoryAndTag([NotNullWhen(true)] out string? repository, } } - private (string, bool)? ComputeVersionPart() + private (string, SemanticVersion, bool)? ComputeVersionPart() { if (SemanticVersion.TryParse(TargetFrameworkVersion, out var tfm) && tfm.Major < FirstVersionWithNewTaggingScheme) { // < 8 TFMs don't support the -aot and -extras images - return ($"{tfm.Major}.{tfm.Minor}", false); + return ($"{tfm.Major}.{tfm.Minor}", tfm, false); } else if (SemanticVersion.TryParse(SdkVersion, out var version)) { if (ComputeVersionInternal(version, tfm) is string majMinor) { - return (majMinor, true); + return (majMinor, version, true); } else { diff --git a/src/Tests/Microsoft.NET.Build.Containers.IntegrationTests/TargetsTests.cs b/src/Tests/Microsoft.NET.Build.Containers.IntegrationTests/TargetsTests.cs index 97c3830f21f0..a0dbe789e1a1 100644 --- a/src/Tests/Microsoft.NET.Build.Containers.IntegrationTests/TargetsTests.cs +++ b/src/Tests/Microsoft.NET.Build.Containers.IntegrationTests/TargetsTests.cs @@ -260,7 +260,7 @@ public void WindowsUsersGetLinuxContainers(string sdkPortableRid, string expecte [InlineData("8.0.100-preview.2", "v8.0", "jammy", "8.0.0-preview.2-jammy")] [InlineData("8.0.100-preview.2", "v8.0", "jammy-chiseled", "8.0.0-preview.2-jammy-chiseled")] [InlineData("8.0.100-rc.2", "v8.0", "jammy-chiseled", "8.0.0-rc.2-jammy-chiseled")] - [InlineData("8.0.100", "v8.0", "jammy-chiseled", "8.0-jammy-chiseled")] + [InlineData("8.0.100", "v8.0", "jammy-chiseled", "8.0-jammy-chiseled-extra")] [Theory] public void CanTakeContainerBaseFamilyIntoAccount(string sdkVersion, string tfmMajMin, string containerFamily, string expectedTag) { @@ -383,6 +383,47 @@ public void AOTAppsLessThan8DoNotGetAOTImages(string rid, string expectedImage) computedBaseImageTag.Should().BeEquivalentTo(expectedImage); } + [Fact] + public void FDDConsoleAppWithCulturesAndOptingIntoChiseledGetsExtras() + { + var expectedImage = "mcr.microsoft.com/dotnet/runtime:8.0-jammy-chiseled-extra"; + var (project, logger, d) = ProjectInitializer.InitProject(new() + { + ["NetCoreSdkVersion"] = "8.0.100", + ["TargetFrameworkVersion"] = "v8.0", + [KnownStrings.Properties.ContainerRuntimeIdentifier] = "linux-x64", + [KnownStrings.Properties.ContainerFamily] = "jammy-chiseled", + [KnownStrings.Properties.InvariantGlobalization] = false.ToString(), + }, projectName: $"{nameof(FDDConsoleAppWithCulturesAndOptingIntoChiseledGetsExtras)}"); + using var _ = d; + var instance = project.CreateProjectInstance(global::Microsoft.Build.Execution.ProjectInstanceSettings.None); + instance.Build(new[] { ComputeContainerBaseImage }, null, null, out var outputs).Should().BeTrue(String.Join(Environment.NewLine, logger.Errors)); + var computedBaseImageTag = instance.GetProperty(ContainerBaseImage)?.EvaluatedValue; + computedBaseImageTag.Should().BeEquivalentTo(expectedImage); + } + + [Fact] + public void FDDAspNetAppWithCulturesAndOptingIntoChiseledGetsExtras() + { + var expectedImage = "mcr.microsoft.com/dotnet/aspnet:8.0-jammy-chiseled-extra"; + var (project, logger, d) = ProjectInitializer.InitProject(new() + { + ["NetCoreSdkVersion"] = "8.0.100", + ["TargetFrameworkVersion"] = "v8.0", + [KnownStrings.Properties.ContainerRuntimeIdentifier] = "linux-x64", + [KnownStrings.Properties.ContainerFamily] = "jammy-chiseled", + [KnownStrings.Properties.InvariantGlobalization] = false.ToString(), + }, bonusItems: new() + { + [KnownStrings.Items.FrameworkReference] = KnownFrameworkReferences.WebApp + }, projectName: $"{nameof(FDDAspNetAppWithCulturesAndOptingIntoChiseledGetsExtras)}"); + using var _ = d; + var instance = project.CreateProjectInstance(global::Microsoft.Build.Execution.ProjectInstanceSettings.None); + instance.Build(new[] { ComputeContainerBaseImage }, null, null, out var outputs).Should().BeTrue(String.Join(Environment.NewLine, logger.Errors)); + var computedBaseImageTag = instance.GetProperty(ContainerBaseImage)?.EvaluatedValue; + computedBaseImageTag.Should().BeEquivalentTo(expectedImage); + } + [InlineData("linux-musl-x64", "mcr.microsoft.com/dotnet/runtime-deps:7.0-alpine")] [InlineData("linux-x64", "mcr.microsoft.com/dotnet/runtime-deps:7.0")] [Theory] From df146e6c7badc3c23e2cf6f7a89fdf9809a32640 Mon Sep 17 00:00:00 2001 From: Chet Husk Date: Thu, 7 Mar 2024 22:57:34 -0600 Subject: [PATCH 331/577] do some truth table tests --- .../TargetsTests.cs | 50 +++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git a/src/Tests/Microsoft.NET.Build.Containers.IntegrationTests/TargetsTests.cs b/src/Tests/Microsoft.NET.Build.Containers.IntegrationTests/TargetsTests.cs index a0dbe789e1a1..9913e6a2ddcb 100644 --- a/src/Tests/Microsoft.NET.Build.Containers.IntegrationTests/TargetsTests.cs +++ b/src/Tests/Microsoft.NET.Build.Containers.IntegrationTests/TargetsTests.cs @@ -362,6 +362,56 @@ public void TrimmedAppsWithCulturesGetExtraImages(string rid, string expectedIma computedBaseImageTag.Should().BeEquivalentTo(expectedImage); } + [InlineData("linux-musl-x64", "mcr.microsoft.com/dotnet/runtime-deps:8.0-alpine")] + [InlineData("linux-x64", "mcr.microsoft.com/dotnet/runtime-deps:8.0-jammy-chiseled")] + [Theory] + public void TrimmedAppsWithoutCulturesGetbaseImages(string rid, string expectedImage) + { + var (project, logger, d) = ProjectInitializer.InitProject(new() + { + ["NetCoreSdkVersion"] = "8.0.100", + ["TargetFrameworkVersion"] = "v8.0", + [KnownStrings.Properties.ContainerRuntimeIdentifier] = rid, + [KnownStrings.Properties.PublishSelfContained] = true.ToString(), + [KnownStrings.Properties.PublishTrimmed] = true.ToString(), + [KnownStrings.Properties.InvariantGlobalization] = true.ToString() + }, projectName: $"{nameof(TrimmedAppsWithCulturesGetExtraImages)}_{rid}_{expectedImage}"); + using var _ = d; + var instance = project.CreateProjectInstance(global::Microsoft.Build.Execution.ProjectInstanceSettings.None); + instance.Build(new[] { ComputeContainerBaseImage }, null, null, out var outputs).Should().BeTrue(String.Join(Environment.NewLine, logger.Errors)); + var computedBaseImageTag = instance.GetProperty(ContainerBaseImage)?.EvaluatedValue; + computedBaseImageTag.Should().BeEquivalentTo(expectedImage); + } + + [InlineData(true, false, "linux-musl-x64", true, "mcr.microsoft.com/dotnet/runtime-deps:8.0-alpine")] + [InlineData(true, false, "linux-musl-x64", false, "mcr.microsoft.com/dotnet/runtime-deps:8.0-alpine-extra")] + [InlineData(false, true, "linux-musl-x64", true, "mcr.microsoft.com/dotnet/nightly/runtime-deps:8.0-alpine-aot")] + [InlineData(false, true, "linux-musl-x64", false, "mcr.microsoft.com/dotnet/runtime-deps:8.0-alpine-extra")] + + [InlineData(true, false, "linux-x64", true, "mcr.microsoft.com/dotnet/runtime-deps:8.0-jammy-chiseled")] + [InlineData(true, false, "linux-x64", false, "mcr.microsoft.com/dotnet/runtime-deps:8.0-jammy-chiseled-extra")] + [InlineData(false, true, "linux-x64", true, "mcr.microsoft.com/dotnet/nightly/runtime-deps:8.0-jammy-chiseled-aot")] + [InlineData(false, true, "linux-x64", false, "mcr.microsoft.com/dotnet/runtime-deps:8.0-jammy-chiseled-extra")] + [Theory] + public void TheBigMatrixOfTrimmingInference(bool trimmed, bool aot, string rid, bool invariant, string expectedImage) + { + var (project, logger, d) = ProjectInitializer.InitProject(new() + { + ["NetCoreSdkVersion"] = "8.0.100", + ["TargetFrameworkVersion"] = "v8.0", + [KnownStrings.Properties.ContainerRuntimeIdentifier] = rid, + [KnownStrings.Properties.PublishSelfContained] = true.ToString(), + [KnownStrings.Properties.PublishTrimmed] = trimmed.ToString(), + [KnownStrings.Properties.PublishAot] = aot.ToString(), + [KnownStrings.Properties.InvariantGlobalization] = invariant.ToString() + }, projectName: $"{nameof(TrimmedAppsWithCulturesGetExtraImages)}_{rid}_{expectedImage}"); + using var _ = d; + var instance = project.CreateProjectInstance(global::Microsoft.Build.Execution.ProjectInstanceSettings.None); + instance.Build(new[] { ComputeContainerBaseImage }, null, null, out var outputs).Should().BeTrue(String.Join(Environment.NewLine, logger.Errors)); + var computedBaseImageTag = instance.GetProperty(ContainerBaseImage)?.EvaluatedValue; + computedBaseImageTag.Should().BeEquivalentTo(expectedImage); + } + [InlineData("linux-musl-x64", "mcr.microsoft.com/dotnet/runtime-deps:7.0-alpine")] [InlineData("linux-x64", "mcr.microsoft.com/dotnet/runtime-deps:7.0")] [Theory] From 90bc6a2c6fe771b7c577981bdd4cf27523bb9442 Mon Sep 17 00:00:00 2001 From: Jason Zhai Date: Thu, 7 Mar 2024 23:42:28 -0800 Subject: [PATCH 332/577] [release/8.0.3xx] Add -pr version of pipeline --- .vsts-pr.yml | 211 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 211 insertions(+) create mode 100644 .vsts-pr.yml diff --git a/.vsts-pr.yml b/.vsts-pr.yml new file mode 100644 index 000000000000..fa3e6e08fd08 --- /dev/null +++ b/.vsts-pr.yml @@ -0,0 +1,211 @@ +trigger: + batch: true + branches: + include: + - main + - release/8.0.3xx + - internal/release/* + - exp/* + +pr: + branches: + include: + - main + - release/* + - internal/release/* + + +variables: + - name: teamName + value: Roslyn-Project-System + - name: _DotNetPublishToBlobFeed + value: false + - name: _CIBuild + value: -restore -build -sign -pack -ci + - name: _DotNetArtifactsCategory + value: .NETCore + - name: _DotNetValidationArtifactsCategory + value: .NETCore + - ${{ if or(startswith(variables['Build.SourceBranch'], 'refs/heads/release/'), startswith(variables['Build.SourceBranch'], 'refs/heads/internal/release/'), eq(variables['Build.Reason'], 'Manual')) }}: + - name: PostBuildSign + value: false + - ${{ else }}: + - name: PostBuildSign + value: true + - ${{ if eq(variables['System.TeamProject'], 'public') }}: + - name: _InternalRuntimeDownloadArgs + value: '' + - name: _OfficialBuildArgs + value: '' + - name: "skipComponentGovernanceDetection" + value: "true" + - ${{ if ne(variables['System.TeamProject'], 'public') }}: + - name: _OfficialBuildArgs + value: /p:OfficialBuilder=Microsoft + - name: Codeql.Enabled + value: true + - group: DotNetBuilds storage account read tokens + - name: _InternalRuntimeDownloadArgs + value: /p:DotNetRuntimeSourceFeed=https://dotnetbuilds.blob.core.windows.net/internal + /p:DotNetRuntimeSourceFeedKey=$(dotnetbuilds-internal-container-read-token-base64) + - ${{ if and(ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest')) }}: + - group: DotNet-CLI-SDLValidation-Params + - template: /eng/common/templates/variables/pool-providers.yml + +stages: +- stage: build + displayName: Build + jobs: + - job: Publish_Build_Configuration + pool: + ${{ if eq(variables['System.TeamProject'], 'public') }}: + vmImage: 'windows-2019' + ${{ if eq(variables['System.TeamProject'], 'internal') }}: + name: $(DncEngInternalBuildPool) + demands: ImageOverride -equals windows.vs2019.amd64 + steps: + - publish: $(Build.SourcesDirectory)\eng\BuildConfiguration + artifact: BuildConfiguration + displayName: Publish Build Config + - template: /eng/build.yml + parameters: + agentOs: Windows_NT + pool: + ${{ if eq(variables['System.TeamProject'], 'public') }}: + name: $(DncEngPublicBuildPool) + demands: ImageOverride -equals 1es-windows-2022-open + ${{ if ne(variables['System.TeamProject'], 'public') }}: + name: $(DncEngInternalBuildPool) + demands: ImageOverride -equals 1es-windows-2022 + ${{ if eq(variables['System.TeamProject'], 'public') }}: + helixTargetQueue: Windows.Amd64.VS2022.Pre.Open + ${{ if ne(variables['System.TeamProject'], 'public') }}: + helixTargetQueue: Windows.Amd64.VS2022.Pre + strategy: + matrix: + Build_Release: + _BuildConfig: Release + _PublishArgs: '-publish /p:DotNetPublishUsingPipelines=true' + ${{ if or(eq(variables['System.TeamProject'], 'public'), in(variables['Build.Reason'], 'PullRequest')) }}: + _SignType: test + _Test: -test + ${{ if and(ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest')) }}: + _SignType: real + _Test: '' + - template: /eng/common/templates/job/source-build.yml + parameters: + platform: + name: 'Managed' + container: 'mcr.microsoft.com/dotnet-buildtools/prereqs:centos-stream8' + - ${{ if or(eq(variables['System.TeamProject'], 'public'), in(variables['Build.Reason'], 'PullRequest')) }}: + - template: /eng/build.yml + parameters: + agentOs: Windows_NT_FullFramework + pool: + ${{ if eq(variables['System.TeamProject'], 'public') }}: + name: $(DncEngPublicBuildPool) + demands: ImageOverride -equals 1es-windows-2022-open + ${{ if ne(variables['System.TeamProject'], 'public') }}: + name: $(DncEngInternalBuildPool) + demands: ImageOverride -equals windows.vs2022preview.amd64 + ${{ if eq(variables['System.TeamProject'], 'public') }}: + helixTargetQueue: Windows.Amd64.VS2022.Pre.Open + ${{ if ne(variables['System.TeamProject'], 'public') }}: + helixTargetQueue: Windows.Amd64.VS2022.Pre + strategy: + matrix: + Build_Debug: + _BuildConfig: Debug + _PublishArgs: '' + _SignType: test + _Test: -test + + - template: /eng/build.yml + parameters: + agentOs: Windows_NT_TestAsTools + pool: + ${{ if eq(variables['System.TeamProject'], 'public') }}: + vmImage: 'windows-2019' + ${{ if ne(variables['System.TeamProject'], 'public') }}: + name: $(DncEngInternalBuildPool) + demands: ImageOverride -equals windows.vs2019.amd64 + strategy: + matrix: + Build_Debug: + _BuildConfig: Debug + _PublishArgs: '' + _SignType: test + + - template: /eng/build.yml + parameters: + agentOs: Ubuntu_22_04 + pool: + ${{ if eq(variables['System.TeamProject'], 'public') }}: + vmImage: 'ubuntu-22.04' + ${{ if ne(variables['System.TeamProject'], 'public') }}: + name: $(DncEngInternalBuildPool) + demands: ImageOverride -equals build.ubuntu.2204.amd64 + ${{ if eq(variables['System.TeamProject'], 'public') }}: + helixTargetQueue: ubuntu.2204.amd64.open + ${{ if ne(variables['System.TeamProject'], 'public') }}: + helixTargetQueue: Ubuntu.2204.Amd64 + strategy: + matrix: + Build_Release: + _BuildConfig: Release + _PublishArgs: '' + _SignType: test + _Test: -test + + - template: /eng/build.yml + parameters: + agentOs: Darwin + pool: + vmImage: 'macOS-latest' + ${{ if eq(variables['System.TeamProject'], 'public') }}: + helixTargetQueue: OSX.13.Amd64.Open + ${{ if ne(variables['System.TeamProject'], 'public') }}: + helixTargetQueue: OSX.13.Amd64 + strategy: + matrix: + Build_Release: + _BuildConfig: Release + _PublishArgs: '' + _SignType: test + _Test: -test + + - template: /eng/template-engine.yml + + - ${{ if and(ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest')) }}: + - template: /eng/common/templates/job/publish-build-assets.yml + parameters: + publishUsingPipelines: true + publishAssetsImmediately: true + dependsOn: + - Windows_NT + - Source_Build_Managed + pool: + name: $(DncEngInternalBuildPool) + demands: ImageOverride -equals windows.vs2019.amd64 +- ${{ if and(ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest')) }}: + - template: /eng/common/templates/post-build/post-build.yml + parameters: + publishingInfraVersion: 3 + enableSymbolValidation: false + enableSigningValidation: false + enableNugetValidation: false + enableSourceLinkValidation: false + publishInstallersAndChecksums: true + publishAssetsImmediately: true + SDLValidationParameters: + enable: false + params: ' -SourceToolsList @("policheck","credscan") + -TsaInstanceURL $(_TsaInstanceURL) + -TsaProjectName $(_TsaProjectName) + -TsaNotificationEmail $(_TsaNotificationEmail) + -TsaCodebaseAdmin $(_TsaCodebaseAdmin) + -TsaBugAreaPath $(_TsaBugAreaPath) + -TsaIterationPath $(_TsaIterationPath) + -TsaRepositoryName "dotnet-sdk" + -TsaCodebaseName "dotnet-sdk" + -TsaPublish $True' From d633a0d7a1081eaf4c2f52256081d4127af7ad26 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Fri, 8 Mar 2024 08:39:20 +0000 Subject: [PATCH 333/577] [release/8.0.3xx] Update dependencies from dotnet/razor (#39256) [release/8.0.3xx] Update dependencies from dotnet/razor - Avoid using AssemblyExtension in Razor tools --- eng/Version.Details.xml | 12 ++++++------ eng/Versions.props | 6 +++--- src/RazorSdk/Tool/DiscoverCommand.cs | 15 +++------------ src/RazorSdk/Tool/GenerateCommand.cs | 21 +++------------------ 4 files changed, 15 insertions(+), 39 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 3301193af5d5..9210d81ef183 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -277,18 +277,18 @@ https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore da7e9894ce22ef8cc02e5acc56e95a6f8cf8f644 - + https://github.com/dotnet/razor - c126dfc208bca863b378ae32f8c5cd3f271cbff6 + bb518aa6b6bfbeaabff1845d2dc5a3e7f0df8d44 - + https://github.com/dotnet/razor - c126dfc208bca863b378ae32f8c5cd3f271cbff6 + bb518aa6b6bfbeaabff1845d2dc5a3e7f0df8d44 - + https://github.com/dotnet/razor - c126dfc208bca863b378ae32f8c5cd3f271cbff6 + bb518aa6b6bfbeaabff1845d2dc5a3e7f0df8d44 https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore diff --git a/eng/Versions.props b/eng/Versions.props index dba7a5d71e6a..8b503bb2bcc8 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -175,9 +175,9 @@ - 7.0.0-preview.24154.9 - 7.0.0-preview.24154.9 - 7.0.0-preview.24154.9 + 7.0.0-preview.24157.1 + 7.0.0-preview.24157.1 + 7.0.0-preview.24157.1 diff --git a/src/RazorSdk/Tool/DiscoverCommand.cs b/src/RazorSdk/Tool/DiscoverCommand.cs index 41b6248bec5f..a1162021d4db 100644 --- a/src/RazorSdk/Tool/DiscoverCommand.cs +++ b/src/RazorSdk/Tool/DiscoverCommand.cs @@ -96,9 +96,6 @@ protected override bool ValidateArguments() private const string RazorCompilerFileName = "Microsoft.CodeAnalysis.Razor.Compiler.dll"; - internal static string GetRazorCompilerPath() - => Path.Combine(Path.GetDirectoryName(typeof(Application).Assembly.Location), RazorCompilerFileName); - /// /// Replaces the assembly for MVC extension with the one shipped alongside SDK (as opposed to the one from NuGet). /// @@ -144,16 +141,8 @@ protected override Task ExecuteCoreAsync() return Task.FromResult(ExitCodeFailure); } - // Loading all of the extensions should succeed as the dependency checker will have already - // loaded them. - var extensions = new RazorExtension[ExtensionNames.Values.Count]; - for (var i = 0; i < ExtensionNames.Values.Count; i++) - { - extensions[i] = new AssemblyExtension(ExtensionNames.Values[i], Parent.Loader.LoadFromPath(ExtensionFilePaths.Values[i])); - } - var version = RazorLanguageVersion.Parse(Version.Value()); - var configuration = RazorConfiguration.Create(version, Configuration.Value(), extensions); + var configuration = new RazorConfiguration(version, Configuration.Value(), Extensions: []); var result = ExecuteCore( configuration: configuration, @@ -176,6 +165,8 @@ private int ExecuteCore(RazorConfiguration configuration, string projectDirector var engine = RazorProjectEngine.Create(configuration, RazorProjectFileSystem.Empty, b => { + b.RegisterExtensions(); + b.Features.Add(new DefaultMetadataReferenceFeature() { References = metadataReferences }); b.Features.Add(new CompilationTagHelperFeature()); b.Features.Add(new DefaultTagHelperDescriptorProvider()); diff --git a/src/RazorSdk/Tool/GenerateCommand.cs b/src/RazorSdk/Tool/GenerateCommand.cs index d2280d7353f6..bcd35a5f6430 100644 --- a/src/RazorSdk/Tool/GenerateCommand.cs +++ b/src/RazorSdk/Tool/GenerateCommand.cs @@ -74,25 +74,8 @@ protected override Task ExecuteCoreAsync() return Task.FromResult(ExitCodeFailure); } - // Loading all of the extensions should succeed as the dependency checker will have already - // loaded them. - var extensions = new RazorExtension[ExtensionNames.Values.Count]; - string razorCompilerPath = null; - for (var i = 0; i < ExtensionNames.Values.Count; i++) - { - // If the extension is the Razor compiler, we'll use the referenced assembly (instead of the SDK one). - // Otherwise the extension's ProvideRazorExtensionInitializerAttribute would be different from the AssemblyExtension's one, - // hence the extension would not be loaded properly. - razorCompilerPath ??= DiscoverCommand.GetRazorCompilerPath(); - var assembly = string.Equals(ExtensionFilePaths.Values[i], razorCompilerPath, StringComparison.OrdinalIgnoreCase) - ? typeof(AssemblyExtension).Assembly - : Parent.Loader.LoadFromPath(ExtensionFilePaths.Values[i]); - - extensions[i] = new AssemblyExtension(ExtensionNames.Values[i], assembly); - } - var version = RazorLanguageVersion.Parse(Version.Value()); - var configuration = RazorConfiguration.Create(version, Configuration.Value(), extensions); + var configuration = new RazorConfiguration(version, Configuration.Value(), Extensions: []); var sourceItems = GetSourceItems( Sources.Values, Outputs.Values, RelativePaths.Values, @@ -203,6 +186,8 @@ private int ExecuteCore( var engine = RazorProjectEngine.Create(configuration, compositeFileSystem, b => { + b.RegisterExtensions(); + b.Features.Add(new StaticTagHelperFeature() { TagHelpers = tagHelpers, }); b.Features.Add(new DefaultTypeNameFeature()); From 82bf5d49aab205ebd7b484fad6f9e71d1f0815bc Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" Date: Fri, 8 Mar 2024 13:53:14 +0000 Subject: [PATCH 334/577] Update dependencies from https://github.com/dotnet/msbuild build 20240307.1 Microsoft.SourceBuild.Intermediate.msbuild , Microsoft.Build , Microsoft.Build.Localization From Version 17.10.0-preview-24127-03 -> To Version 17.10.0-preview-24157-01 From 7506eb0b17ff35b852f65e2addef15aee0dfe966 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" Date: Fri, 8 Mar 2024 13:56:08 +0000 Subject: [PATCH 335/577] Update dependencies from https://github.com/dotnet/roslyn build 20240307.14 Microsoft.CodeAnalysis , Microsoft.CodeAnalysis.CSharp , Microsoft.CodeAnalysis.CSharp.CodeStyle , Microsoft.CodeAnalysis.CSharp.Features , Microsoft.CodeAnalysis.CSharp.Workspaces , Microsoft.CodeAnalysis.Workspaces.MSBuild , Microsoft.Net.Compilers.Toolset From Version 4.10.0-3.24156.11 -> To Version 4.10.0-3.24157.14 --- eng/Version.Details.xml | 28 ++++++++++++++-------------- eng/Versions.props | 14 +++++++------- 2 files changed, 21 insertions(+), 21 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 9210d81ef183..505207b671c3 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -78,34 +78,34 @@ ac0d85557969d51bca72181514ddb7d5796fbbe2 - + https://github.com/dotnet/roslyn - d24b5bb8debd2e89df8db13c84694f2982cc41b1 + d7572561e861a99406618acce36939706026e2c5 - + https://github.com/dotnet/roslyn - d24b5bb8debd2e89df8db13c84694f2982cc41b1 + d7572561e861a99406618acce36939706026e2c5 - + https://github.com/dotnet/roslyn - d24b5bb8debd2e89df8db13c84694f2982cc41b1 + d7572561e861a99406618acce36939706026e2c5 - + https://github.com/dotnet/roslyn - d24b5bb8debd2e89df8db13c84694f2982cc41b1 + d7572561e861a99406618acce36939706026e2c5 - + https://github.com/dotnet/roslyn - d24b5bb8debd2e89df8db13c84694f2982cc41b1 + d7572561e861a99406618acce36939706026e2c5 - + https://github.com/dotnet/roslyn - d24b5bb8debd2e89df8db13c84694f2982cc41b1 + d7572561e861a99406618acce36939706026e2c5 - + https://github.com/dotnet/roslyn - d24b5bb8debd2e89df8db13c84694f2982cc41b1 + d7572561e861a99406618acce36939706026e2c5 https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore diff --git a/eng/Versions.props b/eng/Versions.props index 8b503bb2bcc8..9979ef59d5f8 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -154,13 +154,13 @@ - 4.10.0-3.24156.11 - 4.10.0-3.24156.11 - 4.10.0-3.24156.11 - 4.10.0-3.24156.11 - 4.10.0-3.24156.11 - 4.10.0-3.24156.11 - 4.10.0-3.24156.11 + 4.10.0-3.24157.14 + 4.10.0-3.24157.14 + 4.10.0-3.24157.14 + 4.10.0-3.24157.14 + 4.10.0-3.24157.14 + 4.10.0-3.24157.14 + 4.10.0-3.24157.14 $(MicrosoftNetCompilersToolsetPackageVersion) From 768e88599a0cc53015b2b7adf2d196b8ef356ca4 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" Date: Fri, 8 Mar 2024 13:58:34 +0000 Subject: [PATCH 336/577] Update dependencies from https://github.com/dotnet/arcade build 20240306.1 Microsoft.DotNet.Arcade.Sdk , Microsoft.DotNet.Helix.Sdk , Microsoft.DotNet.SignTool , Microsoft.DotNet.XUnitExtensions From Version 8.0.0-beta.24155.2 -> To Version 8.0.0-beta.24156.1 --- eng/Version.Details.xml | 16 ++++++++-------- eng/Versions.props | 4 ++-- global.json | 4 ++-- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 9210d81ef183..268e0e6a25f6 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -475,22 +475,22 @@ - + https://github.com/dotnet/arcade - fb20e40883718b93d6d60eb0a2446e876ffa3d32 + 1307d3e675219bf384f17764651f46767a07960b - + https://github.com/dotnet/arcade - fb20e40883718b93d6d60eb0a2446e876ffa3d32 + 1307d3e675219bf384f17764651f46767a07960b - + https://github.com/dotnet/arcade - fb20e40883718b93d6d60eb0a2446e876ffa3d32 + 1307d3e675219bf384f17764651f46767a07960b - + https://github.com/dotnet/arcade - fb20e40883718b93d6d60eb0a2446e876ffa3d32 + 1307d3e675219bf384f17764651f46767a07960b https://dev.azure.com/dnceng/internal/_git/dotnet-runtime diff --git a/eng/Versions.props b/eng/Versions.props index 8b503bb2bcc8..53d392cf94e5 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -34,7 +34,7 @@ 7.0.0 4.0.0 7.0.0 - 8.0.0-beta.24155.2 + 8.0.0-beta.24156.1 7.0.0-preview.22423.2 8.0.0 4.3.0 @@ -209,7 +209,7 @@ 6.12.0 6.1.0 - 8.0.0-beta.24155.2 + 8.0.0-beta.24156.1 4.18.4 1.3.2 8.0.0-beta.23607.1 diff --git a/global.json b/global.json index 627302be1b37..848c7b7b29f5 100644 --- a/global.json +++ b/global.json @@ -14,7 +14,7 @@ } }, "msbuild-sdks": { - "Microsoft.DotNet.Arcade.Sdk": "8.0.0-beta.24155.2", - "Microsoft.DotNet.Helix.Sdk": "8.0.0-beta.24155.2" + "Microsoft.DotNet.Arcade.Sdk": "8.0.0-beta.24156.1", + "Microsoft.DotNet.Helix.Sdk": "8.0.0-beta.24156.1" } } From 3c8aaecb0bcf25d05de89069338cb5500b9ea066 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Fri, 8 Mar 2024 22:35:56 +0000 Subject: [PATCH 337/577] [release/8.0.3xx] Update dependencies from microsoft/vstest (#39335) [release/8.0.3xx] Update dependencies from microsoft/vstest --- eng/Version.Details.xml | 12 ++++++------ eng/Versions.props | 6 +++--- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 9210d81ef183..0bc19005c511 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -179,18 +179,18 @@ https://github.com/nuget/nuget.client e49fa71580778b8d9c3352ea5ed15ef204f0389f - + https://github.com/microsoft/vstest - 39c7dd12c7ec24d0552513e84d95476f2077ca33 + 316167369cea59e0ad6ece2a39d94a3a6d49cf12 - + https://github.com/microsoft/vstest - 39c7dd12c7ec24d0552513e84d95476f2077ca33 + 316167369cea59e0ad6ece2a39d94a3a6d49cf12 - + https://github.com/microsoft/vstest - 39c7dd12c7ec24d0552513e84d95476f2077ca33 + 316167369cea59e0ad6ece2a39d94a3a6d49cf12 https://dev.azure.com/dnceng/internal/_git/dotnet-runtime diff --git a/eng/Versions.props b/eng/Versions.props index 8b503bb2bcc8..e822c9a95eb3 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -99,9 +99,9 @@ - 17.10.0-preview-24126-02 - 17.10.0-preview-24126-02 - 17.10.0-preview-24126-02 + 17.10.0-preview-24158-02 + 17.10.0-preview-24158-02 + 17.10.0-preview-24158-02 From 5128fc79113a993abe08f1d21630fc9185b11c50 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Fri, 8 Mar 2024 22:36:24 +0000 Subject: [PATCH 338/577] [release/8.0.3xx] Update dependencies from dotnet/fsharp (#39336) [release/8.0.3xx] Update dependencies from dotnet/fsharp --- eng/Version.Details.xml | 8 ++++---- eng/Versions.props | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 0bc19005c511..8ac51896a480 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -64,13 +64,13 @@ 6f44380e4fdea6ddf5c11f48efeb25c2bf181e62 - + https://github.com/dotnet/fsharp - d143cc18f506c455e4e4e86a78fccae2a0ee1acf + 661d88ab1975665fbe8c580e7e2dab01bf264c27 - + https://github.com/dotnet/fsharp - d143cc18f506c455e4e4e86a78fccae2a0ee1acf + 661d88ab1975665fbe8c580e7e2dab01bf264c27 diff --git a/eng/Versions.props b/eng/Versions.props index e822c9a95eb3..de0169a6ef95 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -150,7 +150,7 @@ - 12.8.300-beta.24157.2 + 12.8.300-beta.24157.6 From d09d757b92250229b11ab486946c8ad3ed818be9 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Fri, 8 Mar 2024 22:36:44 +0000 Subject: [PATCH 339/577] [release/8.0.3xx] Update dependencies from dotnet/razor (#39337) [release/8.0.3xx] Update dependencies from dotnet/razor --- eng/Version.Details.xml | 12 ++++++------ eng/Versions.props | 6 +++--- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 8ac51896a480..7c410cb56a57 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -277,18 +277,18 @@ https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore da7e9894ce22ef8cc02e5acc56e95a6f8cf8f644 - + https://github.com/dotnet/razor - bb518aa6b6bfbeaabff1845d2dc5a3e7f0df8d44 + 8a402bac3ea76fd992a5ef0c54768abc9f439f22 - + https://github.com/dotnet/razor - bb518aa6b6bfbeaabff1845d2dc5a3e7f0df8d44 + 8a402bac3ea76fd992a5ef0c54768abc9f439f22 - + https://github.com/dotnet/razor - bb518aa6b6bfbeaabff1845d2dc5a3e7f0df8d44 + 8a402bac3ea76fd992a5ef0c54768abc9f439f22 https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore diff --git a/eng/Versions.props b/eng/Versions.props index de0169a6ef95..b5b7141a9ea6 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -175,9 +175,9 @@ - 7.0.0-preview.24157.1 - 7.0.0-preview.24157.1 - 7.0.0-preview.24157.1 + 7.0.0-preview.24157.6 + 7.0.0-preview.24157.6 + 7.0.0-preview.24157.6 From bffce4f7dc9388094c95b32bbc332eb0df995367 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Fri, 8 Mar 2024 22:38:46 +0000 Subject: [PATCH 340/577] [release/8.0.3xx] Update dependencies from nuget/nuget.client (#39334) [release/8.0.3xx] Update dependencies from nuget/nuget.client --- eng/Version.Details.xml | 64 ++++++++++++++++++++--------------------- eng/Versions.props | 22 +++++++------- 2 files changed, 43 insertions(+), 43 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 7c410cb56a57..e1967032d472 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -115,69 +115,69 @@ https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore da7e9894ce22ef8cc02e5acc56e95a6f8cf8f644 - + https://github.com/nuget/nuget.client - e49fa71580778b8d9c3352ea5ed15ef204f0389f + 309f2e302dff9e6ba8a2f48ddf28133d68ff7eae - + https://github.com/nuget/nuget.client - e49fa71580778b8d9c3352ea5ed15ef204f0389f + 309f2e302dff9e6ba8a2f48ddf28133d68ff7eae - + https://github.com/nuget/nuget.client - e49fa71580778b8d9c3352ea5ed15ef204f0389f + 309f2e302dff9e6ba8a2f48ddf28133d68ff7eae - + https://github.com/nuget/nuget.client - e49fa71580778b8d9c3352ea5ed15ef204f0389f + 309f2e302dff9e6ba8a2f48ddf28133d68ff7eae - + https://github.com/nuget/nuget.client - e49fa71580778b8d9c3352ea5ed15ef204f0389f + 309f2e302dff9e6ba8a2f48ddf28133d68ff7eae - + https://github.com/nuget/nuget.client - e49fa71580778b8d9c3352ea5ed15ef204f0389f + 309f2e302dff9e6ba8a2f48ddf28133d68ff7eae - + https://github.com/nuget/nuget.client - e49fa71580778b8d9c3352ea5ed15ef204f0389f + 309f2e302dff9e6ba8a2f48ddf28133d68ff7eae - + https://github.com/nuget/nuget.client - e49fa71580778b8d9c3352ea5ed15ef204f0389f + 309f2e302dff9e6ba8a2f48ddf28133d68ff7eae - + https://github.com/nuget/nuget.client - e49fa71580778b8d9c3352ea5ed15ef204f0389f + 309f2e302dff9e6ba8a2f48ddf28133d68ff7eae - + https://github.com/nuget/nuget.client - e49fa71580778b8d9c3352ea5ed15ef204f0389f + 309f2e302dff9e6ba8a2f48ddf28133d68ff7eae - + https://github.com/nuget/nuget.client - e49fa71580778b8d9c3352ea5ed15ef204f0389f + 309f2e302dff9e6ba8a2f48ddf28133d68ff7eae - + https://github.com/nuget/nuget.client - e49fa71580778b8d9c3352ea5ed15ef204f0389f + 309f2e302dff9e6ba8a2f48ddf28133d68ff7eae - + https://github.com/nuget/nuget.client - e49fa71580778b8d9c3352ea5ed15ef204f0389f + 309f2e302dff9e6ba8a2f48ddf28133d68ff7eae - + https://github.com/nuget/nuget.client - e49fa71580778b8d9c3352ea5ed15ef204f0389f + 309f2e302dff9e6ba8a2f48ddf28133d68ff7eae - + https://github.com/nuget/nuget.client - e49fa71580778b8d9c3352ea5ed15ef204f0389f + 309f2e302dff9e6ba8a2f48ddf28133d68ff7eae - + https://github.com/nuget/nuget.client - e49fa71580778b8d9c3352ea5ed15ef204f0389f + 309f2e302dff9e6ba8a2f48ddf28133d68ff7eae https://github.com/microsoft/vstest diff --git a/eng/Versions.props b/eng/Versions.props index b5b7141a9ea6..98bf9edfd20a 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -82,18 +82,18 @@ - 6.10.0-preview.2.73 - 6.10.0-preview.2.73 + 6.10.0-preview.2.76 + 6.10.0-preview.2.76 6.0.0-rc.278 - 6.10.0-preview.2.73 - 6.10.0-preview.2.73 - 6.10.0-preview.2.73 - 6.10.0-preview.2.73 - 6.10.0-preview.2.73 - 6.10.0-preview.2.73 - 6.10.0-preview.2.73 - 6.10.0-preview.2.73 - 6.10.0-preview.2.73 + 6.10.0-preview.2.76 + 6.10.0-preview.2.76 + 6.10.0-preview.2.76 + 6.10.0-preview.2.76 + 6.10.0-preview.2.76 + 6.10.0-preview.2.76 + 6.10.0-preview.2.76 + 6.10.0-preview.2.76 + 6.10.0-preview.2.76 $(NuGetPackagingPackageVersion) $(NuGetProjectModelPackageVersion) From 114884c8584583b36402efbbfbe342edb652e4e9 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Fri, 8 Mar 2024 22:39:02 +0000 Subject: [PATCH 341/577] [release/8.0.3xx] Update dependencies from dotnet/templating (#39339) [release/8.0.3xx] Update dependencies from dotnet/templating --- eng/Version.Details.xml | 8 ++++---- eng/Versions.props | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index e1967032d472..30545ff61c76 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -1,14 +1,14 @@ - + https://github.com/dotnet/templating - a63f333eb83176754b5023bfa20b2edda8f74798 + 9286c228492e41e2374712cd666b365a1ec91235 - + https://github.com/dotnet/templating - a63f333eb83176754b5023bfa20b2edda8f74798 + 9286c228492e41e2374712cd666b365a1ec91235 https://dev.azure.com/dnceng/internal/_git/dotnet-runtime diff --git a/eng/Versions.props b/eng/Versions.props index 98bf9edfd20a..bdbe6aa508c9 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -137,13 +137,13 @@ - 8.0.300-preview.24153.1 + 8.0.300-preview.24157.1 $(MicrosoftTemplateEngineAbstractionsPackageVersion) $(MicrosoftTemplateEngineAbstractionsPackageVersion) $(MicrosoftTemplateEngineAbstractionsPackageVersion) $(MicrosoftTemplateEngineAbstractionsPackageVersion) - 8.0.300-preview.24153.1 + 8.0.300-preview.24157.1 $(MicrosoftTemplateEngineMocksPackageVersion) $(MicrosoftTemplateEngineAbstractionsPackageVersion) $(MicrosoftTemplateEngineMocksPackageVersion) From 3050e4c5fd948cf10f1c1f3b00a2d90bf58cb9a0 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" Date: Sat, 9 Mar 2024 13:55:26 +0000 Subject: [PATCH 342/577] Update dependencies from https://github.com/dotnet/msbuild build 20240307.1 Microsoft.SourceBuild.Intermediate.msbuild , Microsoft.Build , Microsoft.Build.Localization From Version 17.10.0-preview-24127-03 -> To Version 17.10.0-preview-24157-01 From f5fa934e436eea0efbbfeed1e026183a93104625 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" Date: Sat, 9 Mar 2024 13:55:49 +0000 Subject: [PATCH 343/577] Update dependencies from https://github.com/microsoft/vstest build 20240308.6 Microsoft.NET.Test.Sdk , Microsoft.TestPlatform.Build , Microsoft.TestPlatform.CLI From Version 17.10.0-preview-24158-02 -> To Version 17.10.0-preview-24158-06 --- eng/Version.Details.xml | 6 +++--- eng/Versions.props | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 30545ff61c76..cdc865f090f8 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -179,16 +179,16 @@ https://github.com/nuget/nuget.client 309f2e302dff9e6ba8a2f48ddf28133d68ff7eae - + https://github.com/microsoft/vstest 316167369cea59e0ad6ece2a39d94a3a6d49cf12 - + https://github.com/microsoft/vstest 316167369cea59e0ad6ece2a39d94a3a6d49cf12 - + https://github.com/microsoft/vstest 316167369cea59e0ad6ece2a39d94a3a6d49cf12 diff --git a/eng/Versions.props b/eng/Versions.props index bdbe6aa508c9..a8bba306b38a 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -99,9 +99,9 @@ - 17.10.0-preview-24158-02 - 17.10.0-preview-24158-02 - 17.10.0-preview-24158-02 + 17.10.0-preview-24158-06 + 17.10.0-preview-24158-06 + 17.10.0-preview-24158-06 From 6bf7ac44bd3606ab19b501bb943ab281478e44db Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" Date: Sat, 9 Mar 2024 13:56:15 +0000 Subject: [PATCH 344/577] Update dependencies from https://github.com/dotnet/razor build 20240308.2 Microsoft.AspNetCore.Mvc.Razor.Extensions.Tooling.Internal , Microsoft.CodeAnalysis.Razor.Tooling.Internal , Microsoft.NET.Sdk.Razor.SourceGenerators.Transport From Version 7.0.0-preview.24157.6 -> To Version 7.0.0-preview.24158.2 --- eng/Version.Details.xml | 12 ++++++------ eng/Versions.props | 6 +++--- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 30545ff61c76..dfdd080cc43b 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -277,18 +277,18 @@ https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore da7e9894ce22ef8cc02e5acc56e95a6f8cf8f644 - + https://github.com/dotnet/razor - 8a402bac3ea76fd992a5ef0c54768abc9f439f22 + 2e2e848d22f9944fc3d893ab7d4badc1dfaf88e7 - + https://github.com/dotnet/razor - 8a402bac3ea76fd992a5ef0c54768abc9f439f22 + 2e2e848d22f9944fc3d893ab7d4badc1dfaf88e7 - + https://github.com/dotnet/razor - 8a402bac3ea76fd992a5ef0c54768abc9f439f22 + 2e2e848d22f9944fc3d893ab7d4badc1dfaf88e7 https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore diff --git a/eng/Versions.props b/eng/Versions.props index bdbe6aa508c9..0725e7c2b048 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -175,9 +175,9 @@ - 7.0.0-preview.24157.6 - 7.0.0-preview.24157.6 - 7.0.0-preview.24157.6 + 7.0.0-preview.24158.2 + 7.0.0-preview.24158.2 + 7.0.0-preview.24158.2 From be3301e9e371c67ff2853fa436824639c3087b18 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" Date: Sat, 9 Mar 2024 13:57:49 +0000 Subject: [PATCH 345/577] Update dependencies from https://github.com/dotnet/roslyn build 20240308.5 Microsoft.CodeAnalysis , Microsoft.CodeAnalysis.CSharp , Microsoft.CodeAnalysis.CSharp.CodeStyle , Microsoft.CodeAnalysis.CSharp.Features , Microsoft.CodeAnalysis.CSharp.Workspaces , Microsoft.CodeAnalysis.Workspaces.MSBuild , Microsoft.Net.Compilers.Toolset From Version 4.10.0-3.24156.11 -> To Version 4.10.0-3.24158.5 --- eng/Version.Details.xml | 28 ++++++++++++++-------------- eng/Versions.props | 14 +++++++------- 2 files changed, 21 insertions(+), 21 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 505207b671c3..755ce742a914 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -78,34 +78,34 @@ ac0d85557969d51bca72181514ddb7d5796fbbe2 - + https://github.com/dotnet/roslyn - d7572561e861a99406618acce36939706026e2c5 + 026c96327b02c5ce4d3208f821e02d2ffa825312 - + https://github.com/dotnet/roslyn - d7572561e861a99406618acce36939706026e2c5 + 026c96327b02c5ce4d3208f821e02d2ffa825312 - + https://github.com/dotnet/roslyn - d7572561e861a99406618acce36939706026e2c5 + 026c96327b02c5ce4d3208f821e02d2ffa825312 - + https://github.com/dotnet/roslyn - d7572561e861a99406618acce36939706026e2c5 + 026c96327b02c5ce4d3208f821e02d2ffa825312 - + https://github.com/dotnet/roslyn - d7572561e861a99406618acce36939706026e2c5 + 026c96327b02c5ce4d3208f821e02d2ffa825312 - + https://github.com/dotnet/roslyn - d7572561e861a99406618acce36939706026e2c5 + 026c96327b02c5ce4d3208f821e02d2ffa825312 - + https://github.com/dotnet/roslyn - d7572561e861a99406618acce36939706026e2c5 + 026c96327b02c5ce4d3208f821e02d2ffa825312 https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore diff --git a/eng/Versions.props b/eng/Versions.props index 9979ef59d5f8..6a1948bb4599 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -154,13 +154,13 @@ - 4.10.0-3.24157.14 - 4.10.0-3.24157.14 - 4.10.0-3.24157.14 - 4.10.0-3.24157.14 - 4.10.0-3.24157.14 - 4.10.0-3.24157.14 - 4.10.0-3.24157.14 + 4.10.0-3.24158.5 + 4.10.0-3.24158.5 + 4.10.0-3.24158.5 + 4.10.0-3.24158.5 + 4.10.0-3.24158.5 + 4.10.0-3.24158.5 + 4.10.0-3.24158.5 $(MicrosoftNetCompilersToolsetPackageVersion) From 861b5004558c995ed5238ba1faed33abcdcb627f Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" Date: Sat, 9 Mar 2024 13:58:13 +0000 Subject: [PATCH 346/577] Update dependencies from https://github.com/dotnet/templating build 20240308.1 Microsoft.TemplateEngine.Abstractions , Microsoft.TemplateEngine.Mocks From Version 8.0.300-preview.24157.1 -> To Version 8.0.300-preview.24158.1 --- eng/Version.Details.xml | 8 ++++---- eng/Versions.props | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 30545ff61c76..fa95aa84aeac 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -1,14 +1,14 @@ - + https://github.com/dotnet/templating - 9286c228492e41e2374712cd666b365a1ec91235 + 5848011bb33e58542b15352d4bc6003267c56a1f - + https://github.com/dotnet/templating - 9286c228492e41e2374712cd666b365a1ec91235 + 5848011bb33e58542b15352d4bc6003267c56a1f https://dev.azure.com/dnceng/internal/_git/dotnet-runtime diff --git a/eng/Versions.props b/eng/Versions.props index bdbe6aa508c9..cafee043f42a 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -137,13 +137,13 @@ - 8.0.300-preview.24157.1 + 8.0.300-preview.24158.1 $(MicrosoftTemplateEngineAbstractionsPackageVersion) $(MicrosoftTemplateEngineAbstractionsPackageVersion) $(MicrosoftTemplateEngineAbstractionsPackageVersion) $(MicrosoftTemplateEngineAbstractionsPackageVersion) - 8.0.300-preview.24157.1 + 8.0.300-preview.24158.1 $(MicrosoftTemplateEngineMocksPackageVersion) $(MicrosoftTemplateEngineAbstractionsPackageVersion) $(MicrosoftTemplateEngineMocksPackageVersion) From 91b5afb73b2cd03d45160a8bf0903442d2dade29 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" Date: Sat, 9 Mar 2024 14:00:08 +0000 Subject: [PATCH 347/577] Update dependencies from https://github.com/dotnet/arcade build 20240308.1 Microsoft.DotNet.Arcade.Sdk , Microsoft.DotNet.Helix.Sdk , Microsoft.DotNet.SignTool , Microsoft.DotNet.XUnitExtensions From Version 8.0.0-beta.24155.2 -> To Version 8.0.0-beta.24158.1 --- eng/Version.Details.xml | 16 ++++++++-------- eng/Versions.props | 4 ++-- eng/common/SetupNugetSources.ps1 | 26 +++++++++++++------------- global.json | 4 ++-- 4 files changed, 25 insertions(+), 25 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 268e0e6a25f6..23c3aec6c12a 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -475,22 +475,22 @@ - + https://github.com/dotnet/arcade - 1307d3e675219bf384f17764651f46767a07960b + 334436593593431d9dfe13538a8f745f31b3dd59 - + https://github.com/dotnet/arcade - 1307d3e675219bf384f17764651f46767a07960b + 334436593593431d9dfe13538a8f745f31b3dd59 - + https://github.com/dotnet/arcade - 1307d3e675219bf384f17764651f46767a07960b + 334436593593431d9dfe13538a8f745f31b3dd59 - + https://github.com/dotnet/arcade - 1307d3e675219bf384f17764651f46767a07960b + 334436593593431d9dfe13538a8f745f31b3dd59 https://dev.azure.com/dnceng/internal/_git/dotnet-runtime diff --git a/eng/Versions.props b/eng/Versions.props index 53d392cf94e5..2257dd888de1 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -34,7 +34,7 @@ 7.0.0 4.0.0 7.0.0 - 8.0.0-beta.24156.1 + 8.0.0-beta.24158.1 7.0.0-preview.22423.2 8.0.0 4.3.0 @@ -209,7 +209,7 @@ 6.12.0 6.1.0 - 8.0.0-beta.24156.1 + 8.0.0-beta.24158.1 4.18.4 1.3.2 8.0.0-beta.23607.1 diff --git a/eng/common/SetupNugetSources.ps1 b/eng/common/SetupNugetSources.ps1 index 6c65e81925f2..efa2fd72bfaa 100644 --- a/eng/common/SetupNugetSources.ps1 +++ b/eng/common/SetupNugetSources.ps1 @@ -35,7 +35,7 @@ Set-StrictMode -Version 2.0 . $PSScriptRoot\tools.ps1 # Add source entry to PackageSources -function AddPackageSource($sources, $SourceName, $SourceEndPoint, $creds, $Username, $Password) { +function AddPackageSource($sources, $SourceName, $SourceEndPoint, $creds, $Username, $pwd) { $packageSource = $sources.SelectSingleNode("add[@key='$SourceName']") if ($packageSource -eq $null) @@ -48,12 +48,11 @@ function AddPackageSource($sources, $SourceName, $SourceEndPoint, $creds, $Usern else { Write-Host "Package source $SourceName already present." } - - AddCredential -Creds $creds -Source $SourceName -Username $Username -Password $Password + AddCredential -Creds $creds -Source $SourceName -Username $Username -pwd $pwd } # Add a credential node for the specified source -function AddCredential($creds, $source, $username, $password) { +function AddCredential($creds, $source, $username, $pwd) { # Looks for credential configuration for the given SourceName. Create it if none is found. $sourceElement = $creds.SelectSingleNode($Source) if ($sourceElement -eq $null) @@ -82,17 +81,18 @@ function AddCredential($creds, $source, $username, $password) { $passwordElement.SetAttribute("key", "ClearTextPassword") $sourceElement.AppendChild($passwordElement) | Out-Null } - $passwordElement.SetAttribute("value", $Password) + + $passwordElement.SetAttribute("value", $pwd) } -function InsertMaestroPrivateFeedCredentials($Sources, $Creds, $Username, $Password) { +function InsertMaestroPrivateFeedCredentials($Sources, $Creds, $Username, $pwd) { $maestroPrivateSources = $Sources.SelectNodes("add[contains(@key,'darc-int')]") Write-Host "Inserting credentials for $($maestroPrivateSources.Count) Maestro's private feeds." ForEach ($PackageSource in $maestroPrivateSources) { Write-Host "`tInserting credential for Maestro's feed:" $PackageSource.Key - AddCredential -Creds $creds -Source $PackageSource.Key -Username $Username -Password $Password + AddCredential -Creds $creds -Source $PackageSource.Key -Username $Username -pwd $pwd } } @@ -144,13 +144,13 @@ if ($disabledSources -ne $null) { $userName = "dn-bot" # Insert credential nodes for Maestro's private feeds -InsertMaestroPrivateFeedCredentials -Sources $sources -Creds $creds -Username $userName -Password $Password +InsertMaestroPrivateFeedCredentials -Sources $sources -Creds $creds -Username $userName -pwd $Password # 3.1 uses a different feed url format so it's handled differently here $dotnet31Source = $sources.SelectSingleNode("add[@key='dotnet3.1']") if ($dotnet31Source -ne $null) { - AddPackageSource -Sources $sources -SourceName "dotnet3.1-internal" -SourceEndPoint "https://pkgs.dev.azure.com/dnceng/_packaging/dotnet3.1-internal/nuget/v2" -Creds $creds -Username $userName -Password $Password - AddPackageSource -Sources $sources -SourceName "dotnet3.1-internal-transport" -SourceEndPoint "https://pkgs.dev.azure.com/dnceng/_packaging/dotnet3.1-internal-transport/nuget/v2" -Creds $creds -Username $userName -Password $Password + AddPackageSource -Sources $sources -SourceName "dotnet3.1-internal" -SourceEndPoint "https://pkgs.dev.azure.com/dnceng/_packaging/dotnet3.1-internal/nuget/v2" -Creds $creds -Username $userName -pwd $Password + AddPackageSource -Sources $sources -SourceName "dotnet3.1-internal-transport" -SourceEndPoint "https://pkgs.dev.azure.com/dnceng/_packaging/dotnet3.1-internal-transport/nuget/v2" -Creds $creds -Username $userName -pwd $Password } $dotnetVersions = @('5','6','7','8') @@ -159,9 +159,9 @@ foreach ($dotnetVersion in $dotnetVersions) { $feedPrefix = "dotnet" + $dotnetVersion; $dotnetSource = $sources.SelectSingleNode("add[@key='$feedPrefix']") if ($dotnetSource -ne $null) { - AddPackageSource -Sources $sources -SourceName "$feedPrefix-internal" -SourceEndPoint "https://pkgs.dev.azure.com/dnceng/internal/_packaging/$feedPrefix-internal/nuget/v2" -Creds $creds -Username $userName -Password $Password - AddPackageSource -Sources $sources -SourceName "$feedPrefix-internal-transport" -SourceEndPoint "https://pkgs.dev.azure.com/dnceng/internal/_packaging/$feedPrefix-internal-transport/nuget/v2" -Creds $creds -Username $userName -Password $Password + AddPackageSource -Sources $sources -SourceName "$feedPrefix-internal" -SourceEndPoint "https://pkgs.dev.azure.com/dnceng/internal/_packaging/$feedPrefix-internal/nuget/v2" -Creds $creds -Username $userName -pwd $Password + AddPackageSource -Sources $sources -SourceName "$feedPrefix-internal-transport" -SourceEndPoint "https://pkgs.dev.azure.com/dnceng/internal/_packaging/$feedPrefix-internal-transport/nuget/v2" -Creds $creds -Username $userName -pwd $Password } } -$doc.Save($filename) +$doc.Save($filename) \ No newline at end of file diff --git a/global.json b/global.json index 848c7b7b29f5..ca88ff11a2c0 100644 --- a/global.json +++ b/global.json @@ -14,7 +14,7 @@ } }, "msbuild-sdks": { - "Microsoft.DotNet.Arcade.Sdk": "8.0.0-beta.24156.1", - "Microsoft.DotNet.Helix.Sdk": "8.0.0-beta.24156.1" + "Microsoft.DotNet.Arcade.Sdk": "8.0.0-beta.24158.1", + "Microsoft.DotNet.Helix.Sdk": "8.0.0-beta.24158.1" } } From 5fa06be7a7bc00c572db72180eb440e094b69ac5 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" Date: Sun, 10 Mar 2024 12:48:12 +0000 Subject: [PATCH 348/577] Update dependencies from https://github.com/nuget/nuget.client build 6.10.0.78 Microsoft.Build.NuGetSdkResolver , NuGet.Build.Tasks , NuGet.Build.Tasks.Console , NuGet.Build.Tasks.Pack , NuGet.CommandLine.XPlat , NuGet.Commands , NuGet.Common , NuGet.Configuration , NuGet.Credentials , NuGet.DependencyResolver.Core , NuGet.Frameworks , NuGet.LibraryModel , NuGet.Packaging , NuGet.ProjectModel , NuGet.Protocol , NuGet.Versioning From Version 6.10.0-preview.2.76 -> To Version 6.10.0-preview.2.78 --- eng/Version.Details.xml | 64 ++++++++++++++++++++--------------------- eng/Versions.props | 22 +++++++------- 2 files changed, 43 insertions(+), 43 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 30545ff61c76..781766d51860 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -115,69 +115,69 @@ https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore da7e9894ce22ef8cc02e5acc56e95a6f8cf8f644 - + https://github.com/nuget/nuget.client - 309f2e302dff9e6ba8a2f48ddf28133d68ff7eae + 2fdd0d41e33c3354de2750fe154b56751a6682aa - + https://github.com/nuget/nuget.client - 309f2e302dff9e6ba8a2f48ddf28133d68ff7eae + 2fdd0d41e33c3354de2750fe154b56751a6682aa - + https://github.com/nuget/nuget.client - 309f2e302dff9e6ba8a2f48ddf28133d68ff7eae + 2fdd0d41e33c3354de2750fe154b56751a6682aa - + https://github.com/nuget/nuget.client - 309f2e302dff9e6ba8a2f48ddf28133d68ff7eae + 2fdd0d41e33c3354de2750fe154b56751a6682aa - + https://github.com/nuget/nuget.client - 309f2e302dff9e6ba8a2f48ddf28133d68ff7eae + 2fdd0d41e33c3354de2750fe154b56751a6682aa - + https://github.com/nuget/nuget.client - 309f2e302dff9e6ba8a2f48ddf28133d68ff7eae + 2fdd0d41e33c3354de2750fe154b56751a6682aa - + https://github.com/nuget/nuget.client - 309f2e302dff9e6ba8a2f48ddf28133d68ff7eae + 2fdd0d41e33c3354de2750fe154b56751a6682aa - + https://github.com/nuget/nuget.client - 309f2e302dff9e6ba8a2f48ddf28133d68ff7eae + 2fdd0d41e33c3354de2750fe154b56751a6682aa - + https://github.com/nuget/nuget.client - 309f2e302dff9e6ba8a2f48ddf28133d68ff7eae + 2fdd0d41e33c3354de2750fe154b56751a6682aa - + https://github.com/nuget/nuget.client - 309f2e302dff9e6ba8a2f48ddf28133d68ff7eae + 2fdd0d41e33c3354de2750fe154b56751a6682aa - + https://github.com/nuget/nuget.client - 309f2e302dff9e6ba8a2f48ddf28133d68ff7eae + 2fdd0d41e33c3354de2750fe154b56751a6682aa - + https://github.com/nuget/nuget.client - 309f2e302dff9e6ba8a2f48ddf28133d68ff7eae + 2fdd0d41e33c3354de2750fe154b56751a6682aa - + https://github.com/nuget/nuget.client - 309f2e302dff9e6ba8a2f48ddf28133d68ff7eae + 2fdd0d41e33c3354de2750fe154b56751a6682aa - + https://github.com/nuget/nuget.client - 309f2e302dff9e6ba8a2f48ddf28133d68ff7eae + 2fdd0d41e33c3354de2750fe154b56751a6682aa - + https://github.com/nuget/nuget.client - 309f2e302dff9e6ba8a2f48ddf28133d68ff7eae + 2fdd0d41e33c3354de2750fe154b56751a6682aa - + https://github.com/nuget/nuget.client - 309f2e302dff9e6ba8a2f48ddf28133d68ff7eae + 2fdd0d41e33c3354de2750fe154b56751a6682aa https://github.com/microsoft/vstest diff --git a/eng/Versions.props b/eng/Versions.props index bdbe6aa508c9..2a2cf22f2d73 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -82,18 +82,18 @@ - 6.10.0-preview.2.76 - 6.10.0-preview.2.76 + 6.10.0-preview.2.78 + 6.10.0-preview.2.78 6.0.0-rc.278 - 6.10.0-preview.2.76 - 6.10.0-preview.2.76 - 6.10.0-preview.2.76 - 6.10.0-preview.2.76 - 6.10.0-preview.2.76 - 6.10.0-preview.2.76 - 6.10.0-preview.2.76 - 6.10.0-preview.2.76 - 6.10.0-preview.2.76 + 6.10.0-preview.2.78 + 6.10.0-preview.2.78 + 6.10.0-preview.2.78 + 6.10.0-preview.2.78 + 6.10.0-preview.2.78 + 6.10.0-preview.2.78 + 6.10.0-preview.2.78 + 6.10.0-preview.2.78 + 6.10.0-preview.2.78 $(NuGetPackagingPackageVersion) $(NuGetProjectModelPackageVersion) From 9e19b4ea2c9d0e1b02a09dcdf6c7b81cc92713bb Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" Date: Sun, 10 Mar 2024 12:50:10 +0000 Subject: [PATCH 349/577] Update dependencies from https://github.com/dotnet/msbuild build 20240307.1 Microsoft.SourceBuild.Intermediate.msbuild , Microsoft.Build , Microsoft.Build.Localization From Version 17.10.0-preview-24127-03 -> To Version 17.10.0-preview-24157-01 From d03ef0768445d40a8c830c7274789a96c24e2918 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" Date: Sun, 10 Mar 2024 12:50:36 +0000 Subject: [PATCH 350/577] Update dependencies from https://github.com/microsoft/vstest build 20240308.6 Microsoft.NET.Test.Sdk , Microsoft.TestPlatform.Build , Microsoft.TestPlatform.CLI From Version 17.10.0-preview-24158-02 -> To Version 17.10.0-preview-24158-06 From 46603272d1d512a2e17bb004dce732e2831a476c Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" Date: Sun, 10 Mar 2024 12:51:05 +0000 Subject: [PATCH 351/577] Update dependencies from https://github.com/dotnet/razor build 20240309.3 Microsoft.AspNetCore.Mvc.Razor.Extensions.Tooling.Internal , Microsoft.CodeAnalysis.Razor.Tooling.Internal , Microsoft.NET.Sdk.Razor.SourceGenerators.Transport From Version 7.0.0-preview.24157.6 -> To Version 7.0.0-preview.24159.3 --- eng/Version.Details.xml | 12 ++++++------ eng/Versions.props | 6 +++--- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index dfdd080cc43b..4d1fd9fd9953 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -277,18 +277,18 @@ https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore da7e9894ce22ef8cc02e5acc56e95a6f8cf8f644 - + https://github.com/dotnet/razor - 2e2e848d22f9944fc3d893ab7d4badc1dfaf88e7 + 7df391184e830e57ec2342a752075b65ba0d7083 - + https://github.com/dotnet/razor - 2e2e848d22f9944fc3d893ab7d4badc1dfaf88e7 + 7df391184e830e57ec2342a752075b65ba0d7083 - + https://github.com/dotnet/razor - 2e2e848d22f9944fc3d893ab7d4badc1dfaf88e7 + 7df391184e830e57ec2342a752075b65ba0d7083 https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore diff --git a/eng/Versions.props b/eng/Versions.props index 0725e7c2b048..3890796e0bcc 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -175,9 +175,9 @@ - 7.0.0-preview.24158.2 - 7.0.0-preview.24158.2 - 7.0.0-preview.24158.2 + 7.0.0-preview.24159.3 + 7.0.0-preview.24159.3 + 7.0.0-preview.24159.3 From 8367b5f0d4b804dd1f6ff537d5cc7e904c38684c Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" Date: Sun, 10 Mar 2024 12:52:41 +0000 Subject: [PATCH 352/577] Update dependencies from https://github.com/dotnet/roslyn build 20240308.5 Microsoft.CodeAnalysis , Microsoft.CodeAnalysis.CSharp , Microsoft.CodeAnalysis.CSharp.CodeStyle , Microsoft.CodeAnalysis.CSharp.Features , Microsoft.CodeAnalysis.CSharp.Workspaces , Microsoft.CodeAnalysis.Workspaces.MSBuild , Microsoft.Net.Compilers.Toolset From Version 4.10.0-3.24156.11 -> To Version 4.10.0-3.24158.5 From f09fae46c93db241e10705e10aa17c21168d46ce Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" Date: Sun, 10 Mar 2024 12:53:09 +0000 Subject: [PATCH 353/577] Update dependencies from https://github.com/dotnet/templating build 20240308.1 Microsoft.TemplateEngine.Abstractions , Microsoft.TemplateEngine.Mocks From Version 8.0.300-preview.24157.1 -> To Version 8.0.300-preview.24158.1 From 776a8fe309b34092e111eb60001ef912f3e85162 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" Date: Sun, 10 Mar 2024 12:55:12 +0000 Subject: [PATCH 354/577] Update dependencies from https://github.com/dotnet/arcade build 20240308.4 Microsoft.DotNet.Arcade.Sdk , Microsoft.DotNet.Helix.Sdk , Microsoft.DotNet.SignTool , Microsoft.DotNet.XUnitExtensions From Version 8.0.0-beta.24155.2 -> To Version 8.0.0-beta.24158.4 --- eng/Version.Details.xml | 16 ++++++++-------- eng/Versions.props | 4 ++-- eng/common/templates-official/job/job.yml | 4 ++++ eng/common/templates/job/job.yml | 4 ++++ global.json | 4 ++-- 5 files changed, 20 insertions(+), 12 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 23c3aec6c12a..9d7f5fe9d32d 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -475,22 +475,22 @@ - + https://github.com/dotnet/arcade - 334436593593431d9dfe13538a8f745f31b3dd59 + 052a4b9e7a9bdb9744c86c05665f1b46e4d59b15 - + https://github.com/dotnet/arcade - 334436593593431d9dfe13538a8f745f31b3dd59 + 052a4b9e7a9bdb9744c86c05665f1b46e4d59b15 - + https://github.com/dotnet/arcade - 334436593593431d9dfe13538a8f745f31b3dd59 + 052a4b9e7a9bdb9744c86c05665f1b46e4d59b15 - + https://github.com/dotnet/arcade - 334436593593431d9dfe13538a8f745f31b3dd59 + 052a4b9e7a9bdb9744c86c05665f1b46e4d59b15 https://dev.azure.com/dnceng/internal/_git/dotnet-runtime diff --git a/eng/Versions.props b/eng/Versions.props index 2257dd888de1..f808c04f30dd 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -34,7 +34,7 @@ 7.0.0 4.0.0 7.0.0 - 8.0.0-beta.24158.1 + 8.0.0-beta.24158.4 7.0.0-preview.22423.2 8.0.0 4.3.0 @@ -209,7 +209,7 @@ 6.12.0 6.1.0 - 8.0.0-beta.24158.1 + 8.0.0-beta.24158.4 4.18.4 1.3.2 8.0.0-beta.23607.1 diff --git a/eng/common/templates-official/job/job.yml b/eng/common/templates-official/job/job.yml index 9e7bebe9af89..647e3f92e5f3 100644 --- a/eng/common/templates-official/job/job.yml +++ b/eng/common/templates-official/job/job.yml @@ -15,6 +15,7 @@ parameters: timeoutInMinutes: '' variables: [] workspace: '' + templateContext: '' # Job base template specific parameters # See schema documentation - https://github.com/dotnet/arcade/blob/master/Documentation/AzureDevOps/TemplateSchema.md @@ -68,6 +69,9 @@ jobs: ${{ if ne(parameters.timeoutInMinutes, '') }}: timeoutInMinutes: ${{ parameters.timeoutInMinutes }} + ${{ if ne(parameters.templateContext, '') }}: + templateContext: ${{ parameters.templateContext }} + variables: - ${{ if ne(parameters.enableTelemetry, 'false') }}: - name: DOTNET_CLI_TELEMETRY_PROFILE diff --git a/eng/common/templates/job/job.yml b/eng/common/templates/job/job.yml index e24ca2f46f98..8ec5c4f2d9f9 100644 --- a/eng/common/templates/job/job.yml +++ b/eng/common/templates/job/job.yml @@ -15,6 +15,7 @@ parameters: timeoutInMinutes: '' variables: [] workspace: '' + templateContext: '' # Job base template specific parameters # See schema documentation - https://github.com/dotnet/arcade/blob/master/Documentation/AzureDevOps/TemplateSchema.md @@ -68,6 +69,9 @@ jobs: ${{ if ne(parameters.timeoutInMinutes, '') }}: timeoutInMinutes: ${{ parameters.timeoutInMinutes }} + ${{ if ne(parameters.templateContext, '') }}: + templateContext: ${{ parameters.templateContext }} + variables: - ${{ if ne(parameters.enableTelemetry, 'false') }}: - name: DOTNET_CLI_TELEMETRY_PROFILE diff --git a/global.json b/global.json index ca88ff11a2c0..33321a52c506 100644 --- a/global.json +++ b/global.json @@ -14,7 +14,7 @@ } }, "msbuild-sdks": { - "Microsoft.DotNet.Arcade.Sdk": "8.0.0-beta.24158.1", - "Microsoft.DotNet.Helix.Sdk": "8.0.0-beta.24158.1" + "Microsoft.DotNet.Arcade.Sdk": "8.0.0-beta.24158.4", + "Microsoft.DotNet.Helix.Sdk": "8.0.0-beta.24158.4" } } From 8c5f20568edfe9d265cdf48c40f62007ef0f7215 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Mon, 11 Mar 2024 07:19:59 +0000 Subject: [PATCH 355/577] [release/8.0.3xx] Update dependencies from dotnet/source-build-externals (#39363) [release/8.0.3xx] Update dependencies from dotnet/source-build-externals --- eng/Version.Details.xml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index c714ec5696f7..176eb3462bf4 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -333,9 +333,9 @@ 02fe27cd6a9b001c8feb7938e6ef4b3799745759 - - https://dev.azure.com/dnceng/internal/_git/dotnet-source-build-externals - 0f0f1f0f33830f27ed0ff357145d2464b96b1a3e + + https://github.com/dotnet/source-build-externals + 7a9b99e457a2b9792a3c17ccaf95d80038725108 From 04a088da4fec4309f5cb12baca09aae7a6f015de Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" Date: Mon, 11 Mar 2024 12:42:25 +0000 Subject: [PATCH 356/577] Update dependencies from https://github.com/dotnet/msbuild build 20240311.2 Microsoft.SourceBuild.Intermediate.msbuild , Microsoft.Build , Microsoft.Build.Localization From Version 17.10.0-preview-24127-03 -> To Version 17.10.0-preview-24161-02 --- eng/Version.Details.xml | 12 ++++++------ eng/Versions.props | 4 ++-- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index aba5e82e2230..18c9b4f04ccd 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -51,17 +51,17 @@ https://github.com/dotnet/emsdk 2fc2ffd960930318f33fcaa690cbdbc55d72f52d - + https://github.com/dotnet/msbuild - 9af8ff2f951017996172e5b805651ebf957e97f4 + 276f781fa868f553bed33a0a01fc54108c84c672 - + https://github.com/dotnet/msbuild - 9af8ff2f951017996172e5b805651ebf957e97f4 + 276f781fa868f553bed33a0a01fc54108c84c672 - + https://github.com/dotnet/msbuild - 9af8ff2f951017996172e5b805651ebf957e97f4 + 276f781fa868f553bed33a0a01fc54108c84c672 diff --git a/eng/Versions.props b/eng/Versions.props index bbaf0e711766..0111f09c6b79 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -120,7 +120,7 @@ - 17.10.0-preview-24157-01 + 17.10.0-preview-24161-02 $(MicrosoftBuildPackageVersion) - 7.0.0-preview.24159.3 - 7.0.0-preview.24159.3 - 7.0.0-preview.24159.3 + 7.0.0-preview.24160.2 + 7.0.0-preview.24160.2 + 7.0.0-preview.24160.2 From a9bc337432ed25701319ee93c1abfda5e8a4691c Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" Date: Mon, 11 Mar 2024 12:43:14 +0000 Subject: [PATCH 358/577] Update dependencies from https://github.com/dotnet/roslyn build 20240311.2 Microsoft.CodeAnalysis , Microsoft.CodeAnalysis.CSharp , Microsoft.CodeAnalysis.CSharp.CodeStyle , Microsoft.CodeAnalysis.CSharp.Features , Microsoft.CodeAnalysis.CSharp.Workspaces , Microsoft.CodeAnalysis.Workspaces.MSBuild , Microsoft.Net.Compilers.Toolset From Version 4.10.0-3.24158.5 -> To Version 4.10.0-3.24161.2 --- eng/Version.Details.xml | 28 ++++++++++++++-------------- eng/Versions.props | 14 +++++++------- 2 files changed, 21 insertions(+), 21 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 176eb3462bf4..dfce0c9dffea 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -78,34 +78,34 @@ ac0d85557969d51bca72181514ddb7d5796fbbe2 - + https://github.com/dotnet/roslyn - 026c96327b02c5ce4d3208f821e02d2ffa825312 + 01b7c233fdda946c1a5628d4692ed827a07e33dd - + https://github.com/dotnet/roslyn - 026c96327b02c5ce4d3208f821e02d2ffa825312 + 01b7c233fdda946c1a5628d4692ed827a07e33dd - + https://github.com/dotnet/roslyn - 026c96327b02c5ce4d3208f821e02d2ffa825312 + 01b7c233fdda946c1a5628d4692ed827a07e33dd - + https://github.com/dotnet/roslyn - 026c96327b02c5ce4d3208f821e02d2ffa825312 + 01b7c233fdda946c1a5628d4692ed827a07e33dd - + https://github.com/dotnet/roslyn - 026c96327b02c5ce4d3208f821e02d2ffa825312 + 01b7c233fdda946c1a5628d4692ed827a07e33dd - + https://github.com/dotnet/roslyn - 026c96327b02c5ce4d3208f821e02d2ffa825312 + 01b7c233fdda946c1a5628d4692ed827a07e33dd - + https://github.com/dotnet/roslyn - 026c96327b02c5ce4d3208f821e02d2ffa825312 + 01b7c233fdda946c1a5628d4692ed827a07e33dd https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore diff --git a/eng/Versions.props b/eng/Versions.props index b910f76d696d..0e032c91183a 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -154,13 +154,13 @@ - 4.10.0-3.24158.5 - 4.10.0-3.24158.5 - 4.10.0-3.24158.5 - 4.10.0-3.24158.5 - 4.10.0-3.24158.5 - 4.10.0-3.24158.5 - 4.10.0-3.24158.5 + 4.10.0-3.24161.2 + 4.10.0-3.24161.2 + 4.10.0-3.24161.2 + 4.10.0-3.24161.2 + 4.10.0-3.24161.2 + 4.10.0-3.24161.2 + 4.10.0-3.24161.2 $(MicrosoftNetCompilersToolsetPackageVersion) From 386204e7b6664b341174ee4b8cab8875b65188e0 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" Date: Mon, 11 Mar 2024 12:43:36 +0000 Subject: [PATCH 359/577] Update dependencies from https://github.com/dotnet/templating build 20240310.5 Microsoft.TemplateEngine.Abstractions , Microsoft.TemplateEngine.Mocks From Version 8.0.300-preview.24158.1 -> To Version 8.0.300-preview.24160.5 --- eng/Version.Details.xml | 8 ++++---- eng/Versions.props | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 176eb3462bf4..aa66c3602528 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -1,14 +1,14 @@ - + https://github.com/dotnet/templating - 5848011bb33e58542b15352d4bc6003267c56a1f + d41744e4cb84316b2bba4c76eee699592c72be54 - + https://github.com/dotnet/templating - 5848011bb33e58542b15352d4bc6003267c56a1f + d41744e4cb84316b2bba4c76eee699592c72be54 https://dev.azure.com/dnceng/internal/_git/dotnet-runtime diff --git a/eng/Versions.props b/eng/Versions.props index b910f76d696d..14725ea8cb51 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -137,13 +137,13 @@ - 8.0.300-preview.24158.1 + 8.0.300-preview.24160.5 $(MicrosoftTemplateEngineAbstractionsPackageVersion) $(MicrosoftTemplateEngineAbstractionsPackageVersion) $(MicrosoftTemplateEngineAbstractionsPackageVersion) $(MicrosoftTemplateEngineAbstractionsPackageVersion) - 8.0.300-preview.24158.1 + 8.0.300-preview.24160.5 $(MicrosoftTemplateEngineMocksPackageVersion) $(MicrosoftTemplateEngineAbstractionsPackageVersion) $(MicrosoftTemplateEngineMocksPackageVersion) From ef90249dfb6976ce516cf84ffeb1140a8444b5c9 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" Date: Tue, 12 Mar 2024 12:56:53 +0000 Subject: [PATCH 360/577] Update dependencies from https://github.com/dotnet/msbuild build 20240312.2 Microsoft.SourceBuild.Intermediate.msbuild , Microsoft.Build , Microsoft.Build.Localization From Version 17.10.0-preview-24127-03 -> To Version 17.10.0-preview-24162-02 --- eng/Version.Details.xml | 12 ++++++------ eng/Versions.props | 4 ++-- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 18c9b4f04ccd..8d4069aae080 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -51,17 +51,17 @@ https://github.com/dotnet/emsdk 2fc2ffd960930318f33fcaa690cbdbc55d72f52d - + https://github.com/dotnet/msbuild - 276f781fa868f553bed33a0a01fc54108c84c672 + 0326fd7c9e131c4c26bac3c0f72a43ef9fd2812c - + https://github.com/dotnet/msbuild - 276f781fa868f553bed33a0a01fc54108c84c672 + 0326fd7c9e131c4c26bac3c0f72a43ef9fd2812c - + https://github.com/dotnet/msbuild - 276f781fa868f553bed33a0a01fc54108c84c672 + 0326fd7c9e131c4c26bac3c0f72a43ef9fd2812c diff --git a/eng/Versions.props b/eng/Versions.props index 0111f09c6b79..153d64f25fcc 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -120,7 +120,7 @@ - 17.10.0-preview-24161-02 + 17.10.0-preview-24162-02 $(MicrosoftBuildPackageVersion) - 12.8.300-beta.24157.6 + 12.8.300-beta.24161.10 From dea6db39dfcbbfa8526918db2ae515752b70d443 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" Date: Tue, 12 Mar 2024 12:57:45 +0000 Subject: [PATCH 362/577] Update dependencies from https://github.com/dotnet/razor build 20240312.1 Microsoft.AspNetCore.Mvc.Razor.Extensions.Tooling.Internal , Microsoft.CodeAnalysis.Razor.Tooling.Internal , Microsoft.NET.Sdk.Razor.SourceGenerators.Transport From Version 7.0.0-preview.24160.2 -> To Version 7.0.0-preview.24162.1 --- eng/Version.Details.xml | 12 ++++++------ eng/Versions.props | 6 +++--- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index cb49b18a0d31..ccb32068b564 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -277,18 +277,18 @@ https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore da7e9894ce22ef8cc02e5acc56e95a6f8cf8f644 - + https://github.com/dotnet/razor - 43b4713af08b6686a6deef64ade4b7238f10c140 + f98b42182a3e044e47d4e8a9c8f50282bece3f91 - + https://github.com/dotnet/razor - 43b4713af08b6686a6deef64ade4b7238f10c140 + f98b42182a3e044e47d4e8a9c8f50282bece3f91 - + https://github.com/dotnet/razor - 43b4713af08b6686a6deef64ade4b7238f10c140 + f98b42182a3e044e47d4e8a9c8f50282bece3f91 https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore diff --git a/eng/Versions.props b/eng/Versions.props index 76a485b9c398..423f0cde643d 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -175,9 +175,9 @@ - 7.0.0-preview.24160.2 - 7.0.0-preview.24160.2 - 7.0.0-preview.24160.2 + 7.0.0-preview.24162.1 + 7.0.0-preview.24162.1 + 7.0.0-preview.24162.1 From 86c9bd9171e9274e0b4a184607669fd2647f056d Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" Date: Tue, 12 Mar 2024 12:59:28 +0000 Subject: [PATCH 363/577] Update dependencies from https://github.com/dotnet/roslyn build 20240311.10 Microsoft.CodeAnalysis , Microsoft.CodeAnalysis.CSharp , Microsoft.CodeAnalysis.CSharp.CodeStyle , Microsoft.CodeAnalysis.CSharp.Features , Microsoft.CodeAnalysis.CSharp.Workspaces , Microsoft.CodeAnalysis.Workspaces.MSBuild , Microsoft.Net.Compilers.Toolset From Version 4.10.0-3.24161.2 -> To Version 4.10.0-3.24161.10 --- eng/Version.Details.xml | 28 ++++++++++++++-------------- eng/Versions.props | 14 +++++++------- 2 files changed, 21 insertions(+), 21 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index cb49b18a0d31..4165c8ac9e6c 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -78,34 +78,34 @@ ac0d85557969d51bca72181514ddb7d5796fbbe2 - + https://github.com/dotnet/roslyn - 01b7c233fdda946c1a5628d4692ed827a07e33dd + c3565da812d99adf841cb96a764a27d8a93e22ef - + https://github.com/dotnet/roslyn - 01b7c233fdda946c1a5628d4692ed827a07e33dd + c3565da812d99adf841cb96a764a27d8a93e22ef - + https://github.com/dotnet/roslyn - 01b7c233fdda946c1a5628d4692ed827a07e33dd + c3565da812d99adf841cb96a764a27d8a93e22ef - + https://github.com/dotnet/roslyn - 01b7c233fdda946c1a5628d4692ed827a07e33dd + c3565da812d99adf841cb96a764a27d8a93e22ef - + https://github.com/dotnet/roslyn - 01b7c233fdda946c1a5628d4692ed827a07e33dd + c3565da812d99adf841cb96a764a27d8a93e22ef - + https://github.com/dotnet/roslyn - 01b7c233fdda946c1a5628d4692ed827a07e33dd + c3565da812d99adf841cb96a764a27d8a93e22ef - + https://github.com/dotnet/roslyn - 01b7c233fdda946c1a5628d4692ed827a07e33dd + c3565da812d99adf841cb96a764a27d8a93e22ef https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore diff --git a/eng/Versions.props b/eng/Versions.props index 76a485b9c398..3476bc41a69f 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -154,13 +154,13 @@ - 4.10.0-3.24161.2 - 4.10.0-3.24161.2 - 4.10.0-3.24161.2 - 4.10.0-3.24161.2 - 4.10.0-3.24161.2 - 4.10.0-3.24161.2 - 4.10.0-3.24161.2 + 4.10.0-3.24161.10 + 4.10.0-3.24161.10 + 4.10.0-3.24161.10 + 4.10.0-3.24161.10 + 4.10.0-3.24161.10 + 4.10.0-3.24161.10 + 4.10.0-3.24161.10 $(MicrosoftNetCompilersToolsetPackageVersion) From c9fdd3dd478d6ec1921ad4587d5b29b2ababf96a Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" Date: Tue, 12 Mar 2024 12:59:59 +0000 Subject: [PATCH 364/577] Update dependencies from https://github.com/dotnet/source-build-externals build 20240311.1 Microsoft.SourceBuild.Intermediate.source-build-externals From Version 8.0.0-alpha.1.24158.3 -> To Version 8.0.0-alpha.1.24161.1 --- eng/Version.Details.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index cb49b18a0d31..6cc7eb98aa90 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -333,9 +333,9 @@ 02fe27cd6a9b001c8feb7938e6ef4b3799745759 - + https://github.com/dotnet/source-build-externals - 7a9b99e457a2b9792a3c17ccaf95d80038725108 + 00fb7841c80b44262646e57bcfbe90a1b7bc3151 From e273cdbaa88609866ddee954277b9b98ca0154bd Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" Date: Tue, 12 Mar 2024 13:01:53 +0000 Subject: [PATCH 365/577] Update dependencies from https://github.com/dotnet/arcade build 20240311.1 Microsoft.DotNet.Arcade.Sdk , Microsoft.DotNet.Helix.Sdk , Microsoft.DotNet.SignTool , Microsoft.DotNet.XUnitExtensions From Version 8.0.0-beta.24158.4 -> To Version 8.0.0-beta.24161.1 --- eng/Version.Details.xml | 16 ++++++++-------- eng/Versions.props | 4 ++-- global.json | 4 ++-- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index cb49b18a0d31..b4f3a6c0f6cb 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -475,22 +475,22 @@ - + https://github.com/dotnet/arcade - 052a4b9e7a9bdb9744c86c05665f1b46e4d59b15 + 5c3fdd3b5aaaa32b24383ec12a60b37ebff13079 - + https://github.com/dotnet/arcade - 052a4b9e7a9bdb9744c86c05665f1b46e4d59b15 + 5c3fdd3b5aaaa32b24383ec12a60b37ebff13079 - + https://github.com/dotnet/arcade - 052a4b9e7a9bdb9744c86c05665f1b46e4d59b15 + 5c3fdd3b5aaaa32b24383ec12a60b37ebff13079 - + https://github.com/dotnet/arcade - 052a4b9e7a9bdb9744c86c05665f1b46e4d59b15 + 5c3fdd3b5aaaa32b24383ec12a60b37ebff13079 https://dev.azure.com/dnceng/internal/_git/dotnet-runtime diff --git a/eng/Versions.props b/eng/Versions.props index 76a485b9c398..c28faed701a1 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -34,7 +34,7 @@ 7.0.0 4.0.0 7.0.0 - 8.0.0-beta.24158.4 + 8.0.0-beta.24161.1 7.0.0-preview.22423.2 8.0.0 4.3.0 @@ -209,7 +209,7 @@ 6.12.0 6.1.0 - 8.0.0-beta.24158.4 + 8.0.0-beta.24161.1 4.18.4 1.3.2 8.0.0-beta.23607.1 diff --git a/global.json b/global.json index 33321a52c506..0fa57cc1e6b6 100644 --- a/global.json +++ b/global.json @@ -14,7 +14,7 @@ } }, "msbuild-sdks": { - "Microsoft.DotNet.Arcade.Sdk": "8.0.0-beta.24158.4", - "Microsoft.DotNet.Helix.Sdk": "8.0.0-beta.24158.4" + "Microsoft.DotNet.Arcade.Sdk": "8.0.0-beta.24161.1", + "Microsoft.DotNet.Helix.Sdk": "8.0.0-beta.24161.1" } } From a723fc24d8b0870cd61f04dd944588799209b00f Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 12 Mar 2024 17:00:02 -0700 Subject: [PATCH 366/577] [release/8.0.3xx] Make sure package search exits with 1 or 0 in the SDK side (#39463) --- .../dotnet-package/search/PackageSearchCommandParser.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/Cli/dotnet/commands/dotnet-package/search/PackageSearchCommandParser.cs b/src/Cli/dotnet/commands/dotnet-package/search/PackageSearchCommandParser.cs index 5bc951d470c4..7b56396fe9cb 100644 --- a/src/Cli/dotnet/commands/dotnet-package/search/PackageSearchCommandParser.cs +++ b/src/Cli/dotnet/commands/dotnet-package/search/PackageSearchCommandParser.cs @@ -97,6 +97,8 @@ private static CliCommand ConstructCommand() { parseResult.ShowHelp(); } + // Only return 1 or 0 + return exitCode == 0 ? 0 : 1; }); return searchCommand; From 289e637cb2d823870ab9b1bfc47172043cb21065 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" Date: Wed, 13 Mar 2024 12:35:39 +0000 Subject: [PATCH 367/577] Update dependencies from https://github.com/dotnet/source-build-reference-packages build Microsoft.SourceBuild.Intermediate.source-build-reference-packages From Version 8.0.0-alpha.1.24061.1 -> To Version 8.0.0-alpha.1.24162.3 --- eng/Version.Details.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index c4ded59d60d6..1ee2686974da 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -338,9 +338,9 @@ 00fb7841c80b44262646e57bcfbe90a1b7bc3151 - + https://github.com/dotnet/source-build-reference-packages - 453a37ef7ae6c335cd49b3b9ab7713c87faeb265 + c08ec59adcf8b56cd1b4de2090c320496566b5c6 From 640226ed24753b1184eff4ea1ca5b96dbefb82d3 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" Date: Wed, 13 Mar 2024 12:38:24 +0000 Subject: [PATCH 368/577] Update dependencies from https://github.com/dotnet/razor build Microsoft.AspNetCore.Mvc.Razor.Extensions.Tooling.Internal , Microsoft.CodeAnalysis.Razor.Tooling.Internal , Microsoft.NET.Sdk.Razor.SourceGenerators.Transport From Version 7.0.0-preview.24162.1 -> To Version 7.0.0-preview.24163.2 --- eng/Version.Details.xml | 12 ++++++------ eng/Versions.props | 6 +++--- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index c4ded59d60d6..edaa45f44ea0 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -277,18 +277,18 @@ https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore da7e9894ce22ef8cc02e5acc56e95a6f8cf8f644 - + https://github.com/dotnet/razor - f98b42182a3e044e47d4e8a9c8f50282bece3f91 + 9d930bc9fcd3e3e9ba5058092caee0b2792269de - + https://github.com/dotnet/razor - f98b42182a3e044e47d4e8a9c8f50282bece3f91 + 9d930bc9fcd3e3e9ba5058092caee0b2792269de - + https://github.com/dotnet/razor - f98b42182a3e044e47d4e8a9c8f50282bece3f91 + 9d930bc9fcd3e3e9ba5058092caee0b2792269de https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore diff --git a/eng/Versions.props b/eng/Versions.props index 223f4ce1821f..abf8bd54f165 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -175,9 +175,9 @@ - 7.0.0-preview.24162.1 - 7.0.0-preview.24162.1 - 7.0.0-preview.24162.1 + 7.0.0-preview.24163.2 + 7.0.0-preview.24163.2 + 7.0.0-preview.24163.2 From b15df64780b6df28d5f3fe627b5c79f3ca199eb0 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" Date: Wed, 13 Mar 2024 12:40:36 +0000 Subject: [PATCH 369/577] Update dependencies from https://github.com/dotnet/templating build Microsoft.TemplateEngine.Abstractions , Microsoft.TemplateEngine.Mocks From Version 8.0.300-preview.24160.5 -> To Version 8.0.300-preview.24162.13 --- eng/Version.Details.xml | 8 ++++---- eng/Versions.props | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index c4ded59d60d6..db0a331c2b36 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -1,14 +1,14 @@ - + https://github.com/dotnet/templating - d41744e4cb84316b2bba4c76eee699592c72be54 + e6d2e0df0843f9499a41e33b76931b58b9e29266 - + https://github.com/dotnet/templating - d41744e4cb84316b2bba4c76eee699592c72be54 + e6d2e0df0843f9499a41e33b76931b58b9e29266 https://dev.azure.com/dnceng/internal/_git/dotnet-runtime diff --git a/eng/Versions.props b/eng/Versions.props index 223f4ce1821f..4afef03cf81e 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -137,13 +137,13 @@ - 8.0.300-preview.24160.5 + 8.0.300-preview.24162.13 $(MicrosoftTemplateEngineAbstractionsPackageVersion) $(MicrosoftTemplateEngineAbstractionsPackageVersion) $(MicrosoftTemplateEngineAbstractionsPackageVersion) $(MicrosoftTemplateEngineAbstractionsPackageVersion) - 8.0.300-preview.24160.5 + 8.0.300-preview.24162.13 $(MicrosoftTemplateEngineMocksPackageVersion) $(MicrosoftTemplateEngineAbstractionsPackageVersion) $(MicrosoftTemplateEngineMocksPackageVersion) From 4d2c284233b1814268c6264fe8cfaae13f04d3bb Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Tue, 12 Mar 2024 11:05:41 +0000 Subject: [PATCH 370/577] Cherry-pick 9df94f0bab218a74fa3746da91f19949a7c74eea from main --- .../Commands/GetValuesCommand.cs | 71 ++++++++++++------- .../ProjectConstruction/TestProject.cs | 71 ++++++++++--------- 2 files changed, 82 insertions(+), 60 deletions(-) diff --git a/src/Tests/Microsoft.NET.TestFramework/Commands/GetValuesCommand.cs b/src/Tests/Microsoft.NET.TestFramework/Commands/GetValuesCommand.cs index 95cc9bb99481..7288f7a5bc54 100644 --- a/src/Tests/Microsoft.NET.TestFramework/Commands/GetValuesCommand.cs +++ b/src/Tests/Microsoft.NET.TestFramework/Commands/GetValuesCommand.cs @@ -60,11 +60,14 @@ protected override SdkCommandSpec CreateCommand(IEnumerable args) newArgs.Add($"/p:ValueName={_valueName}"); newArgs.AddRange(args); - // Override build target to write out DefineConstants value to a file in the output directory Directory.CreateDirectory(GetBaseIntermediateDirectory().FullName); - string injectTargetPath = Path.Combine( + string customAfterDirectoryBuildTargetsPath = Path.Combine( GetBaseIntermediateDirectory().FullName, - Path.GetFileName(ProjectFile) + ".WriteValuesToFile.g.targets"); + "Custom.After.Directory.Build.targets"); + + var project = XDocument.Load(ProjectFile); + + var ns = project.Root.Name.Namespace; string linesAttribute; if (_valueType == ValueType.Property) @@ -80,35 +83,53 @@ protected override SdkCommandSpec CreateCommand(IEnumerable args) } } - string propertiesElement = ""; + var propertyGroup = project.Root.Elements(ns + "PropertyGroup").FirstOrDefault(); + + if (propertyGroup == null) + { + propertyGroup = new XElement(ns + "PropertyGroup"); + project.Root.AddAfterSelf(propertyGroup); + } + + propertyGroup.Add(new XElement(ns + "CustomAfterDirectoryBuildTargets", $"$(CustomAfterDirectoryBuildTargets);{customAfterDirectoryBuildTargetsPath}")); + propertyGroup.Add(new XElement(ns + "CustomAfterMicrosoftCommonCrossTargetingTargets", $"$(CustomAfterMicrosoftCommonCrossTargetingTargets);{customAfterDirectoryBuildTargetsPath}")); + + project.Save(ProjectFile); + + var customAfterDirectoryBuildTargets = new XDocument(new XElement(ns + "Project")); + + var target = new XElement(ns + "Target", + new XAttribute("Name", TargetName), + ShouldCompile ? new XAttribute("DependsOnTargets", DependsOnTargets) : null); + + customAfterDirectoryBuildTargets.Root.Add(target); + if (Properties.Count != 0) { - propertiesElement += "\n"; + propertyGroup = new XElement(ns + "PropertyGroup"); + customAfterDirectoryBuildTargets.Root.Add(propertyGroup); + foreach (var pair in Properties) { - propertiesElement += $" <{pair.Key}>{pair.Value}\n"; + propertyGroup.Add(new XElement(ns + pair.Key, pair.Value)); } - propertiesElement += " "; } - string injectTargetContents = -$@" - {propertiesElement} - - - - - - -"; - injectTargetContents = injectTargetContents.Replace('`', '"'); - - File.WriteAllText(injectTargetPath, injectTargetContents); + var itemGroup = new XElement(ns + "ItemGroup"); + target.Add(itemGroup); + + itemGroup.Add( + new XElement(ns + "LinesToWrite", + new XAttribute("Include", linesAttribute))); + + target.Add( + new XElement(ns + "WriteLinesToFile", + new XAttribute("File", $@"bin\$(Configuration)\$(TargetFramework)\{_valueName}Values.txt"), + new XAttribute("Lines", "@(LinesToWrite)"), + new XAttribute("Overwrite", bool.TrueString), + new XAttribute("Encoding", "Unicode"))); + + customAfterDirectoryBuildTargets.Save(customAfterDirectoryBuildTargetsPath); var outputDirectory = GetValuesOutputDirectory(_targetFramework); outputDirectory.Create(); diff --git a/src/Tests/Microsoft.NET.TestFramework/ProjectConstruction/TestProject.cs b/src/Tests/Microsoft.NET.TestFramework/ProjectConstruction/TestProject.cs index 39cf0271db4f..bb12967ec11b 100644 --- a/src/Tests/Microsoft.NET.TestFramework/ProjectConstruction/TestProject.cs +++ b/src/Tests/Microsoft.NET.TestFramework/ProjectConstruction/TestProject.cs @@ -352,6 +352,42 @@ internal void Create(TestAsset targetTestAsset, string testProjectsSourceFolder, projectChange(projectXml); } + if (PropertiesToRecord.Any()) + { + var customAfterDirectoryBuildTargetsPath = new FileInfo(Path.Combine(targetFolder, "obj", "Custom.After.Directory.Build.targets")); + customAfterDirectoryBuildTargetsPath.Directory.Create(); + + propertyGroup.Add(new XElement(ns + "CustomAfterDirectoryBuildTargets", $"$(CustomAfterDirectoryBuildTargets);{customAfterDirectoryBuildTargetsPath.FullName}")); + propertyGroup.Add(new XElement(ns + "CustomAfterMicrosoftCommonCrossTargetingTargets", $"$(CustomAfterMicrosoftCommonCrossTargetingTargets);{customAfterDirectoryBuildTargetsPath.FullName}")); + + var customAfterDirectoryBuildTargets = new XDocument(new XElement(ns + "Project")); + + var target = new XElement(ns + "Target", + new XAttribute("Name", "WritePropertyValues"), + new XAttribute("BeforeTargets", "AfterBuild")); + + customAfterDirectoryBuildTargets.Root.Add(target); + + var itemGroup = new XElement(ns + "ItemGroup"); + target.Add(itemGroup); + + foreach (var propertyName in PropertiesToRecord) + { + itemGroup.Add( + new XElement(ns + "LinesToWrite", + new XAttribute("Include", $"{propertyName}: $({propertyName})"))); + } + + target.Add( + new XElement(ns + "WriteLinesToFile", + new XAttribute("File", $@"$(BaseIntermediateOutputPath)\$(Configuration)\$(TargetFramework)\PropertyValues.txt"), + new XAttribute("Lines", "@(LinesToWrite)"), + new XAttribute("Overwrite", bool.TrueString), + new XAttribute("Encoding", "Unicode"))); + + customAfterDirectoryBuildTargets.Save(customAfterDirectoryBuildTargetsPath.FullName); + } + using (var file = File.CreateText(targetProjectPath)) { projectXml.Save(file); @@ -429,41 +465,6 @@ public class {safeThisName}Class { File.WriteAllText(Path.Combine(targetFolder, kvp.Key), kvp.Value); } - - if (PropertiesToRecord.Any()) - { - string propertiesElements = ""; - foreach (var propertyName in PropertiesToRecord) - { - propertiesElements += $" " + Environment.NewLine; - } - - string injectTargetContents = - $@" - - -{propertiesElements} - - - -"; - - injectTargetContents = injectTargetContents.Replace('`', '"'); - - string targetPath = Path.Combine(targetFolder, "obj", Name + ".csproj.WriteValuesToFile.g.targets"); - - if (!Directory.Exists(Path.GetDirectoryName(targetPath))) - { - Directory.CreateDirectory(Path.GetDirectoryName(targetPath)); - } - - File.WriteAllText(targetPath, injectTargetContents); - } } public void AddItem(string itemName, string attributeName, string attributeValue) From 09b0452121a0241d156c3683a36df54f16e1f583 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Wed, 13 Mar 2024 17:29:03 +0000 Subject: [PATCH 371/577] [release/8.0.3xx] Update dependencies from dotnet/roslyn (#39492) [release/8.0.3xx] Update dependencies from dotnet/roslyn --- eng/Version.Details.xml | 28 ++++++++++++++-------------- eng/Versions.props | 14 +++++++------- 2 files changed, 21 insertions(+), 21 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index edaa45f44ea0..89b1c5a9175d 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -78,34 +78,34 @@ ac0d85557969d51bca72181514ddb7d5796fbbe2 - + https://github.com/dotnet/roslyn - c3565da812d99adf841cb96a764a27d8a93e22ef + 9be4c180382a6981a2738f2174f79c5cea967634 - + https://github.com/dotnet/roslyn - c3565da812d99adf841cb96a764a27d8a93e22ef + 9be4c180382a6981a2738f2174f79c5cea967634 - + https://github.com/dotnet/roslyn - c3565da812d99adf841cb96a764a27d8a93e22ef + 9be4c180382a6981a2738f2174f79c5cea967634 - + https://github.com/dotnet/roslyn - c3565da812d99adf841cb96a764a27d8a93e22ef + 9be4c180382a6981a2738f2174f79c5cea967634 - + https://github.com/dotnet/roslyn - c3565da812d99adf841cb96a764a27d8a93e22ef + 9be4c180382a6981a2738f2174f79c5cea967634 - + https://github.com/dotnet/roslyn - c3565da812d99adf841cb96a764a27d8a93e22ef + 9be4c180382a6981a2738f2174f79c5cea967634 - + https://github.com/dotnet/roslyn - c3565da812d99adf841cb96a764a27d8a93e22ef + 9be4c180382a6981a2738f2174f79c5cea967634 https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore diff --git a/eng/Versions.props b/eng/Versions.props index abf8bd54f165..6f9db39b4e42 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -154,13 +154,13 @@ - 4.10.0-3.24161.10 - 4.10.0-3.24161.10 - 4.10.0-3.24161.10 - 4.10.0-3.24161.10 - 4.10.0-3.24161.10 - 4.10.0-3.24161.10 - 4.10.0-3.24161.10 + 4.10.0-3.24163.2 + 4.10.0-3.24163.2 + 4.10.0-3.24163.2 + 4.10.0-3.24163.2 + 4.10.0-3.24163.2 + 4.10.0-3.24163.2 + 4.10.0-3.24163.2 $(MicrosoftNetCompilersToolsetPackageVersion) From 3d0fd237a0cebd42a8c883d08c00cb8538591feb Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" Date: Thu, 14 Mar 2024 12:33:34 +0000 Subject: [PATCH 372/577] Update dependencies from https://github.com/dotnet/source-build-reference-packages build Microsoft.SourceBuild.Intermediate.source-build-reference-packages From Version 8.0.0-alpha.1.24162.3 -> To Version 8.0.0-alpha.1.24163.3 --- eng/Version.Details.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index a09f4a002479..91b84e3ab611 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -338,9 +338,9 @@ 00fb7841c80b44262646e57bcfbe90a1b7bc3151 - + https://github.com/dotnet/source-build-reference-packages - c08ec59adcf8b56cd1b4de2090c320496566b5c6 + 79827eed138fd2575a8b24820b4f385ee4ffb6e6 From b8bc8fe5db90b65f77170d05340db270dba78958 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" Date: Thu, 14 Mar 2024 12:34:43 +0000 Subject: [PATCH 373/577] Update dependencies from https://github.com/microsoft/vstest build Microsoft.NET.Test.Sdk , Microsoft.TestPlatform.Build , Microsoft.TestPlatform.CLI From Version 17.10.0-preview-24158-06 -> To Version 17.10.0-preview-24163-01 --- eng/Version.Details.xml | 12 ++++++------ eng/Versions.props | 6 +++--- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index a09f4a002479..0f4fdb5ffd0f 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -179,18 +179,18 @@ https://github.com/nuget/nuget.client 2fdd0d41e33c3354de2750fe154b56751a6682aa - + https://github.com/microsoft/vstest - 316167369cea59e0ad6ece2a39d94a3a6d49cf12 + c609e2c022b0087b227436a4debf45525eed00e9 - + https://github.com/microsoft/vstest - 316167369cea59e0ad6ece2a39d94a3a6d49cf12 + c609e2c022b0087b227436a4debf45525eed00e9 - + https://github.com/microsoft/vstest - 316167369cea59e0ad6ece2a39d94a3a6d49cf12 + c609e2c022b0087b227436a4debf45525eed00e9 https://dev.azure.com/dnceng/internal/_git/dotnet-runtime diff --git a/eng/Versions.props b/eng/Versions.props index c1b981b22378..aa0cd2a5fa0d 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -99,9 +99,9 @@ - 17.10.0-preview-24158-06 - 17.10.0-preview-24158-06 - 17.10.0-preview-24158-06 + 17.10.0-preview-24163-01 + 17.10.0-preview-24163-01 + 17.10.0-preview-24163-01 From 57772037ce02385429197e95d5e351726712bf13 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" Date: Thu, 14 Mar 2024 12:35:07 +0000 Subject: [PATCH 374/577] Update dependencies from https://github.com/dotnet/fsharp build Microsoft.SourceBuild.Intermediate.fsharp , Microsoft.FSharp.Compiler From Version 8.0.300-beta.24161.10 -> To Version 8.0.300-beta.24163.4 --- eng/Version.Details.xml | 8 ++++---- eng/Versions.props | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index a09f4a002479..d113b3ef6045 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -64,13 +64,13 @@ 0326fd7c9e131c4c26bac3c0f72a43ef9fd2812c - + https://github.com/dotnet/fsharp - 212eaf7fac2d837c51dc49e477a599ebea68338b + 2c03643199368f07a3326709fc68abcbfc482a06 - + https://github.com/dotnet/fsharp - 212eaf7fac2d837c51dc49e477a599ebea68338b + 2c03643199368f07a3326709fc68abcbfc482a06 diff --git a/eng/Versions.props b/eng/Versions.props index c1b981b22378..e7e6a2130a39 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -150,7 +150,7 @@ - 12.8.300-beta.24161.10 + 12.8.300-beta.24163.4 From 2d7a086af408b69c846120910cc23fecae35b0a8 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" Date: Thu, 14 Mar 2024 12:35:30 +0000 Subject: [PATCH 375/577] Update dependencies from https://github.com/dotnet/razor build Microsoft.AspNetCore.Mvc.Razor.Extensions.Tooling.Internal , Microsoft.CodeAnalysis.Razor.Tooling.Internal , Microsoft.NET.Sdk.Razor.SourceGenerators.Transport From Version 7.0.0-preview.24163.2 -> To Version 7.0.0-preview.24164.2 --- eng/Version.Details.xml | 12 ++++++------ eng/Versions.props | 6 +++--- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index a09f4a002479..09101aedda18 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -277,18 +277,18 @@ https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore da7e9894ce22ef8cc02e5acc56e95a6f8cf8f644 - + https://github.com/dotnet/razor - 9d930bc9fcd3e3e9ba5058092caee0b2792269de + d6be87e07ef04821c67627945902a9a62d153666 - + https://github.com/dotnet/razor - 9d930bc9fcd3e3e9ba5058092caee0b2792269de + d6be87e07ef04821c67627945902a9a62d153666 - + https://github.com/dotnet/razor - 9d930bc9fcd3e3e9ba5058092caee0b2792269de + d6be87e07ef04821c67627945902a9a62d153666 https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore diff --git a/eng/Versions.props b/eng/Versions.props index c1b981b22378..dbe9e1c6830b 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -175,9 +175,9 @@ - 7.0.0-preview.24163.2 - 7.0.0-preview.24163.2 - 7.0.0-preview.24163.2 + 7.0.0-preview.24164.2 + 7.0.0-preview.24164.2 + 7.0.0-preview.24164.2 From eb0bf961e706c1a50ad45040d829d23726a5f179 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" Date: Thu, 14 Mar 2024 12:35:53 +0000 Subject: [PATCH 376/577] Update dependencies from https://github.com/dotnet/roslyn build Microsoft.CodeAnalysis , Microsoft.CodeAnalysis.CSharp , Microsoft.CodeAnalysis.CSharp.CodeStyle , Microsoft.CodeAnalysis.CSharp.Features , Microsoft.CodeAnalysis.CSharp.Workspaces , Microsoft.CodeAnalysis.Workspaces.MSBuild , Microsoft.Net.Compilers.Toolset From Version 4.10.0-3.24163.2 -> To Version 4.10.0-3.24164.1 --- eng/Version.Details.xml | 28 ++++++++++++++-------------- eng/Versions.props | 14 +++++++------- 2 files changed, 21 insertions(+), 21 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index a09f4a002479..df3c5ef6882f 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -78,34 +78,34 @@ ac0d85557969d51bca72181514ddb7d5796fbbe2 - + https://github.com/dotnet/roslyn - 9be4c180382a6981a2738f2174f79c5cea967634 + 26b809df38356d4fe1ee376f703dc8832a7ce461 - + https://github.com/dotnet/roslyn - 9be4c180382a6981a2738f2174f79c5cea967634 + 26b809df38356d4fe1ee376f703dc8832a7ce461 - + https://github.com/dotnet/roslyn - 9be4c180382a6981a2738f2174f79c5cea967634 + 26b809df38356d4fe1ee376f703dc8832a7ce461 - + https://github.com/dotnet/roslyn - 9be4c180382a6981a2738f2174f79c5cea967634 + 26b809df38356d4fe1ee376f703dc8832a7ce461 - + https://github.com/dotnet/roslyn - 9be4c180382a6981a2738f2174f79c5cea967634 + 26b809df38356d4fe1ee376f703dc8832a7ce461 - + https://github.com/dotnet/roslyn - 9be4c180382a6981a2738f2174f79c5cea967634 + 26b809df38356d4fe1ee376f703dc8832a7ce461 - + https://github.com/dotnet/roslyn - 9be4c180382a6981a2738f2174f79c5cea967634 + 26b809df38356d4fe1ee376f703dc8832a7ce461 https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore diff --git a/eng/Versions.props b/eng/Versions.props index c1b981b22378..c281ba9c2e3e 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -154,13 +154,13 @@ - 4.10.0-3.24163.2 - 4.10.0-3.24163.2 - 4.10.0-3.24163.2 - 4.10.0-3.24163.2 - 4.10.0-3.24163.2 - 4.10.0-3.24163.2 - 4.10.0-3.24163.2 + 4.10.0-3.24164.1 + 4.10.0-3.24164.1 + 4.10.0-3.24164.1 + 4.10.0-3.24164.1 + 4.10.0-3.24164.1 + 4.10.0-3.24164.1 + 4.10.0-3.24164.1 $(MicrosoftNetCompilersToolsetPackageVersion) From a055ab57352517d043f9f0ce278986a1b6383840 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" Date: Thu, 14 Mar 2024 12:36:15 +0000 Subject: [PATCH 377/577] Update dependencies from https://github.com/dotnet/templating build Microsoft.TemplateEngine.Abstractions , Microsoft.TemplateEngine.Mocks From Version 8.0.300-preview.24162.13 -> To Version 8.0.300-preview.24163.5 --- eng/Version.Details.xml | 8 ++++---- eng/Versions.props | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index a09f4a002479..66e17e7a516f 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -1,14 +1,14 @@ - + https://github.com/dotnet/templating - e6d2e0df0843f9499a41e33b76931b58b9e29266 + 5a3dcbc8022122914aee42fbe0f5143576b2d848 - + https://github.com/dotnet/templating - e6d2e0df0843f9499a41e33b76931b58b9e29266 + 5a3dcbc8022122914aee42fbe0f5143576b2d848 https://dev.azure.com/dnceng/internal/_git/dotnet-runtime diff --git a/eng/Versions.props b/eng/Versions.props index c1b981b22378..db2ef9c63417 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -137,13 +137,13 @@ - 8.0.300-preview.24162.13 + 8.0.300-preview.24163.5 $(MicrosoftTemplateEngineAbstractionsPackageVersion) $(MicrosoftTemplateEngineAbstractionsPackageVersion) $(MicrosoftTemplateEngineAbstractionsPackageVersion) $(MicrosoftTemplateEngineAbstractionsPackageVersion) - 8.0.300-preview.24162.13 + 8.0.300-preview.24163.5 $(MicrosoftTemplateEngineMocksPackageVersion) $(MicrosoftTemplateEngineAbstractionsPackageVersion) $(MicrosoftTemplateEngineMocksPackageVersion) From 3aaa5010a3834aa8504b83e46836f8fa41684fd8 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Thu, 14 Mar 2024 19:08:51 +0000 Subject: [PATCH 378/577] [release/8.0.3xx] Update dependencies from dotnet/arcade (#39494) [release/8.0.3xx] Update dependencies from dotnet/arcade --- eng/Version.Details.xml | 16 ++++++++-------- eng/Versions.props | 4 ++-- eng/common/templates-official/job/job.yml | 18 +++++++++++------- global.json | 4 ++-- 4 files changed, 23 insertions(+), 19 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 96b90087b6cf..bc549cfd7f3f 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -475,22 +475,22 @@ - + https://github.com/dotnet/arcade - 5c3fdd3b5aaaa32b24383ec12a60b37ebff13079 + cd10e5d3748676d70ae2b4d9c84f073eeb203cac - + https://github.com/dotnet/arcade - 5c3fdd3b5aaaa32b24383ec12a60b37ebff13079 + cd10e5d3748676d70ae2b4d9c84f073eeb203cac - + https://github.com/dotnet/arcade - 5c3fdd3b5aaaa32b24383ec12a60b37ebff13079 + cd10e5d3748676d70ae2b4d9c84f073eeb203cac - + https://github.com/dotnet/arcade - 5c3fdd3b5aaaa32b24383ec12a60b37ebff13079 + cd10e5d3748676d70ae2b4d9c84f073eeb203cac https://dev.azure.com/dnceng/internal/_git/dotnet-runtime diff --git a/eng/Versions.props b/eng/Versions.props index 6542cbf98d1b..28ec6cfa7117 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -34,7 +34,7 @@ 7.0.0 4.0.0 7.0.0 - 8.0.0-beta.24161.1 + 8.0.0-beta.24161.7 7.0.0-preview.22423.2 8.0.0 4.3.0 @@ -209,7 +209,7 @@ 6.12.0 6.1.0 - 8.0.0-beta.24161.1 + 8.0.0-beta.24161.7 4.18.4 1.3.2 8.0.0-beta.23607.1 diff --git a/eng/common/templates-official/job/job.yml b/eng/common/templates-official/job/job.yml index 647e3f92e5f3..a2709d10562c 100644 --- a/eng/common/templates-official/job/job.yml +++ b/eng/common/templates-official/job/job.yml @@ -206,9 +206,11 @@ jobs: continueOnError: true condition: always() - ${{ if and(ne(parameters.artifacts.publish.logs, 'false'), ne(parameters.artifacts.publish.logs, '')) }}: - - publish: artifacts/log - artifact: ${{ coalesce(parameters.artifacts.publish.logs.name, 'Logs_Build_$(Agent.Os)_$(_BuildConfig)') }} - displayName: Publish logs + - task: 1ES.PublishPipelineArtifact@1 + inputs: + targetPath: 'artifacts/log' + artifactName: ${{ coalesce(parameters.artifacts.publish.logs.name, 'Logs_Build_$(Agent.Os)_$(_BuildConfig)') }} + displayName: 'Publish logs' continueOnError: true condition: always() @@ -253,7 +255,9 @@ jobs: IgnoreDirectories: ${{ parameters.componentGovernanceIgnoreDirectories }} - ${{ if eq(parameters.enableBuildRetry, 'true') }}: - - publish: $(Build.SourcesDirectory)\eng\common\BuildConfiguration - artifact: BuildConfiguration - displayName: Publish build retry configuration - continueOnError: true + - task: 1ES.PublishPipelineArtifact@1 + inputs: + targetPath: '$(Build.SourcesDirectory)\eng\common\BuildConfiguration' + artifactName: 'BuildConfiguration' + displayName: 'Publish build retry configuration' + continueOnError: true \ No newline at end of file diff --git a/global.json b/global.json index 0fa57cc1e6b6..985d3f491224 100644 --- a/global.json +++ b/global.json @@ -14,7 +14,7 @@ } }, "msbuild-sdks": { - "Microsoft.DotNet.Arcade.Sdk": "8.0.0-beta.24161.1", - "Microsoft.DotNet.Helix.Sdk": "8.0.0-beta.24161.1" + "Microsoft.DotNet.Arcade.Sdk": "8.0.0-beta.24161.7", + "Microsoft.DotNet.Helix.Sdk": "8.0.0-beta.24161.7" } } From 4af7d8638a732166bbfb14a4a4a7437e2de54daa Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" Date: Fri, 15 Mar 2024 12:21:26 +0000 Subject: [PATCH 379/577] Update dependencies from https://github.com/dotnet/razor build Microsoft.AspNetCore.Mvc.Razor.Extensions.Tooling.Internal , Microsoft.CodeAnalysis.Razor.Tooling.Internal , Microsoft.NET.Sdk.Razor.SourceGenerators.Transport From Version 7.0.0-preview.24164.2 -> To Version 7.0.0-preview.24164.4 --- eng/Version.Details.xml | 12 ++++++------ eng/Versions.props | 6 +++--- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 301306be7668..d5e5298e2960 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -277,18 +277,18 @@ https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore da7e9894ce22ef8cc02e5acc56e95a6f8cf8f644 - + https://github.com/dotnet/razor - d6be87e07ef04821c67627945902a9a62d153666 + 55e0597a2090de3b98a4985346eb687b0aeda06f - + https://github.com/dotnet/razor - d6be87e07ef04821c67627945902a9a62d153666 + 55e0597a2090de3b98a4985346eb687b0aeda06f - + https://github.com/dotnet/razor - d6be87e07ef04821c67627945902a9a62d153666 + 55e0597a2090de3b98a4985346eb687b0aeda06f https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore diff --git a/eng/Versions.props b/eng/Versions.props index 0f6acd88df5b..79acc1495acc 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -175,9 +175,9 @@ - 7.0.0-preview.24164.2 - 7.0.0-preview.24164.2 - 7.0.0-preview.24164.2 + 7.0.0-preview.24164.4 + 7.0.0-preview.24164.4 + 7.0.0-preview.24164.4 From 2073b5cb2c0d8a17917302ece90a675daff6f8eb Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" Date: Fri, 15 Mar 2024 12:21:51 +0000 Subject: [PATCH 380/577] Update dependencies from https://github.com/dotnet/roslyn build Microsoft.CodeAnalysis , Microsoft.CodeAnalysis.CSharp , Microsoft.CodeAnalysis.CSharp.CodeStyle , Microsoft.CodeAnalysis.CSharp.Features , Microsoft.CodeAnalysis.CSharp.Workspaces , Microsoft.CodeAnalysis.Workspaces.MSBuild , Microsoft.Net.Compilers.Toolset From Version 4.10.0-3.24164.1 -> To Version 4.10.0-3.24164.3 --- eng/Version.Details.xml | 28 ++++++++++++++-------------- eng/Versions.props | 14 +++++++------- 2 files changed, 21 insertions(+), 21 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 301306be7668..13ff7981a545 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -78,34 +78,34 @@ ac0d85557969d51bca72181514ddb7d5796fbbe2 - + https://github.com/dotnet/roslyn - 26b809df38356d4fe1ee376f703dc8832a7ce461 + 711e122c86db37658d2924f2499c775ce6007b68 - + https://github.com/dotnet/roslyn - 26b809df38356d4fe1ee376f703dc8832a7ce461 + 711e122c86db37658d2924f2499c775ce6007b68 - + https://github.com/dotnet/roslyn - 26b809df38356d4fe1ee376f703dc8832a7ce461 + 711e122c86db37658d2924f2499c775ce6007b68 - + https://github.com/dotnet/roslyn - 26b809df38356d4fe1ee376f703dc8832a7ce461 + 711e122c86db37658d2924f2499c775ce6007b68 - + https://github.com/dotnet/roslyn - 26b809df38356d4fe1ee376f703dc8832a7ce461 + 711e122c86db37658d2924f2499c775ce6007b68 - + https://github.com/dotnet/roslyn - 26b809df38356d4fe1ee376f703dc8832a7ce461 + 711e122c86db37658d2924f2499c775ce6007b68 - + https://github.com/dotnet/roslyn - 26b809df38356d4fe1ee376f703dc8832a7ce461 + 711e122c86db37658d2924f2499c775ce6007b68 https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore diff --git a/eng/Versions.props b/eng/Versions.props index 0f6acd88df5b..cd74bc459a70 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -154,13 +154,13 @@ - 4.10.0-3.24164.1 - 4.10.0-3.24164.1 - 4.10.0-3.24164.1 - 4.10.0-3.24164.1 - 4.10.0-3.24164.1 - 4.10.0-3.24164.1 - 4.10.0-3.24164.1 + 4.10.0-3.24164.3 + 4.10.0-3.24164.3 + 4.10.0-3.24164.3 + 4.10.0-3.24164.3 + 4.10.0-3.24164.3 + 4.10.0-3.24164.3 + 4.10.0-3.24164.3 $(MicrosoftNetCompilersToolsetPackageVersion) From 9927abb44564390c24941a631592034a47c9bbee Mon Sep 17 00:00:00 2001 From: Forgind <12969783+Forgind@users.noreply.github.com> Date: Fri, 15 Mar 2024 11:04:15 -0700 Subject: [PATCH 381/577] Use workload sets as per user request (#37681) This PR should enable installing and updating via workload sets. In particular, if you have mode set to workload sets (and don't use a rollback file), it will now look for the latest workload set (or latest stable if you don't specify to use previews) and install/update to that rather than updating manifests individually. It now also supports dotnet workload update --version x where it will update the workload set version x. Finally, it now will display the workload set it is using if it's set to use workload sets in the install state file when the user runs dotnet workload list. All functionality was manually tested at some point, and there's a new unit test. --- .../Microsoft.DotNet.Cli.Utils/Constants.cs | 1 + .../Microsoft.DotNet.Cli.Utils/PathUtility.cs | 24 +++ .../Windows/InstallMessageDispatcher.cs | 16 ++ .../Windows/InstallRequestMessage.cs | 8 + .../Installer/Windows/InstallRequestType.cs | 5 + .../commands/InstallingWorkloadCommand.cs | 53 ++++++ .../dotnet-workload/InstallStateContents.cs | 14 +- .../dotnet-workload/WorkloadInfoHelper.cs | 7 +- .../clean/WorkloadCleanCommand.cs | 2 +- .../install/FileBasedInstaller.cs | 45 ++++- .../dotnet-workload/install/IInstaller.cs | 4 + .../install/IWorkloadManifestUpdater.cs | 5 +- .../install/LocalizableStrings.resx | 9 + .../install/MsiInstallerBase.cs | 47 ++++- .../install/NetSdkMsiInstallerClient.cs | 64 ++++++- .../install/NetSdkMsiInstallerServer.cs | 5 + .../install/WorkloadGarbageCollector.cs | 8 +- .../install/WorkloadInstallCommand.cs | 110 +++++++---- .../install/WorkloadInstallCommandParser.cs | 1 + .../install/WorkloadManifestUpdater.cs | 176 +++++++++++++----- .../install/xlf/LocalizableStrings.cs.xlf | 15 ++ .../install/xlf/LocalizableStrings.de.xlf | 15 ++ .../install/xlf/LocalizableStrings.es.xlf | 15 ++ .../install/xlf/LocalizableStrings.fr.xlf | 15 ++ .../install/xlf/LocalizableStrings.it.xlf | 15 ++ .../install/xlf/LocalizableStrings.ja.xlf | 15 ++ .../install/xlf/LocalizableStrings.ko.xlf | 15 ++ .../install/xlf/LocalizableStrings.pl.xlf | 15 ++ .../install/xlf/LocalizableStrings.pt-BR.xlf | 15 ++ .../install/xlf/LocalizableStrings.ru.xlf | 15 ++ .../install/xlf/LocalizableStrings.tr.xlf | 15 ++ .../xlf/LocalizableStrings.zh-Hans.xlf | 15 ++ .../xlf/LocalizableStrings.zh-Hant.xlf | 15 ++ .../list/LocalizableStrings.resx | 3 + .../list/WorkloadListCommand.cs | 10 +- .../list/xlf/LocalizableStrings.cs.xlf | 5 + .../list/xlf/LocalizableStrings.de.xlf | 5 + .../list/xlf/LocalizableStrings.es.xlf | 5 + .../list/xlf/LocalizableStrings.fr.xlf | 5 + .../list/xlf/LocalizableStrings.it.xlf | 5 + .../list/xlf/LocalizableStrings.ja.xlf | 5 + .../list/xlf/LocalizableStrings.ko.xlf | 5 + .../list/xlf/LocalizableStrings.pl.xlf | 5 + .../list/xlf/LocalizableStrings.pt-BR.xlf | 5 + .../list/xlf/LocalizableStrings.ru.xlf | 5 + .../list/xlf/LocalizableStrings.tr.xlf | 5 + .../list/xlf/LocalizableStrings.zh-Hans.xlf | 5 + .../list/xlf/LocalizableStrings.zh-Hant.xlf | 5 + .../update/LocalizableStrings.resx | 3 + .../update/WorkloadUpdateCommand.cs | 107 ++++++++--- .../update/WorkloadUpdateCommandParser.cs | 1 + .../update/xlf/LocalizableStrings.cs.xlf | 5 + .../update/xlf/LocalizableStrings.de.xlf | 5 + .../update/xlf/LocalizableStrings.es.xlf | 5 + .../update/xlf/LocalizableStrings.fr.xlf | 5 + .../update/xlf/LocalizableStrings.it.xlf | 5 + .../update/xlf/LocalizableStrings.ja.xlf | 5 + .../update/xlf/LocalizableStrings.ko.xlf | 5 + .../update/xlf/LocalizableStrings.pl.xlf | 5 + .../update/xlf/LocalizableStrings.pt-BR.xlf | 5 + .../update/xlf/LocalizableStrings.ru.xlf | 5 + .../update/xlf/LocalizableStrings.tr.xlf | 5 + .../update/xlf/LocalizableStrings.zh-Hans.xlf | 5 + .../update/xlf/LocalizableStrings.zh-Hant.xlf | 5 + .../Microsoft.DotNet.TemplateLocator.csproj | 1 + ...Microsoft.DotNet.MSBuildSdkResolver.csproj | 1 + .../IWorkloadManifestProvider.cs | 2 + .../IWorkloadResolver.cs | 1 + ...soft.NET.Sdk.WorkloadManifestReader.csproj | 1 + ...loadManifestProvider.InstallStateReader.cs | 104 ----------- .../SdkDirectoryWorkloadManifestProvider.cs | 22 +-- .../SdkFeatureBand.cs | 3 + .../TempDirectoryWorkloadManifestProvider.cs | 1 + .../WorkloadResolver.cs | 3 + .../Microsoft.NET.Build.Tasks.csproj | 1 + .../FakeManifestProvider.cs | 2 + ...kDirectoryWorkloadManifestProviderTests.cs | 12 +- .../GivenWorkloadManifestUpdater.cs | 2 +- .../MockManifestProvider.cs | 1 + .../MockPackWorkloadInstaller.cs | 24 ++- .../MockWorkloadManifestUpdater.cs | 14 +- .../WorkloadGarbageCollectionTests.cs | 2 +- .../MockWorkloadResolver.cs | 5 +- .../GivenDotnetWorkloadUpdate.cs | 63 ++++++- 84 files changed, 1056 insertions(+), 262 deletions(-) delete mode 100644 src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/SdkDirectoryWorkloadManifestProvider.InstallStateReader.cs diff --git a/src/Cli/Microsoft.DotNet.Cli.Utils/Constants.cs b/src/Cli/Microsoft.DotNet.Cli.Utils/Constants.cs index a565090b6e46..5fff0de94751 100644 --- a/src/Cli/Microsoft.DotNet.Cli.Utils/Constants.cs +++ b/src/Cli/Microsoft.DotNet.Cli.Utils/Constants.cs @@ -28,5 +28,6 @@ public static class Constants public static readonly string AnyRid = "any"; public static readonly string RestoreInteractiveOption = "--interactive"; + public static readonly string workloadSetVersionFileName = "workloadVersion.txt"; } } diff --git a/src/Cli/Microsoft.DotNet.Cli.Utils/PathUtility.cs b/src/Cli/Microsoft.DotNet.Cli.Utils/PathUtility.cs index 75019c9e32e3..1957a49a1739 100644 --- a/src/Cli/Microsoft.DotNet.Cli.Utils/PathUtility.cs +++ b/src/Cli/Microsoft.DotNet.Cli.Utils/PathUtility.cs @@ -97,6 +97,30 @@ public static bool TryDeleteDirectory(string directoryPath) } } + /// + /// Deletes the provided file. Then deletes the parent directory if empty + /// and continues to its parent until it fails. Returns whether it succeeded + /// in deleting the file it was intended to delete. + /// + public static bool DeleteFileAndEmptyParents(string path) + { + if (!File.Exists(path)) + { + return false; + } + + File.Delete(path); + var dir = Path.GetDirectoryName(path); + + while (!Directory.EnumerateFileSystemEntries(dir).Any()) + { + Directory.Delete(dir); + dir = Path.GetDirectoryName(dir); + } + + return !File.Exists(path); + } + /// /// Returns childItem relative to directory, with Path.DirectorySeparatorChar as separator /// diff --git a/src/Cli/dotnet/Installer/Windows/InstallMessageDispatcher.cs b/src/Cli/dotnet/Installer/Windows/InstallMessageDispatcher.cs index 7d446db4944d..538bae6d1a46 100644 --- a/src/Cli/dotnet/Installer/Windows/InstallMessageDispatcher.cs +++ b/src/Cli/dotnet/Installer/Windows/InstallMessageDispatcher.cs @@ -192,5 +192,21 @@ public InstallResponseMessage SendUpdateWorkloadModeRequest(SdkFeatureBand sdkFe UseWorkloadSets = newMode, }); } + + /// + /// Send an to adjust the workload set version used for installing and updating workloads + /// + /// The SDK feature band of the install state file to write + /// The workload set version + /// + public InstallResponseMessage SendUpdateWorkloadSetRequest(SdkFeatureBand sdkFeatureBand, string newVersion) + { + return Send(new InstallRequestMessage + { + RequestType = InstallRequestType.AdjustWorkloadSetVersion, + SdkFeatureBand = sdkFeatureBand.ToString(), + WorkloadSetVersion = newVersion, + }); + } } } diff --git a/src/Cli/dotnet/Installer/Windows/InstallRequestMessage.cs b/src/Cli/dotnet/Installer/Windows/InstallRequestMessage.cs index 5ab6430bcbf4..962bdd90dd9f 100644 --- a/src/Cli/dotnet/Installer/Windows/InstallRequestMessage.cs +++ b/src/Cli/dotnet/Installer/Windows/InstallRequestMessage.cs @@ -128,6 +128,14 @@ public bool UseWorkloadSets get; set; } + /// + /// The workload set version + /// + public string WorkloadSetVersion + { + get; set; + } + /// /// Converts a deserialized array of bytes into an . /// diff --git a/src/Cli/dotnet/Installer/Windows/InstallRequestType.cs b/src/Cli/dotnet/Installer/Windows/InstallRequestType.cs index 2d90d3f2f68f..b734531d1b53 100644 --- a/src/Cli/dotnet/Installer/Windows/InstallRequestType.cs +++ b/src/Cli/dotnet/Installer/Windows/InstallRequestType.cs @@ -69,5 +69,10 @@ public enum InstallRequestType /// Changes the workload mode /// AdjustWorkloadMode, + + /// + /// Changes the workload set version + /// + AdjustWorkloadSetVersion, } } diff --git a/src/Cli/dotnet/commands/InstallingWorkloadCommand.cs b/src/Cli/dotnet/commands/InstallingWorkloadCommand.cs index 9e010dfb3632..d8ca6e0fc51d 100644 --- a/src/Cli/dotnet/commands/InstallingWorkloadCommand.cs +++ b/src/Cli/dotnet/commands/InstallingWorkloadCommand.cs @@ -34,6 +34,7 @@ internal abstract class InstallingWorkloadCommand : WorkloadCommandBase protected readonly SdkFeatureBand _sdkFeatureBand; protected readonly ReleaseVersion _targetSdkVersion; protected readonly string _fromRollbackDefinition; + protected string _workloadSetVersion; protected readonly PackageSourceLocation _packageSourceLocation; protected readonly IWorkloadResolverFactory _workloadResolverFactory; protected IWorkloadResolver _workloadResolver; @@ -96,6 +97,53 @@ protected static Dictionary GetInstallStateContents(IEnumerable< manifestVersionUpdates.Select(update => new WorkloadManifestInfo(update.ManifestId.ToString(), update.NewVersion.ToString(), /* We don't actually use the directory here */ string.Empty, update.NewFeatureBand)) ).ToDictionaryForJson(); + public static bool ShouldUseWorkloadSetMode(SdkFeatureBand sdkFeatureBand, string dotnetDir) + { + string path = Path.Combine(WorkloadInstallType.GetInstallStateFolder(sdkFeatureBand, dotnetDir), "default.json"); + var installStateContents = File.Exists(path) ? InstallStateContents.FromString(File.ReadAllText(path)) : new InstallStateContents(); + return installStateContents.UseWorkloadSets ?? false; + } + + protected IEnumerable HandleWorkloadUpdateFromVersion(ITransactionContext context, DirectoryPath? offlineCache) + { + // Ensure workload set mode is set to 'workloadset' + // Do not skip checking the mode first, as setting it triggers + // an admin authorization popup for MSI-based installs. + if (!ShouldUseWorkloadSetMode(_sdkFeatureBand, _dotnetPath)) + { + _workloadInstaller.UpdateInstallMode(_sdkFeatureBand, true); + } + + _workloadManifestUpdater.DownloadWorkloadSet(_workloadSetVersion, offlineCache); + return InstallWorkloadSet(context); + } + + public IEnumerable InstallWorkloadSet(ITransactionContext context) + { + var advertisingPackagePath = Path.Combine(_userProfileDir, "sdk-advertising", _sdkFeatureBand.ToString(), "microsoft.net.workloads"); + if (File.Exists(Path.Combine(advertisingPackagePath, Constants.workloadSetVersionFileName))) + { + // This file isn't created in tests. + PrintWorkloadSetTransition(File.ReadAllText(Path.Combine(advertisingPackagePath, Constants.workloadSetVersionFileName))); + } + var workloadSetPath = _workloadInstaller.InstallWorkloadSet(context, advertisingPackagePath); + var files = Directory.EnumerateFiles(workloadSetPath, "*.workloadset.json"); + return _workloadManifestUpdater.ParseRollbackDefinitionFiles(files); + } + + private void PrintWorkloadSetTransition(string newVersion) + { + var currentVersion = _workloadResolver.GetWorkloadVersion(); + if (currentVersion == null) + { + Reporter.WriteLine(string.Format(Strings.NewWorkloadSet, newVersion)); + } + else + { + Reporter.WriteLine(string.Format(Strings.WorkloadSetUpgrade, currentVersion, newVersion)); + } + } + protected async Task> GetDownloads(IEnumerable workloadIds, bool skipManifestUpdate, bool includePreview, string downloadFolder = null) { List ret = new(); @@ -202,6 +250,11 @@ internal static class InstallingWorkloadCommandParser Hidden = true }; + public static readonly CliOption WorkloadSetVersionOption = new("--version") + { + Description = Strings.WorkloadSetVersionOptionDescription + }; + public static readonly CliOption PrintDownloadLinkOnlyOption = new("--print-download-link-only") { Description = Strings.PrintDownloadLinkOnlyDescription, diff --git a/src/Cli/dotnet/commands/dotnet-workload/InstallStateContents.cs b/src/Cli/dotnet/commands/dotnet-workload/InstallStateContents.cs index 3c30ce66ab73..b625067712d3 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/InstallStateContents.cs +++ b/src/Cli/dotnet/commands/dotnet-workload/InstallStateContents.cs @@ -4,6 +4,8 @@ using System.Text.Json; using System.Text.Json.Serialization; +#pragma warning disable CS8632 + namespace Microsoft.DotNet.Workloads.Workload { internal class InstallStateContents @@ -12,17 +14,21 @@ internal class InstallStateContents public bool? UseWorkloadSets { get; set; } [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] - public Dictionary Manifests { get; set; } + public Dictionary? Manifests { get; set; } + + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? WorkloadVersion { get; set; } private static readonly JsonSerializerOptions s_options = new() { PropertyNamingPolicy = JsonNamingPolicy.CamelCase, WriteIndented = true, + AllowTrailingCommas = true, }; public static InstallStateContents FromString(string contents) { - return JsonSerializer.Deserialize(contents, s_options); + return JsonSerializer.Deserialize(contents, s_options) ?? new InstallStateContents(); } public static InstallStateContents FromPath(string path) @@ -35,4 +41,6 @@ public override string ToString() return JsonSerializer.Serialize(this, s_options); } } -} \ No newline at end of file +} + +#pragma warning restore CS8632 \ No newline at end of file diff --git a/src/Cli/dotnet/commands/dotnet-workload/WorkloadInfoHelper.cs b/src/Cli/dotnet/commands/dotnet-workload/WorkloadInfoHelper.cs index f686d494a53d..ec6a7641db54 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/WorkloadInfoHelper.cs +++ b/src/Cli/dotnet/commands/dotnet-workload/WorkloadInfoHelper.cs @@ -17,6 +17,7 @@ internal class WorkloadInfoHelper : IWorkloadInfoHelper { public readonly SdkFeatureBand _currentSdkFeatureBand; private readonly string _targetSdkVersion; + public string DotnetPath { get; } public WorkloadInfoHelper( bool isInteractive, @@ -30,20 +31,20 @@ public WorkloadInfoHelper( string userProfileDir = null, IWorkloadResolver workloadResolver = null) { - string dotnetPath = dotnetDir ?? Path.GetDirectoryName(Environment.ProcessPath); + DotnetPath = dotnetDir ?? Path.GetDirectoryName(Environment.ProcessPath); ReleaseVersion currentSdkReleaseVersion = new(currentSdkVersion ?? Product.Version); _currentSdkFeatureBand = new SdkFeatureBand(currentSdkReleaseVersion); _targetSdkVersion = targetSdkVersion; userProfileDir ??= CliFolderPathCalculator.DotnetUserProfileFolderPath; ManifestProvider = - new SdkDirectoryWorkloadManifestProvider(dotnetPath, + new SdkDirectoryWorkloadManifestProvider(DotnetPath, string.IsNullOrWhiteSpace(_targetSdkVersion) ? currentSdkReleaseVersion.ToString() : _targetSdkVersion, userProfileDir, SdkDirectoryWorkloadManifestProvider.GetGlobalJsonPath(Environment.CurrentDirectory)); WorkloadResolver = workloadResolver ?? NET.Sdk.WorkloadManifestReader.WorkloadResolver.Create( - ManifestProvider, dotnetPath, + ManifestProvider, DotnetPath, currentSdkReleaseVersion.ToString(), userProfileDir); var restoreConfig = new RestoreActionConfig(Interactive: isInteractive); diff --git a/src/Cli/dotnet/commands/dotnet-workload/clean/WorkloadCleanCommand.cs b/src/Cli/dotnet/commands/dotnet-workload/clean/WorkloadCleanCommand.cs index 5ccc9998f91f..ef0b679607b0 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/clean/WorkloadCleanCommand.cs +++ b/src/Cli/dotnet/commands/dotnet-workload/clean/WorkloadCleanCommand.cs @@ -59,7 +59,7 @@ public override int Execute() private void ExecuteGarbageCollection() { - _workloadInstaller.GarbageCollect(workloadSetVersion => _workloadResolverFactory.CreateForWorkloadSet(_dotnetPath, _sdkVersion.ToString(), _userProfileDir, workloadSetVersion), + _workloadInstaller.GarbageCollect(workloadVersion => _workloadResolverFactory.CreateForWorkloadSet(_dotnetPath, _sdkVersion.ToString(), _userProfileDir, workloadVersion), cleanAllPacks: _cleanAll); DisplayUninstallableVSWorkloads(); diff --git a/src/Cli/dotnet/commands/dotnet-workload/install/FileBasedInstaller.cs b/src/Cli/dotnet/commands/dotnet-workload/install/FileBasedInstaller.cs index 6b4af4b5f2cb..170dda6cccd4 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/install/FileBasedInstaller.cs +++ b/src/Cli/dotnet/commands/dotnet-workload/install/FileBasedInstaller.cs @@ -13,7 +13,7 @@ using NuGet.Common; using NuGet.Versioning; using static Microsoft.NET.Sdk.WorkloadManifestReader.WorkloadResolver; - +using PathUtility = Microsoft.DotNet.Tools.Common.PathUtility; namespace Microsoft.DotNet.Workloads.Workload.Install { @@ -85,6 +85,31 @@ IEnumerable GetPacksInWorkloads(IEnumerable workloadIds) return packs; } + public string InstallWorkloadSet(ITransactionContext context, string advertisingPackagePath) + { + var workloadVersion = File.ReadAllText(Path.Combine(advertisingPackagePath, Constants.workloadSetVersionFileName)); + var workloadSetPath = Path.Combine(_dotnetDir, "sdk-manifests", _sdkFeatureBand.ToString(), "workloadsets", workloadVersion); + context.Run( + action: () => + { + Directory.CreateDirectory(workloadSetPath); + + foreach (var file in Directory.EnumerateFiles(advertisingPackagePath)) + { + File.Copy(file, Path.Combine(workloadSetPath, Path.GetFileName(file)), overwrite: true); + } + }, + rollback: () => + { + foreach (var file in Directory.EnumerateFiles(workloadSetPath)) + { + PathUtility.DeleteFileAndEmptyParents(file); + } + }); + + return workloadSetPath; + } + public void InstallWorkloads(IEnumerable workloadIds, SdkFeatureBand sdkFeatureBand, ITransactionContext transactionContext, DirectoryPath? offlineCache = null) { var packInfos = GetPacksInWorkloads(workloadIds); @@ -452,6 +477,15 @@ public void GarbageCollect(Func getResolverForWorkloa } + public void AdjustWorkloadSetInInstallState(SdkFeatureBand sdkFeatureBand, string workloadVersion) + { + string path = Path.Combine(WorkloadInstallType.GetInstallStateFolder(_sdkFeatureBand, _dotnetDir), "default.json"); + Directory.CreateDirectory(Path.GetDirectoryName(path)); + var installStateContents = InstallStateContents.FromPath(path); + installStateContents.WorkloadVersion = workloadVersion; + File.WriteAllText(path, installStateContents.ToString()); + } + public void RemoveManifestsFromInstallState(SdkFeatureBand sdkFeatureBand) { string path = Path.Combine(WorkloadInstallType.GetInstallStateFolder(_sdkFeatureBand, _dotnetDir), "default.json"); @@ -509,7 +543,14 @@ public void Shutdown() public PackageId GetManifestPackageId(ManifestId manifestId, SdkFeatureBand featureBand) { - return new PackageId($"{manifestId}.Manifest-{featureBand}"); + if (manifestId.ToString().Equals("Microsoft.NET.Workloads", StringComparison.OrdinalIgnoreCase)) + { + return new PackageId($"{manifestId}.{featureBand}"); + } + else + { + return new PackageId($"{manifestId}.Manifest-{featureBand}"); + } } public async Task ExtractManifestAsync(string nupkgPath, string targetPath) diff --git a/src/Cli/dotnet/commands/dotnet-workload/install/IInstaller.cs b/src/Cli/dotnet/commands/dotnet-workload/install/IInstaller.cs index 5d388ef8bd21..275d5ecbcdce 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/install/IInstaller.cs +++ b/src/Cli/dotnet/commands/dotnet-workload/install/IInstaller.cs @@ -13,6 +13,8 @@ internal interface IInstaller : IWorkloadManifestInstaller { int ExitCode { get; } + string InstallWorkloadSet(ITransactionContext context, string advertisingPackagePath); + void InstallWorkloads(IEnumerable workloadIds, SdkFeatureBand sdkFeatureBand, ITransactionContext transactionContext, DirectoryPath? offlineCache = null); void RepairWorkloads(IEnumerable workloadIds, SdkFeatureBand sdkFeatureBand, DirectoryPath? offlineCache = null); @@ -25,6 +27,8 @@ internal interface IInstaller : IWorkloadManifestInstaller IEnumerable GetDownloads(IEnumerable workloadIds, SdkFeatureBand sdkFeatureBand, bool includeInstalledItems); + void AdjustWorkloadSetInInstallState(SdkFeatureBand sdkFeatureBand, string workloadVersion); + /// /// Replace the workload resolver used by this installer. Typically used to call /// for a set of workload manifests that isn't currently installed diff --git a/src/Cli/dotnet/commands/dotnet-workload/install/IWorkloadManifestUpdater.cs b/src/Cli/dotnet/commands/dotnet-workload/install/IWorkloadManifestUpdater.cs index d9dec221ad29..49af91545c87 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/install/IWorkloadManifestUpdater.cs +++ b/src/Cli/dotnet/commands/dotnet-workload/install/IWorkloadManifestUpdater.cs @@ -8,19 +8,22 @@ namespace Microsoft.DotNet.Workloads.Workload.Install { internal interface IWorkloadManifestUpdater { - Task UpdateAdvertisingManifestsAsync(bool includePreviews, DirectoryPath? offlineCache = null); + Task UpdateAdvertisingManifestsAsync(bool includePreviews, bool useWorkloadSets = false, DirectoryPath? offlineCache = null); Task BackgroundUpdateAdvertisingManifestsWhenRequiredAsync(); IEnumerable CalculateManifestUpdates(); IEnumerable CalculateManifestRollbacks(string rollbackDefinitionFilePath); + IEnumerable ParseRollbackDefinitionFiles(IEnumerable files); Task> GetManifestPackageDownloadsAsync(bool includePreviews, SdkFeatureBand providedSdkFeatureBand, SdkFeatureBand installedSdkFeatureBand); IEnumerable GetUpdatableWorkloadsToAdvertise(IEnumerable installedWorkloads); void DeleteUpdatableWorkloadsFile(); + + void DownloadWorkloadSet(string version, DirectoryPath? offlineCache); } internal record ManifestUpdateWithWorkloads(ManifestVersionUpdate ManifestUpdate, WorkloadCollection Workloads); diff --git a/src/Cli/dotnet/commands/dotnet-workload/install/LocalizableStrings.resx b/src/Cli/dotnet/commands/dotnet-workload/install/LocalizableStrings.resx index b9cd5af6b5dd..6fddf990e564 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/install/LocalizableStrings.resx +++ b/src/Cli/dotnet/commands/dotnet-workload/install/LocalizableStrings.resx @@ -346,4 +346,13 @@ Manifest MSI not found in NuGet package {0} + + Update to the specified workload version. + + + Installing workload version {0}. + + + Updating workload version from {0} to {1}. + diff --git a/src/Cli/dotnet/commands/dotnet-workload/install/MsiInstallerBase.cs b/src/Cli/dotnet/commands/dotnet-workload/install/MsiInstallerBase.cs index ed4dfcbe35c8..8f3b0ca4d4e2 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/install/MsiInstallerBase.cs +++ b/src/Cli/dotnet/commands/dotnet-workload/install/MsiInstallerBase.cs @@ -212,10 +212,8 @@ protected void UpdateInstallMode(SdkFeatureBand sdkFeatureBand, bool newMode) if (IsElevated) { // Create the parent folder for the state file and set up all required ACLs - SecurityUtils.CreateSecureDirectory(Path.GetDirectoryName(path)); installStateContents.UseWorkloadSets = newMode; - File.WriteAllText(path, installStateContents.ToString()); - SecurityUtils.SecureFile(path); + CreateSecureFileInDirectory(path, installStateContents.ToString()); } else if (IsClient) { @@ -228,6 +226,35 @@ protected void UpdateInstallMode(SdkFeatureBand sdkFeatureBand, bool newMode) } } + public void AdjustWorkloadSetInInstallState(SdkFeatureBand sdkFeatureBand, string workloadVersion) + { + string path = Path.Combine(WorkloadInstallType.GetInstallStateFolder(sdkFeatureBand, DotNetHome), "default.json"); + var installStateContents = InstallStateContents.FromPath(path); + if ((installStateContents.WorkloadVersion == null && workloadVersion == null) || + (installStateContents.WorkloadVersion != null && installStateContents.WorkloadVersion.Equals(workloadVersion))) + { + return; + } + + Elevate(); + + if (IsElevated) + { + // Create the parent folder for the state file and set up all required ACLs + installStateContents.WorkloadVersion = workloadVersion; + CreateSecureFileInDirectory(path, installStateContents.ToString()); + } + else if (IsClient) + { + InstallResponseMessage response = Dispatcher.SendUpdateWorkloadSetRequest(sdkFeatureBand, workloadVersion); + ExitOnFailure(response, "Failed to update install mode."); + } + else + { + throw new InvalidOperationException($"Invalid configuration: elevated: {IsElevated}, client: {IsClient}"); + } + } + /// /// Installs the specified MSI. /// @@ -506,13 +533,8 @@ public void SaveInstallStateManifestVersions(SdkFeatureBand sdkFeatureBand, Dict if (IsElevated) { // Create the parent folder for the state file and set up all required ACLs - SecurityUtils.CreateSecureDirectory(Path.GetDirectoryName(path)); - - installStateContents.Manifests = manifestContents; - File.WriteAllText(path, installStateContents.ToString()); - - SecurityUtils.SecureFile(path); + CreateSecureFileInDirectory(path, installStateContents.ToString()); } else if (IsClient) { @@ -520,5 +542,12 @@ public void SaveInstallStateManifestVersions(SdkFeatureBand sdkFeatureBand, Dict ExitOnFailure(respone, $"Failed to write install state file: {path}"); } } + + private void CreateSecureFileInDirectory(string path, string contents) + { + SecurityUtils.CreateSecureDirectory(Path.GetDirectoryName(path)); + File.WriteAllText(path, contents); + SecurityUtils.SecureFile(path); + } } } diff --git a/src/Cli/dotnet/commands/dotnet-workload/install/NetSdkMsiInstallerClient.cs b/src/Cli/dotnet/commands/dotnet-workload/install/NetSdkMsiInstallerClient.cs index da42df3373d3..5e22f6bb329d 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/install/NetSdkMsiInstallerClient.cs +++ b/src/Cli/dotnet/commands/dotnet-workload/install/NetSdkMsiInstallerClient.cs @@ -1,6 +1,7 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using System.Linq; using System.Runtime.Versioning; using Microsoft.DotNet.Cli; using Microsoft.DotNet.Cli.NuGetPackageDownloader; @@ -257,6 +258,60 @@ public void GarbageCollect(Func getResolverForWorkloa } } + // advertisingPackagePath is the path to the workload set MSI nupkg in the advertising package. + public string InstallWorkloadSet(ITransactionContext context, string advertisingPackagePath) + { + var pathToReturn = string.Empty; + context.Run( + action: () => + { + pathToReturn = ModifyWorkloadSet(advertisingPackagePath, InstallAction.Install); + }, + rollback: () => + { + ModifyWorkloadSet(advertisingPackagePath, InstallAction.Uninstall); + }); + + return pathToReturn; + } + + private string ModifyWorkloadSet(string advertisingPackagePath, InstallAction requestedAction) + { + ReportPendingReboot(); + + // Resolve the package ID for the manifest payload package + var featureBand = Path.GetFileName(Path.GetDirectoryName(advertisingPackagePath)); + var workloadSetVersion = File.ReadAllText(Path.Combine(advertisingPackagePath, Constants.workloadSetVersionFileName)); + string msiPackageId = GetManifestPackageId(new ManifestId("Microsoft.NET.Workloads"), new SdkFeatureBand(featureBand)).ToString(); + string msiPackageVersion = WorkloadManifestUpdater.WorkloadSetVersionToWorkloadSetPackageVersion(workloadSetVersion); + + Log?.LogMessage($"Resolving Microsoft.NET.Workloads ({workloadSetVersion}) to {msiPackageId} ({msiPackageVersion})."); + + // Retrieve the payload from the MSI package cache. + MsiPayload msi = GetCachedMsiPayload(msiPackageId, msiPackageVersion, null); + VerifyPackage(msi); + DetectState state = DetectPackage(msi.ProductCode, out Version installedVersion); + + InstallAction plannedAction = PlanPackage(msi, state, requestedAction, installedVersion); + + if (plannedAction != InstallAction.None) + { + Elevate(); + + ExecutePackage(msi, plannedAction, msiPackageId); + + // Update the reference count against the MSI. + UpdateDependent( + plannedAction == InstallAction.Uninstall ? + InstallRequestType.RemoveDependent : + InstallRequestType.AddDependent, + msi.Manifest.ProviderKeyName, + _dependent); + } + + return Path.Combine(DotNetHome, "sdk-manifests", _sdkFeatureBand.ToString(), "workloadsets", workloadSetVersion); + } + /// /// Find all the dependents that look like they belong to SDKs. We only care /// about dependents that match the SDK host we're running under. For example, an x86 SDK should not be @@ -587,7 +642,14 @@ public void Shutdown() public PackageId GetManifestPackageId(ManifestId manifestId, SdkFeatureBand featureBand) { - return new PackageId($"{manifestId}.Manifest-{featureBand}.Msi.{RuntimeInformation.ProcessArchitecture.ToString().ToLowerInvariant()}"); + if (manifestId.ToString().Equals("Microsoft.NET.Workloads", StringComparison.OrdinalIgnoreCase)) + { + return new PackageId($"{manifestId}.{featureBand}.Msi.{RuntimeInformation.ProcessArchitecture.ToString().ToLowerInvariant()}"); + } + else + { + return new PackageId($"{manifestId}.Manifest-{featureBand}.Msi.{RuntimeInformation.ProcessArchitecture.ToString().ToLowerInvariant()}"); + } } private static object _msiAdminInstallLock = new(); diff --git a/src/Cli/dotnet/commands/dotnet-workload/install/NetSdkMsiInstallerServer.cs b/src/Cli/dotnet/commands/dotnet-workload/install/NetSdkMsiInstallerServer.cs index 02c3bd3ead58..b2522e50e2d6 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/install/NetSdkMsiInstallerServer.cs +++ b/src/Cli/dotnet/commands/dotnet-workload/install/NetSdkMsiInstallerServer.cs @@ -109,6 +109,11 @@ public void Run() Dispatcher.ReplySuccess($"Updated install mode to use {newMode}."); break; + case InstallRequestType.AdjustWorkloadSetVersion: + AdjustWorkloadSetInInstallState(new SdkFeatureBand(request.SdkFeatureBand), request.WorkloadSetVersion); + Dispatcher.ReplySuccess($"Updated workload set version in install state to {request.WorkloadSetVersion}."); + break; + default: throw new InvalidOperationException($"Unknown message request: {(int)request.RequestType}"); } diff --git a/src/Cli/dotnet/commands/dotnet-workload/install/WorkloadGarbageCollector.cs b/src/Cli/dotnet/commands/dotnet-workload/install/WorkloadGarbageCollector.cs index cf25019d9994..8b75adb64743 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/install/WorkloadGarbageCollector.cs +++ b/src/Cli/dotnet/commands/dotnet-workload/install/WorkloadGarbageCollector.cs @@ -78,11 +78,11 @@ void GarbageCollectWorkloadSets() if (File.Exists(installStateFilePath)) { // If there is a rollback state file (default.json) in the workload install state folder, don't garbage collect the workload set it specifies. - var installState = SdkDirectoryWorkloadManifestProvider.InstallStateReader.ReadInstallState(installStateFilePath); - if (!string.IsNullOrEmpty(installState.WorkloadSetVersion)) + var installState = InstallStateContents.FromPath(installStateFilePath); + if (!string.IsNullOrEmpty(installState.WorkloadVersion)) { - WorkloadSetsToKeep.Add(installState.WorkloadSetVersion); - _verboseReporter.WriteLine($"GC: Keeping workload set version {installState.WorkloadSetVersion} because it is specified in the install state file {installStateFilePath}"); + WorkloadSetsToKeep.Add(installState.WorkloadVersion); + _verboseReporter.WriteLine($"GC: Keeping workload set version {installState.WorkloadVersion} because it is specified in the install state file {installStateFilePath}"); } } else diff --git a/src/Cli/dotnet/commands/dotnet-workload/install/WorkloadInstallCommand.cs b/src/Cli/dotnet/commands/dotnet-workload/install/WorkloadInstallCommand.cs index b5aa34015e8c..7025e5a5bf2b 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/install/WorkloadInstallCommand.cs +++ b/src/Cli/dotnet/commands/dotnet-workload/install/WorkloadInstallCommand.cs @@ -43,6 +43,14 @@ public WorkloadInstallCommand( _workloadManifestUpdater = _workloadManifestUpdaterFromConstructor ?? new WorkloadManifestUpdater(Reporter, _workloadResolver, PackageDownloader, _userProfileDir, _workloadInstaller.GetWorkloadInstallationRecordRepository(), _workloadInstaller, _packageSourceLocation, displayManifestUpdates: Verbosity.IsDetailedOrDiagnostic()); + _workloadSetVersion = parseResult.GetValue(InstallingWorkloadCommandParser.WorkloadSetVersionOption); + if (string.IsNullOrWhiteSpace(_workloadSetVersion)) + { + // If the version of the workload set is currently pinned, treat it as if it were freshly pinned. + var installStateContents = InstallStateContents.FromPath(Path.Combine(WorkloadInstallType.GetInstallStateFolder(_sdkFeatureBand, _dotnetPath), "default.json")); + _workloadSetVersion = installStateContents.WorkloadVersion; + } + ValidateWorkloadIdsInput(); } @@ -107,11 +115,24 @@ public override int Execute() { try { - InstallWorkloads( - _workloadIds.Select(id => new WorkloadId(id)), - _skipManifestUpdate, - _includePreviews, - string.IsNullOrWhiteSpace(_fromCacheOption) ? null : new DirectoryPath(_fromCacheOption)); + DirectoryPath? offlineCache = string.IsNullOrWhiteSpace(_fromCacheOption) ? null : new DirectoryPath(_fromCacheOption); + var workloadIds = _workloadIds.Select(id => new WorkloadId(id)); + if (string.IsNullOrWhiteSpace(_workloadSetVersion)) + { + InstallWorkloads( + workloadIds, + _skipManifestUpdate, + _includePreviews, + offlineCache); + } + else + { + RunInNewTransaction(context => + { + var manifests = HandleWorkloadUpdateFromVersion(context, offlineCache); + InstallWorkloadsAndGarbageCollect(context, workloadIds, manifests, offlineCache, false); + }); + } } catch (Exception e) { @@ -144,32 +165,46 @@ public void InstallWorkloads(IEnumerable workloadIds, bool skipManif } } - if (!skipManifestUpdate) + RunInNewTransaction(context => { - if (Verbosity != VerbosityOptions.quiet && Verbosity != VerbosityOptions.q) + if (!skipManifestUpdate) { - Reporter.WriteLine(LocalizableStrings.CheckForUpdatedWorkloadManifests); - } + if (Verbosity != VerbosityOptions.quiet && Verbosity != VerbosityOptions.q) + { + Reporter.WriteLine(LocalizableStrings.CheckForUpdatedWorkloadManifests); + } + // Add workload Ids that already exist to our collection to later trigger an update in those installed workloads + var installedWorkloads = _workloadInstaller.GetWorkloadInstallationRecordRepository().GetInstalledWorkloads(_sdkFeatureBand); + var previouslyInstalledWorkloads = installedWorkloads.Intersect(workloadIds); + if (previouslyInstalledWorkloads.Any()) + { + Reporter.WriteLine(string.Format(LocalizableStrings.WorkloadAlreadyInstalled, string.Join(" ", previouslyInstalledWorkloads)).Yellow()); + } + workloadIds = workloadIds.Concat(installedWorkloads).Distinct(); - // Add workload Ids that already exist to our collection to later trigger an update in those installed workloads - var installedWorkloads = _workloadInstaller.GetWorkloadInstallationRecordRepository().GetInstalledWorkloads(_sdkFeatureBand); - var previouslyInstalledWorkloads = installedWorkloads.Intersect(workloadIds); - if (previouslyInstalledWorkloads.Any()) - { - Reporter.WriteLine(string.Format(LocalizableStrings.WorkloadAlreadyInstalled, string.Join(" ", previouslyInstalledWorkloads)).Yellow()); - } + var useWorkloadSets = ShouldUseWorkloadSetMode(_sdkFeatureBand, _dotnetPath); + useRollback = !string.IsNullOrWhiteSpace(_fromRollbackDefinition); - workloadIds = workloadIds.Concat(installedWorkloads).Distinct(); + _workloadManifestUpdater.UpdateAdvertisingManifestsAsync(includePreviews, useWorkloadSets, offlineCache).Wait(); - useRollback = !string.IsNullOrWhiteSpace(_fromRollbackDefinition); + if (useWorkloadSets) + { + manifestsToUpdate = InstallWorkloadSet(context); + } + else + { + manifestsToUpdate = useRollback ? _workloadManifestUpdater.CalculateManifestRollbacks(_fromRollbackDefinition) : + _workloadManifestUpdater.CalculateManifestUpdates().Select(m => m.ManifestUpdate); + } + } - _workloadManifestUpdater.UpdateAdvertisingManifestsAsync(includePreviews, offlineCache).Wait(); - manifestsToUpdate = useRollback ? - _workloadManifestUpdater.CalculateManifestRollbacks(_fromRollbackDefinition) : - _workloadManifestUpdater.CalculateManifestUpdates().Select(m => m.ManifestUpdate); - } + InstallWorkloadsAndGarbageCollect(context, workloadIds, manifestsToUpdate, offlineCache, useRollback); + }); + } - InstallWorkloadsWithInstallRecord(_workloadInstaller, workloadIds, _sdkFeatureBand, manifestsToUpdate, offlineCache, useRollback); + private void InstallWorkloadsAndGarbageCollect(ITransactionContext context, IEnumerable workloadIds, IEnumerable manifestsToUpdate, DirectoryPath? offlineCache, bool useRollback) + { + InstallWorkloadsWithInstallRecord(context, _workloadInstaller, workloadIds, _sdkFeatureBand, manifestsToUpdate, offlineCache, useRollback); TryRunGarbageCollection(_workloadInstaller, Reporter, Verbosity, workloadSetVersion => _workloadResolverFactory.CreateForWorkloadSet(_dotnetPath, _sdkVersion.ToString(), _userProfileDir, workloadSetVersion), offlineCache); @@ -204,6 +239,7 @@ private void WriteSDKInstallRecordsForVSWorkloads() } private void InstallWorkloadsWithInstallRecord( + ITransactionContext context, IInstaller installer, IEnumerable workloadIds, SdkFeatureBand sdkFeatureBand, @@ -214,15 +250,8 @@ private void InstallWorkloadsWithInstallRecord( IEnumerable workloadPackToInstall = new List(); IEnumerable newWorkloadInstallRecords = new List(); - var transaction = new CliTransaction - { - RollbackStarted = () => Reporter.WriteLine(LocalizableStrings.RollingBackInstall), - // Don't hide the original error if roll back fails, but do log the rollback failure - RollbackFailed = ex => Reporter.WriteLine(string.Format(LocalizableStrings.RollBackFailedMessage, ex.Message)) - }; - - transaction.Run( - action: context => + context.Run( + action: () => { bool rollback = !string.IsNullOrWhiteSpace(_fromRollbackDefinition); @@ -236,6 +265,8 @@ private void InstallWorkloadsWithInstallRecord( installer.SaveInstallStateManifestVersions(sdkFeatureBand, GetInstallStateContents(manifestsToUpdate)); } + installer.AdjustWorkloadSetInInstallState(sdkFeatureBand, string.IsNullOrWhiteSpace(_workloadSetVersion) ? null : _workloadSetVersion); + _workloadResolver.RefreshWorkloadManifests(); installer.InstallWorkloads(workloadIds, sdkFeatureBand, context, offlineCache); @@ -246,13 +277,11 @@ private void InstallWorkloadsWithInstallRecord( { recordRepo.WriteWorkloadInstallationRecord(workloadId, sdkFeatureBand); } - }, rollback: () => { // InstallWorkloadManifest and InstallWorkloadPacks already handle rolling back their actions, so here we only // need to delete the installation records - foreach (var workloadId in newWorkloadInstallRecords) { installer.GetWorkloadInstallationRecordRepository() @@ -282,5 +311,16 @@ private Task DownloadToOfflineCacheAsync(IEnumerable workloadIds, Di { return GetDownloads(workloadIds, skipManifestUpdate, includePreviews, offlineCache.Value); } + + private void RunInNewTransaction(Action a) + { + var transaction = new CliTransaction() + { + RollbackStarted = () => Reporter.WriteLine(LocalizableStrings.RollingBackInstall), + // Don't hide the original error if roll back fails, but do log the rollback failure + RollbackFailed = ex => Reporter.WriteLine(string.Format(LocalizableStrings.RollBackFailedMessage, ex.Message)) + }; + transaction.Run(context => a(context)); + } } } diff --git a/src/Cli/dotnet/commands/dotnet-workload/install/WorkloadInstallCommandParser.cs b/src/Cli/dotnet/commands/dotnet-workload/install/WorkloadInstallCommandParser.cs index a7bbd03af121..f0323853dd79 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/install/WorkloadInstallCommandParser.cs +++ b/src/Cli/dotnet/commands/dotnet-workload/install/WorkloadInstallCommandParser.cs @@ -61,6 +61,7 @@ internal static void AddWorkloadInstallCommandOptions(CliCommand command) command.AddWorkloadCommandNuGetRestoreActionConfigOptions(); command.Options.Add(CommonOptions.VerbosityOption); command.Options.Add(SkipSignCheckOption); + command.Options.Add(InstallingWorkloadCommandParser.WorkloadSetVersionOption); } } } diff --git a/src/Cli/dotnet/commands/dotnet-workload/install/WorkloadManifestUpdater.cs b/src/Cli/dotnet/commands/dotnet-workload/install/WorkloadManifestUpdater.cs index a7fe27c39f50..bb91d359cdab 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/install/WorkloadManifestUpdater.cs +++ b/src/Cli/dotnet/commands/dotnet-workload/install/WorkloadManifestUpdater.cs @@ -11,6 +11,7 @@ using Microsoft.Extensions.EnvironmentAbstractions; using Microsoft.NET.Sdk.WorkloadManifestReader; using NuGet.Common; +using NuGet.Packaging; using NuGet.Versioning; namespace Microsoft.DotNet.Workloads.Workload.Install @@ -72,12 +73,25 @@ private static WorkloadManifestUpdater GetInstance(string userProfileDir) return new WorkloadManifestUpdater(reporter, workloadResolver, nugetPackageDownloader, userProfileDir, workloadRecordRepo, installer); } - public async Task UpdateAdvertisingManifestsAsync(bool includePreviews, DirectoryPath? offlineCache = null) + public async Task UpdateAdvertisingManifestsAsync(bool includePreviews, bool useWorkloadSets = false, DirectoryPath? offlineCache = null) { - // this updates all the manifests - var manifests = _workloadResolver.GetInstalledManifests(); - await Task.WhenAll(manifests.Select(manifest => UpdateAdvertisingManifestAsync(manifest, includePreviews, offlineCache))).ConfigureAwait(false); - WriteUpdatableWorkloadsFile(); + if (useWorkloadSets) + { + await UpdateManifestWithVersionAsync("Microsoft.NET.Workloads", includePreviews, _sdkFeatureBand, null, offlineCache); + } + else + { + // this updates all the manifests + var manifests = _workloadResolver.GetInstalledManifests(); + await Task.WhenAll(manifests.Select(manifest => UpdateAdvertisingManifestAsync(manifest, includePreviews, offlineCache))).ConfigureAwait(false); + WriteUpdatableWorkloadsFile(); + } + } + + public async void DownloadWorkloadSet(string version, DirectoryPath? offlineCache = null) + { + var correctedVersion = WorkloadSetVersionToWorkloadSetPackageVersion(version); + await UpdateManifestWithVersionAsync("Microsoft.NET.Workloads", includePreviews: true, _sdkFeatureBand, new NuGetVersion(correctedVersion), offlineCache); } public async static Task BackgroundUpdateAdvertisingManifestsAsync(string userProfileDir) @@ -99,7 +113,7 @@ public async Task BackgroundUpdateAdvertisingManifestsWhenRequiredAsync() AdManifestSentinelIsDueForUpdate() && UpdatedAdManifestPackagesExistAsync().GetAwaiter().GetResult()) { - await UpdateAdvertisingManifestsAsync(false); + await UpdateAdvertisingManifestsAsync(false, ShouldUseWorkloadSetMode(_sdkFeatureBand, _userProfileDir)); var sentinelPath = GetAdvertisingManifestSentinelPath(_sdkFeatureBand); if (File.Exists(sentinelPath)) { @@ -112,6 +126,13 @@ public async Task BackgroundUpdateAdvertisingManifestsWhenRequiredAsync() } } + public static bool ShouldUseWorkloadSetMode(SdkFeatureBand sdkFeatureBand, string dotnetDir) + { + string path = Path.Combine(WorkloadInstallType.GetInstallStateFolder(sdkFeatureBand, dotnetDir), "default.json"); + var installStateContents = File.Exists(path) ? InstallStateContents.FromString(File.ReadAllText(path)) : new InstallStateContents(); + return installStateContents.UseWorkloadSets ?? false; + } + private void WriteUpdatableWorkloadsFile() { var installedWorkloads = _workloadRecordRepo.GetInstalledWorkloads(_sdkFeatureBand); @@ -134,6 +155,22 @@ public void DeleteUpdatableWorkloadsFile() } } + public static string WorkloadSetVersionToWorkloadSetPackageVersion(string setVersion) + { + var nugetVersion = new NuGetVersion(setVersion); + var patch = nugetVersion.Revision; + var release = string.IsNullOrWhiteSpace(nugetVersion.Release) ? string.Empty : $"-{nugetVersion.Release}"; + return $"{nugetVersion.Major}.{nugetVersion.Patch}.{patch}{release}"; + } + + public static string WorkloadSetPackageVersionToWorkloadSetVersion(SdkFeatureBand sdkFeatureBand, string packageVersion) + { + var nugetVersion = new NuGetVersion(packageVersion); + var patch = nugetVersion.Patch > 0 ? $".{nugetVersion.Patch}" : string.Empty; + var release = string.IsNullOrWhiteSpace(nugetVersion.Release) ? string.Empty : $"-{nugetVersion.Release}"; + return $"{sdkFeatureBand.Major}.{sdkFeatureBand.Minor}.{nugetVersion.Minor}{patch}{release}"; + } + public static void AdvertiseWorkloadUpdates() { try @@ -196,7 +233,7 @@ public IEnumerable GetUpdatableWorkloadsToAdvertise(IEnumerable CalculateManifestRollbacks(string rollbackDefinitionFilePath) { var currentManifestIds = GetInstalledManifestIds(); - var manifestRollbacks = ParseRollbackDefinitionFile(rollbackDefinitionFilePath); + var manifestRollbacks = ParseRollbackDefinitionFile(rollbackDefinitionFilePath, _sdkFeatureBand); var unrecognizedManifestIds = manifestRollbacks.Where(rollbackManifest => !currentManifestIds.Contains(rollbackManifest.Id)); if (unrecognizedManifestIds.Any()) @@ -205,7 +242,12 @@ public IEnumerable CalculateManifestRollbacks(string roll manifestRollbacks = manifestRollbacks.Where(rollbackManifest => currentManifestIds.Contains(rollbackManifest.Id)); } - var manifestUpdates = manifestRollbacks.Select(manifest => + return CalculateManifestRollbacks(manifestRollbacks); + } + + private IEnumerable CalculateManifestRollbacks(IEnumerable<(ManifestId Id, ManifestVersionWithBand ManifestWithBand)> versionUpdates) + { + var manifestUpdates = versionUpdates.Select(manifest => { var (id, (version, band)) = manifest; var (installedVersion, installedBand) = GetInstalledManifestVersion(id); @@ -261,64 +303,60 @@ public async Task> GetManifestPackageDownloadsAsyn private IEnumerable GetInstalledManifestIds() => _workloadResolver.GetInstalledManifests().Select(manifest => new ManifestId(manifest.Id)); - private async Task UpdateAdvertisingManifestAsync(WorkloadManifestInfo manifest, bool includePreviews, DirectoryPath? offlineCache = null) + private async Task UpdateManifestWithVersionAsync(string id, bool includePreviews, SdkFeatureBand band, NuGetVersion packageVersion = null, DirectoryPath? offlineCache = null) { + var manifestId = new ManifestId(id); string packagePath = null; - var manifestId = new ManifestId(manifest.Id); try { - SdkFeatureBand? currentFeatureBand = null; - var fallbackFeatureBand = new SdkFeatureBand(manifest.ManifestFeatureBand); - // The bands should be checked in the order defined here. - SdkFeatureBand[] bands = [_sdkFeatureBand, fallbackFeatureBand]; - var success = false; - // Use Distinct to eliminate bands that are the same. - foreach (var band in bands.Distinct()) + var manifestPackageId = _workloadManifestInstaller.GetManifestPackageId(manifestId, band); + try + { + // If an offline cache is present, use that. Otherwise, try to acquire the package online. + packagePath = offlineCache != null ? + Directory.GetFiles(offlineCache.Value.Value) + .Where(path => + path.EndsWith(".nupkg") && + Path.GetFileName(path).StartsWith(manifestPackageId.ToString(), StringComparison.OrdinalIgnoreCase) && + (packageVersion == null || path.Contains(packageVersion.ToString()))) + .Max() : + await _nugetPackageDownloader.DownloadPackageAsync(manifestPackageId, packageVersion: packageVersion, packageSourceLocation: _packageSourceLocation, includePreview: includePreviews); + } + catch (NuGetPackageNotFoundException) { - var manifestPackageId = _workloadManifestInstaller.GetManifestPackageId(manifestId, band); - currentFeatureBand = band; - - try - { - // If an offline cache is present, use that. Otherwise, try to acquire the package online. - packagePath = offlineCache != null ? - Directory.GetFiles(offlineCache.Value.Value) - .Where(path => path.EndsWith(".nupkg") && Path.GetFileName(path).StartsWith(manifestPackageId.ToString(), StringComparison.OrdinalIgnoreCase)) - .Max() : - await _nugetPackageDownloader.DownloadPackageAsync(manifestPackageId, packageSourceLocation: _packageSourceLocation, includePreview: includePreviews); - - if (packagePath != null) - { - success = true; - break; - } - } - catch (NuGetPackageNotFoundException) - { - } } - if (!success) + if (packagePath is null) { - _reporter.WriteLine(LocalizableStrings.AdManifestPackageDoesNotExist, manifestId); - return; + return false; } var adManifestPath = GetAdvertisingManifestPath(_sdkFeatureBand, manifestId); await _workloadManifestInstaller.ExtractManifestAsync(packagePath, adManifestPath); // add file that contains the advertised manifest feature band so GetAdvertisingManifestVersionAndWorkloads will use correct feature band, regardless of if rollback occurred or not - File.WriteAllText(Path.Combine(adManifestPath, "AdvertisedManifestFeatureBand.txt"), currentFeatureBand.ToString()); + File.WriteAllText(Path.Combine(adManifestPath, "AdvertisedManifestFeatureBand.txt"), band.ToString()); + + if (id.Equals("Microsoft.NET.Workloads")) + { + // Create version file later used as part of installing the workload set in the file-based installer and in the msi-based installer + using PackageArchiveReader packageReader = new(packagePath); + var downloadedPackageVersion = packageReader.NuspecReader.GetVersion(); + var workloadSetVersion = WorkloadSetPackageVersionToWorkloadSetVersion(_sdkFeatureBand, downloadedPackageVersion.ToString()); + File.WriteAllText(Path.Combine(adManifestPath, Constants.workloadSetVersionFileName), workloadSetVersion); + } if (_displayManifestUpdates) { _reporter.WriteLine(LocalizableStrings.AdManifestUpdated, manifestId); } + return true; } catch (Exception e) { _reporter.WriteLine(LocalizableStrings.FailedAdManifestUpdate, manifestId, e.Message); + return false; } finally { @@ -343,6 +381,22 @@ private async Task UpdateAdvertisingManifestAsync(WorkloadManifestInfo manifest, } } + private async Task UpdateAdvertisingManifestAsync(WorkloadManifestInfo manifest, bool includePreviews, DirectoryPath? offlineCache = null) + { + var fallbackFeatureBand = new SdkFeatureBand(manifest.ManifestFeatureBand); + // The bands should be checked in the order defined here. + SdkFeatureBand[] bands = [_sdkFeatureBand, fallbackFeatureBand]; + foreach (var band in bands.Distinct()) + { + if (await UpdateManifestWithVersionAsync(manifest.Id, includePreviews, band, null, offlineCache)) + { + return; + } + } + + _reporter.WriteLine(LocalizableStrings.AdManifestPackageDoesNotExist, manifest.Id); + } + private (ManifestVersionWithBand ManifestWithBand, WorkloadCollection Workloads)? GetAdvertisingManifestVersionAndWorkloads(ManifestId manifestId) { var manifestPath = Path.Combine(GetAdvertisingManifestPath(_sdkFeatureBand, manifestId), "WorkloadManifest.json"); @@ -419,7 +473,41 @@ private async Task NewerManifestPackageExists(ManifestId manifest) } } - private IEnumerable<(ManifestId Id, ManifestVersionWithBand ManifestWithBand)> ParseRollbackDefinitionFile(string rollbackDefinitionFilePath) + public IEnumerable ParseRollbackDefinitionFiles(IEnumerable rollbackFilePaths) + { + if (rollbackFilePaths.Count() == 1) + { + return CalculateManifestRollbacks(rollbackFilePaths.Single()); + } + + var currentManifestIds = GetInstalledManifestIds(); + // Create a single workload set that includes all the others + List<(ManifestId, ManifestVersionWithBand)> fullSet = new(); + foreach (var rollbackFile in rollbackFilePaths) + { + var rollbacks = ParseRollbackDefinitionFile(rollbackFile, _sdkFeatureBand); + + var unrecognizedManifestIds = rollbacks.Where(rollbackManifest => !currentManifestIds.Contains(rollbackManifest.Id)); + if (unrecognizedManifestIds.Any()) + { + _reporter.WriteLine(string.Format(LocalizableStrings.RollbackDefinitionContainsExtraneousManifestIds, rollbackFile, string.Join(" ", unrecognizedManifestIds)).Yellow()); + rollbacks = rollbacks.Where(rollbackManifest => currentManifestIds.Contains(rollbackManifest.Id)); + } + + fullSet.AddRange(rollbacks); + } + + var reducedFullSet = fullSet.DistinctBy<(ManifestId, ManifestVersionWithBand), ManifestId>(update => update.Item1).ToList(); + if (fullSet.Count != reducedFullSet.Count) + { + var duplicates = reducedFullSet.Where(manifest => fullSet.Where(m => m.Item1.Equals(manifest.Item1)).Count() > 1); + throw new ArgumentException("There were duplicates of the following manifests between the workload set files: " + string.Join(", ", duplicates)); + } + + return CalculateManifestRollbacks(fullSet); + } + + private static IEnumerable<(ManifestId Id, ManifestVersionWithBand ManifestWithBand)> ParseRollbackDefinitionFile(string rollbackDefinitionFilePath, SdkFeatureBand featureBand) { string fileContent; @@ -439,7 +527,7 @@ private async Task NewerManifestPackageExists(ManifestId manifest) } } - var versions = WorkloadSet.FromJson(fileContent, _sdkFeatureBand).ManifestVersions; + var versions = WorkloadSet.FromJson(fileContent, featureBand).ManifestVersions; return versions.Select(kvp => (kvp.Key, new ManifestVersionWithBand(kvp.Value.Version, kvp.Value.FeatureBand))); } diff --git a/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.cs.xlf b/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.cs.xlf index 720a2aefe836..16d19acff6fe 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.cs.xlf +++ b/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.cs.xlf @@ -182,6 +182,11 @@ Odebírání {0}. + + Installing workload version {0}. + Installing workload version {0}. + + Failed to establish a trust relationship with parent process ({0}). Nepovedlo se navázat vztah důvěryhodnosti s nadřazeným procesem ({0}). @@ -367,6 +372,16 @@ Určete, jestli by budoucí operace úloh měly používat sady úloh nebo volné manifesty. + + Updating workload version from {0} to {1}. + Updating workload version from {0} to {1}. + + + + Update to the specified workload version. + Update to the specified workload version. + + Workload updates are available. Run `dotnet workload list` for more information. Jsou k dispozici aktualizace úloh. Pokud chcete získat další informace, spusťte `dotnet workload list`. diff --git a/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.de.xlf b/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.de.xlf index f412e4e21584..3684392e233f 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.de.xlf +++ b/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.de.xlf @@ -182,6 +182,11 @@ {0} wird entfernt + + Installing workload version {0}. + Installing workload version {0}. + + Failed to establish a trust relationship with parent process ({0}). Fehler beim Einrichten einer Vertrauensbeziehung mit dem übergeordneten Prozess ({0}). @@ -367,6 +372,16 @@ Hiermit wird gesteuert, ob zukünftige Workloadvorgänge Workloadsätze oder lose Manifeste verwenden sollen. + + Updating workload version from {0} to {1}. + Updating workload version from {0} to {1}. + + + + Update to the specified workload version. + Update to the specified workload version. + + Workload updates are available. Run `dotnet workload list` for more information. Es sind Workloadupdates verfügbar. Um weitere Informationen zu erhalten, führen Sie `dotnet workload list` aus. diff --git a/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.es.xlf b/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.es.xlf index 661379832a29..b85299b2a989 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.es.xlf +++ b/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.es.xlf @@ -182,6 +182,11 @@ Quitando {0} + + Installing workload version {0}. + Installing workload version {0}. + + Failed to establish a trust relationship with parent process ({0}). No se ha podido establecer una relación de confianza con el proceso primario ({0}). @@ -367,6 +372,16 @@ Controle si las operaciones de carga de trabajo futuras deben usar conjuntos de cargas de trabajo o manifiestos flexibles. + + Updating workload version from {0} to {1}. + Updating workload version from {0} to {1}. + + + + Update to the specified workload version. + Update to the specified workload version. + + Workload updates are available. Run `dotnet workload list` for more information. Hay actualizaciones de carga de trabajo disponibles. Ejecute "dotnet workload list" para obtener más información. diff --git a/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.fr.xlf b/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.fr.xlf index 1462fa793077..22f5c5ee64e0 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.fr.xlf +++ b/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.fr.xlf @@ -182,6 +182,11 @@ Suppression de {0} + + Installing workload version {0}. + Installing workload version {0}. + + Failed to establish a trust relationship with parent process ({0}). Impossible d’établir une relation de confiance avec le processus parent ({0}). @@ -367,6 +372,16 @@ Contrôlez si les futures opérations de charge de travail doivent utiliser des ensembles de charges de travail ou des manifestes lâches. + + Updating workload version from {0} to {1}. + Updating workload version from {0} to {1}. + + + + Update to the specified workload version. + Update to the specified workload version. + + Workload updates are available. Run `dotnet workload list` for more information. Des mises à jour de la charge de travail sont disponibles. Exécutez `dotnet workload list` pour plus d’informations. diff --git a/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.it.xlf b/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.it.xlf index 2f9f807b9fa6..0f2b45bf6774 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.it.xlf +++ b/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.it.xlf @@ -182,6 +182,11 @@ Rimozione di {0} + + Installing workload version {0}. + Installing workload version {0}. + + Failed to establish a trust relationship with parent process ({0}). Impossibile stabilire una relazione di attendibilità con il processo padre ({0}). @@ -367,6 +372,16 @@ Controllare se le operazioni future del carico di lavoro devono usare set di carichi di lavoro o manifesti separati. + + Updating workload version from {0} to {1}. + Updating workload version from {0} to {1}. + + + + Update to the specified workload version. + Update to the specified workload version. + + Workload updates are available. Run `dotnet workload list` for more information. Sono disponibili aggiornamenti del carico di lavoro. Per altre informazioni, eseguire `dotnet workload list`. diff --git a/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.ja.xlf b/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.ja.xlf index 93aa4172e61b..029a1695d244 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.ja.xlf +++ b/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.ja.xlf @@ -182,6 +182,11 @@ {0} を削除しています + + Installing workload version {0}. + Installing workload version {0}. + + Failed to establish a trust relationship with parent process ({0}). 親プロセス ({0}) との信頼関係を確立できませんでした。 @@ -367,6 +372,16 @@ 将来のワークロード操作でワークロード セットを使用するか、ルーズ マニフェストを使用するかを制御します。 + + Updating workload version from {0} to {1}. + Updating workload version from {0} to {1}. + + + + Update to the specified workload version. + Update to the specified workload version. + + Workload updates are available. Run `dotnet workload list` for more information. ワークロードの更新が利用可能です。詳細については、`dotnet workload list` を実行してください。 diff --git a/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.ko.xlf b/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.ko.xlf index dcfa49035630..928954891bfd 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.ko.xlf +++ b/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.ko.xlf @@ -182,6 +182,11 @@ {0} 제거 중 + + Installing workload version {0}. + Installing workload version {0}. + + Failed to establish a trust relationship with parent process ({0}). 부모 프로세스({0})와 신뢰 관계를 설정하지 못했습니다. @@ -367,6 +372,16 @@ 향후 워크로드 작업에서 워크로드 집합을 사용할지, 매니페스트를 완화할지를 제어합니다. + + Updating workload version from {0} to {1}. + Updating workload version from {0} to {1}. + + + + Update to the specified workload version. + Update to the specified workload version. + + Workload updates are available. Run `dotnet workload list` for more information. 워크로드 업데이트를 사용할 수 있습니다. 자세한 내용을 보려면 `dotnet workload list`을 실행하세요. diff --git a/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.pl.xlf b/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.pl.xlf index 6325acdc4b93..b2fc232366d5 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.pl.xlf +++ b/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.pl.xlf @@ -182,6 +182,11 @@ Usuwanie {0} + + Installing workload version {0}. + Installing workload version {0}. + + Failed to establish a trust relationship with parent process ({0}). Nie można ustanowić relacji zaufania z procesem nadrzędnym ({0}). @@ -367,6 +372,16 @@ Określ, czy przyszłe operacje związane z obciążeniami powinny wykorzystywać zestawy obciążeń, czy luźne manifesty. + + Updating workload version from {0} to {1}. + Updating workload version from {0} to {1}. + + + + Update to the specified workload version. + Update to the specified workload version. + + Workload updates are available. Run `dotnet workload list` for more information. Dostępne są aktualizacje obciążenia. Uruchom polecenie `dotnet workload list`, aby uzyskać więcej informacji. diff --git a/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.pt-BR.xlf b/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.pt-BR.xlf index 8c03cca867d1..f28bacbe2588 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.pt-BR.xlf +++ b/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.pt-BR.xlf @@ -182,6 +182,11 @@ Removendo {0} + + Installing workload version {0}. + Installing workload version {0}. + + Failed to establish a trust relationship with parent process ({0}). Falha ao estabelecer uma relação de confiança com o processo pai ({0}). @@ -367,6 +372,16 @@ Controle se as operações de carga de trabalho futuras devem usar conjuntos de carga de trabalho ou manifestos flexíveis. + + Updating workload version from {0} to {1}. + Updating workload version from {0} to {1}. + + + + Update to the specified workload version. + Update to the specified workload version. + + Workload updates are available. Run `dotnet workload list` for more information. As atualizações de carga de trabalho estão disponíveis. Execute `dotnet workload list` para obter mais informações. diff --git a/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.ru.xlf b/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.ru.xlf index b4940992ccc1..ed236e9b4434 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.ru.xlf +++ b/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.ru.xlf @@ -182,6 +182,11 @@ Идет удаление {0} + + Installing workload version {0}. + Installing workload version {0}. + + Failed to establish a trust relationship with parent process ({0}). Не удалось установить отношение доверия с родительским процессом ({0}). @@ -367,6 +372,16 @@ Укажите, должны ли будущие операции рабочей нагрузки использовать наборы рабочей нагрузки или свободные манифесты. + + Updating workload version from {0} to {1}. + Updating workload version from {0} to {1}. + + + + Update to the specified workload version. + Update to the specified workload version. + + Workload updates are available. Run `dotnet workload list` for more information. Доступны обновления рабочей нагрузки. Для получения дополнительных сведений запустите `dotnet workload list`. diff --git a/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.tr.xlf b/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.tr.xlf index 3691d8eb871c..8bfc444dd456 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.tr.xlf +++ b/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.tr.xlf @@ -182,6 +182,11 @@ {0} kaldırılıyor + + Installing workload version {0}. + Installing workload version {0}. + + Failed to establish a trust relationship with parent process ({0}). Üst işlemle ({0}) bir güven ilişkisi kurulamadı. @@ -367,6 +372,16 @@ Gelecekteki iş yükü işlemlerinin iş yükü kümelerini mi yoksa gevşek bildirimleri mi kullanması gerektiğini kontrol edin. + + Updating workload version from {0} to {1}. + Updating workload version from {0} to {1}. + + + + Update to the specified workload version. + Update to the specified workload version. + + Workload updates are available. Run `dotnet workload list` for more information. İş yükü güncelleştirmeleri var. Daha fazla bilgi için `dotnet workload list` çalıştırın. diff --git a/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.zh-Hans.xlf b/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.zh-Hans.xlf index 60dce47d2925..afc5f7b4f3d7 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.zh-Hans.xlf +++ b/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.zh-Hans.xlf @@ -182,6 +182,11 @@ 正在删除 {0} + + Installing workload version {0}. + Installing workload version {0}. + + Failed to establish a trust relationship with parent process ({0}). 未能建立与父进程({0})之间的信任关系。 @@ -367,6 +372,16 @@ 控制未来的工作负载操作应该使用工作负载集还是松散清单。 + + Updating workload version from {0} to {1}. + Updating workload version from {0} to {1}. + + + + Update to the specified workload version. + Update to the specified workload version. + + Workload updates are available. Run `dotnet workload list` for more information. 有可用的工作负载更新。有关详细信息,请运行 `dotnet workload list`。 diff --git a/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.zh-Hant.xlf b/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.zh-Hant.xlf index 4921d99e1aab..b1c547749558 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.zh-Hant.xlf +++ b/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.zh-Hant.xlf @@ -182,6 +182,11 @@ 正在移除 {0} + + Installing workload version {0}. + Installing workload version {0}. + + Failed to establish a trust relationship with parent process ({0}). 無法與父處理序 ({0}) 建立信任關係。 @@ -367,6 +372,16 @@ 控制未來的工作負載作業應該使用工作負載集合還是鬆散資訊清單。 + + Updating workload version from {0} to {1}. + Updating workload version from {0} to {1}. + + + + Update to the specified workload version. + Update to the specified workload version. + + Workload updates are available. Run `dotnet workload list` for more information. 有可用的工作負載更新。如需詳細資訊,請執行 `dotnet workload list`。 diff --git a/src/Cli/dotnet/commands/dotnet-workload/list/LocalizableStrings.resx b/src/Cli/dotnet/commands/dotnet-workload/list/LocalizableStrings.resx index b7a929ae43e1..dbb30fdcd881 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/list/LocalizableStrings.resx +++ b/src/Cli/dotnet/commands/dotnet-workload/list/LocalizableStrings.resx @@ -128,4 +128,7 @@ Use `dotnet workload search` to find additional workloads to install. {Locked="dotnet workload search"} + + Workload version: {0} + \ No newline at end of file diff --git a/src/Cli/dotnet/commands/dotnet-workload/list/WorkloadListCommand.cs b/src/Cli/dotnet/commands/dotnet-workload/list/WorkloadListCommand.cs index 2a3d861b517e..93dcc18f90f3 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/list/WorkloadListCommand.cs +++ b/src/Cli/dotnet/commands/dotnet-workload/list/WorkloadListCommand.cs @@ -20,7 +20,7 @@ internal class WorkloadListCommand : WorkloadCommandBase private readonly bool _includePreviews; private readonly bool _machineReadableOption; private readonly IWorkloadManifestUpdater _workloadManifestUpdater; - private readonly IWorkloadInfoHelper _workloadListHelper; + private readonly WorkloadInfoHelper _workloadListHelper; public WorkloadListCommand( ParseResult parseResult, @@ -93,6 +93,13 @@ public override int Execute() table.PrintRows(installedWorkloads.AsEnumerable(), l => Reporter.WriteLine(l)); + var installState = InstallStateContents.FromPath(Path.Combine(WorkloadInstallType.GetInstallStateFolder(_workloadListHelper._currentSdkFeatureBand, _workloadListHelper.DotnetPath), "default.json")); + if (installState.UseWorkloadSets == true) + { + Reporter.WriteLine(); + Reporter.WriteLine(string.Format(LocalizableStrings.WorkloadSetVersion, _workloadListHelper.WorkloadResolver.GetWorkloadVersion() ?? "unknown")); + } + Reporter.WriteLine(); Reporter.WriteLine(LocalizableStrings.WorkloadListFooter); Reporter.WriteLine(); @@ -110,6 +117,7 @@ public override int Execute() internal IEnumerable GetUpdateAvailable(IEnumerable installedList) { + // This was an internal partner ask, and they do not need to support workload sets. _workloadManifestUpdater.UpdateAdvertisingManifestsAsync(_includePreviews).Wait(); var manifestsToUpdate = _workloadManifestUpdater.CalculateManifestUpdates(); diff --git a/src/Cli/dotnet/commands/dotnet-workload/list/xlf/LocalizableStrings.cs.xlf b/src/Cli/dotnet/commands/dotnet-workload/list/xlf/LocalizableStrings.cs.xlf index dbc5c5d7eb39..66284edd36c8 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/list/xlf/LocalizableStrings.cs.xlf +++ b/src/Cli/dotnet/commands/dotnet-workload/list/xlf/LocalizableStrings.cs.xlf @@ -12,6 +12,11 @@ Pokud chcete najít další úlohy, které se mají nainstalovat, použijte `dotnet workload search`. {Locked="dotnet workload search"} + + Workload version: {0} + Workload version: {0} + + Updates are available for the following workload(s): {0}. Run `dotnet workload update` to get the latest. Aktualizace jsou k dispozici pro následující úlohy: {0}. Pokud chcete získat nejnovější verzi, spusťte aktualizaci úlohy dotnet (`dotnet workload update`). diff --git a/src/Cli/dotnet/commands/dotnet-workload/list/xlf/LocalizableStrings.de.xlf b/src/Cli/dotnet/commands/dotnet-workload/list/xlf/LocalizableStrings.de.xlf index 63bfadefbaed..df59aa34bd89 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/list/xlf/LocalizableStrings.de.xlf +++ b/src/Cli/dotnet/commands/dotnet-workload/list/xlf/LocalizableStrings.de.xlf @@ -12,6 +12,11 @@ Verwenden Sie „dotnet workload search“, um zusätzliche zu installierende Workloads zu finden. {Locked="dotnet workload search"} + + Workload version: {0} + Workload version: {0} + + Updates are available for the following workload(s): {0}. Run `dotnet workload update` to get the latest. Updates sind für die folgenden Workloads verfügbar: {0}. Führen Sie „dotnet workload update“ aus, um die neueste Updates zu erhalten. diff --git a/src/Cli/dotnet/commands/dotnet-workload/list/xlf/LocalizableStrings.es.xlf b/src/Cli/dotnet/commands/dotnet-workload/list/xlf/LocalizableStrings.es.xlf index 6a235d3dceb3..80f0a9398d5e 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/list/xlf/LocalizableStrings.es.xlf +++ b/src/Cli/dotnet/commands/dotnet-workload/list/xlf/LocalizableStrings.es.xlf @@ -12,6 +12,11 @@ Use "dotnet workload search" para buscar cargas de trabajo adicionales para instalar. {Locked="dotnet workload search"} + + Workload version: {0} + Workload version: {0} + + Updates are available for the following workload(s): {0}. Run `dotnet workload update` to get the latest. Hay actualizaciones disponibles para las siguientes cargas de trabajo: {0}. Ejecute "dotnet workload update" para obtener la versión más reciente. diff --git a/src/Cli/dotnet/commands/dotnet-workload/list/xlf/LocalizableStrings.fr.xlf b/src/Cli/dotnet/commands/dotnet-workload/list/xlf/LocalizableStrings.fr.xlf index 7bb2a04f586e..3f4c46ae97ca 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/list/xlf/LocalizableStrings.fr.xlf +++ b/src/Cli/dotnet/commands/dotnet-workload/list/xlf/LocalizableStrings.fr.xlf @@ -12,6 +12,11 @@ Utilisez `dotnet workload search` pour rechercher d’autres charges de travail à installer. {Locked="dotnet workload search"} + + Workload version: {0} + Workload version: {0} + + Updates are available for the following workload(s): {0}. Run `dotnet workload update` to get the latest. Des mises à jour sont disponibles pour les charges de travail suivantes : {0}. Exécutez `dotnet workload update` pour obtenir la dernière version. diff --git a/src/Cli/dotnet/commands/dotnet-workload/list/xlf/LocalizableStrings.it.xlf b/src/Cli/dotnet/commands/dotnet-workload/list/xlf/LocalizableStrings.it.xlf index 1cbcf50e4808..caa33f6a522b 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/list/xlf/LocalizableStrings.it.xlf +++ b/src/Cli/dotnet/commands/dotnet-workload/list/xlf/LocalizableStrings.it.xlf @@ -12,6 +12,11 @@ Utilizzare la `dotnet workload search` per trovare i carichi di lavoro aggiuntivi da installare. {Locked="dotnet workload search"} + + Workload version: {0} + Workload version: {0} + + Updates are available for the following workload(s): {0}. Run `dotnet workload update` to get the latest. Gli aggiornamenti sono disponibili per i carichi di lavoro seguenti: {0}. Per ottenere la versione più recente, eseguire 'dotnet workload update'. diff --git a/src/Cli/dotnet/commands/dotnet-workload/list/xlf/LocalizableStrings.ja.xlf b/src/Cli/dotnet/commands/dotnet-workload/list/xlf/LocalizableStrings.ja.xlf index 2b121428078f..58eaa7887ce4 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/list/xlf/LocalizableStrings.ja.xlf +++ b/src/Cli/dotnet/commands/dotnet-workload/list/xlf/LocalizableStrings.ja.xlf @@ -12,6 +12,11 @@ `dotnet workload search` を使用して追加ワークロードを検出し、インストールします。 {Locked="dotnet workload search"} + + Workload version: {0} + Workload version: {0} + + Updates are available for the following workload(s): {0}. Run `dotnet workload update` to get the latest. 次のワークロードについて更新プログラムを入手可能です: {0}。最新版を取得するには、`dotnet workload update` を実行します。 diff --git a/src/Cli/dotnet/commands/dotnet-workload/list/xlf/LocalizableStrings.ko.xlf b/src/Cli/dotnet/commands/dotnet-workload/list/xlf/LocalizableStrings.ko.xlf index bc25fba551b4..7b93e295c32c 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/list/xlf/LocalizableStrings.ko.xlf +++ b/src/Cli/dotnet/commands/dotnet-workload/list/xlf/LocalizableStrings.ko.xlf @@ -12,6 +12,11 @@ `dotnet workload search`을 사용하여 설치할 추가 워크로드를 찾습니다. {Locked="dotnet workload search"} + + Workload version: {0} + Workload version: {0} + + Updates are available for the following workload(s): {0}. Run `dotnet workload update` to get the latest. 다음 워크로드에 대한 업데이트를 사용할 수 있습니다. {0}. 최신 버전을 받으려면 `dotnet workload update`를 실행하세요. diff --git a/src/Cli/dotnet/commands/dotnet-workload/list/xlf/LocalizableStrings.pl.xlf b/src/Cli/dotnet/commands/dotnet-workload/list/xlf/LocalizableStrings.pl.xlf index d831a98b9807..6dab03cac48a 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/list/xlf/LocalizableStrings.pl.xlf +++ b/src/Cli/dotnet/commands/dotnet-workload/list/xlf/LocalizableStrings.pl.xlf @@ -12,6 +12,11 @@ Użyj polecenia „dotnet workload search”, aby znaleźć dodatkowe obciążenia do zainstalowania. {Locked="dotnet workload search"} + + Workload version: {0} + Workload version: {0} + + Updates are available for the following workload(s): {0}. Run `dotnet workload update` to get the latest. Aktualizacje są dostępne dla następujących obciążeń: {0}. Uruchom polecenie `dotnet workload update`, aby uzyskać najnowszą wersję. diff --git a/src/Cli/dotnet/commands/dotnet-workload/list/xlf/LocalizableStrings.pt-BR.xlf b/src/Cli/dotnet/commands/dotnet-workload/list/xlf/LocalizableStrings.pt-BR.xlf index b9246e9d8a9b..bfd92a1420d3 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/list/xlf/LocalizableStrings.pt-BR.xlf +++ b/src/Cli/dotnet/commands/dotnet-workload/list/xlf/LocalizableStrings.pt-BR.xlf @@ -12,6 +12,11 @@ Use `dotnet workload search` para encontrar cargas de trabalho adicionais a serem instaladas. {Locked="dotnet workload search"} + + Workload version: {0} + Workload version: {0} + + Updates are available for the following workload(s): {0}. Run `dotnet workload update` to get the latest. As atualizações estão disponíveis para as seguintes cargas de trabalho(s): {0}. Execute `dotnet workload update` para obter o mais recente. diff --git a/src/Cli/dotnet/commands/dotnet-workload/list/xlf/LocalizableStrings.ru.xlf b/src/Cli/dotnet/commands/dotnet-workload/list/xlf/LocalizableStrings.ru.xlf index 7ddcbf47db14..8001bc04e0f0 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/list/xlf/LocalizableStrings.ru.xlf +++ b/src/Cli/dotnet/commands/dotnet-workload/list/xlf/LocalizableStrings.ru.xlf @@ -12,6 +12,11 @@ Используйте `dotnet workload search`, чтобы найти дополнительные рабочие нагрузки для установки. {Locked="dotnet workload search"} + + Workload version: {0} + Workload version: {0} + + Updates are available for the following workload(s): {0}. Run `dotnet workload update` to get the latest. Обновления доступны для следующих рабочих нагрузок: {0}. Чтобы получить последнюю версию, запустите `dotnet workload update`. diff --git a/src/Cli/dotnet/commands/dotnet-workload/list/xlf/LocalizableStrings.tr.xlf b/src/Cli/dotnet/commands/dotnet-workload/list/xlf/LocalizableStrings.tr.xlf index 9ea3ecc06a29..3b0ac98ba2d2 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/list/xlf/LocalizableStrings.tr.xlf +++ b/src/Cli/dotnet/commands/dotnet-workload/list/xlf/LocalizableStrings.tr.xlf @@ -12,6 +12,11 @@ Yüklenecek ek iş yüklerini bulmak için `dotnet workload search` kullanın. {Locked="dotnet workload search"} + + Workload version: {0} + Workload version: {0} + + Updates are available for the following workload(s): {0}. Run `dotnet workload update` to get the latest. Şu iş yükleri için güncelleştirmeler var: {0}. En son sürümü almak için `dotnet workload update` çalıştırın. diff --git a/src/Cli/dotnet/commands/dotnet-workload/list/xlf/LocalizableStrings.zh-Hans.xlf b/src/Cli/dotnet/commands/dotnet-workload/list/xlf/LocalizableStrings.zh-Hans.xlf index ae6dab8c46d0..35e9756641e4 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/list/xlf/LocalizableStrings.zh-Hans.xlf +++ b/src/Cli/dotnet/commands/dotnet-workload/list/xlf/LocalizableStrings.zh-Hans.xlf @@ -12,6 +12,11 @@ 使用`dotnet workload search`查找要安装的其他工作负载。 {Locked="dotnet workload search"} + + Workload version: {0} + Workload version: {0} + + Updates are available for the following workload(s): {0}. Run `dotnet workload update` to get the latest. 以下工作负载有可用的更新: {0}。请运行 `dotnet workload update` 以获取最新版本。 diff --git a/src/Cli/dotnet/commands/dotnet-workload/list/xlf/LocalizableStrings.zh-Hant.xlf b/src/Cli/dotnet/commands/dotnet-workload/list/xlf/LocalizableStrings.zh-Hant.xlf index 8365be692fe5..424fdf614a55 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/list/xlf/LocalizableStrings.zh-Hant.xlf +++ b/src/Cli/dotnet/commands/dotnet-workload/list/xlf/LocalizableStrings.zh-Hant.xlf @@ -12,6 +12,11 @@ 使用 `dotnet workload search` 尋找其他要安裝的工作負載。 {Locked="dotnet workload search"} + + Workload version: {0} + Workload version: {0} + + Updates are available for the following workload(s): {0}. Run `dotnet workload update` to get the latest. 以下工作負載有可用的更新: {0}。執行 `dotnet workload update` 以取得最新更新。 diff --git a/src/Cli/dotnet/commands/dotnet-workload/update/LocalizableStrings.resx b/src/Cli/dotnet/commands/dotnet-workload/update/LocalizableStrings.resx index 77709f82d798..58a400e6ede6 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/update/LocalizableStrings.resx +++ b/src/Cli/dotnet/commands/dotnet-workload/update/LocalizableStrings.resx @@ -156,4 +156,7 @@ Update workloads based on specified rollback definition file. + + Updating to a rollback file is not compatible with workload sets. Install and Update will now use loose manifests. To update to a specific workload version, use --version. + \ No newline at end of file diff --git a/src/Cli/dotnet/commands/dotnet-workload/update/WorkloadUpdateCommand.cs b/src/Cli/dotnet/commands/dotnet-workload/update/WorkloadUpdateCommand.cs index bf09bce1112b..0d14b1fc84f7 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/update/WorkloadUpdateCommand.cs +++ b/src/Cli/dotnet/commands/dotnet-workload/update/WorkloadUpdateCommand.cs @@ -37,6 +37,7 @@ public WorkloadUpdateCommand( tempDirPath: tempDirPath) { + _workloadSetVersion = parseResult.GetValue(InstallingWorkloadCommandParser.WorkloadSetVersionOption); _fromPreviousSdk = parseResult.GetValue(WorkloadUpdateCommandParser.FromPreviousSdkOption); _adManifestOnlyOption = parseResult.GetValue(WorkloadUpdateCommandParser.AdManifestOnlyOption); _printRollbackDefinitionOnly = parseResult.GetValue(WorkloadUpdateCommandParser.PrintRollbackOption); @@ -73,7 +74,13 @@ public override int Execute() } else if (_adManifestOnlyOption) { - _workloadManifestUpdater.UpdateAdvertisingManifestsAsync(_includePreviews, string.IsNullOrWhiteSpace(_fromCacheOption) ? null : new DirectoryPath(_fromCacheOption)).Wait(); + _workloadManifestUpdater.UpdateAdvertisingManifestsAsync( + _includePreviews, + ShouldUseWorkloadSetMode(_sdkFeatureBand, _dotnetPath), + string.IsNullOrWhiteSpace(_fromCacheOption) ? + null : + new DirectoryPath(_fromCacheOption)) + .Wait(); Reporter.WriteLine(); Reporter.WriteLine(LocalizableStrings.WorkloadUpdateAdManifestsSucceeded); } @@ -105,7 +112,19 @@ public override int Execute() { try { - UpdateWorkloads(_includePreviews, string.IsNullOrWhiteSpace(_fromCacheOption) ? null : new DirectoryPath(_fromCacheOption)); + DirectoryPath? offlineCache = string.IsNullOrWhiteSpace(_fromCacheOption) ? null : new DirectoryPath(_fromCacheOption); + if (string.IsNullOrWhiteSpace(_workloadSetVersion)) + { + CalculateManifestUpdatesAndUpdateWorkloads(_includePreviews, offlineCache); + } + else + { + RunInNewTransaction(context => + { + var manifestUpdates = HandleWorkloadUpdateFromVersion(context, offlineCache); + UpdateWorkloads(false, manifestUpdates, offlineCache, context); + }); + } } catch (Exception e) { @@ -118,29 +137,55 @@ public override int Execute() return _workloadInstaller.ExitCode; } - public void UpdateWorkloads(bool includePreviews = false, DirectoryPath? offlineCache = null) + public void CalculateManifestUpdatesAndUpdateWorkloads(bool includePreviews = false, DirectoryPath? offlineCache = null) { Reporter.WriteLine(); + var useRollback = !string.IsNullOrWhiteSpace(_fromRollbackDefinition); + var useWorkloadSets = ShouldUseWorkloadSetMode(_sdkFeatureBand, _dotnetPath); + + if (useRollback && useWorkloadSets) + { + // Rollback files are only for loose manifests. Update the mode to be loose manifests. + Reporter.WriteLine(LocalizableStrings.UpdateFromRollbackSwitchesModeToLooseManifests); + _workloadInstaller.UpdateInstallMode(_sdkFeatureBand, false); + useWorkloadSets = false; + } + var workloadIds = GetUpdatableWorkloads(); WriteSDKInstallRecordsForVSWorkloads(workloadIds); - _workloadManifestUpdater.UpdateAdvertisingManifestsAsync(includePreviews, offlineCache).Wait(); + _workloadManifestUpdater.UpdateAdvertisingManifestsAsync(includePreviews, useWorkloadSets, offlineCache).Wait(); - var useRollback = !string.IsNullOrWhiteSpace(_fromRollbackDefinition); + IEnumerable manifestsToUpdate; + RunInNewTransaction(context => + { + if (useWorkloadSets) + { + manifestsToUpdate = InstallWorkloadSet(context); + } + else + { + manifestsToUpdate = useRollback ? _workloadManifestUpdater.CalculateManifestRollbacks(_fromRollbackDefinition) : + _workloadManifestUpdater.CalculateManifestUpdates().Select(m => m.ManifestUpdate); + } - var manifestsToUpdate = useRollback ? - _workloadManifestUpdater.CalculateManifestRollbacks(_fromRollbackDefinition) : - _workloadManifestUpdater.CalculateManifestUpdates().Select(m => m.ManifestUpdate); + UpdateWorkloads(useRollback, manifestsToUpdate, offlineCache, context); + + Reporter.WriteLine(); + Reporter.WriteLine(string.Format(LocalizableStrings.UpdateSucceeded, string.Join(" ", workloadIds))); + Reporter.WriteLine(); + }); + } - UpdateWorkloadsWithInstallRecord(_sdkFeatureBand, manifestsToUpdate, useRollback, offlineCache); + private void UpdateWorkloads(bool useRollback, IEnumerable manifestsToUpdate, DirectoryPath? offlineCache, ITransactionContext context) + { + var workloadIds = GetUpdatableWorkloads(); + + UpdateWorkloadsWithInstallRecord(_sdkFeatureBand, manifestsToUpdate, useRollback, context, offlineCache); WorkloadInstallCommand.TryRunGarbageCollection(_workloadInstaller, Reporter, Verbosity, workloadSetVersion => _workloadResolverFactory.CreateForWorkloadSet(_dotnetPath, _sdkVersion.ToString(), _userProfileDir, workloadSetVersion), offlineCache); _workloadManifestUpdater.DeleteUpdatableWorkloadsFile(); - - Reporter.WriteLine(); - Reporter.WriteLine(string.Format(LocalizableStrings.UpdateSucceeded, string.Join(" ", workloadIds))); - Reporter.WriteLine(); } private void WriteSDKInstallRecordsForVSWorkloads(IEnumerable updateableWorkloads) @@ -157,23 +202,11 @@ private void UpdateWorkloadsWithInstallRecord( SdkFeatureBand sdkFeatureBand, IEnumerable manifestsToUpdate, bool useRollback, + ITransactionContext context, DirectoryPath? offlineCache = null) { - - var transaction = new CliTransaction(); - - transaction.RollbackStarted = () => - { - Reporter.WriteLine(LocalizableStrings.RollingBackInstall); - }; - // Don't hide the original error if roll back fails, but do log the rollback failure - transaction.RollbackFailed = ex => - { - Reporter.WriteLine(string.Format(LocalizableStrings.RollBackFailedMessage, ex.Message)); - }; - - transaction.Run( - action: context => + context.Run( + action: () => { foreach (var manifestUpdate in manifestsToUpdate) { @@ -189,6 +222,8 @@ private void UpdateWorkloadsWithInstallRecord( _workloadInstaller.RemoveManifestsFromInstallState(sdkFeatureBand); } + _workloadInstaller.AdjustWorkloadSetInInstallState(sdkFeatureBand, string.IsNullOrWhiteSpace(_workloadSetVersion) ? null : _workloadSetVersion); + _workloadResolver.RefreshWorkloadManifests(); var workloads = GetUpdatableWorkloads(); @@ -232,5 +267,21 @@ private IEnumerable GetUpdatableWorkloads() return workloads; } + + private void RunInNewTransaction(Action a) + { + var transaction = new CliTransaction(); + transaction.RollbackStarted = () => + { + Reporter.WriteLine(LocalizableStrings.RollingBackInstall); + }; + // Don't hide the original error if roll back fails, but do log the rollback failure + transaction.RollbackFailed = ex => + { + Reporter.WriteLine(string.Format(LocalizableStrings.RollBackFailedMessage, ex.Message)); + }; + + transaction.Run(context => a(context)); + } } } diff --git a/src/Cli/dotnet/commands/dotnet-workload/update/WorkloadUpdateCommandParser.cs b/src/Cli/dotnet/commands/dotnet-workload/update/WorkloadUpdateCommandParser.cs index fe068fc74b70..787189013bb4 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/update/WorkloadUpdateCommandParser.cs +++ b/src/Cli/dotnet/commands/dotnet-workload/update/WorkloadUpdateCommandParser.cs @@ -43,6 +43,7 @@ private static CliCommand ConstructCommand() command.Options.Add(TempDirOption); command.Options.Add(FromPreviousSdkOption); command.Options.Add(AdManifestOnlyOption); + command.Options.Add(InstallingWorkloadCommandParser.WorkloadSetVersionOption); command.AddWorkloadCommandNuGetRestoreActionConfigOptions(); command.Options.Add(CommonOptions.VerbosityOption); command.Options.Add(PrintRollbackOption); diff --git a/src/Cli/dotnet/commands/dotnet-workload/update/xlf/LocalizableStrings.cs.xlf b/src/Cli/dotnet/commands/dotnet-workload/update/xlf/LocalizableStrings.cs.xlf index 0d57937d6b65..0cc940248598 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/update/xlf/LocalizableStrings.cs.xlf +++ b/src/Cli/dotnet/commands/dotnet-workload/update/xlf/LocalizableStrings.cs.xlf @@ -42,6 +42,11 @@ Aktualizace úlohy {0} neproběhla úspěšně z následujícího důvodu: + + Updating to a rollback file is not compatible with workload sets. Install and Update will now use loose manifests. To update to a specific workload version, use --version. + Updating to a rollback file is not compatible with workload sets. Install and Update will now use loose manifests. To update to a specific workload version, use --version. + + Successfully updated workload(s): {0}. Úlohy se úspěšně aktualizovaly: {0}. diff --git a/src/Cli/dotnet/commands/dotnet-workload/update/xlf/LocalizableStrings.de.xlf b/src/Cli/dotnet/commands/dotnet-workload/update/xlf/LocalizableStrings.de.xlf index 7fe3755912f5..eec11ddc74e8 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/update/xlf/LocalizableStrings.de.xlf +++ b/src/Cli/dotnet/commands/dotnet-workload/update/xlf/LocalizableStrings.de.xlf @@ -42,6 +42,11 @@ Fehler beim Update der Workload "{0}". Ursache: + + Updating to a rollback file is not compatible with workload sets. Install and Update will now use loose manifests. To update to a specific workload version, use --version. + Updating to a rollback file is not compatible with workload sets. Install and Update will now use loose manifests. To update to a specific workload version, use --version. + + Successfully updated workload(s): {0}. Workload(s) erfolgreich aktualisiert: {0}. diff --git a/src/Cli/dotnet/commands/dotnet-workload/update/xlf/LocalizableStrings.es.xlf b/src/Cli/dotnet/commands/dotnet-workload/update/xlf/LocalizableStrings.es.xlf index 61eacfcb2be0..5fd3c603769c 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/update/xlf/LocalizableStrings.es.xlf +++ b/src/Cli/dotnet/commands/dotnet-workload/update/xlf/LocalizableStrings.es.xlf @@ -42,6 +42,11 @@ La carga de trabajo "{0}" no se pudo actualizar debido a lo siguiente: + + Updating to a rollback file is not compatible with workload sets. Install and Update will now use loose manifests. To update to a specific workload version, use --version. + Updating to a rollback file is not compatible with workload sets. Install and Update will now use loose manifests. To update to a specific workload version, use --version. + + Successfully updated workload(s): {0}. La(s) carga(s) de trabajo se ha(n) actualizado correctamente: {0} diff --git a/src/Cli/dotnet/commands/dotnet-workload/update/xlf/LocalizableStrings.fr.xlf b/src/Cli/dotnet/commands/dotnet-workload/update/xlf/LocalizableStrings.fr.xlf index ffa504cef235..767a9f67a439 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/update/xlf/LocalizableStrings.fr.xlf +++ b/src/Cli/dotnet/commands/dotnet-workload/update/xlf/LocalizableStrings.fr.xlf @@ -42,6 +42,11 @@ Échec de la mise à jour de la charge de travail '{0}' pour la ou les raisons suivantes : + + Updating to a rollback file is not compatible with workload sets. Install and Update will now use loose manifests. To update to a specific workload version, use --version. + Updating to a rollback file is not compatible with workload sets. Install and Update will now use loose manifests. To update to a specific workload version, use --version. + + Successfully updated workload(s): {0}. Mise à jour réussie du charge de travail : {0}. diff --git a/src/Cli/dotnet/commands/dotnet-workload/update/xlf/LocalizableStrings.it.xlf b/src/Cli/dotnet/commands/dotnet-workload/update/xlf/LocalizableStrings.it.xlf index 0d9403d54fe4..f3d40db0dc9b 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/update/xlf/LocalizableStrings.it.xlf +++ b/src/Cli/dotnet/commands/dotnet-workload/update/xlf/LocalizableStrings.it.xlf @@ -42,6 +42,11 @@ L'aggiornamento del carico di lavoro '{0}' non è riuscito. Motivi: + + Updating to a rollback file is not compatible with workload sets. Install and Update will now use loose manifests. To update to a specific workload version, use --version. + Updating to a rollback file is not compatible with workload sets. Install and Update will now use loose manifests. To update to a specific workload version, use --version. + + Successfully updated workload(s): {0}. I carichi di lavoro sono stati aggiornati: {0}. diff --git a/src/Cli/dotnet/commands/dotnet-workload/update/xlf/LocalizableStrings.ja.xlf b/src/Cli/dotnet/commands/dotnet-workload/update/xlf/LocalizableStrings.ja.xlf index a3555167d604..27a35287eee3 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/update/xlf/LocalizableStrings.ja.xlf +++ b/src/Cli/dotnet/commands/dotnet-workload/update/xlf/LocalizableStrings.ja.xlf @@ -42,6 +42,11 @@ ワークロード '{0}' を更新できませんでした。原因: + + Updating to a rollback file is not compatible with workload sets. Install and Update will now use loose manifests. To update to a specific workload version, use --version. + Updating to a rollback file is not compatible with workload sets. Install and Update will now use loose manifests. To update to a specific workload version, use --version. + + Successfully updated workload(s): {0}. ワークロード {0} が正常に更新されました。 diff --git a/src/Cli/dotnet/commands/dotnet-workload/update/xlf/LocalizableStrings.ko.xlf b/src/Cli/dotnet/commands/dotnet-workload/update/xlf/LocalizableStrings.ko.xlf index 1f9d499812c4..2dcea44b5860 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/update/xlf/LocalizableStrings.ko.xlf +++ b/src/Cli/dotnet/commands/dotnet-workload/update/xlf/LocalizableStrings.ko.xlf @@ -42,6 +42,11 @@ 다음으로 인해 워크로드 '{0}'을(를) 업데이트하지 못했습니다. + + Updating to a rollback file is not compatible with workload sets. Install and Update will now use loose manifests. To update to a specific workload version, use --version. + Updating to a rollback file is not compatible with workload sets. Install and Update will now use loose manifests. To update to a specific workload version, use --version. + + Successfully updated workload(s): {0}. 워크로드를 업데이트했습니다. {0}. diff --git a/src/Cli/dotnet/commands/dotnet-workload/update/xlf/LocalizableStrings.pl.xlf b/src/Cli/dotnet/commands/dotnet-workload/update/xlf/LocalizableStrings.pl.xlf index 222d233a4c10..96c9a3f67371 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/update/xlf/LocalizableStrings.pl.xlf +++ b/src/Cli/dotnet/commands/dotnet-workload/update/xlf/LocalizableStrings.pl.xlf @@ -42,6 +42,11 @@ Aktualizacja obciążenia „{0}” nie powiodła się z następującego powodu: + + Updating to a rollback file is not compatible with workload sets. Install and Update will now use loose manifests. To update to a specific workload version, use --version. + Updating to a rollback file is not compatible with workload sets. Install and Update will now use loose manifests. To update to a specific workload version, use --version. + + Successfully updated workload(s): {0}. Pomyślnie zaktualizowano pakiety robocze: {0}. diff --git a/src/Cli/dotnet/commands/dotnet-workload/update/xlf/LocalizableStrings.pt-BR.xlf b/src/Cli/dotnet/commands/dotnet-workload/update/xlf/LocalizableStrings.pt-BR.xlf index c5db7d56ba3e..235954d94f87 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/update/xlf/LocalizableStrings.pt-BR.xlf +++ b/src/Cli/dotnet/commands/dotnet-workload/update/xlf/LocalizableStrings.pt-BR.xlf @@ -42,6 +42,11 @@ Falha ao atualizar a carga de trabalho '{0}' devido ao seguinte motivo: + + Updating to a rollback file is not compatible with workload sets. Install and Update will now use loose manifests. To update to a specific workload version, use --version. + Updating to a rollback file is not compatible with workload sets. Install and Update will now use loose manifests. To update to a specific workload version, use --version. + + Successfully updated workload(s): {0}. Carga(s) de trabalho atualizada(s) com êxito: {0}. diff --git a/src/Cli/dotnet/commands/dotnet-workload/update/xlf/LocalizableStrings.ru.xlf b/src/Cli/dotnet/commands/dotnet-workload/update/xlf/LocalizableStrings.ru.xlf index f65de634659b..b3b7e621533e 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/update/xlf/LocalizableStrings.ru.xlf +++ b/src/Cli/dotnet/commands/dotnet-workload/update/xlf/LocalizableStrings.ru.xlf @@ -42,6 +42,11 @@ Не удалось обновить рабочую нагрузку "{0}" по следующей причине: + + Updating to a rollback file is not compatible with workload sets. Install and Update will now use loose manifests. To update to a specific workload version, use --version. + Updating to a rollback file is not compatible with workload sets. Install and Update will now use loose manifests. To update to a specific workload version, use --version. + + Successfully updated workload(s): {0}. Рабочие нагрузки успешно обновлены: {0}. diff --git a/src/Cli/dotnet/commands/dotnet-workload/update/xlf/LocalizableStrings.tr.xlf b/src/Cli/dotnet/commands/dotnet-workload/update/xlf/LocalizableStrings.tr.xlf index 6c7f77da9566..670f5d690df9 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/update/xlf/LocalizableStrings.tr.xlf +++ b/src/Cli/dotnet/commands/dotnet-workload/update/xlf/LocalizableStrings.tr.xlf @@ -42,6 +42,11 @@ Aşağıdaki nedenlerle '{0}' iş yükü güncelleştirilemedi: + + Updating to a rollback file is not compatible with workload sets. Install and Update will now use loose manifests. To update to a specific workload version, use --version. + Updating to a rollback file is not compatible with workload sets. Install and Update will now use loose manifests. To update to a specific workload version, use --version. + + Successfully updated workload(s): {0}. İş yükleri başarıyla güncelleştirildi: {0}. diff --git a/src/Cli/dotnet/commands/dotnet-workload/update/xlf/LocalizableStrings.zh-Hans.xlf b/src/Cli/dotnet/commands/dotnet-workload/update/xlf/LocalizableStrings.zh-Hans.xlf index 3c981c1c23c4..3beaaebc1acf 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/update/xlf/LocalizableStrings.zh-Hans.xlf +++ b/src/Cli/dotnet/commands/dotnet-workload/update/xlf/LocalizableStrings.zh-Hans.xlf @@ -42,6 +42,11 @@ 工作负载“{0}”因以下原因而未能更新: + + Updating to a rollback file is not compatible with workload sets. Install and Update will now use loose manifests. To update to a specific workload version, use --version. + Updating to a rollback file is not compatible with workload sets. Install and Update will now use loose manifests. To update to a specific workload version, use --version. + + Successfully updated workload(s): {0}. 已成功更新工作负载: {0}。 diff --git a/src/Cli/dotnet/commands/dotnet-workload/update/xlf/LocalizableStrings.zh-Hant.xlf b/src/Cli/dotnet/commands/dotnet-workload/update/xlf/LocalizableStrings.zh-Hant.xlf index 20dab178f25e..914b6a666c8a 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/update/xlf/LocalizableStrings.zh-Hant.xlf +++ b/src/Cli/dotnet/commands/dotnet-workload/update/xlf/LocalizableStrings.zh-Hant.xlf @@ -42,6 +42,11 @@ 因為下列原因,所以無法更新工作負載 '{0}': + + Updating to a rollback file is not compatible with workload sets. Install and Update will now use loose manifests. To update to a specific workload version, use --version. + Updating to a rollback file is not compatible with workload sets. Install and Update will now use loose manifests. To update to a specific workload version, use --version. + + Successfully updated workload(s): {0}. 已成功更新工作負載: {0}。 diff --git a/src/Microsoft.DotNet.TemplateLocator/Microsoft.DotNet.TemplateLocator.csproj b/src/Microsoft.DotNet.TemplateLocator/Microsoft.DotNet.TemplateLocator.csproj index 20f6d73e1473..84bd3a16954c 100644 --- a/src/Microsoft.DotNet.TemplateLocator/Microsoft.DotNet.TemplateLocator.csproj +++ b/src/Microsoft.DotNet.TemplateLocator/Microsoft.DotNet.TemplateLocator.csproj @@ -51,6 +51,7 @@ + diff --git a/src/Resolvers/Microsoft.DotNet.MSBuildSdkResolver/Microsoft.DotNet.MSBuildSdkResolver.csproj b/src/Resolvers/Microsoft.DotNet.MSBuildSdkResolver/Microsoft.DotNet.MSBuildSdkResolver.csproj index 77a9cf79660b..600d5decb5e7 100644 --- a/src/Resolvers/Microsoft.DotNet.MSBuildSdkResolver/Microsoft.DotNet.MSBuildSdkResolver.csproj +++ b/src/Resolvers/Microsoft.DotNet.MSBuildSdkResolver/Microsoft.DotNet.MSBuildSdkResolver.csproj @@ -72,6 +72,7 @@ + diff --git a/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/IWorkloadManifestProvider.cs b/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/IWorkloadManifestProvider.cs index a3acabf746e2..f6a5e9676624 100644 --- a/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/IWorkloadManifestProvider.cs +++ b/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/IWorkloadManifestProvider.cs @@ -14,6 +14,8 @@ public interface IWorkloadManifestProvider string GetSdkFeatureBand(); + string? GetWorkloadVersion(); + Dictionary GetAvailableWorkloadSets(); } } diff --git a/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/IWorkloadResolver.cs b/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/IWorkloadResolver.cs index 283aaffd387f..05a86f60d3b5 100644 --- a/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/IWorkloadResolver.cs +++ b/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/IWorkloadResolver.cs @@ -19,6 +19,7 @@ public interface IWorkloadResolver string GetManifestVersion(string manifestId); IEnumerable GetInstalledManifests(); string GetSdkFeatureBand(); + string? GetWorkloadVersion(); IEnumerable GetUpdatedWorkloads(WorkloadResolver advertisingManifestResolver, IEnumerable installedWorkloads); WorkloadManifest GetManifestFromWorkload(WorkloadId workloadId); diff --git a/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/Microsoft.NET.Sdk.WorkloadManifestReader.csproj b/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/Microsoft.NET.Sdk.WorkloadManifestReader.csproj index bfeb093643bd..afc2aa64034c 100644 --- a/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/Microsoft.NET.Sdk.WorkloadManifestReader.csproj +++ b/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/Microsoft.NET.Sdk.WorkloadManifestReader.csproj @@ -21,6 +21,7 @@ + diff --git a/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/SdkDirectoryWorkloadManifestProvider.InstallStateReader.cs b/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/SdkDirectoryWorkloadManifestProvider.InstallStateReader.cs deleted file mode 100644 index 7579778f6a46..000000000000 --- a/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/SdkDirectoryWorkloadManifestProvider.InstallStateReader.cs +++ /dev/null @@ -1,104 +0,0 @@ -// Copyright (c) .NET Foundation and contributors. All rights reserved. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. - - -using Microsoft.NET.Sdk.Localization; -using static Microsoft.NET.Sdk.WorkloadManifestReader.WorkloadManifestReader; -using Microsoft.Deployment.DotNet.Releases; - -#if USE_SYSTEM_TEXT_JSON -using System.Text.Json; -#else -using Newtonsoft.Json; -using JsonTokenType = Newtonsoft.Json.JsonToken; -#endif - -namespace Microsoft.NET.Sdk.WorkloadManifestReader -{ - public partial class SdkDirectoryWorkloadManifestProvider - { - public class InstallState - { - public string? WorkloadSetVersion { get; set; } - public WorkloadSet? Manifests { get; set; } - } - - public static class InstallStateReader - { - public static InstallState ReadInstallState(string installStatePath) - { - using var fileStream = File.OpenRead(installStatePath); - -#if USE_SYSTEM_TEXT_JSON - var readerOptions = new JsonReaderOptions - { - AllowTrailingCommas = true, - CommentHandling = JsonCommentHandling.Skip - }; - var reader = new Utf8JsonStreamReader(fileStream, readerOptions); -#else - using var textReader = new StreamReader(fileStream, System.Text.Encoding.UTF8, true); - using var jsonReader = new JsonTextReader(textReader); - - var reader = new Utf8JsonStreamReader(jsonReader); -#endif - - InstallState installState = new(); - - JsonReader.ConsumeToken(ref reader, JsonTokenType.StartObject); - while (reader.Read()) - { - switch (reader.TokenType) - { - case JsonTokenType.PropertyName: - var propName = reader.GetString(); - if (string.Equals("workloadVersion", propName, StringComparison.OrdinalIgnoreCase)) - { - installState.WorkloadSetVersion = JsonReader.ReadString(ref reader); - } - else if (string.Equals("manifests", propName, StringComparison.OrdinalIgnoreCase)) - { - installState.Manifests = ReadManifests(ref reader); - } - else - { - JsonReader.ConsumeValue(ref reader); - } - break; - - case JsonTokenType.EndObject: - return installState; - default: - throw new JsonFormatException(Strings.UnexpectedTokenAtOffset, reader.TokenType, reader.TokenStartIndex); - } - } - - throw new JsonFormatException(Strings.IncompleteDocument); - } - - static WorkloadSet ReadManifests(ref Utf8JsonStreamReader reader) - { - JsonReader.ConsumeToken(ref reader, JsonTokenType.StartObject); - Dictionary workloadSetDict = new(); - - while (reader.Read()) - { - switch (reader.TokenType) - { - case JsonTokenType.PropertyName: - var propName = reader.GetString(); - var propValue = JsonReader.ReadString(ref reader); - workloadSetDict[propName] = propValue; - break; - case JsonTokenType.EndObject: - return WorkloadSet.FromDictionaryForJson(workloadSetDict, new SdkFeatureBand(new ReleaseVersion(0,0,0))); - default: - throw new JsonFormatException(Strings.UnexpectedTokenAtOffset, reader.TokenType, reader.TokenStartIndex); - } - } - throw new JsonFormatException(Strings.IncompleteDocument); - } - } - } -} - diff --git a/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/SdkDirectoryWorkloadManifestProvider.cs b/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/SdkDirectoryWorkloadManifestProvider.cs index 95e51e8a6e6a..eeefd7dee1c7 100644 --- a/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/SdkDirectoryWorkloadManifestProvider.cs +++ b/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/SdkDirectoryWorkloadManifestProvider.cs @@ -1,12 +1,7 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; using System.Security.Cryptography; -using System.Text; using Microsoft.Deployment.DotNet.Releases; using Microsoft.DotNet.Cli; using Microsoft.DotNet.Workloads.Workload; @@ -136,15 +131,15 @@ public void RefreshWorkloadManifests() var installStateFilePath = Path.Combine(WorkloadInstallType.GetInstallStateFolder(_sdkVersionBand, _sdkRootPath), "default.json"); if (File.Exists(installStateFilePath)) { - var installState = InstallStateReader.ReadInstallState(installStateFilePath); - if (!string.IsNullOrEmpty(installState.WorkloadSetVersion)) + var installState = InstallStateContents.FromPath(installStateFilePath); + if (!string.IsNullOrEmpty(installState.WorkloadVersion)) { - if (!availableWorkloadSets.TryGetValue(installState.WorkloadSetVersion!, out _workloadSet)) + if (!availableWorkloadSets.TryGetValue(installState.WorkloadVersion!, out _workloadSet)) { - throw new FileNotFoundException(string.Format(Strings.WorkloadVersionFromInstallStateNotFound, installState.WorkloadSetVersion, installStateFilePath)); + throw new FileNotFoundException(string.Format(Strings.WorkloadVersionFromInstallStateNotFound, installState.WorkloadVersion, installStateFilePath)); } } - _manifestsFromInstallState = installState.Manifests; + _manifestsFromInstallState = installState.Manifests is null ? new WorkloadSet() : WorkloadSet.FromDictionaryForJson(installState.Manifests, _sdkVersionBand); _installStateFilePath = installStateFilePath; } } @@ -157,13 +152,18 @@ public void RefreshWorkloadManifests() } } - public string GetWorkloadVersion() + public string? GetWorkloadVersion() { if (_workloadSet?.Version is not null) { return _workloadSet?.Version!; } + if (InstallStateContents.FromPath(Path.Combine(WorkloadInstallType.GetInstallStateFolder(_sdkVersionBand, _sdkRootPath), "default.json")).UseWorkloadSets == true) + { + return null; + } + using (SHA256 sha256Hash = SHA256.Create()) { byte[] bytes = sha256Hash.ComputeHash(Encoding.UTF8.GetBytes(string.Join(";", diff --git a/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/SdkFeatureBand.cs b/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/SdkFeatureBand.cs index e496e9d757d9..0ce6d4eed582 100644 --- a/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/SdkFeatureBand.cs +++ b/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/SdkFeatureBand.cs @@ -30,6 +30,9 @@ public SdkFeatureBand(ReleaseVersion version) } } + public int Major => _featureBand.Major; + public int Minor => _featureBand.Minor; + public bool Equals(SdkFeatureBand other) { return _featureBand.Equals(other._featureBand); diff --git a/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/TempDirectoryWorkloadManifestProvider.cs b/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/TempDirectoryWorkloadManifestProvider.cs index b45a463771b2..a764fb2d9fb5 100644 --- a/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/TempDirectoryWorkloadManifestProvider.cs +++ b/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/TempDirectoryWorkloadManifestProvider.cs @@ -54,6 +54,7 @@ public IEnumerable GetManifestDirectories() } public string GetSdkFeatureBand() => _sdkVersionBand; + public string? GetWorkloadVersion() => _sdkVersionBand.ToString() + ".2"; public Dictionary GetAvailableWorkloadSets() => new(); } } diff --git a/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/WorkloadResolver.cs b/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/WorkloadResolver.cs index 040a0f7a1495..81fdae3f4c2d 100644 --- a/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/WorkloadResolver.cs +++ b/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/WorkloadResolver.cs @@ -109,6 +109,8 @@ public void RefreshWorkloadManifests() ComposeWorkloadManifests(); } + public string? GetWorkloadVersion() => _manifestProvider.GetWorkloadVersion(); + private void LoadManifestsFromProvider(IWorkloadManifestProvider manifestProvider) { foreach (var readableManifest in manifestProvider.GetManifests()) @@ -741,6 +743,7 @@ public void RefreshWorkloadManifests() { } public Dictionary GetAvailableWorkloadSets() => new(); public IEnumerable GetManifests() => Enumerable.Empty(); public string GetSdkFeatureBand() => _sdkFeatureBand; + public string? GetWorkloadVersion() => _sdkFeatureBand.ToString() + ".2"; } } diff --git a/src/Tasks/Microsoft.NET.Build.Tasks/Microsoft.NET.Build.Tasks.csproj b/src/Tasks/Microsoft.NET.Build.Tasks/Microsoft.NET.Build.Tasks.csproj index 1c16e13b948b..e1e67af18320 100644 --- a/src/Tasks/Microsoft.NET.Build.Tasks/Microsoft.NET.Build.Tasks.csproj +++ b/src/Tasks/Microsoft.NET.Build.Tasks/Microsoft.NET.Build.Tasks.csproj @@ -90,6 +90,7 @@ + diff --git a/src/Tests/Microsoft.NET.Sdk.WorkloadManifestReader.Tests/FakeManifestProvider.cs b/src/Tests/Microsoft.NET.Sdk.WorkloadManifestReader.Tests/FakeManifestProvider.cs index 92ddb64a0829..7c8fa003a368 100644 --- a/src/Tests/Microsoft.NET.Sdk.WorkloadManifestReader.Tests/FakeManifestProvider.cs +++ b/src/Tests/Microsoft.NET.Sdk.WorkloadManifestReader.Tests/FakeManifestProvider.cs @@ -40,6 +40,7 @@ public IEnumerable GetManifests() public string GetSdkFeatureBand() => "8.0.100"; public Dictionary GetAvailableWorkloadSets() => throw new NotImplementedException(); + public string? GetWorkloadVersion() => "8.0.100.2"; } internal class InMemoryFakeManifestProvider : IWorkloadManifestProvider, IEnumerable<(string id, string content)> @@ -66,5 +67,6 @@ public IEnumerable GetManifests() IEnumerator IEnumerable.GetEnumerator() => throw new NotImplementedException(); public string GetSdkFeatureBand() => "8.0.100"; public Dictionary GetAvailableWorkloadSets() => throw new NotImplementedException(); + public string? GetWorkloadVersion() => "8.0.100.2"; } } diff --git a/src/Tests/Microsoft.NET.Sdk.WorkloadManifestReader.Tests/SdkDirectoryWorkloadManifestProviderTests.cs b/src/Tests/Microsoft.NET.Sdk.WorkloadManifestReader.Tests/SdkDirectoryWorkloadManifestProviderTests.cs index 13a4f6d3570b..44bf3f961184 100644 --- a/src/Tests/Microsoft.NET.Sdk.WorkloadManifestReader.Tests/SdkDirectoryWorkloadManifestProviderTests.cs +++ b/src/Tests/Microsoft.NET.Sdk.WorkloadManifestReader.Tests/SdkDirectoryWorkloadManifestProviderTests.cs @@ -48,7 +48,7 @@ public void ItShouldReturnTheWorkloadVersion(bool useWorkloadSet) { ""ios"": ""11.0.2/8.0.100"", ""android"": ""33.0.2-rc.1/8.0.200"", - ""maui"": ""15.0.1-rc.456/8.0.200-rc.2"", + ""maui"": ""15.0.1-rc.456/8.0.200-rc.2"" } "); } @@ -494,7 +494,7 @@ public void ItUsesWorkloadSetFromGlobalJson() { "sdk": { "version": "8.0.200", - "workloadversion": "8.0.201" + "workloadVersion": "8.0.201" }, "msbuild-sdks": { "Microsoft.DotNet.Arcade.Sdk": "7.0.0-beta.23254.2", @@ -536,7 +536,7 @@ public void ItFailsIfWorkloadSetFromGlobalJsonIsNotInstalled() { "sdk": { "version": "8.0.200", - "workloadversion": "8.0.201" + "workloadVersion": "8.0.201" }, "msbuild-sdks": { "Microsoft.DotNet.Arcade.Sdk": "7.0.0-beta.23254.2", @@ -565,7 +565,7 @@ public void ItFailsIfGlobalJsonIsMalformed() File.WriteAllText(globalJsonPath, """ { "sdk": { - "workloadversion": [ "8.0.202" ] + "workloadVersion": [ "8.0.202" ] } } """); @@ -862,7 +862,7 @@ public void ItFallsBackForManifestNotInInstallState() """ { "manifests": { - "ios": "12.0.1/8.0.200", + "ios": "12.0.1/8.0.200" } } """); @@ -885,7 +885,7 @@ public void GlobalJsonOverridesInstallState() { "sdk": { "version": "8.0.200", - "workloadversion": "8.0.201" + "workloadVersion": "8.0.201" }, "msbuild-sdks": { "Microsoft.DotNet.Arcade.Sdk": "7.0.0-beta.23254.2", diff --git a/src/Tests/dotnet-workload-install.Tests/GivenWorkloadManifestUpdater.cs b/src/Tests/dotnet-workload-install.Tests/GivenWorkloadManifestUpdater.cs index 029d28fd9ee6..1a12d4ccb8b9 100644 --- a/src/Tests/dotnet-workload-install.Tests/GivenWorkloadManifestUpdater.cs +++ b/src/Tests/dotnet-workload-install.Tests/GivenWorkloadManifestUpdater.cs @@ -558,7 +558,7 @@ public void GivenWorkloadManifestUpdateItChoosesHighestManifestVersionInCache() var installationRepo = new MockInstallationRecordRepository(); var installer = new MockPackWorkloadInstaller(dotnetRoot); var manifestUpdater = new WorkloadManifestUpdater(_reporter, workloadResolver, nugetDownloader, testDir, installationRepo, installer); - manifestUpdater.UpdateAdvertisingManifestsAsync(false, new DirectoryPath(offlineCache)).Wait(); + manifestUpdater.UpdateAdvertisingManifestsAsync(false, false, new DirectoryPath(offlineCache)).Wait(); // We should have chosen the higher version manifest package to install/ extract installer.ExtractCallParams.Count().Should().Be(1); diff --git a/src/Tests/dotnet-workload-install.Tests/MockManifestProvider.cs b/src/Tests/dotnet-workload-install.Tests/MockManifestProvider.cs index f3298b0d654b..935fb9addfe8 100644 --- a/src/Tests/dotnet-workload-install.Tests/MockManifestProvider.cs +++ b/src/Tests/dotnet-workload-install.Tests/MockManifestProvider.cs @@ -48,5 +48,6 @@ public IEnumerable GetManifests() } public string GetSdkFeatureBand() => SdkFeatureBand.ToString(); + public string GetWorkloadVersion() => SdkFeatureBand.ToString() + ".2"; } } diff --git a/src/Tests/dotnet-workload-install.Tests/MockPackWorkloadInstaller.cs b/src/Tests/dotnet-workload-install.Tests/MockPackWorkloadInstaller.cs index 37a204706607..fb4b3924dea5 100644 --- a/src/Tests/dotnet-workload-install.Tests/MockPackWorkloadInstaller.cs +++ b/src/Tests/dotnet-workload-install.Tests/MockPackWorkloadInstaller.cs @@ -8,6 +8,7 @@ using Microsoft.NET.Sdk.WorkloadManifestReader; using Microsoft.DotNet.ToolPackage; using Microsoft.DotNet.Workloads.Workload; +using Microsoft.DotNet.Cli.Utils; namespace Microsoft.DotNet.Cli.Workload.Install.Tests { @@ -24,13 +25,14 @@ internal class MockPackWorkloadInstaller : IInstaller public bool FailingGarbageCollection; private readonly string FailingPack; private readonly string _dotnetDir; + private string workloadSetContents; public IWorkloadResolver WorkloadResolver { get; set; } public int ExitCode => 0; public MockPackWorkloadInstaller(string dotnetDir, string failingWorkload = null, string failingPack = null, bool failingRollback = false, IList installedWorkloads = null, - IList installedPacks = null, bool failingGarbageCollection = false) + IList installedPacks = null, bool failingGarbageCollection = false, string workloadSetContents = "") { InstallationRecordRepository = new MockInstallationRecordRepository(failingWorkload, installedWorkloads); FailingRollback = failingRollback; @@ -38,6 +40,7 @@ public MockPackWorkloadInstaller(string dotnetDir, string failingWorkload = null FailingPack = failingPack; FailingGarbageCollection = failingGarbageCollection; _dotnetDir = dotnetDir; + this.workloadSetContents = workloadSetContents; } IEnumerable GetPacksForWorkloads(IEnumerable workloadIds) @@ -61,6 +64,17 @@ public void UpdateInstallMode(SdkFeatureBand sdkFeatureBand, bool newMode) throw new NotImplementedException(); } + public void AdjustWorkloadSetInInstallState(SdkFeatureBand sdkFeatureBand, string workloadVersion) + { + var installStatePath = Path.Combine(Path.GetTempPath(), "dotnetTestPath", "metadata", "workloads", sdkFeatureBand.ToString(), "InstallState", "default.json"); + var contents = InstallStateContents.FromPath(installStatePath); + contents.WorkloadVersion = workloadVersion; + if (File.Exists(installStatePath)) + { + File.WriteAllText(installStatePath, contents.ToString()); + } + } + public void InstallWorkloads(IEnumerable workloadIds, SdkFeatureBand sdkFeatureBand, ITransactionContext transactionContext, DirectoryPath? offlineCache = null) { List packs = new List(); @@ -91,6 +105,14 @@ public void InstallWorkloads(IEnumerable workloadIds, SdkFeatureBand }); } + public string InstallWorkloadSet(ITransactionContext context, string advertisingPackagePath) + { + var version = Path.GetFileName(Path.GetDirectoryName(advertisingPackagePath ?? string.Empty)); + Directory.CreateDirectory(advertisingPackagePath); + File.WriteAllText(Path.Combine(advertisingPackagePath, Constants.workloadSetVersionFileName), version); + return Path.GetDirectoryName(advertisingPackagePath ?? string.Empty); + } + public void RepairWorkloads(IEnumerable workloadIds, SdkFeatureBand sdkFeatureBand, DirectoryPath? offlineCache = null) => throw new NotImplementedException(); public void GarbageCollect(Func getResolverForWorkloadSet, DirectoryPath? offlineCache = null, bool cleanAllPacks = false) diff --git a/src/Tests/dotnet-workload-install.Tests/MockWorkloadManifestUpdater.cs b/src/Tests/dotnet-workload-install.Tests/MockWorkloadManifestUpdater.cs index 6a3d90073c64..3b7a0275a2e6 100644 --- a/src/Tests/dotnet-workload-install.Tests/MockWorkloadManifestUpdater.cs +++ b/src/Tests/dotnet-workload-install.Tests/MockWorkloadManifestUpdater.cs @@ -13,13 +13,15 @@ internal class MockWorkloadManifestUpdater : IWorkloadManifestUpdater public int CalculateManifestUpdatesCallCount = 0; public int GetManifestPackageDownloadsCallCount = 0; private readonly IEnumerable _manifestUpdates; + private bool _fromWorkloadSet; - public MockWorkloadManifestUpdater(IEnumerable manifestUpdates = null) + public MockWorkloadManifestUpdater(IEnumerable manifestUpdates = null, bool fromWorkloadSet = false) { _manifestUpdates = manifestUpdates ?? new List(); + _fromWorkloadSet = fromWorkloadSet; } - public Task UpdateAdvertisingManifestsAsync(bool includePreview, DirectoryPath? cachePath = null) + public Task UpdateAdvertisingManifestsAsync(bool includePreview, bool useWorkloadSets = false, DirectoryPath? cachePath = null) { UpdateAdvertisingManifestsCallCount++; return Task.CompletedTask; @@ -42,11 +44,19 @@ public Task> GetManifestPackageDownloadsAsync(bool public IEnumerable CalculateManifestRollbacks(string rollbackDefinitionFilePath) { + if (_fromWorkloadSet && !rollbackDefinitionFilePath.EndsWith("installed.workloadset.json")) + { + throw new Exception("Should be updating or installing via workload set."); + } + return _manifestUpdates.Select(t => t.ManifestUpdate); } public Task BackgroundUpdateAdvertisingManifestsWhenRequiredAsync() => throw new NotImplementedException(); public IEnumerable GetUpdatableWorkloadsToAdvertise(IEnumerable installedWorkloads) => throw new NotImplementedException(); public void DeleteUpdatableWorkloadsFile() { } + + public void DownloadWorkloadSet(string version, DirectoryPath? offlineCache) => throw new NotImplementedException(); + public IEnumerable ParseRollbackDefinitionFiles(IEnumerable files) => _manifestUpdates.Select(t => t.ManifestUpdate); } } diff --git a/src/Tests/dotnet-workload-install.Tests/WorkloadGarbageCollectionTests.cs b/src/Tests/dotnet-workload-install.Tests/WorkloadGarbageCollectionTests.cs index 7946e7e3ce5a..0cd4e2a2fe21 100644 --- a/src/Tests/dotnet-workload-install.Tests/WorkloadGarbageCollectionTests.cs +++ b/src/Tests/dotnet-workload-install.Tests/WorkloadGarbageCollectionTests.cs @@ -200,7 +200,7 @@ public void GarbageCollectManifestsWithInstallState() """ { "manifests": { - "testmanifest": "2.0.0/6.0.300", + "testmanifest": "2.0.0/6.0.300" } } """); diff --git a/src/Tests/dotnet-workload-search.Tests/MockWorkloadResolver.cs b/src/Tests/dotnet-workload-search.Tests/MockWorkloadResolver.cs index 0a769ee235ea..5a9bdd9cb706 100644 --- a/src/Tests/dotnet-workload-search.Tests/MockWorkloadResolver.cs +++ b/src/Tests/dotnet-workload-search.Tests/MockWorkloadResolver.cs @@ -17,17 +17,18 @@ public MockWorkloadResolver(IEnumerable available public IEnumerable GetAvailableWorkloads() => _availableWorkloads; public IEnumerable GetInstalledWorkloadPacksOfKind(WorkloadPackKind kind) => throw new NotImplementedException(); - public IEnumerable GetPacksInWorkload(WorkloadId workloadId) => throw new NotImplementedException(); + public IEnumerable GetPacksInWorkload(WorkloadId workloadId) => Array.Empty(); public IEnumerable GetExtendedWorkloads(IEnumerable workloadIds) => throw new NotImplementedException(); public ISet GetWorkloadSuggestionForMissingPacks(IList packId, out ISet unsatisfiablePacks) => throw new NotImplementedException(); - public void RefreshWorkloadManifests() => throw new NotImplementedException(); + public void RefreshWorkloadManifests() { } public WorkloadResolver.PackInfo TryGetPackInfo(WorkloadPackId packId) => throw new NotImplementedException(); public bool IsPlatformIncompatibleWorkload(WorkloadId workloadId) => throw new NotImplementedException(); public string GetManifestVersion(string manifestId) => throw new NotImplementedException(); public IEnumerable GetInstalledManifests() => throw new NotImplementedException(); public IWorkloadResolver CreateOverlayResolver(IWorkloadManifestProvider overlayManifestProvider) => throw new NotImplementedException(); public string GetSdkFeatureBand() => "12.0.400"; + public string GetWorkloadVersion() => "12.0.400.2"; public IEnumerable GetUpdatedWorkloads(WorkloadResolver advertisingManifestResolver, IEnumerable installedWorkloads) => throw new NotImplementedException(); WorkloadResolver IWorkloadResolver.CreateOverlayResolver(IWorkloadManifestProvider overlayManifestProvider) => throw new NotImplementedException(); WorkloadManifest IWorkloadResolver.GetManifestFromWorkload(WorkloadId workloadId) => throw new NotImplementedException(); diff --git a/src/Tests/dotnet-workload-update.Tests/GivenDotnetWorkloadUpdate.cs b/src/Tests/dotnet-workload-update.Tests/GivenDotnetWorkloadUpdate.cs index 896569702333..ef980e0ba4d4 100644 --- a/src/Tests/dotnet-workload-update.Tests/GivenDotnetWorkloadUpdate.cs +++ b/src/Tests/dotnet-workload-update.Tests/GivenDotnetWorkloadUpdate.cs @@ -13,6 +13,7 @@ using Microsoft.DotNet.Cli.Utils; using static Microsoft.NET.Sdk.WorkloadManifestReader.WorkloadResolver; using System.Text.Json; +using Microsoft.DotNet.Cli.Workload.Search.Tests; namespace Microsoft.DotNet.Cli.Workload.Update.Tests { @@ -190,6 +191,64 @@ public void GivenWorkloadUpdateItUpdatesOutOfDatePacks() installer.InstalledPacks.Where(pack => pack.Id.ToString().Contains("Android")).Count().Should().Be(8); } + [Theory] + [InlineData(true)] + [InlineData(false)] + public void UpdateViaWorkloadSet(bool upgrade) + { + var versionNumber = "8.0.0"; + var workloadSetContents = @" +{ +""android"": ""2.3.4/8.0.200"" +} +"; + var nugetPackageDownloader = new MockNuGetPackageDownloader(); + var workloadResolver = new MockWorkloadResolver(new WorkloadInfo[] { new WorkloadInfo(new WorkloadId("android"), string.Empty) }); + var workloadInstaller = new MockPackWorkloadInstaller( + Path.Combine(Path.GetTempPath(), "dotnetTestPat", "userProfileDir"), + installedWorkloads: new List() { new WorkloadId("android")}, + workloadSetContents: workloadSetContents) + { + WorkloadResolver = workloadResolver + }; + var oldVersion = upgrade ? "2.3.2" : "2.3.6"; + var workloadManifestUpdater = new MockWorkloadManifestUpdater( + manifestUpdates: new ManifestUpdateWithWorkloads[] { + new ManifestUpdateWithWorkloads(new ManifestVersionUpdate(new ManifestId("android"), new ManifestVersion(oldVersion), "8.0.200", new ManifestVersion("2.3.4"), "8.0.200"), Enumerable.Empty>().ToDictionary()) + }, + fromWorkloadSet: true); + var resolverFactory = new MockWorkloadResolverFactory(Path.Combine(Path.GetTempPath(), "dotnetTestPath"), versionNumber, workloadResolver, "userProfileDir"); + var updateCommand = new WorkloadUpdateCommand(Parser.Instance.Parse("dotnet workload update"), Reporter.Output, resolverFactory, workloadInstaller, nugetPackageDownloader, workloadManifestUpdater); + + var installStatePath = Path.Combine(Path.GetTempPath(), "dotnetTestPath", "metadata", "workloads", versionNumber, "InstallState", "default.json"); + var contents = new InstallStateContents(); + contents.UseWorkloadSets = true; + var versionFile = Path.Combine("userProfileDir", "sdk-advertising", "8.0.0", "microsoft.net.workloads", Constants.workloadSetVersionFileName); + try + { + Directory.CreateDirectory(Path.GetDirectoryName(installStatePath)); + File.WriteAllText(installStatePath, contents.ToString()); + updateCommand.Execute(); + File.Exists(versionFile).Should().BeTrue(); + File.ReadAllText(versionFile).Should().Be("8.0.0"); + } + finally + { + if (File.Exists(versionFile)) + { + File.Delete(versionFile); + } + + if (File.Exists(installStatePath)) + { + File.Delete(installStatePath); + } + } + + workloadInstaller.InstalledManifests.Count.Should().Be(1); + workloadInstaller.InstalledManifests[0].manifestUpdate.NewVersion.ToString().Should().Be("2.3.4"); + } + [Fact] public void GivenWorkloadUpdateItRollsBackOnFailedUpdate() { @@ -332,7 +391,7 @@ public void ApplyRollbackAcrossFeatureBand(string existingSdkFeatureBand, string }; (var dotnetPath, var updateCommand, var packInstaller, _, _, _) = GetTestInstallers(parseResult, manifestUpdates: manifestsToUpdate, sdkVersion: "6.0.300", identifier: existingSdkFeatureBand + newSdkFeatureBand, installedFeatureBand: existingSdkFeatureBand); - updateCommand.UpdateWorkloads(); + updateCommand.CalculateManifestUpdatesAndUpdateWorkloads(); packInstaller.InstalledManifests[0].manifestUpdate.ManifestId.Should().Be(manifestsToUpdate[0].ManifestUpdate.ManifestId); packInstaller.InstalledManifests[0].manifestUpdate.NewVersion.Should().Be(manifestsToUpdate[0].ManifestUpdate.NewVersion); @@ -362,7 +421,7 @@ public void ApplyRollbackWithMultipleManifestsAcrossFeatureBand() }; (_, var updateCommand, var packInstaller, _, _, _) = GetTestInstallers(parseResult, manifestUpdates: manifestsToUpdate, sdkVersion: "6.0.300", installedFeatureBand: "6.0.300"); - updateCommand.UpdateWorkloads(); + updateCommand.CalculateManifestUpdatesAndUpdateWorkloads(); packInstaller.InstalledManifests[0].manifestUpdate.ManifestId.Should().Be(manifestsToUpdate[0].ManifestUpdate.ManifestId); packInstaller.InstalledManifests[0].manifestUpdate.NewVersion.Should().Be(manifestsToUpdate[0].ManifestUpdate.NewVersion); From 97b05148e34ee384de9d35fc8fcc889f9c7eae36 Mon Sep 17 00:00:00 2001 From: Daniel Plaisted Date: Tue, 12 Dec 2023 10:23:46 -0500 Subject: [PATCH 382/577] Add MSI installer tests --- .../MsiInstallerTests.cs | 343 ++++++++++++++++++ 1 file changed, 343 insertions(+) create mode 100644 src/Tests/dotnet-workload-install.Tests/MsiInstallerTests.cs diff --git a/src/Tests/dotnet-workload-install.Tests/MsiInstallerTests.cs b/src/Tests/dotnet-workload-install.Tests/MsiInstallerTests.cs new file mode 100644 index 000000000000..37540e2e64e3 --- /dev/null +++ b/src/Tests/dotnet-workload-install.Tests/MsiInstallerTests.cs @@ -0,0 +1,343 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.Runtime.CompilerServices; +using ManifestReaderTests; +using Microsoft.DotNet.Cli.NuGetPackageDownloader; +using Microsoft.DotNet.ToolPackage; +using Microsoft.DotNet.Workloads.Workload.Install; +using Microsoft.NET.Sdk.WorkloadManifestReader; +using NuGet.Versioning; +using static Microsoft.NET.Sdk.WorkloadManifestReader.WorkloadResolver; +using Microsoft.Extensions.EnvironmentAbstractions; +using System.Text.Json; +using Microsoft.TemplateEngine.Edge.Constraints; +using Microsoft.DotNet.Cli.Utils; + +namespace Microsoft.DotNet.Cli.Workload.Install.Tests +{ + public class MsiInstallerTests : SdkTest + { + // Remote execution notes: + // psexec / uses Admin share (C$) + // ddrits / cloudtest + // sysinternals: filemon / regmon + // How to apply snapshot via C#: https://stackoverflow.com/questions/60173096/hyperv-wmi-apply-snapshot-in-c-sharp + // Also see https://stackoverflow.com/questions/1735978/manipulate-hyper-v-from-net + + + // Reminder: Enable "Remote Service Management" firewall rule so that PSExec will run more quickly + + const string TargetMachineName = "dsp-vm"; + const string PsExecPath = @"C:\Users\Daniel\Downloads\PSTools\PsExec.exe"; + const string SdkInstallerVersion = "8.0.100"; + const string SdkInstallerFileName = $"dotnet-sdk-{SdkInstallerVersion}-win-x64.exe"; + + const string RollbackRC1 = """ + { + "microsoft.net.sdk.android": "34.0.0-rc.1.432/8.0.100-rc.1", + "microsoft.net.sdk.ios": "16.4.8825-net8-rc1/8.0.100-rc.1", + "microsoft.net.sdk.maccatalyst": "16.4.8825-net8-rc1/8.0.100-rc.1", + "microsoft.net.sdk.macos": "13.3.8825-net8-rc1/8.0.100-rc.1", + "microsoft.net.sdk.maui": "8.0.0-rc.1.9171/8.0.100-rc.1", + "microsoft.net.sdk.tvos": "16.4.8825-net8-rc1/8.0.100-rc.1", + "microsoft.net.workload.mono.toolchain.current": "8.0.0-rc.1.23419.4/8.0.100-rc.1", + "microsoft.net.workload.emscripten.current": "8.0.0-rc.1.23415.5/8.0.100-rc.1", + "microsoft.net.workload.emscripten.net6": "8.0.0-rc.1.23415.5/8.0.100-rc.1", + "microsoft.net.workload.emscripten.net7": "8.0.0-rc.1.23415.5/8.0.100-rc.1", + "microsoft.net.workload.mono.toolchain.net6": "8.0.0-rc.1.23419.4/8.0.100-rc.1", + "microsoft.net.workload.mono.toolchain.net7": "8.0.0-rc.1.23419.4/8.0.100-rc.1" + } + """; + + const string Rollback8_0_101 = """ + { + "microsoft.net.sdk.android": "34.0.52/8.0.100", + "microsoft.net.sdk.ios": "17.2.8004/8.0.100", + "microsoft.net.sdk.maccatalyst": "17.2.8004/8.0.100", + "microsoft.net.sdk.macos": "14.2.8004/8.0.100", + "microsoft.net.sdk.maui": "8.0.3/8.0.100", + "microsoft.net.sdk.tvos": "17.2.8004/8.0.100", + "microsoft.net.workload.mono.toolchain.current": "8.0.1/8.0.100", + "microsoft.net.workload.emscripten.current": "8.0.1/8.0.100", + "microsoft.net.workload.emscripten.net6": "8.0.1/8.0.100", + "microsoft.net.workload.emscripten.net7": "8.0.1/8.0.100", + "microsoft.net.workload.mono.toolchain.net6": "8.0.1/8.0.100", + "microsoft.net.workload.mono.toolchain.net7": "8.0.1/8.0.100", + "microsoft.net.sdk.aspire": "8.0.0-preview.2.23619.3/8.0.100" + } + """; + + + public MsiInstallerTests(ITestOutputHelper log) : base(log) + { + + } + + [Fact] + public void UninstallSdk() + { + RunRemoteCommand($@"c:\SdkTesting\{SdkInstallerFileName}", "/quiet", "/uninstall"); + } + + [Fact] + public void SdkInstallation() + { + RunRemoteCommand("dotnet", "--version") + .Should() + .HaveStdOut("7.0.401"); + + RunRemoteCommand($@"c:\SdkTesting\{SdkInstallerFileName}", "/quiet"); + + new DirectoryInfo($@"\\{TargetMachineName}\c$\Program Files\dotnet\sdk\{SdkInstallerVersion}") + .Should() + .Exist(); + + RunRemoteCommand("dotnet", "--version") + .Should() + .HaveStdOut(SdkInstallerVersion); + + RunRemoteCommand($@"c:\SdkTesting\{SdkInstallerFileName}", "/quiet", "/uninstall"); + + new DirectoryInfo($@"\\{TargetMachineName}\c$\Program Files\dotnet\sdk\{SdkInstallerVersion}") + .Should() + .NotExist(); + + RunRemoteCommand("dotnet", "--version") + .Should() + .HaveStdOut("7.0.401"); + + } + + [Fact] + public void WorkloadInstallation() + { + //CleanupInstallState(); + + //RunRemoteCommand($@"c:\SdkTesting\{SdkInstallerFileName}", "/quiet"); + + //DeployStage2Sdk(); + + var rollbackResult = RunRemoteCommand("dotnet", "workload", "update", "--print-rollback"); + rollbackResult.Should().Pass(); + var originalManifests = ParseRollbackOutput(rollbackResult.StdOut); + + + RunRemoteCommand("dotnet", "workload", "install", "wasm-tools", "--skip-manifest-update"); + + RunRemoteCommand("dotnet", "workload", "list", "--machine-readable") + .Should() + .HaveStdOutContaining("wasm-tools"); + + CheckForDuplicateManifests(); + + File.WriteAllText($@"\\{TargetMachineName}\c$\SdkTesting\rollback-rc1.json", RollbackRC1); + + RunRemoteCommand("dotnet", "workload", "update", "--from-rollback-file", @"c:\SdkTesting\rollback-rc1.json", "--skip-sign-check"); + + File.WriteAllText($@"\\{TargetMachineName}\c$\SdkTesting\rollback-8.0.101.json", Rollback8_0_101); + + RunRemoteCommand("dotnet", "workload", "update", "--from-rollback-file", @"c:\SdkTesting\rollback-8.0.101.json", "--skip-sign-check"); + + HashSet<(string id, string version, string featureBand)> expectedManifests = new(); + foreach (var kvp in originalManifests.ManifestVersions.Concat(WorkloadSet.FromJson(Rollback8_0_101, new SdkFeatureBand(SdkInstallerVersion)).ManifestVersions)) + { + expectedManifests.Add((kvp.Key.ToString(), kvp.Value.Version.ToString(), kvp.Value.FeatureBand.ToString())); + } + + var unexpectedManifests = GetInstalledManifestVersions() + .SelectMany(kvp => kvp.Value.Select(v => (id: kvp.Key, version: v.version, featureBand: v.sdkFeatureBand))) + .Except(expectedManifests); + + if (unexpectedManifests.Any()) + { + Assert.Fail($"Unexpected manifests installed: {string.Join(", ", unexpectedManifests)}"); + } + + //CheckForDuplicateManifests(); + + //RunRemoteCommand($@"c:\SdkTesting\{SdkInstallerFileName}", "/quiet", "/uninstall"); + } + + [Fact] + public void InstallStateShouldBeRemovedOnSdkUninstall() + { + // This is currently broken, needs to be added to the finalizer + throw new NotImplementedException(); + } + + [Fact] + public void RepeatedUpdateToSameRollbackFile() + { + // Should not install or uninstall anything + } + + void CleanupInstallState() + { + var featureBand = new SdkFeatureBand(SdkInstallerVersion); + string installStatePath = $@"\\{TargetMachineName}\c$\ProgramData\dotnet\workloads\{featureBand}\InstallState\default.json"; + if (File.Exists(installStatePath)) + { + File.Delete(installStatePath); + } + } + + void CheckForDuplicateManifests() + { + var installedManifestVersions = GetInstalledManifestVersions(); + + foreach (var (manifestId, installedVersions) in installedManifestVersions) + { + if (installedVersions.Count > 1) + { + Assert.Fail($"Found multiple manifest versions for {manifestId}: {string.Join(", ", installedVersions)}"); + } + //installedVersions.Count.Should().Be(1, $"Only one version of manifest {manifestId} should be installed"); + } + } + + Dictionary> GetInstalledManifestVersions() + { + Dictionary> installedManifestVersions = new(); + + foreach (var manifestFeatureBandPath in Directory.GetDirectories($@"\\{TargetMachineName}\c$\Program Files\dotnet\sdk-manifests")) + { + var manifestFeatureBand = Path.GetFileName(manifestFeatureBandPath); + if (manifestFeatureBand.Equals("7.0.100")) + { + // Skip manifests from SDK pre-installed with VS on dev image + continue; + } + + foreach (var manifestIdPath in Directory.GetDirectories(manifestFeatureBandPath)) + { + var manifestId = Path.GetFileName(manifestIdPath); + new FileInfo(Path.Combine(manifestIdPath, "WorkloadManifest.json")) + .Should().NotExist("Not expecting non side-by-side workload manifests"); + + foreach (var manifestVersionPath in Directory.GetDirectories(manifestIdPath)) + { + new FileInfo(Path.Combine(manifestVersionPath, "WorkloadManifest.json")) + .Should().Exist("Workload manifest should exist"); + + var manifestVersion = Path.GetFileName(manifestVersionPath); + if (!installedManifestVersions.TryGetValue(manifestId, out var installedVersions)) + { + installedVersions = new(); + installedManifestVersions[manifestId] = installedVersions; + } + installedVersions.Add((manifestVersion, manifestFeatureBand)); + } + } + } + + return installedManifestVersions; + } + + [Fact] + void TempTest() + { + //CleanupInstallState(); + //RunRemoteCommand("dotnet", "--version") + // .Should() + // .HaveStdOut("7.0.401"); + + //RunRemoteCommand($@"c:\SdkTesting\{SdkInstallerFileName}", "/quiet"); + //DeployStage2Sdk(); + CleanupInstallState(); + RunRemoteCommand($@"c:\SdkTesting\{SdkInstallerFileName}", "/quiet", "/uninstall"); + } + + void DeployStage2Sdk() + { + Log.WriteLine(TestContext.Current.ToolsetUnderTest.SdkFolderUnderTest); + + + var existingSdkFolder = $@"\\dsp-vm\c$\Program Files\dotnet\sdk\{SdkInstallerVersion}"; + //var targetSdkFolder = $@"\\dsp-vm\c$\Program Files\dotnet\sdk\{TestContext.Current.ToolsetUnderTest.SdkVersion}"; + var targetSdkFolder = existingSdkFolder; + var backupSdkFolder = $@"\\dsp-vm\c$\SdkTesting\backup\{SdkInstallerVersion}"; + + var existingVersionFileContents = File.ReadAllLines(Path.Combine(existingSdkFolder, ".version")); + + if (!Directory.Exists(backupSdkFolder)) + { + Directory.CreateDirectory(Path.GetDirectoryName(backupSdkFolder)); + Directory.Move(existingSdkFolder, backupSdkFolder); + } + else if (Directory.Exists(targetSdkFolder)) + { + Directory.Delete(targetSdkFolder, true); + } + + CopyDirectory(TestContext.Current.ToolsetUnderTest.SdkFolderUnderTest, targetSdkFolder); + + var newVersionFileContents = File.ReadAllLines(Path.Combine(targetSdkFolder, ".version")); + // Change feature band for deployed SDK to match MSI installation version + newVersionFileContents[1] = existingVersionFileContents[1]; + File.WriteAllLines(Path.Combine(targetSdkFolder, ".version"), newVersionFileContents); + } + + WorkloadSet ParseRollbackOutput(string output) + { + var filteredOutput = string.Join(Environment.NewLine, + output.Split(Environment.NewLine) + .Except(["==workloadRollbackDefinitionJsonOutputStart==", "==workloadRollbackDefinitionJsonOutputEnd=="])); + + return WorkloadSet.FromJson(filteredOutput, defaultFeatureBand: new SdkFeatureBand(SdkInstallerVersion)); + } + + + private static void CopyDirectory(string sourcePath, string destPath) + { + if (!Directory.Exists(destPath)) + { + Directory.CreateDirectory(destPath); + } + + foreach (var dir in Directory.GetDirectories(sourcePath)) + { + CopyDirectory(dir, Path.Combine(destPath, Path.GetFileName(dir))); + } + + foreach (var file in Directory.GetFiles(sourcePath)) + { + new FileInfo(file).CopyTo(Path.Combine(destPath, Path.GetFileName(file)), true); + } + } + + + CommandResult RunRemoteCommand(params string[] args) + { + var result = new RemoteCommand(Log, args).Execute(); + + result.Should().Pass(); + + return result; + } + + class RemoteCommand : TestCommand + { + + + public RemoteCommand(ITestOutputHelper log, params string[] args) + : base(log) + { + Arguments.Add("-nobanner"); + Arguments.Add($@"\\{TargetMachineName}"); + Arguments.AddRange(args); + } + + protected override SdkCommandSpec CreateCommand(IEnumerable args) + { + var sdkCommandSpec = new SdkCommandSpec() + { + FileName = PsExecPath, + Arguments = args.ToList(), + WorkingDirectory = WorkingDirectory, + }; + return sdkCommandSpec; + } + } + } +} From 9e6c4543c3e73832d11df2b1d7ff7c172318240b Mon Sep 17 00:00:00 2001 From: Daniel Plaisted Date: Fri, 26 Jan 2024 17:13:57 -0500 Subject: [PATCH 383/577] WIP --- Directory.Packages.props | 2 + sdk.sln | 9 +- .../MsiInstallerTests.cs | 82 ++++- .../RemoteDirectory.cs | 41 +++ .../RemoteFile.cs | 16 + .../dotnet-MsiInstallation.Tests/VMAction.cs | 46 +++ .../VirtualMachine.cs | 298 ++++++++++++++++++ .../dotnet-MsiInstallation.Tests.csproj | 39 +++ 8 files changed, 522 insertions(+), 11 deletions(-) rename src/Tests/{dotnet-workload-install.Tests => dotnet-MsiInstallation.Tests}/MsiInstallerTests.cs (85%) create mode 100644 src/Tests/dotnet-MsiInstallation.Tests/RemoteDirectory.cs create mode 100644 src/Tests/dotnet-MsiInstallation.Tests/RemoteFile.cs create mode 100644 src/Tests/dotnet-MsiInstallation.Tests/VMAction.cs create mode 100644 src/Tests/dotnet-MsiInstallation.Tests/VirtualMachine.cs create mode 100644 src/Tests/dotnet-MsiInstallation.Tests/dotnet-MsiInstallation.Tests.csproj diff --git a/Directory.Packages.props b/Directory.Packages.props index 5d37eb795d6b..5e9ea4aefb2a 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -39,6 +39,7 @@ + @@ -89,6 +90,7 @@ + diff --git a/sdk.sln b/sdk.sln index b1025a787ea9..4c8aa2737e13 100644 --- a/sdk.sln +++ b/sdk.sln @@ -473,7 +473,9 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.NET.Build.Contain EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.NET.Build.Containers.UnitTests", "src\Tests\Microsoft.NET.Build.Containers.UnitTests\Microsoft.NET.Build.Containers.UnitTests.csproj", "{E54506B8-0B81-4FC4-99B5-5C67E19D4B09}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SDDLTests", "src\Tests\SDDLTests\SDDLTests.csproj", "{FEA8B7B5-901B-4A3A-948F-7E5F54F09FF5}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SDDLTests", "src\Tests\SDDLTests\SDDLTests.csproj", "{FEA8B7B5-901B-4A3A-948F-7E5F54F09FF5}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "dotnet-MsiInstallation.Tests", "src\Tests\dotnet-MsiInstallation.Tests\dotnet-MsiInstallation.Tests.csproj", "{36975025-857B-45F0-AB39-904B521A6713}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -893,6 +895,10 @@ Global {FEA8B7B5-901B-4A3A-948F-7E5F54F09FF5}.Debug|Any CPU.Build.0 = Debug|Any CPU {FEA8B7B5-901B-4A3A-948F-7E5F54F09FF5}.Release|Any CPU.ActiveCfg = Release|Any CPU {FEA8B7B5-901B-4A3A-948F-7E5F54F09FF5}.Release|Any CPU.Build.0 = Release|Any CPU + {36975025-857B-45F0-AB39-904B521A6713}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {36975025-857B-45F0-AB39-904B521A6713}.Debug|Any CPU.Build.0 = Debug|Any CPU + {36975025-857B-45F0-AB39-904B521A6713}.Release|Any CPU.ActiveCfg = Release|Any CPU + {36975025-857B-45F0-AB39-904B521A6713}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -1056,6 +1062,7 @@ Global {7DCA2BEC-B1E1-4F2B-952A-A26B5110FDA5} = {580D1AE7-AA8F-4912-8B76-105594E00B3B} {E54506B8-0B81-4FC4-99B5-5C67E19D4B09} = {580D1AE7-AA8F-4912-8B76-105594E00B3B} {FEA8B7B5-901B-4A3A-948F-7E5F54F09FF5} = {580D1AE7-AA8F-4912-8B76-105594E00B3B} + {36975025-857B-45F0-AB39-904B521A6713} = {580D1AE7-AA8F-4912-8B76-105594E00B3B} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {FB8F26CE-4DE6-433F-B32A-79183020BBD6} diff --git a/src/Tests/dotnet-workload-install.Tests/MsiInstallerTests.cs b/src/Tests/dotnet-MsiInstallation.Tests/MsiInstallerTests.cs similarity index 85% rename from src/Tests/dotnet-workload-install.Tests/MsiInstallerTests.cs rename to src/Tests/dotnet-MsiInstallation.Tests/MsiInstallerTests.cs index 37540e2e64e3..c87faf9f8d84 100644 --- a/src/Tests/dotnet-workload-install.Tests/MsiInstallerTests.cs +++ b/src/Tests/dotnet-MsiInstallation.Tests/MsiInstallerTests.cs @@ -2,7 +2,6 @@ // The .NET Foundation licenses this file to you under the MIT license. using System.Runtime.CompilerServices; -using ManifestReaderTests; using Microsoft.DotNet.Cli.NuGetPackageDownloader; using Microsoft.DotNet.ToolPackage; using Microsoft.DotNet.Workloads.Workload.Install; @@ -13,17 +12,23 @@ using System.Text.Json; using Microsoft.TemplateEngine.Edge.Constraints; using Microsoft.DotNet.Cli.Utils; +//using System.Management; +using Microsoft.Management.Infrastructure; +using System.Xml.Linq; -namespace Microsoft.DotNet.Cli.Workload.Install.Tests +namespace Microsoft.DotNet.MsiInstallerTests { - public class MsiInstallerTests : SdkTest + public class WorkloadTests : SdkTest, IDisposable { // Remote execution notes: // psexec / uses Admin share (C$) // ddrits / cloudtest // sysinternals: filemon / regmon + // May need to run winrm quickconfig to use WMI // How to apply snapshot via C#: https://stackoverflow.com/questions/60173096/hyperv-wmi-apply-snapshot-in-c-sharp // Also see https://stackoverflow.com/questions/1735978/manipulate-hyper-v-from-net + // Official documentation?: https://learn.microsoft.com/en-us/windows/win32/hyperv_v2/exporting-virtual-machines + // How to rename a snapshot: https://stackoverflow.com/questions/7599217/setting-hyper-v-snapshots-name-programmatically // Reminder: Enable "Remote Service Management" firewall rule so that PSExec will run more quickly @@ -68,10 +73,36 @@ public class MsiInstallerTests : SdkTest } """; + VirtualMachine VM { get; } - public MsiInstallerTests(ITestOutputHelper log) : base(log) + public WorkloadTests(ITestOutputHelper log) : base(log) { - + VM = new VirtualMachine(Log); + } + + public void Dispose() + { + VM.Dispose(); + } + + + [Fact] + public async Task UseWMI() + { + var snapshots = VM.GetSnapshots(); + + foreach (var snapshot in snapshots) + { + Log.WriteLine(snapshot.id + ": " + snapshot.name); + + //await vm.RenameSnapshot(snapshot.id, snapshot.name + " - renamed"); + } + + //await VM.CreateSnapshotAsync("New test snapshot"); + + //await VM.ApplySnapshotAsync("9BA74A78-D221-436E-9875-0A3BF86CEF4A"); + + await Task.Yield(); } [Fact] @@ -106,9 +137,38 @@ public void SdkInstallation() RunRemoteCommand("dotnet", "--version") .Should() .HaveStdOut("7.0.401"); + } + + [Fact] + public void SdkInstallation2() + { + VM.RunCommand("dotnet", "--version") + .Should() + .HaveStdOut("7.0.401"); + + VM.RunCommand($@"c:\SdkTesting\{SdkInstallerFileName}", "/quiet"); + + new DirectoryInfo($@"\\{TargetMachineName}\c$\Program Files\dotnet\sdk\{SdkInstallerVersion}") + .Should() + .Exist(); + + //RunRemoteCommand("dotnet", "--version") + // .Should() + // .HaveStdOut(SdkInstallerVersion); + + //RunRemoteCommand($@"c:\SdkTesting\{SdkInstallerFileName}", "/quiet", "/uninstall"); + + //new DirectoryInfo($@"\\{TargetMachineName}\c$\Program Files\dotnet\sdk\{SdkInstallerVersion}") + // .Should() + // .NotExist(); + + //RunRemoteCommand("dotnet", "--version") + // .Should() + // .HaveStdOut("7.0.401"); } + [Fact] public void WorkloadInstallation() { @@ -238,14 +298,14 @@ void CheckForDuplicateManifests() void TempTest() { //CleanupInstallState(); - //RunRemoteCommand("dotnet", "--version") - // .Should() - // .HaveStdOut("7.0.401"); + RunRemoteCommand("dotnet", "--version") + .Should() + .HaveStdOut("7.0.401"); //RunRemoteCommand($@"c:\SdkTesting\{SdkInstallerFileName}", "/quiet"); //DeployStage2Sdk(); - CleanupInstallState(); - RunRemoteCommand($@"c:\SdkTesting\{SdkInstallerFileName}", "/quiet", "/uninstall"); + //CleanupInstallState(); + //RunRemoteCommand($@"c:\SdkTesting\{SdkInstallerFileName}", "/quiet", "/uninstall"); } void DeployStage2Sdk() @@ -316,6 +376,8 @@ CommandResult RunRemoteCommand(params string[] args) return result; } + + class RemoteCommand : TestCommand { diff --git a/src/Tests/dotnet-MsiInstallation.Tests/RemoteDirectory.cs b/src/Tests/dotnet-MsiInstallation.Tests/RemoteDirectory.cs new file mode 100644 index 000000000000..36cf0fd37c61 --- /dev/null +++ b/src/Tests/dotnet-MsiInstallation.Tests/RemoteDirectory.cs @@ -0,0 +1,41 @@ +// Licensed to the .NET Foundation under one or more agreements. +// 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 FluentAssertions.Execution; + +namespace Microsoft.DotNet.MsiInstallerTests +{ + internal class RemoteDirectory + { + public string Path { get; } + + public bool Exists { get { throw new NotImplementedException(); } } + + public Assertions Should() + { + return new Assertions(this); + } + + public class Assertions + { + RemoteDirectory _directory; + + public Assertions(RemoteDirectory directory) + { + _directory = directory; + } + + public AndConstraint Exist() + { + Execute.Assertion.ForCondition(_directory.Exists) + .FailWith("Expected directory {0} does not exist.", _directory.Path); + return new AndConstraint(this); + } + } + } +} diff --git a/src/Tests/dotnet-MsiInstallation.Tests/RemoteFile.cs b/src/Tests/dotnet-MsiInstallation.Tests/RemoteFile.cs new file mode 100644 index 000000000000..54c48272db28 --- /dev/null +++ b/src/Tests/dotnet-MsiInstallation.Tests/RemoteFile.cs @@ -0,0 +1,16 @@ +// Licensed to the .NET Foundation under one or more agreements. +// 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; + +namespace Microsoft.DotNet.MsiInstallerTests +{ + internal class RemoteFile + { + public string Path { get; } + } +} diff --git a/src/Tests/dotnet-MsiInstallation.Tests/VMAction.cs b/src/Tests/dotnet-MsiInstallation.Tests/VMAction.cs new file mode 100644 index 000000000000..f429ea4160a7 --- /dev/null +++ b/src/Tests/dotnet-MsiInstallation.Tests/VMAction.cs @@ -0,0 +1,46 @@ +// Licensed to the .NET Foundation under one or more agreements. +// 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; + +namespace Microsoft.DotNet.MsiInstallerTests +{ + // Core actions: + // - Run command + // - Copy file to VM + // - Enumerate and read files / directories + + // Run command + // - Install .NET SDK (From SdkTesting folder) + // - Uninstall .NET SDK + // - Workload install / uninstall + // - Apply rollback file + // - Get .NET version + // Copy file to VM + // - Deploy stage 2 SDK + + + internal abstract class VMAction + { + public abstract SerializedVMAction Serialize(); + + public abstract VMActionResult Run(); + + + + } + + class SerializedVMAction + { + + } + + class VMActionResult + { + + } +} diff --git a/src/Tests/dotnet-MsiInstallation.Tests/VirtualMachine.cs b/src/Tests/dotnet-MsiInstallation.Tests/VirtualMachine.cs new file mode 100644 index 000000000000..59ea3fef9c1e --- /dev/null +++ b/src/Tests/dotnet-MsiInstallation.Tests/VirtualMachine.cs @@ -0,0 +1,298 @@ +// Licensed to the .NET Foundation under one or more agreements. +// 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 Microsoft.DotNet.Cli.Utils; +using Microsoft.Management.Infrastructure; +using Microsoft.Management.Infrastructure.Serialization; +using static Microsoft.ApplicationInsights.MetricDimensionNames.TelemetryContext; + +namespace Microsoft.DotNet.MsiInstallerTests +{ + internal class VirtualMachine : IDisposable + { + public string VMName { get; set; } = "Windows 11 dev environment"; + + const string virtNamespace = @"root\virtualization\v2"; + + public ITestOutputHelper Log { get; set; } + + private CimSession _session; + + public VirtualMachine(ITestOutputHelper log) + { + Log = log; + _session = CimSession.Create(Environment.MachineName); + } + + public CommandResult RunCommand(params string[] args) + { + throw new NotImplementedException(); + } + + public void CopyFile(string localSource, string vmDestination) + { + throw new NotImplementedException(); + } + + public void WriteFile(string vmDestination, string contents) + { + throw new NotImplementedException(); + } + + public RemoteDirectory GetRemoteDirectory(string path) + { + throw new NotImplementedException(); + } + + + private CimInstance GetVMInstance() + { + return _session.QueryInstances(virtNamespace, "WQL", $"SELECT * FROM Msvm_ComputerSystem WHERE ElementName='{VMName}'").First(); + } + + public IEnumerable<(string id, string name)> GetSnapshots() + { + return GetSnapshotInstances().Select(s => ((string)s.CimInstanceProperties["ConfigurationID"].Value, (string)s.CimInstanceProperties["ElementName"].Value)); + } + + private IEnumerable GetSnapshotInstances() + { + + using var vm = GetVMInstance(); + var snapshots = _session.QueryInstances(virtNamespace, "WQL", $"SELECT * FROM Msvm_VirtualSystemSettingData WHERE VirtualSystemIdentifier='{vm.CimInstanceProperties["Name"].Value}' And IsSaved='True'").ToList(); + //Log.WriteLine("Snapshot count: " + snapshots.Count); + //foreach (var snapshot in snapshots) + //{ + // Log.WriteLine(snapshot.CimInstanceProperties["ElementName"].Value.ToString()); + // //Log.WriteLine(snapshot.ToString()); + // //foreach (var prop in snapshot.CimInstanceProperties) + // //{ + // // Log.WriteLine($"\t{prop.Name}: {prop.Value}"); + // //} + //} + + return snapshots; + } + + public async Task RenameSnapshotAsync(string snapshotId, string newName) + { + var snapshots = GetSnapshotInstances(); + + var snapshot = snapshots.Single(s => s.CimInstanceProperties["ConfigurationID"].Value.ToString() == snapshotId); + + snapshot.CimInstanceProperties["ElementName"].Value = newName; + + + var managementService = _session.QueryInstances(@"root\virtualization\v2", "WQL", "SELECT * FROM Msvm_VirtualSystemManagementService").Single(); + var modifyVmMethod = managementService.CimClass.CimClassMethods.Single(m => m.Name == "ModifySystemSettings"); + //foreach (var param in modifyVmMethod.Parameters) + //{ + // Log.WriteLine($"{param.Name}: {param.CimType}"); + //} + + CimSerializer serializer = CimSerializer.Create(); + var snapshotString = Encoding.Unicode.GetString(serializer.Serialize(snapshot, InstanceSerializationOptions.None)); + + CimMethodParametersCollection cimMethodParameters = new CimMethodParametersCollection { + CimMethodParameter.Create("SystemSettings", snapshotString, CimType.String, CimFlags.In) + }; + + var result = _session.InvokeMethod(virtNamespace, managementService, "ModifySystemSettings", cimMethodParameters); + + await WaitForJobSuccess(result); + + } + + public async Task CreateSnapshotAsync(string snapshotName) + { + //Log.WriteLine(Environment.MachineName); + + //CimSession session = GetCimSession(publicServer.HostName); + //CimInstance vm = session.QueryInstances(@"root\virtualization\v2", "WQL", "SELECT * FROM Msvm_ComputerSystem WHERE Name='" + publicServer.MachineID + "'").FirstOrDefault(); + //var vms = session.QueryInstances(virtNamespace, "WQL", $"SELECT * FROM Msvm_ComputerSystem WHERE ElementName='{VMName}'"); + //var vms = session.QueryInstances(@"root\virtualization\v2", "WQL", "SELECT * FROM Msvm_ComputerSystem"); + //var vm = session.CreateInstance(@"root\virtualization\v2", "Msvm_VirtualSystemManagementService"); + //var vms = session.QueryInstances(@"root\virtualization\v2", "WQL", "SELECT * FROM Msvm_VirtualSystemManagementService"); + + //foreach (var vm in vms) + //{ + // //Log.WriteLine(vm.ToString()); + // //Log.WriteLine(vm.CimInstanceProperties["MachineID"].Value.ToString()); + // Log.WriteLine(vm.CimInstanceProperties["ElementName"].Value.ToString()); + // foreach (var prop in vm.CimInstanceProperties) + // { + // Log.WriteLine($"\t{prop.Name}: {prop.Value}"); + // } + //} + + using var targetVM = GetVMInstance(); + + var existingSnapshots = GetSnapshots().ToDictionary(s => s.id, s => s.name); + + var snapshotService = _session.EnumerateInstances(virtNamespace, "Msvm_VirtualSystemSnapshotService").First(); + + //var settingData = _session.CreateInstance(virtNamespace, new CimInstance("CIM_SettingData")); + + CimMethodParametersCollection cimMethodParameters = new CimMethodParametersCollection { + CimMethodParameter.Create("AffectedSystem", targetVM, CimType.Reference, CimFlags.In), + CimMethodParameter.Create("SnapshotType", 2, CimType.UInt16, CimFlags.In), + }; + + + + var result = _session.InvokeMethod(virtNamespace, snapshotService, "CreateSnapshot", cimMethodParameters); + + await WaitForJobSuccess(result); + + //var updatedSnapshots = GetSnapshots().ToDictionary(s => s.id, s => s.name); + //foreach (var snapshot in updatedSnapshots) + //{ + // if (!existingSnapshots.ContainsKey(snapshot.Key)) + // { + // Log.WriteLine($"Created snapshot {snapshot.Value} ({snapshot.Key})"); + // } + //} + + var newSnapshot = GetSnapshots().Single(s => !existingSnapshots.ContainsKey(s.id)); + + //Log.WriteLine($"Created snapshot {newSnapshot.name} ({newSnapshot.id})"); + + await RenameSnapshotAsync(newSnapshot.id, snapshotName); + + } + + public async Task ApplySnapshotAsync(string snapshotId) + { + await SetRunningAsync(false); + + var snapshots = GetSnapshotInstances(); + + var snapshot = snapshots.Single(s => s.CimInstanceProperties["ConfigurationID"].Value.ToString() == snapshotId); + + var snapshotService = _session.EnumerateInstances(virtNamespace, "Msvm_VirtualSystemSnapshotService").First(); + + CimMethodParametersCollection cimMethodParameters = new CimMethodParametersCollection + { + CimMethodParameter.Create("Snapshot", snapshot, CimType.Reference, CimFlags.In), + }; + + var result = _session.InvokeMethod(virtNamespace, snapshotService, "ApplySnapshot", cimMethodParameters); + + await WaitForJobSuccess(result); + + await SetRunningAsync(true); + } + + public async Task SetRunningAsync(bool running) + { + using var vm = GetVMInstance(); + + bool isAlreadyRunning = (UInt16) vm.CimInstanceProperties["EnabledState"].Value == 2; + if (running == isAlreadyRunning) + { + return; + } + + var methodParameters = new CimMethodParametersCollection() + { + CimMethodParameter.Create("RequestedState", (UInt16) (running ? 2 : 4), CimFlags.In) + }; + + var result = _session.InvokeMethod(virtNamespace, vm, "RequestStateChange", methodParameters); + + await WaitForJobSuccess(result); + } + + private static bool IsRunning(JobState jobState) + { + return jobState == JobState.New || jobState == JobState.Starting || jobState == JobState.Running || jobState == JobState.Suspended || jobState == JobState.ShuttingDown; + } + + private async Task WaitForJobSuccess(CimMethodResult result) + { + if ((uint)result.ReturnValue.Value == 4096) + { + CimInstance job = (CimInstance)result.OutParameters["Job"].Value; + job = _session.GetInstance(virtNamespace, job); + while (IsRunning((JobState)(UInt16)job.CimInstanceProperties["JobState"].Value)) + { + await Task.Delay(100); + job = _session.GetInstance(job.CimSystemProperties.Namespace, job); + } + + var jobState = (JobState)(UInt16)job.CimInstanceProperties["JobState"].Value; + if (jobState != JobState.Completed && jobState != JobState.CompletedWithWarnings) + { + throw new Exception("Job failed"); + } + } + else + { + if (result.ReturnValue.Value is UInt32 returnValue) + { + if (returnValue != 0) + { + throw new Exception($"Job failed with return value {returnValue}"); + } + } + else + { + throw new Exception($"Job failed with return value {result.ReturnValue.Value}"); + } + } + } + + public void Dispose() + { + _session.Dispose(); + } + + enum JobState + { + New = 2, + Starting = 3, + Running = 4, + Suspended = 5, + ShuttingDown = 6, + Completed = 7, + Terminated = 8, + Killed = 9, + Exception = 10, + CompletedWithWarnings = 32768 + } + + + private class CimObserver : IObserver + { + TaskCompletionSource _tcs; + Management.Infrastructure.Generic.CimAsyncResult _result; + + public Task Task => _tcs.Task; + + public CimObserver(Management.Infrastructure.Generic.CimAsyncResult result) + { + _tcs = new TaskCompletionSource(); + _result = result; + _result.Subscribe(this); + } + + public void OnCompleted() + { + } + public void OnError(Exception error) + { + _tcs.SetException(error); + } + public void OnNext(T value) + { + _tcs.SetResult(value); + } + } + + } +} diff --git a/src/Tests/dotnet-MsiInstallation.Tests/dotnet-MsiInstallation.Tests.csproj b/src/Tests/dotnet-MsiInstallation.Tests/dotnet-MsiInstallation.Tests.csproj new file mode 100644 index 000000000000..791307c67819 --- /dev/null +++ b/src/Tests/dotnet-MsiInstallation.Tests/dotnet-MsiInstallation.Tests.csproj @@ -0,0 +1,39 @@ + + + + + Tests\$(MSBuildProjectName) + + + + + + Exe + $(SdkTargetFramework)-windows + + + + testMsiInstallation + Microsoft.DotNet.MsiInstallerTests + + + + + + + + + + + + + + + + + + + + + + From 06bac1aa2939394bda6505922c2feade1df0a8a4 Mon Sep 17 00:00:00 2001 From: Daniel Plaisted Date: Mon, 29 Jan 2024 10:05:04 -0500 Subject: [PATCH 384/577] WIP --- .../MsiInstallerTests.cs | 4 +- .../RemoteDirectory.cs | 8 +- .../dotnet-MsiInstallation.Tests/VMAction.cs | 25 ++ .../dotnet-MsiInstallation.Tests/VMControl.cs | 257 +++++++++++++++++ .../VMStateTree.cs | 19 ++ .../VirtualMachine.cs | 264 +----------------- 6 files changed, 317 insertions(+), 260 deletions(-) create mode 100644 src/Tests/dotnet-MsiInstallation.Tests/VMControl.cs create mode 100644 src/Tests/dotnet-MsiInstallation.Tests/VMStateTree.cs diff --git a/src/Tests/dotnet-MsiInstallation.Tests/MsiInstallerTests.cs b/src/Tests/dotnet-MsiInstallation.Tests/MsiInstallerTests.cs index c87faf9f8d84..c4e19eb13379 100644 --- a/src/Tests/dotnet-MsiInstallation.Tests/MsiInstallerTests.cs +++ b/src/Tests/dotnet-MsiInstallation.Tests/MsiInstallerTests.cs @@ -73,11 +73,11 @@ public class WorkloadTests : SdkTest, IDisposable } """; - VirtualMachine VM { get; } + VMControl VM { get; } public WorkloadTests(ITestOutputHelper log) : base(log) { - VM = new VirtualMachine(Log); + VM = new VMControl(Log); } public void Dispose() diff --git a/src/Tests/dotnet-MsiInstallation.Tests/RemoteDirectory.cs b/src/Tests/dotnet-MsiInstallation.Tests/RemoteDirectory.cs index 36cf0fd37c61..104379d17036 100644 --- a/src/Tests/dotnet-MsiInstallation.Tests/RemoteDirectory.cs +++ b/src/Tests/dotnet-MsiInstallation.Tests/RemoteDirectory.cs @@ -14,7 +14,13 @@ internal class RemoteDirectory { public string Path { get; } - public bool Exists { get { throw new NotImplementedException(); } } + public bool Exists + { + get + { + throw new NotImplementedException(); + } + } public Assertions Should() { diff --git a/src/Tests/dotnet-MsiInstallation.Tests/VMAction.cs b/src/Tests/dotnet-MsiInstallation.Tests/VMAction.cs index f429ea4160a7..52c270a51708 100644 --- a/src/Tests/dotnet-MsiInstallation.Tests/VMAction.cs +++ b/src/Tests/dotnet-MsiInstallation.Tests/VMAction.cs @@ -39,6 +39,31 @@ class SerializedVMAction } + class SerializedRunCommand + { + public List Arguments { get; set; } = new List(); + + public override bool Equals(object obj) + { + if (obj is SerializedRunCommand other) + { + return Arguments.SequenceEqual(other.Arguments); + } + return false; + } + + public override int GetHashCode() + { + var hashcode = new HashCode(); + hashcode.Add(Arguments.Count); + foreach (var arg in Arguments) + { + hashcode.Add(arg.GetHashCode()); + } + return hashcode.ToHashCode(); + } + } + class VMActionResult { diff --git a/src/Tests/dotnet-MsiInstallation.Tests/VMControl.cs b/src/Tests/dotnet-MsiInstallation.Tests/VMControl.cs new file mode 100644 index 000000000000..a78d9c070675 --- /dev/null +++ b/src/Tests/dotnet-MsiInstallation.Tests/VMControl.cs @@ -0,0 +1,257 @@ +// Licensed to the .NET Foundation under one or more agreements. +// 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 Microsoft.DotNet.Cli.Utils; +using Microsoft.DotNet.Installer.Windows; +using Microsoft.Management.Infrastructure; +using Microsoft.Management.Infrastructure.Serialization; +using static Microsoft.ApplicationInsights.MetricDimensionNames.TelemetryContext; + +namespace Microsoft.DotNet.MsiInstallerTests +{ + internal class VMControl : IDisposable + { + public string VMName { get; set; } = "Windows 11 dev environment"; + + const string virtNamespace = @"root\virtualization\v2"; + + public ITestOutputHelper Log { get; } + + private CimSession _session; + private CimInstance VMInstance { get; } + + public VMControl(ITestOutputHelper log) + { + if (!WindowsUtils.IsAdministrator()) + { + throw new Exception("Must be running as admin to control virtual machines"); + } + + Log = log; + _session = CimSession.Create(Environment.MachineName); + VMInstance = _session.QueryInstances(virtNamespace, "WQL", $"SELECT * FROM Msvm_ComputerSystem WHERE ElementName='{VMName}'").Single(); + } + + + + public IEnumerable<(string id, string name)> GetSnapshots() + { + return GetSnapshotInstances().Select(s => ((string)s.CimInstanceProperties["ConfigurationID"].Value, (string)s.CimInstanceProperties["ElementName"].Value)); + } + + private IEnumerable GetSnapshotInstances() + { + var snapshots = _session.QueryInstances(virtNamespace, "WQL", $"SELECT * FROM Msvm_VirtualSystemSettingData WHERE VirtualSystemIdentifier='{VMInstance.CimInstanceProperties["Name"].Value}' And IsSaved='True'").ToList(); + //Log.WriteLine("Snapshot count: " + snapshots.Count); + //foreach (var snapshot in snapshots) + //{ + // Log.WriteLine(snapshot.CimInstanceProperties["ElementName"].Value.ToString()); + // //Log.WriteLine(snapshot.ToString()); + // //foreach (var prop in snapshot.CimInstanceProperties) + // //{ + // // Log.WriteLine($"\t{prop.Name}: {prop.Value}"); + // //} + //} + + return snapshots; + } + + public async Task RenameSnapshotAsync(string snapshotId, string newName) + { + var snapshots = GetSnapshotInstances(); + + var snapshot = snapshots.Single(s => s.CimInstanceProperties["ConfigurationID"].Value.ToString() == snapshotId); + + snapshot.CimInstanceProperties["ElementName"].Value = newName; + + + var managementService = _session.QueryInstances(@"root\virtualization\v2", "WQL", "SELECT * FROM Msvm_VirtualSystemManagementService").Single(); + var modifyVmMethod = managementService.CimClass.CimClassMethods.Single(m => m.Name == "ModifySystemSettings"); + //foreach (var param in modifyVmMethod.Parameters) + //{ + // Log.WriteLine($"{param.Name}: {param.CimType}"); + //} + + CimSerializer serializer = CimSerializer.Create(); + var snapshotString = Encoding.Unicode.GetString(serializer.Serialize(snapshot, InstanceSerializationOptions.None)); + + CimMethodParametersCollection cimMethodParameters = new CimMethodParametersCollection { + CimMethodParameter.Create("SystemSettings", snapshotString, CimType.String, CimFlags.In) + }; + + var result = _session.InvokeMethod(virtNamespace, managementService, "ModifySystemSettings", cimMethodParameters); + + await WaitForJobSuccess(result); + + } + + public async Task CreateSnapshotAsync(string snapshotName) + { + var existingSnapshots = GetSnapshots().ToDictionary(s => s.id, s => s.name); + + var snapshotService = _session.EnumerateInstances(virtNamespace, "Msvm_VirtualSystemSnapshotService").First(); + + //var settingData = _session.CreateInstance(virtNamespace, new CimInstance("CIM_SettingData")); + + CimMethodParametersCollection cimMethodParameters = new CimMethodParametersCollection { + CimMethodParameter.Create("AffectedSystem", VMInstance, CimType.Reference, CimFlags.In), + CimMethodParameter.Create("SnapshotType", 2, CimType.UInt16, CimFlags.In), + }; + + + + var result = _session.InvokeMethod(virtNamespace, snapshotService, "CreateSnapshot", cimMethodParameters); + + await WaitForJobSuccess(result); + + //var updatedSnapshots = GetSnapshots().ToDictionary(s => s.id, s => s.name); + //foreach (var snapshot in updatedSnapshots) + //{ + // if (!existingSnapshots.ContainsKey(snapshot.Key)) + // { + // Log.WriteLine($"Created snapshot {snapshot.Value} ({snapshot.Key})"); + // } + //} + + var newSnapshot = GetSnapshots().Single(s => !existingSnapshots.ContainsKey(s.id)); + + //Log.WriteLine($"Created snapshot {newSnapshot.name} ({newSnapshot.id})"); + + await RenameSnapshotAsync(newSnapshot.id, snapshotName); + + } + + public async Task ApplySnapshotAsync(string snapshotId) + { + await SetRunningAsync(false); + + var snapshots = GetSnapshotInstances(); + + var snapshot = snapshots.Single(s => s.CimInstanceProperties["ConfigurationID"].Value.ToString() == snapshotId); + + var snapshotService = _session.EnumerateInstances(virtNamespace, "Msvm_VirtualSystemSnapshotService").First(); + + CimMethodParametersCollection cimMethodParameters = new CimMethodParametersCollection + { + CimMethodParameter.Create("Snapshot", snapshot, CimType.Reference, CimFlags.In), + }; + + var result = _session.InvokeMethod(virtNamespace, snapshotService, "ApplySnapshot", cimMethodParameters); + + await WaitForJobSuccess(result); + + await SetRunningAsync(true); + } + + public async Task SetRunningAsync(bool running) + { + bool isAlreadyRunning = (UInt16) VMInstance.CimInstanceProperties["EnabledState"].Value == 2; + if (running == isAlreadyRunning) + { + return; + } + + var methodParameters = new CimMethodParametersCollection() + { + CimMethodParameter.Create("RequestedState", (UInt16) (running ? 2 : 4), CimFlags.In) + }; + + var result = _session.InvokeMethod(virtNamespace, VMInstance, "RequestStateChange", methodParameters); + + await WaitForJobSuccess(result); + } + + private static bool IsRunning(JobState jobState) + { + return jobState == JobState.New || jobState == JobState.Starting || jobState == JobState.Running || jobState == JobState.Suspended || jobState == JobState.ShuttingDown; + } + + private async Task WaitForJobSuccess(CimMethodResult result) + { + if ((uint)result.ReturnValue.Value == 4096) + { + CimInstance job = (CimInstance)result.OutParameters["Job"].Value; + job = _session.GetInstance(virtNamespace, job); + while (IsRunning((JobState)(UInt16)job.CimInstanceProperties["JobState"].Value)) + { + await Task.Delay(100); + job = _session.GetInstance(job.CimSystemProperties.Namespace, job); + } + + var jobState = (JobState)(UInt16)job.CimInstanceProperties["JobState"].Value; + if (jobState != JobState.Completed && jobState != JobState.CompletedWithWarnings) + { + throw new Exception("Job failed"); + } + } + else + { + if (result.ReturnValue.Value is UInt32 returnValue) + { + if (returnValue != 0) + { + throw new Exception($"Job failed with return value {returnValue}"); + } + } + else + { + throw new Exception($"Job failed with return value {result.ReturnValue.Value}"); + } + } + } + + public void Dispose() + { + VMInstance.Dispose(); + _session.Dispose(); + } + + enum JobState + { + New = 2, + Starting = 3, + Running = 4, + Suspended = 5, + ShuttingDown = 6, + Completed = 7, + Terminated = 8, + Killed = 9, + Exception = 10, + CompletedWithWarnings = 32768 + } + + + private class CimObserver : IObserver + { + TaskCompletionSource _tcs; + Management.Infrastructure.Generic.CimAsyncResult _result; + + public Task Task => _tcs.Task; + + public CimObserver(Management.Infrastructure.Generic.CimAsyncResult result) + { + _tcs = new TaskCompletionSource(); + _result = result; + _result.Subscribe(this); + } + + public void OnCompleted() + { + } + public void OnError(Exception error) + { + _tcs.SetException(error); + } + public void OnNext(T value) + { + _tcs.SetResult(value); + } + } + + } +} diff --git a/src/Tests/dotnet-MsiInstallation.Tests/VMStateTree.cs b/src/Tests/dotnet-MsiInstallation.Tests/VMStateTree.cs new file mode 100644 index 000000000000..fb37397f2cef --- /dev/null +++ b/src/Tests/dotnet-MsiInstallation.Tests/VMStateTree.cs @@ -0,0 +1,19 @@ +// Licensed to the .NET Foundation under one or more agreements. +// 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; + +namespace Microsoft.DotNet.MsiInstallerTests +{ + internal class VMStateTree + { + public string SnapshotId { get; set; } + public string SnapshotName { get; set; } + + public Dictionary Actions { get; set; } + } +} diff --git a/src/Tests/dotnet-MsiInstallation.Tests/VirtualMachine.cs b/src/Tests/dotnet-MsiInstallation.Tests/VirtualMachine.cs index 59ea3fef9c1e..e18f83688a7d 100644 --- a/src/Tests/dotnet-MsiInstallation.Tests/VirtualMachine.cs +++ b/src/Tests/dotnet-MsiInstallation.Tests/VirtualMachine.cs @@ -7,26 +7,21 @@ using System.Text; using System.Threading.Tasks; using Microsoft.DotNet.Cli.Utils; -using Microsoft.Management.Infrastructure; -using Microsoft.Management.Infrastructure.Serialization; -using static Microsoft.ApplicationInsights.MetricDimensionNames.TelemetryContext; namespace Microsoft.DotNet.MsiInstallerTests { internal class VirtualMachine : IDisposable { - public string VMName { get; set; } = "Windows 11 dev environment"; - - const string virtNamespace = @"root\virtualization\v2"; - - public ITestOutputHelper Log { get; set; } - - private CimSession _session; - + ITestOutputHelper Log { get; } + VMControl VMControl { get; } public VirtualMachine(ITestOutputHelper log) { Log = log; - _session = CimSession.Create(Environment.MachineName); + VMControl = new VMControl(log); + } + public void Dispose() + { + VMControl.Dispose(); } public CommandResult RunCommand(params string[] args) @@ -49,250 +44,5 @@ public RemoteDirectory GetRemoteDirectory(string path) throw new NotImplementedException(); } - - private CimInstance GetVMInstance() - { - return _session.QueryInstances(virtNamespace, "WQL", $"SELECT * FROM Msvm_ComputerSystem WHERE ElementName='{VMName}'").First(); - } - - public IEnumerable<(string id, string name)> GetSnapshots() - { - return GetSnapshotInstances().Select(s => ((string)s.CimInstanceProperties["ConfigurationID"].Value, (string)s.CimInstanceProperties["ElementName"].Value)); - } - - private IEnumerable GetSnapshotInstances() - { - - using var vm = GetVMInstance(); - var snapshots = _session.QueryInstances(virtNamespace, "WQL", $"SELECT * FROM Msvm_VirtualSystemSettingData WHERE VirtualSystemIdentifier='{vm.CimInstanceProperties["Name"].Value}' And IsSaved='True'").ToList(); - //Log.WriteLine("Snapshot count: " + snapshots.Count); - //foreach (var snapshot in snapshots) - //{ - // Log.WriteLine(snapshot.CimInstanceProperties["ElementName"].Value.ToString()); - // //Log.WriteLine(snapshot.ToString()); - // //foreach (var prop in snapshot.CimInstanceProperties) - // //{ - // // Log.WriteLine($"\t{prop.Name}: {prop.Value}"); - // //} - //} - - return snapshots; - } - - public async Task RenameSnapshotAsync(string snapshotId, string newName) - { - var snapshots = GetSnapshotInstances(); - - var snapshot = snapshots.Single(s => s.CimInstanceProperties["ConfigurationID"].Value.ToString() == snapshotId); - - snapshot.CimInstanceProperties["ElementName"].Value = newName; - - - var managementService = _session.QueryInstances(@"root\virtualization\v2", "WQL", "SELECT * FROM Msvm_VirtualSystemManagementService").Single(); - var modifyVmMethod = managementService.CimClass.CimClassMethods.Single(m => m.Name == "ModifySystemSettings"); - //foreach (var param in modifyVmMethod.Parameters) - //{ - // Log.WriteLine($"{param.Name}: {param.CimType}"); - //} - - CimSerializer serializer = CimSerializer.Create(); - var snapshotString = Encoding.Unicode.GetString(serializer.Serialize(snapshot, InstanceSerializationOptions.None)); - - CimMethodParametersCollection cimMethodParameters = new CimMethodParametersCollection { - CimMethodParameter.Create("SystemSettings", snapshotString, CimType.String, CimFlags.In) - }; - - var result = _session.InvokeMethod(virtNamespace, managementService, "ModifySystemSettings", cimMethodParameters); - - await WaitForJobSuccess(result); - - } - - public async Task CreateSnapshotAsync(string snapshotName) - { - //Log.WriteLine(Environment.MachineName); - - //CimSession session = GetCimSession(publicServer.HostName); - //CimInstance vm = session.QueryInstances(@"root\virtualization\v2", "WQL", "SELECT * FROM Msvm_ComputerSystem WHERE Name='" + publicServer.MachineID + "'").FirstOrDefault(); - //var vms = session.QueryInstances(virtNamespace, "WQL", $"SELECT * FROM Msvm_ComputerSystem WHERE ElementName='{VMName}'"); - //var vms = session.QueryInstances(@"root\virtualization\v2", "WQL", "SELECT * FROM Msvm_ComputerSystem"); - //var vm = session.CreateInstance(@"root\virtualization\v2", "Msvm_VirtualSystemManagementService"); - //var vms = session.QueryInstances(@"root\virtualization\v2", "WQL", "SELECT * FROM Msvm_VirtualSystemManagementService"); - - //foreach (var vm in vms) - //{ - // //Log.WriteLine(vm.ToString()); - // //Log.WriteLine(vm.CimInstanceProperties["MachineID"].Value.ToString()); - // Log.WriteLine(vm.CimInstanceProperties["ElementName"].Value.ToString()); - // foreach (var prop in vm.CimInstanceProperties) - // { - // Log.WriteLine($"\t{prop.Name}: {prop.Value}"); - // } - //} - - using var targetVM = GetVMInstance(); - - var existingSnapshots = GetSnapshots().ToDictionary(s => s.id, s => s.name); - - var snapshotService = _session.EnumerateInstances(virtNamespace, "Msvm_VirtualSystemSnapshotService").First(); - - //var settingData = _session.CreateInstance(virtNamespace, new CimInstance("CIM_SettingData")); - - CimMethodParametersCollection cimMethodParameters = new CimMethodParametersCollection { - CimMethodParameter.Create("AffectedSystem", targetVM, CimType.Reference, CimFlags.In), - CimMethodParameter.Create("SnapshotType", 2, CimType.UInt16, CimFlags.In), - }; - - - - var result = _session.InvokeMethod(virtNamespace, snapshotService, "CreateSnapshot", cimMethodParameters); - - await WaitForJobSuccess(result); - - //var updatedSnapshots = GetSnapshots().ToDictionary(s => s.id, s => s.name); - //foreach (var snapshot in updatedSnapshots) - //{ - // if (!existingSnapshots.ContainsKey(snapshot.Key)) - // { - // Log.WriteLine($"Created snapshot {snapshot.Value} ({snapshot.Key})"); - // } - //} - - var newSnapshot = GetSnapshots().Single(s => !existingSnapshots.ContainsKey(s.id)); - - //Log.WriteLine($"Created snapshot {newSnapshot.name} ({newSnapshot.id})"); - - await RenameSnapshotAsync(newSnapshot.id, snapshotName); - - } - - public async Task ApplySnapshotAsync(string snapshotId) - { - await SetRunningAsync(false); - - var snapshots = GetSnapshotInstances(); - - var snapshot = snapshots.Single(s => s.CimInstanceProperties["ConfigurationID"].Value.ToString() == snapshotId); - - var snapshotService = _session.EnumerateInstances(virtNamespace, "Msvm_VirtualSystemSnapshotService").First(); - - CimMethodParametersCollection cimMethodParameters = new CimMethodParametersCollection - { - CimMethodParameter.Create("Snapshot", snapshot, CimType.Reference, CimFlags.In), - }; - - var result = _session.InvokeMethod(virtNamespace, snapshotService, "ApplySnapshot", cimMethodParameters); - - await WaitForJobSuccess(result); - - await SetRunningAsync(true); - } - - public async Task SetRunningAsync(bool running) - { - using var vm = GetVMInstance(); - - bool isAlreadyRunning = (UInt16) vm.CimInstanceProperties["EnabledState"].Value == 2; - if (running == isAlreadyRunning) - { - return; - } - - var methodParameters = new CimMethodParametersCollection() - { - CimMethodParameter.Create("RequestedState", (UInt16) (running ? 2 : 4), CimFlags.In) - }; - - var result = _session.InvokeMethod(virtNamespace, vm, "RequestStateChange", methodParameters); - - await WaitForJobSuccess(result); - } - - private static bool IsRunning(JobState jobState) - { - return jobState == JobState.New || jobState == JobState.Starting || jobState == JobState.Running || jobState == JobState.Suspended || jobState == JobState.ShuttingDown; - } - - private async Task WaitForJobSuccess(CimMethodResult result) - { - if ((uint)result.ReturnValue.Value == 4096) - { - CimInstance job = (CimInstance)result.OutParameters["Job"].Value; - job = _session.GetInstance(virtNamespace, job); - while (IsRunning((JobState)(UInt16)job.CimInstanceProperties["JobState"].Value)) - { - await Task.Delay(100); - job = _session.GetInstance(job.CimSystemProperties.Namespace, job); - } - - var jobState = (JobState)(UInt16)job.CimInstanceProperties["JobState"].Value; - if (jobState != JobState.Completed && jobState != JobState.CompletedWithWarnings) - { - throw new Exception("Job failed"); - } - } - else - { - if (result.ReturnValue.Value is UInt32 returnValue) - { - if (returnValue != 0) - { - throw new Exception($"Job failed with return value {returnValue}"); - } - } - else - { - throw new Exception($"Job failed with return value {result.ReturnValue.Value}"); - } - } - } - - public void Dispose() - { - _session.Dispose(); - } - - enum JobState - { - New = 2, - Starting = 3, - Running = 4, - Suspended = 5, - ShuttingDown = 6, - Completed = 7, - Terminated = 8, - Killed = 9, - Exception = 10, - CompletedWithWarnings = 32768 - } - - - private class CimObserver : IObserver - { - TaskCompletionSource _tcs; - Management.Infrastructure.Generic.CimAsyncResult _result; - - public Task Task => _tcs.Task; - - public CimObserver(Management.Infrastructure.Generic.CimAsyncResult result) - { - _tcs = new TaskCompletionSource(); - _result = result; - _result.Subscribe(this); - } - - public void OnCompleted() - { - } - public void OnError(Exception error) - { - _tcs.SetException(error); - } - public void OnNext(T value) - { - _tcs.SetResult(value); - } - } - } } From 88b20e63bc6802d4caed60bef4356be9e924704b Mon Sep 17 00:00:00 2001 From: Daniel Plaisted Date: Wed, 31 Jan 2024 07:14:36 -0500 Subject: [PATCH 385/577] WIP --- .../MsiInstallerTests.cs | 242 ++++++++++------- .../dotnet-MsiInstallation.Tests/VMAction.cs | 105 ++++++-- .../dotnet-MsiInstallation.Tests/VMControl.cs | 254 +++++++++++++++--- .../VMStateTree.cs | 2 +- .../VirtualMachine.cs | 139 +++++++++- 5 files changed, 584 insertions(+), 158 deletions(-) diff --git a/src/Tests/dotnet-MsiInstallation.Tests/MsiInstallerTests.cs b/src/Tests/dotnet-MsiInstallation.Tests/MsiInstallerTests.cs index c4e19eb13379..e77e4b7c49d7 100644 --- a/src/Tests/dotnet-MsiInstallation.Tests/MsiInstallerTests.cs +++ b/src/Tests/dotnet-MsiInstallation.Tests/MsiInstallerTests.cs @@ -73,11 +73,13 @@ public class WorkloadTests : SdkTest, IDisposable } """; - VMControl VM { get; } + //VMControl VM { get; } + VirtualMachine VM { get; } public WorkloadTests(ITestOutputHelper log) : base(log) { - VM = new VMControl(Log); + //VM = new VMControl(Log); + VM = new VirtualMachine(Log); } public void Dispose() @@ -85,11 +87,61 @@ public void Dispose() VM.Dispose(); } + [Fact] + public void InstallSdk() + { + VM.RunCommand($@"c:\SdkTesting\{SdkInstallerFileName}", "/quiet") + .Should() + .Pass(); + } + + [Fact] + public void InstallWasm() + { + InstallSdk(); + + VM.WriteFile($@"C:\SdkTesting\rollback-rc1.json", RollbackRC1); + VM.RunCommand("dotnet", "workload", "update", "--from-rollback-file", @"c:\SdkTesting\rollback-rc1.json", "--skip-sign-check"); + + VM.RunCommand("dotnet", "workload", "install", "wasm-tools", "--skip-manifest-update") + .Should() + .Pass(); + } + + [Fact] + public void InstallAndroid() + { + InstallSdk(); + + VM.WriteFile($@"C:\SdkTesting\rollback-rc1.json", RollbackRC1); + VM.RunCommand("dotnet", "workload", "update", "--from-rollback-file", @"c:\SdkTesting\rollback-rc1.json", "--skip-sign-check"); + + VM.RunCommand("dotnet", "workload", "install", "Android", "--skip-manifest-update") + .Should() + .Pass(); + } + + [Fact] + public void InstallAndroidAndWasm() + { + InstallSdk(); + + VM.WriteFile($@"C:\SdkTesting\rollback-rc1.json", RollbackRC1); + VM.RunCommand("dotnet", "workload", "update", "--from-rollback-file", @"c:\SdkTesting\rollback-rc1.json", "--skip-sign-check"); + + VM.RunCommand("dotnet", "workload", "install", "Android", "--skip-manifest-update") + .Should() + .Pass(); + + VM.RunCommand("dotnet", "workload", "install", "wasm-tools", "--skip-manifest-update") + .Should() + .Pass(); + } [Fact] public async Task UseWMI() { - var snapshots = VM.GetSnapshots(); + var snapshots = VM.VMControl.GetSnapshots(); foreach (var snapshot in snapshots) { @@ -98,6 +150,8 @@ public async Task UseWMI() //await vm.RenameSnapshot(snapshot.id, snapshot.name + " - renamed"); } + await VM.VMControl.RenameSnapshotAsync("D258F2C9-F4BE-47F7-8D9C-DF5D955B84BC", "Can I rename this?"); + //await VM.CreateSnapshotAsync("New test snapshot"); //await VM.ApplySnapshotAsync("9BA74A78-D221-436E-9875-0A3BF86CEF4A"); @@ -105,132 +159,132 @@ public async Task UseWMI() await Task.Yield(); } - [Fact] - public void UninstallSdk() - { - RunRemoteCommand($@"c:\SdkTesting\{SdkInstallerFileName}", "/quiet", "/uninstall"); - } + //[Fact(Skip = "testing")] + //public void UninstallSdk() + //{ + // RunRemoteCommand($@"c:\SdkTesting\{SdkInstallerFileName}", "/quiet", "/uninstall"); + //} - [Fact] - public void SdkInstallation() - { - RunRemoteCommand("dotnet", "--version") - .Should() - .HaveStdOut("7.0.401"); + //[Fact(Skip = "testing")] + //public void SdkInstallation() + //{ + // RunRemoteCommand("dotnet", "--version") + // .Should() + // .HaveStdOut("7.0.401"); - RunRemoteCommand($@"c:\SdkTesting\{SdkInstallerFileName}", "/quiet"); + // RunRemoteCommand($@"c:\SdkTesting\{SdkInstallerFileName}", "/quiet"); - new DirectoryInfo($@"\\{TargetMachineName}\c$\Program Files\dotnet\sdk\{SdkInstallerVersion}") - .Should() - .Exist(); + // new DirectoryInfo($@"\\{TargetMachineName}\c$\Program Files\dotnet\sdk\{SdkInstallerVersion}") + // .Should() + // .Exist(); - RunRemoteCommand("dotnet", "--version") - .Should() - .HaveStdOut(SdkInstallerVersion); + // RunRemoteCommand("dotnet", "--version") + // .Should() + // .HaveStdOut(SdkInstallerVersion); - RunRemoteCommand($@"c:\SdkTesting\{SdkInstallerFileName}", "/quiet", "/uninstall"); + // RunRemoteCommand($@"c:\SdkTesting\{SdkInstallerFileName}", "/quiet", "/uninstall"); - new DirectoryInfo($@"\\{TargetMachineName}\c$\Program Files\dotnet\sdk\{SdkInstallerVersion}") - .Should() - .NotExist(); + // new DirectoryInfo($@"\\{TargetMachineName}\c$\Program Files\dotnet\sdk\{SdkInstallerVersion}") + // .Should() + // .NotExist(); - RunRemoteCommand("dotnet", "--version") - .Should() - .HaveStdOut("7.0.401"); - } + // RunRemoteCommand("dotnet", "--version") + // .Should() + // .HaveStdOut("7.0.401"); + //} - [Fact] - public void SdkInstallation2() - { - VM.RunCommand("dotnet", "--version") - .Should() - .HaveStdOut("7.0.401"); + //[Fact] + //public void SdkInstallation2() + //{ + // //VM.RunCommand("dotnet", "--version") + // // .Should() + // // .HaveStdOut("7.0.401"); - VM.RunCommand($@"c:\SdkTesting\{SdkInstallerFileName}", "/quiet"); + // //VM.RunCommand($@"c:\SdkTesting\{SdkInstallerFileName}", "/quiet"); - new DirectoryInfo($@"\\{TargetMachineName}\c$\Program Files\dotnet\sdk\{SdkInstallerVersion}") - .Should() - .Exist(); + // //new DirectoryInfo($@"\\{TargetMachineName}\c$\Program Files\dotnet\sdk\{SdkInstallerVersion}") + // // .Should() + // // .Exist(); - //RunRemoteCommand("dotnet", "--version") - // .Should() - // .HaveStdOut(SdkInstallerVersion); + // //RunRemoteCommand("dotnet", "--version") + // // .Should() + // // .HaveStdOut(SdkInstallerVersion); - //RunRemoteCommand($@"c:\SdkTesting\{SdkInstallerFileName}", "/quiet", "/uninstall"); + // //RunRemoteCommand($@"c:\SdkTesting\{SdkInstallerFileName}", "/quiet", "/uninstall"); - //new DirectoryInfo($@"\\{TargetMachineName}\c$\Program Files\dotnet\sdk\{SdkInstallerVersion}") - // .Should() - // .NotExist(); + // //new DirectoryInfo($@"\\{TargetMachineName}\c$\Program Files\dotnet\sdk\{SdkInstallerVersion}") + // // .Should() + // // .NotExist(); - //RunRemoteCommand("dotnet", "--version") - // .Should() - // .HaveStdOut("7.0.401"); + // //RunRemoteCommand("dotnet", "--version") + // // .Should() + // // .HaveStdOut("7.0.401"); - } + //} - [Fact] - public void WorkloadInstallation() - { - //CleanupInstallState(); + //[Fact(Skip = "testing")] + //public void WorkloadInstallation() + //{ + // //CleanupInstallState(); - //RunRemoteCommand($@"c:\SdkTesting\{SdkInstallerFileName}", "/quiet"); + // //RunRemoteCommand($@"c:\SdkTesting\{SdkInstallerFileName}", "/quiet"); - //DeployStage2Sdk(); + // //DeployStage2Sdk(); - var rollbackResult = RunRemoteCommand("dotnet", "workload", "update", "--print-rollback"); - rollbackResult.Should().Pass(); - var originalManifests = ParseRollbackOutput(rollbackResult.StdOut); + // var rollbackResult = RunRemoteCommand("dotnet", "workload", "update", "--print-rollback"); + // rollbackResult.Should().Pass(); + // var originalManifests = ParseRollbackOutput(rollbackResult.StdOut); - RunRemoteCommand("dotnet", "workload", "install", "wasm-tools", "--skip-manifest-update"); + // RunRemoteCommand("dotnet", "workload", "install", "wasm-tools", "--skip-manifest-update"); - RunRemoteCommand("dotnet", "workload", "list", "--machine-readable") - .Should() - .HaveStdOutContaining("wasm-tools"); + // RunRemoteCommand("dotnet", "workload", "list", "--machine-readable") + // .Should() + // .HaveStdOutContaining("wasm-tools"); - CheckForDuplicateManifests(); + // CheckForDuplicateManifests(); - File.WriteAllText($@"\\{TargetMachineName}\c$\SdkTesting\rollback-rc1.json", RollbackRC1); + // File.WriteAllText($@"\\{TargetMachineName}\c$\SdkTesting\rollback-rc1.json", RollbackRC1); - RunRemoteCommand("dotnet", "workload", "update", "--from-rollback-file", @"c:\SdkTesting\rollback-rc1.json", "--skip-sign-check"); + // RunRemoteCommand("dotnet", "workload", "update", "--from-rollback-file", @"c:\SdkTesting\rollback-rc1.json", "--skip-sign-check"); - File.WriteAllText($@"\\{TargetMachineName}\c$\SdkTesting\rollback-8.0.101.json", Rollback8_0_101); + // File.WriteAllText($@"\\{TargetMachineName}\c$\SdkTesting\rollback-8.0.101.json", Rollback8_0_101); - RunRemoteCommand("dotnet", "workload", "update", "--from-rollback-file", @"c:\SdkTesting\rollback-8.0.101.json", "--skip-sign-check"); + // RunRemoteCommand("dotnet", "workload", "update", "--from-rollback-file", @"c:\SdkTesting\rollback-8.0.101.json", "--skip-sign-check"); - HashSet<(string id, string version, string featureBand)> expectedManifests = new(); - foreach (var kvp in originalManifests.ManifestVersions.Concat(WorkloadSet.FromJson(Rollback8_0_101, new SdkFeatureBand(SdkInstallerVersion)).ManifestVersions)) - { - expectedManifests.Add((kvp.Key.ToString(), kvp.Value.Version.ToString(), kvp.Value.FeatureBand.ToString())); - } + // HashSet<(string id, string version, string featureBand)> expectedManifests = new(); + // foreach (var kvp in originalManifests.ManifestVersions.Concat(WorkloadSet.FromJson(Rollback8_0_101, new SdkFeatureBand(SdkInstallerVersion)).ManifestVersions)) + // { + // expectedManifests.Add((kvp.Key.ToString(), kvp.Value.Version.ToString(), kvp.Value.FeatureBand.ToString())); + // } - var unexpectedManifests = GetInstalledManifestVersions() - .SelectMany(kvp => kvp.Value.Select(v => (id: kvp.Key, version: v.version, featureBand: v.sdkFeatureBand))) - .Except(expectedManifests); + // var unexpectedManifests = GetInstalledManifestVersions() + // .SelectMany(kvp => kvp.Value.Select(v => (id: kvp.Key, version: v.version, featureBand: v.sdkFeatureBand))) + // .Except(expectedManifests); - if (unexpectedManifests.Any()) - { - Assert.Fail($"Unexpected manifests installed: {string.Join(", ", unexpectedManifests)}"); - } + // if (unexpectedManifests.Any()) + // { + // Assert.Fail($"Unexpected manifests installed: {string.Join(", ", unexpectedManifests)}"); + // } - //CheckForDuplicateManifests(); + // //CheckForDuplicateManifests(); - //RunRemoteCommand($@"c:\SdkTesting\{SdkInstallerFileName}", "/quiet", "/uninstall"); - } + // //RunRemoteCommand($@"c:\SdkTesting\{SdkInstallerFileName}", "/quiet", "/uninstall"); + //} - [Fact] - public void InstallStateShouldBeRemovedOnSdkUninstall() - { - // This is currently broken, needs to be added to the finalizer - throw new NotImplementedException(); - } + //[Fact(Skip = "testing")] + //public void InstallStateShouldBeRemovedOnSdkUninstall() + //{ + // // This is currently broken, needs to be added to the finalizer + // throw new NotImplementedException(); + //} - [Fact] - public void RepeatedUpdateToSameRollbackFile() - { - // Should not install or uninstall anything - } + //[Fact(Skip = "testing")] + //public void RepeatedUpdateToSameRollbackFile() + //{ + // // Should not install or uninstall anything + //} void CleanupInstallState() { diff --git a/src/Tests/dotnet-MsiInstallation.Tests/VMAction.cs b/src/Tests/dotnet-MsiInstallation.Tests/VMAction.cs index 52c270a51708..332934d7dddc 100644 --- a/src/Tests/dotnet-MsiInstallation.Tests/VMAction.cs +++ b/src/Tests/dotnet-MsiInstallation.Tests/VMAction.cs @@ -3,9 +3,11 @@ using System; using System.Collections.Generic; +using System.Diagnostics; using System.Linq; using System.Text; using System.Threading.Tasks; +using Microsoft.DotNet.Cli.Utils; namespace Microsoft.DotNet.MsiInstallerTests { @@ -13,59 +15,126 @@ namespace Microsoft.DotNet.MsiInstallerTests // - Run command // - Copy file to VM // - Enumerate and read files / directories + // - Is this actually an action? // Run command // - Install .NET SDK (From SdkTesting folder) // - Uninstall .NET SDK // - Workload install / uninstall // - Apply rollback file - // - Get .NET version + // - Get .NET version - this shouldn't change state // Copy file to VM // - Deploy stage 2 SDK + enum VMActionType + { + RunCommand, + CopyFileToVM, + WriteFileToVM, + } - internal abstract class VMAction + // Use a single class for all actions to make it easier to serialize + class SerializedVMAction { - public abstract SerializedVMAction Serialize(); + public VMActionType Type { get; set; } - public abstract VMActionResult Run(); + // Applies to RunCommand + public List Arguments { get; set; } - + // Applies to CopyFileToVM, WriteFileToVM + public string TargetPath { get; set; } - } + // Applies to CopyFileToVM + public string SourcePath { get; set; } - class SerializedVMAction - { + // Applies to CopyFileToVM + public string ContentHash { get; set; } - } + // Applies to WriteFileToVM + public string FileContents { get; set; } - class SerializedRunCommand - { - public List Arguments { get; set; } = new List(); + public string GetDescription() + { + switch (Type) + { + case VMActionType.RunCommand: + return $"Run command: {string.Join(" ", Arguments)}"; + case VMActionType.CopyFileToVM: + return $"Copy file to VM: {SourcePath} -> {TargetPath}"; + case VMActionType.WriteFileToVM: + return $"Write file to VM: {TargetPath}"; + default: + throw new NotImplementedException(); + } + } public override bool Equals(object obj) { - if (obj is SerializedRunCommand other) + if (obj is not SerializedVMAction action) + { + return false; + } + + if ((Arguments == null) != (action.Arguments == null)) { - return Arguments.SequenceEqual(other.Arguments); + return false; } - return false; + + if (Arguments != null && !Arguments.SequenceEqual(action.Arguments)) + { + return false; + } + + return Type == action.Type && + TargetPath == action.TargetPath && + SourcePath == action.SourcePath && + ContentHash == action.ContentHash && + FileContents == action.FileContents; } public override int GetHashCode() { var hashcode = new HashCode(); - hashcode.Add(Arguments.Count); - foreach (var arg in Arguments) + hashcode.Add(Type); + if (Arguments != null) { - hashcode.Add(arg.GetHashCode()); + hashcode.Add(Arguments.Count); + foreach (var arg in Arguments) + { + hashcode.Add(arg.GetHashCode()); + } } + hashcode.Add(TargetPath); + hashcode.Add(SourcePath); + hashcode.Add(ContentHash); + hashcode.Add(FileContents); return hashcode.ToHashCode(); } + + public static bool operator ==(SerializedVMAction left, SerializedVMAction right) => EqualityComparer.Default.Equals(left, right); + public static bool operator !=(SerializedVMAction left, SerializedVMAction right) => !(left == right); } class VMActionResult { + public string Filename { get; set; } + public List Arguments { get; set; } + public int ExitCode { get; set; } + public string StdOut { get; set; } + public string StdErr { get; set; } + public CommandResult ToCommandResult() + { + return new CommandResult( + Arguments == null ? null : new ProcessStartInfo + { + FileName = Arguments[0], + // This doesn't handle quoting arguments with spaces correctly, but we don't expect this to be used except for logging + Arguments = string.Join(" ", Arguments.Skip(1)), + }, + ExitCode, + StdOut, + StdErr); + } } } diff --git a/src/Tests/dotnet-MsiInstallation.Tests/VMControl.cs b/src/Tests/dotnet-MsiInstallation.Tests/VMControl.cs index a78d9c070675..789624b25fb0 100644 --- a/src/Tests/dotnet-MsiInstallation.Tests/VMControl.cs +++ b/src/Tests/dotnet-MsiInstallation.Tests/VMControl.cs @@ -17,13 +17,21 @@ namespace Microsoft.DotNet.MsiInstallerTests internal class VMControl : IDisposable { public string VMName { get; set; } = "Windows 11 dev environment"; + public string VMMachineName { get; set; } = "dsp-vm"; + public string PsExecPath = @"C:\Users\Daniel\Downloads\PSTools\PsExec.exe"; const string virtNamespace = @"root\virtualization\v2"; public ITestOutputHelper Log { get; } private CimSession _session; - private CimInstance VMInstance { get; } + private CimInstance VMInstance + { + get + { + return _session.QueryInstances(virtNamespace, "WQL", $"SELECT * FROM Msvm_ComputerSystem WHERE ElementName='{VMName}'").Single(); + } + } public VMControl(ITestOutputHelper log) { @@ -34,10 +42,26 @@ public VMControl(ITestOutputHelper log) Log = log; _session = CimSession.Create(Environment.MachineName); - VMInstance = _session.QueryInstances(virtNamespace, "WQL", $"SELECT * FROM Msvm_ComputerSystem WHERE ElementName='{VMName}'").Single(); + //VMInstance = _session.QueryInstances(virtNamespace, "WQL", $"SELECT * FROM Msvm_ComputerSystem WHERE ElementName='{VMName}'").Single(); } + public CommandResult RunCommandOnVM(params string[] args) + { + var remoteCommand = new RemoteCommand(Log, VMMachineName, PsExecPath, args); + for (int i=0; i<3; i++) + { + var result = remoteCommand.Execute(); + if (result.ExitCode != 6 && !result.StdErr.Contains("The handle is invalid")) + { + return result; + } + Log.WriteLine("PsExec failed, retrying..."); + Thread.Sleep(500); + } + + throw new Exception("PsExec failed"); + } public IEnumerable<(string id, string name)> GetSnapshots() { @@ -63,34 +87,57 @@ private IEnumerable GetSnapshotInstances() public async Task RenameSnapshotAsync(string snapshotId, string newName) { - var snapshots = GetSnapshotInstances(); - var snapshot = snapshots.Single(s => s.CimInstanceProperties["ConfigurationID"].Value.ToString() == snapshotId); - snapshot.CimInstanceProperties["ElementName"].Value = newName; + for (int i = 0; i < 4; i++) + { + try + { + var snapshots = GetSnapshotInstances(); - var managementService = _session.QueryInstances(@"root\virtualization\v2", "WQL", "SELECT * FROM Msvm_VirtualSystemManagementService").Single(); - var modifyVmMethod = managementService.CimClass.CimClassMethods.Single(m => m.Name == "ModifySystemSettings"); - //foreach (var param in modifyVmMethod.Parameters) - //{ - // Log.WriteLine($"{param.Name}: {param.CimType}"); - //} - CimSerializer serializer = CimSerializer.Create(); - var snapshotString = Encoding.Unicode.GetString(serializer.Serialize(snapshot, InstanceSerializationOptions.None)); + var managementService = _session.QueryInstances(@"root\virtualization\v2", "WQL", "SELECT * FROM Msvm_VirtualSystemManagementService").Single(); + var modifyVmMethod = managementService.CimClass.CimClassMethods.Single(m => m.Name == "ModifySystemSettings"); + //foreach (var param in modifyVmMethod.Parameters) + //{ + // Log.WriteLine($"{param.Name}: {param.CimType}"); + //} - CimMethodParametersCollection cimMethodParameters = new CimMethodParametersCollection { - CimMethodParameter.Create("SystemSettings", snapshotString, CimType.String, CimFlags.In) - }; + var snapshot = snapshots.Single(s => s.CimInstanceProperties["ConfigurationID"].Value.ToString() == snapshotId); - var result = _session.InvokeMethod(virtNamespace, managementService, "ModifySystemSettings", cimMethodParameters); + snapshot.CimInstanceProperties["ElementName"].Value = newName; - await WaitForJobSuccess(result); + Log.WriteLine("Renaming snapshot " + snapshotId + " to " + newName); + //foreach (var prop in snapshot.CimInstanceProperties) + //{ + // Log.WriteLine($"\t{prop.Name}: {prop.Value}"); + //} + + CimSerializer serializer = CimSerializer.Create(); + var snapshotString = Encoding.Unicode.GetString(serializer.Serialize(snapshot, InstanceSerializationOptions.None)); + + CimMethodParametersCollection cimMethodParameters = new CimMethodParametersCollection { + CimMethodParameter.Create("SystemSettings", snapshotString, CimType.String, CimFlags.In) + }; + var result = _session.InvokeMethod(virtNamespace, managementService, "ModifySystemSettings", cimMethodParameters); + + await WaitForJobSuccess(result); + return; + } + catch (Exception ex) when (ex.Message.Contains("ErrorCode: 32773") && ex.Message.Contains("The parameter is incorrect. (0x80070057)")) + { + Log.WriteLine("Rename failed: " + ex.Message); + Thread.Sleep(500); + continue; + } + } + Log.WriteLine("Gave up renaming snapshot " + snapshotId + " to " + newName); + } - public async Task CreateSnapshotAsync(string snapshotName) + public async Task CreateSnapshotAsync(string snapshotName) { var existingSnapshots = GetSnapshots().ToDictionary(s => s.id, s => s.name); @@ -104,6 +151,7 @@ public async Task CreateSnapshotAsync(string snapshotName) }; + Log.WriteLine("Creating snapshot " + snapshotName); var result = _session.InvokeMethod(virtNamespace, snapshotService, "CreateSnapshot", cimMethodParameters); @@ -120,10 +168,16 @@ public async Task CreateSnapshotAsync(string snapshotName) var newSnapshot = GetSnapshots().Single(s => !existingSnapshots.ContainsKey(s.id)); - //Log.WriteLine($"Created snapshot {newSnapshot.name} ({newSnapshot.id})"); - await RenameSnapshotAsync(newSnapshot.id, snapshotName); + if (!string.IsNullOrEmpty(snapshotName)) + { + await RenameSnapshotAsync(newSnapshot.id, snapshotName); + } + + Log.WriteLine($"Created snapshot {snapshotName} ({newSnapshot.id})"); + + return newSnapshot.id; } public async Task ApplySnapshotAsync(string snapshotId) @@ -141,6 +195,8 @@ public async Task ApplySnapshotAsync(string snapshotId) CimMethodParameter.Create("Snapshot", snapshot, CimType.Reference, CimFlags.In), }; + Log.WriteLine($"Applying snapshot {snapshot.CimInstanceProperties["ElementName"].Value} ({snapshot.CimInstanceProperties["ConfigurationID"].Value})"); + var result = _session.InvokeMethod(virtNamespace, snapshotService, "ApplySnapshot", cimMethodParameters); await WaitForJobSuccess(result); @@ -150,20 +206,43 @@ public async Task ApplySnapshotAsync(string snapshotId) public async Task SetRunningAsync(bool running) { - bool isAlreadyRunning = (UInt16) VMInstance.CimInstanceProperties["EnabledState"].Value == 2; - if (running == isAlreadyRunning) + VMEnabledState getCurrentState() + { + var state = (VMEnabledState) (UInt16)VMInstance.CimInstanceProperties["EnabledState"].Value; + Log.WriteLine("Current EnabledState: " + state); + return state; + } + + var targetState = running ? VMEnabledState.Enabled : VMEnabledState.Disabled; + + if (getCurrentState() == targetState) { return; } + //bool isAlreadyRunning = getCurrentState() == 2; + //if (running == isAlreadyRunning) + //{ + // return; + //} + + Log.WriteLine("Setting EnabledState to " + targetState); + var methodParameters = new CimMethodParametersCollection() { - CimMethodParameter.Create("RequestedState", (UInt16) (running ? 2 : 4), CimFlags.In) + CimMethodParameter.Create("RequestedState", (UInt16) targetState, CimFlags.In) }; + var result = _session.InvokeMethod(virtNamespace, VMInstance, "RequestStateChange", methodParameters); await WaitForJobSuccess(result); + + for (int i = 0; i < 10 && getCurrentState() != targetState; i++) + { + Log.WriteLine("Waiting for state change..."); + await Task.Delay(250); + } } private static bool IsRunning(JobState jobState) @@ -186,7 +265,23 @@ private async Task WaitForJobSuccess(CimMethodResult result) var jobState = (JobState)(UInt16)job.CimInstanceProperties["JobState"].Value; if (jobState != JobState.Completed && jobState != JobState.CompletedWithWarnings) { - throw new Exception("Job failed"); + Log.WriteLine("Job failed: " + jobState); + //foreach (var prop in job.CimInstanceProperties) + //{ + // Log.WriteLine($"\t{prop.Name}: {prop.Value}"); + //} + + string exceptionText = "Job failed: " + jobState; + + try + { + exceptionText += Environment.NewLine + + "ErrorCode: " + job.CimInstanceProperties["ErrorCode"].Value + Environment.NewLine + + "ErrorDescription: " + job.CimInstanceProperties["ErrorDescription"].Value; + } + catch { } + + throw new Exception(exceptionText); } } else @@ -225,31 +320,106 @@ enum JobState CompletedWithWarnings = 32768 } + enum VMEnabledState : UInt16 + { + Unknown = 0, + Other = 1, + Enabled = 2, + Disabled = 3, + ShuttingDown = 4, + NotApplicable = 5, + EnabledButOffline = 6, + //NoContact = 7, + //LostCommunication = 8, + //DisabledNoRedundancy = 9, + //InTest = 10, + //Deferred = 11, + //Quiesce = 12, + //Starting = 13, + //Snapshotting = 14, + //Saving = 15, + //Stopping = 16, + //Pausing = 17, + //Resuming = 18, + //FastSnapshotting = 19, + //FastSaving = 20, + //StartingUp = 21, + //PoweringDown = 22, + //PoweringUp = 23, + //SavingState = 24, + //RestoringState = 25, + //Paused = 26, + //Resumed = 27, + //Suspended = 28, + //StartingUpService = 29, + //UndoingSnapshot = 30, + //ImportingSnapshot = 31, + //ExportingSnapshot = 32, + //MergingSnapshot = 33, + //RemovingSnapshot = 34, + //ApplyingSnapshot = 35, + //Killing = 36, + //StoppingService = 37, + //SuspendedWithSavedState = 38, + //StartingUpWithSavedState = 39, + //InService = 40, + //NoRecovery = 41, + //Last = 42 + } - private class CimObserver : IObserver + //private class CimObserver : IObserver + //{ + // TaskCompletionSource _tcs; + // Management.Infrastructure.Generic.CimAsyncResult _result; + + // public Task Task => _tcs.Task; + + // public CimObserver(Management.Infrastructure.Generic.CimAsyncResult result) + // { + // _tcs = new TaskCompletionSource(); + // _result = result; + // _result.Subscribe(this); + // } + + // public void OnCompleted() + // { + // } + // public void OnError(Exception error) + // { + // _tcs.SetException(error); + // } + // public void OnNext(T value) + // { + // _tcs.SetResult(value); + // } + //} + + class RemoteCommand : TestCommand { - TaskCompletionSource _tcs; - Management.Infrastructure.Generic.CimAsyncResult _result; + string _targetMachineName; + string _psExecPath; - public Task Task => _tcs.Task; - public CimObserver(Management.Infrastructure.Generic.CimAsyncResult result) + public RemoteCommand(ITestOutputHelper log, string targetMachineName, string psExecPath, params string[] args) + : base(log) { - _tcs = new TaskCompletionSource(); - _result = result; - _result.Subscribe(this); - } + _targetMachineName = targetMachineName; + _psExecPath = psExecPath; - public void OnCompleted() - { + Arguments.Add("-nobanner"); + Arguments.Add($@"\\{_targetMachineName}"); + Arguments.AddRange(args); } - public void OnError(Exception error) - { - _tcs.SetException(error); - } - public void OnNext(T value) + + protected override SdkCommandSpec CreateCommand(IEnumerable args) { - _tcs.SetResult(value); + var sdkCommandSpec = new SdkCommandSpec() + { + FileName = _psExecPath, + Arguments = args.ToList(), + WorkingDirectory = WorkingDirectory, + }; + return sdkCommandSpec; } } diff --git a/src/Tests/dotnet-MsiInstallation.Tests/VMStateTree.cs b/src/Tests/dotnet-MsiInstallation.Tests/VMStateTree.cs index fb37397f2cef..d79f91ad679f 100644 --- a/src/Tests/dotnet-MsiInstallation.Tests/VMStateTree.cs +++ b/src/Tests/dotnet-MsiInstallation.Tests/VMStateTree.cs @@ -14,6 +14,6 @@ internal class VMStateTree public string SnapshotId { get; set; } public string SnapshotName { get; set; } - public Dictionary Actions { get; set; } + public Dictionary Actions { get; set; } = new(); } } diff --git a/src/Tests/dotnet-MsiInstallation.Tests/VirtualMachine.cs b/src/Tests/dotnet-MsiInstallation.Tests/VirtualMachine.cs index e18f83688a7d..87063b540ea6 100644 --- a/src/Tests/dotnet-MsiInstallation.Tests/VirtualMachine.cs +++ b/src/Tests/dotnet-MsiInstallation.Tests/VirtualMachine.cs @@ -3,6 +3,7 @@ using System; using System.Collections.Generic; +using System.Diagnostics; using System.Linq; using System.Text; using System.Threading.Tasks; @@ -13,11 +14,32 @@ namespace Microsoft.DotNet.MsiInstallerTests internal class VirtualMachine : IDisposable { ITestOutputHelper Log { get; } - VMControl VMControl { get; } + public VMControl VMControl { get; } + + static VMStateTree _rootState; + VMStateTree _currentState; + VMStateTree _currentAppliedState; + public VirtualMachine(ITestOutputHelper log) { Log = log; VMControl = new VMControl(log); + + // TODO: Load root state from file + + if (_rootState == null) + { + _rootState = new VMStateTree() + { + SnapshotId = "60667B5C-EC88-430E-8C69-5E4214123941", + SnapshotName = "Updated expired password, enabled Remote Management", + }; + } + + _currentState = _rootState; + + VMControl.ApplySnapshotAsync(_currentState.SnapshotId).Wait(); + _currentAppliedState = _currentState; } public void Dispose() { @@ -26,7 +48,20 @@ public void Dispose() public CommandResult RunCommand(params string[] args) { - throw new NotImplementedException(); + if (args.Length == 0) + { + throw new ArgumentException("Must provide at least one argument", nameof(args)); + } + + var action = new SerializedVMAction + { + Type = VMActionType.RunCommand, + Arguments = args.ToList(), + }; + + var vmActionResult = Apply(action); + + return vmActionResult.ToCommandResult(); } public void CopyFile(string localSource, string vmDestination) @@ -36,7 +71,16 @@ public void CopyFile(string localSource, string vmDestination) public void WriteFile(string vmDestination, string contents) { - throw new NotImplementedException(); + var action = new SerializedVMAction + { + Type = VMActionType.WriteFileToVM, + TargetPath = vmDestination, + FileContents = contents, + }; + + var vmActionResult = Apply(action); + + vmActionResult.ToCommandResult().Should().Pass(); } public RemoteDirectory GetRemoteDirectory(string path) @@ -44,5 +88,94 @@ public RemoteDirectory GetRemoteDirectory(string path) throw new NotImplementedException(); } + VMActionResult Apply(SerializedVMAction action) + { + if (_currentState.Actions.TryGetValue(action, out var result)) + { + _currentState = result.resultingState; + return result.actionResult; + } + + if (_currentAppliedState != _currentState) + { + VMControl.ApplySnapshotAsync(_currentState.SnapshotId).Wait(); + } + + var actionResult = Run(action); + + string actionDescription = action.GetDescription(); + + string newSnapshotId = VMControl.CreateSnapshotAsync(actionDescription).Result; + + var resultingState = new VMStateTree + { + SnapshotId = newSnapshotId, + SnapshotName = actionDescription, + }; + + _currentState.Actions[action] = (actionResult, resultingState); + _currentState = resultingState; + _currentAppliedState = resultingState; + + return actionResult; + } + + VMActionResult Run(SerializedVMAction action) + { + if (action.Type == VMActionType.RunCommand) + { + var result = VMControl.RunCommandOnVM(action.Arguments.ToArray()); + return new VMActionResult + { + Filename = action.Arguments[0], + Arguments = action.Arguments.Skip(1).ToList(), + ExitCode = result.ExitCode, + StdOut = result.StdOut, + StdErr = result.StdErr, + }; + } + else if (action.Type == VMActionType.CopyFileToVM) + { + throw new NotImplementedException(); + } + else if (action.Type == VMActionType.WriteFileToVM) + { + var targetSharePath = VMPathToSharePath(action.TargetPath); + if (!Directory.Exists(Path.GetDirectoryName(targetSharePath))) + { + Directory.CreateDirectory(Path.GetDirectoryName(targetSharePath)); + } + + File.WriteAllText(targetSharePath, action.FileContents); + + return new VMActionResult + { + ExitCode = 0, + StdOut = "", + StdErr = "", + }; + } + else + { + throw new NotImplementedException(); + } + } + + string VMPathToSharePath(string vmPath) + { + var dirInfo = new DirectoryInfo(vmPath); + + if (dirInfo.Root.FullName.Substring(1) != @":\") + { + throw new ArgumentException("Unrecognized directory root for: " + vmPath, nameof(vmPath)); + } + + string driveLetter = dirInfo.Root.FullName.Substring(0, 1); + + string pathUnderDrive = dirInfo.FullName.Substring(3); + + return $@"\\{VMControl.VMMachineName}\{driveLetter}$\{pathUnderDrive}"; + + } } } From 95ed966c52d2b33ec17dbf2d74a3a7c356048d13 Mon Sep 17 00:00:00 2001 From: Daniel Plaisted Date: Wed, 31 Jan 2024 17:20:05 -0500 Subject: [PATCH 386/577] WIP --- .../MsiInstallerTests.cs | 4 +- .../dotnet-MsiInstallation.Tests/VMAction.cs | 2 +- .../dotnet-MsiInstallation.Tests/VMControl.cs | 72 ++++++++----------- 3 files changed, 32 insertions(+), 46 deletions(-) diff --git a/src/Tests/dotnet-MsiInstallation.Tests/MsiInstallerTests.cs b/src/Tests/dotnet-MsiInstallation.Tests/MsiInstallerTests.cs index e77e4b7c49d7..4b719728f432 100644 --- a/src/Tests/dotnet-MsiInstallation.Tests/MsiInstallerTests.cs +++ b/src/Tests/dotnet-MsiInstallation.Tests/MsiInstallerTests.cs @@ -116,7 +116,7 @@ public void InstallAndroid() VM.WriteFile($@"C:\SdkTesting\rollback-rc1.json", RollbackRC1); VM.RunCommand("dotnet", "workload", "update", "--from-rollback-file", @"c:\SdkTesting\rollback-rc1.json", "--skip-sign-check"); - VM.RunCommand("dotnet", "workload", "install", "Android", "--skip-manifest-update") + VM.RunCommand("dotnet", "workload", "install", "android", "--skip-manifest-update") .Should() .Pass(); } @@ -129,7 +129,7 @@ public void InstallAndroidAndWasm() VM.WriteFile($@"C:\SdkTesting\rollback-rc1.json", RollbackRC1); VM.RunCommand("dotnet", "workload", "update", "--from-rollback-file", @"c:\SdkTesting\rollback-rc1.json", "--skip-sign-check"); - VM.RunCommand("dotnet", "workload", "install", "Android", "--skip-manifest-update") + VM.RunCommand("dotnet", "workload", "install", "android", "--skip-manifest-update") .Should() .Pass(); diff --git a/src/Tests/dotnet-MsiInstallation.Tests/VMAction.cs b/src/Tests/dotnet-MsiInstallation.Tests/VMAction.cs index 332934d7dddc..5375223bfffa 100644 --- a/src/Tests/dotnet-MsiInstallation.Tests/VMAction.cs +++ b/src/Tests/dotnet-MsiInstallation.Tests/VMAction.cs @@ -58,7 +58,7 @@ public string GetDescription() switch (Type) { case VMActionType.RunCommand: - return $"Run command: {string.Join(" ", Arguments)}"; + return $"Run: {string.Join(" ", Arguments)}"; case VMActionType.CopyFileToVM: return $"Copy file to VM: {SourcePath} -> {TargetPath}"; case VMActionType.WriteFileToVM: diff --git a/src/Tests/dotnet-MsiInstallation.Tests/VMControl.cs b/src/Tests/dotnet-MsiInstallation.Tests/VMControl.cs index 789624b25fb0..e99861fa37a3 100644 --- a/src/Tests/dotnet-MsiInstallation.Tests/VMControl.cs +++ b/src/Tests/dotnet-MsiInstallation.Tests/VMControl.cs @@ -27,10 +27,10 @@ internal class VMControl : IDisposable private CimSession _session; private CimInstance VMInstance { - get - { - return _session.QueryInstances(virtNamespace, "WQL", $"SELECT * FROM Msvm_ComputerSystem WHERE ElementName='{VMName}'").Single(); - } + get; + //{ + // return _session.QueryInstances(virtNamespace, "WQL", $"SELECT * FROM Msvm_ComputerSystem WHERE ElementName='{VMName}'").Single(); + //} } public VMControl(ITestOutputHelper log) @@ -42,7 +42,7 @@ public VMControl(ITestOutputHelper log) Log = log; _session = CimSession.Create(Environment.MachineName); - //VMInstance = _session.QueryInstances(virtNamespace, "WQL", $"SELECT * FROM Msvm_ComputerSystem WHERE ElementName='{VMName}'").Single(); + VMInstance = _session.QueryInstances(virtNamespace, "WQL", $"SELECT * FROM Msvm_ComputerSystem WHERE ElementName='{VMName}'").Single(); } public CommandResult RunCommandOnVM(params string[] args) @@ -87,54 +87,40 @@ private IEnumerable GetSnapshotInstances() public async Task RenameSnapshotAsync(string snapshotId, string newName) { - - - - for (int i = 0; i < 4; i++) + if (newName.Length >= 100) { - try - { - var snapshots = GetSnapshotInstances(); + newName = newName.Substring(0, 96) + "..."; + } + var snapshots = GetSnapshotInstances(); - var managementService = _session.QueryInstances(@"root\virtualization\v2", "WQL", "SELECT * FROM Msvm_VirtualSystemManagementService").Single(); - var modifyVmMethod = managementService.CimClass.CimClassMethods.Single(m => m.Name == "ModifySystemSettings"); - //foreach (var param in modifyVmMethod.Parameters) - //{ - // Log.WriteLine($"{param.Name}: {param.CimType}"); - //} + var managementService = _session.QueryInstances(@"root\virtualization\v2", "WQL", "SELECT * FROM Msvm_VirtualSystemManagementService").Single(); + var modifyVmMethod = managementService.CimClass.CimClassMethods.Single(m => m.Name == "ModifySystemSettings"); + //foreach (var param in modifyVmMethod.Parameters) + //{ + // Log.WriteLine($"{param.Name}: {param.CimType}"); + //} - var snapshot = snapshots.Single(s => s.CimInstanceProperties["ConfigurationID"].Value.ToString() == snapshotId); + var snapshot = snapshots.Single(s => s.CimInstanceProperties["ConfigurationID"].Value.ToString() == snapshotId); - snapshot.CimInstanceProperties["ElementName"].Value = newName; + snapshot.CimInstanceProperties["ElementName"].Value = newName; - Log.WriteLine("Renaming snapshot " + snapshotId + " to " + newName); - //foreach (var prop in snapshot.CimInstanceProperties) - //{ - // Log.WriteLine($"\t{prop.Name}: {prop.Value}"); - //} + Log.WriteLine("Renaming snapshot " + snapshotId + " to " + newName); + //foreach (var prop in snapshot.CimInstanceProperties) + //{ + // Log.WriteLine($"\t{prop.Name}: {prop.Value}"); + //} - CimSerializer serializer = CimSerializer.Create(); - var snapshotString = Encoding.Unicode.GetString(serializer.Serialize(snapshot, InstanceSerializationOptions.None)); + CimSerializer serializer = CimSerializer.Create(); + var snapshotString = Encoding.Unicode.GetString(serializer.Serialize(snapshot, InstanceSerializationOptions.None)); - CimMethodParametersCollection cimMethodParameters = new CimMethodParametersCollection { - CimMethodParameter.Create("SystemSettings", snapshotString, CimType.String, CimFlags.In) - }; + CimMethodParametersCollection cimMethodParameters = new CimMethodParametersCollection { + CimMethodParameter.Create("SystemSettings", snapshotString, CimType.String, CimFlags.In) + }; - var result = _session.InvokeMethod(virtNamespace, managementService, "ModifySystemSettings", cimMethodParameters); + var result = _session.InvokeMethod(virtNamespace, managementService, "ModifySystemSettings", cimMethodParameters); - await WaitForJobSuccess(result); - return; - } - catch (Exception ex) when (ex.Message.Contains("ErrorCode: 32773") && ex.Message.Contains("The parameter is incorrect. (0x80070057)")) - { - Log.WriteLine("Rename failed: " + ex.Message); - Thread.Sleep(500); - continue; - } - } - Log.WriteLine("Gave up renaming snapshot " + snapshotId + " to " + newName); - + await WaitForJobSuccess(result); } public async Task CreateSnapshotAsync(string snapshotName) From 7c0c393808eb96083aad8e51466a8bc3c1935147 Mon Sep 17 00:00:00 2001 From: Daniel Plaisted Date: Fri, 2 Feb 2024 09:58:47 -0500 Subject: [PATCH 387/577] WIP --- .../dotnet-MsiInstallation.Tests/VMAction.cs | 28 ++++- .../dotnet-MsiInstallation.Tests/VMControl.cs | 12 +- .../VMStateTree.cs | 47 +++++++ .../VirtualMachine.cs | 116 ++++++++++++++++-- 4 files changed, 179 insertions(+), 24 deletions(-) diff --git a/src/Tests/dotnet-MsiInstallation.Tests/VMAction.cs b/src/Tests/dotnet-MsiInstallation.Tests/VMAction.cs index 5375223bfffa..c153604ef0cb 100644 --- a/src/Tests/dotnet-MsiInstallation.Tests/VMAction.cs +++ b/src/Tests/dotnet-MsiInstallation.Tests/VMAction.cs @@ -30,6 +30,7 @@ enum VMActionType { RunCommand, CopyFileToVM, + CopyFolderToVM, WriteFileToVM, } @@ -41,14 +42,17 @@ class SerializedVMAction // Applies to RunCommand public List Arguments { get; set; } - // Applies to CopyFileToVM, WriteFileToVM + // Applies to CopyFileToVM, CopyFolderToVM, WriteFileToVM public string TargetPath { get; set; } - // Applies to CopyFileToVM + // Applies to CopyFileToVM, CopyFolderToVM public string SourcePath { get; set; } - // Applies to CopyFileToVM - public string ContentHash { get; set; } + // Applies to CopyFileToVM, CopyFolderToVM + /// + /// Identifier for the contents of the file or folder to copy. This could be a hash, but for our purposes a combination of the file size and last modified time should work. + /// + public string ContentId { get; set; } // Applies to WriteFileToVM public string FileContents { get; set; } @@ -61,6 +65,8 @@ public string GetDescription() return $"Run: {string.Join(" ", Arguments)}"; case VMActionType.CopyFileToVM: return $"Copy file to VM: {SourcePath} -> {TargetPath}"; + case VMActionType.CopyFolderToVM: + return $"Copy folder to VM: {SourcePath} -> {TargetPath}"; case VMActionType.WriteFileToVM: return $"Write file to VM: {TargetPath}"; default: @@ -88,7 +94,7 @@ public override bool Equals(object obj) return Type == action.Type && TargetPath == action.TargetPath && SourcePath == action.SourcePath && - ContentHash == action.ContentHash && + ContentId == action.ContentId && FileContents == action.FileContents; } @@ -106,7 +112,7 @@ public override int GetHashCode() } hashcode.Add(TargetPath); hashcode.Add(SourcePath); - hashcode.Add(ContentHash); + hashcode.Add(ContentId); hashcode.Add(FileContents); return hashcode.ToHashCode(); } @@ -136,5 +142,15 @@ public CommandResult ToCommandResult() StdOut, StdErr); } + + public static VMActionResult Success() + { + return new VMActionResult + { + ExitCode = 0, + StdOut = "", + StdErr = "", + }; + } } } diff --git a/src/Tests/dotnet-MsiInstallation.Tests/VMControl.cs b/src/Tests/dotnet-MsiInstallation.Tests/VMControl.cs index e99861fa37a3..f6c18ef62602 100644 --- a/src/Tests/dotnet-MsiInstallation.Tests/VMControl.cs +++ b/src/Tests/dotnet-MsiInstallation.Tests/VMControl.cs @@ -27,10 +27,11 @@ internal class VMControl : IDisposable private CimSession _session; private CimInstance VMInstance { - get; - //{ - // return _session.QueryInstances(virtNamespace, "WQL", $"SELECT * FROM Msvm_ComputerSystem WHERE ElementName='{VMName}'").Single(); - //} + get + { + // Query WMI for the VM instance each time so that the state is always up to date + return _session.QueryInstances(virtNamespace, "WQL", $"SELECT * FROM Msvm_ComputerSystem WHERE ElementName='{VMName}'").Single(); + } } public VMControl(ITestOutputHelper log) @@ -42,7 +43,6 @@ public VMControl(ITestOutputHelper log) Log = log; _session = CimSession.Create(Environment.MachineName); - VMInstance = _session.QueryInstances(virtNamespace, "WQL", $"SELECT * FROM Msvm_ComputerSystem WHERE ElementName='{VMName}'").Single(); } public CommandResult RunCommandOnVM(params string[] args) @@ -60,7 +60,7 @@ public CommandResult RunCommandOnVM(params string[] args) Thread.Sleep(500); } - throw new Exception("PsExec failed"); + throw new Exception(@$"PsExec failed, make sure VM is running and can be accessed via \\{VMMachineName}"); } public IEnumerable<(string id, string name)> GetSnapshots() diff --git a/src/Tests/dotnet-MsiInstallation.Tests/VMStateTree.cs b/src/Tests/dotnet-MsiInstallation.Tests/VMStateTree.cs index d79f91ad679f..4b2bda1285f7 100644 --- a/src/Tests/dotnet-MsiInstallation.Tests/VMStateTree.cs +++ b/src/Tests/dotnet-MsiInstallation.Tests/VMStateTree.cs @@ -15,5 +15,52 @@ internal class VMStateTree public string SnapshotName { get; set; } public Dictionary Actions { get; set; } = new(); + + public SerializeableVMStateTree ToSerializeable() + { + return new SerializeableVMStateTree() + { + SnapshotId = SnapshotId, + SnapshotName = SnapshotName, + Actions = Actions.Select(a => new SerializeableVMStateTree.Entry() { + Action = a.Key, + ActionResult = a.Value.actionResult, + ResultingState = a.Value.resultingState.ToSerializeable() + }) + .ToList() + }; + } + } + + internal class SerializeableVMStateTree + { + public string SnapshotId { get; set; } + public string SnapshotName { get; set; } + + public List Actions { get; set; } + + + public class Entry + { + public SerializedVMAction Action { get; set; } + public VMActionResult ActionResult { get; set; } + public SerializeableVMStateTree ResultingState { get; set; } + } + + public VMStateTree ToVMStateTree() + { + var tree = new VMStateTree() + { + SnapshotId = SnapshotId, + SnapshotName = SnapshotName, + }; + + foreach (var entry in Actions) + { + tree.Actions.Add(entry.Action, (entry.ActionResult, entry.ResultingState.ToVMStateTree())); + } + + return tree; + } } } diff --git a/src/Tests/dotnet-MsiInstallation.Tests/VirtualMachine.cs b/src/Tests/dotnet-MsiInstallation.Tests/VirtualMachine.cs index 87063b540ea6..df4c462e440a 100644 --- a/src/Tests/dotnet-MsiInstallation.Tests/VirtualMachine.cs +++ b/src/Tests/dotnet-MsiInstallation.Tests/VirtualMachine.cs @@ -6,6 +6,8 @@ using System.Diagnostics; using System.Linq; using System.Text; +using System.Text.Json; +using System.Text.Json.Serialization; using System.Threading.Tasks; using Microsoft.DotNet.Cli.Utils; @@ -20,20 +22,31 @@ internal class VirtualMachine : IDisposable VMStateTree _currentState; VMStateTree _currentAppliedState; + string _stateFile; + public VirtualMachine(ITestOutputHelper log) { Log = log; VMControl = new VMControl(log); - // TODO: Load root state from file + _stateFile = Path.Combine(Environment.CurrentDirectory, "vmstate.json"); - if (_rootState == null) + // Load root state from file, if it exists + if (File.Exists(_stateFile)) + { + string json = File.ReadAllText(_stateFile); + _rootState = JsonSerializer.Deserialize(json, GetSerializerOptions()).ToVMStateTree(); + } + else { - _rootState = new VMStateTree() + if (_rootState == null) { - SnapshotId = "60667B5C-EC88-430E-8C69-5E4214123941", - SnapshotName = "Updated expired password, enabled Remote Management", - }; + _rootState = new VMStateTree() + { + SnapshotId = "60667B5C-EC88-430E-8C69-5E4214123941", + SnapshotName = "Updated expired password, enabled Remote Management", + }; + } } _currentState = _rootState; @@ -43,9 +56,22 @@ public VirtualMachine(ITestOutputHelper log) } public void Dispose() { + string json = JsonSerializer.Serialize(_rootState.ToSerializeable(), GetSerializerOptions()); + File.WriteAllText(_stateFile, json); + VMControl.Dispose(); } + JsonSerializerOptions GetSerializerOptions() + { + return new JsonSerializerOptions() + { + WriteIndented = true, + DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull, + Converters = { new JsonStringEnumConverter() } + }; + } + public CommandResult RunCommand(params string[] args) { if (args.Length == 0) @@ -69,6 +95,21 @@ public void CopyFile(string localSource, string vmDestination) throw new NotImplementedException(); } + public void CopyFolder(string localSource, string vmDestination) + { + var action = new SerializedVMAction + { + Type = VMActionType.CopyFolderToVM, + SourcePath = localSource, + TargetPath = vmDestination, + ContentId = GetDirectoryContentId(localSource), + }; + + var vmActionResult = Apply(action); + + vmActionResult.ToCommandResult().Should().Pass(); + } + public void WriteFile(string vmDestination, string contents) { var action = new SerializedVMAction @@ -138,6 +179,14 @@ VMActionResult Run(SerializedVMAction action) { throw new NotImplementedException(); } + else if (action.Type == VMActionType.CopyFolderToVM) + { + var targetSharePath = VMPathToSharePath(action.TargetPath); + + CopyDirectory(action.SourcePath, targetSharePath); + + return VMActionResult.Success(); + } else if (action.Type == VMActionType.WriteFileToVM) { var targetSharePath = VMPathToSharePath(action.TargetPath); @@ -148,12 +197,7 @@ VMActionResult Run(SerializedVMAction action) File.WriteAllText(targetSharePath, action.FileContents); - return new VMActionResult - { - ExitCode = 0, - StdOut = "", - StdErr = "", - }; + return VMActionResult.Success(); } else { @@ -161,6 +205,54 @@ VMActionResult Run(SerializedVMAction action) } } + string GetFileContentId(string path) + { + var info = new FileInfo(path); + return $"{info.LastWriteTimeUtc.Ticks}-{info.Length}"; + } + + string GetDirectoryContentId(string path) + { + StringBuilder sb = new StringBuilder(); + var info = new DirectoryInfo(path); + + void ProcessDirectory(DirectoryInfo dir, string relativeTo) + { + foreach (var file in dir.GetFiles()) + { + sb.AppendLine($"{Path.GetRelativePath(relativeTo, file.FullName)}:{file.LastWriteTimeUtc.Ticks}-{file.Length}"); + } + + foreach (var subDir in dir.GetDirectories()) + { + sb.AppendLine(subDir.FullName); + ProcessDirectory(subDir, relativeTo); + } + } + + ProcessDirectory(info, path); + + return sb.ToString(); + } + + static void CopyDirectory(string sourcePath, string destPath) + { + if (!Directory.Exists(destPath)) + { + Directory.CreateDirectory(destPath); + } + + foreach (var dir in Directory.GetDirectories(sourcePath)) + { + CopyDirectory(dir, Path.Combine(destPath, Path.GetFileName(dir))); + } + + foreach (var file in Directory.GetFiles(sourcePath)) + { + new FileInfo(file).CopyTo(Path.Combine(destPath, Path.GetFileName(file)), true); + } + } + string VMPathToSharePath(string vmPath) { var dirInfo = new DirectoryInfo(vmPath); From 1559a39c7871bac0c4b7c9aef92e156241b8f9d0 Mon Sep 17 00:00:00 2001 From: Daniel Plaisted Date: Fri, 2 Feb 2024 16:24:32 -0500 Subject: [PATCH 388/577] WIP --- .../MsiInstallerTests.cs | 33 ++--- .../RemoteFile.cs | 9 +- .../dotnet-MsiInstallation.Tests/VMAction.cs | 46 +++++-- .../dotnet-MsiInstallation.Tests/VMControl.cs | 19 ++- .../VirtualMachine.cs | 130 ++++++++++++++++-- 5 files changed, 189 insertions(+), 48 deletions(-) diff --git a/src/Tests/dotnet-MsiInstallation.Tests/MsiInstallerTests.cs b/src/Tests/dotnet-MsiInstallation.Tests/MsiInstallerTests.cs index 4b719728f432..43d13a63d22e 100644 --- a/src/Tests/dotnet-MsiInstallation.Tests/MsiInstallerTests.cs +++ b/src/Tests/dotnet-MsiInstallation.Tests/MsiInstallerTests.cs @@ -93,6 +93,8 @@ public void InstallSdk() VM.RunCommand($@"c:\SdkTesting\{SdkInstallerFileName}", "/quiet") .Should() .Pass(); + + DeployStage2Sdk(); } [Fact] @@ -150,8 +152,6 @@ public async Task UseWMI() //await vm.RenameSnapshot(snapshot.id, snapshot.name + " - renamed"); } - await VM.VMControl.RenameSnapshotAsync("D258F2C9-F4BE-47F7-8D9C-DF5D955B84BC", "Can I rename this?"); - //await VM.CreateSnapshotAsync("New test snapshot"); //await VM.ApplySnapshotAsync("9BA74A78-D221-436E-9875-0A3BF86CEF4A"); @@ -366,30 +366,19 @@ void DeployStage2Sdk() { Log.WriteLine(TestContext.Current.ToolsetUnderTest.SdkFolderUnderTest); - - var existingSdkFolder = $@"\\dsp-vm\c$\Program Files\dotnet\sdk\{SdkInstallerVersion}"; - //var targetSdkFolder = $@"\\dsp-vm\c$\Program Files\dotnet\sdk\{TestContext.Current.ToolsetUnderTest.SdkVersion}"; - var targetSdkFolder = existingSdkFolder; - var backupSdkFolder = $@"\\dsp-vm\c$\SdkTesting\backup\{SdkInstallerVersion}"; + var installedSdkFolder = $@"c:\Program Files\dotnet\sdk\{SdkInstallerVersion}"; - var existingVersionFileContents = File.ReadAllLines(Path.Combine(existingSdkFolder, ".version")); + var vmVersionFilePath = Path.Combine(installedSdkFolder, ".version"); - if (!Directory.Exists(backupSdkFolder)) - { - Directory.CreateDirectory(Path.GetDirectoryName(backupSdkFolder)); - Directory.Move(existingSdkFolder, backupSdkFolder); - } - else if (Directory.Exists(targetSdkFolder)) + var existingVersionFileContents = VM.GetRemoteFile(vmVersionFilePath).ReadAllText().Split(Environment.NewLine); + var newVersionFileContents = File.ReadAllLines(Path.Combine(TestContext.Current.ToolsetUnderTest.SdkFolderUnderTest, ".version")); + newVersionFileContents[1] = existingVersionFileContents[1]; + + using (var group = VM.CreateActionGroup("Deploy Stage 2 SDK")) { - Directory.Delete(targetSdkFolder, true); + group.CopyFolder(TestContext.Current.ToolsetUnderTest.SdkFolderUnderTest, installedSdkFolder); + group.WriteFile(vmVersionFilePath, string.Join(Environment.NewLine, newVersionFileContents)); } - - CopyDirectory(TestContext.Current.ToolsetUnderTest.SdkFolderUnderTest, targetSdkFolder); - - var newVersionFileContents = File.ReadAllLines(Path.Combine(targetSdkFolder, ".version")); - // Change feature band for deployed SDK to match MSI installation version - newVersionFileContents[1] = existingVersionFileContents[1]; - File.WriteAllLines(Path.Combine(targetSdkFolder, ".version"), newVersionFileContents); } WorkloadSet ParseRollbackOutput(string output) diff --git a/src/Tests/dotnet-MsiInstallation.Tests/RemoteFile.cs b/src/Tests/dotnet-MsiInstallation.Tests/RemoteFile.cs index 54c48272db28..304bed4d2f7d 100644 --- a/src/Tests/dotnet-MsiInstallation.Tests/RemoteFile.cs +++ b/src/Tests/dotnet-MsiInstallation.Tests/RemoteFile.cs @@ -9,8 +9,15 @@ namespace Microsoft.DotNet.MsiInstallerTests { - internal class RemoteFile + abstract class RemoteFile { + public RemoteFile(string path) + { + Path = path; + } + public string Path { get; } + + public abstract string ReadAllText(); } } diff --git a/src/Tests/dotnet-MsiInstallation.Tests/VMAction.cs b/src/Tests/dotnet-MsiInstallation.Tests/VMAction.cs index c153604ef0cb..c785ea5ae7bb 100644 --- a/src/Tests/dotnet-MsiInstallation.Tests/VMAction.cs +++ b/src/Tests/dotnet-MsiInstallation.Tests/VMAction.cs @@ -5,6 +5,7 @@ using System.Collections.Generic; using System.Diagnostics; using System.Linq; +using System.Runtime.CompilerServices; using System.Text; using System.Threading.Tasks; using Microsoft.DotNet.Cli.Utils; @@ -32,6 +33,8 @@ enum VMActionType CopyFileToVM, CopyFolderToVM, WriteFileToVM, + // Used to combine multiple actions into a single action, so they don't get snapshotted separately + ActionGroup, } // Use a single class for all actions to make it easier to serialize @@ -39,6 +42,8 @@ class SerializedVMAction { public VMActionType Type { get; set; } + public string ExplicitDescription { get; set; } + // Applies to RunCommand public List Arguments { get; set; } @@ -57,8 +62,15 @@ class SerializedVMAction // Applies to WriteFileToVM public string FileContents { get; set; } + // Applies to ActionGroup + public List Actions { get; set; } + public string GetDescription() { + if (!string.IsNullOrEmpty(ExplicitDescription)) + { + return ExplicitDescription; + } switch (Type) { case VMActionType.RunCommand: @@ -69,6 +81,8 @@ public string GetDescription() return $"Copy folder to VM: {SourcePath} -> {TargetPath}"; case VMActionType.WriteFileToVM: return $"Write file to VM: {TargetPath}"; + case VMActionType.ActionGroup: + return $"Action group: {string.Join(", ", Actions.Select(a => a.GetDescription()))}"; default: throw new NotImplementedException(); } @@ -81,21 +95,27 @@ public override bool Equals(object obj) return false; } - if ((Arguments == null) != (action.Arguments == null)) + static bool ListsAreEqual(List a, List b) { - return false; - } - - if (Arguments != null && !Arguments.SequenceEqual(action.Arguments)) - { - return false; + if (a == null && b == null) + { + return true; + } + if (a == null || b == null) + { + return false; + } + return a.SequenceEqual(b); } return Type == action.Type && + ExplicitDescription == action.ExplicitDescription && + ListsAreEqual(Arguments, action.Arguments) && TargetPath == action.TargetPath && SourcePath == action.SourcePath && ContentId == action.ContentId && - FileContents == action.FileContents; + FileContents == action.FileContents && + ListsAreEqual(Actions, action.Actions); } public override int GetHashCode() @@ -153,4 +173,14 @@ public static VMActionResult Success() }; } } + + interface IVMActionGroup : IDisposable + { + void RunCommand(params string[] args); + void CopyFile(string localSource, string vmDestination); + + void CopyFolder(string localSource, string vmDestination); + + void WriteFile(string vmDestination, string contents); + } } diff --git a/src/Tests/dotnet-MsiInstallation.Tests/VMControl.cs b/src/Tests/dotnet-MsiInstallation.Tests/VMControl.cs index f6c18ef62602..04a7fb63ae78 100644 --- a/src/Tests/dotnet-MsiInstallation.Tests/VMControl.cs +++ b/src/Tests/dotnet-MsiInstallation.Tests/VMControl.cs @@ -168,11 +168,24 @@ public async Task CreateSnapshotAsync(string snapshotName) public async Task ApplySnapshotAsync(string snapshotId) { - await SetRunningAsync(false); + if (!await ApplySnapshotIfExistsAsync(snapshotId)) + { + throw new Exception("Snapshot not found: " + snapshotId); + } + } + public async Task ApplySnapshotIfExistsAsync(string snapshotId) + { var snapshots = GetSnapshotInstances(); - var snapshot = snapshots.Single(s => s.CimInstanceProperties["ConfigurationID"].Value.ToString() == snapshotId); + var snapshot = snapshots.SingleOrDefault(s => s.CimInstanceProperties["ConfigurationID"].Value.ToString() == snapshotId); + + if (snapshot == null) + { + return false; + } + + await SetRunningAsync(false); var snapshotService = _session.EnumerateInstances(virtNamespace, "Msvm_VirtualSystemSnapshotService").First(); @@ -188,6 +201,8 @@ public async Task ApplySnapshotAsync(string snapshotId) await WaitForJobSuccess(result); await SetRunningAsync(true); + + return true; } public async Task SetRunningAsync(bool running) diff --git a/src/Tests/dotnet-MsiInstallation.Tests/VirtualMachine.cs b/src/Tests/dotnet-MsiInstallation.Tests/VirtualMachine.cs index df4c462e440a..139e542009a7 100644 --- a/src/Tests/dotnet-MsiInstallation.Tests/VirtualMachine.cs +++ b/src/Tests/dotnet-MsiInstallation.Tests/VirtualMachine.cs @@ -50,9 +50,6 @@ public VirtualMachine(ITestOutputHelper log) } _currentState = _rootState; - - VMControl.ApplySnapshotAsync(_currentState.SnapshotId).Wait(); - _currentAppliedState = _currentState; } public void Dispose() { @@ -72,7 +69,7 @@ JsonSerializerOptions GetSerializerOptions() }; } - public CommandResult RunCommand(params string[] args) + SerializedVMAction CreateRunCommandAction(params string[] args) { if (args.Length == 0) { @@ -85,17 +82,38 @@ public CommandResult RunCommand(params string[] args) Arguments = args.ToList(), }; - var vmActionResult = Apply(action); + return action; + } + + public CommandResult RunCommand(params string[] args) + { + var vmActionResult = Apply(CreateRunCommandAction(args)); return vmActionResult.ToCommandResult(); } + SerializedVMAction CreateCopyFileAction(string localSource, string vmDestination) + { + var action = new SerializedVMAction + { + Type = VMActionType.CopyFileToVM, + SourcePath = localSource, + TargetPath = vmDestination, + ContentId = GetFileContentId(localSource), + }; + + return action; + } + public void CopyFile(string localSource, string vmDestination) { - throw new NotImplementedException(); + Apply(CreateCopyFileAction(localSource, vmDestination)) + .ToCommandResult() + .Should() + .Pass(); } - public void CopyFolder(string localSource, string vmDestination) + SerializedVMAction CreateCopyFolderAction(string localSource, string vmDestination) { var action = new SerializedVMAction { @@ -105,12 +123,17 @@ public void CopyFolder(string localSource, string vmDestination) ContentId = GetDirectoryContentId(localSource), }; - var vmActionResult = Apply(action); + return action; + } + + public void CopyFolder(string localSource, string vmDestination) + { + var vmActionResult = Apply(CreateCopyFolderAction(localSource, vmDestination)); vmActionResult.ToCommandResult().Should().Pass(); } - public void WriteFile(string vmDestination, string contents) + SerializedVMAction CreateWriteFileAction(string vmDestination, string contents) { var action = new SerializedVMAction { @@ -119,16 +142,40 @@ public void WriteFile(string vmDestination, string contents) FileContents = contents, }; - var vmActionResult = Apply(action); + + return action; + } + + public void WriteFile(string vmDestination, string contents) + { + var vmActionResult = Apply(CreateWriteFileAction(vmDestination, contents)); vmActionResult.ToCommandResult().Should().Pass(); } + public IVMActionGroup CreateActionGroup(string name) + { + return new VMActionGroup(this, name); + } + + public RemoteFile GetRemoteFile(string path) + { + return new VMRemoteFile(this, path); + } + public RemoteDirectory GetRemoteDirectory(string path) { throw new NotImplementedException(); } + void SyncToCurrentState() + { + if (_currentAppliedState != _currentState) + { + VMControl.ApplySnapshotAsync(_currentState.SnapshotId).Wait(); + } + } + VMActionResult Apply(SerializedVMAction action) { if (_currentState.Actions.TryGetValue(action, out var result)) @@ -137,10 +184,7 @@ VMActionResult Apply(SerializedVMAction action) return result.actionResult; } - if (_currentAppliedState != _currentState) - { - VMControl.ApplySnapshotAsync(_currentState.SnapshotId).Wait(); - } + SyncToCurrentState(); var actionResult = Run(action); @@ -199,9 +243,20 @@ VMActionResult Run(SerializedVMAction action) return VMActionResult.Success(); } + else if (action.Type == VMActionType.ActionGroup) + { + VMActionResult lastResult = VMActionResult.Success(); + + foreach (var subAction in action.Actions) + { + lastResult = Run(subAction); + } + + return lastResult; + } else { - throw new NotImplementedException(); + throw new NotImplementedException(action.Type.ToString()); } } @@ -269,5 +324,50 @@ string VMPathToSharePath(string vmPath) return $@"\\{VMControl.VMMachineName}\{driveLetter}$\{pathUnderDrive}"; } + + class VMActionGroup : IVMActionGroup + { + VirtualMachine _vm; + SerializedVMAction _action; + + public VMActionGroup(VirtualMachine vm, string name) + { + _vm = vm; + _action = new SerializedVMAction + { + Type = VMActionType.ActionGroup, + ExplicitDescription = name, + Actions = new List(), + }; + } + + public void RunCommand(params string[] args) => _action.Actions.Add(_vm.CreateRunCommandAction(args)); + + public void CopyFile(string localSource, string vmDestination) => _action.Actions.Add(_vm.CreateCopyFileAction(localSource, vmDestination)); + public void CopyFolder(string localSource, string vmDestination) => _action.Actions.Add(_vm.CreateCopyFolderAction(localSource, vmDestination)); + + + public void WriteFile(string vmDestination, string contents) => _action.Actions.Add(_vm.CreateWriteFileAction(vmDestination, contents)); + + public void Dispose() + { + _vm.Apply(_action); + } + } + + class VMRemoteFile : RemoteFile + { + VirtualMachine _vm; + public VMRemoteFile(VirtualMachine vm, string path) : base(path) + { + _vm = vm; + } + + public override string ReadAllText() + { + _vm.SyncToCurrentState(); + return File.ReadAllText(_vm.VMPathToSharePath(Path)); + } + } } } From 4cd59df34c9c2cfdbcb3ad9abc01b91b0f80fc12 Mon Sep 17 00:00:00 2001 From: Daniel Plaisted Date: Tue, 6 Feb 2024 13:15:03 -0500 Subject: [PATCH 389/577] WIP --- .../MsiInstallerTests.cs | 100 ++++++++----- .../RemoteFile.cs | 2 + .../dotnet-MsiInstallation.Tests/VMAction.cs | 137 ++++++++++++++++-- .../VirtualMachine.cs | 120 +++------------ 4 files changed, 216 insertions(+), 143 deletions(-) diff --git a/src/Tests/dotnet-MsiInstallation.Tests/MsiInstallerTests.cs b/src/Tests/dotnet-MsiInstallation.Tests/MsiInstallerTests.cs index 43d13a63d22e..eadc01f64380 100644 --- a/src/Tests/dotnet-MsiInstallation.Tests/MsiInstallerTests.cs +++ b/src/Tests/dotnet-MsiInstallation.Tests/MsiInstallerTests.cs @@ -78,7 +78,6 @@ public class WorkloadTests : SdkTest, IDisposable public WorkloadTests(ITestOutputHelper log) : base(log) { - //VM = new VMControl(Log); VM = new VirtualMachine(Log); } @@ -90,7 +89,8 @@ public void Dispose() [Fact] public void InstallSdk() { - VM.RunCommand($@"c:\SdkTesting\{SdkInstallerFileName}", "/quiet") + VM.CreateRunCommand($@"c:\SdkTesting\{SdkInstallerFileName}", "/quiet") + .Execute() .Should() .Pass(); @@ -102,10 +102,18 @@ public void InstallWasm() { InstallSdk(); - VM.WriteFile($@"C:\SdkTesting\rollback-rc1.json", RollbackRC1); - VM.RunCommand("dotnet", "workload", "update", "--from-rollback-file", @"c:\SdkTesting\rollback-rc1.json", "--skip-sign-check"); + VM.WriteFile($@"C:\SdkTesting\rollback-rc1.json", RollbackRC1) + .Execute() + .Should() + .Pass(); + + VM.CreateRunCommand("dotnet", "workload", "update", "--from-rollback-file", @"c:\SdkTesting\rollback-rc1.json", "--skip-sign-check") + .Execute() + .Should() + .Pass(); - VM.RunCommand("dotnet", "workload", "install", "wasm-tools", "--skip-manifest-update") + VM.CreateRunCommand("dotnet", "workload", "install", "wasm-tools", "--skip-manifest-update") + .Execute() .Should() .Pass(); } @@ -115,10 +123,18 @@ public void InstallAndroid() { InstallSdk(); - VM.WriteFile($@"C:\SdkTesting\rollback-rc1.json", RollbackRC1); - VM.RunCommand("dotnet", "workload", "update", "--from-rollback-file", @"c:\SdkTesting\rollback-rc1.json", "--skip-sign-check"); + VM.WriteFile($@"C:\SdkTesting\rollback-rc1.json", RollbackRC1) + .Execute() + .Should() + .Pass(); + + VM.CreateRunCommand("dotnet", "workload", "update", "--from-rollback-file", @"c:\SdkTesting\rollback-rc1.json", "--skip-sign-check") + .Execute() + .Should() + .Pass(); - VM.RunCommand("dotnet", "workload", "install", "android", "--skip-manifest-update") + VM.CreateRunCommand("dotnet", "workload", "install", "android", "--skip-manifest-update") + .Execute() .Should() .Pass(); } @@ -128,14 +144,23 @@ public void InstallAndroidAndWasm() { InstallSdk(); - VM.WriteFile($@"C:\SdkTesting\rollback-rc1.json", RollbackRC1); - VM.RunCommand("dotnet", "workload", "update", "--from-rollback-file", @"c:\SdkTesting\rollback-rc1.json", "--skip-sign-check"); + VM.WriteFile($@"C:\SdkTesting\rollback-rc1.json", RollbackRC1) + .Execute() + .Should() + .Pass(); + + VM.CreateRunCommand("dotnet", "workload", "update", "--from-rollback-file", @"c:\SdkTesting\rollback-rc1.json", "--skip-sign-check") + .Execute() + .Should() + .Pass(); - VM.RunCommand("dotnet", "workload", "install", "android", "--skip-manifest-update") + VM.CreateRunCommand("dotnet", "workload", "install", "android", "--skip-manifest-update") + .Execute() .Should() .Pass(); - VM.RunCommand("dotnet", "workload", "install", "wasm-tools", "--skip-manifest-update") + VM.CreateRunCommand("dotnet", "workload", "install", "wasm-tools", "--skip-manifest-update") + .Execute() .Should() .Pass(); } @@ -196,29 +221,33 @@ public async Task UseWMI() //[Fact] //public void SdkInstallation2() //{ - // //VM.RunCommand("dotnet", "--version") - // // .Should() - // // .HaveStdOut("7.0.401"); + // VM.CreateRunCommand("dotnet", "--version") + // .Execute() + // .Should() + // .HaveStdOut("7.0.401"); - // //VM.RunCommand($@"c:\SdkTesting\{SdkInstallerFileName}", "/quiet"); + // VM.CreateRunCommand($@"c:\SdkTesting\{SdkInstallerFileName}", "/quiet") + // .Execute() + // .Should() + // .Pass(); - // //new DirectoryInfo($@"\\{TargetMachineName}\c$\Program Files\dotnet\sdk\{SdkInstallerVersion}") - // // .Should() - // // .Exist(); + // new DirectoryInfo($@"\\{TargetMachineName}\c$\Program Files\dotnet\sdk\{SdkInstallerVersion}") + // .Should() + // .Exist(); - // //RunRemoteCommand("dotnet", "--version") - // // .Should() - // // .HaveStdOut(SdkInstallerVersion); + // RunRemoteCommand("dotnet", "--version") + // .Should() + // .HaveStdOut(SdkInstallerVersion); - // //RunRemoteCommand($@"c:\SdkTesting\{SdkInstallerFileName}", "/quiet", "/uninstall"); + // RunRemoteCommand($@"c:\SdkTesting\{SdkInstallerFileName}", "/quiet", "/uninstall"); - // //new DirectoryInfo($@"\\{TargetMachineName}\c$\Program Files\dotnet\sdk\{SdkInstallerVersion}") - // // .Should() - // // .NotExist(); + // new DirectoryInfo($@"\\{TargetMachineName}\c$\Program Files\dotnet\sdk\{SdkInstallerVersion}") + // .Should() + // .NotExist(); - // //RunRemoteCommand("dotnet", "--version") - // // .Should() - // // .HaveStdOut("7.0.401"); + // RunRemoteCommand("dotnet", "--version") + // .Should() + // .HaveStdOut("7.0.401"); //} @@ -235,7 +264,7 @@ public async Task UseWMI() // var rollbackResult = RunRemoteCommand("dotnet", "workload", "update", "--print-rollback"); // rollbackResult.Should().Pass(); // var originalManifests = ParseRollbackOutput(rollbackResult.StdOut); - + // RunRemoteCommand("dotnet", "workload", "install", "wasm-tools", "--skip-manifest-update"); @@ -374,11 +403,12 @@ void DeployStage2Sdk() var newVersionFileContents = File.ReadAllLines(Path.Combine(TestContext.Current.ToolsetUnderTest.SdkFolderUnderTest, ".version")); newVersionFileContents[1] = existingVersionFileContents[1]; - using (var group = VM.CreateActionGroup("Deploy Stage 2 SDK")) - { - group.CopyFolder(TestContext.Current.ToolsetUnderTest.SdkFolderUnderTest, installedSdkFolder); - group.WriteFile(vmVersionFilePath, string.Join(Environment.NewLine, newVersionFileContents)); - } + VM.CreateActionGroup("Deploy Stage 2 SDK", + VM.CopyFolder(TestContext.Current.ToolsetUnderTest.SdkFolderUnderTest, installedSdkFolder), + VM.WriteFile(vmVersionFilePath, string.Join(Environment.NewLine, newVersionFileContents))) + .Execute() + .Should() + .Pass(); } WorkloadSet ParseRollbackOutput(string output) diff --git a/src/Tests/dotnet-MsiInstallation.Tests/RemoteFile.cs b/src/Tests/dotnet-MsiInstallation.Tests/RemoteFile.cs index 304bed4d2f7d..8a45c31c7cee 100644 --- a/src/Tests/dotnet-MsiInstallation.Tests/RemoteFile.cs +++ b/src/Tests/dotnet-MsiInstallation.Tests/RemoteFile.cs @@ -9,6 +9,8 @@ namespace Microsoft.DotNet.MsiInstallerTests { + // TODO: Add VMAction for reading remote file, to allow read of file to be cached, avoiding the need to apply a snapshot to read the file on subsequent runs + abstract class RemoteFile { public RemoteFile(string path) diff --git a/src/Tests/dotnet-MsiInstallation.Tests/VMAction.cs b/src/Tests/dotnet-MsiInstallation.Tests/VMAction.cs index c785ea5ae7bb..cad9f8111c70 100644 --- a/src/Tests/dotnet-MsiInstallation.Tests/VMAction.cs +++ b/src/Tests/dotnet-MsiInstallation.Tests/VMAction.cs @@ -27,6 +27,132 @@ namespace Microsoft.DotNet.MsiInstallerTests // Copy file to VM // - Deploy stage 2 SDK + abstract class VMAction + { + public VirtualMachine VM { get; } + + protected VMAction(VirtualMachine vm) + { + VM = vm; + } + + public string ExplicitDescription { get; set; } + + public CommandResult Execute() + { + return VM.Apply(Serialize()).ToCommandResult(); + } + + public SerializedVMAction Serialize() + { + var serialized = SerializeDerivedProperties(); + serialized.ExplicitDescription = ExplicitDescription; + return serialized; + } + protected abstract SerializedVMAction SerializeDerivedProperties(); + } + + class VMRunAction : VMAction + { + public List Arguments { get; set; } + + public VMRunAction(VirtualMachine vm, List arguments = null) : base(vm) + { + Arguments = arguments ?? new List(); + } + + protected override SerializedVMAction SerializeDerivedProperties() + { + return new SerializedVMAction + { + Type = VMActionType.RunCommand, + Arguments = Arguments, + }; + } + } + + class VMCopyFileAction : VMAction + { + public string LocalSource { get; set; } + public string TargetPath { get; set; } + + public VMCopyFileAction(VirtualMachine vm) : base(vm) + { + } + + protected override SerializedVMAction SerializeDerivedProperties() + { + return new SerializedVMAction + { + Type = VMActionType.CopyFileToVM, + SourcePath = LocalSource, + TargetPath = TargetPath, + ContentId = VirtualMachine.GetFileContentId(LocalSource), + + }; + } + } + + class VMCopyFolderAction : VMAction + { + public string LocalSource { get; set; } + public string TargetPath { get; set; } + + public VMCopyFolderAction(VirtualMachine vm) : base(vm) + { + } + + protected override SerializedVMAction SerializeDerivedProperties() + { + return new SerializedVMAction + { + Type = VMActionType.CopyFolderToVM, + SourcePath = LocalSource, + TargetPath = TargetPath, + ContentId = VirtualMachine.GetDirectoryContentId(LocalSource), + }; + } + } + + class VMWriteFileAction : VMAction + { + public string TargetPath { get; set; } + public string FileContents { get; set; } + + public VMWriteFileAction(VirtualMachine vm) : base(vm) + { + } + + protected override SerializedVMAction SerializeDerivedProperties() + { + return new SerializedVMAction + { + Type = VMActionType.WriteFileToVM, + TargetPath = TargetPath, + FileContents = FileContents, + }; + } + } + + class VMGroupedAction : VMAction + { + public List Actions { get; set; } + + public VMGroupedAction(VirtualMachine vm) : base(vm) + { + Actions = new List(); + } + + protected override SerializedVMAction SerializeDerivedProperties() + { + return new SerializedVMAction + { + Type = VMActionType.ActionGroup, + Actions = Actions.Select(a => a.Serialize()).ToList(), + }; + } + } + enum VMActionType { RunCommand, @@ -141,6 +267,7 @@ public override int GetHashCode() public static bool operator !=(SerializedVMAction left, SerializedVMAction right) => !(left == right); } + // Do we need a separate VMActionResult, or should we just use CommandResult? class VMActionResult { public string Filename { get; set; } @@ -173,14 +300,4 @@ public static VMActionResult Success() }; } } - - interface IVMActionGroup : IDisposable - { - void RunCommand(params string[] args); - void CopyFile(string localSource, string vmDestination); - - void CopyFolder(string localSource, string vmDestination); - - void WriteFile(string vmDestination, string contents); - } } diff --git a/src/Tests/dotnet-MsiInstallation.Tests/VirtualMachine.cs b/src/Tests/dotnet-MsiInstallation.Tests/VirtualMachine.cs index 139e542009a7..31a7bd4a41f5 100644 --- a/src/Tests/dotnet-MsiInstallation.Tests/VirtualMachine.cs +++ b/src/Tests/dotnet-MsiInstallation.Tests/VirtualMachine.cs @@ -13,7 +13,7 @@ namespace Microsoft.DotNet.MsiInstallerTests { - internal class VirtualMachine : IDisposable + class VirtualMachine : IDisposable { ITestOutputHelper Log { get; } public VMControl VMControl { get; } @@ -69,93 +69,45 @@ JsonSerializerOptions GetSerializerOptions() }; } - SerializedVMAction CreateRunCommandAction(params string[] args) + public VMRunAction CreateRunCommand(params string[] args) { - if (args.Length == 0) - { - throw new ArgumentException("Must provide at least one argument", nameof(args)); - } - - var action = new SerializedVMAction - { - Type = VMActionType.RunCommand, - Arguments = args.ToList(), - }; - - return action; + return new VMRunAction(this, args.ToList()); } - public CommandResult RunCommand(params string[] args) + public VMCopyFileAction CopyFile(string localSource, string vmDestination) { - var vmActionResult = Apply(CreateRunCommandAction(args)); - - return vmActionResult.ToCommandResult(); - } - - SerializedVMAction CreateCopyFileAction(string localSource, string vmDestination) - { - var action = new SerializedVMAction + return new VMCopyFileAction(this) { - Type = VMActionType.CopyFileToVM, - SourcePath = localSource, + LocalSource = localSource, TargetPath = vmDestination, - ContentId = GetFileContentId(localSource), }; - - return action; } - public void CopyFile(string localSource, string vmDestination) + public VMCopyFolderAction CopyFolder(string localSource, string vmDestination) { - Apply(CreateCopyFileAction(localSource, vmDestination)) - .ToCommandResult() - .Should() - .Pass(); - } - - SerializedVMAction CreateCopyFolderAction(string localSource, string vmDestination) - { - var action = new SerializedVMAction + return new VMCopyFolderAction(this) { - Type = VMActionType.CopyFolderToVM, - SourcePath = localSource, + LocalSource = localSource, TargetPath = vmDestination, - ContentId = GetDirectoryContentId(localSource), }; - - return action; - } - - public void CopyFolder(string localSource, string vmDestination) - { - var vmActionResult = Apply(CreateCopyFolderAction(localSource, vmDestination)); - - vmActionResult.ToCommandResult().Should().Pass(); } - SerializedVMAction CreateWriteFileAction(string vmDestination, string contents) + public VMWriteFileAction WriteFile(string vmDestination, string contents) { - var action = new SerializedVMAction + return new VMWriteFileAction(this) { - Type = VMActionType.WriteFileToVM, TargetPath = vmDestination, FileContents = contents, }; - - - return action; } - public void WriteFile(string vmDestination, string contents) + public VMGroupedAction CreateActionGroup(string name, params VMAction[] actions) { - var vmActionResult = Apply(CreateWriteFileAction(vmDestination, contents)); - - vmActionResult.ToCommandResult().Should().Pass(); - } - - public IVMActionGroup CreateActionGroup(string name) - { - return new VMActionGroup(this, name); + return new VMGroupedAction(this) + { + ExplicitDescription = name, + Actions = actions.ToList(), + }; } public RemoteFile GetRemoteFile(string path) @@ -176,7 +128,8 @@ void SyncToCurrentState() } } - VMActionResult Apply(SerializedVMAction action) + // Runs a command if necessary, or returns previously recorded result. Handles syncing to the correct state, creating a new snapshot, etc. + public VMActionResult Apply(SerializedVMAction action) { if (_currentState.Actions.TryGetValue(action, out var result)) { @@ -205,6 +158,7 @@ VMActionResult Apply(SerializedVMAction action) return actionResult; } + // Runs a command, with no state management VMActionResult Run(SerializedVMAction action) { if (action.Type == VMActionType.RunCommand) @@ -260,13 +214,13 @@ VMActionResult Run(SerializedVMAction action) } } - string GetFileContentId(string path) + public static string GetFileContentId(string path) { var info = new FileInfo(path); return $"{info.LastWriteTimeUtc.Ticks}-{info.Length}"; } - string GetDirectoryContentId(string path) + public static string GetDirectoryContentId(string path) { StringBuilder sb = new StringBuilder(); var info = new DirectoryInfo(path); @@ -325,36 +279,6 @@ string VMPathToSharePath(string vmPath) } - class VMActionGroup : IVMActionGroup - { - VirtualMachine _vm; - SerializedVMAction _action; - - public VMActionGroup(VirtualMachine vm, string name) - { - _vm = vm; - _action = new SerializedVMAction - { - Type = VMActionType.ActionGroup, - ExplicitDescription = name, - Actions = new List(), - }; - } - - public void RunCommand(params string[] args) => _action.Actions.Add(_vm.CreateRunCommandAction(args)); - - public void CopyFile(string localSource, string vmDestination) => _action.Actions.Add(_vm.CreateCopyFileAction(localSource, vmDestination)); - public void CopyFolder(string localSource, string vmDestination) => _action.Actions.Add(_vm.CreateCopyFolderAction(localSource, vmDestination)); - - - public void WriteFile(string vmDestination, string contents) => _action.Actions.Add(_vm.CreateWriteFileAction(vmDestination, contents)); - - public void Dispose() - { - _vm.Apply(_action); - } - } - class VMRemoteFile : RemoteFile { VirtualMachine _vm; From 5f90bb6c0c3cdb3a3aaa03302b7456043949fe13 Mon Sep 17 00:00:00 2001 From: Daniel Plaisted Date: Tue, 6 Feb 2024 19:04:34 -0500 Subject: [PATCH 390/577] Support getting remote directory, and commands that don't change state --- .../MsiInstallerTests.cs | 60 +++++++++++-------- .../RemoteDirectory.cs | 17 ++++-- .../dotnet-MsiInstallation.Tests/VMAction.cs | 6 ++ .../dotnet-MsiInstallation.Tests/VMControl.cs | 3 +- .../VirtualMachine.cs | 38 +++++++++++- 5 files changed, 87 insertions(+), 37 deletions(-) diff --git a/src/Tests/dotnet-MsiInstallation.Tests/MsiInstallerTests.cs b/src/Tests/dotnet-MsiInstallation.Tests/MsiInstallerTests.cs index eadc01f64380..61f40f42d4d6 100644 --- a/src/Tests/dotnet-MsiInstallation.Tests/MsiInstallerTests.cs +++ b/src/Tests/dotnet-MsiInstallation.Tests/MsiInstallerTests.cs @@ -31,7 +31,7 @@ public class WorkloadTests : SdkTest, IDisposable // How to rename a snapshot: https://stackoverflow.com/questions/7599217/setting-hyper-v-snapshots-name-programmatically - // Reminder: Enable "Remote Service Management" firewall rule so that PSExec will run more quickly + // Reminder: Enable "Remote Service Management" firewall rule so that PSExec will run more quickly. Make sure network is set to "Private" in Windows settings (or enable the firewall rule for public networks). const string TargetMachineName = "dsp-vm"; const string PsExecPath = @"C:\Users\Daniel\Downloads\PSTools\PsExec.exe"; @@ -218,38 +218,37 @@ public async Task UseWMI() // .HaveStdOut("7.0.401"); //} - //[Fact] - //public void SdkInstallation2() - //{ - // VM.CreateRunCommand("dotnet", "--version") - // .Execute() - // .Should() - // .HaveStdOut("7.0.401"); + [Fact] + public void SdkInstallation2() + { + GetInstalledSdkVersion().Should().Be("7.0.401"); - // VM.CreateRunCommand($@"c:\SdkTesting\{SdkInstallerFileName}", "/quiet") - // .Execute() - // .Should() - // .Pass(); + VM.CreateRunCommand($@"c:\SdkTesting\{SdkInstallerFileName}", "/quiet") + .Execute() + .Should() + .Pass(); - // new DirectoryInfo($@"\\{TargetMachineName}\c$\Program Files\dotnet\sdk\{SdkInstallerVersion}") - // .Should() - // .Exist(); + VM.GetRemoteDirectory($@"c:\Program Files\dotnet\sdk\{SdkInstallerVersion}") + .Should() + .Exist(); - // RunRemoteCommand("dotnet", "--version") - // .Should() - // .HaveStdOut(SdkInstallerVersion); + GetInstalledSdkVersion().Should().Be(SdkInstallerVersion); - // RunRemoteCommand($@"c:\SdkTesting\{SdkInstallerFileName}", "/quiet", "/uninstall"); + VM.CreateRunCommand($@"c:\SdkTesting\{SdkInstallerFileName}", "/quiet", "/uninstall") + .Execute() + .Should() + .Pass(); - // new DirectoryInfo($@"\\{TargetMachineName}\c$\Program Files\dotnet\sdk\{SdkInstallerVersion}") - // .Should() - // .NotExist(); + VM.GetRemoteDirectory($@"c:\Program Files\dotnet\sdk\{SdkInstallerVersion}") + .Should() + .NotExist(); - // RunRemoteCommand("dotnet", "--version") - // .Should() - // .HaveStdOut("7.0.401"); + new DirectoryInfo($@"\\{TargetMachineName}\c$\Program Files\dotnet\sdk\{SdkInstallerVersion}") + .Should() + .NotExist(); - //} + GetInstalledSdkVersion().Should().Be("7.0.401"); + } //[Fact(Skip = "testing")] @@ -315,6 +314,15 @@ public async Task UseWMI() // // Should not install or uninstall anything //} + string GetInstalledSdkVersion() + { + var command = VM.CreateRunCommand("dotnet", "--version"); + command.ShouldChangeState = false; + var result = command.Execute(); + result.Should().Pass(); + return result.StdOut; + } + void CleanupInstallState() { var featureBand = new SdkFeatureBand(SdkInstallerVersion); diff --git a/src/Tests/dotnet-MsiInstallation.Tests/RemoteDirectory.cs b/src/Tests/dotnet-MsiInstallation.Tests/RemoteDirectory.cs index 104379d17036..356bd628a589 100644 --- a/src/Tests/dotnet-MsiInstallation.Tests/RemoteDirectory.cs +++ b/src/Tests/dotnet-MsiInstallation.Tests/RemoteDirectory.cs @@ -10,18 +10,17 @@ namespace Microsoft.DotNet.MsiInstallerTests { - internal class RemoteDirectory + abstract class RemoteDirectory { public string Path { get; } - public bool Exists + protected RemoteDirectory(string path) { - get - { - throw new NotImplementedException(); - } + Path = path; } + public abstract bool Exists { get; } + public Assertions Should() { return new Assertions(this); @@ -42,6 +41,12 @@ public AndConstraint Exist() .FailWith("Expected directory {0} does not exist.", _directory.Path); return new AndConstraint(this); } + public AndConstraint NotExist() + { + Execute.Assertion.ForCondition(!_directory.Exists) + .FailWith("Expected directory {0} not to exist.", _directory.Path); + return new AndConstraint(this); + } } } } diff --git a/src/Tests/dotnet-MsiInstallation.Tests/VMAction.cs b/src/Tests/dotnet-MsiInstallation.Tests/VMAction.cs index cad9f8111c70..9accf748f206 100644 --- a/src/Tests/dotnet-MsiInstallation.Tests/VMAction.cs +++ b/src/Tests/dotnet-MsiInstallation.Tests/VMAction.cs @@ -38,6 +38,8 @@ protected VMAction(VirtualMachine vm) public string ExplicitDescription { get; set; } + public bool ShouldChangeState { get; set; } = true; + public CommandResult Execute() { return VM.Apply(Serialize()).ToCommandResult(); @@ -47,6 +49,7 @@ public SerializedVMAction Serialize() { var serialized = SerializeDerivedProperties(); serialized.ExplicitDescription = ExplicitDescription; + serialized.ShouldChangeState = ShouldChangeState; return serialized; } protected abstract SerializedVMAction SerializeDerivedProperties(); @@ -170,6 +173,8 @@ class SerializedVMAction public string ExplicitDescription { get; set; } + public bool ShouldChangeState { get; set; } + // Applies to RunCommand public List Arguments { get; set; } @@ -236,6 +241,7 @@ static bool ListsAreEqual(List a, List b) return Type == action.Type && ExplicitDescription == action.ExplicitDescription && + ShouldChangeState == action.ShouldChangeState && ListsAreEqual(Arguments, action.Arguments) && TargetPath == action.TargetPath && SourcePath == action.SourcePath && diff --git a/src/Tests/dotnet-MsiInstallation.Tests/VMControl.cs b/src/Tests/dotnet-MsiInstallation.Tests/VMControl.cs index 04a7fb63ae78..e42540293ab0 100644 --- a/src/Tests/dotnet-MsiInstallation.Tests/VMControl.cs +++ b/src/Tests/dotnet-MsiInstallation.Tests/VMControl.cs @@ -210,7 +210,6 @@ public async Task SetRunningAsync(bool running) VMEnabledState getCurrentState() { var state = (VMEnabledState) (UInt16)VMInstance.CimInstanceProperties["EnabledState"].Value; - Log.WriteLine("Current EnabledState: " + state); return state; } @@ -227,7 +226,7 @@ VMEnabledState getCurrentState() // return; //} - Log.WriteLine("Setting EnabledState to " + targetState); + Log.WriteLine($"Changing EnabledState from {getCurrentState()} to {targetState}"); var methodParameters = new CimMethodParametersCollection() { diff --git a/src/Tests/dotnet-MsiInstallation.Tests/VirtualMachine.cs b/src/Tests/dotnet-MsiInstallation.Tests/VirtualMachine.cs index 31a7bd4a41f5..37319d1ce158 100644 --- a/src/Tests/dotnet-MsiInstallation.Tests/VirtualMachine.cs +++ b/src/Tests/dotnet-MsiInstallation.Tests/VirtualMachine.cs @@ -24,6 +24,9 @@ class VirtualMachine : IDisposable string _stateFile; + // Whether we should trust the ShouldChangeState property of the action. If not, then we will re-apply the previous snapshot after the action runs to make sure the state hasn't been polluted. + public bool TrustShouldChangeState { get; set; } = true; + public VirtualMachine(ITestOutputHelper log) { Log = log; @@ -43,8 +46,8 @@ public VirtualMachine(ITestOutputHelper log) { _rootState = new VMStateTree() { - SnapshotId = "60667B5C-EC88-430E-8C69-5E4214123941", - SnapshotName = "Updated expired password, enabled Remote Management", + SnapshotId = "CF853278-1B6B-4816-8E51-FBDBE3AABA2C", + SnapshotName = "Set network to private", }; } } @@ -117,7 +120,7 @@ public RemoteFile GetRemoteFile(string path) public RemoteDirectory GetRemoteDirectory(string path) { - throw new NotImplementedException(); + return new VMRemoteDirectory(this, path); } void SyncToCurrentState() @@ -125,6 +128,7 @@ void SyncToCurrentState() if (_currentAppliedState != _currentState) { VMControl.ApplySnapshotAsync(_currentState.SnapshotId).Wait(); + _currentAppliedState = _currentState; } } @@ -141,6 +145,16 @@ public VMActionResult Apply(SerializedVMAction action) var actionResult = Run(action); + if (!action.ShouldChangeState) + { + if (!TrustShouldChangeState) + { + VMControl.ApplySnapshotAsync(_currentState.SnapshotId).Wait(); + } + + return actionResult; + } + string actionDescription = action.GetDescription(); string newSnapshotId = VMControl.CreateSnapshotAsync(actionDescription).Result; @@ -293,5 +307,23 @@ public override string ReadAllText() return File.ReadAllText(_vm.VMPathToSharePath(Path)); } } + + class VMRemoteDirectory : RemoteDirectory + { + VirtualMachine _vm; + public VMRemoteDirectory(VirtualMachine vm, string path) : base(path) + { + _vm = vm; + } + + public override bool Exists + { + get + { + _vm.SyncToCurrentState(); + return Directory.Exists(_vm.VMPathToSharePath(Path)); + } + } + } } } From 97ef42a118ab23afd4487ded3981ebf6194f8e21 Mon Sep 17 00:00:00 2001 From: Daniel Plaisted Date: Wed, 7 Feb 2024 06:49:19 -0500 Subject: [PATCH 391/577] Add WithDescription --- src/Tests/dotnet-MsiInstallation.Tests/VMAction.cs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/Tests/dotnet-MsiInstallation.Tests/VMAction.cs b/src/Tests/dotnet-MsiInstallation.Tests/VMAction.cs index 9accf748f206..56a9b619e861 100644 --- a/src/Tests/dotnet-MsiInstallation.Tests/VMAction.cs +++ b/src/Tests/dotnet-MsiInstallation.Tests/VMAction.cs @@ -45,6 +45,12 @@ public CommandResult Execute() return VM.Apply(Serialize()).ToCommandResult(); } + public VMAction WithDescription(string description) + { + ExplicitDescription = description; + return this; + } + public SerializedVMAction Serialize() { var serialized = SerializeDerivedProperties(); From 403a5a58a708f1dd83dbdb75729d6833c66f5a18 Mon Sep 17 00:00:00 2001 From: Daniel Plaisted Date: Thu, 8 Feb 2024 11:23:16 -0500 Subject: [PATCH 392/577] Refactor ReadOnly actions, cache their results, and use them for RemoteFile/RemoteDirectory --- .../MsiInstallerTests.cs | 54 +++------ .../dotnet-MsiInstallation.Tests/VMAction.cs | 22 +++- .../VMStateTree.cs | 21 +++- .../VirtualMachine.cs | 108 ++++++++++++++++-- 4 files changed, 152 insertions(+), 53 deletions(-) diff --git a/src/Tests/dotnet-MsiInstallation.Tests/MsiInstallerTests.cs b/src/Tests/dotnet-MsiInstallation.Tests/MsiInstallerTests.cs index 61f40f42d4d6..b831979f5b32 100644 --- a/src/Tests/dotnet-MsiInstallation.Tests/MsiInstallerTests.cs +++ b/src/Tests/dotnet-MsiInstallation.Tests/MsiInstallerTests.cs @@ -90,6 +90,7 @@ public void Dispose() public void InstallSdk() { VM.CreateRunCommand($@"c:\SdkTesting\{SdkInstallerFileName}", "/quiet") + .WithDescription($"Install SDK {SdkInstallerVersion}") .Execute() .Should() .Pass(); @@ -97,25 +98,24 @@ public void InstallSdk() DeployStage2Sdk(); } + void ApplyRC1Manifests() + { + VM.CreateActionGroup("Rollback to RC1 manifests", + VM.WriteFile($@"C:\SdkTesting\rollback-rc1.json", RollbackRC1), + VM.CreateRunCommand("dotnet", "workload", "update", "--from-rollback-file", @"c:\SdkTesting\rollback-rc1.json", "--skip-sign-check")) + .Execute().Should().Pass(); + } + [Fact] public void InstallWasm() { InstallSdk(); - VM.WriteFile($@"C:\SdkTesting\rollback-rc1.json", RollbackRC1) - .Execute() - .Should() - .Pass(); - - VM.CreateRunCommand("dotnet", "workload", "update", "--from-rollback-file", @"c:\SdkTesting\rollback-rc1.json", "--skip-sign-check") - .Execute() - .Should() - .Pass(); + ApplyRC1Manifests(); VM.CreateRunCommand("dotnet", "workload", "install", "wasm-tools", "--skip-manifest-update") - .Execute() - .Should() - .Pass(); + .WithDescription("Install wasm workload") + .Execute().Should().Pass(); } [Fact] @@ -123,17 +123,10 @@ public void InstallAndroid() { InstallSdk(); - VM.WriteFile($@"C:\SdkTesting\rollback-rc1.json", RollbackRC1) - .Execute() - .Should() - .Pass(); - - VM.CreateRunCommand("dotnet", "workload", "update", "--from-rollback-file", @"c:\SdkTesting\rollback-rc1.json", "--skip-sign-check") - .Execute() - .Should() - .Pass(); + ApplyRC1Manifests(); VM.CreateRunCommand("dotnet", "workload", "install", "android", "--skip-manifest-update") + .WithDescription("Install android workload") .Execute() .Should() .Pass(); @@ -144,22 +137,16 @@ public void InstallAndroidAndWasm() { InstallSdk(); - VM.WriteFile($@"C:\SdkTesting\rollback-rc1.json", RollbackRC1) - .Execute() - .Should() - .Pass(); - - VM.CreateRunCommand("dotnet", "workload", "update", "--from-rollback-file", @"c:\SdkTesting\rollback-rc1.json", "--skip-sign-check") - .Execute() - .Should() - .Pass(); + ApplyRC1Manifests(); VM.CreateRunCommand("dotnet", "workload", "install", "android", "--skip-manifest-update") + .WithDescription("Install android workload") .Execute() .Should() .Pass(); VM.CreateRunCommand("dotnet", "workload", "install", "wasm-tools", "--skip-manifest-update") + .WithDescription("Install wasm workload") .Execute() .Should() .Pass(); @@ -224,6 +211,7 @@ public void SdkInstallation2() GetInstalledSdkVersion().Should().Be("7.0.401"); VM.CreateRunCommand($@"c:\SdkTesting\{SdkInstallerFileName}", "/quiet") + .WithDescription($"Install SDK {SdkInstallerVersion}") .Execute() .Should() .Pass(); @@ -243,10 +231,6 @@ public void SdkInstallation2() .Should() .NotExist(); - new DirectoryInfo($@"\\{TargetMachineName}\c$\Program Files\dotnet\sdk\{SdkInstallerVersion}") - .Should() - .NotExist(); - GetInstalledSdkVersion().Should().Be("7.0.401"); } @@ -317,7 +301,7 @@ public void SdkInstallation2() string GetInstalledSdkVersion() { var command = VM.CreateRunCommand("dotnet", "--version"); - command.ShouldChangeState = false; + command.IsReadOnly = true; var result = command.Execute(); result.Should().Pass(); return result.StdOut; diff --git a/src/Tests/dotnet-MsiInstallation.Tests/VMAction.cs b/src/Tests/dotnet-MsiInstallation.Tests/VMAction.cs index 56a9b619e861..e1381748c967 100644 --- a/src/Tests/dotnet-MsiInstallation.Tests/VMAction.cs +++ b/src/Tests/dotnet-MsiInstallation.Tests/VMAction.cs @@ -38,7 +38,8 @@ protected VMAction(VirtualMachine vm) public string ExplicitDescription { get; set; } - public bool ShouldChangeState { get; set; } = true; + // Indicates that the action doesn't change the state of the VM, which allows extra snapshots to be avoided + public bool IsReadOnly { get; set; } public CommandResult Execute() { @@ -55,7 +56,7 @@ public SerializedVMAction Serialize() { var serialized = SerializeDerivedProperties(); serialized.ExplicitDescription = ExplicitDescription; - serialized.ShouldChangeState = ShouldChangeState; + serialized.IsReadOnly = IsReadOnly; return serialized; } protected abstract SerializedVMAction SerializeDerivedProperties(); @@ -168,6 +169,8 @@ enum VMActionType CopyFileToVM, CopyFolderToVM, WriteFileToVM, + GetRemoteDirectory, + GetRemoteFile, // Used to combine multiple actions into a single action, so they don't get snapshotted separately ActionGroup, } @@ -179,12 +182,12 @@ class SerializedVMAction public string ExplicitDescription { get; set; } - public bool ShouldChangeState { get; set; } + public bool IsReadOnly { get; set; } // Applies to RunCommand public List Arguments { get; set; } - // Applies to CopyFileToVM, CopyFolderToVM, WriteFileToVM + // Applies to CopyFileToVM, CopyFolderToVM, WriteFileToVM, GetRemoteDirectory, GetRemoteFile public string TargetPath { get; set; } // Applies to CopyFileToVM, CopyFolderToVM @@ -218,6 +221,10 @@ public string GetDescription() return $"Copy folder to VM: {SourcePath} -> {TargetPath}"; case VMActionType.WriteFileToVM: return $"Write file to VM: {TargetPath}"; + case VMActionType.GetRemoteDirectory: + return $"Get remote directory: {TargetPath}"; + case VMActionType.GetRemoteFile: + return $"Get remote file: {TargetPath}"; case VMActionType.ActionGroup: return $"Action group: {string.Join(", ", Actions.Select(a => a.GetDescription()))}"; default: @@ -247,7 +254,7 @@ static bool ListsAreEqual(List a, List b) return Type == action.Type && ExplicitDescription == action.ExplicitDescription && - ShouldChangeState == action.ShouldChangeState && + IsReadOnly == action.IsReadOnly && ListsAreEqual(Arguments, action.Arguments) && TargetPath == action.TargetPath && SourcePath == action.SourcePath && @@ -288,6 +295,11 @@ class VMActionResult public string StdOut { get; set; } public string StdErr { get; set; } + // For GetRemoteDirectory and GetRemoteFile + public bool Exists { get; set; } + public List Directories { get; set; } + public List Files { get; set; } + public CommandResult ToCommandResult() { return new CommandResult( diff --git a/src/Tests/dotnet-MsiInstallation.Tests/VMStateTree.cs b/src/Tests/dotnet-MsiInstallation.Tests/VMStateTree.cs index 4b2bda1285f7..78701ec8990f 100644 --- a/src/Tests/dotnet-MsiInstallation.Tests/VMStateTree.cs +++ b/src/Tests/dotnet-MsiInstallation.Tests/VMStateTree.cs @@ -16,6 +16,8 @@ internal class VMStateTree public Dictionary Actions { get; set; } = new(); + public Dictionary ReadOnlyActions { get; set; } = new(); + public SerializeableVMStateTree ToSerializeable() { return new SerializeableVMStateTree() @@ -26,7 +28,12 @@ public SerializeableVMStateTree ToSerializeable() Action = a.Key, ActionResult = a.Value.actionResult, ResultingState = a.Value.resultingState.ToSerializeable() - }) + }).ToList(), + ReadOnlyActions = ReadOnlyActions.Select(a => new SerializeableVMStateTree.ReadOnlyEntry() + { + Action = a.Key, + ActionResult = a.Value + }).ToList() .ToList() }; } @@ -39,6 +46,8 @@ internal class SerializeableVMStateTree public List Actions { get; set; } + public List ReadOnlyActions { get; set; } + public class Entry { @@ -47,6 +56,12 @@ public class Entry public SerializeableVMStateTree ResultingState { get; set; } } + public class ReadOnlyEntry + { + public SerializedVMAction Action { get; set; } + public VMActionResult ActionResult { get; set; } + } + public VMStateTree ToVMStateTree() { var tree = new VMStateTree() @@ -59,6 +74,10 @@ public VMStateTree ToVMStateTree() { tree.Actions.Add(entry.Action, (entry.ActionResult, entry.ResultingState.ToVMStateTree())); } + foreach (var entry in ReadOnlyActions) + { + tree.ReadOnlyActions.Add(entry.Action, entry.ActionResult); + } return tree; } diff --git a/src/Tests/dotnet-MsiInstallation.Tests/VirtualMachine.cs b/src/Tests/dotnet-MsiInstallation.Tests/VirtualMachine.cs index 37319d1ce158..ac1a8bb0ecb6 100644 --- a/src/Tests/dotnet-MsiInstallation.Tests/VirtualMachine.cs +++ b/src/Tests/dotnet-MsiInstallation.Tests/VirtualMachine.cs @@ -9,6 +9,7 @@ using System.Text.Json; using System.Text.Json.Serialization; using System.Threading.Tasks; +using Microsoft.Build.Execution; using Microsoft.DotNet.Cli.Utils; namespace Microsoft.DotNet.MsiInstallerTests @@ -24,8 +25,8 @@ class VirtualMachine : IDisposable string _stateFile; - // Whether we should trust the ShouldChangeState property of the action. If not, then we will re-apply the previous snapshot after the action runs to make sure the state hasn't been polluted. - public bool TrustShouldChangeState { get; set; } = true; + // Whether we should trust the IsReadOnly property of the action. If not, then we will re-apply the previous snapshot after the action runs to make sure the state hasn't been polluted. + public bool TrustIsReadOnly { get; set; } = true; public VirtualMachine(ITestOutputHelper log) { @@ -47,7 +48,7 @@ public VirtualMachine(ITestOutputHelper log) _rootState = new VMStateTree() { SnapshotId = "CF853278-1B6B-4816-8E51-FBDBE3AABA2C", - SnapshotName = "Set network to private", + SnapshotName = "Initial test state (Set network to private)", }; } } @@ -135,23 +136,35 @@ void SyncToCurrentState() // Runs a command if necessary, or returns previously recorded result. Handles syncing to the correct state, creating a new snapshot, etc. public VMActionResult Apply(SerializedVMAction action) { - if (_currentState.Actions.TryGetValue(action, out var result)) + if (action.IsReadOnly) { - _currentState = result.resultingState; - return result.actionResult; + if (_currentState.ReadOnlyActions.TryGetValue(action, out var readOnlyResult)) + { + return readOnlyResult; + } + } + else + { + if (_currentState.Actions.TryGetValue(action, out var result)) + { + _currentState = result.resultingState; + return result.actionResult; + } } SyncToCurrentState(); var actionResult = Run(action); - if (!action.ShouldChangeState) + if (action.IsReadOnly) { - if (!TrustShouldChangeState) + if (!TrustIsReadOnly) { VMControl.ApplySnapshotAsync(_currentState.SnapshotId).Wait(); } + _currentState.ReadOnlyActions[action] = actionResult; + return actionResult; } @@ -211,6 +224,38 @@ VMActionResult Run(SerializedVMAction action) return VMActionResult.Success(); } + else if (action.Type == VMActionType.GetRemoteDirectory) + { + var targetSharePath = VMPathToSharePath(action.TargetPath); + var result = VMActionResult.Success(); + + if (Directory.Exists(targetSharePath)) + { + result.Exists = true; + result.Directories = Directory.GetDirectories(targetSharePath).Select(SharePathToVMPath).ToList(); + result.Files = Directory.GetFiles(targetSharePath).Select(SharePathToVMPath).ToList(); + } + else + { + result.Exists = false; + } + return result; + } + else if (action.Type == VMActionType.GetRemoteFile) + { + var targetSharePath = VMPathToSharePath(action.TargetPath); + var result = VMActionResult.Success(); + if (File.Exists(targetSharePath)) + { + result.Exists = true; + result.StdOut = File.ReadAllText(targetSharePath); + } + else + { + result.Exists = false; + } + return result; + } else if (action.Type == VMActionType.ActionGroup) { VMActionResult lastResult = VMActionResult.Success(); @@ -290,7 +335,23 @@ string VMPathToSharePath(string vmPath) string pathUnderDrive = dirInfo.FullName.Substring(3); return $@"\\{VMControl.VMMachineName}\{driveLetter}$\{pathUnderDrive}"; + } + + // Copilot wrote the entire body of this method + string SharePathToVMPath(string sharePath) + { + if (!sharePath.StartsWith($@"\\{VMControl.VMMachineName}\")) + { + throw new ArgumentException("Unrecognized share path: " + sharePath, nameof(sharePath)); + } + + string pathUnderDrive = sharePath.Substring($@"\\{VMControl.VMMachineName}\".Length); + + string driveLetter = pathUnderDrive.Substring(0, 1); + + string pathAfterDrive = pathUnderDrive.Substring(3); + return $"{driveLetter}:\\{pathAfterDrive}"; } class VMRemoteFile : RemoteFile @@ -301,10 +362,24 @@ public VMRemoteFile(VirtualMachine vm, string path) : base(path) _vm = vm; } + VMActionResult GetResult() + { + return _vm.Apply(new SerializedVMAction() + { + Type = VMActionType.GetRemoteFile, + TargetPath = Path, + IsReadOnly = true + }); + } + public override string ReadAllText() { - _vm.SyncToCurrentState(); - return File.ReadAllText(_vm.VMPathToSharePath(Path)); + var result = GetResult(); + if (!result.Exists) + { + throw new FileNotFoundException("File not found: " + Path); + } + return result.StdOut; } } @@ -316,12 +391,21 @@ public VMRemoteDirectory(VirtualMachine vm, string path) : base(path) _vm = vm; } + VMActionResult GetResult() + { + return _vm.Apply(new SerializedVMAction() + { + Type = VMActionType.GetRemoteDirectory, + TargetPath = Path, + IsReadOnly = true + }); + } + public override bool Exists { get { - _vm.SyncToCurrentState(); - return Directory.Exists(_vm.VMPathToSharePath(Path)); + return GetResult().Exists; } } } From faf1b4c4cdeddcf147c06e0afa51bd92ddedc906 Mon Sep 17 00:00:00 2001 From: Daniel Plaisted Date: Thu, 8 Feb 2024 18:28:41 -0500 Subject: [PATCH 393/577] Port workload installation / GC test to new APIs --- .../MsiInstallerTests.cs | 230 ++++++------------ .../RemoteDirectory.cs | 2 + .../RemoteFile.cs | 37 +++ .../dotnet-MsiInstallation.Tests/VMAction.cs | 6 + .../VirtualMachine.cs | 12 +- 5 files changed, 122 insertions(+), 165 deletions(-) diff --git a/src/Tests/dotnet-MsiInstallation.Tests/MsiInstallerTests.cs b/src/Tests/dotnet-MsiInstallation.Tests/MsiInstallerTests.cs index b831979f5b32..2e133ca14fc3 100644 --- a/src/Tests/dotnet-MsiInstallation.Tests/MsiInstallerTests.cs +++ b/src/Tests/dotnet-MsiInstallation.Tests/MsiInstallerTests.cs @@ -89,6 +89,12 @@ public void Dispose() [Fact] public void InstallSdk() { + VM.CreateRunCommand("setx", "DOTNET_NOLOGO", "true") + .WithDescription("Disable .NET SDK first run message") + .Execute() + .Should() + .Pass(); + VM.CreateRunCommand($@"c:\SdkTesting\{SdkInstallerFileName}", "/quiet") .WithDescription($"Install SDK {SdkInstallerVersion}") .Execute() @@ -106,6 +112,14 @@ void ApplyRC1Manifests() .Execute().Should().Pass(); } + void Apply8_0_101Manifests() + { + VM.CreateActionGroup("Rollback to 8.0.101 manifests", + VM.WriteFile($@"C:\SdkTesting\rollback-8.0.101.json", Rollback8_0_101), + VM.CreateRunCommand("dotnet", "workload", "update", "--from-rollback-file", @"c:\SdkTesting\rollback-8.0.101.json", "--skip-sign-check")) + .Execute().Should().Pass(); + } + [Fact] public void InstallWasm() { @@ -113,9 +127,7 @@ public void InstallWasm() ApplyRC1Manifests(); - VM.CreateRunCommand("dotnet", "workload", "install", "wasm-tools", "--skip-manifest-update") - .WithDescription("Install wasm workload") - .Execute().Should().Pass(); + InstallWorkload("wasm-tools"); } [Fact] @@ -125,11 +137,7 @@ public void InstallAndroid() ApplyRC1Manifests(); - VM.CreateRunCommand("dotnet", "workload", "install", "android", "--skip-manifest-update") - .WithDescription("Install android workload") - .Execute() - .Should() - .Pass(); + InstallWorkload("android"); } [Fact] @@ -139,17 +147,9 @@ public void InstallAndroidAndWasm() ApplyRC1Manifests(); - VM.CreateRunCommand("dotnet", "workload", "install", "android", "--skip-manifest-update") - .WithDescription("Install android workload") - .Execute() - .Should() - .Pass(); + InstallWorkload("android"); - VM.CreateRunCommand("dotnet", "workload", "install", "wasm-tools", "--skip-manifest-update") - .WithDescription("Install wasm workload") - .Execute() - .Should() - .Pass(); + InstallWorkload("wasm-tools"); } [Fact] @@ -171,42 +171,8 @@ public async Task UseWMI() await Task.Yield(); } - //[Fact(Skip = "testing")] - //public void UninstallSdk() - //{ - // RunRemoteCommand($@"c:\SdkTesting\{SdkInstallerFileName}", "/quiet", "/uninstall"); - //} - - //[Fact(Skip = "testing")] - //public void SdkInstallation() - //{ - // RunRemoteCommand("dotnet", "--version") - // .Should() - // .HaveStdOut("7.0.401"); - - // RunRemoteCommand($@"c:\SdkTesting\{SdkInstallerFileName}", "/quiet"); - - // new DirectoryInfo($@"\\{TargetMachineName}\c$\Program Files\dotnet\sdk\{SdkInstallerVersion}") - // .Should() - // .Exist(); - - // RunRemoteCommand("dotnet", "--version") - // .Should() - // .HaveStdOut(SdkInstallerVersion); - - // RunRemoteCommand($@"c:\SdkTesting\{SdkInstallerFileName}", "/quiet", "/uninstall"); - - // new DirectoryInfo($@"\\{TargetMachineName}\c$\Program Files\dotnet\sdk\{SdkInstallerVersion}") - // .Should() - // .NotExist(); - - // RunRemoteCommand("dotnet", "--version") - // .Should() - // .HaveStdOut("7.0.401"); - //} - [Fact] - public void SdkInstallation2() + public void SdkInstallation() { GetInstalledSdkVersion().Should().Be("7.0.401"); @@ -235,55 +201,38 @@ public void SdkInstallation2() } - //[Fact(Skip = "testing")] - //public void WorkloadInstallation() - //{ - // //CleanupInstallState(); - - // //RunRemoteCommand($@"c:\SdkTesting\{SdkInstallerFileName}", "/quiet"); - - // //DeployStage2Sdk(); - - // var rollbackResult = RunRemoteCommand("dotnet", "workload", "update", "--print-rollback"); - // rollbackResult.Should().Pass(); - // var originalManifests = ParseRollbackOutput(rollbackResult.StdOut); - - - // RunRemoteCommand("dotnet", "workload", "install", "wasm-tools", "--skip-manifest-update"); - - // RunRemoteCommand("dotnet", "workload", "list", "--machine-readable") - // .Should() - // .HaveStdOutContaining("wasm-tools"); - - // CheckForDuplicateManifests(); + [Fact] + public void WorkloadInstallation() + { + InstallSdk(); - // File.WriteAllText($@"\\{TargetMachineName}\c$\SdkTesting\rollback-rc1.json", RollbackRC1); + var originalManifests = GetRollback(); - // RunRemoteCommand("dotnet", "workload", "update", "--from-rollback-file", @"c:\SdkTesting\rollback-rc1.json", "--skip-sign-check"); + InstallWorkload("wasm-tools"); - // File.WriteAllText($@"\\{TargetMachineName}\c$\SdkTesting\rollback-8.0.101.json", Rollback8_0_101); + ListWorkloads().Should().Contain("wasm-tools"); - // RunRemoteCommand("dotnet", "workload", "update", "--from-rollback-file", @"c:\SdkTesting\rollback-8.0.101.json", "--skip-sign-check"); + CheckForDuplicateManifests(); - // HashSet<(string id, string version, string featureBand)> expectedManifests = new(); - // foreach (var kvp in originalManifests.ManifestVersions.Concat(WorkloadSet.FromJson(Rollback8_0_101, new SdkFeatureBand(SdkInstallerVersion)).ManifestVersions)) - // { - // expectedManifests.Add((kvp.Key.ToString(), kvp.Value.Version.ToString(), kvp.Value.FeatureBand.ToString())); - // } + ApplyRC1Manifests(); - // var unexpectedManifests = GetInstalledManifestVersions() - // .SelectMany(kvp => kvp.Value.Select(v => (id: kvp.Key, version: v.version, featureBand: v.sdkFeatureBand))) - // .Except(expectedManifests); + Apply8_0_101Manifests(); - // if (unexpectedManifests.Any()) - // { - // Assert.Fail($"Unexpected manifests installed: {string.Join(", ", unexpectedManifests)}"); - // } + HashSet<(string id, string version, string featureBand)> expectedManifests = new(); + foreach (var kvp in originalManifests.ManifestVersions.Concat(WorkloadSet.FromJson(Rollback8_0_101, new SdkFeatureBand(SdkInstallerVersion)).ManifestVersions)) + { + expectedManifests.Add((kvp.Key.ToString(), kvp.Value.Version.ToString(), kvp.Value.FeatureBand.ToString())); + } - // //CheckForDuplicateManifests(); + var unexpectedManifests = GetInstalledManifestVersions() + .SelectMany(kvp => kvp.Value.Select(v => (id: kvp.Key, version: v.version, featureBand: v.sdkFeatureBand))) + .Except(expectedManifests); - // //RunRemoteCommand($@"c:\SdkTesting\{SdkInstallerFileName}", "/quiet", "/uninstall"); - //} + if (unexpectedManifests.Any()) + { + Assert.Fail($"Unexpected manifests installed: {string.Join(", ", unexpectedManifests)}"); + } + } //[Fact(Skip = "testing")] //public void InstallStateShouldBeRemovedOnSdkUninstall() @@ -327,7 +276,6 @@ void CheckForDuplicateManifests() { Assert.Fail($"Found multiple manifest versions for {manifestId}: {string.Join(", ", installedVersions)}"); } - //installedVersions.Count.Should().Be(1, $"Only one version of manifest {manifestId} should be installed"); } } @@ -335,7 +283,9 @@ void CheckForDuplicateManifests() { Dictionary> installedManifestVersions = new(); - foreach (var manifestFeatureBandPath in Directory.GetDirectories($@"\\{TargetMachineName}\c$\Program Files\dotnet\sdk-manifests")) + var manifestsRoot = VM.GetRemoteDirectory($@"c:\Program Files\dotnet\sdk-manifests"); + + foreach (var manifestFeatureBandPath in manifestsRoot.Directories) { var manifestFeatureBand = Path.GetFileName(manifestFeatureBandPath); if (manifestFeatureBand.Equals("7.0.100")) @@ -344,15 +294,15 @@ void CheckForDuplicateManifests() continue; } - foreach (var manifestIdPath in Directory.GetDirectories(manifestFeatureBandPath)) + foreach (var manifestIdPath in VM.GetRemoteDirectory(manifestFeatureBandPath).Directories) { var manifestId = Path.GetFileName(manifestIdPath); - new FileInfo(Path.Combine(manifestIdPath, "WorkloadManifest.json")) + VM.GetRemoteFile(Path.Combine(manifestIdPath, "WorkloadManifest.json")) .Should().NotExist("Not expecting non side-by-side workload manifests"); - foreach (var manifestVersionPath in Directory.GetDirectories(manifestIdPath)) + foreach (var manifestVersionPath in VM.GetRemoteDirectory(manifestIdPath).Directories) { - new FileInfo(Path.Combine(manifestVersionPath, "WorkloadManifest.json")) + VM.GetRemoteFile(Path.Combine(manifestVersionPath, "WorkloadManifest.json")) .Should().Exist("Workload manifest should exist"); var manifestVersion = Path.GetFileName(manifestVersionPath); @@ -369,20 +319,6 @@ void CheckForDuplicateManifests() return installedManifestVersions; } - [Fact] - void TempTest() - { - //CleanupInstallState(); - RunRemoteCommand("dotnet", "--version") - .Should() - .HaveStdOut("7.0.401"); - - //RunRemoteCommand($@"c:\SdkTesting\{SdkInstallerFileName}", "/quiet"); - //DeployStage2Sdk(); - //CleanupInstallState(); - //RunRemoteCommand($@"c:\SdkTesting\{SdkInstallerFileName}", "/quiet", "/uninstall"); - } - void DeployStage2Sdk() { Log.WriteLine(TestContext.Current.ToolsetUnderTest.SdkFolderUnderTest); @@ -403,68 +339,46 @@ void DeployStage2Sdk() .Pass(); } - WorkloadSet ParseRollbackOutput(string output) + CommandResult InstallWorkload(string workloadName) { - var filteredOutput = string.Join(Environment.NewLine, - output.Split(Environment.NewLine) - .Except(["==workloadRollbackDefinitionJsonOutputStart==", "==workloadRollbackDefinitionJsonOutputEnd=="])); + var result = VM.CreateRunCommand("dotnet", "workload", "install", workloadName, "--skip-manifest-update") + .WithDescription($"Install {workloadName} workload") + .Execute(); - return WorkloadSet.FromJson(filteredOutput, defaultFeatureBand: new SdkFeatureBand(SdkInstallerVersion)); - } + result.Should().Pass(); + return result; + } - private static void CopyDirectory(string sourcePath, string destPath) + string ListWorkloads() { - if (!Directory.Exists(destPath)) - { - Directory.CreateDirectory(destPath); - } + var result = VM.CreateRunCommand("dotnet", "workload", "list", "--machine-readable") + .WithIsReadOnly(true) + .Execute(); - foreach (var dir in Directory.GetDirectories(sourcePath)) - { - CopyDirectory(dir, Path.Combine(destPath, Path.GetFileName(dir))); - } + result.Should().Pass(); - foreach (var file in Directory.GetFiles(sourcePath)) - { - new FileInfo(file).CopyTo(Path.Combine(destPath, Path.GetFileName(file)), true); - } + return result.StdOut; } - - CommandResult RunRemoteCommand(params string[] args) + WorkloadSet GetRollback() { - var result = new RemoteCommand(Log, args).Execute(); + var result = VM.CreateRunCommand("dotnet", "workload", "update", "--print-rollback") + .WithIsReadOnly(true) + .Execute(); result.Should().Pass(); - return result; + return ParseRollbackOutput(result.StdOut); } - - - class RemoteCommand : TestCommand + WorkloadSet ParseRollbackOutput(string output) { + var filteredOutput = string.Join(Environment.NewLine, + output.Split(Environment.NewLine) + .Except(["==workloadRollbackDefinitionJsonOutputStart==", "==workloadRollbackDefinitionJsonOutputEnd=="])); - - public RemoteCommand(ITestOutputHelper log, params string[] args) - : base(log) - { - Arguments.Add("-nobanner"); - Arguments.Add($@"\\{TargetMachineName}"); - Arguments.AddRange(args); - } - - protected override SdkCommandSpec CreateCommand(IEnumerable args) - { - var sdkCommandSpec = new SdkCommandSpec() - { - FileName = PsExecPath, - Arguments = args.ToList(), - WorkingDirectory = WorkingDirectory, - }; - return sdkCommandSpec; - } + return WorkloadSet.FromJson(filteredOutput, defaultFeatureBand: new SdkFeatureBand(SdkInstallerVersion)); } } } diff --git a/src/Tests/dotnet-MsiInstallation.Tests/RemoteDirectory.cs b/src/Tests/dotnet-MsiInstallation.Tests/RemoteDirectory.cs index 356bd628a589..1c4762e1385e 100644 --- a/src/Tests/dotnet-MsiInstallation.Tests/RemoteDirectory.cs +++ b/src/Tests/dotnet-MsiInstallation.Tests/RemoteDirectory.cs @@ -21,6 +21,8 @@ protected RemoteDirectory(string path) public abstract bool Exists { get; } + public abstract List Directories { get; } + public Assertions Should() { return new Assertions(this); diff --git a/src/Tests/dotnet-MsiInstallation.Tests/RemoteFile.cs b/src/Tests/dotnet-MsiInstallation.Tests/RemoteFile.cs index 8a45c31c7cee..008fdf53474b 100644 --- a/src/Tests/dotnet-MsiInstallation.Tests/RemoteFile.cs +++ b/src/Tests/dotnet-MsiInstallation.Tests/RemoteFile.cs @@ -3,9 +3,11 @@ using System; using System.Collections.Generic; +using System.IO; using System.Linq; using System.Text; using System.Threading.Tasks; +using FluentAssertions.Execution; namespace Microsoft.DotNet.MsiInstallerTests { @@ -20,6 +22,41 @@ public RemoteFile(string path) public string Path { get; } + public abstract bool Exists { get; } + public abstract string ReadAllText(); + + public Assertions Should() + { + return new Assertions(this); + } + + public class Assertions + { + RemoteFile _file; + + public Assertions(RemoteFile file) + { + _file = file; + } + + public AndConstraint Exist(string because = "", params object[] reasonArgs) + { + Execute.Assertion + .ForCondition(_file.Exists) + .BecauseOf(because, reasonArgs) + .FailWith($"Expected File {_file.Path} to exist, but it does not."); + return new AndConstraint(this); + } + + public AndConstraint NotExist(string because = "", params object[] reasonArgs) + { + Execute.Assertion + .ForCondition(!_file.Exists) + .BecauseOf(because, reasonArgs) + .FailWith($"Expected File {_file.Path} to not exist, but it does."); + return new AndConstraint(this); + } + } } } diff --git a/src/Tests/dotnet-MsiInstallation.Tests/VMAction.cs b/src/Tests/dotnet-MsiInstallation.Tests/VMAction.cs index e1381748c967..6cbf2c3c9935 100644 --- a/src/Tests/dotnet-MsiInstallation.Tests/VMAction.cs +++ b/src/Tests/dotnet-MsiInstallation.Tests/VMAction.cs @@ -52,6 +52,12 @@ public VMAction WithDescription(string description) return this; } + public VMAction WithIsReadOnly(bool isReadOnly) + { + IsReadOnly = isReadOnly; + return this; + } + public SerializedVMAction Serialize() { var serialized = SerializeDerivedProperties(); diff --git a/src/Tests/dotnet-MsiInstallation.Tests/VirtualMachine.cs b/src/Tests/dotnet-MsiInstallation.Tests/VirtualMachine.cs index ac1a8bb0ecb6..59bacb0a5044 100644 --- a/src/Tests/dotnet-MsiInstallation.Tests/VirtualMachine.cs +++ b/src/Tests/dotnet-MsiInstallation.Tests/VirtualMachine.cs @@ -372,6 +372,8 @@ VMActionResult GetResult() }); } + public override bool Exists => GetResult().Exists; + public override string ReadAllText() { var result = GetResult(); @@ -401,13 +403,9 @@ VMActionResult GetResult() }); } - public override bool Exists - { - get - { - return GetResult().Exists; - } - } + public override bool Exists => GetResult().Exists; + + public override List Directories => GetResult().Directories; } } } From eb837e4f5789f333a7883e12df9dc8f9cfbea16b Mon Sep 17 00:00:00 2001 From: Daniel Plaisted Date: Thu, 8 Feb 2024 18:47:13 -0500 Subject: [PATCH 394/577] Improve assertion message formatting --- src/Tests/dotnet-MsiInstallation.Tests/MsiInstallerTests.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Tests/dotnet-MsiInstallation.Tests/MsiInstallerTests.cs b/src/Tests/dotnet-MsiInstallation.Tests/MsiInstallerTests.cs index 2e133ca14fc3..a5d82f0e64e9 100644 --- a/src/Tests/dotnet-MsiInstallation.Tests/MsiInstallerTests.cs +++ b/src/Tests/dotnet-MsiInstallation.Tests/MsiInstallerTests.cs @@ -230,7 +230,7 @@ public void WorkloadInstallation() if (unexpectedManifests.Any()) { - Assert.Fail($"Unexpected manifests installed: {string.Join(", ", unexpectedManifests)}"); + Assert.Fail($"Unexpected manifests installed:\r\n{string.Join(Environment.NewLine, unexpectedManifests.Select(m => $"{m.id} {m.version}/{m.featureBand}"))}"); } } From dff6463e9153321112cc90a44a3113a58f98a3cf Mon Sep 17 00:00:00 2001 From: Daniel Plaisted Date: Sun, 11 Feb 2024 21:06:48 -0500 Subject: [PATCH 395/577] Trim deleted snapshots, better logging for grouped actions --- .../Commands/TestCommand.cs | 21 +++-- .../dotnet-MsiInstallation.Tests/VMAction.cs | 16 ++-- .../VirtualMachine.cs | 78 ++++++++++++++++--- 3 files changed, 92 insertions(+), 23 deletions(-) diff --git a/src/Tests/Microsoft.NET.TestFramework/Commands/TestCommand.cs b/src/Tests/Microsoft.NET.TestFramework/Commands/TestCommand.cs index dfef5f0f2311..0a743c4a0c89 100644 --- a/src/Tests/Microsoft.NET.TestFramework/Commands/TestCommand.cs +++ b/src/Tests/Microsoft.NET.TestFramework/Commands/TestCommand.cs @@ -132,22 +132,27 @@ public virtual CommandResult Execute(IEnumerable args) var result = ((Command)command).Execute(ProcessStartedHandler); - Log.WriteLine($"> {result.StartInfo.FileName} {result.StartInfo.Arguments}"); - Log.WriteLine(result.StdOut); + LogCommandResult(Log, result); + + return result; + } + + public static void LogCommandResult(ITestOutputHelper log, CommandResult result) + { + log.WriteLine($"> {result.StartInfo.FileName} {result.StartInfo.Arguments}"); + log.WriteLine(result.StdOut); if (!string.IsNullOrEmpty(result.StdErr)) { - Log.WriteLine(""); - Log.WriteLine("StdErr:"); - Log.WriteLine(result.StdErr); + log.WriteLine(""); + log.WriteLine("StdErr:"); + log.WriteLine(result.StdErr); } if (result.ExitCode != 0) { - Log.WriteLine($"Exit Code: {result.ExitCode}"); + log.WriteLine($"Exit Code: {result.ExitCode}"); } - - return result; } } } diff --git a/src/Tests/dotnet-MsiInstallation.Tests/VMAction.cs b/src/Tests/dotnet-MsiInstallation.Tests/VMAction.cs index 6cbf2c3c9935..3b20a2fac339 100644 --- a/src/Tests/dotnet-MsiInstallation.Tests/VMAction.cs +++ b/src/Tests/dotnet-MsiInstallation.Tests/VMAction.cs @@ -306,15 +306,19 @@ class VMActionResult public List Directories { get; set; } public List Files { get; set; } + public List GroupedResults { get; set; } + public CommandResult ToCommandResult() { + var psi = new ProcessStartInfo + { + FileName = Filename, + // This doesn't handle quoting arguments with spaces correctly, but we don't expect this to be used except for logging + Arguments = Arguments == null ? null : string.Join(" ", Arguments), + }; + return new CommandResult( - Arguments == null ? null : new ProcessStartInfo - { - FileName = Arguments[0], - // This doesn't handle quoting arguments with spaces correctly, but we don't expect this to be used except for logging - Arguments = string.Join(" ", Arguments.Skip(1)), - }, + psi, ExitCode, StdOut, StdErr); diff --git a/src/Tests/dotnet-MsiInstallation.Tests/VirtualMachine.cs b/src/Tests/dotnet-MsiInstallation.Tests/VirtualMachine.cs index 59bacb0a5044..1b2e9ed269cf 100644 --- a/src/Tests/dotnet-MsiInstallation.Tests/VirtualMachine.cs +++ b/src/Tests/dotnet-MsiInstallation.Tests/VirtualMachine.cs @@ -19,7 +19,7 @@ class VirtualMachine : IDisposable ITestOutputHelper Log { get; } public VMControl VMControl { get; } - static VMStateTree _rootState; + VMStateTree _rootState; VMStateTree _currentState; VMStateTree _currentAppliedState; @@ -43,17 +43,30 @@ public VirtualMachine(ITestOutputHelper log) } else { - if (_rootState == null) + var snapshots = VMControl.GetSnapshots(); + var testStartSnapshots = snapshots.Where(s => s.name.Contains("Test start", StringComparison.OrdinalIgnoreCase)).ToList(); + if (testStartSnapshots.Count == 0) { - _rootState = new VMStateTree() + throw new Exception("No test start snapshots found"); + } + else if (testStartSnapshots.Count > 1) + { + foreach (var snapshot in testStartSnapshots) { - SnapshotId = "CF853278-1B6B-4816-8E51-FBDBE3AABA2C", - SnapshotName = "Initial test state (Set network to private)", - }; + Log.WriteLine(snapshot.id + ": " + snapshot.name); + } + throw new Exception("Multiple test start snapshots found"); } + _rootState = new VMStateTree + { + SnapshotId = testStartSnapshots[0].Item1, + SnapshotName = testStartSnapshots[0].Item2 + }; } _currentState = _rootState; + + TrimMissingSnapshots(); } public void Dispose() { @@ -73,6 +86,28 @@ JsonSerializerOptions GetSerializerOptions() }; } + public void TrimMissingSnapshots() + { + var snapshotIds = VMControl.GetSnapshots().Select(s => s.id).ToHashSet(); + + Recurse(_rootState); + + void Recurse(VMStateTree node) + { + var nodesToRemove = node.Actions.Where(a => !snapshotIds.Contains(a.Value.resultingState.SnapshotId)).ToList(); + foreach (var nodeToRemove in nodesToRemove) + { + Log.WriteLine($"Removing missing snapshot from tree: {nodeToRemove.Value.resultingState.SnapshotName}"); + node.Actions.Remove(nodeToRemove.Key); + } + + foreach (var result in node.Actions.Select(a => a.Value.resultingState)) + { + Recurse(result); + } + } + } + public VMRunAction CreateRunCommand(params string[] args) { return new VMRunAction(this, args.ToList()); @@ -133,6 +168,21 @@ void SyncToCurrentState() } } + void LogActionResult(SerializedVMAction action, VMActionResult result) + { + if (action.Type == VMActionType.RunCommand) + { + TestCommand.LogCommandResult(Log, result.ToCommandResult()); + } + else if (action.Type == VMActionType.ActionGroup && result.GroupedResults != null) + { + for (int i=0; i results = new(); foreach (var subAction in action.Actions) { - lastResult = Run(subAction); + results.Add(Run(subAction)); } + var result = VMActionResult.Success(); + if (results.Any()) + { + result.ExitCode = results.Last().ExitCode; + result.StdOut = results.Last().StdOut; + result.StdErr = results.Last().StdErr; + } + result.GroupedResults = results; - return lastResult; + return result; } else { From 9454ac2bbb848a89187c165a5ef14619a1fbccf5 Mon Sep 17 00:00:00 2001 From: Daniel Plaisted Date: Sun, 11 Feb 2024 21:07:18 -0500 Subject: [PATCH 396/577] Add tests for install state removal and repeated rollback --- .../MsiInstallerTests.cs | 87 +++++++++++-------- 1 file changed, 53 insertions(+), 34 deletions(-) diff --git a/src/Tests/dotnet-MsiInstallation.Tests/MsiInstallerTests.cs b/src/Tests/dotnet-MsiInstallation.Tests/MsiInstallerTests.cs index a5d82f0e64e9..e3f0809af62b 100644 --- a/src/Tests/dotnet-MsiInstallation.Tests/MsiInstallerTests.cs +++ b/src/Tests/dotnet-MsiInstallation.Tests/MsiInstallerTests.cs @@ -33,8 +33,6 @@ public class WorkloadTests : SdkTest, IDisposable // Reminder: Enable "Remote Service Management" firewall rule so that PSExec will run more quickly. Make sure network is set to "Private" in Windows settings (or enable the firewall rule for public networks). - const string TargetMachineName = "dsp-vm"; - const string PsExecPath = @"C:\Users\Daniel\Downloads\PSTools\PsExec.exe"; const string SdkInstallerVersion = "8.0.100"; const string SdkInstallerFileName = $"dotnet-sdk-{SdkInstallerVersion}-win-x64.exe"; @@ -104,20 +102,33 @@ public void InstallSdk() DeployStage2Sdk(); } - void ApplyRC1Manifests() + void UninstallSdk() { - VM.CreateActionGroup("Rollback to RC1 manifests", - VM.WriteFile($@"C:\SdkTesting\rollback-rc1.json", RollbackRC1), - VM.CreateRunCommand("dotnet", "workload", "update", "--from-rollback-file", @"c:\SdkTesting\rollback-rc1.json", "--skip-sign-check")) - .Execute().Should().Pass(); + VM.CreateRunCommand($@"c:\SdkTesting\{SdkInstallerFileName}", "/quiet", "/uninstall") + .WithDescription($"Uninstall SDK {SdkInstallerVersion}") + .Execute() + .Should() + .Pass(); + } + + private CommandResult ApplyManifests(string manifestContents, string rollbackID) + { + CommandResult result = VM.CreateActionGroup("Rollback to " + rollbackID + " manifests", + VM.WriteFile($@"c:\SdkTesting\rollback-{rollbackID}.json", manifestContents), + VM.CreateRunCommand("dotnet", "workload", "update", "--from-rollback-file", $@"c:\SdkTesting\rollback-{rollbackID}.json", "--skip-sign-check")) + .Execute(); + result.Should().Pass(); + return result; } - void Apply8_0_101Manifests() + CommandResult ApplyRC1Manifests() { - VM.CreateActionGroup("Rollback to 8.0.101 manifests", - VM.WriteFile($@"C:\SdkTesting\rollback-8.0.101.json", Rollback8_0_101), - VM.CreateRunCommand("dotnet", "workload", "update", "--from-rollback-file", @"c:\SdkTesting\rollback-8.0.101.json", "--skip-sign-check")) - .Execute().Should().Pass(); + return ApplyManifests(RollbackRC1, "rc1"); + } + + CommandResult Apply8_0_101Manifests() + { + return ApplyManifests(Rollback8_0_101, "8.0.101"); } [Fact] @@ -202,7 +213,7 @@ public void SdkInstallation() [Fact] - public void WorkloadInstallation() + public void WorkloadInstallationAndGarbageCollection() { InstallSdk(); @@ -234,18 +245,35 @@ public void WorkloadInstallation() } } - //[Fact(Skip = "testing")] - //public void InstallStateShouldBeRemovedOnSdkUninstall() - //{ - // // This is currently broken, needs to be added to the finalizer - // throw new NotImplementedException(); - //} + [Fact] + public void InstallStateShouldBeRemovedOnSdkUninstall() + { + InstallSdk(); + InstallWorkload("wasm-tools"); + ApplyRC1Manifests(); + var featureBand = new SdkFeatureBand(SdkInstallerVersion); + var installStatePath = $@"c:\ProgramData\dotnet\workloads\{featureBand}\InstallState\default.json"; + VM.GetRemoteFile(installStatePath).Should().Exist(); + UninstallSdk(); + VM.GetRemoteFile(installStatePath).Should().NotExist(); + } + + [Fact] + public void RepeatedUpdateToSameRollbackFile() + { + InstallSdk(); + InstallWorkload("wasm-tools"); + ApplyRC1Manifests(); + ApplyRC1Manifests() + .Should() + .NotHaveStdOutContaining("Installing"); + } - //[Fact(Skip = "testing")] - //public void RepeatedUpdateToSameRollbackFile() - //{ - // // Should not install or uninstall anything - //} + [Fact] + public void ShouldNotShowRebootMessage() + { + throw new NotImplementedException(); + } string GetInstalledSdkVersion() { @@ -256,16 +284,6 @@ string GetInstalledSdkVersion() return result.StdOut; } - void CleanupInstallState() - { - var featureBand = new SdkFeatureBand(SdkInstallerVersion); - string installStatePath = $@"\\{TargetMachineName}\c$\ProgramData\dotnet\workloads\{featureBand}\InstallState\default.json"; - if (File.Exists(installStatePath)) - { - File.Delete(installStatePath); - } - } - void CheckForDuplicateManifests() { var installedManifestVersions = GetInstalledManifestVersions(); @@ -331,6 +349,7 @@ void DeployStage2Sdk() var newVersionFileContents = File.ReadAllLines(Path.Combine(TestContext.Current.ToolsetUnderTest.SdkFolderUnderTest, ".version")); newVersionFileContents[1] = existingVersionFileContents[1]; + // TODO: It would be nice if the description included the date/time of the SDK build, to distinguish different snapshots VM.CreateActionGroup("Deploy Stage 2 SDK", VM.CopyFolder(TestContext.Current.ToolsetUnderTest.SdkFolderUnderTest, installedSdkFolder), VM.WriteFile(vmVersionFilePath, string.Join(Environment.NewLine, newVersionFileContents))) From 547312a1b250e36038923e37d65f73b6879e14fb Mon Sep 17 00:00:00 2001 From: Daniel Plaisted Date: Mon, 12 Feb 2024 10:52:02 -0500 Subject: [PATCH 397/577] Add sanity check for wasm workload --- Directory.Packages.props | 1 - .../MsiInstallerTests.cs | 74 +++++++++++-------- .../dotnet-MsiInstallation.Tests/VMAction.cs | 24 ++++++ .../dotnet-MsiInstallation.Tests/VMControl.cs | 15 +++- .../VirtualMachine.cs | 24 +++++- .../dotnet-MsiInstallation.Tests.csproj | 1 - 6 files changed, 101 insertions(+), 38 deletions(-) diff --git a/Directory.Packages.props b/Directory.Packages.props index 5e9ea4aefb2a..f785a3f751ee 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -90,7 +90,6 @@ - diff --git a/src/Tests/dotnet-MsiInstallation.Tests/MsiInstallerTests.cs b/src/Tests/dotnet-MsiInstallation.Tests/MsiInstallerTests.cs index e3f0809af62b..73abf6aec52e 100644 --- a/src/Tests/dotnet-MsiInstallation.Tests/MsiInstallerTests.cs +++ b/src/Tests/dotnet-MsiInstallation.Tests/MsiInstallerTests.cs @@ -15,6 +15,7 @@ //using System.Management; using Microsoft.Management.Infrastructure; using System.Xml.Linq; +using Microsoft.Build.Evaluation; namespace Microsoft.DotNet.MsiInstallerTests { @@ -33,7 +34,7 @@ public class WorkloadTests : SdkTest, IDisposable // Reminder: Enable "Remote Service Management" firewall rule so that PSExec will run more quickly. Make sure network is set to "Private" in Windows settings (or enable the firewall rule for public networks). - const string SdkInstallerVersion = "8.0.100"; + const string SdkInstallerVersion = "8.0.101"; const string SdkInstallerFileName = $"dotnet-sdk-{SdkInstallerVersion}-win-x64.exe"; const string RollbackRC1 = """ @@ -84,8 +85,7 @@ public void Dispose() VM.Dispose(); } - [Fact] - public void InstallSdk() + void InstallSdk(bool deployStage2 = true) { VM.CreateRunCommand("setx", "DOTNET_NOLOGO", "true") .WithDescription("Disable .NET SDK first run message") @@ -99,7 +99,10 @@ public void InstallSdk() .Should() .Pass(); - DeployStage2Sdk(); + if (deployStage2) + { + DeployStage2Sdk(); + } } void UninstallSdk() @@ -163,35 +166,12 @@ public void InstallAndroidAndWasm() InstallWorkload("wasm-tools"); } - [Fact] - public async Task UseWMI() - { - var snapshots = VM.VMControl.GetSnapshots(); - - foreach (var snapshot in snapshots) - { - Log.WriteLine(snapshot.id + ": " + snapshot.name); - - //await vm.RenameSnapshot(snapshot.id, snapshot.name + " - renamed"); - } - - //await VM.CreateSnapshotAsync("New test snapshot"); - - //await VM.ApplySnapshotAsync("9BA74A78-D221-436E-9875-0A3BF86CEF4A"); - - await Task.Yield(); - } - [Fact] public void SdkInstallation() { GetInstalledSdkVersion().Should().Be("7.0.401"); - VM.CreateRunCommand($@"c:\SdkTesting\{SdkInstallerFileName}", "/quiet") - .WithDescription($"Install SDK {SdkInstallerVersion}") - .Execute() - .Should() - .Pass(); + InstallSdk(deployStage2: false); VM.GetRemoteDirectory($@"c:\Program Files\dotnet\sdk\{SdkInstallerVersion}") .Should() @@ -199,10 +179,7 @@ public void SdkInstallation() GetInstalledSdkVersion().Should().Be(SdkInstallerVersion); - VM.CreateRunCommand($@"c:\SdkTesting\{SdkInstallerFileName}", "/quiet", "/uninstall") - .Execute() - .Should() - .Pass(); + UninstallSdk(); VM.GetRemoteDirectory($@"c:\Program Files\dotnet\sdk\{SdkInstallerVersion}") .Should() @@ -245,6 +222,7 @@ public void WorkloadInstallationAndGarbageCollection() } } + // Fixed by https://github.com/dotnet/installer/pull/18266 [Fact] public void InstallStateShouldBeRemovedOnSdkUninstall() { @@ -264,6 +242,8 @@ public void RepeatedUpdateToSameRollbackFile() InstallSdk(); InstallWorkload("wasm-tools"); ApplyRC1Manifests(); + + TestWasmWorkload(); ApplyRC1Manifests() .Should() .NotHaveStdOutContaining("Installing"); @@ -275,6 +255,12 @@ public void ShouldNotShowRebootMessage() throw new NotImplementedException(); } + [Fact] + public void ApplyRollbackShouldNotUpdateAdvertisingManifests() + { + throw new NotImplementedException(); + } + string GetInstalledSdkVersion() { var command = VM.CreateRunCommand("dotnet", "--version"); @@ -284,6 +270,30 @@ string GetInstalledSdkVersion() return result.StdOut; } + void TestWasmWorkload() + { + var snapshot = VM.CreateSnapshot(); + + VM.CreateRunCommand("dotnet", "new", "blazorwasm", "-o", "BlazorWasm") + .WithWorkingDirectory(@"c:\SdkTesting") + .Execute() + .Should() + .Pass(); + + var result = VM.CreateRunCommand("dotnet", "publish", "/p:RunAotCompilation=true") + .WithWorkingDirectory(@"c:\SdkTesting\BlazorWasm") + .Execute(); + + result.Should().Pass(); + + // When publishing a blazorwasm project without the wasm-tools workload installed, the following message is displayed: + // Publishing without optimizations. Although it's optional for Blazor, we strongly recommend using `wasm-tools` workload! You can install it by running `dotnet workload install wasm-tools` from the command line. + // (Setting RunAotCompilation=true explicitly causes a build failure if the workload isn't installed) + result.Should().NotHaveStdOutContaining("Publishing without optimizations"); + + snapshot.Apply(); + } + void CheckForDuplicateManifests() { var installedManifestVersions = GetInstalledManifestVersions(); diff --git a/src/Tests/dotnet-MsiInstallation.Tests/VMAction.cs b/src/Tests/dotnet-MsiInstallation.Tests/VMAction.cs index 3b20a2fac339..53555acfdee7 100644 --- a/src/Tests/dotnet-MsiInstallation.Tests/VMAction.cs +++ b/src/Tests/dotnet-MsiInstallation.Tests/VMAction.cs @@ -72,17 +72,26 @@ class VMRunAction : VMAction { public List Arguments { get; set; } + public string WorkingDirectory { get; set; } + public VMRunAction(VirtualMachine vm, List arguments = null) : base(vm) { Arguments = arguments ?? new List(); } + public VMRunAction WithWorkingDirectory(string workingDirectory) + { + WorkingDirectory = workingDirectory; + return this; + } + protected override SerializedVMAction SerializeDerivedProperties() { return new SerializedVMAction { Type = VMActionType.RunCommand, Arguments = Arguments, + WorkingDirectory = WorkingDirectory, }; } } @@ -193,6 +202,9 @@ class SerializedVMAction // Applies to RunCommand public List Arguments { get; set; } + // Applies to RunCommand + public string WorkingDirectory { get; set; } + // Applies to CopyFileToVM, CopyFolderToVM, WriteFileToVM, GetRemoteDirectory, GetRemoteFile public string TargetPath { get; set; } @@ -262,6 +274,7 @@ static bool ListsAreEqual(List a, List b) ExplicitDescription == action.ExplicitDescription && IsReadOnly == action.IsReadOnly && ListsAreEqual(Arguments, action.Arguments) && + WorkingDirectory == action.WorkingDirectory && TargetPath == action.TargetPath && SourcePath == action.SourcePath && ContentId == action.ContentId && @@ -273,6 +286,8 @@ public override int GetHashCode() { var hashcode = new HashCode(); hashcode.Add(Type); + hashcode.Add(ExplicitDescription); + hashcode.Add(IsReadOnly); if (Arguments != null) { hashcode.Add(Arguments.Count); @@ -281,10 +296,19 @@ public override int GetHashCode() hashcode.Add(arg.GetHashCode()); } } + hashcode.Add(WorkingDirectory); hashcode.Add(TargetPath); hashcode.Add(SourcePath); hashcode.Add(ContentId); hashcode.Add(FileContents); + if (Actions != null) + { + hashcode.Add(Actions.Count); + foreach (var action in Actions) + { + hashcode.Add(action.GetHashCode()); + } + } return hashcode.ToHashCode(); } diff --git a/src/Tests/dotnet-MsiInstallation.Tests/VMControl.cs b/src/Tests/dotnet-MsiInstallation.Tests/VMControl.cs index e42540293ab0..4eff7cb88d66 100644 --- a/src/Tests/dotnet-MsiInstallation.Tests/VMControl.cs +++ b/src/Tests/dotnet-MsiInstallation.Tests/VMControl.cs @@ -45,9 +45,9 @@ public VMControl(ITestOutputHelper log) _session = CimSession.Create(Environment.MachineName); } - public CommandResult RunCommandOnVM(params string[] args) + public CommandResult RunCommandOnVM(string[] args, string workingDirectory = null) { - var remoteCommand = new RemoteCommand(Log, VMMachineName, PsExecPath, args); + var remoteCommand = new RemoteCommand(Log, VMMachineName, PsExecPath, workingDirectory, args); for (int i=0; i<3; i++) { @@ -398,16 +398,25 @@ class RemoteCommand : TestCommand { string _targetMachineName; string _psExecPath; + string _workingDirectory; - public RemoteCommand(ITestOutputHelper log, string targetMachineName, string psExecPath, params string[] args) + public RemoteCommand(ITestOutputHelper log, string targetMachineName, string psExecPath, string workingDirectory, string[] args) : base(log) { _targetMachineName = targetMachineName; _psExecPath = psExecPath; + _workingDirectory = workingDirectory; Arguments.Add("-nobanner"); Arguments.Add($@"\\{_targetMachineName}"); + + if (!string.IsNullOrEmpty(workingDirectory)) + { + Arguments.Add("-w"); + Arguments.Add(workingDirectory); + } + Arguments.AddRange(args); } diff --git a/src/Tests/dotnet-MsiInstallation.Tests/VirtualMachine.cs b/src/Tests/dotnet-MsiInstallation.Tests/VirtualMachine.cs index 1b2e9ed269cf..fe42426f71f9 100644 --- a/src/Tests/dotnet-MsiInstallation.Tests/VirtualMachine.cs +++ b/src/Tests/dotnet-MsiInstallation.Tests/VirtualMachine.cs @@ -159,6 +159,11 @@ public RemoteDirectory GetRemoteDirectory(string path) return new VMRemoteDirectory(this, path); } + public VMSnapshot CreateSnapshot() + { + return new VMSnapshot(this, _currentState); + } + void SyncToCurrentState() { if (_currentAppliedState != _currentState) @@ -242,7 +247,7 @@ VMActionResult Run(SerializedVMAction action) { if (action.Type == VMActionType.RunCommand) { - var result = VMControl.RunCommandOnVM(action.Arguments.ToArray()); + var result = VMControl.RunCommandOnVM(action.Arguments.ToArray(), workingDirectory: action.WorkingDirectory); return new VMActionResult { Filename = action.Arguments[0], @@ -467,5 +472,22 @@ VMActionResult GetResult() public override List Directories => GetResult().Directories; } + + public class VMSnapshot + { + VirtualMachine _vm; + VMStateTree _snapshot; + + public VMSnapshot(VirtualMachine vm, VMStateTree snapshot) + { + _vm = vm; + _snapshot = snapshot; + } + + public void Apply() + { + _vm._currentState = _snapshot; + } + } } } diff --git a/src/Tests/dotnet-MsiInstallation.Tests/dotnet-MsiInstallation.Tests.csproj b/src/Tests/dotnet-MsiInstallation.Tests/dotnet-MsiInstallation.Tests.csproj index 791307c67819..78a9e1fb3cd3 100644 --- a/src/Tests/dotnet-MsiInstallation.Tests/dotnet-MsiInstallation.Tests.csproj +++ b/src/Tests/dotnet-MsiInstallation.Tests/dotnet-MsiInstallation.Tests.csproj @@ -25,7 +25,6 @@ - From ef2ddc18ccad0a67a33fc2588f2afa12245a7d2f Mon Sep 17 00:00:00 2001 From: Daniel Plaisted Date: Tue, 13 Feb 2024 13:17:53 -0500 Subject: [PATCH 398/577] Add InstallWithRollback test --- .../MsiInstallerTests.cs | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/src/Tests/dotnet-MsiInstallation.Tests/MsiInstallerTests.cs b/src/Tests/dotnet-MsiInstallation.Tests/MsiInstallerTests.cs index 73abf6aec52e..9fe527157023 100644 --- a/src/Tests/dotnet-MsiInstallation.Tests/MsiInstallerTests.cs +++ b/src/Tests/dotnet-MsiInstallation.Tests/MsiInstallerTests.cs @@ -237,18 +237,34 @@ public void InstallStateShouldBeRemovedOnSdkUninstall() } [Fact] - public void RepeatedUpdateToSameRollbackFile() + public void UpdateWithRollback() { InstallSdk(); InstallWorkload("wasm-tools"); ApplyRC1Manifests(); TestWasmWorkload(); + + // Second time applying same rollback file shouldn't do anything ApplyRC1Manifests() .Should() .NotHaveStdOutContaining("Installing"); } + [Fact] + public void InstallWithRollback() + { + InstallSdk(); + + VM.WriteFile($@"c:\SdkTesting\rollback-rc1.json", RollbackRC1) + .Execute().Should().Pass(); + + VM.CreateRunCommand("dotnet", "workload", "install", "wasm-tools", "--from-rollback-file", $@"c:\SdkTesting\rollback-rc1.json") + .Execute().Should().Pass(); + + TestWasmWorkload(); + } + [Fact] public void ShouldNotShowRebootMessage() { From 15e7a52dbc69d0ee11ceb299fc459533deaf870c Mon Sep 17 00:00:00 2001 From: Daniel Plaisted Date: Tue, 13 Feb 2024 13:51:32 -0500 Subject: [PATCH 399/577] Doc WIP --- src/Tests/dotnet-MsiInstallation.Tests/README.md | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 src/Tests/dotnet-MsiInstallation.Tests/README.md diff --git a/src/Tests/dotnet-MsiInstallation.Tests/README.md b/src/Tests/dotnet-MsiInstallation.Tests/README.md new file mode 100644 index 000000000000..d00b9966687a --- /dev/null +++ b/src/Tests/dotnet-MsiInstallation.Tests/README.md @@ -0,0 +1,14 @@ +# VM-based installation tests + +On Windows, when the .NET SDK is installed either via the standalone installer or by Visual Studio, it is installed to the Program Files folder. In both cases it uses MSIs under the hood, so we call this an MSI-based install (as opposed to a file-based install which consists of unzipping or copying the .NET SDK files to an arbitrary folder). + +For an MSI-based .NET SDK install, .NET SDK workloads are also installed using MSIs. This modifies global machine state, which makes it hard to write automated tests for MSI-based workload operations. + +To address this, the MSI Installation tests use a Virtual Machine as the target environment to install the .NET SDK and workloads. APIs to run commands on the Virtual Machine or to inspect its file system are available and are similar to the test APIs used in other tests in the repo. + +Because installation actions can be fairly slow, the test infrastructure uses VM snapshots (also called checkpoints) to avoid repeating an action that was already run. Thus, if multiple tests have the same setup steps, those steps won't be repeated for each test, rather the correct snapshot will be applied when needed. As tests are run, a tree of states (with corresponding snapshots) and actions to transition between them are built up from the initial state. This tree of states is saved across test runs, so if nothing has changed then running a test a second time should complete very quickly, as all of the results of the test actions were already recorded. + +## Setting up a VM for running tests + +- [Enable Hyper-V](https://learn.microsoft.com/en-us/virtualization/hyper-v-on-windows/quick-start/enable-hyper-v) +- Create a Hyper-V Virtual Machine. A simple way to do this is to use "Quick Create" and choose "Windows 11 dev environment". This currently creates a VM with Visual Studio 17.7 and .NET SDK 7.0.401 installed. For now the tests are written to take this into account, in the future we may want to start with a clean installation of Windows. \ No newline at end of file From a14ce4d494ea5e5b9bf54add2ff6f57f5fedd290 Mon Sep 17 00:00:00 2001 From: Daniel Plaisted Date: Tue, 13 Feb 2024 15:20:09 -0500 Subject: [PATCH 400/577] WIP --- src/Tests/dotnet-MsiInstallation.Tests/MsiInstallerTests.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Tests/dotnet-MsiInstallation.Tests/MsiInstallerTests.cs b/src/Tests/dotnet-MsiInstallation.Tests/MsiInstallerTests.cs index 9fe527157023..214603d3f311 100644 --- a/src/Tests/dotnet-MsiInstallation.Tests/MsiInstallerTests.cs +++ b/src/Tests/dotnet-MsiInstallation.Tests/MsiInstallerTests.cs @@ -30,6 +30,7 @@ public class WorkloadTests : SdkTest, IDisposable // Also see https://stackoverflow.com/questions/1735978/manipulate-hyper-v-from-net // Official documentation?: https://learn.microsoft.com/en-us/windows/win32/hyperv_v2/exporting-virtual-machines // How to rename a snapshot: https://stackoverflow.com/questions/7599217/setting-hyper-v-snapshots-name-programmatically + // There is a 50 checkpoint max // Reminder: Enable "Remote Service Management" firewall rule so that PSExec will run more quickly. Make sure network is set to "Private" in Windows settings (or enable the firewall rule for public networks). From 5d64292af0986fa8cd80566fb0ae99d77e627d27 Mon Sep 17 00:00:00 2001 From: Daniel Plaisted Date: Tue, 13 Feb 2024 17:00:11 -0500 Subject: [PATCH 401/577] WIP --- src/Tests/dotnet-MsiInstallation.Tests/README.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/Tests/dotnet-MsiInstallation.Tests/README.md b/src/Tests/dotnet-MsiInstallation.Tests/README.md index d00b9966687a..e3fb38478db4 100644 --- a/src/Tests/dotnet-MsiInstallation.Tests/README.md +++ b/src/Tests/dotnet-MsiInstallation.Tests/README.md @@ -11,4 +11,14 @@ Because installation actions can be fairly slow, the test infrastructure uses VM ## Setting up a VM for running tests - [Enable Hyper-V](https://learn.microsoft.com/en-us/virtualization/hyper-v-on-windows/quick-start/enable-hyper-v) +- For the tests to remotely control the VM, your host computer needs to be able to access the VM over the network. To enable this, you need to create a virtual switch for the VM which will also be shared by the host PC. In Hyper-V Manager, go to Virtual Switch Manager. Create a new Virtual Switch connected to your external network adapter, and check the box that says "Allow management operating system to share this network adapter." +- Create a Hyper-V Virtual machine. + - You can download a Windows 11 .iso here: https://www.microsoft.com/en-us/software-download/windows11/ + - In the networking configuration for the VM, select the Virtual Switch you created + - Under Security, check "Enable Trusted Platform Module" (and possibly the "Encrypt state..." checkbox under it), which is required to install Windows 11 + - Start the VM and install Windows + - Probably you don't want to sign on to the test VM with a Microsoft account. Setting up with a local account is tricky, but you can do so with these steps: https://www.tomshardware.com/how-to/install-windows-11-without-microsoft-account + - In the VM settings in Hyper-V manager, enable all the integration services (so you can copy/paste files to the VM, for example) +- + - Create a Hyper-V Virtual Machine. A simple way to do this is to use "Quick Create" and choose "Windows 11 dev environment". This currently creates a VM with Visual Studio 17.7 and .NET SDK 7.0.401 installed. For now the tests are written to take this into account, in the future we may want to start with a clean installation of Windows. \ No newline at end of file From 747f47cce62ab58d4bfe11e694df80ffbd9db7c8 Mon Sep 17 00:00:00 2001 From: Daniel Plaisted Date: Tue, 13 Feb 2024 21:25:07 -0500 Subject: [PATCH 402/577] WIP docs --- .../dotnet-MsiInstallation.Tests/README.md | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/src/Tests/dotnet-MsiInstallation.Tests/README.md b/src/Tests/dotnet-MsiInstallation.Tests/README.md index e3fb38478db4..9a583ec4168e 100644 --- a/src/Tests/dotnet-MsiInstallation.Tests/README.md +++ b/src/Tests/dotnet-MsiInstallation.Tests/README.md @@ -10,15 +10,28 @@ Because installation actions can be fairly slow, the test infrastructure uses VM ## Setting up a VM for running tests +The main requirements for running the tests are: + +- A Hyper-V Virtual Machine +- Access to the VM via the admin share (`\\TestVM\c$`) +- [PsExec](https://learn.microsoft.com/en-us/sysinternals/downloads/psexec) on the PATH of the host machine +- "Remote Service Management" enabled in firewall settings inside the VM (this avoids a delay of 15-30 seconds for each command that is run) + +Detailed steps: + - [Enable Hyper-V](https://learn.microsoft.com/en-us/virtualization/hyper-v-on-windows/quick-start/enable-hyper-v) - For the tests to remotely control the VM, your host computer needs to be able to access the VM over the network. To enable this, you need to create a virtual switch for the VM which will also be shared by the host PC. In Hyper-V Manager, go to Virtual Switch Manager. Create a new Virtual Switch connected to your external network adapter, and check the box that says "Allow management operating system to share this network adapter." -- Create a Hyper-V Virtual machine. +- Create a Hyper-V Virtual machine + - You will need to choose a name for the virtual machine (used by the host) and a machine name for it when setting up Windows inside the VM. You can choose whatever names you want, but "Test VM" and "TestVM" are good defaults. - You can download a Windows 11 .iso here: https://www.microsoft.com/en-us/software-download/windows11/ - In the networking configuration for the VM, select the Virtual Switch you created - Under Security, check "Enable Trusted Platform Module" (and possibly the "Encrypt state..." checkbox under it), which is required to install Windows 11 - Start the VM and install Windows - Probably you don't want to sign on to the test VM with a Microsoft account. Setting up with a local account is tricky, but you can do so with these steps: https://www.tomshardware.com/how-to/install-windows-11-without-microsoft-account - In the VM settings in Hyper-V manager, enable all the integration services (so you can copy/paste files to the VM, for example) -- +- In network settings inside the VM, switch the network connection type to Private Network, and turn on Network discovery and File and printer sharing. +- Inside the VM, set the HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System\LocalAccountTokenFilterPolicy registry value to 1 ([reference](https://learn.microsoft.com/en-us/troubleshoot/windows-server/windows-security/user-account-control-and-remote-restriction)). This will allow you to access the admin share (`\\TestVM\c$`). +- Browse to the admin share in File Explorer to confirm it's working. You will need to enter the username and password for the VM. Select the option to save the login information. This will allow the tests to access the VM. +- Inside the VM, go to "Allow an app through Windows Firewall", and add "Remote Service Management" to the list of allowed apps and features. This allows PsExec to launch commands quickly, otherwise there is a delay of around 15-30 seconds for each command that is run. +- Download PSTools, extract them somewhere, and add that folder to your PATH. Run something like `psexec \\TestVM cmd /c dir c:\` to verify that PsExec can run commands on the VM. The command should complete in less than a second, if it takes longer then the Remote Service Management firewall rule is probably not enabled correctly. -- Create a Hyper-V Virtual Machine. A simple way to do this is to use "Quick Create" and choose "Windows 11 dev environment". This currently creates a VM with Visual Studio 17.7 and .NET SDK 7.0.401 installed. For now the tests are written to take this into account, in the future we may want to start with a clean installation of Windows. \ No newline at end of file From 7632c429cc15312339c3bdca07525537d7416acd Mon Sep 17 00:00:00 2001 From: Daniel Plaisted Date: Wed, 14 Feb 2024 07:23:10 -0500 Subject: [PATCH 403/577] WIP --- .../dotnet-MsiInstallation.Tests/VMControl.cs | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/src/Tests/dotnet-MsiInstallation.Tests/VMControl.cs b/src/Tests/dotnet-MsiInstallation.Tests/VMControl.cs index 4eff7cb88d66..774f4e9eba33 100644 --- a/src/Tests/dotnet-MsiInstallation.Tests/VMControl.cs +++ b/src/Tests/dotnet-MsiInstallation.Tests/VMControl.cs @@ -18,10 +18,11 @@ internal class VMControl : IDisposable { public string VMName { get; set; } = "Windows 11 dev environment"; public string VMMachineName { get; set; } = "dsp-vm"; - public string PsExecPath = @"C:\Users\Daniel\Downloads\PSTools\PsExec.exe"; const string virtNamespace = @"root\virtualization\v2"; + string _psExecPath; + public ITestOutputHelper Log { get; } private CimSession _session; @@ -43,11 +44,21 @@ public VMControl(ITestOutputHelper log) Log = log; _session = CimSession.Create(Environment.MachineName); + + if (!ToolsetInfo.TryResolveCommand("PsExec", out _psExecPath)) + { + throw new Exception("Couldn't find PsExec on PATH"); + } + } + + public static List GetVirtualMachines(ITestOutputHelper log) + { + var session = CimSession.Create(Environment.MachineName); } public CommandResult RunCommandOnVM(string[] args, string workingDirectory = null) { - var remoteCommand = new RemoteCommand(Log, VMMachineName, PsExecPath, workingDirectory, args); + var remoteCommand = new RemoteCommand(Log, VMMachineName, _psExecPath, workingDirectory, args); for (int i=0; i<3; i++) { From 061f974f4d7321f9cfd3ed54378d43cc95c24d49 Mon Sep 17 00:00:00 2001 From: Daniel Plaisted Date: Wed, 14 Feb 2024 15:17:46 -0500 Subject: [PATCH 404/577] Add VM Test settings --- .../MsiInstallerTests.cs | 25 +++++++++-- .../dotnet-MsiInstallation.Tests/VMControl.cs | 27 ++++++++++-- .../VMTestSettings.cs | 22 ++++++++++ .../VirtualMachine.cs | 42 ++++++++++++++++++- 4 files changed, 107 insertions(+), 9 deletions(-) create mode 100644 src/Tests/dotnet-MsiInstallation.Tests/VMTestSettings.cs diff --git a/src/Tests/dotnet-MsiInstallation.Tests/MsiInstallerTests.cs b/src/Tests/dotnet-MsiInstallation.Tests/MsiInstallerTests.cs index 214603d3f311..f6049b63a379 100644 --- a/src/Tests/dotnet-MsiInstallation.Tests/MsiInstallerTests.cs +++ b/src/Tests/dotnet-MsiInstallation.Tests/MsiInstallerTests.cs @@ -35,8 +35,22 @@ public class WorkloadTests : SdkTest, IDisposable // Reminder: Enable "Remote Service Management" firewall rule so that PSExec will run more quickly. Make sure network is set to "Private" in Windows settings (or enable the firewall rule for public networks). - const string SdkInstallerVersion = "8.0.101"; - const string SdkInstallerFileName = $"dotnet-sdk-{SdkInstallerVersion}-win-x64.exe"; + string SdkInstallerVersion + { + get + { + if (!string.IsNullOrEmpty(VM.VMTestSettings.SdkInstallerVersion)) + { + return VM.VMTestSettings.SdkInstallerVersion; + } + else + { + return "8.0.101"; + } + } + } + + string SdkInstallerFileName => $"dotnet-sdk-{SdkInstallerVersion}-win-x64.exe"; const string RollbackRC1 = """ { @@ -366,10 +380,15 @@ void CheckForDuplicateManifests() void DeployStage2Sdk() { - Log.WriteLine(TestContext.Current.ToolsetUnderTest.SdkFolderUnderTest); + if (!VM.VMTestSettings.ShouldTestStage2) + { + return; + } var installedSdkFolder = $@"c:\Program Files\dotnet\sdk\{SdkInstallerVersion}"; + Log.WriteLine($"Deploying SDK from {TestContext.Current.ToolsetUnderTest.SdkFolderUnderTest} to {installedSdkFolder} on VM."); + var vmVersionFilePath = Path.Combine(installedSdkFolder, ".version"); var existingVersionFileContents = VM.GetRemoteFile(vmVersionFilePath).ReadAllText().Split(Environment.NewLine); diff --git a/src/Tests/dotnet-MsiInstallation.Tests/VMControl.cs b/src/Tests/dotnet-MsiInstallation.Tests/VMControl.cs index 774f4e9eba33..c184fc98d1ef 100644 --- a/src/Tests/dotnet-MsiInstallation.Tests/VMControl.cs +++ b/src/Tests/dotnet-MsiInstallation.Tests/VMControl.cs @@ -16,8 +16,8 @@ namespace Microsoft.DotNet.MsiInstallerTests { internal class VMControl : IDisposable { - public string VMName { get; set; } = "Windows 11 dev environment"; - public string VMMachineName { get; set; } = "dsp-vm"; + public string VMName { get; } + public string VMMachineName { get; } const string virtNamespace = @"root\virtualization\v2"; @@ -35,7 +35,7 @@ private CimInstance VMInstance } } - public VMControl(ITestOutputHelper log) + public VMControl(ITestOutputHelper log, string vMName, string vMMachineName) { if (!WindowsUtils.IsAdministrator()) { @@ -43,6 +43,9 @@ public VMControl(ITestOutputHelper log) } Log = log; + VMName = vMName; + VMMachineName = vMMachineName; + _session = CimSession.Create(Environment.MachineName); if (!ToolsetInfo.TryResolveCommand("PsExec", out _psExecPath)) @@ -53,7 +56,23 @@ public VMControl(ITestOutputHelper log) public static List GetVirtualMachines(ITestOutputHelper log) { - var session = CimSession.Create(Environment.MachineName); + if (!WindowsUtils.IsAdministrator()) + { + throw new Exception("Must be running as admin to control virtual machines"); + } + + using var session = CimSession.Create(Environment.MachineName); + + var vms = session.QueryInstances(virtNamespace, "WQL", "SELECT * FROM Msvm_ComputerSystem WHERE Caption='Virtual Machine'").ToList(); + + List vmNames = new List(); + + foreach (var vm in vms) + { + vmNames.Add((string)vm.CimInstanceProperties["ElementName"].Value); + } + + return vmNames; } public CommandResult RunCommandOnVM(string[] args, string workingDirectory = null) diff --git a/src/Tests/dotnet-MsiInstallation.Tests/VMTestSettings.cs b/src/Tests/dotnet-MsiInstallation.Tests/VMTestSettings.cs new file mode 100644 index 000000000000..22fbdf22e83d --- /dev/null +++ b/src/Tests/dotnet-MsiInstallation.Tests/VMTestSettings.cs @@ -0,0 +1,22 @@ +// Licensed to the .NET Foundation under one or more agreements. +// 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; + +namespace Microsoft.DotNet.MsiInstallerTests +{ + internal class VMTestSettings + { + public string VMName { get; set; } + public string VMMachineName { get; set; } + public string SdkInstallerVersion { get; set; } + + public bool ShouldTestStage2 { get; set; } = true; + + + } +} diff --git a/src/Tests/dotnet-MsiInstallation.Tests/VirtualMachine.cs b/src/Tests/dotnet-MsiInstallation.Tests/VirtualMachine.cs index fe42426f71f9..4480d03e442f 100644 --- a/src/Tests/dotnet-MsiInstallation.Tests/VirtualMachine.cs +++ b/src/Tests/dotnet-MsiInstallation.Tests/VirtualMachine.cs @@ -19,6 +19,8 @@ class VirtualMachine : IDisposable ITestOutputHelper Log { get; } public VMControl VMControl { get; } + public VMTestSettings VMTestSettings { get; } + VMStateTree _rootState; VMStateTree _currentState; VMStateTree _currentAppliedState; @@ -31,9 +33,45 @@ class VirtualMachine : IDisposable public VirtualMachine(ITestOutputHelper log) { Log = log; - VMControl = new VMControl(log); - _stateFile = Path.Combine(Environment.CurrentDirectory, "vmstate.json"); + var testSettingsFile = Path.Combine(Environment.CurrentDirectory, "VMTestSettings.json"); + if (File.Exists(testSettingsFile)) + { + string json = File.ReadAllText(testSettingsFile); + VMTestSettings = JsonSerializer.Deserialize(json); + } + else + { + VMTestSettings = new(); + } + + if (string.IsNullOrEmpty(VMTestSettings.VMName)) + { + var virtualMachineNames = VMControl.GetVirtualMachines(Log); + + if (virtualMachineNames.Count == 0) + { + throw new Exception("No virtual machines found"); + } + else if (virtualMachineNames.Count == 1) + { + VMTestSettings.VMName = virtualMachineNames[0]; + } + else if (virtualMachineNames.Count > 1) + { + throw new Exception($"Multiple virtual machines found. Use {testSettingsFile} to specify which VM should be used for tests."); + } + } + + if (string.IsNullOrEmpty(VMTestSettings.VMMachineName)) + { + VMTestSettings.VMMachineName = VMTestSettings.VMName.Replace(" ", ""); + } + + VMControl = new VMControl(log, VMTestSettings.VMName, VMTestSettings.VMMachineName); + + + _stateFile = Path.Combine(Environment.CurrentDirectory, "VMState.json"); // Load root state from file, if it exists if (File.Exists(_stateFile)) From 96e8f7e4202c44112eb8b6fd219b3ff047557b5b Mon Sep 17 00:00:00 2001 From: Daniel Plaisted Date: Wed, 14 Feb 2024 15:34:06 -0500 Subject: [PATCH 405/577] Doc update --- documentation/general/workloads/README.md | 1 + .../dotnet-MsiInstallation.Tests/README.md | 20 +++++++++++++++++++ 2 files changed, 21 insertions(+) diff --git a/documentation/general/workloads/README.md b/documentation/general/workloads/README.md index b87ea7404d4a..c0b42f9a91a4 100644 --- a/documentation/general/workloads/README.md +++ b/documentation/general/workloads/README.md @@ -20,3 +20,4 @@ Other documentation for workloads is in this repo: - [Grouping multiple packs into one MSI](https://github.com/dotnet/sdk/issues/21741) - [Handling workload assets across major .NET versions](cross-version-workloads.md) - [Workload Clean Command](workload-clean.md) +- [Workload MSI Installation Tests](/src/Tests/dotnet-MsiInstallation.Tests/README.md) diff --git a/src/Tests/dotnet-MsiInstallation.Tests/README.md b/src/Tests/dotnet-MsiInstallation.Tests/README.md index 9a583ec4168e..1f0c161997ec 100644 --- a/src/Tests/dotnet-MsiInstallation.Tests/README.md +++ b/src/Tests/dotnet-MsiInstallation.Tests/README.md @@ -16,6 +16,7 @@ The main requirements for running the tests are: - Access to the VM via the admin share (`\\TestVM\c$`) - [PsExec](https://learn.microsoft.com/en-us/sysinternals/downloads/psexec) on the PATH of the host machine - "Remote Service Management" enabled in firewall settings inside the VM (this avoids a delay of 15-30 seconds for each command that is run) +- Tests need to be run with admin priviledges, which are required to use the WMI APIs to control VMs Detailed steps: @@ -34,4 +35,23 @@ Detailed steps: - Browse to the admin share in File Explorer to confirm it's working. You will need to enter the username and password for the VM. Select the option to save the login information. This will allow the tests to access the VM. - Inside the VM, go to "Allow an app through Windows Firewall", and add "Remote Service Management" to the list of allowed apps and features. This allows PsExec to launch commands quickly, otherwise there is a delay of around 15-30 seconds for each command that is run. - Download PSTools, extract them somewhere, and add that folder to your PATH. Run something like `psexec \\TestVM cmd /c dir c:\` to verify that PsExec can run commands on the VM. The command should complete in less than a second, if it takes longer then the Remote Service Management firewall rule is probably not enabled correctly. +- Create a `C:\SdkTesting` folder inside the VM. Copy the standalone installer for the baseline version of the SDK used to test (for example `dotnet-sdk-8.0.100-win-x64.exe`) to that folder +- Recommended: + - Install [Visual Studio Remote Tools](https://learn.microsoft.com/visualstudio/debugger/remote-debugging?view=vs-2022#download-and-install-the-remote-tools) in the VM so that if you need to debug the SDK you can do so. Run the remote tools and allow it through the firewall + - Install any other tools or set up any other settings you would like on the VM to help investigate failures. It's easier if you do this all as part of the initial state, otherwise each time you run a test the state will be reset so you may end up repeating the same actions multiple times. +- Create a snapshot (checkpoint) of the VM in Hyper-V manager. Rename the snapshot so that the name contains "Test start". There needs to be exactly one snapshot with "Test start" in its name, which the tests will use as the initial root state. +## Test settings + +The tests can read settings from a `VMTestSettings.json` file, and they store the VM State tree in a `VMState.json` file. Both of these go in the current directory, which when running tests in Visual Studio will be `bin\Tests\dotnet-MsiInstallation.Tests\Debug`. The `VMTestSettings.json` file can have the following values: + +- **VMName** - The name of the VM to use for testing. This is the name displayed in Hyper-V manager. This value doesn't need to be set if there is only one Virtual Machine on the host. +- **VMMachineName** - The machine name used by the VM's operating system. This is what is used to browse to the machine in File Explorer, for example `\\TestVM`. If this isn't specified, the tests will use the VM Name with any spaces removed for the VM machine name. +- **SdkInstallerVersion** - The version of the SDK to install for testing. The installer for this version needs to be copied to `C:\SdkTesting` inside the VM. +- **ShouldTestStage2** - If set to true (which is the default), then the tests will copy the SDK implementation binaries to the installed SDK folder inside the VM. Basically, you should leave this set to true if you want to test local changes to the SDK, and you should set it to false if you want to test the SDK specified in `SdkInstallerVersion`. + +If you want to change the snapshot used for the initial test state, in addition to renaming the snapshots so that the new one has "Test Start" in its name, you will need to delete the `VMState.json` file, as otherwise the root test state will be read from it. + +## Notes + +Hyper-V supports a maximum of 50 snapshots per VM. If you make changes to the SDK and re-run tests, new snapshots will be created for the newly deployed stage 2 SDK. You may need to delete the older snapshots in order avoid hitting the snapshot limit. Also, if you want to force a test to run a command instead of using the cached result, you can delete the corresponding snapshot. \ No newline at end of file From 0325624e53445a1aab702da8abfa8462b0a28327 Mon Sep 17 00:00:00 2001 From: Daniel Plaisted Date: Fri, 1 Mar 2024 16:59:38 -0500 Subject: [PATCH 406/577] Apply suggestions from code review Co-authored-by: Noah Gilson --- .../dotnet-MsiInstallation.Tests/README.md | 28 +++++++++++++++---- 1 file changed, 22 insertions(+), 6 deletions(-) diff --git a/src/Tests/dotnet-MsiInstallation.Tests/README.md b/src/Tests/dotnet-MsiInstallation.Tests/README.md index 1f0c161997ec..8daee4647df7 100644 --- a/src/Tests/dotnet-MsiInstallation.Tests/README.md +++ b/src/Tests/dotnet-MsiInstallation.Tests/README.md @@ -21,17 +21,33 @@ The main requirements for running the tests are: Detailed steps: - [Enable Hyper-V](https://learn.microsoft.com/en-us/virtualization/hyper-v-on-windows/quick-start/enable-hyper-v) -- For the tests to remotely control the VM, your host computer needs to be able to access the VM over the network. To enable this, you need to create a virtual switch for the VM which will also be shared by the host PC. In Hyper-V Manager, go to Virtual Switch Manager. Create a new Virtual Switch connected to your external network adapter, and check the box that says "Allow management operating system to share this network adapter." -- Create a Hyper-V Virtual machine +- For the tests to remotely control the VM, your host computer needs to be able to access the VM over the network. To enable this, you need to create a virtual switch for the VM which will also be shared by the host PC. In Hyper-V Manager, click on your desktop and then go to Virtual Switch Manager. + +![Image of Hyper-V Manager showing switch manager dialog](https://github.com/dotnet/sdk/assets/23152278/64ea359c-a5b6-4c40-9698-e89843ddd21c) + + +Create a new Virtual Switch connected to your external network adapter, and check the box that says "Allow management operating system to share this network adapter." + +![Image showing creation of a network switch](https://github.com/dotnet/sdk/assets/23152278/2134d692-6eaf-4d54-bcbf-1aeb98bfa15c) + +- Create a Hyper-V Virtual machine. The simplest way is to use 'Quick Create' and modify the settings after creation -- it will find an appropriate ISO for you. If you need a more specific build, you can follow the steps at https://learn.microsoft.com/virtualization/hyper-v-on-windows/quick-start/create-virtual-machine. Either way, apply the following modifications: - You will need to choose a name for the virtual machine (used by the host) and a machine name for it when setting up Windows inside the VM. You can choose whatever names you want, but "Test VM" and "TestVM" are good defaults. - - You can download a Windows 11 .iso here: https://www.microsoft.com/en-us/software-download/windows11/ - - In the networking configuration for the VM, select the Virtual Switch you created - - Under Security, check "Enable Trusted Platform Module" (and possibly the "Encrypt state..." checkbox under it), which is required to install Windows 11 + - If needed, you can download a Windows 11 .iso here: https://www.microsoft.com/en-us/software-download/windows11/ + - In the networking configuration for the VM, select the Virtual Switch you created. + - Make sure that you create a generation 2 VM so UEFI is supported (this occurs by default in Quick Create if it is supported on your machine, which needs TPM 2.0.) + + +![The generation 2 box should be selected](https://github.com/dotnet/sdk/assets/23152278/5062e3d5-10fd-47c6-a066-c5662de1db6b) + + - Right click the VM and go to settings. Under Security, check "Enable Trusted Platform Module" (and possibly the "Encrypt state..." checkbox under it), which is required to install Windows 11 - Start the VM and install Windows - - Probably you don't want to sign on to the test VM with a Microsoft account. Setting up with a local account is tricky, but you can do so with these steps: https://www.tomshardware.com/how-to/install-windows-11-without-microsoft-account + - Probably you don't want to sign on to the test VM with a Microsoft account. Setting up with a local account is tricky, but you can do so with these steps: https://web.archive.org/web/20240120203712/https://www.tomshardware.com/how-to/install-windows-11-without-microsoft-account - In the VM settings in Hyper-V manager, enable all the integration services (so you can copy/paste files to the VM, for example) - In network settings inside the VM, switch the network connection type to Private Network, and turn on Network discovery and File and printer sharing. - Inside the VM, set the HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System\LocalAccountTokenFilterPolicy registry value to 1 ([reference](https://learn.microsoft.com/en-us/troubleshoot/windows-server/windows-security/user-account-control-and-remote-restriction)). This will allow you to access the admin share (`\\TestVM\c$`). + +You may also run this under an admin prompt: +`REG ADD HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System /v LocalAccountTokenFilterPolicy /t REG_DWORD /d 1` - Browse to the admin share in File Explorer to confirm it's working. You will need to enter the username and password for the VM. Select the option to save the login information. This will allow the tests to access the VM. - Inside the VM, go to "Allow an app through Windows Firewall", and add "Remote Service Management" to the list of allowed apps and features. This allows PsExec to launch commands quickly, otherwise there is a delay of around 15-30 seconds for each command that is run. - Download PSTools, extract them somewhere, and add that folder to your PATH. Run something like `psexec \\TestVM cmd /c dir c:\` to verify that PsExec can run commands on the VM. The command should complete in less than a second, if it takes longer then the Remote Service Management firewall rule is probably not enabled correctly. From 5b39400edbb6bc0bd7738152cf45971b77038a69 Mon Sep 17 00:00:00 2001 From: Daniel Plaisted Date: Fri, 1 Mar 2024 17:47:19 -0500 Subject: [PATCH 407/577] Check images into repo --- .../dotnet-MsiInstallation.Tests/README.md | 6 +++--- .../images/network-switch-creation.png | Bin 0 -> 180170 bytes .../images/virtual-machine-generation-2.png | Bin 0 -> 144028 bytes .../images/virtual-switch-manager.png | Bin 0 -> 151492 bytes 4 files changed, 3 insertions(+), 3 deletions(-) create mode 100644 src/Tests/dotnet-MsiInstallation.Tests/images/network-switch-creation.png create mode 100644 src/Tests/dotnet-MsiInstallation.Tests/images/virtual-machine-generation-2.png create mode 100644 src/Tests/dotnet-MsiInstallation.Tests/images/virtual-switch-manager.png diff --git a/src/Tests/dotnet-MsiInstallation.Tests/README.md b/src/Tests/dotnet-MsiInstallation.Tests/README.md index 8daee4647df7..0c21ac265461 100644 --- a/src/Tests/dotnet-MsiInstallation.Tests/README.md +++ b/src/Tests/dotnet-MsiInstallation.Tests/README.md @@ -23,12 +23,12 @@ Detailed steps: - [Enable Hyper-V](https://learn.microsoft.com/en-us/virtualization/hyper-v-on-windows/quick-start/enable-hyper-v) - For the tests to remotely control the VM, your host computer needs to be able to access the VM over the network. To enable this, you need to create a virtual switch for the VM which will also be shared by the host PC. In Hyper-V Manager, click on your desktop and then go to Virtual Switch Manager. -![Image of Hyper-V Manager showing switch manager dialog](https://github.com/dotnet/sdk/assets/23152278/64ea359c-a5b6-4c40-9698-e89843ddd21c) +![Image of Hyper-V Manager showing switch manager dialog](images/virtual-switch-manager.png) Create a new Virtual Switch connected to your external network adapter, and check the box that says "Allow management operating system to share this network adapter." -![Image showing creation of a network switch](https://github.com/dotnet/sdk/assets/23152278/2134d692-6eaf-4d54-bcbf-1aeb98bfa15c) +![Image showing creation of a network switch](images/network-switch-creation.png) - Create a Hyper-V Virtual machine. The simplest way is to use 'Quick Create' and modify the settings after creation -- it will find an appropriate ISO for you. If you need a more specific build, you can follow the steps at https://learn.microsoft.com/virtualization/hyper-v-on-windows/quick-start/create-virtual-machine. Either way, apply the following modifications: - You will need to choose a name for the virtual machine (used by the host) and a machine name for it when setting up Windows inside the VM. You can choose whatever names you want, but "Test VM" and "TestVM" are good defaults. @@ -37,7 +37,7 @@ Create a new Virtual Switch connected to your external network adapter, and chec - Make sure that you create a generation 2 VM so UEFI is supported (this occurs by default in Quick Create if it is supported on your machine, which needs TPM 2.0.) -![The generation 2 box should be selected](https://github.com/dotnet/sdk/assets/23152278/5062e3d5-10fd-47c6-a066-c5662de1db6b) +![The generation 2 box should be selected](images/virtual-machine-generation-2.png) - Right click the VM and go to settings. Under Security, check "Enable Trusted Platform Module" (and possibly the "Encrypt state..." checkbox under it), which is required to install Windows 11 - Start the VM and install Windows diff --git a/src/Tests/dotnet-MsiInstallation.Tests/images/network-switch-creation.png b/src/Tests/dotnet-MsiInstallation.Tests/images/network-switch-creation.png new file mode 100644 index 0000000000000000000000000000000000000000..f460db7d38d269d0f281f5a2089e1563e9694e14 GIT binary patch literal 180170 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

#eKD%p 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 z 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 literal 0 HcmV?d00001 diff --git a/src/Tests/dotnet-MsiInstallation.Tests/images/virtual-machine-generation-2.png b/src/Tests/dotnet-MsiInstallation.Tests/images/virtual-machine-generation-2.png new file mode 100644 index 0000000000000000000000000000000000000000..04e16c81e4b9ebd080f8a61caab91e15466c0689 GIT binary patch literal 144028 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
iyuGJLj)BMyY!nk`f_HjTl9F((U#bE2JpxeeX%y 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�jyKXTR$dLTg`K$f$M1u4_KHqLHb9wdHI@JmPzTjOu|Pg+?0X}G z@JOUo#<+1aL8T!0R^RfTmPM-U2hU3zKk$b#Lj7tX(gN$trfL1D>P@DlEmrXSm%^Pv z;h=7ddHI(-K@!f*YE=pvmixAxDg767Rej_5>YKnO>c=#3k#;R6iZVZDj`l{T^nn?{ zfcsxbNTR0zsspOOaD@jTZod)}HxZ_g!>0l+%usm)%UzP1#l@|3cd3hYcmB$E`}qqI zk?!tp)4DCBXbc^Zf&osoTl+>(haDe5!vp+7{ZjVPm%Z~Pm*_*{igCw$LgA;EuUtO7 z_l6pZK87#l$=#ZBMwRi8-E7|UZRIn}-72tgdD!B#d*UBl+Cyg(k$>@OKXWX_zI`vG zQJOn1xU$NhdY7B{qax@L^`?xw{9W&Q#$Pa0k(*rQhLXJi3%r z&B0u{&W4E|&)F()p%b;~S6~Fv;$A+(Xk8q{ z8!IwbyPUyi<_^IruOO4Dy%lxdcNE&4Bp7BrQjF#WSDl7SlcorAYtY>|`}H`%6S{*7 zL1;UZb#N@YK0Ww`KA`x>Sqbp|e8@H^3%K_q^)b;>)C%D-HQayGrx>Y@FV|*cmsxl# zxiMA$R~qZHilj#2U{D#MS^wMIUtuRvlPNBLvt23VP6CB+~L z415h@0)jwnJ=(*-T{+qGP)N}iurC(F0uaN*WS=w00DXJhE_?7c)0S6uG11Yq?Cj5n z*naf&^`!(>(Fyrwj$Y3QE5qA14oBIj4mJ{2*iF3e=GyTR0+)lhj>UyUj~ugmZslJW zF27^teUYdtSiuFFOqty|O0gmwnIt|@XuunBi1fHkksf!OqP<*ln(9I=cHqzz&pjI8 zw0feBUmV(=9F0?o92U6%InO>GewpBVwTO=vjSWp!nXL?C?UFjoS}iE#cTb>+ z?>!w`dI6nN6(d_F2igO@YMOcst3y!?my6muEVr60SxPt)$xPQXRd~7y4M%n|3U@T| zD&r4LxKM4X-R=%-ZYw%P^ge4_lDUj}AE=tP?9iu^mu6RfPDmsX)I)fyQ8u(fYjJ$a z-xW6J%5GpQ)v&qH2($^tq7P^L9e_}89~k(Kggb}2VCJ#qtxQ!O8zsONBT2|l2y``U zHobBvNw$1~lMXaaHUqG`eo0m1{2?E)qpu5q_H>d2Tmp-b9xgnG(K!ixqAgYL*?^54 zLDg=@pXo*191a$AchWCt69#XMSXb}J;}4}CL!FLs%3w2W{fyleIbJGi^F+r@rx>_=AY4;+183HD8@~y@OlV}1 z0wxnS1Vf~nyGl`hUHDZc4{OIcYePckc*A0(Sy=MNCKGLEN+0aha&6iFxO zwqFW6>Ko1?y_?yNHfO%HQTRt4e4L9cJi$R){$vKt;TGbzqGCWCHU+D7V6ysMUCRr! zb;mESLk76Kf0S`s0&sl3407av<6~1415Uz_Vxh+ZVx_>ZY}wkf`v(tt;7JQh+mas6wr-ck$=z^~zhIo*y}=+aL%HFd9l!kaIA zL~_r*Gqd!^)JZEGUq52npVYNP&8cg))Yyc1JX?+!6ndxV6k~^rOh#0ah$O_%9lD$4 zFFAh+lX5dJUM>iV`$F>LCh_A7-ExwUj3x-u3xB??^mHO&b=n@42(re4A!DylW?_6= z`m+NHn^5%KGvRskLd~RaBe+EL2m;?-6o^rYcnciCnddtbp=4z`<9U9*sh7#aXjjSS zsVYXzzBF0BmuLq)b|88YUr*<5eY(1$KFukj@7sAOFJl(aZ}ck|X`=@A3MaPjthr0C zxM1j&Ox`ZHx$FytbPXFcUP=u!jQZme*}U(?KkBKIwY&bVN6f1OXYP`;b%|4VXJK;e zOGw0XFx;SuO*m7IFX820XkCUp(g@sdb(XKO=4^)`%Ey~6H9_Y>&J!WqH8)|m@(hHw zEnbGKz1lczM-*M6u^9@#^FH@>{JR~>E$ZXP(6O6f&`I);{fM;Lx9XK5o&rx1x8Ax9 zIlNCo5XSxfUSC0D5j}YedKLoamgza5%DCABFCcz08y0DsiJQ0eXegVsKG{<@NB>3X z>=)x1#cfBpIcsPz&}m*TNII=g$>^+X0%vl$V7zZ-fADRc(A{Xkj=c>^)CwAWHoCx^ zDCMtj)T8(SwCAQYty{XgjSwrfpA0mtl6^7BG7jt6?Dg7=S`Lu7MY}U@Ew6fa>k}i2 z*e85eC6fN&jYkcSYI<6M;`tn>LYR){W!zb_pT&L{6hSQ6&^=6HrE_av6XwK>$2}Aw zvA}E3Wz&PfDgq2{^Zt9>h41cbw}Ehj^B(EX4qgGFuFdn}6Mp@ru6Q_S0``t%AVbG# zddYV0yNzsMBwNHikTucXX{SiY;o|+N?e84{Si~{&SV<=}FJlIDx46s>j}|ZnWk$~g z>_vXbI|*fO#a24)BSu9>6LNcU+ORHAieaV=aG5Z_;+4JzCy7>0E}5}{XZM%Y9GkyK z8WwJe(5)Q4`f?;7`SuOSBk-CcrZj8d8qGphW=yz3A!2>As-5sxyQqY8j1hQD-eW$) zqOUV0-9=_JlbLeOsN8d`C0izJWxq+5dD%N7?CoL$u=B}QQd{+W5@OmyEqLk(jMBR% zmbN2vuo|*N9WV<9&5*i|ud%xfPLSO1!zby^Cbjf?R#9SGAt;R3s} zUZrSMh2LAU-~hn=!|-KnSFX_r*Xf>}@!Gt!ZIhUA)!^2#`H5juW?4BGaVtME<~IA{ z>$v7Ih^Al^NR#*(*uRP;b>FGkK)2&vDCpB+ikj9LbBM-8d#uY_`jBhex~s)3WENM^ z91yX7t%Vgo;Z%B#=H5D-?6$0CcMbmm3#URbUa$RM8;K(iM3RvkHGSEVD;K~7uP-vZ z8=WAUHW~_<;9l&5me(md)3D(2mH+}?+I-c@B=u&NS9e7r8OPB&wV!}ntXbjFr_bLe z(S?D?QQhLOYCo#%(pP@)K-<(j=}efOjQy$-SCi!7+_7;y6cOjU7!4mrx!K9u5J`PQ z=ffReqmK*QMCe0r60Tt7YCKcKd08HcC&hT{A9o#)2}i>{%~j+=4{To=0NuwguQ+Fg z28=qbzL;T-qpW-U9(Lddq`c$n1toai_hLi+iN$J#jEQYUF{)dRw!F@ijE(PFdsQL( zpWk0eh;V%6qvxaod_f_ijO9HJiKp!EIC~`p7(g^Z2K{;97M4l@&GY?@@PV#SA)o6w zX}59@ILS|b_HA3c^5}Sf%n`#&$dob~<30gi2S*HeGc-jX4gCXU!wrz!!enbFc(5Cjy{ALhYLVG;-9D=_$2}o_)A)_n$iG|!vXfL;hBt6 z*zeU5YXe@jB~Q)vkHh=-r&s~-Knl(J$o)aj9!%Yqmnv`cD22p8nzSnwb<)4}V`!ntZ@Bm$~5G1Nahfp7? z9nS$#L$NW4jBgJ|NBx%Zf2qjchD^d`Q(Ovosme2eMw9@W(0?Yo&IG)wjr;V&Uv5Kw zF@>y~EF}hn`j5a2ej0r-je-oW;sVG5Ym+lIHTIwNhfL!CUly>jaBDEVDr4{%aPR)V z2x;*Fs5NYBOjm_{y#fa;tsj(-XUT6`pRoZ!YawksQ9}gI^0Lf{w#@e{pLk(^+CCGq z@Iz-=mo$kFd$w45E-YgY?vwpmDWw1589*~9v?l=56Y(0|+>+i``?96E9c~@D>W;zk zoYF#gSD^#&T2mOt$q(`z!xA(bEw{$cPiw*%rm>hb%^1{ut_VsMVCXuP8-XPt3m52*I~i}0V~{%5+tjQ{!e;`HJYDQ8y4VJDRm@R;#l5EEIYm2wZC z$0I;!)Pm3`1m)!Qo5oFOHhS(DiB(>x{1LXI&id>KfpE^<=l#cJ4C2$-h&qziD~2@Q zLzFuwh*;!kl4VgZHotTF{AXDM<7wjTErra6semJq#uWx?!^Ds<0f`P$$kPjfaIJ+Z zFbRu@$wZYu_SFs#vHA@B_?l97gm4g}HF5uFy9zv;1m>~ei^Bxj@8mLH?ffT^0rsoP z_FDbj#seaK`W&E%&wl=sFa5Cd`T~!iZc{v&?=8>{aBFeYyX_fZ=yT5rW5!#_`_LCS@!`3y+HzWE-Oli?YH8qJP-Uu z$*n=#vjX0bedqF~jYhktJK;HYRAHg0W3kl@+0&^(7|3bQ$E)TMuB6gpkwit-)|7o| zi416zTv^=+_SZuFR>6@Hyztdv$eHIbA%_U8^jrYnd-#`}I#X2F}|P zO3oeaoca$knuL^pY?S@Zb8p+ya!{STbj%C2o$W7Hh(*AZiy*yEn#=sq8&aYRMP)=N#YbW z9GVtvO;Cw)WEbqzRkQ^t{7_2|I(em=~KVi^pzC-SPgtx z+OU#xWM+P$7U(!{kC~M!*fQ+lZ2g%hL1$_+;hSRCoCWCQRR7-u4zK2Kb9nC&Gm5^GK*Q3#`GL^JL$YFRlY)M|L%Td z5JN5;(Kpwg%w@}pVAm=;ieOgRG0W~l%aISqXAt7PxK7CAFLIP;7HtLI~9ZcnkyuQA+@MYe3@VbpYHdxFA z$=SNatfn39Rjo%!mp|hkTMpSFWt?#8RDzCos`xf^_f;$rC%Uh+;Ip0RPGSgXmx1pK z2FKUcN>~11Gn9%cMl33-aM`}L;MYWtyrDZPWg^x1BYCQ|O@nh55^w4jwD2!AvL%}j z38so=&K~z16#E+0rGH3(?Tf8O1LP7>lRdj*(p$Gp6ITInU=BK$cc@saDhKeWxat4u z8K9!aa&X*F%6T`f+SS`@XhVL$@rHUsKe&>#Tdc7Y3Py|$JAZx`{>hX{`k4auP9D$a%$nZmJ{>~f z_dG<-#4I)?&2r{Kb=Bd&8f0_q5eX=z%)>g|>YW;(2bx|93JUOMyn{`33Geq4LB+4! z26r`5bR_t&2(o+?9WR#&#>ttm8>?JV6Ln)cJ2%N9U#b`G6xDhFciU|c<~RbUcJnv+ z3b``!t&e~&O_u|6S8^QT{D?Rs$1;dVXRehOoZ)8c8qfF>W9J+?nOeLpXtzh3IbUIeH4$2O3^e7oScEuc~&~YC(M})vg{+qM0OrF{ls=guy&HrQe68JfG_G`9g@7a^>JavvEW~LZnDq_of z=wL!38;xYMQr?6kZKk7cappYuJb1Y`XqJ!VY^6Ykh6mS9K7wM*k6TuWTJ|zEgwcuc zTTy-ym7fG5KVkle!{@^X8MkevuXYw#c6VPjy0=i|GfpHGrQa0qn1OnIB)GA&U_sS-S6`?xJKl2RC;*%)^s3M= zm;dOwtY4tD-i+j}zeaRmod7==Ny}4 z%9|@(WO+f(wpRX(Z*Kx;1<#yeplx&8;rltBXdMtKN6-1P`;&ZX zMCRw>&a8oneaAO_VIzBk2X0s+%K|Ar1kBH zPXx84fvWPy&fuqR)1R z6pFY}vxg}z@AdFM9_^0hd9sM`vA-K#TfCNHqUg&aO_)>5>7lx0CY6b<5M4d9k7_)x zX)UgX={NanzNlyc^EF+{JKTVoX{)T7w)g`o>QM2>U~y-vQG^aKGf1{=sGuq9(Mgf z*{+(veF1%Bm$&qc$IYz?j$u=^C;Bok4jD4 z?|WNvV_-84PhVT=Ib_*C9+}K3q;#GL4tscef_=`|sda#g6SuQUlwS|juili>OHY?~ z-^aj^Eg5)ti*&l|s8|!;_agN$u&9Xucg-coE?SWl6V`f14-s1#NY{&muRC*r^xngH z+ql+QIMI=Bg6fb+{!o+zEd6$;a#B}9vC2ePttRw%JwxwrU1n>`JNP{0@!EWmgsojT z`V8f*a|IxC8tPwFx-s{ULcqY;oWjj%eHn~z{71jN((5k<>&jk3htk()7pU5o!{*t~KR+7!raHv1Y)%PWD)12J90W=&eAC5W zYl@i2bl>5GqI|G()(qM=85mQxCD9P1J5@YTN?yQtU5s>~mOCR*EZ{nazG)s1Q5mTm z0@2m$94H&+2bTwH1k90*b}5yEG&~ZAC?)bQsgrpg#^4VpHU7O1dw9vEM8U5Tk?*ZA z3xqe9cum?$rcxEZh!jl{5(}3g`P<4Bo~m<6fG4x12M-O>=(yZ4pC{DLBA#U4^L!Op zzR(La3=4J3KS|n1t32=$tE)28jPC)0*nhr1C4s1LjZ=+N3DDFsF-Hubm;WnpDcff{ z_%|?+Pel>@IWAFJT9(P_`c85($=3A=m-az7VT=W@b4*sRb&tZ(OpTSGcikf>#g{s~ zYDej7w7GYLUs2-iVy5_AP6}3c`A)`low56{7bxK6XGI{nT{vrbXpzYZ0kvhA2sk|p zd1l{pB^^Z{p8^~U2JPZ}IAA@wTX1yQ8;^(qaLt|Z&qT{#3YIz~8$>iM(@!ElMXXy| zupS!9W=ZiBzvE9%h?S_-6)%!tAsnql&hncI`;kD$Av-TM(P(7WcHbR$fZ_7PDyEX} z;X}g5qci!6myDQbcInp3hh%;$&IEdk8V;A69L9~b5s*l)V!g0r_3TU` z!s%?&=g|N0MgicBF|QG)9;U}4T!go!t&Pno-(wF8)OmZ1C4$1CFmB2WCBC^Qch)7;SJv0} z^xa_YNlkkNj%vB%TB~Da{<=J?{vlm+H}ttE2uDwut-x)gqG-H;h4iIM@AR(9Wr_06 z=@#vq@k~^2F29L4YrZBZ2j2+TO?R|~$PWvwhNP4iYFNQqi&yD6Rhyaat0ab#v2#4| z&Of@Ms|P~g)NfJ@djOre9!~iuk+l9KvDZRJT(SyGFW^ zj~2~zsh8sF++yq7FY(u1twFMpC#h_NWr!`8&_9K_+g$hXm^8~xcgFMogpn(_lL3v5 zjRxW-7WjOFBL>}5LkN4#82qlc>2-^3b{`8h#mvu+&$kvlQIyg$y7mX*^z>RAJ@;7Y zW76Ka<)ffqNyn|VlGVyJ=Tt0-ZcTB-CeK%~Dk1>2d*ywTWy_=qJxvd`uJi-++{4rq zzSfp{Rb*UObDIr2x}^iJ=KS6WaCw|JHpkXw{W7_ML%^Dl=%3^_)HuIh3zjfBsD0h^ zJ=@TZF?LSQG8@H4nm1SDO4Ne@M^;>1yl!)NZt0?U&VyakM=eW>GMxu5HElY>fFr;j zb^g0Gn4G)x(kG{?pfFiFbX%*QXt9vxXM?sn{Jm?4<$=Mtayhrg$yX5p3GnkeRNFw+ zz2F&orm+K|oVBVQpZK4|sF%!-eF@tQ_ zF!2&(-n@A;{3Tva2iSrzUKmPf=?yv3B$B6NUDoz_k~?_y$W*DMLTT5{# zJyI)-WPBY8#IyCSLCV)DwzJyhp0uv5GxIrYy}mLnf0&B>rfxl+=V`Z#F&|)f`v_`k z%VOge5o!jGfff2p%=(ETv5B2?_=pI^)3%BLHWNZuo)pO4w-f$bE2=SWS;F-#jbU&lib|5yT{h>?U!4S4hlWfhnS2i!#yGu}IJM zC*GVBcWvodl?t0UvCq?SZ$#P;oS8)rC(oJh(>|D5-mgJeM8SJy|2mpHsu8b9toZHo z1B-!vBbJ-pv#5g?9aBC~uKk)u3#pMobh|MVL;ChhY>6E1*>dM51Ko851g@)}%Mg%* z-w2K%O9};I*qa=XNy&XUl=1)^Sn;PNl6n5D_L%wSnCmH9VE&55o^&1Y=UNOt%kK6dSXC>HxKUb`F}%-vl}0;Z|6@Z z55}WkB+#2Ilps8SPzz3;I5kSX$s$&6BpL7&sTA{qKx)aRLSdO@p<}sfiCaK9+eZ@Z zmjx^#Qi@j7rF_7(vxUm@yxcY_Ss?vFheZK`w61oQMq|NC-Me_O)5H{(xLxu>DKcr{ zK__)DYt|@%O1`m8Q(Ti_%TSu(l-J`Z0b)aS^yWre{?zplu+fXA1299j!vx^6GUIA@ zIvyrpN${p{3cnjNNb~~KAg%drvNR3|iJa|4?CX?v6!QD0EN5B;)#zfo8#Gbim6Da} zcc(b*gAf?M>a%f_nNXwd@fJ#qa44h;BpUe6jn=5*YorOrkz@g`RH_K9?WOJ?ioE#L z-QUk0+cV&pBpiowzom_i^C#~BSi+Nm_%CMwBe#KQ!34>N<~-pa=ko~?+U>8cff}8Y zfb;RTvix~Rn_O+|CW1gvP(Mwe4(gA&I_KxFb5aiKZFkR zX$hNR?ZwVwB`vAt{X%=peEH$g_m0cxFiQ)#s;z&?bI`y)>OU}|!9w3xPp<8WLQ&tl zOS6@8?Na`Cfzp=H#o-)Ur1#NPk?yN_U#{xNzpY!AA0!Voh+dt{45YN4fht|D)H}~+ z)L)gIf=4@x&xr+u?Gw(S=z2UhXJe^YgG_Ysox0~@xm~BHUeA!3^yUc&-1=Zx zr#}$?nn;po!lrI;^bpAPx&V1>%RF*425fazGpF(;f-jpqC!**CIXPVYZC!{>Tkebv9Q=XcMpDEou(#q zSxyeTirR55V@o@<>+I{3od+()%iKFt1yCVhW_HcaTV&|y z!zl-!GE6pYk}C8jMEoB>Ea(|R3P;#f=zaC7CdJFsdS=^`=G&#}(WEOew2EV5Q9O@VwP0Z)KKZ6uQ zE_$J7HYOZy+)Z`> zS3U#6ck}u$jtEJK2F5c30wSBK-^h!}5D0ld>zvByQ;X)VG(<=MpyhfXP%r+^QbDkp zB?vewSnLAedn(Dlhv1#|Tl{k_z<-Ae0tMf^VDbGw5FH$V@ACZ${jOmhHdOyN`9SJf z(a$Ju;9sNp+jM$R2Kq>V$B%r)9zvw%F0Y!(EI$za_K*PHqp~1j0@SL#Uu+7_&(Hr) zG{3U4BKGbbMXKQkAZrU;w%KQ!larI2oLp(zhh;vL8oX)l{tsyNcbia=3oKj(xO9Lg zQj7zS;SjjL!aV7xZWEpjw2G8{0cKLPMRspjA5<{2QP>OObh zM#DXI*_gEA&t%GE(LN6n0Y+)V$6!GFZ!!`1C88c8E8dT$=TygYNI=TSXM2>An@`%w z$tnKN#+9}KUPwsj{CnYv%@q_gKJ&jDUdXZ?>i_`Gy^dnNUMV7ue_$tK^uhlAOuc>9 zUp}B&cZ`p}0d~eudjWcXtKlH9EhP#7(Drux#@zkjkg2(+7kU|}sKiqVAaRWhS_?eS zb1W<>pqNoKHJ|T~IfDo+76Tx#Na=4IX)qc3po1}ql1$kE;r%Vl>CjbGRRBIs^C|1U zbiSrY0tjuCSw{k%{|XU!)l5>tG>A~+_(JT^BS|0PUkw7DG-!p$f*-mmEI{W7P_K95 z{H`zOA5npr^kGRV<$sOGKWL>GEASfUPrcZ{zme1i)aI*@Am{H%G28+S#D5To$NX#i zfG1nLfPZiJK+=l{jFu^p%`R?Is}sG+CShev!2|iIoZ3*((Mer$`^Ajt3jlWMFFe0; zfirsFt_l%uNqqa3v!zhrKZH4r+g6OC+tmG3ygme+6eJde_x&53*pLop$t5r+j089tiYid*CuV#xnfic?Wng zQ*je@C(dt`>;O7dl$)zcPjB(m>unZ0wfmZExusvYM+~RJ76(q)k&&{zF1>wM%q8M` zwtYPKetoRihAP+3;0r)qq$o3lgCFI zy%w1@P&C8gGCd2;Yx|l0&(D>fsv#$Faq@Vl34{(MrDu9&=2?21^OW^%SwSm6ZSN}E=Vn`K%UxAbQIB6r2RV)+~(T$CaKb-X?bOY(mwM)BJ z-w(SVmPc+3^LM##cIf^3Ei=5?ovWwRMiKbK8tZM9LLrsP`nyw0795;H#!Px*i z{nXRXkMRxFCRm9gk8B&M_2bdGio`l^i=zUKcy_tp4-QUwpD4+QmmSc?It%B!BSmLL zP_z9{96Q?adNGMA=Dvrj>s~q@51OH;w{?>bXrA4DZ~ruUZFtvD3@FDrvr2M~qp>j+ zW1`$2QTn_>pNX@kJ{2+1#6|v$tf|qISU*tlYe%qhUkSe%jzL z^q3|H#$P%OA{4>wZ0_;r~s<9)Xkr#QG^zbe*mjYowB-sslbzU`qi%oUGp zPUU4!Bj-|%l0>42)R30C6(RkAAouh|4$U11pHRQ=Z+ivA@L2%Ld2dTCAP$g%2(i|- z#>V14ddv}%Z~t124>lAp8RaT+s^k)-Z1sd*QRcwH!h`XjM`igx7x4@9xPxEW0LK>A zi!NoxB0025oqkkhDD!`9G#gM^A__KZd{*dfArl@>rFe3V+c9$Hs5d&wPdgrJbN6Me zY%jLPdMch3rm*_xgFr&+WN%%eBPyRebDn#%VHI*D_4E!jHiBzM_P+oB$Jbj&Mb$=a z<4AW%4-HC4cXugLg3^t2cXvsPbeD<>(%m^AjUYqUNaxVa?~Kp;#Jj%V_pQTXoj+#I zoV)gY?d#rqUsoM!LonING0d^V(4lCw3s_a!(aDgwo4P z<;0xw-)6c9iqzSvoOte&)$A~L%}uW3#%r423SDk8>ow%|evJzJxIvb9`#0J8$0pzd z1{AC4Nk80%lZSL;$3xA`pR2q``_H~rR78IU0@mLrd=l#Dh6+h)qxMF>>y?ewu-I(U z(egZ@ChwKsZxc&$$)yE`UNp_dO;Mb^XfjG1w-bkTG+-J-=D)nY#){*onQI2h<+Gy= zTP^=c&QW$MQ8n&i(rZAg(j)JjKmkvEGl+L2WQ0M!NoMkRpiACQrO^xq0f{@)C^f$% zcE|cEh1L*rglYr$8T5kWx4(VQJimD+a3~h6X)>*HTpj4*t!0hf>s{&YEZa`rm{!?n zvLC2$)e8B!Mc>hK4f-nAeWQ-b-*A%zQu%4h&XYq>)(A4rJ=DGIC0WPjG7${E`9LG|^W{hf)my`1>wWwuUU!t>4a^ZjLJ z4?8w*PPJO3C2>XiY}MA?EXZ*N-D_EE%4H?9iSzpM)JUnHCY<< zcOMZCY;rEniRO|SuWHOS`~co6*~;4A&cW;1FNc_DL-5iMrK05G7aF$UoVuTvuPSL8 zyoSLAGDwW&jmou*nrZ*IIPj$r1b41G%#sCxAdc2&@YzsYO#ebj`Tc)p13kkjAZ|sZ zv_|;2E~Ki#slbyWhDp|3&`MN{ij%-jJS9cnL0xb9>8fo&Xa!!^h%GyweOYC|(fg=# z)o?|*H;5&7VU9(E?CoS)gTrFaB$cc7n*wY7w(Dsffl13pXP??vOj z>YuDffTIKLGmjX4p+3m!_#dQ#J)=HrG$|2BvP;IadEr;FkUwfrcqYzQE*SHjVq;?O z236V6TtP~qy$nxzTlU|5*+>=+7J6Q!za$A+`(uS)zeSG5fcVTTv_Sp6V4DlJ zz_*9JVTuVe67DPaNTLU`5^Lon4EFYAE>*&+mHU_)lMNrAw`-9uyHQoOaHVIHL^b-} zF>06VyNnzQsB#XiR@$Dc0WK$g{)8+;8+SXT2~*0tIPCGTz;HvdBF) zZzKNT{^V~Ec{B(2hUQe;3>wji)ZpXBz|j5tU1ET3Y-0Qq0g(?|U*1u&GYUjrHd;Sk zD~gVe0YFjKRz^n2`B|A8@$Feg*@=Q8plPmh%UfQ&5+J!KJFjN&`g8PXA;O_gCN$Zt z?W0JF4`er=_3OM$>HN_VS6etZZ>im&)$B(Sw1ivOHx!5?c3U~(#?7#vGaXiW=-OU* zu2C*1XQLYx&gy|749Pe_+cc|oVi!H%v$}CqneQJJM-#FLBp?-3YYPzC#0|^`l2O~t zvotIEl&Kki`?J$6e0cSyv@ItU{Edh@M@PEu+b`WfFtxniL9m{vhy`Zeg;TZ1B8|I~ znN%G|P18PwtlqT}bkGB>${XNMzG+#Fs=hS)aMrS@s7iPBSB&T%gr?LEfYPTy3G0~h z1#%cfme!O6)Jp#L?(OUXVh9(qgt`Ld;%7U*hU_KzY@{E~8n~L=lUDpFG8XEEsjf$g z&W>5V(IVI9mnTQh3@T6-euy~TaMw~cOl7yNd)FJG=lep-7>jc=*{~R%zNJ@DT4&VH&wHH=EWL8dpB=-E zPc<+C;+grgsz#n6dw?@1i5l|_hA$4anboat-?U)NTuVAwI7tY0YnHz1m4~{R3nGC) z?<{pevsNw&f#R7q7`T&H7_}#DX$QR6D5ZPK&lE@e+ zzs_Ut?LmbMWzX`=1sh3Dml%ZM*4}(Yq7toN+01j;uJ8R2(4Vjtbfz76yJgreus2dd zsJ2FopJf$vmAh#ye(1)s+iKjfTI^Zcv_TOLM8_Xjj3yZyuip3O<_&NLV6&VZC{E=D zW#Xi_BVZ2NqTSoUE5+fY{K+16we^;!0GVWEp` z*4=d6+=!iKsVX~&&we0MW#0Q}T-7Om2)^5WS72MO{q!_#b}m3vaE%{UmMnaS-O>N$ zg3Z&oHFD%mbU~;pfa%oZ!gu^&C z^JdH{p=Wq1g`HR7=V)i}dCzCFbzN}8n$K$$Y==_`%^UuJ!c>7I3eXK< zI=$q7K&>6%55w&EW?jG1t3O7@1kNDjbe>mwW}}Rp6AJ6S7OIc3tZ5sgXnk02_&RUJ zp{c6)nCzSIXyp3>XqmBBB5Qxbil2p%ul2%93XtFR=HzDbrgu_)8;50XgR-53ZA(_E z#G}jB=lLiBPG2~yN|<;%g2b1uj@&?Ojl&99V>y9iTdd#>TIzYW;_?wH}p5Lz)h3o41Vd=X?t)|a&=)3_OueXE2!3>&b>V?Wr^*nb6$7!J7j`|8Q;giSUwtGex^F%ns?QovlmsB?k|DilQDBktmXOFQ00 zNfT>q4XBGQ#Huk-_V;jdSp}(`S0v_(k6GnvQ-B^uh&d%&&n7NvuHT{4&CQc2QoJlT zY74D%L&z!+ONVM+`}n&OC@KUD-+Wr`th``j%)@4)ebS@dE}8g=lJ$(9|7Z_{j)TFG zGCt$29&}!oHF(z}`>u5%Y3t=#Q}b7emrM^*{hsmG)4lH^aVRtzUKz&uQcSqZXkvpv z>O+;zTA&gZLYPP6&|-^P{mqOp>W2^aU-Lg};BRaWBW1TN)K#rk1))d(fL)4+b+R&} zemWN-eie8yBY8Siu0DDTL^UXVX+aY3Iy~+i&C4KKoXD)Oqxnccvope=@{noX6g7fm z)hbJ`&Ya(fMbk8vN<;x964fmL^~${x5j0ZBH-AzcuI#C8=$U$ee!OZIYxN_wdU*bm z=!dtcr2h^y$2{$Su_*wd1p?R>W-YjP8-;vDNKBAb6LF1i&7J)T38Y?ldXtjt9A{yP zE1dYlJF#E5m2>3NzT%csH;&T7CQiHE zTrx+;ffeLa)Pm1##(=Y8nF^j=|ChRnxURj&jA^RK5y+e3c;uGHhW>Ek`1ni6_yQz3mb8s*Ocga2VU*#pJx1de#qHngjEYA-NDHOI zCbJ$6CJ5V-bi@z1z9`YoZ^x$O%P_pbH9OpTT_%xi0cUpq`Fjdau=pU_;A%myPLG1g z$|vEzh2IqtC>I&^+uAg+T!SS`|L~C%};3> zbVq%(ITw0D-(kb(hkb?Z6zai8BMr>o#mk8f{g24cg4#NLlf!05OEKcL%~lV7MBMSt z{CwH)2|RBxf26y++|+8vTP|izA+Tt?{YROZk*``>lGV3xtb~yTE9Hu@HqCJdhy)3zzC?Lb%ahW((JrHO~tWX zxz^hEM(eIAnD<6|)v+#rKHbx8{U^q#QFF{yAM2dwMz_UiPD7{i-vM!uC!8AiV+dPq;ounQ zE&u}$XK*64jY?Q_U;p~oUCcw^%sZPBLoTmD_^=v`z#6$k#rXu*?lx*>eSZs~O{-em zjobR4`uJpF8}>Sp-W_2ycFuNyxr#02C2Yi#3p*S(*P4m9e8 zPPKVIIzK5k`u1c6L(ManhJpnjPK=iv_#*Dz1YIsqUwNwV7x^VCrQ8>ZENUBDHvD)b zmZ%Et7coAOzr$@^HfM=aRx@q(eD;7{F)H}RcG7c?CoQW5YR)4d&UgP_#BHqF6Dnd* zzjMwUSgd@Hi#2*>=5@nXau4clt#`6+DETt=O;TLj==Y@qDF>B7Z_-!dtMbzezI~p| zAAX~**L%7gdU|eWh589TgE?VL8)|uDC0czib~gFTLsn?-!oipkA9_DNF@vtvvWqaL z6(C3!F@yp!ZA=`DaWfgrd}CHlueiD8tD0T;5*R3yONPqCVs8VP9HZfNcy*0hlwhFv55c!#^$O-(yYgAa!fuiAQqn#)?^ z`$JyMNxW>kp^J1I(QR>IAJzAR{kZw$!;sw*=2qIs)gVCArvGfQ3yHG>;ou;@t9}W9 zot|Ulae_F#^OEn;qBdPjwwU~nROM|OXnqX*^5bs1BGXS_I7tykn>GCHlAuRY?0>(Y zl-ug*@tBgRAUzc%EH`)QUC8&y$@2=)M!%a4GIO2tlfX0L zPqq;7k>n?4&Ce(_bw*$xQal5G$oi(zOx48Pi7k@R2nnGT6$aKR?Owa(O>7!jT426L zo8ZsMMp1pVIK6qx0o%@zkI?m!P(5Hnp? z&d7I9^U3!?c1(J4<^uufA_Lr59N2tfDVe?jigMb7l@|)%+*)~ToV6#7boKdLY}8p( z&Xu)Bl%@-MovRL=7=#?)9kqHzo(%b#EHpoM0=7V}j<2d$jA1qswxSRN1DLm2JI|&} z-dKx5pS;0G)Y^wFA~Lc|pnw!!<(Kl?fR+22n;}cVY#@=WIJ%7#xi8Z26~13|8^pQ@ zEW=iHv1Dd;h*Cw$#w_qLCZ+IV$#g51eCfgMkc(@@gi3BDce80|*!i$&(|^>5de&K|1yl|rNtU(cq4`>7tHy#y1N>yBrrk|O?_!*LV>k1Ts@u_> zYWgAyVP$U47iY35XWWes;>z$ojH9-5>e(4vz5E_z?thp6&6?|$vrOn7`GBD79sa@L zVI(ue%6pX*A*$sD=B`g8FZ|9(liPWSxA78<_H|u8H3aMMrXupPqvFPFYRhu#<0LYF z>5j?oouSK{dZdLgaeUJ(8qmWg>r}ogqMeF8KK@R8@H|$P=WG2cHihr`V{7RVHO@Aw z?EYu@K?Sp&#@zSeq_?4=_#4i+s!U8$7eiy}B~Y?jBUcn7rV^4!aL00Id4MPum^Bi7 zg=^GMzdCxTce!&CRAia>W2^0q+#eBf)j1GDRpndEw}*RVy`I3HvCmycc%%7f6G5!! z6_jBT*WX_q);!3*S;w{Ibn^ZxauhI8_Y%+78Rv^362WTWf{j7>{koOa-*w`Fo*$G6 zE_BiTa*_vV4~k-?0Avm2R_wr0fmxI!eNX=CdHGkJxec1jwTEv~b^`{(VuxsIl9J)5 z`kjy)EEyYC7_4{#-Kw-PYh)#O~LZpP*0H9x((#=2Fnq4;*T5KQq{un}_; z<%W)p51+tM8yJcJFaKWw#E#4QVQ(h=3PzanSM$woqDch+iK`p? zND#Yh7xP!FuW#0j$En*9+(w&w4&#bcs(wenJoXk^icMPIyrvX$bnJ34PaXFj;`P3| z={cDeSTHJz-^qU<{GL*OAA*i|rYQHtEGM+41nM|k279Up*$Dw%>pRc)VC8X+Xv40c zo9Pff6>E(qh?KVux-8V|UOR*I@8XC+E#B88Kz+nii_gNUn6L3eeqzUmA+{1wg9E04;AYG&l>#Do!oprvCS zvhi5~1;1s zbRdgi2|H7-^K^4*{SLYdw)E(b?y1VI{5^vtmflFe@K%Hb*CEr`?GogVu?}+dvZE=OqACihz@Ih6x~NdW(38mEq_J0%zucSi_#C9|9Qow`!W82ig;9y zeHXg>45vWQon<3iq?17ifzEdG!Y`q=fvWP(!enKbuLAU3coLjr3)RAG4X5f&hM&}!l z82htKYX)%do_u=N=D(OlT*Vs+OW@&9ng(PBF zBxi3($wB4mv7*j06T=PgQq zIh@ix?p?@IZ&X#<2>m|b_M^&W(G{ol1cZ)(yP^tJy7fYi0t5*EE?aqIiHIG)JREHW z2#eB0OKnGhtyXuRO26;0>Jx9J#CNv@k>LL7wlba$9;Mf`Z?o6`Z+ka^_Wm9lzht-) z%v}UbF}yrI{K1#rzeiD7Jk=Iii5JkmbXN$j@aq%ze}eAZidKrI?Q*swzfj}S zixvHGEun#a>}fyPV~GD~)Q(nYAhED2E6Df?u53F2@u$)2tH?n# z+SGh2Ao%sA6Zqo$LYU%1qPXaPbaB-;fc6dfW6l5%T5P{IE|?A>)8W(AIncevB665gJFtdgLvU8hnIwIG;gp8F=OWh>oPLvl@d+v!N z(|uWmi{47<{&}UQ8DXIe)y#x0+BKa9z(;5H#AsuUK?)m63H=mVsWR&@ke3_ zURoY5R}c*}OndFe<~WNwHHs2DpM)RD!H3NwnDd%6Qu!m`3c+keMZA+Vu(r3ch>zFz zYCWE5@{+`*l!zRe_mVzq`#)Y6Sn(E5$8G?NeE38?tFS6Nma28p_^99!1Od3DP>hfs z1sc)V1ECRoB#5gY65L2R)+PvF?#-Mqr5rZw&tXM^4^OQS|B|HsYXHXI0|oJMq^rq+ zUhF}K&$*qqSZa{X|FpF;3O7E2Yi4L3jgGF+HgRi@SZv~!CQ<{V7`xc7p*B4IC%-8>^ zZLcl`=!p+|0P{bEHRLB|{8+wZ;`q3FFBp9MpK%;qZ0n}!%FN7suB7x#D15P#k&$tx z(i91(0F;!Kb#3&ZfawvPDjFXVtb-m$%B~kK>UBWN%DVf>gK0grNSGh z??(9Z0wh0c#Flu`)7Jqpc?b*E_I$!HK@2u*2Y2l9EA%g2k3%3)?FqPZ0(Qvki&|Tv zwy5PI-gM$>1XLwYB>EOsskj6Ce8M}Vzm1MxrrzEHmBIg7zQpPPLPN=UjT??A12)JekEVpx($cl}gEwrF{zX zjTexj4(9V01R#iPzHm?%DXy(V{H>v0c+1fi(k#w@bFN{Amc zd1*BlLk-Fd*A*kdN*MQl3xF3?!!=OYct>0`3PRzxwErWA!ps1ND-nCIW(K~Az4ii? zV!itnpbab`^$j{fZRW`W=BxMF*|7$h*sdORG=RNG$Jp%fPnb#ATlajsGe@BE`#r`! z^ZelQzW!T`-#_S**YlHE!<0ElhctTiXrxK^eKTB!U$nM=^kbGa?`cvbIR81iY9QB~ zWtO8AP)pH4(Y4*3dqO)zJZMCu5_j^unm*voy`F=04%65nVJRhP=F5K+Z3|@JFOEMs zAgx|-48Ij~8%ctLFlL-bDv{uBnx9oJ81Lc|$6L(EdTFf)Yby4)d%aiEWh)Tjy>Rog_Z#XPTV?>{pP+%wjzP$x*Y zMYv&e`CUAfW5VDqvbNeA4ya5OT3IMZA!DgG51zX(MROh5Hc_){68B)idhV1RcF-Ju)VG6?5TI!1`=`C8(g~;Gv>6Xg zl$tm=h08TezVZ2Sto5)p_LwNJ&oO2AOs3h+5kW@FF+F_>)#^V|OU&xhz@DuA9X)%ZAHCSWYx_4aTIbN0z#&X)6Du4s2We7hwd$;d!4sS@Szq_JIF6? zP*si&8^cUQiD`5#g;Y7IL$&7GxExm*_jH;bCzq&#aor?c*yLrQVscGcrq=nYTeg)T zwWk`bl;*MNFv)+mYN;k-K+MLmB!Q|#YMltU72eD(hU+UAu)rrKPp0yMu7QTN|NaJ* z{apP?d?I`o^AW45_o<*uCjvcO9&&QomaxzhH*vU5hE@e>dEL%9BM*mt==0OtCy$AA zXzrFPDm!@}8$K-e_BUo>H9g-wZ1Njf!!5_-lX+=J(4H!rbgb_P_d`+9z4M0?^3z`q zp{u*f1gT}{A48OdC^I6iMZ%naa^rRj2e?z1Ush`#C2}t8=TH*H4ZJ1)Sg+W3Oys0D zsT1IXiDFT-`@-F37Q@c*x}69p&8K7T3*j6OT4aA>#iFG3dr*@gHH+TJfDAM*1+tA! zl|3CV8!`|}=`9ZbMtR5|)SB_n){{~PC`(l5JzB~~B=TkjHa@4mzT`h{Y(YlwXBlX1 zt-G9jKOOUvqTXC^0*7N|bpVjDI%aC)kXWMSiGNS!XKxdxsP^3y){9A!m>(Ur@22SO zdqXcquOS9760v8u`x0qHAi=9SbU+MK`b&{K`IF7`BEw`3q3tZ@z;#zgY7oC;=-2u3 zPKGBSmf68h?aMlPKF8xbS_2&Bx&DO#ri`CoiJM176WZ*x%xVKzh!N zy3}$FkH?&GCX} zA2egbyNav=9F+Cz&|($I3)~vM0%i81_R;lv9_P*)r`$ahV z7*D9F5gJj$N}2P-`+zy5EsS?BPqb@#iD253)5K!;NW=Sf;3q0xzMkymHnWT3YxlCx zkyk%e^(6jMyqZ90UJke{AA6$Kg0(iA2T$>EhL-WEB4rMM zk&W?G+MPmB`Ss1A7BAYPz@OuA0Lc6oTnR~33I+fzKh+*K0D47$DN{kX_E)d1yg|&u zj0aTQT*lTglq(j3e|)mzYVs!DROW>4MZ6R;cO@tp%U+vm!V>ZUBQuTW^us1MUG}Dg zDMfuq`c-rLCN!;_e}}K(OBf5bpg9>oXnWj!57hpt3KhhN@1t0^>{`BOxu0vo3=^r7 ziS2r6O7U!uW)v@8lr!>4p|y2R`bJ!Y_`nKxo=Iiv95kOeQIfkUR1sN{PWDH(GUk1EywFgWlVNVQOac5e{o4Ky z=Joi^jJ^W)@vA54=Dy2}TM}ztGpL`w9`bekt&|pwNGt`%5*c#1A&99jfLn_!hlEt1 z!-6+Z_=rJhs8MSNVTwA{?&N{FqNI{zd12eUmL`KKUo(VU9)lC8qFxpEuax8~m~B2)Nr!Bk-yUM?;;3FIe?z529tY zRtGdwFh*&NIe0WQk{HJNPM~h;6*g97ZQE}?Qp!1Mfp{!@Q266ZsNDiTsYK&-4~@v% zhNCHK0c!DphV;+^jZ9VinuMzlZneeW{;2EQ=ZjU2I*RVpwNxR4Clqk-IJUCxO=7Mm zAie1_1RIw8WMbcBLIe~exQNS{f>_v} zDW^m-u47I4I7SqY+H7N3mrT@?4R}Cwp=^}dN@oZc4^L=&yM*ugUNoRcDyyc3MN%C*U*38f!FgxSHrb``B<<|c0!O-EeT~VmsDly+vbOjxDkg?pAWt9jSbSz3 zQ^>h-V56C&&|998XKL7)I*%jvHRk7O6$q||v+CZoJn z=(JxHs=e0RQq#O`Jp^e~r-+7PX@}y2IJfWF?_YffwU-)F)Y(B4>TEq;wRkAT<#wQ^ z=iM;quKNVCRDF|heS$36(^}}E-r#7ywPjuCb3#HUc;Tgkijhm?$++Bq$+*w`kU=FE zxxn|_@j&Jfd^YZ}!zhNAw6;1;a9L<0YR~N!)iiezV>lYowjuiOw1)wt$-VbxqIZamZ@bd2Uk z&34>|lGg-+Yqxp1EOz*mGx*4%jLN+;E>LdYVV$@<9+G0q_^x-ain;7B(c{QPsTI}o zLV8D_IEt^*N?2sg%^Mj>0`QG=&toqBeI26lGT78qtfCm^a(G_LZ1gtg8D?F^wzelIVh3qH7T?(Pi_VVWIs2-EsrZWj8Ovd!h9P zLGW;aG?BvV06I7_-{^hDSf0HY)=&{7JZ@!efXf(d__sp{FeU7OC2Yf(1%B>`4*2b$ z=MGDMn4Lbt@z>TlxyfNur|wUlmJm?_HN%+2KD>Xg^E2sPc(~ki!p8)hD)@M-0hX3p z!U+FA4_1G|*Y176!jUc6^Oe<$%kBOUSo-2L;lTN^J+Rl0e*{{sVq47)pR1{A@Qzdj!!78h}T9 zWtjynkV1hAN=pBaprpD2oC8DuOCIyDp(kS2Mg%mE$4Ud^0Y(cy(bT-eKdXim%ukz?8iUQ)fDXGCcLj2TG=gV6~x)t&|{+ANe;77XM zNFOBStl3WKb_5O#S|fki9n#T?Q+)kK{plCl`V7!E+Y^Ac{&%|5h@OV#3cZ7!zgHB zMDYH3R_L-U(PH9ahf=?HjU`*MnI6qd4H~MUjcrA-OP1G>G{kFb*_C!0AUf5p#k+W{ ziGTgUngc;mCtv8@K5DG9(Fb(F!t-#Q4{IcjhvIQQsPm?D!iiywpLHrbiSqJ3b8!pD z3A;_3L%~ZK0##4v?0)r-8c)f#aqy0thp;?Z69zu`{8LUuwMrq?`o-$>^E#cxr+2>Q zU-GC=Pn)IHoSuCyYYz$VB!3Q*2rsrE0$II%ODiBi;^^pDSy$KB6NTq;bMBClnHep~ z&c%4Wi9Q%+pSov1(ycy@N$Y za`90j^c?hXuR$0xd^)iv4uYUkFwbK}br4=Rp(hbm&}*hAPiTdN$R0<_VMhWqI3nE> z0YO31#G8x5Si0&@pPugR?X3VTdmas-TnOZ}x>&h#TL=ETVg7Hs=&cP{{=;YeyTFQ3 zdRo9}T_-3SxqE_Ya`1-5ac-8r%LXqF``l!HV*coPWsk9fv3Xy$kIpR@KFci6^ZkUb zKr5Q5i~x*Mr|WO)CoOd(=|NYZYtcRDDFN#0IAml>zV24yp`%4a-d?5q*L#<5BEct? zMVs1@GoD=-p66cgb;i;3kq3Ebv0m56>Wt`oG@HPdS7%N8GN2kU{6L#vKW|8;9@IIm zgYK`XsR=vX)?8?GK_cZa2o4KFLPSDJ%E-{cN5xvLKGMB3x@>b^I@^Wx?S}7K@MP*) z1-|%aa{*e12L}qWu_u8*xPc$wN(FLC7y;Vxz?nC{w4HY=Qnx{(*+dzukk<;cSPqeB zaKpX?GHGHlnH3ie#RFfMiUvve77x=c9X(Bj0;Dji@+<|3J{)Jb@0JJAiQ#g|j4WO> zVsVp=AY<=Qay05pEljPKUw-EJ<~1He|32I@{i}z@wE%1_lQB#Kcb{ z2Xu9H*Kp0=)aT?-qCaH=3LN1R5YQbcktpe)w;o z=tBeGMh3u8@^=p?09_NqQNYNTMo;-Qx_*Y&2PeVFFhWyXpdkI;k=uY+NfG_&lX|K; z`2rqF4xwQIhPCii(KDoW&TodefnH z$-FoC`SNVlTPB#2goM#3XmgZGNLV=9BOyX^{Ho|b&5_cDpQpYISOOr2H(VdvNd=4r zG-r^xK!A@#iHeE-=m^37!5sbc^KG2!qNmxsXW`P35gBNYL>3y{dP~)(q5nkaATnu{ z+FsI9n~aeZmO{@kff02>VKP>~J#%a(=nFb{lT!ggWc31d2=Gb7na`hhj&I>p67tXz zAG~?X7SzoGBT+5ajhTIeQ#IL(Q6H$$C;X@a{mYx{vL9LC+1Xh$8;nB7s!C0rOQ2Q! zY+3=Fx7-|i&qE3(TD4M?R|0=)Y^5Kw^GzaRHGX`dlq@_Iv)1vF0-j25K}2d|Xh{Mhx$|1~t*2 zGKTXILCOuo+Sax|MDb*IO>^dS!*BeE5v@k{X{3h zp|S9YJ*DT}yLfp$OPCD9VNi*elXPV5TNWTKl_(%CM#exxu zUh`bq@p8iun)&z9pn5?Zd@F__ADsg$dmg^BMLF{TrTf7R?f~np!E7}-u zp?B$JqRUMh%COpKU$ybW0ABoe7l&m!`~6z{Aj-ywp7ev&^SYtNW;32ZP#f7VNp%%y zcsR1RkI(A#cm1Q&Q#OrQ9rVZuw8hz(nagvZ{PqFylN0{hbnj3f{ zkL**1FlaXmjf z75@?5GQvm8ROuISId6r;#S)+L;!G6DtMFNmBY5mgN#7)~no_(E|9O~1K`r@Dm{7eYB0YehRG?qqV=~d0(|$biXi{fyDG#z=Hc>kd`f*rQES03!^;JmiSI5Se zzmr8SZ%?Q*_-sTXar9qtkw~`aJI@JW+_m3QdPrO$KU_mP03lbjscjy@<P{yKiFh&dywU;(ma$Ga8&B$>5KX8L0;UdUsINcC_zaUXngw0moQg!Dc= zIl(F_NdDqSP$!Erp=kE<=YE@`);g><&{n~6%5r7ULtu`C3!);VqB|$)#05yGyOeZk zRf%;9a%8+Ua9kN!b#sm#^SK%FLHWm)f9ZrfdPl!qt%<(CAusD%nX58@aKI?XZ>21e z>17#KR>|X)5xyl_4!uZ_bIlM1^v%%|ROGepuV96aM=n*5y?XS7y}OM@>NwBd_;5-Z zH_rRf(-S@?cKm#6v=yd^%)`roulG@s{QY__y^I-3!{*}|aXcBs;Mavtg&Z*wIv6b; zhO38%cxq$sL#y60_A~HLp*?106>F#tt*hgI@)#rU<*jMOxlu&h^lR(A{eAWWOp@-! zsi~=M3Iu#lIxM`+-HBo}Y#f}47B46F!zDxP#E6wfpOX!<0yZ%@HF7enr_aK7flaf8Jj{}OAr&Aj+g?A_@C~W;IO~2GMv|jkEl1&dB&W{VRv*S!mOfM?kW+oCxP-T8@L@5fKqb8=i&&a^)o(CSJ&>Vlg*?|mOUtkKgL;HYGGAn zi;l4|&0@2MED)uEIjG5JJN2ARlTPeb6+JdpQB@Tez$?9;5$DUBsVhEI0ku0aUcaRiM7wI^GM7Rjc)=I%U^QRv+%0!1=To#JH-T^ zc3APqMTvEvKSe4meuET0xAV^2X~`3jI{XQ=?(S7W;=kOGlrSmaI6vHUyn$s77S6Xb z{9oPX0;ww!<`DoA$3@6~u~}$vGOnVGz$f$Cn|Z~iNH@jnI9*1*GyNR^(fFRkrKn)w zSj$2N($F1L@Fv?)r}hpzC+tH~a{lnf+b0YI^C&l#TPySB$C`RU1N;j;rjP<)aoytc3=mcz1<+Q*5q}}%LpZlH)7OXc`SWKpaq~issv`}Y_=pcg z-93llXsawV!H^<(EI#`ge97A*q%1xg`m`c-ocNmR>fX+)?g%XWxga2Sty}!SWdF2l zt85XUeIBR3KKX*+L)jNn0}T}@Y5(Vfz#;0Hn{m9RAAvJsO}wDEg^)_?AeR!DSKU1H@J4!IwBlV7@opqB zL#_IfFFFSV`Xb#Nfot6f2yQQ-D;(&9o-Mf(US^f3kR}?tngm!=|O^27%RShP4she5)09M zUDdphFCrl!fsD+~#wJ=cHlmsc032Oj%K=fSIG}eB%$C^HsPTr%N-l#oU*dys7%48k z4bWfA-36SNq{PP$?oXtNT`gD7)@d5jxnvQeRGTpbTt3HzM(&+orBO6Nw*<>U5900j z*LJVJ>k-3`V&1-eD{YdKo68a2)a~^Fs!c2uNd+V|@$T69|+I2w$Sd ze-aX|5fwQ%!piSf0blJ~^z5$UZcXubKTREPv>=6=g|H(u2~KZ$$t2E}z%=f^efH|s zK3?GSUY1O_XaCk^eP_`)pHX0(8&qVGA4n!@ipWSLx?wL7i(mtwK0&g2VpEnFs;R*Z z-q1sHUp4l)nS1mmpC<1{AEDZ2mEJIQ3#y&9LRcx7L$>jx4|2g&Y)z9A@ZYeWCHMy1 zKyDtyqW%NG^V-KKovWHa*LkZwQi%W)5D+-KyN9Qy5{HI{(x!Y-N9~uf7PFiF|JZx$ zu&TDGUszCD1Vm~}BO(n-NrwW`4U#HKx0J-DK}iMal7>w;(t?C^cc(NcC3)xKsGRq` z?|Yx``M&!+-~HqMarVKz=ALVgF-QK!Saaogz6VDR77}xs+!7BY_V``#1U2Ji4S!L< zN5@YIb#-;bkN9|a-Xi^QzM;CY_@P{V{+N)g@KnSIBgy)H9_s_q;v4hN3E!)gU_V98 z3GNc#xDmEJp#IjAAjuSK!??g-hS|nKyhkT+a{&2jIX}}6%1UawtYgZ(FaC;}Mm(pK zCpzTMl>8{zjT0Xx<12ktqRh(5@)3GaMA`0!tJ}z4g{Q^DA+CFqh2(a!YBx#2c1e?E zjUBt~3c;PF$O47^x`Ol_#^xK8y<6Ybj#DgTPX481Vvvqm^^Ls3R55^b?9Ki|`wJao zg-~d8RxvR#>z%pBAU_t#lwdk}p6i4zQuIS%h=mZ&;PqlQqo7fvf{T_G1#}@2t=+-e zz}%?omR>bLS^Gqsnzc{QOgKywD5^a9ykaqu%D0&azU9eUCF5l$97^njb#T4(9BadL zxXFEy4)4RqT=d38n@3I)4XIOO-??5>AcuNOHTm~cOhsa|t$ljdKsoNUtru)9^ z;rx@xXMU{0gkY=dq11e`JCyvTN!Di?l^m8{JIXC$h4iIE3ss^2H7&~_`azho*Zv)ip}1b*)& zFpn|TKiaR7>_qut)3<#xV3~Pt$9$cX3qQLYye~cE<${6u?0&>(PuB3Q_^QC>z%<4J zt0UX*4rX3Mlj(C2>eMz(UG$>EM?t91I!5w{?>pWMBw}hgoD%5GRJ?ssJ$Rj+_Bzdj zKC;_xn^=<;HNE9qk7VL`3BrzUC#fHo8I2pFZaQP|MZd;dHt>CTWS%rx%k3L@j@`@{ zsXupzX7~F5#khs!`wvH}JvW)~c7_jcNL9VU!(LBp|2S;a_ zT<3!Lt)`dUBf$cI$~?x*2B>*|#ZTb|Q1_uTN~V*Z+`nDX4n=vqo5yun+j zY!(sDI@hln+WAONTbrG%@%pj;kCVp*IMRv}Of(qek->8z9~!^fz^>kvZK#}ApT#2y zS@)bQ@$V^p73t%+ZcB7b*wxUAbakgc>Kl*MJW6t?&txlYby4W7&1<2+d~Ln9HPr|?kT*HK=Y^hlpj{Puo}yGP@8zjvC?hGEm(er;M*;U1>a zeF8=M4}1n0bH9FtfA2SBx-oU2vQlNGc0Whn>}yV;*6hdRoYzeJU*$VT@&!e#B1j!| z-25lvDE{UY!oQ#vI{0$1K!$J{B#HDH@m?1#bnH+IooI&l4CENOEhg$g;6J;u5fm60 zNL>}6ryAPO-;ckvv{V5AotSH&`?85YrZRMCZEicgQ+FDG^m7QLTMQ-2Ba;3fiMwxq@%2A)1Zhj9CAVf8GK&%D=yoQ4O>wn%cDD4L)h5z1J3h__i>@A&K-oy1e)ut4EZdbE$=PSoI62Xc0&zC$M z{&S7();&eAgYP&_E^!*L;h5L_y_@k3P8d*|rw0*1I%x8<-HmkY%jHeigRm+NeZkEk z@cNa&)oLMVT|Xdv&83^d8Pd1k!Q=LGXc9)QjhkZgUuat9CxXy4YOHUM+4boEw@ZN@ zXzh5z|yg zA%8F1YVE0zN%!RjpvVBgRn;;Y{((c4#5|gh(O4;_x0se`)nXtu+KIsFsQ_+Zs8+D~xGZt*5c|qe})*_qU z*1Xo+yY(N69m3HVw=javnwbRm83yH9I5w^u zfTzLM=HKdhX~ZNgFVPw-G&}s7(gmR+_97hiHdpB?RU#ZM!{QXrx@}=miQvr}bfH(C zM3aFt2P@_1SxVS=s))wVQk)eBq;K8H+(eBcK_}2}QGtr=X`subLN{gU#T)H*KK+3^FBhUYHbBhAiEzPkS_9>?sPFE;wXe-fv0t01sc2I?1B3qcxMK_f06)0R z@@RdV6Hm(-P(xze1<*pCPbY!S7EaTyA;7u=NJ7XRtD$C&D=447^=Nz}aT`WH`x#07 zNe#>UJR_oFoTpmK?r^~D#(}Qadn047mvrwAd-#&>_za)NP*zBBvUBX8uRB+q=Ckv| zbpm+;=-Td19~+7%^QrAw2IiX%icX?p_k0r3Ir-FoU2G}0!H$SRrLv~uGyQx1&uDk;iZEA&V956Q`@E}tos z5(Ad9(Be2a$5DvF>9~!@c$9&DG}hc`9AI31Odo8 z$Gg@NGEQ>vu+Q&(9cQC!Sa0?# z<1H<^(=|LC+I;&&B`%B#+s~_XPSf<@%7R;NUmDXR6z6*0bMS;u-0bZSZzoQW+e!Lx zM+BYGyRA4C?UmSa))N}J#Yqm^K76=|&An#mcxQLG4Kwtu<3ig{l}+_SF2)9wX0O{~ z&PO7T(imD)4v&+!bZ05M#Y^h0$=^wmlzrzF>BUJd__6-m3Pw&G|Az>j98FsbRMBeE zZH1fuOpC%h`x`B<76~_~g)V!~aVSBV`zqy6La4PGu*$S6lo`638Hk)l2E$4h&BDyU z!=F{tyN#rZph8I5?cBTfL{YCwMM^2N%kW8(b@ER|TSRuy8$WZ^Rancs$BIed_aVYg z6HYI=D)G!I&D#$Sw8d@xaW$l@Uw879eCMHPk>9Mh^3v@YH1;-`Hqqbp@82%2^NIi2 zELQHtVhdAkDIfD4u^q*mOB2oL6SFq%wz9425}K)8HcqXtJ2(%?<0GS}>6OtxPS>91*OFoV9QhdO)COY4-(FbQ7)p-J zpO*o*Y@`BewBip(i6NDjqEjGDD#Rtk@;kKRPYT`v&yB`D|2|i|9VSH;6e3~f4*K!9 z(Z?n;W$M&jp@>*2WOmch@B|MUWsY1n;3A-Vt9 zNV`f?KTxyeDxne_SpHSv`Iqc;W*zgKUV&Aif0>NHG*qGvvfhDwTU{%Oi=*I%L?)H6#Ws`H18jLfzxgN#mx-##{;OMKmk))e|VcY+W4_ zwro&C*Xfe8YFb)xG8#4H2-Yd}$j>LztuClff2Y%Hw*ceG*4C=1Sd_#p|N4VuQX&6| zDRIy#iXrm^Zeom=XU#Xux%UY4pgPl0j4(9$uT;eu1%-BAv7PL@Im6eQm-Q&cBHYy9 zaNQZ^N`93h$Fn^G4ox?o?yBnhh({mCT6^J!0jFp5Av4e3fqV@3UR?;nWA601cNfO> zlQ;<0=hvfnBq@ZvQmgQ)&xTV!-Fa*jzB+gH#|c8kORLksYLgQeBZ8~-dWcGY`@y+X zVSfehS-zS;$>sz}d}(QKg~8SD-P&H+q4(}F(l3ZtJs*|lH4-|wf}Hl$hg)vHvH6LU z5t|8GLl{j{d~*=upaIV>6QrK+rViNE4jv3}X<|sc%6;|}l~guR@ql8Zpt}zTqrpO} z@yO_)9m)G{RtXMe^Cq#ADR*N>qdo4NR>*C)Pl{gq8m_(A{+`!u9`T>y$7`*;`1T5C zrxvabmk8q$C_MIHwRzdr%8fHC?~weYze~fdKjV{|j~Cw5w+|7xzI+l9FN`9Gj5PDv z#m~zqx~m%=1#sKE-6wK@xv5u??Z=`K5*svCzWBARX4K<$6`;D$tC?spTi_eMYK`h5 zH^V&+jO)Jh9KQSQqCj*)46Hgub2Jpca)4e>4YBuTAPW5?OiOTY5HyzI%x1`JC&%KQ z2%ZvBsUqI-1-fRdcsYcdY=g){)R9ynjh7!>Dw_<%b!xlTs_dH>6MG9tDv_o@%k$AO zP7R*dJh0Od+!Xt1v1A1tQI|!kw$AHfvG8|tV(GIX;n@Wy;Xe+^QmV>DCs~@UWUmv6 z%`bHtHfm~Wj8oBcV7$h5dqkv0TDiVy6H6PL7 zm-#J=R0XrhRW=2bOWSjb2@IJ(5_HF@$ZqOawunOnC~-*My4yFS~M{$2f;!f2|B zRXpgnpLJ94)7#yYlr&P;gR}^-qzC<)?|VOtuHTlR;@E%WeyDqUoZ02Qj*GXAWlryw zH+iu7pjm@X{$9P#*0JvdeH6bEJs^dQ!*O%S!aS10{s9AlMh>Hf>NPbEuy%Zc_4CodOf6xafZ_pV*>c312+@@s-PP0qh`+7FNMRxl8MG; zDvx`6G}t@uXW>WenPN}E-RgP83-x(=w=nM7AL51WN7G2fc!D}~vV_y!m%nftoFjX9 zzHXrUa%TrvACpr*eu_`yHn=Fx-(10x%WhTtSmZ6)h7E>S%wS8LzWnyUOM6=T-$aFk2e;!j}&CX!yztas?nh7U2>;!{iIqJU#8E2-X}jgEEi4?`+D4jX9<5b)d)Z@g}x%Aq#$0e zgnEI7BXgl_HS;@!jbPEzlMZ}Ly?0j6_nf=1@$EaSoP6vMhC$qW5jlsLq4ISecHA`H z=xGcbyGlebELrELIb!1!Ci)%e?e7hcKWB-I@YOJuREBu_s8_U27UOMgT+f)f_OhJ- zu;jRB1a0Nl#&F+CNPBl9=2-WWfG>*z#XYGa^6Mo`C%V0fEJns0Xg|@)e7{tSp)=>a z^-!of?a7|TE#BAmE&0@eO4o`EfLPZ4dZ1yC++Ajz62*eb-|?db>p%(;=kp!%x#O*82I|e?q}~+ejd) zal7(z$`iEU$3YJsJT0Pyu7)cLhb0yAGh!(cXth#+^fX8{}OceF^(q= z7L&!8E|=HY(B3`Z7Vf{x8&&x0Zt^QcN~cfNid0FCGWK3fY2)TG)i0bT<+!j|ymwl+ z4L_Nu-2FcFniQ^E3u|sJX0s{~1kFLDH$>wDUgUS6JDA0pyYCAeebTF=k7CzHO}_y{ zKixM^>VJ*dA&^!d%adBm%h4r+`Sr+SZ+kIPwbyP4$@|v88$#Y))UJHvx{-pz%Y#im zB7k32T6{GRV#IWyeWscpH!fmCZDdd^_Oasr(V%)57>~4UvWL6-1pAQiW2%NXNS92k z^*06GTdHZT@L+;#%-eYF@&`zu&Gen5Mi=rXP4ZoIrD*9!>auPH=8x4vHV% zM>UOhZpI-r=Rk=UUuOOM?Y|zk;;!i<&3_P@4^@WG#L|g*`aS4kjZQLh>!A!}*Yz;9 zPk7snJH~nx>c`(?sVwolfpvTak+b#5Ny>@CjAi|+=X0-~d_5szSa4(9pv3k7GinpV zvwL}MQoj9r0vc?Fu-(1mB+Kbqwiqrf#v7CFh8j0*UjCB*?i??s#$>U<-uzKE@_k&E zOVlT+mLlb64hAGn`=sycIs|k#+mFlgZ5V4WA9YNF0Gtw^Q9c2I*xfZ^Qu^?DxN*v zBY5-}Z>5GFUFp`XYu8d!YzgS8y;=Gm@p_XxZApf+JeIn$BJlA}s_;!E`X}fZbq6w{ z)EF2~T1)tTc0TN;ivD~c*!}a@d3V>L^K#8=omsT=fu=5&AMt|Rqs;Vuq7Nn!)F%rh zzdEA8ftODA7V4irMnlQ4;|Za0zk-ZTdGYZ~6-iV-+vWiYGWttZ_a2^X&$tk9k*D09 zR#ZPMb488dtX*wwDXTad`G$~vpILco>%dpiz`wtDuh+kZ9z@~QsEkhe%njMQd0!o0 z%^O@Mep0WLRQTb#2IHSwf%~ms+`$Se7Kl~G3Aw+>(8|$VQTgrGz_u3{Kcea0GcrW* z41Nt)xPAmo)SO3=EpY`2{1f^p2)>e3Xcrfaf^@CpjoCFu^GlLm zN&zyIwV^eZ5mIuL*`Y*HfC<>jz{tY2mQ}oq`Jj&+8ZZ%=p@GO1qz4$duvm=Hc8Do* z48lh1sXm6|zgYynioQw7(RGUmjmF(Q7X>}YTnA|hT3R48m|*>=(CPOg!K7>GxG=4j z=%;`P89;=A=fZt3je8g-E{xB3c9iQcGlbIt-ySqIeF1zk1$&^S?*0o}nm!gT>~Q$O4FV)ydwiU96OCsW_XF-s4PZG_E_#ZLa*CQ=H|imouNENX97Z!yr_|=)RtdB z9{&+guyxLOK-?mw3T|A(ZGC?w$=WxH2OYXhiH#)f-OR_bp;p%^rus&cEIe98wuuh@ zX|9+t>oCrLCnd_1R@N>Nzb^TGE1P*ug|hxxRH{zGu`T_f|K`_6t7oUj#yL@bmy(NH zPzwZMuQM7C=~@w`uu&WezuaR;P2SUr&VP4ySR}HRWsYzdKzl8yTKJGab?({2a2_Q! z+KKk8)&>8VIYF)7LWk0C`c;)VTe%JRQ|c(?Aslld7?s2>j|;5}RnY!LRTV^4tWp6k zpz1B4O8g@a>IGHINYXydwXNTBs2!6er#Q|`8N+xe2+gJ}e{8n>9|ty{Z2=or1ZtyTWgSak6% z^PAU5$^tn^WPGK{do|xLF1;a>#qKeKiaMC{#B=Xe4t@MRHPYH z?(XJ5v&`qaav;S^LD!(>xbg1#pvW{0f~zh;iV2ZQZQ6!tUAoUulpE-8MxWvt)@E9C zEaUUoC%XxezxSm`lcA(K2Q!yG<%RT=`k;@UUF&%!vgI_}?bk0yNKSX3BGtsvh5T4* z&v5zmV|B03XRzS-nK_T$6Nmc({Q~hieOiyFnX@#_bvPDU=y~newRs5tTfQ}*|%^;gMv%bWJ;n4X>O;!3w|1LMZ z(}R;70YS75R06ny;_rIMLeB%Lfr24bp@unk~>`=jq8U zu44B!bq=iJMW38?Lnz=CD=O~~)%nZA*=O~iAXp39!C)r1=a)sD|4-^^xQoz#;?%pCO{ z*}l?e<}L0sI|O|n9~Ke^fNG zQC&DN@F9Qay$OKGE#Z5_Y%2P6-93-WKf~r%?9I_?N+swGT@3r<5BJCdzxTjqs#|UCn$)hT7GA*&4 zmpkP*NUq%dE^A~)@0u3?+!yeJT^uBI7vuTwJbTwOGU)0%m7uNpYXWO+W3Wl}#j4+! z{hLS@KgVy}4SKTb_C3jAZm#}3N4h1|4K6A#j{Ka~hLhWtbtNrjSn_r@`^hzphv2e| z95;m6wFsu~<*`_xkyqwhzqQYUB{!?KWeVpZGbr*V>fTe7nwC3K^_VSR*co>mq}LJd zHt0?#eK@58UZOr|J%Kuj`EzJJuXI;!epXX3DaC)eEo)iVA}@DG@BKlP>C}CnHiv~m z=fc|K%s|Xq9qlx%TRrVtgoE3q>hs(Qpux#V=#fAr_weynq|yrV=iP>J%gnNN4YGsc ziPMk8ce_XbGD#mD#2$LzPAi+MmatxU6Bv~9L{DbInu8V1>^uxjsKLk zj)vuDq8`(*0F#{KfmHpXBWY11ZH2@trlIfxHXk2fhLPjI^fE-o97Rbl*A`lm=>%E) z2%D&CTXo9aQ-ihE56Zl+m*jKf*d+)3!+Sr4w-At%erk7PQBUbZQ7QXkMJDK`TPrfF zl$vi~mzAdOuci`P$;|m`W9vwN`k_yTL#HYofzw6_+(bq4RSZs_@2R2f*}{{J(W)m} zthxcyPNGI9p*A(Tnq+R#DdrMgYbW2tH1Fqp{!tw&AK$#uHnG83gxU7%FUP{5Xl;$# zIF0r;e0UqfqAg(_MO2^86tyhC9S_*pAO+f?w@~Po4+V?EUKUQyn#PNhTEcJCi4?O& zRqcAt-+FFNND@%<+*dhv#mU+Z^mm#c7Ipd=;;?r#Fb8w9azeBSee=Rd+QD+V+da;( z_XX|flL|e73v(i({9KVSFKb_ED`5=`@x=lf8mdS zw-HKJ8P+e1;xYp7n%9PAnI=4})G=o?P`8VG^8-u1I{tCoW^;3MJ{3C$Jb#dt7vGWF zSf~7IaJJTB`Rs8AB$w8*`4Rberi6MV(Q;{OUBu55JHq_=$eS zl#YUUem+CyFgJmM$LJ#GuU4kw@VitTaOKC@9O3ODR|iVXU2Ec($v9t6BDOQXzTdA! zma|mxLVl=P_*~+Y!||=}^(UmK1IZ@rHBY}i&S;>fxD8v*T}Tc~dRHFMI>H(9OM9RJ z346~esmNsV*s$~D)Lk@eh?aILA-PF@EzEUiYBE*?Hq4Z0Vi!$2{gu8mz1ioI;+rU; zKFz1T!SBvft!tW@F@o@Y4vCPit%E>%B(Lqu3ut5`2C$n`R>s+5mMiHl?NSWg`6#SsKHwz*TRMq)xID&2QrP7Ic3?$aN_gZ zKR5t_>n5LhyI9_Z!+27L1N-8ISvNEVWwEnWhi*R($aWeRJUTUdySbLsKn8_T7{ugdLFcE490grx9-O;=wX#o9BU^D}&fO_Q!*Vkj^_oI`5_{l=n`; zFmvYQM_X~_CmYK*68W8ssUh%FZ2zLwXa*TMm25gQ|)2!=A`(rJRX2 zxo!F7OW}PZG|ILdGv1>vVSddRku^jvDmA7A%A@jb10J9Fc5r-k#?n~Z7kkz5%U8iM zP%?twnl~hyrrGA$%QISs&8j^^MfK?$hdFX7S;X zL51?E(L|Bh@?no-{q~M`vphrF8$gF5pef*ojWq}`>Ss}y@L;jEBVBwG5{t`jIoyPV zgXg(`rp>l&ZPTBO!*QZcO{Jf7$@LUis|Zy#f1!k%p7I^l>AczdfpBp$7kM6@pr?~C zt4?6ImE??RSa>tbr#W3ZVUkNSP1jkBS^Naib8lrzmNm#yU9l;ftG^5D45t&8@;-ph zu7QqYR<|h{J*dCV;BA8i$~V?KkKS>&y+7ed5_ue+&m|KHQb)wqI_f{3ybKTQ5)qS{ zltsX>QE!a7$w)Hx0Y{mvY!m^~HFA)yoe+~ITxomI$x3G}#;$y2zm4g& zpwCUaZGA3IZwAMm-ZW}Cy*a+^^hTn=ak0GGX=S*4w=cAOZ!9kP$fVstbFq+0kc~^H zMOz3!zy}t`CW_@_PP3)3n6egW2RnHWx*^28AFaxd8cmal^vEL|vebRD)oiDxG1%vQ zZ)#Zz&aOvBIkx$4R1yrivz+H~c3-VgaJ+1lUmeKuXd`4mkoTW|Tmdg=IN(^?zqMq7 zkq4!#7Y_KP6xcPhqaRgAvYN(UVsbUB;Z?rDq!}y%PNsp`u`(jqLSW#3N;Dy#eaD8C zMQv)fHpbp150+=1d$S$!ePfVz*X{PykTjp}uykEr-uZ^3PQHbUgk>&6Ua~YJVlyTp z#`=Xvp7I(Xlt2(#;z*9NlSs(UfT66IUXPY$-|zwd6v zEc9t&BZhifIM*^Q!YCFh+jP#J<7}#uT8ryf+N&%VYS}*6aq9KZ6w33fB`p)h`{3qk zz;m`@n@2*nne}j9Gs}JhhIm?>9>cYf`AW;4{tg2bPaVlZo`{{MU=h5ZXqNf*fJ)6> zbG1*u1f$|BXwELOmy2-Nk#bwo$P6=hI$KGsP9}~@z5HPehdy}{`-bNgWP2!O=T3V@ z1#yT9g^2)0_ae%Ieb#NQ(wCGprF)2DIM#x8uff}4_vEmA&vT8>$-&~ypx(5U*p1*| zA(mBLmAR~?^MfD zH`16HEKISN$OqehA9(vU2j{kIUK;Ya$G~DgW#|;dv%&=?0FD06IK)yj2r!{>OuytY z+eZ-0C$%-bz!P@wi6Xz?d#gW4?$ma9faU)^WBpU$Q~YZ6;2k;obhA$`xpwV3OFdl>wytnQ zhMAfHy#C@bWLbiwBRbh6>R9NKaV@V}$7i18Y!8d%A5>Go!5CD{<#`T$*Ne3dJKNPM*HB$ig^M;ltmoKnT8juJv zbjSc*`yB^9vjVH}B6`0_Gh+q@cBxtKgOmb2N*xTWPSD1_6c=_79FZ00tz#nj5rE~6 z^cAr~;=%xarS{z5<|Q>=5XM#Q&P0J^hz|yq`4{U!1FONnrM(4{-!}$MA($ROaZz@! z)X{lzz;YWSB7z_a)F4O#^Fi3}{0FRtSR1Tn2Ib{1bRH<1E>?{@g`CO~SO-@=o%&_6 zT|nU>bap5Phrn)q5w!Q*X8O-MCT>X@nZzcJtH>j;?mFcTH=P%@Ygs-?Gog4>%x|H_#s%} zADW+?Bd7NqW@RM!Q*fFLwD#pPfcMweP37PMHwmyxIJ%eKh2Gs~p1Gc69XKsl3eW%4 z#zo4SSfTQEQ(|=_w3Z>_!0xnQwV;f7CH0_fU})~a^DNR1u}kKQ<2mwhaQU=6{j7?T zRH%sP;>8oD)CKlJ{I|Vuf8gC*Nr8AZnZ24D%2_&Rwm_q8&0WK>7;D0y@Z_dA^2<& zohJ?KigHA}ETn-3_*M};heMnWu39W1Qim`j zs!{&{++^?#g2h|l(DwC&PW-f>PHt6jAI7vF(Fa>t-KC&LDN^PFk3kL^%{9P(t=nec z<$&pP!a#=5fZRA|BAY@q1v1VsB^7S^nvPdQIMr?w9c@ft(@u>YZssz=M(@>O4sYe- z56kGe5GC(YExo-4*%eiO|grKic2OBFtUQw9R_4%4_V`a1{rk z9Ik{IHO#$f3AgTFbFa;c(CV%`dN<_c+oDIubzdgH*)`KYS7POb(Hv&rIA0FwAKfl+ z@Bn8_PkerD3JxcX26?)5dIb+L@GKAjzJ|#r1X(RJqzsH8JNa4(!qpV@*V)T``jxL) zlPqTGmNWZqHx0fSgHHy#eedl#T#6<@C~uMtu5jzAizVBgpSdiOOu z$#Sp3N+pCXcgAvq*sdm{y#pu7+Mt97xFs{lF8;h(a0N0nJ;+`7FllxX!-2ZzNQ?P= zD$AlW;0(nLl1brTQtE?6hb6-*Z6A}YR=D9l`G92qtiiV=9`1$OTh7kbT8)b01*fW0-L)K4Y^>e>qv%}L1|XzIrI$xf*43zJ*z{XRY;qwU-bfv03W0Q7wytS0?nEZrX&xOr< z_Qbue_a-<`1)B9@B-9L_f~J|pBj+Wz;a^obYYX3sU~)@S;c-! zh#f!KlA-xvPx(&Oa2rmJpEJg?Cc3IYXysLhe zCx=&FO{!83XSe+{&~^PWFXi({$ffG7gxEY=V*IK~lKYhDfFffVX&-%vG_TuP>b{v? z-U`j6EmOw;QDG(A?DMM2b{S^v(?^p;2~ri7JCm_vf@QgFw^&mg7##+;&M@@KmmTB3 z2LBBKj`2YiT0Fwy$tX*&p4mItPJhG=*EOt}M9z;J^C+{z+q)JlN=u}pMRzQYCw1e0RA}h@rK{xet z*TOP2ZGXv3XYCUHvS6ieq;ASS3DN|xUsl5A!?|DP{;sGIYog9gFa3Eig{c1Pdp013 zEQkR+H<%d>l}D^3kqoZ~>2LY2ot!a`6&+_HTZm_5ng$}XkPg@CWZc@{cGLUXbZ_9m zGkAR>k6EkCs6Aqm*RfCexgt(H`D+QH;H}}UZ(TL{-?fJA9ESq?Z7cDi*tTQ5Vrjr!&`UeoQ&Oz38Vf2}^P`#s|6jDCM`V&aJ3sK_OIk@bb zGz9)A1tk6eCTZv17;-E}Ssh5p2WL=a6^2dj+AVKk1eq(6EIqp7p#nl621gRf?mw9c`vZKgoLMMrkV9r^g$-oJC`)Zb!cPGs=JrEP@tKz6Z zp$IV)!5IJ&E_j($z{*d?E z7t9yF3k=2skEW!{^~*5=aE)uSokxD^Y9e z_#*dmg0h>AcR1uuZdOYTnizN7;l`$zmohTTUS$K;i=P?*1n3wz7gp@0C@2HtYmi>b z!AuD~}i&289UwyM+P---7gm80oc7GdRlv69>oe z+20)HB2{@dLe5r`A-hKR)F{qTX#T5P`^Rj`e&YYO_HmK7ysLHCBLAP)CG0C?97jw@ zcP0&L+UNIP?4k1{gH_O|g$qCeF@(>iZe&(N@Bsg>Mu0Dg0C+ycZ72?EgPtILB;4i! zKnD(!a*7fPg>4@+%(TuLKYfdzI@EP=Z0M0QT4YvHrKq{Z%6Zp*`p+M`Sla5TK@m3vESw~Kj^{$P2d;Gh@9W!=X)=D5q1Q;h@7}aoA_BgcXOcUqnj2Jw z5F+LrtH>4~_d2>~UBZ_cB9pQqGHB!=NgGQ#R6+pHVvcUPGz+)|m4MTO-=abIUIc_V zjzFO6B3WlMHFEixfUp(Feqk^_ZxP&a1Z_9!>U3%LUE zPOPD*UsSLv%18Qy-X^;z3fS@1Vg#DxeI*37w=N3NfFkIoRk(o10rv~g!LDUO72PzR z8_*R>PNZVL=IMCFUNyQ<@p-s9hn40h-;V2jC8|l9RmbUF&f;rDmVqofHQ53Zn?`%V zS}}#ZqWVPM#tRc{*fE4Tn4SB^M>bmn5gq@SpntYiLkBQ%bwLJ{3Z8<*t;?T$`9is( zI5~nVG8m@glnM!3LdC=2ksPhek||5mJ#A!oyms`Ov)o&&OS$)ayr+f;602;4NYeJI zEKS!vpJ68wAdtemRFl4u%jzvX@%T3-(?`iy{xU7WFW@$v4g4j4$ zdDn~v#T7oRxD(4JVlc^?Wa_+69_*E z;#*|8%ujQ=jxPQ`rH+pyZ)o3Lifb&MLvvRkLvIPybhV9*dE7;84Svwu!=BCgvV%7$ zzE%q@P*zkNYE?q6&qrE6K>y#}(PL^d3NnFjXZ9 zNy>2+#ZGIAB6o;sM`S#wjYpM*;18yM4Bv(I;|YaSS2e7La^@P4TRDZ7Wl*I?L!o{> z$vRd@rRYm=YHv|@G_b!D$qJuYYSVXq^6#4G`>fu77IYLema*YnV>ieu>Oh^s>C}e0 zN4AmI)mWo)79bl_+u@RA{qpc3w)wV4Eoq7NaEcNVHXlMaaad*kjFBLstv^e^_JL7$ zOpS^HGit87qzT$KC>sAxf!rIRBAX2TC^~W%6-e$$?F=HpHBiFrfWiExRZH{jGhd#{ zK1q3%s0?H0epJ_i(Yrk=0^^#mM6J~A14m$UywHv6(hgRXd=zIf8LTv&6fn5b(rF^J z?cK&XiCAf8jW!?u@H}Hdi9Y|L+R>`Qa{F)fnB;~#Mv$`g0@WWSuNQ$pi;@B}EF=jC zv>0eBVg=Vg&&|?}plr8N*|b$l8Cb4U;#-_Ri4Kgx?qX36NAUtwxf?yZ;m^nH*`#L6 z=N2}I@^p?_5$5GtCX=QqW7xdem_cer&3(!SV!(~wroDvhGGsM~p^Rh!@E2AwfM!RuI2 zUN*W)xsy*;oiWnfgl|M_%T-YCK?Eu1?cOl(b_f4jS21#l^8pbDhtCuO3?cPaP0h3u zdxyR9uxaI}^H-;D`n0%Hl5HE8JQVEctnT=(n)?;9$~Q@5vCWkO5}^IH)s*+>}!P6Zj7r?!s?gdB=NfKjCTCZogz zt|q^?nns+cqLOf4lk)>-)7XXkq`KKIFS&tYXn4Vg&-TZH_32IvFSe1A2t^rjUjK7z z@Fp@{@No8&zBh*!t)o=GGr2Z z4GA6osK$*Jov(iQ!*ryw-T%pv!j3Bnc~n;0;~!a@ts9kwWjfY>mF^0XDG0f=q+{Ly zO=AM~$>8|{HAGiGW)wF^uu^A4fXZfZ^ph0p@>3gYY}EsdFGuhR?7di6j+Vom?OAeN zMBc;Hi0OQVfGM;AgQ!H!8`X%VtJQ-Q!w*#vd`iWHTU=T?H!bBAi`!-1O#7>vnfc?D z=#eoHs;3?H@JMAls}A0_3|C$jN#StX{hrF6>ZV2Doc6x5OE9yZLv-E~g?BY%X8hYQ zeA(McjXt+cuNx>Rom))ZrKeff0)ke%*0>7%rVntUn7IFBhpivo--yji4w|rwEw0H( z!m#$l=_(FSD^|jYj9&Tw2)?YWb2u!nYz@KkX)t=sX+qVOh0q=NK+PLAs$Ez*!o^m?RMqI4hkcA_-e~U&?dB;Dfbl>cgsF)Z9NqMq< zU$wyF4@zW<2ps-x^p$2GnOr-~r{8gQ}VA)Vp4QeBhL zt<2i*&T2uZj#==0X~g)?P!k8fEF6>Z`y3I~2SMsSE+_+bW2in7=XOMM6(d$U53Qw! zlRqvI&DMlJsH;t^lSop;_;En(Rr*4PanZRZM|^!3uKm#QB51mZsp{n*u9mPd0RUJD zm>s!EABlhP*SpU)dk*^z^morP#6rbSEx8bl+omSm1A6AZhgtoSZt<0*w2AIUIzK+A zo#BTdI%kxRst;ZbZoE+}b=y|R&1+HpY;W25w1QqgwzXa{`Z%@l*6SAaY}68^cMe!t zYVpCVJ3l3{VFNm{vG8<*&f^s;qp>9GsdAI7=V1&cQ_01?H(*I}iEio0Tetcng>pmP z`XX0fJ?ka?7r@UAh2+YZgy1U@C_sCAv*p5;rqVt;>v1fZI=8jz%RJsgExo;zKjd|~ zyGW_$%H1a)>5@WVMWd7;_+^!E-@$e8+vmK-XK`dQe3H1gkwKBIxwneYECms# z%)k&0+&}n%Pcs_FCj)%!m>T)non>#M(@%s9+J#kRmHB;dEj6>`23L<#?ZtvLt0mOM zlw*0qOSeHQ-Jf`45|SdFCmP@@emVD^Lu+1sKge0UPjF8YoA2h$8&(%{8Jug$HsPw* zVs`s6l=&DbrgEVqy<-wF#w>v_i1j&2ZP#_3IL#3}JBt%M+I%aRGb#I;$U@TcSG1EL z%YMQO{drrV!QxFu7B01e7h%)Zhi9ieO;c4F&hHv+;e9BZEkcHs1`YC}MseGZ9UX4w z9n4gZRHTL}#mA#vNXdm&`Ck~6Ut;rxPFwv+Pv-mg*9J}`SUESBb6JnxAgs?BO&)xe zHb*7zk8~|tNy#T%oe$PhEndSI{O+VSSQV#QY8jF#wUHN7W#yW_|Kiw-;zkgSc^xPs z{c)I-&$vLuT&!pVtaE`caQK`bqpyN&z)BnGwO?~-Y*5c};z{O#5DBi3Nm)z=>hzZC zY2L9){x}6<+%Ck#tx6)%_E46h{AoHYcL^aLJBa9g?uW1&$wO?EuQd*>sV??!aX8HK zdVRr%-OhQ&^tZg&S|AK0bwBQ+2kU>4vI47=`o(thKxIv_@UTwGnL{Ac!Fu}k7g4VgFc>?NRqVW0-#_kC@F$(3g&01M z>Jp-=Gxdm=s6@#lOEFyzHtP2HS^0A~D1?~}C-PrNAJjNr+7yigq99O6jiVKm6Ne%S zT`*~3zdrIMCoc*dX#tay2`sBgC8umT_a}lI1Fcj<#wXO0!?;X7l z4HO3hAH1-k{}Y^E`Bx#0R2ldi_O-S=NLVi2=Y{zJAAw8&cwAU5w7(VyCDj-KT@jFI zJpj|k;)O~73k3RGNSld*c=S}=9>hxjp#=7i>O6Z1!Db2NQ>r0IVw{Fe;>=I$#PBDV zOaSWg-@|5rE*+uE9iej_{HHJRbC+haW#vKd0m~_e?N=UA{j~v4&?!%O6)c2A zcn)+J14qOGc+;Oci*d<>YoQm&8`q}FF^fR>#%Nqygg{2y$821o!&K`~B2Zm%4+1|j z*S?Yt#iy4g&@sL zF&6ld7I-lo728r+vvI%GQogl#Gn>7vQ7K)Uv(`t2%Z}@oe1q2!Tc@* z%60Of>~OMR9|yoWbV^D*SU<`i!vwxaWd&fEMeiA(==^Rc52!MmfhgNd%q1O?FH%sM zA3^eOCHzaoH6|7?{%j`_H2M(I86t!1{of_~zlD4#-UUo`g&3dAIX+PEIM#cH$5}3% zUY!aa_}>Da|Mkv!a%z>nY`hT^&8t3byOmrnj4iBc4LEHiS#U&1N!7va{m^VK7 z7m0T;0S}>04w}1N1IeZ7+lLOaQG!}^fw7N_;xe1+fY84NLLVFHjsk6iFKATdvi+sO z|68HK&W1yK51`U-0ztXgx;fA(w_gHjkzZJ@DE$$zr+8%qW@!{rvL5O)&HIF zQttkL-DUgXhgbge0{rhsD?xV?t9FF~c){??e{f%SuLE$P2;IWg7Hfa(OlIaiA3s03 zp!#}YW}QkEP>2c(2nev4tPBs2Wcmj`{Kpj3Lk%9j%w$*+^$($LKxaosBQW~<^^4XO zD^GGBn+5cw!q>Gv&!FrQGF9Ls8lZ$-*9iSU;co-_)pVVk&>6mA`nkxT)#x9%uY@(Z z^o{K2FXvnsor@2UV#u89ymXp2tE?GU2CAEt`r)^|{twT4fd;<9+=H)By#<1oXA+u+ ziVf~wn*DiTl5dyWgDP|e)cw*{RBQ|`)f7W^Dyn zO>-_8qeMMD7#Lr)ZUzGv|Mf`6Z+^O81rRu&mGvkLIT%>^^|z|8R)M<8T8P!Tqdj48=#E-gpbIxRFi-^?jQ$(JkNbp{r&q_~=H?bX zbxq>&V|spme&cJXs3xGl9>!%B1zt*FyEeqERkzL#Rq6liE*A*&%P{!DK*=Ty6HF>- zJ?Blxq)}i0PcIYQcaIw9gPSm+l>oNoO9t`;0S5Gcj0vKiAw~v|ONCGf@M&DobQg_LxyZB}_c`Z2 z`#JahNoN^SLuzXxT-?M051}RA$Rx_CRW5{z3U7H^y6+_z@FD}WS(*G2V%Cr<}Ce1DEd)2a+hsmcX@3JRnTGh?l2?L)2Pm1wol5s(DS)V z`)&PC?GEeLFZY?rUEFjn`1+5dcIri4ue4Su1p5mt-+BUD0F5^FG!I!Y0&hz_W#w-L zQ7`wVZET}W*tzps`J;fz9=f$j_H5vE^nG}2qeA9OJt!>W@L`T8S^|}O{r0xB{WzBc z>!cTuZO=uZ-@(g~)SsgD8yMH<*tlEg%3_ueAO3vkur*TfI$d{M)S6(GgjVqMG9VmM zac+C?2;xMWBOEsZCm4W!8<{s4e2;Bi+jRy;C?&>uZx}|(RzKyV^C;3=9@^w$`jq2B zgs5Njj6ss+I@DL3K*D(VpgS-0ky(}8PjGX1zoESV6~2b(8`&!}&$7PS#1`&b5)zG>{2CBBh(iMRy?uF!Q2^J7G(IgA*Dqt5^adOh27B7O&9+-FDw{$l)cE*r-@Dw^LUJmuq_pj1{_E4@ufaUC4z$ zQaSIRkc37b`P%U!nLB;n`BPCrw1O)xX~X&Cges#9iP?%oW|9)++u=>H<0iN7U-c*Zjhn`dBmay@v_gqPV6^53a)iUU4LZJxfd> zaSD>dhHKJ{C_K?ci^qDK9<*30UKaq4-d03^g@zWytJgR-cvUkoG^ZhD>hIspKTe&0 zyLek?T3V*PzF7*!<@mo~rtV`y_;~9@oz17->@D}wxVD&jws`yV0hO1+79RrUe7j6y znV3x+%rgC_t3Kn$y^Q;N(0esM>rE2Q)qBm{C*az(F2`0-c(T#Ccf!&WI4SeDkNJPr zj%`|BsWLX+_gDHPdA*hS($#$g(<6Ld+g|9t+VlZED?2!$0Wbc{KSLRb&K_~Ug*rRd z66OQ%-cpbuZ&k8=&kGg`KfQ4nnxcNOKK}&G2Q@o5k!6(P^XOS;RIS`Zd<=vH57{%# z9E#4|q`}Sa75QsV*_f%>`@s;kZsoZauUER)>Gn2zo*!E`YtxeQxe;sHXju@kSQaLI zu|jYp|Nam8Fv@&?opp5muw&2rsRzgWzdfmTzVh8~5dmCUPXClFZtqwjmWCF$_dU_@ zl(YOIJNIU*rsZN1wT~ zKF8^a%+0>XOBdQTtL8+TcGjf*IGAUJe~dPG%z7C*xNCK2<4s6MHYq!{d52o& z4L44v5k91QP0ZxH%P94X6;p5Y|KVbVAB;Rr+{-gF|GA@tj?K5^h7#+=MY#X%Y0+L= zzBPl%foRzp%R;fG(6QZBR;kruv<=1HXv{X1N43qT7c61p4+z_SsGW(%hN-#GJ=>O4 zVd8YN@@j4VVbVEZ1j?x&BSzpb9el$xzTRZ2h+jHWHJ$3N5J|W72leY z@>WHpKEEu~^K6qt4w~>Hl~XwNbkg`2?Ky(C@X+k^Yv+!H3Hd^2oZ>nE&1k)D%f^

os2}jO>ITVI+JfD%D;LV7Og~4iSXT@=U!}Kq;ZSGIO_;8t)<4ov#dh4 z3~wkuHvP0Xh;cVLaI+tOXQ2x8*4g+U{9Ownyfe!jSzDWBnA6!Ldh%sJ$nN9V^lx@T zTeuahEHY2g4V!|x&mv^xxzJf_@5c=u>0}bU7WhiHy5ZpePcqh~gZYQ3_&KcV`P3uo`y6^G+ zAWn9QjF9&pf6~_HRsZ0+UKug&iP_cBIp0Tlibac_i_usYx|zY~4DW?8g8PxBO8J!e zK8?vRdrI=lMOnu>DO0P9&SZWmmt^iz@BSZ8HbS<&&*){1>)@B-;&amTd2ux+#~WMk z)V*KqC>$OUMHAD0OiycP^*va>u;^f8dxcTSwt+W408`r>VAEp`w<@gof5k`&qMJZh zL)P%wgl7r!<8IY{WJXWJ@D~%<(y58@6Z(PZTc>=_7jR522ur!BxLmzMHzVBnCX2eG z&-09@bWTRJc8%iv6=kj=+`+VmgI%ev#`{3k`iq4v#gdd7pBrj=IU5^Q-I|^3B2tph zmvQ%(xke5xu#5AYoVnVD*J8kg$}Sv=HJPofoPKi>=O^4h?4JIpS<}k7$>=JR>tL+q z!7kdtEhrhMh3|~=q%T_Hz3-DOjayUaY7{&jPx%!{Nulay4nDdwpb#JO#WO&=X0cDO z_{Sy2h&eK|S6r56+LX=lEaHRtK9Z&%4cqa4Y5@okDBJq}UAQvyqZASWE1oHX9MT18 z81cAjm#sfy)$z)4OiW`s`;Ui-)<22ELeeKIv?a_ULx37z$cuiFhx6lU!tn{GH2PhB zAgZaHW8rhG@?lK_W0Sn^IDt~9f<+yoT$Uy(2lELw=}ZLut*amM9ki@&KSj9;=k z*{mzJA#^v7qz~C)1m4TuAwF}gu7H$#$+*Vx@#Opx+mES<&pDb?adlS+d?TBVOC-?W z{zBWdfMUd8D3=0x){r$bgOKEHi6uzUCt=%yTAwWcB5~o)md356?tAc#(!?fq=dohE`RH?PYt5VsC+IieX1vc*`iAzk=MxGu=`Qd$vKVpXu|kOO#8)Mr#iZ~=Xfm2>2SB|N@LL`uHRFi^rdcS zO7h_J9KBbZoZU&%oTo*k;^|}{0Xtwl+7|cr9#J?`cEw?!3VH!CqJ8^aVTe%JkzmKq z&$mAsYl_g~UN1#o4|5zY-Zx1lqF!*E|C&-|A>%X}FW&gN1^pmTl{&(;(Uj*LZ$p`| zsprVTxmco%wOl4$A!8!PlClF8dBb-F(zbHp2T?Z zJgqn6en(^yF!gsRGVjw#81K`#e`ogW_@&D`I#PIAWt>_ca?N?UZIb>p`{WpY{t;7d zG>(T;tpBZmpPu6zV%QY@?xsoXAYS;MthbFDc{?p0u!T6bA!&*h#g z3;sC7v~oCDPy0H}G#GxI%0u^)^eE~ziW9e&CO=8~_F^wTm?+yfcdBvcqHlw`wRI$4 z4B9*(F8OoyC#3FvC(_h?o|6f@RaJwNkuF9?ut}38eOa1doR*s^ z_En4HyyRS;eRI4*H&$84Pk zLk^Vfi8vk0z|Sg<_{Ze&tA!VP8P;auEamkaKKU`N(SoiHvQxVBHhNk!Y?9nyH>6~10S>M;_$B>r3-w6 zXnIK8aao4+ER*e-5WFt-kV6dbmY@9&%V5eOXC3PEsHhmWA&1q>CQs)8{DH+tb=yM2 z?6=yY5|Tr*Gd6=h-Dl7<6tjDS-trU9KtV~4R_nLIeH3Cf`g{d&(Q#v3(aMaB$TI%Onw7b-h>0;q`gEMr$h#6Rq3^@M3a2Xg<{Sq@X`WmM*vqcfl zP$R$27OwGn9|JV(Es{f0#j5-T@WFl4(%NxBq!AbNo{-GT?%S|#J<%Zh+59G@*hU*h%&UFxSFcK;qN(N| zYp(Sf6Sp(UU6_YcvbBuEo2joN`}Is;gbnsfOPgQj#EuxZ9%r0g&|7KPEWRKuuh--6(P|**3{|K!%(KRRyCa34zH(n{)uN)=D0ufAy!C6~c`*x;hN zPc%2-H6P+eGWG$*Q-}Dxuvr!%F30vK&Fi0$mXfg|x+Vt1zSbh5^0fN&bQ|&w*o-C& zWqFuGAAs8+>CNZ2dTx&OeLTp@`UE*dFp#UVlm|=pA-D^1Xt7{4F@}xDN~K=tY?$Pc z)hzZtDocvqDJ3I1yrfiC)?rAFeO%}|XC#?0&K4QU_M4SQ8Y>PCRpT~GAgvLnv@71i zk3n=n&uV?HI2rM!VYGc6X7Zmq)uBSfu4@jMeAMHvDBC0B5P63pbF3bH9+zt)Z8{;g z*m&uk+6X2;eQ2*$xQkwvn)-U(`xarxoK6;JyAuq|z2KlG+lnG&96-40EB!HTP|#yQ<>16n>~0rs zWi%gXoc+HvPA8@HHO1_8<=n>3`B%7iyUT}7k3T#wHoy6mN-l2bQ>Fbg+u;2h6C(2($`BIqC2a0EP(6QF& z#wthR8}$L4I9?Vt&QqhUve*)qENa?OSk(W0Nr)h9MQN0*Z`D(fRGOacd*)0+NsN3& z6KZ`5qR_ik0}((NSot&6Y|R~tMxSjMXtrCtp6vqv-RgVo!Y;IWKQqwp=7dovnHew^ z-l`}V|H8obKm!k@VqkQ^eQqkUS~tUQ(b%ymMCHCq!T2zFA-qP{{yfEYu3VHe$yAx5 zSKr#PPWVTD-fPi~B?{1=N#&ZNBF%B>Q|i*i7>c#Q5HxGh^Or!;Szp0$7(;a^6MW_b+9b|EC!Eu*gdAM-u-|V{r#f6XXRA(geW>@X^b=O zUR)6=o#;Rgcr)`-)H5XaD5E3kwWAx{4lNrX5XXu=al>%6(cru^g*$&KWU)}>v= zqxR@si!-h+IvKMijRO|+_&Bl4JsHo^(Ui!6Nlx@`)QAc`4(~Z&KJXUpb962z&pNha zB3R)e-#K@Rfx|+TNBwK!>=gMWXOSR^EKJm;;QMqbI|a9@l&tgu6!n~5y17Esz!E0v zgmI=VXw|@yyXye9(L1j;18nRFY*6VSw`tZdITNw?mp$Hfh5^$&1JX~ib_@OAJjsOW zqmkGEci%F}ro?2$*`otT^;85GKke;H5+7A~FpBz~)uRzPLW%S2Mq!U*=Sr~8@|McO z>kY9BeFGa@iw-*!S$ye)d8^3+TgX+N*ZM8EgcGnA}VxEOw}*RvE&(hI?wQ3&t_-oK~X^K*5qV_yYD z6gAA8mqc5kG~LWwIYkiU@gK%{HpPi2Qi^`uhe1Pirudf@4vOVd_tt2#6=RX@BVUheQ6)%0daFdN(J2CUJo59T%Q^ zfq3u8A&d>8{Y9ao(oQ`I#-uh6gqgH-P-(?psPa%JxbfHkMOzgj7eqqX)MVyk_*_^DHdZ0P(*7CSQ2;v0!LW;3LkDV(VAgw_!6Ycat0B zrGnI8l-k`~giZ8;O=`kLZsdGGU^Yp{tyea&lzCg|3=O# z`B*#iY=dL_97#pSr6uOb|04YRBbxs;dMt=NVZ4S?Ct3Hph9GxAh0^8uG1NMyW2QGR z@n47T|6=cKogDnDL&S7kl~5KfzP(@7y5)=YL1P;u`H7%2jEI^(4t|MV;yB}q>7=I7 zrZH6S4pp8lAor$|v^Maoc0ZjSf9$7jDmP24tuZhXg z!q7PYa=KMP2=w&NnJGdN(o(#OA!BhKKS*$+^Q0QseiI}XTz6j(d9s8t%#J7*T2bb7 z3?d+!k$Vs{ctNo%d4Avm%P(OGan(h??lY@ezZC4+rescCwZM{nFb*2`t|3b%f$dMO zo1t5Qn<_{UW^M^4g8z3F%tMISK>_&fx-f)rF0L`RR}i$71MI(%-yUUPH4BDlj$P{^ zVqQv&V73uAcEuS4w*g#5>nCI2D*A$tGF>ZZ{}&9qhy;=&nDA9!f<@C-!=VVWI8p)U z+p-U0cw2KxT2JH4#etsL9IV`Vqk(gPOTPugh~AW#xD`0!?*Nc@UhSh}*b3eV=auXY z0PPh(>Z(jf&Z-Oa5->KmSSO+hJE}}8(VyucCYNvdsxQa&HQ+vsx!!uP8^a;Qwvnx z38QvuwE}VYQ^09(=(c*i0z1Dp)O^a$?x&_nhxzFW@yY=E93VU0u9CdQ5(3~4cE4bv zrU?ctg846~!-DYuYCOjK!Yb?{unb2e_}YJn^@muhe>m%>xc(8tWxf7?x6b<`^n=tjPwAD*SeRyW+Me zYDwGm96swWkvd|hM%y1Bv7zHT=>8XvqR+*FEO^6mwsR9M`)uVy&%x)(N$MdR*?p&9 zBAKtBX~7^oWQtIem5z+pIHNS-UfL?z@+OS;2aolCe#*=8DG(-6pR=VbEvj`NDt@KFva(JIE2OQ|hi^%4 zhO{IyrQx(P6g#PDn1wp+;XVv)s~an+F58Xp^n>v&_o;$rAz#^N?+lmXFdT-Apl1I| zg)J*kynyUxk;$PNA=UU)$m{LPI}I3_$w5x>ZB9e*YRxeG&qGbosi^$%#+5_pk;FfMk-?^Dyb!M3~kk$UM0x3Y3G7d}~UHF{yHO7#&JE4TOT6sdM~ zU<3?|coQL@YI}i3oe4uK=!>&c;q)NC+OM>&Av)-D8{?+RYau)A5wbT6gg5{Su8e z?pZa9B;KtAdne)tWhoNZsMSROtOE)6!wbC>*<7O?*ck`gcym@=9htCwD7i2KPw0 zEb8Krg!VE}s+(Y=c?-Ya{#maGE{Cyh4Vm@DmDk|3PGX)BVHKj^N*vps1TI6wu?D=l zzqj}9RhlG#E(!Uvxo@Xx=e3`RnmO!{9`+<1I8{(PbItXY^3h*-@~d`6LGv&_lr7iD|BMKs`pb7wc3HY1^<)WhsvA0Uu<|jpWi5 zassDe5UjpAJ{prseOjA8FTT!lb?x{opv`DrZh=M(*u~|M-6^M%{URCRs)wGA@R7qS zLo<<1k+PBW$D7Txf)awulVdNP{9&u_vA$YC&p|{{lr8Rv*H&)v?~(Lk(8=%5riSze23EaIyLuoyzSZo(h^6S&xWfOf9YHfbx^t6 zP@c>*r|7P4;f`bw8{SDJNqeq@r2z|sh!W?re6Xs;Hvn+botO7f(@cWwOww{BaCjhw z%5gn>BEB|;($3GZ{d!Pmv8joPQgr~f8gsh$R@i%g&AIp`76yzun(Nz-RT`#&kY;T8 zcmQflQ0Bt%WisSMJ*Jk-)B;F(%jXLWR{&*Tf!dGa@RA%4HBAL$%pR$w+7RUjV)&UZ za!v+H6r)DHX+1y`2xayC`>G_jy?lwtF>M4M2~hmP+ow?lMlxm_04;Ig?3G3nYlH zE|JDk+~p^RrxX1~3%tKl?h?k!x7Q0PkKgp1AIVEL;O~6%YmKC;lH%zO1t|0tM_PKf zdv$0QMMfhAf7#R`kOaLZ>26Y<>Ab1loo-(wbV0!{WM!2B``CHt&n2Nqegj~iE7Sr% zdxu??0K1ONW2-9Zw>figNdcot)EKW--;@}_7tlO^WBSDJkEfO#YqlF0ui(S-a-#=7 z)+B}5EIBSykLC3GBN<2Yh;EvN6V(clywhzSdUMs@`0f?hO_XS#PT%=3eg88dps)Cy z-*d#HSfibpGOZz6vCNw=Z)Kx8&u9DFPk$Tt3tU^t<#K15uh86^_sV_r_OSD|Yh?JR z4;-$*X!M*J&zGJI{=>?@o;V;WG3Ta1zj4P{mHUCsk{8=phKU49v-eiN#i*sZtoJhE z85rn-UUC<4?`{|EwedkUdH>UrB|o_GN8rdK2$HzOgPT!7-REq{9w<%9B7Fu|rH$kh zpW}ELCQR6T<>s>tZIZn<0srzTZ=|?xkBxc1Wm&KVuvIc|$Z;a8gFdEAzh7mypMWo; zs+z(T#d2iVdiBvA3fmM7D8c1f_I5vV3>=1;uj<=ui|G&k+;^HFF-TbYJDq~$Bqg|R z_xr`*hbF^Db82Taw~PMRp@YDP=%jzb5Ao;{&e}h#*gV?*!dCA2xBLy9>jiDJM%d?rjs9sVvI5Mzp*+>9 zSu9LcNN~GcAJ^;o?^n{&3%c{Fd?VRu8L9F$qz+*?&7@BgO8%LC-)c(ENIbDAB}MW! z4&AHGkDFxe^ZoZLy=T3;-ToF&Th1_{R&Hu|nc%2Xtb@!~ABq<_RRnx%L@&zzE*=uJ zrH_I>*dDgIUe8(VKx9sEo9E45@ROKr*|ThCs*s)eN13@64O5<-RegGCIMC(BA}4o6 f+=mZM%X| literal 0 HcmV?d00001 From d87cb46290be6c0d4861352d247512ec8f63ea5e Mon Sep 17 00:00:00 2001 From: Daniel Plaisted Date: Fri, 1 Mar 2024 18:10:13 -0500 Subject: [PATCH 408/577] Fix pack error for MSI installation tests --- src/Tests/Directory.Build.targets | 2 +- .../dotnet-MsiInstallation.Tests.csproj | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Tests/Directory.Build.targets b/src/Tests/Directory.Build.targets index 48565a5e5c1d..c8188b9231a5 100644 --- a/src/Tests/Directory.Build.targets +++ b/src/Tests/Directory.Build.targets @@ -5,7 +5,7 @@ $(MSBuildAllProjects);$(MSBuildThisFileFullPath) - + true true $(PackageId) diff --git a/src/Tests/dotnet-MsiInstallation.Tests/dotnet-MsiInstallation.Tests.csproj b/src/Tests/dotnet-MsiInstallation.Tests/dotnet-MsiInstallation.Tests.csproj index 78a9e1fb3cd3..1fd1667d2d2a 100644 --- a/src/Tests/dotnet-MsiInstallation.Tests/dotnet-MsiInstallation.Tests.csproj +++ b/src/Tests/dotnet-MsiInstallation.Tests/dotnet-MsiInstallation.Tests.csproj @@ -13,7 +13,7 @@ - testMsiInstallation + false Microsoft.DotNet.MsiInstallerTests From 3d5259af95aeef7e64c349abfc39e3dbe289673b Mon Sep 17 00:00:00 2001 From: Daniel Plaisted Date: Sun, 3 Mar 2024 19:15:59 -0500 Subject: [PATCH 409/577] Don't run MSI installation tests in Helix / CI --- src/Tests/UnitTests.proj | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/Tests/UnitTests.proj b/src/Tests/UnitTests.proj index 1fe198defc1e..c370c687902d 100644 --- a/src/Tests/UnitTests.proj +++ b/src/Tests/UnitTests.proj @@ -1,4 +1,4 @@ - + test/product/ @@ -45,6 +45,9 @@ net472 net472 + + + From 922beea4bb557aea0ade02ede8c7bb6c14737abe Mon Sep 17 00:00:00 2001 From: Daniel Plaisted Date: Fri, 8 Mar 2024 07:04:08 -0500 Subject: [PATCH 410/577] Apply suggestions from code review Co-authored-by: Noah Gilson --- .../MsiInstallerTests.cs | 15 +------- .../dotnet-MsiInstallation.Tests/README.md | 35 +++++++++++++++---- 2 files changed, 30 insertions(+), 20 deletions(-) diff --git a/src/Tests/dotnet-MsiInstallation.Tests/MsiInstallerTests.cs b/src/Tests/dotnet-MsiInstallation.Tests/MsiInstallerTests.cs index f6049b63a379..90c71dffe39c 100644 --- a/src/Tests/dotnet-MsiInstallation.Tests/MsiInstallerTests.cs +++ b/src/Tests/dotnet-MsiInstallation.Tests/MsiInstallerTests.cs @@ -1,21 +1,8 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System.Runtime.CompilerServices; -using Microsoft.DotNet.Cli.NuGetPackageDownloader; -using Microsoft.DotNet.ToolPackage; -using Microsoft.DotNet.Workloads.Workload.Install; -using Microsoft.NET.Sdk.WorkloadManifestReader; -using NuGet.Versioning; -using static Microsoft.NET.Sdk.WorkloadManifestReader.WorkloadResolver; -using Microsoft.Extensions.EnvironmentAbstractions; -using System.Text.Json; -using Microsoft.TemplateEngine.Edge.Constraints; using Microsoft.DotNet.Cli.Utils; -//using System.Management; -using Microsoft.Management.Infrastructure; -using System.Xml.Linq; -using Microsoft.Build.Evaluation; +using Microsoft.NET.Sdk.WorkloadManifestReader; namespace Microsoft.DotNet.MsiInstallerTests { diff --git a/src/Tests/dotnet-MsiInstallation.Tests/README.md b/src/Tests/dotnet-MsiInstallation.Tests/README.md index 0c21ac265461..65a8ecb24951 100644 --- a/src/Tests/dotnet-MsiInstallation.Tests/README.md +++ b/src/Tests/dotnet-MsiInstallation.Tests/README.md @@ -43,14 +43,24 @@ Create a new Virtual Switch connected to your external network adapter, and chec - Start the VM and install Windows - Probably you don't want to sign on to the test VM with a Microsoft account. Setting up with a local account is tricky, but you can do so with these steps: https://web.archive.org/web/20240120203712/https://www.tomshardware.com/how-to/install-windows-11-without-microsoft-account - In the VM settings in Hyper-V manager, enable all the integration services (so you can copy/paste files to the VM, for example) -- In network settings inside the VM, switch the network connection type to Private Network, and turn on Network discovery and File and printer sharing. -- Inside the VM, set the HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System\LocalAccountTokenFilterPolicy registry value to 1 ([reference](https://learn.microsoft.com/en-us/troubleshoot/windows-server/windows-security/user-account-control-and-remote-restriction)). This will allow you to access the admin share (`\\TestVM\c$`). +- In network settings inside the VM OS Windows Network Settings, switch the network connection type to Private Network, and turn on Network discovery and File and printer sharing. + +The first setting can be found in the 'Ethernet' or 'Wireless Connection' tab at the top. +![image](https://github.com/dotnet/sdk/assets/23152278/7ddd317d-eca3-47e9-a07b-88bcab8d96a2) + +Network Discovery and File Sharing is found under the 'advanced' tab, then under Advanced Sharing Settings. +![image](https://github.com/dotnet/sdk/assets/23152278/08d9fbfc-a603-4da4-b98f-129a2ee90c7b) + +![image](https://github.com/dotnet/sdk/assets/23152278/ccb891bf-d30d-4555-b0fb-88216c63c21e) + + +- Inside the VM, set the HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System\LocalAccountTokenFilterPolicy registry value to 1 ([reference](https://learn.microsoft.com/en-us/troubleshoot/windows-server/windows-security/user-account-control-and-remote-restriction)). This will allow you to access the admin share (`\\TestVM\c$`). Note that the PC Name could be different from the VM name, and you should use that instead if it's different, such as if the PC is named `WINDEV2401EVAL`. You may also run this under an admin prompt: `REG ADD HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System /v LocalAccountTokenFilterPolicy /t REG_DWORD /d 1` -- Browse to the admin share in File Explorer to confirm it's working. You will need to enter the username and password for the VM. Select the option to save the login information. This will allow the tests to access the VM. +- After all of this, you _must_ restart your host machine and the VM. Failure to do so will result in 'Access Denied.' Browse to the admin share in File Explorer to confirm it's working. You will need to enter the username and password for the VM. The username will likely be the PC name\the user name, such as `WINDEV2401EVAL\User`, and you need to manually create a password in the VM. Select the option to save the login information. This will allow the tests to access the VM. - Inside the VM, go to "Allow an app through Windows Firewall", and add "Remote Service Management" to the list of allowed apps and features. This allows PsExec to launch commands quickly, otherwise there is a delay of around 15-30 seconds for each command that is run. -- Download PSTools, extract them somewhere, and add that folder to your PATH. Run something like `psexec \\TestVM cmd /c dir c:\` to verify that PsExec can run commands on the VM. The command should complete in less than a second, if it takes longer then the Remote Service Management firewall rule is probably not enabled correctly. +- Download PSTools (https://learn.microsoft.com/en-us/sysinternals/downloads/pstools), extract them somewhere, and add that folder to your PATH. Run something like `psexec \\TestVM cmd /c dir c:\` to verify that PsExec can run commands on the VM. The command should complete in less than a second, if it takes longer then the Remote Service Management firewall rule is probably not enabled correctly. - Create a `C:\SdkTesting` folder inside the VM. Copy the standalone installer for the baseline version of the SDK used to test (for example `dotnet-sdk-8.0.100-win-x64.exe`) to that folder - Recommended: - Install [Visual Studio Remote Tools](https://learn.microsoft.com/visualstudio/debugger/remote-debugging?view=vs-2022#download-and-install-the-remote-tools) in the VM so that if you need to debug the SDK you can do so. Run the remote tools and allow it through the firewall @@ -59,15 +69,28 @@ You may also run this under an admin prompt: ## Test settings -The tests can read settings from a `VMTestSettings.json` file, and they store the VM State tree in a `VMState.json` file. Both of these go in the current directory, which when running tests in Visual Studio will be `bin\Tests\dotnet-MsiInstallation.Tests\Debug`. The `VMTestSettings.json` file can have the following values: +Run the tests under Visual Studio -- to do so, you must launch Visual Studio with admin privileges. + +The tests can read settings from a `VMTestSettings.json` file which you need to manually create. The tests store the VM State tree in a `VMState.json` file. Both of these go in the current directory, which when running tests in Visual Studio will be `artifacts\bin\Tests\dotnet-MsiInstallation.Tests\Debug`. The `VMTestSettings.json` file can have the following values: - **VMName** - The name of the VM to use for testing. This is the name displayed in Hyper-V manager. This value doesn't need to be set if there is only one Virtual Machine on the host. - **VMMachineName** - The machine name used by the VM's operating system. This is what is used to browse to the machine in File Explorer, for example `\\TestVM`. If this isn't specified, the tests will use the VM Name with any spaces removed for the VM machine name. - **SdkInstallerVersion** - The version of the SDK to install for testing. The installer for this version needs to be copied to `C:\SdkTesting` inside the VM. - **ShouldTestStage2** - If set to true (which is the default), then the tests will copy the SDK implementation binaries to the installed SDK folder inside the VM. Basically, you should leave this set to true if you want to test local changes to the SDK, and you should set it to false if you want to test the SDK specified in `SdkInstallerVersion`. - +Example: + +```json +{ + "VMName": "TestVM", + "VMMachineName": "WINDEV2401EVAL", + "SdkInstallerVersion": "8.0.300-preview.24155.26" +} If you want to change the snapshot used for the initial test state, in addition to renaming the snapshots so that the new one has "Test Start" in its name, you will need to delete the `VMState.json` file, as otherwise the root test state will be read from it. ## Notes +If you see this error: + +`Microsoft.Management.Infrastructure.CimException : The client cannot connect to the destination specified in the request. Verify that the service on the destination is running and is accepting requests. Consult the logs and documentation for the WS-Management service running on the destination, most commonly IIS or WinRM. If the destination is the WinRM service, run the following command on the destination to analyze and configure the WinRM service: "winrm quickconfig".` +then you need to restart your machine and try to access the c$ aforementioned folder again. When you log in, make sure you log in with the user and select the button to 'Remember your credentials.' Hyper-V supports a maximum of 50 snapshots per VM. If you make changes to the SDK and re-run tests, new snapshots will be created for the newly deployed stage 2 SDK. You may need to delete the older snapshots in order avoid hitting the snapshot limit. Also, if you want to force a test to run a command instead of using the cached result, you can delete the corresponding snapshot. \ No newline at end of file From 6d7bdbbce78b554c4a9e988cb10d1d98438d45c9 Mon Sep 17 00:00:00 2001 From: Daniel Plaisted Date: Fri, 8 Mar 2024 08:55:28 -0500 Subject: [PATCH 411/577] Add images to repo --- .../dotnet-MsiInstallation.Tests/README.md | 6 +++--- .../images/advanced-network-settings.png | Bin 0 -> 56217 bytes .../images/file-and-printer-sharing.png | Bin 0 -> 58699 bytes .../images/private-network.png | Bin 0 -> 75481 bytes 4 files changed, 3 insertions(+), 3 deletions(-) create mode 100644 src/Tests/dotnet-MsiInstallation.Tests/images/advanced-network-settings.png create mode 100644 src/Tests/dotnet-MsiInstallation.Tests/images/file-and-printer-sharing.png create mode 100644 src/Tests/dotnet-MsiInstallation.Tests/images/private-network.png diff --git a/src/Tests/dotnet-MsiInstallation.Tests/README.md b/src/Tests/dotnet-MsiInstallation.Tests/README.md index 65a8ecb24951..de25f3da0d1a 100644 --- a/src/Tests/dotnet-MsiInstallation.Tests/README.md +++ b/src/Tests/dotnet-MsiInstallation.Tests/README.md @@ -46,12 +46,12 @@ Create a new Virtual Switch connected to your external network adapter, and chec - In network settings inside the VM OS Windows Network Settings, switch the network connection type to Private Network, and turn on Network discovery and File and printer sharing. The first setting can be found in the 'Ethernet' or 'Wireless Connection' tab at the top. -![image](https://github.com/dotnet/sdk/assets/23152278/7ddd317d-eca3-47e9-a07b-88bcab8d96a2) +![image](images/private-network.png) Network Discovery and File Sharing is found under the 'advanced' tab, then under Advanced Sharing Settings. -![image](https://github.com/dotnet/sdk/assets/23152278/08d9fbfc-a603-4da4-b98f-129a2ee90c7b) +![image](images/advanced-network-settings.png) -![image](https://github.com/dotnet/sdk/assets/23152278/ccb891bf-d30d-4555-b0fb-88216c63c21e) +![image](images/file-and-printer-sharing.png) - Inside the VM, set the HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System\LocalAccountTokenFilterPolicy registry value to 1 ([reference](https://learn.microsoft.com/en-us/troubleshoot/windows-server/windows-security/user-account-control-and-remote-restriction)). This will allow you to access the admin share (`\\TestVM\c$`). Note that the PC Name could be different from the VM name, and you should use that instead if it's different, such as if the PC is named `WINDEV2401EVAL`. diff --git a/src/Tests/dotnet-MsiInstallation.Tests/images/advanced-network-settings.png b/src/Tests/dotnet-MsiInstallation.Tests/images/advanced-network-settings.png new file mode 100644 index 0000000000000000000000000000000000000000..b8e5cce7726cf28f1fbcbda2fd7f58b3c201aa42 GIT binary patch literal 56217 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

%PyC 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�d!O|(c1<@ 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

vGAPZ7F@w>Vb@XuU#b0@oKpr!V#_E`v=m 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 literal 0 HcmV?d00001 From b314451c42bd6c7c598fecf478a53fabb2dcb286 Mon Sep 17 00:00:00 2001 From: Daniel Plaisted Date: Fri, 8 Mar 2024 17:33:01 -0500 Subject: [PATCH 412/577] Improving virtual machine setup instructions --- .../dotnet-MsiInstallation.Tests/README.md | 78 +++++++++++------- .../images/network-switch-creation.png | Bin 180170 -> 143579 bytes .../images/virtual-switch-manager.png | Bin 151492 -> 97752 bytes 3 files changed, 50 insertions(+), 28 deletions(-) diff --git a/src/Tests/dotnet-MsiInstallation.Tests/README.md b/src/Tests/dotnet-MsiInstallation.Tests/README.md index de25f3da0d1a..8ccc5086d9e4 100644 --- a/src/Tests/dotnet-MsiInstallation.Tests/README.md +++ b/src/Tests/dotnet-MsiInstallation.Tests/README.md @@ -15,57 +15,81 @@ The main requirements for running the tests are: - A Hyper-V Virtual Machine - Access to the VM via the admin share (`\\TestVM\c$`) - [PsExec](https://learn.microsoft.com/en-us/sysinternals/downloads/psexec) on the PATH of the host machine +- Windows Remote Management service running on host machine - "Remote Service Management" enabled in firewall settings inside the VM (this avoids a delay of 15-30 seconds for each command that is run) - Tests need to be run with admin priviledges, which are required to use the WMI APIs to control VMs -Detailed steps: +### Enable Hyper-V -- [Enable Hyper-V](https://learn.microsoft.com/en-us/virtualization/hyper-v-on-windows/quick-start/enable-hyper-v) -- For the tests to remotely control the VM, your host computer needs to be able to access the VM over the network. To enable this, you need to create a virtual switch for the VM which will also be shared by the host PC. In Hyper-V Manager, click on your desktop and then go to Virtual Switch Manager. +Follow these instructions to enable Hyper-V on your host machine: [Enable Hyper-V](https://learn.microsoft.com/en-us/virtualization/hyper-v-on-windows/quick-start/enable-hyper-v) -![Image of Hyper-V Manager showing switch manager dialog](images/virtual-switch-manager.png) +### Set up a Virtual Switch + +For the tests to remotely control the VM, your host computer needs to be able to access the VM over the network. To enable this, you need to create a virtual switch for the VM which will also be shared by the host PC. In Hyper-V Manager, click on your host machine and then go to Virtual Switch Manager. +![Image of Hyper-V Manager showing switch manager dialog](images/virtual-switch-manager.png) Create a new Virtual Switch connected to your external network adapter, and check the box that says "Allow management operating system to share this network adapter." ![Image showing creation of a network switch](images/network-switch-creation.png) -- Create a Hyper-V Virtual machine. The simplest way is to use 'Quick Create' and modify the settings after creation -- it will find an appropriate ISO for you. If you need a more specific build, you can follow the steps at https://learn.microsoft.com/virtualization/hyper-v-on-windows/quick-start/create-virtual-machine. Either way, apply the following modifications: - - You will need to choose a name for the virtual machine (used by the host) and a machine name for it when setting up Windows inside the VM. You can choose whatever names you want, but "Test VM" and "TestVM" are good defaults. - - If needed, you can download a Windows 11 .iso here: https://www.microsoft.com/en-us/software-download/windows11/ - - In the networking configuration for the VM, select the Virtual Switch you created. - - Make sure that you create a generation 2 VM so UEFI is supported (this occurs by default in Quick Create if it is supported on your machine, which needs TPM 2.0.) - - +### Note: Virtual Machine names + +There are two different names for a virtual machine. There is the name that the host computer uses to identify the virtual machine. This is what you see in Hyper-V Manager. We call this name the "VM Name". There is also the PC name that the Operating System inside the virtual machine uses to identify itself. You can see or modify this in the system settings inside the virtual machine, and this is what you use to access the machine over the network. We call this name the "VM Machine Name". + +For example, if you use Hyper-V's "Quick Create" to create a Virtual Machine, the VM Name may be "Windows 11 dev environment", while the VM Machine Name may be "WINDEV2401EVAL". In this case you would access the admin share using `\\WINDEV2401EVAL\C$`. + +### Create a Hyper-V Virtual machine using Quick Create + +The simplest way to create a virtual machine is to use "Quick Create". This will create a virtual machine that is ready to use without having to do much configuration. The virtual machine will have Visual Studio and the .NET SDK installed. Currently this doesn't impact the tests, but in the future it may be necessary to uninstall Visual Studio from the virtual machine. + +- In Hyper-V manager, select your host machine, select "Quick Create...", and choose "Windows 11 dev environment" +- In the same creation dialog, click "More Options" and select the virtual switch you created for Network +- Once the virtual machine is created, it will have a user account without a password. You will need to add a password in order to connect to the machine over the network. Go to sign-in options in the system settings and set up a password. + +### Create a Hyper-V Virtual machine using a clean install + +You can also create a virtual machine by installing Windows on it from scratch. General instructions are [here](https://learn.microsoft.com/virtualization/hyper-v-on-windows/quick-start/create-virtual-machine). To create the virtual machine: + +- Download a Windows 11 .iso here: https://www.microsoft.com/en-us/software-download/windows11/ +- You will need to choose a VM name when you create the VM and a VM machine name when setting up Windows inside the VM. You can choose whatever names you want, but "Test VM" and "TestVM" are good defaults. +- In the networking configuration for the VM, select the Virtual Switch you created. +- Make sure that you create a generation 2 VM so UEFI is supported + ![The generation 2 box should be selected](images/virtual-machine-generation-2.png) - - Right click the VM and go to settings. Under Security, check "Enable Trusted Platform Module" (and possibly the "Encrypt state..." checkbox under it), which is required to install Windows 11 - - Start the VM and install Windows - - Probably you don't want to sign on to the test VM with a Microsoft account. Setting up with a local account is tricky, but you can do so with these steps: https://web.archive.org/web/20240120203712/https://www.tomshardware.com/how-to/install-windows-11-without-microsoft-account - - In the VM settings in Hyper-V manager, enable all the integration services (so you can copy/paste files to the VM, for example) +- Right click the VM and go to settings. Under Security, check "Enable Trusted Platform Module" (and possibly the "Encrypt state..." checkbox under it), which is required to install Windows 11 +- Start the VM and install Windows +- Probably you don't want to sign on to the test VM with a Microsoft account. Setting up with a local account is tricky, but you can do so with these steps: https://web.archive.org/web/20240120203712/https://www.tomshardware.com/how-to/install-windows-11-without-microsoft-account +- In the VM settings in Hyper-V manager, enable all the integration services (so you can copy/paste files to the VM, for example) + +### Further setup + +These steps need to be taken regardless of the method used to create the virtual machine: + - In network settings inside the VM OS Windows Network Settings, switch the network connection type to Private Network, and turn on Network discovery and File and printer sharing. The first setting can be found in the 'Ethernet' or 'Wireless Connection' tab at the top. + ![image](images/private-network.png) Network Discovery and File Sharing is found under the 'advanced' tab, then under Advanced Sharing Settings. + ![image](images/advanced-network-settings.png) ![image](images/file-and-printer-sharing.png) - -- Inside the VM, set the HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System\LocalAccountTokenFilterPolicy registry value to 1 ([reference](https://learn.microsoft.com/en-us/troubleshoot/windows-server/windows-security/user-account-control-and-remote-restriction)). This will allow you to access the admin share (`\\TestVM\c$`). Note that the PC Name could be different from the VM name, and you should use that instead if it's different, such as if the PC is named `WINDEV2401EVAL`. - -You may also run this under an admin prompt: -`REG ADD HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System /v LocalAccountTokenFilterPolicy /t REG_DWORD /d 1` -- After all of this, you _must_ restart your host machine and the VM. Failure to do so will result in 'Access Denied.' Browse to the admin share in File Explorer to confirm it's working. You will need to enter the username and password for the VM. The username will likely be the PC name\the user name, such as `WINDEV2401EVAL\User`, and you need to manually create a password in the VM. Select the option to save the login information. This will allow the tests to access the VM. +- Inside the VM, set the HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System\LocalAccountTokenFilterPolicy registry value to 1 ([reference](https://learn.microsoft.com/en-us/troubleshoot/windows-server/windows-security/user-account-control-and-remote-restriction)). This will allow you to access the admin share (for example, `\\TestVM\c$` or `\\WINDEV2401EVAL\c$`). + - The easiest way to add this registry value is to run the following from an admin command prompt: `REG ADD HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System /v LocalAccountTokenFilterPolicy /t REG_DWORD /d 1` +- After all of this, you _must_ restart your host machine and the VM. Failure to do so will result in 'Access Denied.' Browse to the admin share (for example `\\WINDEV2401EVAL\c$` in File Explorer to confirm it's working. You will need to enter the username and password for the VM. The username will be of the form `\`, such as `WINDEV2401EVAL\User`. Select the option to save the login information. This will allow the tests to access the VM. - Inside the VM, go to "Allow an app through Windows Firewall", and add "Remote Service Management" to the list of allowed apps and features. This allows PsExec to launch commands quickly, otherwise there is a delay of around 15-30 seconds for each command that is run. -- Download PSTools (https://learn.microsoft.com/en-us/sysinternals/downloads/pstools), extract them somewhere, and add that folder to your PATH. Run something like `psexec \\TestVM cmd /c dir c:\` to verify that PsExec can run commands on the VM. The command should complete in less than a second, if it takes longer then the Remote Service Management firewall rule is probably not enabled correctly. +- Download PSTools (https://learn.microsoft.com/en-us/sysinternals/downloads/pstools), extract them somewhere, and add that folder to your PATH. Run `psexec \\WINDEV2401EVAL cmd /c dir c:\` (replacing `WINDEV2401EVAL` with the VM machine name) to verify that PsExec can run commands on the VM. The command should complete in less than a second. If it takes longer then the Remote Service Management firewall rule is probably not enabled correctly. - Create a `C:\SdkTesting` folder inside the VM. Copy the standalone installer for the baseline version of the SDK used to test (for example `dotnet-sdk-8.0.100-win-x64.exe`) to that folder +- Make sure that the "Windows Remote Management" service is running on the host machine. The easiest way to do this is to run `winrm quickconfig` from a command prompt. This is needed for the tests to call the WMI APIs to control the virtual machine. - Recommended: - Install [Visual Studio Remote Tools](https://learn.microsoft.com/visualstudio/debugger/remote-debugging?view=vs-2022#download-and-install-the-remote-tools) in the VM so that if you need to debug the SDK you can do so. Run the remote tools and allow it through the firewall - Install any other tools or set up any other settings you would like on the VM to help investigate failures. It's easier if you do this all as part of the initial state, otherwise each time you run a test the state will be reset so you may end up repeating the same actions multiple times. -- Create a snapshot (checkpoint) of the VM in Hyper-V manager. Rename the snapshot so that the name contains "Test start". There needs to be exactly one snapshot with "Test start" in its name, which the tests will use as the initial root state. +- Create a snapshot (checkpoint) of the virtual machine in Hyper-V manager. Rename the snapshot so that the name contains "Test start". There needs to be exactly one snapshot with "Test start" in its name, which the tests will use as the initial root state. ## Test settings @@ -85,12 +109,10 @@ Example: "VMMachineName": "WINDEV2401EVAL", "SdkInstallerVersion": "8.0.300-preview.24155.26" } +``` + If you want to change the snapshot used for the initial test state, in addition to renaming the snapshots so that the new one has "Test Start" in its name, you will need to delete the `VMState.json` file, as otherwise the root test state will be read from it. ## Notes -If you see this error: - -`Microsoft.Management.Infrastructure.CimException : The client cannot connect to the destination specified in the request. Verify that the service on the destination is running and is accepting requests. Consult the logs and documentation for the WS-Management service running on the destination, most commonly IIS or WinRM. If the destination is the WinRM service, run the following command on the destination to analyze and configure the WinRM service: "winrm quickconfig".` -then you need to restart your machine and try to access the c$ aforementioned folder again. When you log in, make sure you log in with the user and select the button to 'Remember your credentials.' -Hyper-V supports a maximum of 50 snapshots per VM. If you make changes to the SDK and re-run tests, new snapshots will be created for the newly deployed stage 2 SDK. You may need to delete the older snapshots in order avoid hitting the snapshot limit. Also, if you want to force a test to run a command instead of using the cached result, you can delete the corresponding snapshot. \ No newline at end of file +Hyper-V supports a maximum of 50 snapshots per VM. If you make changes to the SDK and re-run tests, new snapshots will be created for the newly deployed stage 2 SDK. You may need to delete the older snapshots in order avoid hitting the snapshot limit. Also, if you want to force a test to run a command instead of using the cached result, you can delete the corresponding snapshot. diff --git a/src/Tests/dotnet-MsiInstallation.Tests/images/network-switch-creation.png b/src/Tests/dotnet-MsiInstallation.Tests/images/network-switch-creation.png index f460db7d38d269d0f281f5a2089e1563e9694e14..be35d588eef43769b555c2b6b071ddb4a371d0f1 100644 GIT binary patch literal 143579 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�sevgnpHT$QO8l1z)%FBf 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 literal 180170 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

#eKD%p z<N@50Brf^8JJ zYvpwksR<&W(w3)hxuH;PDd7`ujb;ilj6NR1rX{8}*$khVvQkROfO(_!5-HZitb%%O zBF{TN9_~$(gq0Y5P}HSf(NItb!vi2-Htp?E`o5lZ^^H|&8xC;WOY9EzIX9j+p*>Wh8hNw#x>M{0sq&>`p{7(KxVtB}qH=zM!2P9?J5G?dYP3 z&Fzu9JZ4Hx)J1X@t>`2-nv6nolSbD-!eSfc#KxmjS`v?w?}C>TR9(Mxz23iYuoxEY z;2i@!VMmCaS$7Z2&xfQ379rR!f5e?9rC@y^_-J;H)qM?}HGw9wZ(I-gIT=I7Az|eT z5?b&cu2XwA7-FgAdsR<18@}J0qOc&)fz+4f;Rz1W`yRo&?U)qV6iZZJJ8)C?(K2IY zEO#SBxoMNI14=3vP;fn$q-?moZO{5#7{XN5^Ii0F{;P1)K#M#~jrG#PeeD`RkZ$Q7 z_x1eR+1)2Vz($#-Fnj=|(^{Mv@sj)M_e7c--S6Qi)1s1%{);WOR__O=5-}MJ4EunL zk2Zl&6PBRaneIPl!))2BcU{P8oe)l&0f`0$11QKi7vB?16)xxpacCmh<|}af^dm2p zH;kX1-Pom0VZ~#$M#-K;->7U?UX>-WBd>bbYy0tlLuU3%Dl`SGBRGxRo#&UAl4^-8 zHWmV`aC|8#U*nggO*p$^1|Xvp6sw({(2lPa#XeUd#o8FaVPIg;Rp@mQXA)-DSVqOo zDt~k&F3?Zy_Vu}PEOk={9dl}7EjvL(fV6{m2OKsts!w`vzbQo{37mwX5>-7GCF&HR z_(rWMf#CLzHrg

qO^xAm2dPh=)n%KLblq~+)pgkUBCki){KKv-TIm1Nea zK9G-}=|4oEcn*VDwDD|~j(IVEacZjHmfYyjS~v>p%(k)t%%VSIH5aS@@nkqRv{+ zpBEK1ZRg|bb`i6RID8P>l=6WE!B8_$SKSSnUV&YX^28jKie+-h4A zN4H6A%_;wEuIaHAvb0n8ocCg)l%Ml$ULtn-y?`6Ak4?<7ZBmD8# zsO}xjX*q|lck_gHJ$_CREp5*W^^H+bq}FuQ*g~V&&)CCU@V78vrPN?6@_-u;G9lpd zAe1k8hN)TiY1bANQ3K_f{SZ*{L(_}mfqQad5JTU_6u97mK)YoVbV-JGsqZ-sBXSu& zx~kfECnTbW5rvr%`YZ5*t$3V zOzMw2V~1&Ce9Z=-nunL0INzdJyobQ!36(#Q#^Gj5rDAYPtkfSkZ%1zy>NBN%OB^Ds z{0e6?9N_CRfz=+oby8{UsI3-^e-eRxZ-mEY`%LnDhP>F-LOPJ}tt~Kf($MKKTM%h2 zYQT~vgKnAp;c+zFVSvAq2}ZA7Oj8;)W1z)o{N(A>IaPoOY0PlEcneEJ<9AfA;LDwY z=dCcSrw+j2_wMFzPv$RkVXubuMdZ9g7l;|y<)5A`_EImahl^u+PrFP$r;7@{lPQQO zv3}yy?I6n8x^b`Z9kkX2ZSpGQ`L;U13NimMr-SAf5NP9ffDOd1WPq6OWTUWW0uNn+ z9OzyFaJN3;5;MCXoIa#MGPV5n-*)H0W;TYInZ@c};CYvmlLXV@3~|8U(Fy%tKxCfK zD?5i&J~NC4rR!!5qb!|OCQX;wid^l4RlF+87cu8fLQGx_OxBqyM>%QTjy3T{u#*J= zCD`xlh?G^z9jm~D4ao|N>i|~7#^*+Kes65>2t|84Dt^?h`QiMv(-@kOn65L(+|%8{ z_ou%(R~PC_i$;RhO3rQzlHj6s?Gv&^O`4@lt*{yJtoj2da~Ic3#x-EJmq}1C!($At zX0#w!lY|zC=6e=Um8-6f$RN~8Ye{#9iQvOj3ck{Rn#2iFBk=C!akNFpl+J(utyRKZ z0uv5SkC^000D)t?``09`A`Uwo>*e*v7b#M>;c251vw(TMrbp^2#y`oVdEy?M3Bqn3 zDiXq8{e&6|E!(H9ajN~6^A#o&X$=VV*=}V`Hw^dP`+;}5TCwD*%Pf@6WCRAn-mdy4 zp|FBONNX6}!NpX18-9?YKApYJlu~XqjE!;DzETZMW%NW0REb-Kwo68tMo^ZYm?%}{ zMW|cb+Uy-P1s{t@uOOr{h|~}dg4W3DiEA2bo|6pJurFk=5I%ju5gGdtdsZ9@dY%$Y zi1Z%YKLgEqGifOKdp@gDnYyRyq#`qFz#Pwu#Ea;`}1HAuphm!oQ~LFIWzLNe|nL9Mm!0P(XNxI%-+t< zW+o_|Pu*C$JN`B6NE}>hAtWjajvGIa;}Y`+yTS{`Kr@JXqYYdP<#!l{(ema#1y-!C zqRL&zPX~n9`C^iZ*k3wAn$|>mFcazmGJ+#%E_&W46r8_o_QMqZCG8A%tV|f}($~=TVDz{noy;bU`1G=jx(YSkbu48MxUP6x9CQwm zq|JaG(VR8y(#GW7P5xQ-dtkLFRQ7mgs(w~Etz&EZdmppmmIL@qvOORakZ5t`T-Nu9 z8tYM0^i+46xsS2Npw1q>9lssok3DHvp&jjV9#Hm`2Lto4FiTlmHCb{`EyHrx+Plik z7zj*QhL2En-%8p{MIG~r2^&N%g?@?@$gL;w@5r3@Dewx%Cf0kbCK7N_FdX4*tG+Ph z(rq0Jm_8H7u4u+=SUH(1GRQ|lKaIoe6;d|wb!!V$q&CicjQ?Y#rG;BlYw0bC^=jU- zohycZR{)%#p#l)c9so&yMvT4IX*Tj}=kA6eO+d#W9dUwocfN;O!U|Xf35Ru{(?ih; zPx~x6g2#yfkG#@3JtD&Ke$PZ0jxf2R3z@*X>)AtrSaw6#-yJe;?Mw2~6DvLEwU{uf z?fDQ6F)I=&_dd6_ynz<&pNxgT%yydq8mNZY7p()>V05z)>;-U9%v54+S`?$(O@vq< z&xJIvolLi*4#Pt})I?CQor@8iKQyQXF|&uK_|Xq$+h%p*RhP1XzaVR;Mr4f1c?@TJ zGkys=Q)QqhWPjk^Ef!O~R-e>7JEt4)FQh2!o7To&ETwagS_&v!5%{e@d8J>>(|m~? zk{d%xY&fl#LH2mfT;y`-A68l(t4W#5sJc`($P9OR=;r3pP85*K;f>NpEuv}99B993 zcNXqXy;eB{?@X6`8R>536_;k0M9SW)%hABcZ^^=$%woy6cjf4+rx8BR6FD#o0vhhN zt6ndS3K;o|3WSDh8>;IINBoF3}2PJhJF-co@`h-zHH;y`0 zT5XAnjvg3+#YoD}-)5MW!Zrx>f567WBje#|Htc9^{|fj!p*4N-GkULp{tn>QumN$8 z>mYGRMG>UdOgTO-kt-Lz=~gNbsUvVS6pX0GwFEkX&j{-`N6Hx@-DOoQAYR_jgqii9 zVc&~#8uvOtg>s9mjAUKQQCT$;hGMl!9yKLpJ=ae~b9%KL%V*jak+o{`d%w)V=6l$k&)6us)bao+@^9-_H z2iE(mqu@Kbq}-d0b$eFoa?^m&Le7qk%XBbrLm)yJ&KzUgxL)Gp+)`OmZfJoY| zJ?kpeGfFOL=6VW}_S>`$Iqsz^4^8S~4_NP+#=f^lK59aX?mh=-!Z6D_G~$=rX6XJB zg}~r@J146PNO$vtE>;>Mibo?lN*;x3GxA#5!XqktW60sDcw^0hK^AIqCs)%L=8hkd zhkt0_dF|fw+g_R8<_~coCf~nqi9rAQz|Pw0L~ZjANE=U=wQpMPb?7%=qB>(}OBxAs z|8B&PTj>m<$4kvqUN0LW=cz(l?|PS%EoUbaRd}@M(RYHn6e~n z#{nj~v1F?|f>o%7u7gaHz*G z?}|-+R;`?46{x1|PgghdJ$*0$7rTU`08<~qn}mHapGEC>_JaJ$_yLGWJnN03^5Q7( z%;;A>J2RGz1=^!*o$n5x-rNiX!DDS~Z}$k0l!QjVdht0{)o52qfPIDA1U51ng%As6 z<7*dl=rSK@E%jXmM2GulF@n}8>iq)P!TOiZ`%+MrOpsy?$UPIdqnnYg`D0%F`|Dwp z9W}4Ojxu5xo}LH8Q(LN7dNRABvKx!OcMVhVl$rxGpB0&kIRiWlZ<{TtV?Q#ghm1I& zGsCUbcvd{KP^ND-wBH^K*fU*YbPVTituK5@$|1j}l(=~T6?LkVxylDo4_CWoXR?prq(0e8h&OMcr$IXpQmkY~Gqoyjpja7w`;=EWQYhV6Kidz4hqV1( zGlP(C%B%5G6%(ysxG!t%|B9I>u57X~TdHp7;Lx2d8uHqDd?KDG4f9ooQ-h);76O1* zNu3Hdf(WGS1)KSbC07a+>IUfl`W`$rCBo+{5d553?>F~+D20NlmQ0*qsYfD61)rl% z@y?ub9PGqM?Ih;(Av*-+Os`yN9yZC9k^1v|o`#?uQe{ty3 zR)iRDtKNN}F`=NKc27Yzh(@XWu#*f0Ji%~@jLev-{%R7rq+-i|g!U^122SsIH_;yO z#aBGk!*xliXb?;VDs9gTvWmJ4As;!G!Mi|-JHshjoAjSMq*9*i68^FqUC zE}om@AWMZ3pELbqgjkl=ca&X%TnJ4;TaL{VUOSgT>x}pErXb7{Kd|*PAPm+ZyIaBY zIE-Xo;jAG{-j6;2D3=vS*SWF-#AgGj6^O#>$#&W^n3MG!BD_mxaL+dN4&A%X#BU_4 z%P23$r|)MHkNPnVwO#F|k+k<>y0F$g;pO}lk9%EO5if{7^Ek~yny_XpQz)gkD3a`Bf&dx?~| z+q*7rSkmJd!wnZbpepG11tWLJFS1SQ6`h|4wCJ_(IUjdhIRj`aB?9tgtIzWXy7N8p z>6SjJ1t%@WasAMTXn)?x#LjAex6iPm&tAo{6p>=|kae8w#^qzh?`{5q5iF+*J54v& zXk(8WF$0yYBZ+a;jQSI5lfB_i=c*J!*Ocei)fE=Tag*~C&)A=-zOwSfLHRIXyK7Jk zI!@9rgDOcbo>bkFt!##efOWuDAi3z$pM_S$4kzi^OD{~?yJ9+d%d>}ZuEl}o^U9m&QZ}(Dr5h zPA@wWsYgTBFD&r{Q94?*x9-=>01%-%r>6#G5J~3L?-e6Yz;1VM3h^MgoPQ_HG?^M% z@$}=A>8z>uY-K0ZP0P1feMO<7<6CBJOq0-M2?}$xL~`*I(#xGXFr{4oyJ6MIYAAwm zUChphe(pzZaYRASN9O0g%N992Cqh0PyqFb{gJG7znRsR)^a;(lbCW3X*;!ox^I*kI zx~b@D6yQJ0^m&Sy-PR-E6}9eX!Ef=z3NyEF^sqpj33loqAmWs~P!JF<>?&DseHN$* z?>&i8%o`2I&z0)X#mbYeFTA7rbs0~~k?sgY3o(`uRMK{M^|ad|sCr_;oBR*Nf@Vz1 zXbaZ}MmID7Lp<8x;2qR=1FLZ&ruhw|8k6sc=VR;m$?u86#|27uTE0FEIkw&gp{Ti& zj6MKL0LoW+Rh78g7gaf(UTYGzqR;0vB`kZ-mQIWkpf zI@~T4CJM*-KL6w%;7+g2)ydAE!ryX?2jiE=x+lj3NEp^Pu>OBtBS&xG_YTF^?tsnR zUDftGQfhjfAQKbU3{>#-P84GS#tJrcT~jhXdTfKAcUxZh6x1VfLQ=k1t)4(Q583na zFjkW*<~x6of=@(5w-OS=vDzVqRql`H*iyW-#W6Y z8&Se0Nnk>yOUqhF2WdqlWT{(QA5r7KMIBfkS`aVc0c>#QR!VkiVj$;URj(>)Ab zX+Gk_Q@)#5B^Q~R7OE!nGYAcfDbft7VF5aWk&$tOqPDm1b|8wmesbtjre(QOQ89xY zVvJ|Stf3qdXB3x;^j2d2({8YdV!W4|taBHnIj0gBn2d6J@7^^$k7ZyF7OJZb)yncf z+80bZz+_!2-B80)eC>KiO8)_5^5Xnjg;!VUb%#}E6_FZDOsL=Gldx5#fv&k>d`k|S z-&OFXc92~>L`Xg;%GU0%Z^S(Rw5KdL;=yX1*|EY+`m-_lX~;268g@t;rg+1bm-F$F zELPQ<@Ebb6q)2EZKG8ap7<`T5pdLxlR%-&^I`(LC0%nEmPX#>)$Uai7KimuqrH!ZD zIijtK_BLwD>a)xxON2bZY$Q+#NpDG6{}XI7odUwR0U#eypG8Fpfpfa=Ha`UJvhpE& z!})kg>-hat?2B;Y!GIigSg?P{@F(9mN6}{;r7mF9u z(#@1_ipz(-mUk8izjTeeybr-He=VTl$$1ffO`#MLmXG3@B7cdZyt5s#c6LunBwjrs z#6p7U^JkbK+RV}K82{@Bz59Lx13;CMn)7V#oAotLINXuOXp z%B4yr{<2Nf+DBqf6hJWyiPvN=TO03CF;alKW8(CIOQzQUm&^n;F%l|9jOEbFQPuuG ze!$0RG~h#jfMbr=F-bjA@(FYM4^QT%KrkF^k40|ZaL#$ z@sxG{62V#jKMw;Z5bO~jAD5C6mc*!+Q&knqG4)>pmKZ9*AJp_ue0n;fDMN27_Ol%4 z-c3_elkKBNfvzb-|A<+N+cA(`w^l;$_B1#?K9EJy!}R$V(+@*k-w%w!s`XWW*D5Cr z9MQGM;L#OgM+XNK0)nX6Sd{#v8Ua2!+y80>0VqYi`^kr_uMk zScZRvA%rl)|MpJic%ouoy%s=u`^lN7sB}t&Jm!BR2LL$#FHv@b3G=ZJfbX(AU%BK5 zQ`va*ss9q20Fmt1{P&zDFoNY00-M(90Sp}5+)+Kf6UO$I2>BnW3URy*e7*)oQt~=* zf&w5L}N*iuqbs($g1FQ07RDBAayf}vRas^Xj^L&In!6w0CLoEbvS9moPY2Z2C} zg;1>82a3>1UZceZns8*X|CC1D~K~b>QBA&Zazw`%Cia9 z(@Rcb}=vfbZ_T-7nN{6rdg_U6lDoOhmHfWEKKs5!!XiZM|h)OY<+TC}v5gP_lG zFe1$iL+v+jbHj>iI6CuIXa-JH)aeg6SprEB6~0#|F#T1rbU>Vcf5h)6I2Dcv3dbX= z$w0bu8#bb6L6UF?R_v0N<`8o$4)t_`kHJqf*v1a-r6;LL@hD;<$eGw?TCoOE1%fq5Wl60_5_xR{b?-pMiKHPNona3qN5E^?6%jEormQ`bhWSvn}SKW_)yJB zQP00C5v`l)8Jj;;Xm08`;%+%hXuUv4!mJ=<0SS1kKz_hC6W^H-oABrWrw5Fu)fO&! z)bcfPepwu6&H0C!Q=Q+_fx|$6!S^l-aIxQptOrc50UWOf5eVR@>DiMmpVBo>AsT5< zgeS_0sG!?Yas=|F79WiHrqI&uWXsw6ONw&pmYBIH5>xR2tQr9Y^2(DJ>0p*?E5=q7 zful5K;ODF~&nb|lfb9-ecy%Kx_XM$mS8IRMJ|Lr|t=aXQ8j175dD0T|STE(1G|M5* zCT;f`6Ff6}Z8T0pwMZG}q~mQu!ANt8jltQMqfOujBTQ*(I>f-=vcZ zc)$xiAzjmC6?_K~Yf4k}*h<#f`hK=LZNw+R8%VHa2!sV^`XI1~k?yd~oq4QpQQ?UJh7^6IqTl%s7_(LCJY#LPqib)HuQK4;*)79^V zykh^lhKx=I(w05+F$lag8<2Bq*I5g;A2EfKD!%#7b{v3ouji~_3UNVRvW0_ z{LG3+uy;uKrx2fGY?2y6%#--7tng72l7o8LDn^)G1>6G_87&tU6C2t%c8!x_IHx6F zB<-r|`=j6xt@NLmV00hR5yFg&>k2u%(1lgCYj)`)41d-9p zK^WjBeMJk`SK#Gya0S7`vlTNj7L7#@no)#aSY9onUS9fsv)t-Ley6>0hGTtsQjS>u z4T{UiI_iOt(9Q`SrSJ}>8>PSC(QbFXAbqZ?KIsG6wk3H)Tllsz3f686lO!Hc)3}V~ zzMqVN9A%9o8b)qJL^jQdh&$0RmNHT_u=VUiSnQS}CUTvzY>q9`PhqYwRVL!YlEki(us?424w`-=zy(x;tQ>|^;QxY^GX5oLMf5y~IEM{8CiDHr!I*dB3LB5;expiu>5- z6eL=A&CUt#n=H-+a$s&0XAWz!r2~?fn|Y|yg{TVG$r6LTTq&P|ruE_>N5?3kolB#? z5T`v)K9>$Pa<{8bplg$=Zf4UV?YxiXKKhIM7y+XfKih0bb(iNQVLf!};!GZ2o)l2z zt#GTI*e$whzAF5|A0M&FvOr`%D}fT@M)*%_mO|KrJS24ZAz&l3=Kyu{2I5dKUOAW# zui5(H>scnN8@fJ=nM_pbR9ehKhQ|wcOP7Pp2vA)P>)k)0!hrg}l;K1i2sCCXwKZ!orxt znERul)WtwavT`

BI5h!W(^YQB}k~iY*#{?1hBD;t;RS%R-?pa%xY>NU?2RKjFq= z&>bqtfkV;M%_z*E4fh!5ziI3680Ti(_jzviB!>#|#wo zzcCM`99_Lmtcy0YNCdG7I1yD zbNu0~kNJk%Mf>^>Te+?~agt}hjAAw^S{AX}&RA4%cX3&+iZ~CoT8sue!;<-Kr7wM? zPl=r{<}FF~2rES0>Zqx3Or&+OXC+Pd?D?)g`z-KSbqA+?_{6lE>hN?3Ll&dbY%IWVwwJd39Ge@tKi~!k8lw!4+NMX*k#Qa#Hf_ z7H9|4W=q*^5gB4gfM;?yw_|Kc>#jkp`>B` zs?68Ktw$oSNzC!6PZ8*|Zukf(h#i|9{XcX#QPSx$ux2M_iG&jh@e25P;k=7YxT*xP ze?~lPbKl_;`QXM}-}sB33a2UO8@6R1);;47ja67n_Frb2_(Os(39Le&yq6X}eSYfC z1b4nFQd^szGDFi^gdi5zvMkEC%o9zaA#{+dR*C+kjK4Q4nmaq+Irud7qJxmZ0v-^2 zi|vz<7wYl2#zT_CW-`b;_!BDcmm|fvF_Rl(>X~e#N!jxg-eHH5Ru8#eVC1f?P*nhL zna^>c4(H6^Y?#-$e!wbzAfzN2u<0%L<86}b;wSt2h7VT`J8M%u{Q_ZynQ4KQW*+(q z5+G%}S4t(r9~~E9Bif%KI*wRzWt3Er8kc307EPRglp( zAbji3NHJXv7&3FnrHr`VE|NFfAT+NC$QA(aU@Zg6g+CBB-UQ}=PHp#_@)^(yK@wI0 zT{-^LF_-^N*0AtJxZ;iJgRV4^xUEyeB_@@TWga`a6g}Pll1!xTAHZxd2!99W)dAzT zd_7H_IH$n$1Li=>xJcgcMZ(Or;|8i-w+i`rQ<@8hD1_f8v&&%f9fFqgyZn5?4d_Y` z&zo>)q;Dnmdn59n5bm+Bji`(YY}s0;EV3%(d$Tvn?dr5C5NU0xmu)8R1na=QFh=#} zNk?p=5rj1Q!X`hAy0%W)!nHOK3Ej?p3%$Anvz1?pzC$(psG=S*v{gF@(8-5 z5yJThts{<=Y=#jfT#0SYMiriC8a}iB1|I}bXiqh~y8ULqPTvu7b)qcKS6Lm)7l;H? zNYVupsNi-cT=)i}&iY(wsSlx|N?DD%wP!8D-k~&6lDGX)8q5ojeh-G#>Ywe;xxQZ0 z`<>L(VGBA#kC{Pqj+^kUy^P`|H+>=E5X$}L zYTb5(%Rg{P*caREwvj}@*$Mq!A$&_h16rs6rGMA`4RD`Kcj*p(w}Mp4twqt#O85Rs zx1IXwN`7n~5OP6^!0|)(!yR`~ZG+*L4(a5>Uoo>$^X}^UFlq`e1I*4eV|hWFkHKfI zjs|?5(da_z+ORtJ?`|tJg6AnAwq@rCt!_RAO54i%&9`d=0s`Dzu!oROjX77cFkq>WW9=QPz@6k1*0~ zKV@=@B8|(R+DN1!O#CT(P@534-0XzU+P4`QOs~E>WENL}={(E%v8>X^kn3wM)_3oW zvh_g6^AYG56k`+HKG}dY*NtSY_vNTlGr>~horxLhrhI7LOb#8HQNkAP)CE`R&>i{A zQjH$a>MnAb}u2bauH5B(%| zna`{okkw~*gS;Lv>Lz4^f)HloL0xXAP9u&>p>^h1c6A>@!k6}rKYQuCFOlURA9Y8f zB3m!}B0M?QOHT4f%&4Wx34aa05x*8Zh9qC^ChI(9rARt1d~xRcs@Z6z&$O3*7YCb= zY^XT+4rolE1|LQifLH>pd#o)R5pjsU(&RU3LUv4Rc?s|SkguKcAwC?dSJOUY3g~7A zsPnUYw>Hv+iNxfQ!`+&D=$zftwrWz0uEmPUVOvA9ZM)%5dqgHvEfd-K0HI*wJrB6E|w@XQuTK#IyMP@VDmrBp*MMBgC?JS9_pO6|H$J&oT z`q@IPPIRpqa`t5w{Igdh(cVu@Y&J;h_T=cDWNiHKFyWB`NSIVXCu(KbQ9V3m+_|FPemUt?SEZ%5*gsh?9qD;N*M8d_e5uBG*9 zj|mh0QKS$^^dU(+&P8!!#b57LR0pm&s>EMx6+YUu=^LMh99k zh!XO9v}F$Vy;be&hVhLI76eZ07Qa}My2iaR*M70WW@9xNRM+xS@^d0(pn9N^{#bYc zH{=-i@6k(V*7xO<&wDTm8&-FH*}d6Z98^`N(ty)OAyJV;VZ2^#fM=Ew>`JO_mn3?i z{`9^h0yqD83IV?wri8HPepkITTSm**1RgWDQipg7p=y<$>?=w6&~!FW3*mOg6NGZd z*}!?S)u-|jVR;9ZDG`y_FESpNA2Db(d^xon<%m=6pCyfVs)i5)lw z^77ahD_r!EQeA!#^B+|{`dwxb=cV%mv1%b&>^jCBDtZte00OJy$B927+ijy3IJ7J+ z4X&r)5LoxaS5>{3;851G){6LXQMzGrjtfa5HgoOLLX z4(d!kRrOIhjmBXuw1;hR>?SADa$85gXGc(S;~nmGUWR`&HNLXoa^Prc!{%4NeO)&- zt{PFQtdl~#YP(sUodWkB2|cthBA*4sG}w@nwCW)jRLUr%&ZYE1yZ)IazJiSXJ-!f= z47qP)b?|ihbb=w3hl=k-u6y}Cj0M*2XT=sgj)W7m0$LnWKcDe`-bg8HoqJqap|;K^ z1auBY5oKRt9KWdY&lBV?3qp@G7k8wSfY1jKsdR z&cM+-S3?OU)(g=xWWz*IQl5)Dyejh`L5YQO$))$~AL_8OX~Q~K1cB%DbgixjnAGi!$igBTH15o(~ko?SSj4VI1A#sg$cF_wq1_c}B8KK)`!irVh z9(khEKE0qHA~zx+E}Sgy=?;c#vxJIPs9pTNhFJ=fC3wTe#gka zgkm^_o_Mhk?|Q@xKHaU&GccE6USxB>=ev?Jf5Q87UPbV!`mwEXuC36>rG)X*RRd~( zoDO~tzYg=$Z-dj-CVXYeh3pry7>;0g_TWsZY|*F5mT}p@!u#&yc8A`!S(IQ$x}Wf5 zsoiD>f%()|^MV73jTi%}R;(h$VV>*M=KSfX(P8k6`1qa%@0)rmx#7cuC zj`Z|m+(n&H_EQfKTds{|-Snv4nDWa>%F)ODKACVA{3xjqYis{Wc0DV2vy4dMD&bZI zD^!yGW7UBhiIU3-p~(U>+N=nvJ8*KoccN|XD5VxrGk-JL@++FSwxP}4dww&qq9Cbbrx?597b%9Is`@EdtDaD3H7i z<~?{m5v){e;~eD72ooW5$&2GL#fL8?3m54idZNxXXgSV zF+m}oO3lic-V$_^RVH2gAR=Jf&Y7}SJ`n;H3Ofljhu?@pi6{h9$r_*m+OAutV?N;! zcQ0TQeU0JvfZMFEgz0dS@`Ld>i*5qFDKd=I@B$qlm1`S+WCG$LTC}6T>Y#02_j%l^ zo~WNif5U*%c)|f+d*aVHxk6vN>qSJX-xqeaA@IL~3LX;9iCTeGK|(tj{U8R_4KFG2IkfD$7xaMzKjIbd%li~?L#?a3a=ZFx zgxW&JzMR#tP~N!EUeQz(yd~_!DJ!P0o{SXv=Nfwntm|lnIs01_mU>)tydy&nz134* z2CSbsOk1D~TntI&$tg)cy5|!!GgsdIuzLb+DYModPT*Z0a)>05={O-r#=e4nKEFxC zB?h{lF@o#l*`+2^z7M3-l#*-mT}}$9QhU*Go}Kt6w(VQVTY!WMopc3V#Z8GCMiotB zAA`5@&48w0?4yAV_Kq69OCu4>HE&m64;mxw{C(`WdWVgiyLnbQgSaj*5h}vovqpV- z9HWrRvgh#4FQxe?Rbc5*sxIf%mffi^r|F0dqV{$VPh7VQa07pMor~sH`^)LD;!<7T zg@v_LIsg2`rH$AZq83qQw+)+zgWDN?A$Jp`fVtcQbUZIzP26LlucUi);K1aRUB(H z;T_;g>h!E_pM3_{qQL__Nrg_O!Wd@7z>zd+rpL^ebH^gC4vY$dGd|ldQRv71W3u4A zQyz+YVs1WXwFXG^Gx^%s#MRZ+D3wG$kJUP2aRd~&#QZi^{b&VXDjT45LI53OURTwH zX&p}j-pjKAhVO!<-xsH}P|+UB-2xvK+(ymX^MemO4^vAHb*i;&Tk)7GtpI??7Srt&gr>q7ve=Q+|^`VPW~BRIR`pL5~Wn*l;t1A<%0fvYG3`*g5sI zoRkTD(xh;x>9#lDhZxb^kLlonGB|H&iBtB*2;1aE5$Gb!#yhUIvSq`hJX9p9{Ka@! zxPE8*69hGVVFsgWGPR%Hq?vmMj?Pk#o?~uOm2f!C0h3YKqLpebwkL?zxd`>;Cvck< zwCJsbDnO5R8)j1Dw=Hs&YY7ORRjjNf(`2s{u$v5}TbpnX8M)o*_Yw<|4xXeR_Wa`|5vnied9Hnss~&`qkkHj~g0vS?ZR7jKl*a1LJ*Vm6U{gW=)pF8D zdsZaj%w@wZZKCbA^+h8~VeYZnUy8ZyVI!&mRi<~YkuDiAXFgi~s)z6JL_pXefmmj! zF&))xiB!KGMaHr!96uLte!|*TjOmka^D=?)pH@QckAG^&K!qwTCoX*UL_#0t33E}_ zx_ZLZM)PEHkp_wUu5#|o))ycLG8Hun!mMIu@)YTnh@*H=>7#(tJfAS0hFCpV+3J7s z-i|az{f~zLHtl+vnLihm=oQv3doaVFg(I*B4A9$yi}D5hxInrRnFV%pr23|1vdG)OLI4$=6CgoW*{V z}J+UI+1=X^@vAGAk&$ZgNh-Jth$Yn`9pBvKGM$|L2Vyad2Y{78docxqc!#4oXsmQt>FY zh*as+*j7*M41#)mq<)^}A)~wGkMefdH6L#D|6I)3W!9k{Ui>I3niTP1g>9I6G@uIV z54G-QzPZ!udM*vJ<0%U&`2b&Df2OJ);~s}2sf(>>{(*WF!eljXTT7#0Wzj}0dQg$< zIiLfTq;{40ao!R2V~&Wt4*$V-IcZxMqea^Tt?||MDwvWOL90Bw61WxgeT{to>nb$9 zRld`eB6cbE&Jq6i2U+FCfn%Rup*0NO8&D{n0f|tU)hQdSW_Q zG`G`fL=Lf}RiqGU3(Pq0)GRJ{(5LodtUV4+8IKB7IDb#RHY1{~3~IgRZly&sRl5dH z)X1qQ=Xbxt!&S~5;T6W2Jv%2k1R7VH+EkQ}-(T|8tRo&5C@acN8tvvu!VrN=dhEcrMckuj|iSp{Uo&dOSf z82SwM_c!+h;K}Cqv&)p0v1#W9(>C5aVo0R8XW+RZar*3~p7AABPKNGThg=(?e;_T` zzC-m+CirT&ld>4@q1YaM?!4zwiWpO1W|tcb*utH?IK;ZgU4uhOgD|%SIz&u`_&$~SH zs=_WFSYKS5w=aAi&`IKknTJJvP8$hvN(^^QkNZ+4G;gg=VGuk9-~!h0B3*QGB47!Z ztDg_jgJ--Ak(O|tLFdVn#|C3x ztI)otDR`I+4v=X>Z^!3HGVq=7yWnXUJ&Dm;f2K4i2w!M&)wIlkSn2HC( z)FQ;HCD6FkUtN`9QHnE9bz>S_4ZJ{u3;ysg&t=?`z@(en2)7b$upgeO8)G!r(C#$h zgSzqtat`fi=`;}W!Ab??dpZ9sSN{=#9dd547p=s%_sW~cmRuNF^DB!4xjn=~ztZ|8 z#!r?=dRnT^d?bomVG=}gg4};wY;?A1cJar=wD^6P=tx; z#m#)L(%d}Qip^5~j!&qXoH4-Y=Y0{0`b|p7?TzQoL*^|J-3gveHyo)L{@3j-=Q=G4eA2aJx$80K9eU0(+(W)G$Ye-^;6lu5-I zuI~Gr3()pE^=e&sK)TNH2leaT=7l+1p@REc9MR1K2%@aB1az$Cn)nu2Dyr(pR3j?`W2ee4hI9C)1h><=WbCb@(RAVS+lR2j&hXTUikh zWKEV@2568+LFupnssn5=XnOry5Y(M-|MPFV)K4pa7-2|{Orka<&;97%-^1v6gGK|4}OjELh3^}#LYXP1$>0ZwVYqmK6W zc1ANzYz8-rwx{>rq(4u&2(}P5oKQ$E7%YBGOpeE->TLdsUTJ1@kT1I;NRmE(7Rw<^ zzu?|m(mGB+$rH!%e%GT9bD(31%yr~UX`4#F7+zD!lZ6C%<`YLEamalj*kbyZ>+9D% zD+1|8J)bp>Yo1^6y^CUHtZw*#Y&xMMN~uc5Dj2MH)A3ZMcQnI6g~i3C z^6Fe<+ckjz$1%p|;)tK#PI^~0#*whnb6>{{YZuU!v_H)s_E9#Wh^=bS$o^VZgH7>h zLUXbsZlACdS#uwK(j0@b5Sk4J46ePVIWWT@@&3 zQivEhIaJcK>%-*T{BW@3qpLe9cagqak4H9}lhJ3-rC?`lyDPwEoB6zK>LhM~Pvn4k zECldXJph!X%?d271PcTg@X!Wfl-&+l9_od^EB!j8>BIb%VZ3Eo>al$wJnU4KSvf|I z@>+;Y#PjA_kY#%t&zQyJ*C|%n;q9)ER{4XW*OPpWtov>~2IkEvWzty2aTaR@f!Q3(S>5`6a_5w&-{l$ie>aKHgp9t50U%zPrBgPL=>%oC~w2%8c-{d9C+%g68ubFtgcJX4z;bE}Dt zQ29`FSW~%;$vGYsFtOUnj)_xA^0i3tTE}!6%t;@L+lsQvb->dapG^zAeHSV>*w1z{u7_Z@c_D?tIsmg_G81$cM(Q(1GRlv-Wu8`G&{h+muS?z=5x!C6_cPj~d7rGxNtd#d{nwZw;mfMWjPHl8__r&L!@vmUrm4vXW%5e1SX{FgQN8 za{RlFUso&abFa{CiDKGy2?-)>{CzYBB2sX5uGzLLg89D=#5)y5*A4^cyQQM>MnjD=f~b0+qs{> zRa`uPh2_SVFVCAR#qDrjUIa3)9v>_|Vd9Sj3F{{TVLOAlXQKi0htVh%4yzXir!&;f zmaLY zd_dc)HR~Z##KC6f|A0&N$kdO*;=ox_IM8{FVB@djleg52)!y3EpPiPK>v;M-@N z(5tc@C0IKEY~jD@a(VFb)ASe&5SSCPBcC!}DeVRtsQ!6lC6_pSFpztO%*_ln*%*zA z;IKwuaE#fJCJxxSMy2O3(weS7k_PhSDZ9xP4bC$EawjGLxefZYDg2?$2}0RRZUBRn zU{CNo5|AL9awsPfyqr2G_YZdV#K$I?b7q!%EiU7^Os>x!-wVq*D2n0Y37?&w4g(+r z!#iD+es&Ymn^yh_eCbOXkB@T3_jryZr;dN`+)IFRlF9QOT>qgPv#nqD#zi!j*7fN> z4-!YBK!OKs&s+KkBuI@U$y-^(To`@^es%TvIKRkQJEhb<7W%qN1VNRru z%Im)r$BKKDB-dovVazOYf)~&yC_O)hUbbUx9mT%6bGhc;-rhb;%aS4H7H?;M5?b#fj~q-cvMrDFxI+M0bm0bQYUTet zld7}Xa7Ls(;;&&O66oTvpq0l`=3IpKXAEPHKDWhc`A zt~n;42+9f)DlE71w&6!(3k?xyL#48=%Vz@lr!-2UwwW}uya zdAYvsJu60(Zq-|AAt6#~YHF=o7l!rzln7!ji{_RV*pv0&ZPOLDIHaTz_4UG56*_>z zn_j8ZL*JhfC70QjBkzGKLbG(CM~MMPXd6-NibKAs!ZHq?;9Xiuz}=g+A}of{GjodG zuUu^$8K$OMeQ^AOZ0|ohItl=;I7>@QT4ffX^Sv4H>Z+ObxU8>lBRBkNUm_R3?=3%I zM?R%pJzQ!VW{%w-EL{{R3HmR|(s*3*mM1NHDhD8==; z9!eIZvBPo@gw`b3xKL)p(nuH->DPsdc%4&mbK@Bs8+Uhii@$ss#@)M;lja+U5``1x z@b)ch@DX(-uEk3m8^*V@)zsg%c+?->-c|je`K(tLs+v=@^rnJe2F}m8|rc3TY(Z;Wn5LON+4u1G-(=It-65uQ6Y)_*nCQdf`21t--9?967=zW+H@ep=I zB9)NaZj40)q%vo%#iybCt(=d3idn+w*qCI!&b;CkWnL$ze0fmZmmKCg{Im*^O;%*; zNqQJww-?5Xrt`=oD7hwrppYk7z%uVDHZ z#3&xWMCul20?q;x34Ri)IV<)~)eImgV2TF`hogH_K6wh=zy3|g2;w>kXg;;Mde0-qq_*5`2kT?q`QN zkb{>RXZI#t7d&Y5{DQQ$zBz6%1JJtP-OIY~T`tF;V~NNpeTIk%j7k1c@T)?K5Inu@ z)`FG4OP@!WEOa3eOfm7ueW{?^ZOu4hO165cZ}mKJwUtc7R3O$dXWzdopV~uX$OH8fuIA^7=j~liEl^6~^W;R77CeftoVW=cZ?X zvhZ+3v*H#PhdI37iA$ttc)uhjc7ySNLmcLJf09NQwNqr~ucoeU+#AQDf)at^gOkDX zT^>u)ukQUBV>Fon4e@hpYikyFRt(I{gAiAUAh#dGcw+UJ$eFGC64Ip)_(>mQfMC}2 zdr!2cd*5YuPeVyR+zh_ZCI|k;`r_wJ6ty?oV_J>c--E+exNQfb?C2e`#?nRo-~%-; zO@rr>qe0{ZCzkm1kQj6}vATDy|BBc5GFKfX@Z-q-=MMawzEPvE? z`WbYELp?x;hsDk}%!vTJ$(q}|@PH{L1(PMKYxmyh(8yXL#?Pu^cozkSWHI3Wu$Xl`&X=$;%Jb2<{9%2yE*sMA5ZCk3W#| zkZ-g7xj|R(GC!!c7GWc+9_QBFuzs+P&A?}GfQWwjUD8eio}O)Zc@hVRuUW77?=q_z-_*>SaCZocbtF+Xg=N?-5?`-fpIHt8!w5-VU3 zGrSZ|W!bG4p`AV_LS-9i|DI%$vX*x)9zB}NV9ydu6t#q3Z2yWXMwN5tIy3&y-d^QG zQShDfd`IxT&(O`(!qObIC?qQ~*344gS`EmQ2``8-&>kgy+_PQvY0&iUm|sRVCd1&0!&Qm(AQY&LqKwB}WJNHe-2By@x(+Vtl z$yZji$eM`R>S|%#BYc|UGd^mJsP;4_ALnE8L+bQxBssFwXvv?txbA8QeG)}b)xXy@ zRXD<7@mWE#LF($xj=jZ)HhCFM$=9jjNLp#_gnZTiWtw;RK}rEIlnAuba$q!y>;Uvd z(6)QY5GteVKdaxUCA3p~IXg|#*5Qdk9>tM$k2V28hY0wAs?;oT_9iJ8Fz!WCJ=ZTb zAMV*Bla5%(G+2Y@>RvC_(ZNpXfJV1oV+(uncGm9&M|s*L7uCZ?F(Tf(y`3Z>3wvr0 z+kfz`e(zvZ|)zt%P2iNsfXm1&A~WUkj(2(F=Dje+ zCa2rx_d8+qBz;eezY<+;6(K=%3gdo`L8O(Uh{@Ky+4^u}&nzD9@8SkvVnNu*x)`48 z6AATYcti0ngX;Mi5zc`*NyzVK5UJJ8G-H1wcp?QBk?26f?|1C^1A4m+%F$#vPgHan zLc;BIaQty-;bLNOU?}g7*9P(L4nX9ZHqQ7N6z;vserBw~cejIG93+tmQI|K20IsPyoku02i<)!7&Sd=p&crRr7$pdv-K|aFmnIT6KVu;d~meA7V2Js}* zwrbpyNHs&-)6_=N)C}Wl``rGY_cRFB(lEoS-o_`h7}cIKv~O}GE5aI4h3ewm-SUWe zX#ZGyiI3JcG2piuowgPOM(JiFT6dnUbanW%@8C&|;10+k5e}W{a!wry)iFj4Fxd1J z`qxSeBsqKgLOjux{e8^RlB!uHQlEI_p`T&YSlbQjZSPBjGLLzx-)kc4+dp&JxGi*ba#?-nV-31nVV40`jM7aAlh{J^8Sq12&9)c#H9@JPM3_HkX$SZ!@ z#OI=i^Mppiu5)sUOZk5B1<`S*!=VFwV|!Veow$Y!%xzNQlW@$WT<7aolc0D0-~;NX zKS)%&3>3w+hdD7yQT?kPbj(tZx^fyG$b+sM!^B>0up>w!HHHK@Jis>HuBlD3MYX&v zL>jyJHanKS-LEd?eMVeqHyge<`;P3&mxN~Gcgy!SrlV3#n#%pC_LKtvN4hU_eqW;LXcn&<^@bSR`f3k?~!vLMMpVhq72FkPT*af|g#43gP zp@pK3vpoFq`P>u?j;%W+k@VZQZ!F)Nc(_TW3TQtjC80YwIFJds6|B7pZw#X*rMgB6 zv{QQC#8+8-;&JM?enE73&+bhX(##$DQ){4k(kUu~_18NoQkz_F$%S~m)~iSn{wIt6 zY+y|A9&(g9);;Y!(J_xfDQYtVN1IfWcTLK8aanS$=2e3t45vzi@yT)8;k@mgk-2>o zR#LwycR``1QOCJj^0BOg53=+u_?6_IxNqvogOq%8~e2*o>UU{t8ZH?^u-~DgL z^4vAyrTXD$fj|IvrK_te0k{7Jfj0}zh=~DpR~NoW^u4hv8lsl4 zYj6CuXTN%wc)(t8Ay*)$PW`RGi8MB{?O?b~Ddu`x0J%gf7g$O69-v08en?ebvX{lao%6EbZ?LCtH5 z*#2R)d-OH>C0iqtxmp+@vHEBG?BT%}N$d87-&Y2_;`Q|$-rXu>4CCp!8sOTxwdYfJ zpvJT{|9CsNnCWq1DpCo@@9Y>04cD0KeJK78?^gt=f1N0ePnqL{HZ2Fhf3pFsZ6!n1 zfFCXnyP)JSh86mj@hgxj3SXdm3NERbHegxQEe@f;U{vxyRP8yxphF>uQN-%mL%joZ_t^;rawR;Pvq*} zq4R`fKnz6TKP{BD(3AGlE*FsKM3FqxO~GE}z@=2w_E!+V=g(&iu03TR-yyd>*uFwZ z5JZC4AZzO+!ZqeZGhNNB#mgDT>flsFj&z=m4vsK?t~8clA)bbM|EA&Zv0dH`g<)a_ zVXSj-up*#-#tJ?*H6x9hbZ~*z&mu5N7)}NUjnq2qtqZV8d71iCgphHNa0v)PBO@`? zG&Pgt!90)eX#96=%uz?$e2=_RkB=*9i#Z(chdq@7w$)WWn3j( zV}x&+G+W%vusP2plqF6Zi#6hD`mZJu4)5Q8CIOIAuXN(DJ?_V>az!rz!J+Z=rb`7i)65NaB0O z@tRw$d~k9>tK5wGA?ll03p=Zhh0`X7WYiJ8G}*)MfwWdyAb^=ZdGRq*lx4@+3+C&#B~{>oC@BU{T|X7!bizH_TF$v2G-eXV6y zaCBm4%=3g3G~fETk$kqMGr}2Kq$*IEmg4ba_awJFbHJ5NZO^%5Sgq=s~=3`0<%WtBo zYA4!C`axr9o|x6 zn&$WPYB<=j$ybg`@;@O)#sNB659gVW`r3(exOX8 z{^HPR%sA+ESYPRsuIUHvNPvvg)bRW4qy3Ef!d5lHJS_cVk9A z4dH3ByhQ63jh@DCzVayj*{pdo(~x)$Q`_%bZ@pIn;7mqxMjO|`u`vnFxQN?ZCOM95 z`!droTPJNDB7HTBL>zPiY8>LO2cOd z$w&!f056SWqO!1^oPm$~UW8vJ8OKug+_iA+3syN!y)Eg1)++yiVN~!~p^so*=iN&e!^xkT>aex*0lJK_mbD)9vX~ zc&Vw$V=f`Xzmf~kz~d4)z5yltGE}+%30V4XJZ!+?Y0ZxNN>SW|X*UT|Zn`~fab~l^ z#w||a+cwZoSPc6Qz77DNs*j+2c2pbj{u{(x@j8Z>_=%WWjqJ>d_Dk%Uh|g6f4{z=z z;e*MGQm2=eJwN&U#f7ob9*H4%9GALr~;7dRP7J2x7@~{k%s2-4)ND7fAd~uMg5z0T#!Xi7;eff0!u!{|NW(dk6rR_X&)>OVJ`hS4q!^1ypNy4h~cn?iR zq#9pybVX!V&}SNl#mTcRE2DHo6w*BUe{j?}Dq4$_aS$IW4bpURzIV`5*&-y8bYe|q zqH^O|25c*)rsAICQGJi-A93ia&3o}T7a%48{0D5_6R0%SR!jF{qEeYagKztINKm@B zQ_M$1*UG=OBqjo6AA)wjFll1r;s)8zR2u*O$^-4>_Cr0t#P{y~?pz&VUS8gFR@P9B zd_*B>tR~fV+vb0nlJ4~e?#V!f?{^MqEywD!gJGy&ev%>j`P zm>Sm|g8nqI57pKDJ-3t9PFZID2nYy((gASfZwFXp{Qf`>#vX*c+}w0j6JRtExZKNK z&eO-!=N~AUmI$gL%3Lq@^`)exTP7w5Pc{a+6vgh$lx5RMp~$i{K6XTGxb(}8KG16m zFGz=C2Td**%Y6vf?{I7%6$xS`1cj5Eo5h)R%29x(butD96gDaMVzz$PVSQsB5h>Y|*f zIFW;2ZNUolKwuoS#>2L@l-`~m%3|RX34X!p;V21-kn`)M{DkJ>4!;Umn*8rpQ7Ro4 zqO)W_yy^s7S%q9tPd_)#j<~3;6;#vEc*P~wE+0Dwpdx@}MX#6|Y~?k1wN018c7~{C zFb#6AnwzBf5@nKtsqIYxtS9J(lr%A}`b|$>2tmGP8kHkzx6mnJS0ZpU~m4QZ*f_WAfcSKd`r?g@FM!)xC#xE5A6a^UXz)wzzNZpbIE50QSt`DZ=%6gV{?R%2d#i7wMj zK+K~&{voYS+Oko9-|(k60id`ysiA(CQ--yFxs7*QO0M{Zns{&y1km+*9Uol*B}&6A z6Wj%1C%!L#8L)5T4*~vHOKCy?*19aOtklpskhFG5xMprOk$N84jZp^R%E=;L;~ui| z6r*0AMw9+ET9m{=xtAX8UF0(LO}Oi9r!9+~%H1l~N<|BuW40Ojj8aQu63M?=UwnB3 z*15CSx$&|j+wIjsZ37baoxbaM{jQEVff%HWAGQ6R|xo8&GAh z75@0uU-E2c&IH{6+cUTcGFllM8(ZyhlsQVwY3@OEtqTN0@FZx5*XW)-BR)_fCLM*= z2^j`{p@=x@H1bPk{w1kloPoFf?ra$~`8R*a7=G(7bnR1XPPmA2y z{)c(R`vQ(xnfeQGlq7o~t8K=Rfy}!S`1+fR)=y%#C_PtGpBjc1gz#ICF~z?C#VqrR z%T+45(eDh&xpf-)Q%vZ3K6CIMrcRQ7E9wLFxcJD{Y6U&ay*hcmu+>{iDv7$nOxC9Gf#_(D9D?9msyNg-51 zvX52B`7bKUqmH%i4qbo+;MLA)ZqOgD;^H2C2@-MxN=|in#ea+qb_%qd%4yR2~@#nk^NPU!UauAUJZ)esyvNw$eNhBfV)k>|^AbM&NDyOD4A^O0oaszC_ z+%cQ#+FBC;2DK=@%Ww#WREP)1()|2XE$dy%V^Hwpp1-lh_T_}N4he(k zG{7>6Ikx=JAA(?)aYs|U@UG_bjxTQ0#8j?Mr~E^Ra9>I^mM=HqtY7^pI7UK=OgQv zc=yZK&k(WVC6!XX%;7cN&M!JNBniTG?{%`jcxvZH{K28oCD1F7L>8?mUBZsAd)!HgH!DP?3Jy;2vT>2KGbj9WqVhv>l2jqZK1>0%ZevL-h=cZlQsP}K8`#fVI2!UZYn+I(gA%t63aPlfn5_rmO168neNps71uN?F>~E6#WC2^Id?qLB_T3ExfqBKZsAYI( z3}OxN+Pa-9YfdeP7_H)rm>xc0il%$SRMAXR>cXN~EC5ZjfF^o+ZdnX;-eYlbFd{7^REr1}? zH;YZI-)!Vmnnn2jZujNs_5lbv_N_YRjur1ApPm2b zHJL2#cLdjc;lY+JtUtyW+Xbemnbm@;xI=Thze}kSy*8EWaj+kpVMWQKNs1JnjBgWJ z72KRCW3Y{)36`27*omjjiB|VL!1a#=R<=1ID@GbkR-2gCz*-|a^W zt}x{elx$1?g%+H0tDV}BA#cuPz5Ix<{-E5>EO1u6{1AJho+>1EaTzV}z;t_f&m_N> zCqleQ{1}~_0^DGwPFdmS`0NGZ+QcPxiEDYbX&#v^%mPlWjy1QHlK4<-L?)}H)^#VF znUyB0P-{SPVbN;qB8ks|hJ^(LG+&c>_wMIWKzjYTv?@VD5J=l7I!(%3hMILjDeKj| zjKktW`Pg|S8Yr`hqzsZ&w7==qW;7I0!yb~ zN{IP!xl+cBzzMJ;YWt|xr4z}4GeF`%Mx{!K^S#?7NhOgp*3;&@m90l$sA0QG*3DWP9*L+*_}59q z`V5sJm@L@gj1?M+NVM5v0GMSO9?;R%w6ld)4&@oxaz29TS!Axnvj0)oRdy*Hai483CB?3~MV={9cGWofd z*zfKg6ED~@Ln{A83JSH8TXTsf9rdQ2z|T?8nx;8(2cx0`MmbQ>1TZs8{O&V+`h~*03}N*_&1rTH<5vX0l(Kd^V_*v^ZJZ<7bPflBj2)W%uDoBSW?iiP$sJP z#TyjYsxB8<`b&$vSiLxO*R41FTjcrjW}QbBG6!3AOAHbgk-wiPd;2Nthim1CI=Z_1 z>kpdea_g*2Xd4pVzxfw4Du0aDQ2|Xv7`hY-)ZEp@3wo)?fdSF3g@CJ&U4*|Ac$hQ7 z1n8)k>+AOr_5{_OH^w{Tg~KEiglq=E>@xDd5pc?Q+kLyD$t9(v5CDISHIcreqN0=3 zgO*Na$I^cj0OMg5z7p~Z{chkn~Q2W962M)!n74uh1?>A5K!dBo|8NE^aj3kF1>xHB)M#Vy)|E3+@glz`? z8J2#e{|AG1?3oOrJu-jKn<8;_f-oxwdilFTmUVLG&Y?`5(FJu$+&zS}1O3D4Nf_mI%|qS%b_VOq}e%_q&+&z3auGES_X75LA8A9e8-AFv;>*!Io8BN&=m z>nyGa6Ma>-^LsD%pLE$6*s@0t4UdE>#h1AQ&CL~2YI}NcFf@`muJ06kCcKZ020pSI zp)HLyOWd7De6?kBtvCJ|mnqPiADXrG&e@roL}w@!<&#taJPig8&M^(a8x{tJSPO5+ z9xW|x?B~xRQ+(#Wh|mAjA&@#wZzt&`2jD z(g)$}h~T-kk@lh6l9I~n*Wz)_1|^MU=;()^R!|xrea}b@&(;bU~{#u*Stzjol501DG*LY>YqJ*Osu9Fx))2n4}>jH?yN5OWne{wP? z0Po=xLD`K8*zAcM_)ODdc-WmC?O|~tRVX7XXA=P+QW)dp!<^TQgL5G4q0nx7StBDV z0ycxl;9vv>VHxh~)=O*v#uj^%DjWth@bq~99>5ZQmX%GtesA7;bO&d$CJKM8-BJpu#qGz~@oO~n2&{1tFv+C%bebs4-j zrVHtbsA%AU;Z_U)pu_eX4oEdh;AP)6Cte$dVX1*pPbTsDQ6|%QK zW=eeTWV|KCFVTZ7r31@}3B500qh<|4<|{yL9j%DlnU_A_e2E0fkcnR?<&ycYWKD3_ zyy(Kb3$YbRP$oLP>MfDRx1 zvyO>3;C-43aGGK`4f@n9%6~eL0QAj+8I?gd%8JM+`^92iRzaN z;E4bv>j4rK(j86xm#Lduf4;WWF~o2G91U_N00mVgOr)$LQDT>{@Jqx2%VXE$>@=Ei zAnoEY4;6su1ODMA0fv6Hb(N~o6z7ShH-HgJLwdt-=iVTtDnWZ1tS<3f?%FAP{k38M zsQVAV*%jsOk=>sozR<`*N(F$%z(TKe@09|08UJ6bgktjZ-|(@y1Tk1#7$b2wgo5*I z>rU79BERJP-+9Ot9jlcSts>6s%Sgb1PY2OLZl9;l`oAnrJf2Uy$e|scfj0d0r>CZsLL`n-xUU9Lkx%o50(SL%6f1I93*eDtJ zAwq5o;e--3*ngb0F?0_knU)2?khx zuD>TBu*US+4MNn+ALRcib*KOWH~h~BrUTIZD_J)s59Z_lXq-pz=>2U>C>-!spkzc9 z&>}+AdvmD9o@ReDJpjy64yrvT4mKW(7y>AYfk(S33H}UfHI3!_56v3@eK5QN=En2? zXWan%P^}N%p!CwJ{zp>*OoDH(_Z6!GLNNeiJfMsT8jdB$qll>g&*$&`1}Xw6#IiGB zfQz6d7{KShk@Iqw(4t8EQ&<8$z63u4qPc!{Q}b9>lHLWhUkE1u9KD-}Ae)%T` zXXSuIQ49M77Z?8M8UW6RQt9d6F#j(R74!J>rhv-lz%x=}&h2uv3I1e!JU&M7EAS?J zVvwUDl<4AEDo{c(kk7qbI_f6-k4j7hgmddf5Me4K5K~i2XMyqtIa@@CiaA2~KZ_%W zF0L{XshaKaDqzGm@XF88``L#cX8#EtS}6ilKTU5zSN!rQ69iC7!4IdBW5-FS{wtaR z(NJ;Fm4Tm)f4nN_ky5W@-Bmng1hdf3{?`1^u=~CO#(IlcAv+}}B zWj&0Lw}r{&VeDnUHCK_%&cU5Rj^z3qLV4F@aJEDZ^Hl=@Vvb*P-%=Y#{T2^-og!g+ zZC;<3Us=T+L4SWfPLcWL01qq`P&>Ykk)7r z8r9`%^))gwG&)klnLLRcX(|3dp|yzT&E^Rh7RcM-dCRDl?_|_Le>ukH8(=7UfhK%z z*jQz+jVau;4K`@HL`?N^Vjm}~3D@a3GHC!WW5I{g2x>Orsz=!pFI~DF)_Gjz`E`71 z^2WJCQhXtGtv>q8Ty%!;4q3xmIv=Vkg~}xojZbx7s%c4am33ZS;h3Y!7$X~D18V4s|4b3L~r>+4ey#9 zRx&gdjk-y7_(gm?E{>88gJvjX-qs-peL|yplU;a&@9Q#h$3L-SSLd4FgAQ$qz(ZB5)Rv$d&fA*qv z=wrZ*!!7K-7tf_#%u7UUXT*Dt9Yx1pQ)CV@6eGK8ihMsembfB82!&-f45w9@#NAPE z_5C!Zss7g`I8-XwNu;u)oBZOIJ;nVObx{Cid;rSOM*qJkQ$yu{dFMN6#~T?LDSvH( zo?QLnuuc{zgk|tvvE^I2%jB)T#k7ik+YEZ};X40<+_Qk_caZnG}|?I+EVI)L9|z;d8_bb_(f_Bu9!|O@!9uuttYB5M;ME%o#4X; zhkLjg#f{AJa=dTfuJ~(L*sAv*Zi!|%&m1uj9Ri5`48Vl0^y5o)3s(ZXei{*Fx><8@ zZGJrozqrH$7fOj0sn&ixNd4NT-NY0@`EusN>Am?tzkzKmMTGOO$n85e+f=-|N$S2M zUy$s$cmvlhjaRRvi3%&>kDY)D=ll{Talf^z=(EpVY}(?2gEvmc+LqRR*#mgtpeOV< zIo@j%RI2kLn*yC{7QJ^p->P?i_R<){8@xk(>%B!JuP?YoGV28U6sGQFM3nn2%7Wh^ z{;qb#^ItsG-b1NBV3x(VQo9bvZ0|{#us)kcit&G$H(w^~il5IBa@+K3C;vwhFMkR& z`ynKSksJPi8J?eycHZcJ>109hHy41Ki3vT;@7_~_kEy^Enh058O9;(VHXNY{+{p_V)JwZ=zYXi#!-WTQzxPMPw~Ny=PPyegmoOvZRGpGaB32Bd5Z%UW zg!ck7^GqOlOg>;<^Amc;ZDZ znoakhEmu@jDncJ&X&69e#Gg>JvmwNY!>n(AaN4+N4DEf`%fAGAmt^b{6JloLQY~Cj z3fG*JDTSlIc4m;aZt<)?S?1KcPw{e8nS(cMM@6UqA?AxSVd&1n>+{Yx5T=zE-S;(Z zrHHT4{n~>;s9%$THjGo`X-4BIQR?l~!y=eZIBMXP?U1c=YnMZu_N_3dGx{^H@DUZK z#V=w@od^0+JHBr8^CAwxpWgbv+{9uqJg56Gog*IfkD7qM#{#PBsR=v@DrO4I%go$x zc|czTWQ!X$qENwl;Tkj@bX{)vUAYS%zb6TuUD*LY_18PX*L!bm7XF%jZH?)&hqhQ! zY&8|zY9?veaY3;uLYHDXQr+*8xE(KHalM09MEuO}VZ|^Lg^HCMf4`%(m$mI%yup)K zW!jJiX$8j+gqYW?yI~5A}_*t6@wA~-Kh}xlK}Xq z{xL8g@m}B(zXW9C1U|r%)*oSZbNEM0ie}{Z`B=yZS$_)wL&e(d)k(tTuaMe2&8zH? z8H~ao7~j4Lj*iD=$jzWOc}J1#$eLTjqP=2bw~KdZ_b$<$RwfvFizxWp4MEtAdn`_R z^3x~PXhv6H`ob>G`2hGg=;y45 z6nh#g+Lw=t_@5(!YKmVR4npP8ogxd@J&XFa`w4WPQliAbNRU3e(s}(r_vRnzg6eQ~ zU4SdW2r*YU>dI_@`le#Q27dGMmsPZ6xIt_m51l`nzFR;X4h5C!B@TCNEcEqaj~CJ$ zN1@y$@xS=b7c|>B`6FOI5nq>8lWw4TWHIo2da-XD2|P_*^sip==cn3$L8W@?|5SQV zO6Ccm25-fo7ec!EXigoL5&nx8WgW0j#DPPGQW^g&5St3&BOLJCDu_#$l*|TPE%Tpu z`zQZzra>>HrCERsHihB-*JAnzfJ2KK*34H*eH0y_j~p6;983nN-_G7KmwcJzzux^0 z6CfO%oC<=1*;D9&iv_(f3gS&G@&5xMjT+IZ-sIp~lo6AYlUv!^O4{1m>J^`#yPck% z8hLmSiKbzdRiLK3S+)I_NHlk}Ka%fdczRgmQ-C2?0nOfo;$M@JV&mdM;|+a@^EC=v z!||Dx-#1(?M@-havvG2AHcNeuu%?yp`4+|ZU)1QjrwP&S$Y{Cd&`yQ^7!dg`(}U4afnp*jf-y<_oUksdcP zaMns2HKI}3HSoVbeI89N6goSrH@W9#9n>}+)nfph5(1r_oljd<0mw~-8~_7L`Q-Xx zFdDq{iful}+Ya$8w?HgITe2sj#b=QD%T3whvb|v{Ixs(Z&qd}$-U^Le zRaxS}%CcdE8n|3UHRGT(Qx;N$DjKqtPa8zO_db+j;u{-KVALA*iv4NE=0>KHp}^|j zK39Ys;13TUYC}{m_}SKrgJzoHQgenUun|W?bhWp~F`+LMeT(hc4Bh04RP$I^^xc5b z$nm%8{T#lP?`gis7a})wsaLs#LFWipujh+C+LMh0H!+<$4gJ0x8K?Cqrh~bW?=o-Q zOIZ@;pxlc+p`W_RZGX5L?YbI`H`~y8GN}kBhe00;!>K9x{AUDotKmZ#92p(GJf>;b zk;r9fRH4%%71a}rb@fnY=~rUuUw{0IY1lf(v6;y*CmZIR3bXiCivl{qVj2N+b0B2G zwR(BmtF&-95N!klKFK3+4Pf*Qdx~EYqtVcATLZ&Q$&O=()KS1h&(Ty37Q+Qau*}Qy zCG(tXiq|lSDs^;|EMNFN4#wnaT#1VsFQ^!6QtDIH8LH31^PP4oUy&8DN1;=dIxa3m zjk)LbJWJIsbCix@uf@xCXH?g^fh<&{b?ByN0l`||%I?=9QnY?elC+$Fd} zfZ!h7El6j%%;q}iWG<3PtX=0|I!&G~T2gcwxNA9N*|>#`w}bjS#EqX`9AvDfJe>_~;_3rA~h z!J6uN111FpBQucj*o#?O9(w_o&J8;o!Xc;ABjGBV0ewDRjE<10DLzae~zb+wOybB6y6GA*8#*VW5p8;Xstt7;B zk&q-3mNJT+o+XGD-tn*dz65wbhTwVM^tqeg!Eaw7yo<3UL&NeU;I)k5lKU&mWw9{SlKW}l z<)?f^whugV&#lQ96Ve;kK9V-}laXWuMG263K@GuKAj(sgg^CeJfb9LYNK&3y5HF>U ziaj4b8A1xm^-2ku$~1gr_J~~Q%cH@*BN+AO_3KU9CO4x&TLo%lwf)3s_zrsohPjHz z=$WaI@+gs$Eh&$hT#nl05cIENF58NsVem^SVU*7LzC_JN{bM9NQJ+^!TY^k!3OUUS zj(tb_${EDd;Dy#liquV4HFX|RYw14UP&l-VTo0+ir^C!`pvusb4K7=YIoa_uGJT(! z=YXnTitl_@^gfGNXaO~$Kk}8ngZJ>5ZfcTPo5sl!>085_wIzj3IA$+{XSNMxkmA9V zMlk)+-G7!L29>u7b9>McpBiN}aGCK+o*n2$!b5OR)wPBLzRNP{gm2z>Cgl-nfg|yv z=#Nz6w0AVJhYmNPef%Q#wiB@5Nk1a#b1G12^up+<1cKr|-;ZgJ-{nHlD_biD@3s$k~)}!jC@+54+u34vZ+e&6NN23LYHLTV5={ zsfXCBF}{27OG`Z*P;cjR8UmX>4)?KhnY|~+V6UW78#z@m+>E8nAizkBDJ0k<-CJjq zxk*Ot!zeKtud1cL19YNFPwM|cMYbATdv^rC1@D4?j`dJsvbH*1wg7oYE)hkO|MYvj zHMih&aZMy8my(oVE}-QC>1QVQ;LKL$o%4(bOcUifA%;+dg9MRDWyD369tF*-%%ev6 zq>e~JFGViasv)9~NYMWJcmUR1Y5ZFiyDd`z`c(e7(cX=-7$8r_%sGdoNyn{)Yip2$ zN5*f4K#n9{WDr)RNnIq6E-?-{2RX@0kXe%Kcp<&mL5EabOUGAWMz2~bX#%!h$|Uz| zi+N<9ophIfyIau8lZBZ<45s>iCLjLE{g3rV9B#V2ft%l6 zdn9ZJX48kUEWt>Dn5AzDSMWDm7A@zixCUw0;_P>p5=1>l*od@y*z!PY$$=fsWzRi} z$E7#6=ois1f&7lXyU6R{Zp$C*Ppn+&^^g0FGQj@Ov8$;J14hu%$GlFD+)R}I=Ri`s zE*~2F>o=oXsQ6~PNj;S}M>L8oi4&=BF2SWx;c6qDRE=)b)z61|q!bN>QrptWW~j~s z2R$6_ptP-ioFPP)CaJ-_VAK#Xk;&1g$26we?Vk=h6W;o*=nOk9F8uh+#_hs!{xxLP zDs9t`nRw?ZNdyy)>)F?&vdjo8_3f=hkOV_E?}6q`D!`JqPzGOGlkX9id}zS3xwIY&pZ)Eh>mIPZH772E_a}~ zW$-OAfZRC)UCwZNpNaNU_%IQF3Ly-&suI~@INkLA$u+nC33oJ?EBIiN<0np{>uX^z zD0x6N=(OLWvLCMzD9Xs$R^VOCp*B`JQY_LJQ1b{&Ght^tM~k5-5dF z%#4ASEokfr37QH&D@!gK<@d|4Z4I#e9^=q>!@#KW!+`v;i2du8I;p}~?@EI@U!5&O zo*@7u&QMkg)=pmTn-8X~Jbaxfe`tqS%|LZmZZ{n>_mRCoU7~%@J@3}g9-C$1%xQv=m(@|cpa?m~Lz5n;v+w-L4j3#u3I15a+G%{4DyEgXO z>d>Z-L8M8Ng3hN2UE56?CEiC0wzp9QvAt3ah=U0JNN@<#&ZcZ4uYGEjqFZ5{Cs8x* zSJ3`WAi8DmcJdcBV?wzS-D}qQ2~F7-d%>ovHdI8psDjx+re0?w``&7!&0x{?TjVA( z^G;dG#S~4Qn`cXAxg87B$Fm3xE~U{D1umV)nVIC+wl3j_Y$tz|AcIy^irg`=&wp6$ zH(Frj)i$G6XOX|$ain%V;o`HPrStpqpc9$+-Ahi)=D0p=*AqAn#G>aLBi8e$ZfY8C zq4Wi#ngRSZW)Uubkn*9w$U=)eUr@C-_`{QLrAJK7)?KY^R(S^~KRM3ndn zs`ZkN^~P}O4h!58D|Oz#4+PJDZugW+dX2VyiikpI4xNkom(0`7@wX1iHgTo|5Tcdr{oXkZb4ewioWt3AhV_ zO;V>Qxf9Ax>QFHaEiq}UCGY4`_T*PeQ*Nxh$pd%cpC79qQg}5Y8+6=$?h=w7MRG5a zLN4s8l?d%8cJpk)fxf?2my-`19$7=+_p*Rr@&XTkbg8YfVX-BK!la zhXU<`d^u4ZV5iG4ivL_hIrp8FEaz^81zVwov^CdyJ@Gt07Cxwc$w)MFYELY6@+Kt_ z0ihv6ytUmtgwTEOKv$G`kY z5Dk6Fy$qiS@0avdd9k6Mq-q`>UG2Rs;j23i6jSHVd$PYmU1Q9@(79O8RXpA-i~;rx zM3idHUTHu*4RKbyyXkB9MdMtN&@14xI`ks&9fj%Arh`skFHFT8V(C5Ccg!~;Q6FK7 zC#8H+0*Xv1H4sAj^ATq4^Gd)n%VuTahfl-diB}gaa{2N@*CZwLaVVBgkjKWyjVK23 zlt~8;F_Q|C;@GeCjZ;_C?l|6EQEgXB^@NZux9@Y1&g!a`jtv-Z(mr3MPw3ouip-mN zdjDuB2I6pg!278@E=71>!@`P;O~%YcCbJp(VJ8LJQS!K9d|D=o>T>kKu^8_HI)6?q zr9X65rMJv_DEz}Fa~eVby#9g;v{j03b|p0f9jB6G)Q|;&E~HF=W9AOCsY$VmH zZ6`I})1P9#VJyA=VK)qTfNjw13@LF@qwNKZPxINqHJI*LBtngF!RIv2fC zV=Lx$!e*u|F*%`^1kEX{QubvZxT(?F1V}gb@HY;jm%A;K+)MUJ z7AJ^1s#o$quhbtCyYx~Y{aBV^4IXYK02sE1G4eEz@sSF7;9%Q>2#-7gUUuBfcb7Xo z7371lbPs#E*IKu2?beJ8;vm1v!gWU(FKt!?RHFgRw=0gO06oOGF$DS3J#U94{YT&; zHX1KQ?~vW%Zf8Y?*;A|UzE>u@aed+SMYF1*RwQu^89B)Nf!O#=C=xGbU#9`cdY|!{ z=Vlu9m0b!Fmll2f&$twl)4-+=K3@)_VR%v%w(l!gLUnpP2wM`yZ|mgI`8jAm#Qr-V z6uzqp@rRuQ!Og^Jc<~Zy?RK5K%SxlX%fZ)-Jb$bul@5Y3G&K4YOaYcs>jWKjt&WLigoXl1 zJVRxEvh{@qfwc|luF!?L%-Fapzm(WHr>!3F03p$=IPzNw1EtW*L@jzw_jkKLgM*q; z5e>yI(Ea9WJqGn8W9fhT5_6w+>qDL-t~Xu_F8L6>YrDt#ua`8LoE5H}gbc9#`$OS5 zhEZ-@p1*k&iLwYd{un`U(cKOh!doK8v zz0~E6>FHl4!PJ+PaMpZp%yE>qKFQu(ygk?|tQ$mEVRd9^U1UtsDe)aOQ~Q>^=?Oy}=-JZ2-rgMlK&|LM4CU+QGT#1z3vdz~&-?Yd3Q3lr8O%vR-QZ4%T4)Hb1 z`#MEBT&Y*Kg6$qxN>GQ?$Dacq14K?fC5Uz(cF*a!P24QMtm@{}qwlWEFBwneE!EO4 zA!joY5b3Ay&B(tJz13|a3lYnGbFaIs_oedhIr2}BgzRQCU(IF){XPYqXheVAW?vGa zhW>zH^BL;%;=8zWT1cv`H5QWMjKLKPhtlm#XK+B$B?8`*T#9XEMow+|p|h>u`L);H zsJHtG;bd9OCHt7;8S1nW#V!BjWe!Ff%Jvb4=;Rk|k+^SZziabQ-&eM~OHQ~gKiM!Q zT3O0rMp^K#nOmkaP@Gsbfeet)4tK^8qX6JS-h#T+oy(v%B>kW#fotFM<39vER|Zfq z+R@w4#qI5npv|P2X?Ifnz#F7Rp?Y`{Oe-pGYMiY63nI}r(FIS7KwzshyEAxd`8G<> zd4jikh>SVFW`(TfDMNH1$PmoEe!HgVy<5+t<9;bmHG)m9(lX(UcADIDpv>3q#ce3q zK+wF!Ab*tdj&>sg0b=N zHT9~aw5qa6f8?!JJMDdBA^>@0(1a3mE095`-jx8u%94s&NI6Hw@+bb?0?{6W(+qo# zO)f`-N>(uK19U#D)a%fN`h9$ykh#5Xl2sOztG(cBUF^mwp2cK54?=(=970_Ri5CH{l(?K}atWTsxM=wh}VRc-=+~Soi zs@b7?(4uP)cFfcGiH>pJ_rlptRr}m&Lg~kcfAp-S=0o5(cOmt6;Sa(6?^%%FyK#q8 z{r;P^*Ts4dZH|Hb-hYm%q*;hq$;pH&rruLsNmJ`J63iW0RzfE79uGR~S9J}ViFTkH@B?(l1EyirNNrCZQqF^i11@fMBFOfm@q&%_W zg%~UsSPGV4Jl=h$^Zu`plRu|q?doz9tlbU@M7}+z#m9fHUDLVd-MfbbljvGj2cFD3 zGJpJFox!-H3Qus+1crVTw#{3Knh$SqOV7qw_?rz#arhC2qF_vBe`|C{zYg4hRWBDY zd==RfY@49L8DZt!DTrH--hA0ha*f_fSQ{Py_&Z!h-1~&0?2T#4hfDKU?6duzi0FFj zQc|mu;*)kX0{niXHJa?C?Ob8OtEkirmrlt+iu*4dcakGArp~4P(2IZmcoi;EbiXur zg!6h@70zP^XFq|T$68+e&HyHRJp1JjyN-@l4aQkPtbgdzz{^h@BI!w}e^5bu*e>{I z2SH2=HMmgM?p0aN`u0qDzD@0kqwR{1BFZPOaN8zyN&UV>+Z0%p(Faobj6jx1WwXVR z0D>x(6j4&Y*U7bR=PbL+8LboJ;C_*a5)E z5)799qB3CPx2JgS%|{;l^>B*yd)n)8(1-U& zW$XrZy)eHna>8`bL8Zg!Htr#`zd+Kyw+mgnGjE%r0Z*|ieTTM3P|Wz8dQZ~ZcbbL! z+tT*Bkm&WQQRZs=tkl_a9D`1t1ove?&FL2Ls=z*eXg`dP0LU@y@@)#%l;Y&_hpZn~ zz~3zK>{qC-m6Z4^ijd-%8y@5|J}iKua_}8WvO>&X4#LzD27RcGl?@?!yAw6AoI^0E zXC#BYyWEy6&+{tavD)5a83XQXcZFEtI*qDeiw=r%mSYq;9$k3vw03RtW{V8g!B(-? zXA|@%SPQ`n-()*4akEirw#`uAj=gF!)tbm7TuU^MLllm23rthp=Jq>v6I-DInXDBP zUMAKem8Z|Nwwref%MUH^cfaOx!>eZH$h{n|oNT$gCu%#SVbdt2RgCS42<3$}=}oY^ zy$B+a{%i2i>t)wYzOI}SGxUduCsWwGj#Kgz+6WZ&D-eqVqU5Wh4`SLk5R+b4s)&_{ zDIGoER@CZx@VMlZ+0mD+ca9NAz_6f<(m;BUY^C}nG%FG*nB){u zbl}vkGqN9>(mx@f{;LmTD1x~u!gJNZ4j0|ncLpL+3XJ*uU8j99!bhsp7+#VH} z5Bo(#gr}FpI}!G1$2^3Df(_ujXW^YIw+qFFQ$Zei(T!ZW%kbrSu@osg4T$-Wv_qsS zlIQ-*X1;uW$oe_uNv92H^ISS)a$gSChf1xHl&x$#f!1&MaXC2k4W^pOe36 z>@7`_4MciB>;E+|skw59v)3QnCJe?&5wG^-!R#VXcv36#9g_FSSs~0P8VdI@hM~Y6WJt@Z?}bztIfg&O3>%;q4zvC(%xOXDZJ!IE z>hd;V+=Tzg=|&EWrJLwJ-tm!pU(t|Gc%!m8q?e3DlN^>@ift|faS3(x85kb63AzkptnTxARKE}i6&}UHIf0Lp9l>S( zZ#F{y50W~brN(P}*;ms{y3-?0Ay|v1URD_3x}}|+w*Y)5p4{H3FP<&SZ*kCAnEm@b z#7svIRP2iw3p-1-XL*;~+L%AKo6k18SE*YcA5Rbg_cInP4B-ox8E?cvzONk5SNC7M z1A_30!Dqlt^=7jJ$>v?9l8=DZgXPg$y{7X(X8k6}%aCuBvFI{a$6rfWy5JgCWA?!6vAys%V$eNt)@w|o}>Pf=igQv}<%l;q2m zxh*ENj|}H)v>;?bFSq6cbCDa8j^rO1ZAAqfodV8c2t`aiz#Uhk{8!_ymHrnr>#k3% z=X|MAKLI@R0S&}{S|YI}yexe+87zGpyl=!^29F;M8Lg#0tG_-G1uoc5+cd*x9kf~%2j z7s@7Q-!ON4MP4sEiM%#m)eTy&&?^%{ySSn@9-z{z1Y#eO$V0@19JqBUO4aEea+e`? zuyQM6IC2^_&{NYx)&;au%O5=oFBz+~-`RWI8>29@QbZho6?fO92-8va7O`@(Y~UC^ zYSVG^7Bb^xh5qCtqMKd^Hx>w_ett|pNGa#Ysc|H;?+6--^IDHOXl5O(vtZC^Iwxp( znBktS7qX2Ks;wjGdUk{xWK6EN5?*9!Cpw#acwaM?5WE%By-Z}@-T|%rC5VnZ`S9R( zitCi=v+qHaw`c{{7c&&M*Pmp|&T0{}58Bf4z$}+|xMU>gm?u8ut272mY2< z?#`CvmplSrK}Ubfw-QmaZ}pb|DW8otk6BL6B1bNrf{pA*PC@Oxq&WN?tvm^=z%B|e z7TuU6*SARCEx|;BrIKQs`3S70P2lCL!?W9$5k$Ub3#>p78FswAd%?^8{3geNZ)X_W z0|ZIMxZ!iJ1c)=nZw+VV{yx;giJbUC-TKT-s|-`9xlB`EJ2`Is>nkJa8~qBd4d>V2`)& z9p1nea>XHSlcQ6ks5zxSZ+jHLeG)<7K4-q%o%=F^D)3&d{kq@VR_;@l&V{S}feuR> zP8`0&fSn)ad*vWfCOikrDY!C;5yVTAqpxX?8Y5oqL0@PH$Jb&?m_*Tc+3s`K-h)Ha zM4RE|gFK?FoSB^oR5ypQ!7 zxJv1cLc$pKCp&Zq?|O}ar$--B%b z&-#Wz4IK2_LJp2&tKS>QBV)!8j26}&x6|l)%^YTwgQBJ0ZXBMsjQ$Lw=Fi7ZkzhTt z^-_s64-e^)258*d#0!9yQ|?lx=&+u3>j}T9e^sIh;GM$OZ*dy`9m7)Nbzxu*FRI zAoxuyu|&!j2s)Bni8QVaZSL-lTho3W`@x`P!|{2K;w`fdY1g%NdTuTZ($RYl0@VO` zu>$;DD zCk(I9y16026z80lM&SvDY(lPnw3U6&zsFxyUevOtk2a0FyeX*0kg`=z(nE~9esJMv zWlW*wC+$!NlJ|!$?L7dfSNFW(y2i%h&4$LJTr7B``$lnk1;c;udcg*cuyyKm;y4@g zMFI&p;&)Lut?tQpj0z{qUcakYAsx}@#}P_9$Y1ZxKlZhp-yptUWV?&n2*%yDgKNU! z>wckc80#b;my9QQwnRyBnt^Bxt8>zg(YcvM4!o#z4`-;Esj%q_PN(3^>vD_K-o3^d z7J!Vxj$D!$td`%mz@%&@FMadajujGQz5aP!tClWNM4BvY<}^N%?#Uk}=o#h46)8Wu zm33d87F%v=2x+rgjoZA>IMXh4ONxZ*6xiK&G>#lV@JPEnG6d>(Az)^6eP5)|0H*UN zKWB3qGHdScn|**>o?NhV<*+sjjWE_Pa}v?*ddwkZWh#NM8n7eb**RlCROxYKMP2GU z8U*_A^Cf{wK<^Erf+br5ErW{q@tfo~mBC)i1a73%e^)*lF4-LN0-fVu45{Mp%J=U$ zZ!ZJPWaZ^0O-v}6@#ApKnR0Jc!0`@?dU|>vpbx?@MZ^>p6MAXC@@S9LwNeSjR1k0? zwkwgGCJ7~OR7Bi13zGK=cX^A;u`!a@8Ij)T>p-QHPz^>49|}16RwNahKYSFrHXd#k z%C#EfIRA*&H$v_$nDFW|q)@g6xaet zfAusxceAXrG8HZ!hfb-Wx*B6*V&eGtIP-R4bCWfO0v;az@peu*<=eNgrluwv2dZyA zk`hfu{@E(mpy%7xRD?#S&z~4qiliibRpUDz+IPbeSXe} zPG%`5QS|t6Locr+XwH>IbxO7j^g(=TQ#989-tLXy-!*O5X?%^0L?9LR#Xa|V|3B~! zZGiB@y4&BD@tZzJWad^@VO7GF)!z6njFQ>Hf5~B1S22Y~q@VK9CsG6{Q?x&lKlp4# zaD8(oMw17|$!g~qQV?0`w4unmWyj^vW*;UQ{R2o<4}LZ$_{%*>!X4H_AVC>>Rf{R$ z^x554!lDIRtSR}@xsY5qB4XmA1fzJ5ES`cJD_FVC50FaX{{W0Vf2FW*IEEV*itj9w zhnW9W2^ISmd@`FEWhsvh?0_Q1ifcwXBI+!BS{ReX# z4IA?>cFe$FhTtw8f?#xN{Ph!`C6uzMdsF`}HwPiU#QgsSxUq2)77apj>f5^#kecr! zzSU~~JEi|1!rmcbPeFz%3)R|E#CFO85!t^S!pwbrjL6}U31|2Z2C6^g5klBO991J* z_D>0a%g6%}kSq_7WwIfLGUtCNyniusAM*a;(Og}mjOO(r`v0f~iPJv-QTZJbk<|Z7 z9^k*Axz2gxXkt1@;wTOkGMHWc92*=-zW+ex#7Jd@5WgBi+1T0jwYnWaI{ZXTiM~Oa zEyv8Ae1bG@^1N7$_`7??v30hzP~rU}$2%BgX^6=EZ2K_=4`r;^nExTmO%`N;)5yti zQM?*t|1hvKkP(LSXx{j!O9fB|{x4qb==KlQS0uxDD+*Z|F{BTKkP#l<{|x4F*r)gp zSq?e>LF+#B?4WDPKw`siG55d7oZ^E2riSWP^w$5K^USq>t;}%>$_wT{-~MNutsM*n ziX@<@|6Rlo(D*+q^V!*3asfh>KvBLUgZ#i+ojadbbDnqie*v{ao_~GY_lLxrgH5`r;_;6-pJe{RhZ++{igS2FWegD~Yb_gQwILR;mg|8Ode4UyjK>gpQT{G*HR>Hm)|$~x1F z{cGj^v1lZRU)Zfm>Rn5$23Kh zG@8zL|Ay0p`I2S-ZW#>hBScau3xAg<^)Km~o%zYpw2XBZ=Rb5^edk}esl_`fX^7Q| zxl%dLpuEq+@^<)QJ?&XoKZPRm9x5pQ&WaHg)Xs4BK)HP^6{JmY+9*uu;lcVUf6(uH~UI147g} zGC#KguaWp2cR=YS&8;fZjim#Pp~5yiB+!)=pMv^42^ClQPpUYs`x!^f|ElHOSx1pQ zTY+85M>lenW4=l%u#;S1@4Y=FjqI<~LW-eNh2i}iD6V7D#J^pux8uCRVXMtZjcNOW z1lR7o%3P}}WBhe#WVLS1m^;h3(Qo^<_PS8unH;ViV_BNCR#5ordJ5#HAqaZtKwAE8 zJb#j6G!6G{4VCWgkHS`(eYSBD0rVE(pdMp^Cf=^SC%J3=R8g5;(x?_3^5e$t?YBYW>IeY|F zQ|N@r`qwK?ep+aX=MWM1Gp;fPwoiQpIIxS*d{OT7%qmwlMd0fGginYw>Hy7=JnOCe zV3SZKPemU5UB`?mSYm6p+2r(MsVY7mUEw}G+>%nt(iVKF37(b?N>xsB($vupvtDv{ zLuaTq@kZ~(xxb^|f*yU@ahQMZK4dj;W^bh>=?-wyBQK?_^s|RJq(EWADnR@T&TguT zzvbpXRP0@F@0xUh-Q2bz9tDWP!otTV>;?7ZF#IccDhtOZ=O^M`%9vo^_~VPpE~qZ+ zr*~IqMa{aHiXkWt)Q*`O&~QKYwsMczk5$rZ#HWJE@6cUxDz9|5o0sNYS&Z z6mlC_9c$Y-;JMbJs2Ug~AedqLl0tj0)C_XKQi#HklSs?h6B3h0(7g**?tGQY-bBT% zRj8f7>{=&JLUxp=mYYnKD8BfVF@%}l9>0EQ{@OeRpFbAaBTiy(#_CP@nyA&VV5{Q& z6J}5qlbKvM3w6ebrc3!sJ2X6^GzJ0SiN5@#MREW zf20n4ifEut@fZUUspy1ZuaGa`eS7FHx2jd=~K8P0dJAi?1Xka_ike z@4h5ceghpoFvu#}AIK}9`eCRPd3u!DyXyxZFn`tUqGY=iG3|rvAmm_oS;h#nS z1|V)NjVt_R^QnF$++;CNN*4Zmov>D>La{UW8Am-d6KTJp$Ii1)0ctRVq$ecXj*gh z23UbEeHYHgsR4gnx+mvGKN!Ky4TX~KiQIMbGt`7PFc7_UkQ20HFfsQEbq}`oJ75YH z;!2|79)8PY@Can{|B29WY@4E9ChoE6V@>>h+V~nF--ddjSW-NYTkb|)rG_!G%?qug z*wDg-+H^|DZA)=G=5x+j(R@wnFB}!Zy}qzowBv#byJWRfFiRgh!z3m!k=msCXwT6c zms*QST9P5zUWCZQZ-)@jjZa*^yG~x;wF$(Ppv4uGR%AzAkN!>GDXld^Rv%S1 z|9pBtdXs7-l2+uXQ&)G9lPl+sYq+Jdj@lq}WpJ|036n-UyH+)3?-`y|^CyS%wKL`- zR-Lwv9GfLvs^>P4l+HwhA6`P2ELJV<*p0t!)+l|fFv!E`yTDU9bC<0-37gxCV+oes zN-N1h8oK24KAj%<#+RiU&IzwbXgURzrE-X?re3dVuoioW#nw*UBXHx^I9)!glEax7 znyOwXqnJ-YPNA$W5HnZ#`i;)z^w!2aBSU`Z6*Z37#MP@%Q#-`Z9%SpIhTkO)8gj9kXc=D~(WaqBs*Wv)upbdsAj(~`Po zD`u#<b8uov2lg7M9JAxv-)}_o=wF9)aWa8%DZrV@3}R7OY-C- zZ9VBdLMhe~|EekWTzRj~RcZw%{V1W6wgQp-vGzh;?c z_$y^taBAjGdnNT#29J+>#R`4KJ8Gl98&mhl zjK)`zN_{Fq%bDPfkE)(~F@Hv#!IZ6P`E1ZoYjLl4sT-73jXAjAu zwBsSADc|)HQ380unNaj40+Y_Hng(`*NB4y~W-EtLOQIvhKlrBl1&^XeW6m_Z1M&Fe z^CJc@@7F&*iZ&^9kC?(0YHc^2X0<5O{Ed0~OGxRfs| z$X~Q6q=jMGe{r$TlNcYLh-ai~&4pK|>y>eRVZW!}dcRliZd_SKs(Wfk=qt1H&}O`N z&~40KP}GN<#4XKEQx(P>?c6Iwcnr5KJJnVU*U=WojU^kZn{v<|q1UI{B@;SK*Kjx`zjgD~dM}HF4a+ zbfZT>n#s&Y0=XHBdmC+Pg&>FNY@bT0grhIUuUiN9hWd}W$2RmKdS8-m7KCftatRyV zd(CmxzqQS5%>{$??$6lm>~Pa}Jkg?0tI0L`?uynb3k6%1l3%{yxpJZu+BnK^?x9?2OQBB^@D^`zM^`5jK3cbN?2->S z2jK{C!IzaegeC5bJD;EQ7zdFc_&tV6`(6{V&o$r7jJd3=eF|`1LogvaMRltym5O4mLV*X1 zH=xz}D1?yoX`v{DqI z+-dAbb36^nwOMGhZ+y)|Gh5Y(D!G8gXueY-!pNn$BrQ$yc|6-x8%etfjUm?xti>IK zeF#%O#J5=EoC^S34`wcfV1aVjdoJxKKAPz?CAxcg^yqwn@#w%9m?(7Nnrqc?soJ>_ zgQ|v@iE-%IUMLf>=*nMHL2~PCNO!3o)Z>ldr!&o?q5RN(AL;yeD;NK-t-M=`B^b>{ zH8~|>_SEt?QnE{E)pz^+*WijjnXSH_aZ__)sBoBsLeH_2RFFQpYhB|s4`z3fd)T-R zTTVbDpSERqbst>RP-68cGa*_+8AT3rvPm|zD2xaWSl_*Df=#l10R3Al!K5Mj1<G-@{)i^KSD=0>e#8&f?q$0CVr~&`3J_Mp&5&91w+S?-!&>gF-U$}LC5i< zg*{tRAtSC}Ov$R2sHj3;1rt8*pRgYje)5xN;qu`xyFlL=zld2ef>+qxDOE}mhy2r2 zum!tu_t^lUQ+}6>v!wL{OkxILQ~GuxPcq8|m(0@hDGBjUqTKNv!amn+Qhw%cNKB5| z`n@;1xkVayc#hs1JUb1gplDI1wM5xbMCSQT+!v~5H$nE=Gwl$ri_B1lf*3`vfVZJI zU>^3;n2h+0Yk1U7EWZ!-H?>+rgKrL@{cxmsjZBFPu9Ex}Wp^ykr!#_jhmTt>Gt#ni z$&NFp9}AR?VjHe`xZL%2GVwd^k&3I3TiSu(Ro z41ov%1}pHt*ATm+yV{dx4vA>0N5K_*&Cb7%ztE;8qKg0ZixL0JFK#J=fA^UbX%mKX zmmm-QBPkfquqMhzCoYt;G^Iz4yY~czF2(m6S1E@+Ol~Q`ummw$&IW_5OsOVR$?8+a z8k(dDUi={IEtnRC0H-=54F)}3sYnJI2i@QtW!3oflZWq>R;uwRG6DS{tmcyQar!%9 zc><(YTalesIMeqytLFeS5IlTBVUxKy6yP1Q?9s?(iAMOJY+8U2WX?^Oq^Jp%jt|=Vgb5sG_^58^Na2LTB0dz*CBk`rp zV3dUqk7#EFDSP7=S&XzUK=mXgD-y;uF!v6KqHv;YI03n{MQqRF2kK;^+z)LJi6vo} z{Go)-?-C8fD;J{V-ZBzGM}JjIy(c+M^K>t~_^DjhVm)20`<9UBq%i4zoxJrj7498_ zVqb8tKiRDs)Ss~YnMPx^(RZ)rPjenKx6 zd-C5!t)lhI@8O&t#@z~l2H?2C6Q~B$xzWH4+ zvXD%s$n%xt$sOn@U*^JEr!g1i|M64{ConN}`V~_Wk>3mKTWJ@lwTRPZ)=kIdk>iZ> zAksz?%(fkdEICNpeMZ*1CFa6tD5|U^8dSo`5m~%X{WlBXVxRmh!b_TqH~s6{g;tnE z%EE%4fl1=C3+rT_f}~Ow{x8pLcllUVv{8R0Z!&!M#q#N*8tH&Ia{ksjk&jQGNT_)H zC@E?5h^i1;g~-B6QDiS+kIzUVHx_XfG~e+Cn(9BhVI5hMoadRA-`JO~@LkCe_H!`SA>(M$+KkX-;rm?cDdD)?hoj0Ot_= z8Ui(&3bqbHa+{~N_JG<&LvdDcj`{?)at+otc6|kYP^;MJ@q;2KE1Wxs$*z!)S4y@$ z22pZxDq5uO7QpIG*f@=wQKYw(D9zwuCj`$dC`uoEyz7v$*T;blw+(RbUNwjxkGId6 zVh~f+Wf&d3PWEHP$tvYkoi~+|397kejtlh{u?*u?*J;zAu4afRtb#sR;BZWeJzi>| zAI(eRFf4t4e?3K#P#f=FP}q)kN=)l{TTq|9RWzVpU6eDA4JHIM=O?nY1erm41)!c^ z<2HG(VvqID8S!+c!tIwYs%uB>{2?|!JW&}s6qrN@~jFDxF#Bu zXx54*rd+$2T$D-ezCx*CQ3lKM$lraiW=(U{J(UWo1dvWKe43O5c@sQk)`XRpB0zf1 z@Qt0}J~6#jld^%m!ljdM>BKez9=@C}10;PRH(kBL$m`-E6$B*cNJ#u6G_8V!f`*XE ztVln)Ahxy~C+-C$^7`qGkB9AC`@FEtw845zrDW;7(MHtbCWr174HCwVz>8XSM>*uR zyRSEV-_oMi*M;^EA`FjaQ`CQn=XpY5-1JieXH)i+@bvER=xcuUw33n$_b2e$(V0@0 zMvcrOg&9T_wIkft7e7|!7m_f2Z_qo*!s$~ZVu`&zo#s64q3@!JT4Pxpf%Wu(s8grv z)Iw2636^40R)$mW3W7)5y|drI!*t3CM-%~T5<0mR=IsE8euTLn6#uaS$Nto&oE9m!*hyIL~R>uCiRxUl@l^R*Ni=ms13?b%EA?6Rk8!2-W&lBe`7&m{TCmXXWClWrM zEmukRB`*E3ch<|6G#=1^S)0z4OULbSuzgKX(eaZNN^$Uapo(~$LcK^!_X3+M3-enV1; zp=02Zq(>|cqpe-&SddtyFy-ZX^1A2AwqTCk=$L~+q;QP`A;Few-=d(7+I{X_Go@uv zTHr)dSUv!pW`xx7d54zz4_g9)&q-mn?tT*kf}G28-_x(FNpf6!JH~KT_3-Oa+kLJ~ zV^Vi%S8hGy-m|ztCIH*GXUZDL7mWk@18yo1w^YYsFsL=r^*VfydWAcXDV9}~4DSNN zT~~51E5Sydj`RXgb_(;S3`3p(QhfJ>TElXc*lv|V`_^+nTPG^wQz7oxQk@i|`v<^5UYFxrN1NHb_Oy zb6axppCT8e@)+<1t9kIfJeC=Q-NHP_;}B#U8pdJVU~Z*!mcLP%_ILe;ki(7 ztiV9L5~d&=`UnXvm3(<(OK$PCocKpa(X6?ejJs_=`2^B5By1eJMJkonD&o}C7vc|C z$5e$S)Z1tdu{0=5Q9!M=232pIyT$u~O@?-jy3f5eL z|2Bu2!G_x(qfK zR+5$W&P>aW&0WZcM=gtnEC_&UJqF`=p$sIr!PQ-s_U4E@6+d|R?YuMTkMBzoKX z9D=;Tn3k{pKEcK&FIlbZ`?QloL{EW~ZV2%OHTm+gP`AT9TA%Q2_}9vh*1sxdW~*cz z^Xv^#Anas(cO{d!qR+x(<9vJK)e~31(mHxvU%a#?wC(8NMNJvKxRfT*M>qFrIX78$ zny8IcoI~j_tW|Qvbwk=)q?fNx5;pPm*F`}f1FjRk>t2>7ydFtPV}c_pfP&BqdK}3| zBZWqC9wlL(Om{{ujWo*Nd|XcHxCKAh5p9kd%i^q}^GO!-JnEokj{W0l?9H0c=~#cE3M z5~!Tu{leDIB09@Zm^a3k*CIz5SNsP?>y1XDZmk{cB{+`MJ_+yb_PP7>jymQbC&<_& zjwSqghz73^#`KmT8PQMBjR%&1D2emz^Hfg-nQFLLKaE>h&|Wy{lQ2WpV(e(Ae6ep4 z$&)x4q*Q@YO=15!JSp*~wO)2&p}5I|FY~mdf%U3U+7Xk&jsr|zlB8Io1PL*~!+ALU zixVx+lbs|0X{4JEq9?p_tz4^mIK-Gmxj2J$wOY~#Rt>=Fe$ACOhJ;+V6Ta*(k(>k4 znJagTs)IJ+#@;CzpTW3)KrxGjT z*aifK!jiWSBZHRM9NrJ{3O&2&=5{74o)a{e-Q8R!W@IflCzAz=`hQ!X-t8Sl4cO=T zv{(}y!M2R?yE7xms=a1BJ$b@Z-(LN~iq`~=V|y!mS}XiT?oMHdyfr_R=Ocy8V^-q? z%#^dQ5_M#bBVR9}OHj<+KwVUZIz7%Q-4JD{C|1h|$Dx0+3q!nqZ58s%SJ5Z4UWA-R zPD8q8rdd(S^n)?=T$*;_;O_1ag4^I8Ah=s_9b5-@ z2^QSl3GVLh?(V@I5}W{moFRKZ&-cFPto8lj2dk&M@9L`R>bkD((r3+vVGWqf)Nk)=Pw1_y*1*D#wHYz={NK(9 z5gys2Yb!XG_FL$Zb}p_T?9)cNBA*pcobI(kHCSJmA4sZYc_!5W^R0=?r5w1>{Gu;W zLxQtzai)2T)itnTXVi+Sizl)An@GhWFBZKXqCaPAz-$*->0?}c#3e8Y24-_JLgIyh z(fMeL4Adt9R8WnseIl;n`8f=tQ(*DT2p{goo;j&_egFEi zIxFY3(d7m5vlRG}!#nABxrR}Hqqu>$ySUe&GCJ~f`7JtPujpC>imizvyAr0|^^GIH zRIA>3TW`jLtGo=!!*yLg)=i0P23d@@V{iT!hqtckz+|G8o)9a_w^tIue4G=O6>Mj8 z*Zhl`VH^-1^yAl`%-z`ieaen zQ+ooC5m>F9g2w!l@sTmDCcM@y9aHk$YyxSv$i+3vjS7JDh9tJO&VPGx+IB%LS*VK;P`fA zdb!_ZPIUN{In|mwqsAI#5+5|*tE2><)J5`i54yd*?=^Yo-$^T)F4`rt4BUj?voWT6 zIvd|kazY0skitBA9!Ca#@Ux%Nh3}?aJR$IRYd~rXW_G^Q+WA!nO-r>N|CNZnRyDeN z3+ayuw=f-W(1U&br{lAEg3xZJNA7YW(&|!$@yHTCoW#@mOfH>dVHxqk!B}-!I%3J0 zb!=$9_}^&)}S?1O;RO?+3ydBs`#v~#D~?s_`hunYZT@=pkXY0xn;catg80}cgm zn`1`ncIm$L|JaQEeYl`BXEkJ+sF1kLjEaA^J0Otv5ogeXLc3DOw*G#LOlDg6g({sF z#d^96a@spKSSJli?J+0i*c322b~7?L)pIgWFv8=7y4u=m*bIl0k|JDKDxm;EhA^p` zpisR!^5%h<+t`S#H=mYy;{^%iO1^-}byDxyPN~5fHbDsa!B398rYn}Hh7LqbjVHdM zdirwdAqanIz;4c7l4JGdgG~l-!6G(CKgzWjj#9PKxadIq&lI(~Q9Jkr7iToyN1ikr zX80&dG9*oE2BP6Vl6Q?{zj4EY8rVs6z&w__9snwG(i0aJ|G`$2w-^vp`ZzSa;MHda|=U?U$WSK9QNr}p*T5#e__La9bXq$WHu2RTy**+(?t;z#P+B+-vB zoHm)cksmMhTiEw9S=NQ5zhA)&Go{M^VNiSCqTK9_vnUs%V~Coi0hbT_g5V@8H0HCc z@&$(I0MRN5InSz!5m$4ARI{S@#TMg^@YLuzX)8u8A8$SH!V71iOiPSJ-^O+*t}Mb( zi#UJ32Ci~RZ$;*ZU0i%qPbf6tK-7KGq31Gpk>`3vD^RC6Fn4x(vdJ7eM+O#rMd3C= zce;j5J%R`n0g+7o#}fP^Ei}=1AJY%=j!{B--rBqKmf`ZIvQZxjTObkzWeZ}6VIwSt zJ<(1LF{6l`V09gFuN89F0hMODO++m*_;O+RW{uVBte}j+!&=P6>e)xKvgV&I+e)>+ zeOE1lr#BCE^Qwt-+)<-MTC2Sb>r9_xjJ&0DxF0pF-anPI3fZ~GfdCt|*>joInO@NS zFeZ7-zfhV1A3c$psm%e^^Sw4YeF5LYOX=V`n4xS0Yrr>Hn@5&W7n`VILP%C+FLG7Z z`}LPw8=|c`N$MHMdi}Q z*%`wi56Y-XF%{03Mh1hzFmGEGJ+EjEF8(w?_%wfAC4Qh$2eC)gN6@Cii8~>=UeEzz zEY<<{Z_GEN_?8bTYU#JYP?Ey7qMbE3*7pI#ksPBSM*!eG60XP;;iy5}+LdQ?uZJ%v zTUjp$Ruc>N0DFIs!W>k@jf_ zot%Q4sJUK>D6ZC%d>`DdTxe}pQ$v`MIsK@AFf@m5R_O)`k+L~khBvzOOLDleQatwIpAy^ z>X|D*o8FQW{C4D;#v#1M$I&=C=WQ{zeeSYvWVVP*T)#<*Bt zoXRr9Z7?V;gSx_;K}rp&BzezXzPjfO1=z0N16n|QaAFXHygEGMv2&mLF)JY9ekHp9);j_aXB;j6)@#uI(lzJfKl^Pq{Jae@! zWbInZWS~FfrYXuW79kDH2z^+?y?Zg=zoPQ_uAd-1DIdDLh>*dt9QI6Pnc-rgs(9By zPq58f5a8;LJH&c_`nm)arH+)f8oK&;@O_nbKQ`34&DF+OvXx%+u!hL13o?8WQ%3J- zPC%xSIR4_)juQx)U0c61T8ot8jWH=oc{5PYiK*4XR%10%%CE$1tU^Yv;4+tj$s0iE z8?Ta5xt~=x_7#ybm66xEPoY=ND9bdstlt5`u3l-=NjF20Mv+7|GajyS7k36Xa$k(-N7{lgo7Fc z*B9if=*d1@hWAY*V&Cn0QkM{Ja%mhEYMSxHM|S)iYzTUdV6Iy5=!QQeBl8`TP%zqs z-%DWJKN-d+w9f;CGZj8yDNHmhdLZn`po1T5mE9YM=isPN8!s_ks`+7W)Hbh*6XZ|T z&{*DhXYBD?4Iddb^*v`IJtub4GDf{Ms~K|7$xSYCGtl#v-s}#QQF4&=S$1AW9+!8d zT$Z~&DVaFpU@!^O3IppL6>dl#h^<=n9TY$xFeiFcncI|qE=i^`NS@qYOYzjEFH*^* z0g*bCylo$ZQJNfgKha~I{q?&=0EMOqPl8Axao=?Vl72Pb=X2u>XWI#JmTq{d=N1#zQl0u!vTiOvJw+soWr!?pv}-PM^W>7 zh=hE0xZlsXtXzCyTJ=Ve6{)Oz7oXmr1l_a@k4tN{hUb+uXS&l5fAzpk*BH*d`MF#_ z8hG8I!VCH^&JX`QVXqL=Pfo_dVt^;RDjrXxP9LgV3U2PF%y+7J8i=NmbUNOrNmU!_8fQ~8sp$eGYpN6)5r#|vSFk|?B+SrM3olquIF2>5k>1}(gc}rrW3ssXqOex9 zshJAsIfXZ_Z=tCqE;Y>`5m*0~R?}xyFD+Zsh}HLtkEh6ZW(lO#cuxpYIAP^Gic6k- zxE&zQRqOM&yz{sT_jPWM+i(C@5fN3<8r{)bUHfRKzo>{bb|B>(+r=21-pEIgLM&r$ zQ1F}CI{Xp^h8@9Vk?B{XJvI>C(9FtMMUc!dgLk0R{*4ZT@>g3iH>Bqw|F&v+e%j(r zfEqdFRU zf5tWqOX=*G6$6A^uu_V3Yo4%Z8``^r95)cm=0Fo!1!PI*E=0xG-X#_7+GJ_{`aF1t zqJ93N#!3@WoskB-4ysdLf);hf0!6AMiRrZC8cljy(L54A^7m@uZu-GxgmVRQCV-7~?p}oTWmoT;2g^dtoFSd+B^WC`YnxgFZG6yh zOxu%wwomrokQT6$x-Wq5uND$7Z;r(sIURIRG~t9f4iKB_4V@ngEDbCzSDZ>~20%E- zalcfvfG;zbw~-}X2uwYTzO;PlOyChZ)u#NFGCV6i^y+ZBI&5s|=Zuj6D>Y0U`~@89 z`5|UX`R8&7-xIFWnwfvg(H%JdO}}J}U{f?FRaiII6jA0pL0!R(x8wY4d-|fUx*Z~< zKWec>Qv_qU$3QUVKU{z&JDg-`riKLS3Z57E0u`yEx)EF%+HwC{ws%+}5x;&;{6g7i zb9MT%E@%84rFk#JYxz~abx@eVuzWmDJ{Z;i2{aIKJjOvBM!aDy@(YDpY@T$b<0B(s z$H?HtQ@D-WO%}OB{90@yS8ZH<|Z`{(>7b)vfU?z zMLLomH&oHThKXCw~(v;o9v2^@A~&oK;p$IcHo9 zFNh@3r`Sfe_~YqVjHXEKSHouOkcx~pVlDH#BR0FviNez-?kShNGx7E(XTth1KH0mD zXrjFvK&UNfm95MLxKWOe)lFtj3eq6+_>R7A>zOs3bP!ruJr^#+j+{SlKQJC@x`t2Q zm-wTo+w(c5W3ECk!|Sm^RHzBxNAPOvfN<0D{6VE#l_wZh3QyV6FO#-=C*^O9LV|;@ z03`;keND3HrZo0k>urmjj)5Xk9cEhfJpR!->HYg6R-OUOmnd@NYQl%+s)fOq_XCdF z$`UY*+R!5Hq!E-F4lZJF`RtLCu3=W}7OUM(?JHcAo2`2KkOt-XMH@ylbUmQtJ+bi@ zZtUe@qlt(DYs4a@cb@fVMFiaOh1h-iEScI+eGr0~I{>*InP)Gp5s^k>;WDTu1s9&% z)|T}S&BN+BkB!hMGb08&3>6!=*slDpKa!NfA3@hHx=>>DTTnTx?=Dten<8v$iM4H} zaZFFhw`;Q9a-gX$>&R~hLRGr7xj6!_p2 zAaW8$cqybi?+&JqTcY~pt4mMCa=-bq(PtYLOdT%l-<(_AF?Rh{?Y`KiBROs|MGK~+ zrWV8x?xrLP{qN$Mws`^kTrhzveF;^$y0!wnB5V4yGcv2pt<_1kmTdWR>csO-LStJO z00rx3wX_sM%Vwoe6O2p-D;^@=L&oS#7zS^b;jEDL#p2SK71xD5?<&S49@x+YNs`;@WVEI~4T;rO_1b|7-EPOj zdqm_$$fQo^Ze{ayUlgDUB6>K4`3?cUq5hMYDTGiN{gxcjgE#p;Zc0{hSW2SflCj!Q znjKBCC{oM=?R_bunA~LrvoJp=)I}aywmq!4<>M1|{3vusoB;iz!1W2!0HifQege37 z5~AoU6S|0afr9kjh#{oo?r;b@dGgGD-0i1^{_=vqeET~cpUBJ}`Y{Y0A;gSvKw4xf zcN@Siio$@25(~x1NgS|o|jo8ap=2(Edyss}Ha&<^ZYBBHT2x>n2_?xrZ{P1%`~s8lY5O?Fx} z#855yORd|Q6}g%r`js)RCco0D#RPT4dmB_Cqf%O%B998bWy1(;rK+;m1fB7`_?RBP z%E2=ENpBplByz}Tb=Y*i>Wb~B4mf^kyp1tvCFPLA1dDxJk&Bj#1NWrtNxqV2?L+xh zyvYya2qB*p@#0(Me+iar&RXqksMj*ZWQ85P*n*N?4$kCX23M4+m%-CqpYu;Md041^JAQ%X|ZHTxqixVb5POch3Lk0dO6}V&f+z~ zP(>S)HeM5^@-H9P3g*dPTsdQQy^k|m9^TC!nj1HgR?qaf)n_}hDRG#~KU|$$njI5w zTD8qBkxmgoRu%AJOeHWlP+n>aYZJyyPvd*yyfJjo;%nLUfA&ef0Q?i@pjAm}x_=H> zvE(oeZ%Yq#>4psd2Jf7Bz5ka#lYuJ86sD?2P2dc2`NO4B`az`>@LPeX0!j9ARIv_S zM0P3$uJCxN(6^o#DM*CVEciqf&omYFl}R3iNha^JM{El$S>e7JiAUw8h?l?{obfr~WiapWY{ZV%!$);ft!3=4WKa zQ%Q4SY+PJ@x21p$Dkk8ngyl0w&aU|sk)>C_2J?As6TjLP;Bo1UU)Z$%5zc#@JykQx zNN@po7Q$B*`y}Y+w~nxxiQ}(Hyl&*B>P?gpO@Qwr5y=2`=qlY@H=!S(VrNWu?Tp72 zz8m~CK$=s7*W{XN!RZX1H)>{c&S>flf~taZOXDL(w*VCC_}M!U9GK>g2q9fO)JN8Tqzo)j{tPlQxnNCYQ6CHqkWi z##CfM00AnQ;E`0i*iLGuzsn$k^@p$SY+o0e(AHmZEQ*M0+{yw~5|Z2KkYk5Bio0w5 za3YAZO^Er|QF$tMgD0*hx!P+ecrXOqz-OkMpgfZb)yKIg>1K3YI}*vsvv5bSvlU9} zQ|JmX`na@y_ufFXk#xA}R97-u>(1S>fvWXFWZ`32S`tc20RISf*)unMatz*Yw~Ual z5bv9?J#1E~t|GT3C1lDEAqon$8m}~uOqRr@Dpx-;7hh*^Vx=5Er4e1IdJ^cp z6e!jj9)H@w6jodZ+8xCqLRRx8T zMG6$_l0{1R)w>xzlKwX+sbHC_9!V$crUb@LYPx?perw0Oz+02Fv7L;r zva^{mU|JMtIKo&4$HeF?wDNo3O1VbC<2Pf2aZ^OyP=_9m^y$p)_JHKrgUOXg@Z>WQljf=%2VoUIo0g) zgh%od59owGWI@NNFkrL#_b=KBzInVX(oVmV%H0o=<=b-P#);Rfva^uU<5H86=9Z*p z-2$+pKn`CNj>Ay!;tSC`qWhPl!;-BfMUAP9v&K?BZXH#ov^EsJR!56cMy>MD50X~l z#jCqmQc0h+M&s9?Ud`Fa!X5-Dw&6~PpXHltG=^6s)r#KKY~0Ji!)!qgNmk4Fd}s3= zWGzHAqJZ0Xa4sSC_?>RI5%ZGE-6-84M%HJRH{N)@cR*@!F$y7p)X+y%1h!oe^bZ3;WOzl7YQ{>SR4C!Olty7s8g zjGo_i?zx(zyjRr!doA<3uvWiY4#cr{YLveJ= z%JJDoO8xp2VYgti{j}@RsYto2OY-oi58<{rf1Yc#+nv5*gn{0tRp%?Iu%nCcWQsX9 z`+aKf0%^c`L^hm7fQGs8%dzWei<;5n2+kLlndG?E7A-qMZ<>H!{H+n6yTZNM0tS+e zUM&gujn11-&P0bB=I>ixR{D9=VqUUOm+)m}UeG4(;P&LxHP9xb!ka>!NO_MEmExLc zspAxEIFAZz%yEd8v?7^3fj4%ghbvrnpCdV4x|G4VUhK2NsI;QZd7kbx<$8Z(zUevb z(HChi7_Vy&{!3i-$->IJlxnTQA$6TfXbg(`Ld&bWZSnaz(8g_3 zs;tBA_nIB#q#c+(epax7JJ{rOw=t9Z&enH=)&u5IjJcB3tf}{Z>bh`GxwYeF;asD+ zt6y*ki975JbSizcCf#C&Rf^`M>K~id8QLBl_Fea+TVFVO0H>$m!9j#EYQK=u zn+_@z^w<-UOG4vayA-L5@O}&FH|j<4K`(VgF@3cAz4~O}dnzIbt{clkgPiDOxz85P ziY#?=KgNmA0k=*hDZzoC z(A*bR>6d9;>i<@-_b3~VkX*)4?I(C!m;nBQ1JAvrCk(q~1U9r|f-_-tP{Ch>JpuNu zuyBuuxo~!K(t1Q6a8aF5?bZJK`oL4xeT#K{VQ6F~gK7{supMES|Ku-jb-)wZWEn%&E;};7uSv_^Hes#jBC{TA$J;m>_a1J;=-v({r6qcb(Tn z;B?x@e(*ub2OFxu;O=K*rmNh2VC#+RO^^QBd^zZ4ro_NB(=;n4U397r^fH%npgS^< zZl;oge?%OG0LBma0{@pT`}^uxGX zVw>*x6KO0-Qis4)+wGpNO8mN_AbSZmlqSJ)pV56^7WhP3nX4|Fzi@xUcN%m3A~C4y6ir%FEeq(2c8eVZFo zK0NRoReVtX?qCdbhA`84*DI6%h0n(~vu>Saz4V2X1;}d@Tc@Ta}nljzDVwO0{~!Cu5}OzdGjz zZ7BS@JX&RBYkz!U0wh6(558OgzMiAjr42o*(wWr3?2n-Y=Gl^{NYS0G{z#`y&OfRj zDNtF#aM`*Cu6ILDCW3D@AVofPWPE)pfXo1@C{~d&W0M-@isiZWfOz}_p;miWN=cMQ!g+p? z6sP!8>V=#=dGs)jAxUZFH1{cdDi#E%ODag3Efct zn>tXAnP!r1lF2{ zipe*oz#Q!+Bc7$Jdq$d79(OU5ePGWYtO8So|4S(iHBn+c8zc3m87G{U0c>n_f7-Z0 zuC&lFjUvKV*kWspUA?iF3%U(@M?ztpaLEMPT|S?+hk8xcDC!O^#*MdlKeAOtMvEA4 z`OR8by!<{@vvB5++6K8$XO_`EptjmdLpzCioaEa);1-Iox z#?(9TCW?cwC8DGm{v2Cl4fsg^q?oC=8pHYdECZe&WhP2@C`se~`RY1}0e{xQ{$h>O zLW0@2;PH`Gg2Po)m-z#h>qLX8F`C*aG3L4zSB;~s+$mfdYt(E&p)lms3FYb5!dAeE zH3R&}%X%&Uz!;Cdb5QrV;$#@@%pS>45mt&SP=?xX@dT!VvD%1} zSOP#CJp3bg({MESoxc^8U%KQKsCBxsqbW_|fvvsf%0UYtBktnRX?lPp^2 zsQ;Z5bViy$yw2;=bU%en@P#JldhQ}$oE+ay4IzN{V;EI28uJ(Y9m99Pb>d_Vbyi?F zxt@X{gGHb<2=j*FV}<8FA0yCXG$8DRbF{?r(e7CvqH&DN82SY&jc@%5_E5Jvwn^kFi|k408H@_pzx9M74QTz-u0T(?aaSSo?H8(q^h$eHe$3 zYN#`}cPLMp`T7p>ie#WZNmR#cKqkP*6A3sQvWtWK-e$hn$jx{yORO|r^yAKOvTRJ4 zgpg++FsP{s9i;_>_txXx$6~DLDjSoyjeBy#H2>N2K+#*hz27>cBp>QK7ruPa5t*eihiI^>-aBi#P?awuCtZ%?&n-I4IYpR^%s(? zWP#1=nh^!D<%ew#md5Z^>IS}?r0Q^k^LL)mM2QK;*sNW5DVBppx-H%Ya##`Hmt8v@%o);WB95wIA zou}4-DegV9$TRPhVLz9FL(~5|BdhQ&(-8=AhLB}A(^NcADgnQTwAR-&?td`{t9!3@ zJnU?5JB$HhtW*@QsA1A6{L?ZdqlV3Q5ux#g`Ng~`?(-NzfGI>eD~fs_mCeCG-7VsM z(}cY?BYuu6g)+S1CUBrH71r!Am21>80zySGKmMW5{Q@?!h;wBxD(S=6Q$;mp(nH@j zzM{+x;W74@tFJCA++4BK&p_;lf!O9CDILq-E8o#|d~IrYGeZk?Q!UGLk=7UK9mlL2 zN<=q;Pp*hGm6mL|1B^z3thM17I~SN@KRwctBpxND+>WoSVX_toL}+qV8%^L#bm@xf zmBw_4OC>rS-w>WQ0s{0_?a9?cfySGVk7dw9#lA z#2*lhTJPf=q{J}Zj!aUV96f&Qorc{!e0%MIZcjO%(7C^SBBJt2v0a~$nmzLxef_Mh zw`G>aL9Vbeoj2U#%4*w%;Wr0FF|ys!n~3`J14iu_X{ zTYMGouZkN@eNN-q6iGmuSYZvs-UeZZKG~dP)C(tC-NjJp#B>3{Ar1qVce&6JjYdQ+gs7uwqWJ|R^uobPp#hYw zJW(WXMbI?4Pu92GjU5CseVD_19>;GL@Yfg~XbM1Nb5tQ`K}yM~$bHpK>lg_uO9ZsV z(W+6T;XCdYNsVPH&=eK(6X(lmADkH(xA#UaQ3(FvQnlNV71JU+dPPh;;Tlfd1xt?* z$fbiWwepRmGyG~i#X;-4#Qe%9a9P!e8U9Ro+!sL8ypo3yLMvzzyjkkxU4?$vKRt|1 zxoWObv0x3@cM8w>l#pC0M~RPNOPDiwEN9%VS`R84hAtOMdAfqJ|T zg*VDLvvUHW?)$E}s#EJl_!VulMgtYF-+8%qDeY0aFeua#7EC*-`V2#nfB>u}Ad<#w zC<1hR%rUv2V*FZQEF(>`Hi-sjytT1%I#)E+hfm;xvu89#Y!J+1@JTz;rSNcgR#i|U z@qn0 zzC5b?Ckp6{3p7e>87XdrNtZeM(TEEb7!OmUx#~9FPoeaG_BIsY9KL&^czu<(@v^O% zVCmbx>_5PJ!56d8Ym6#MY2(DY;dF1W#R#L!(OTcqpREOTR=-nIoINPKP73!0*hq0$-{w|$vS)HhRrMPt_U;6bzQtNA1 z%-Q51lC>)1O22@*kKvw(qKpTr!OP~ujvrvpGEsc1@oIllPawJevN5x<)2=xlB}b3S zW6aUeBRg2p_ek)uE$xxp#|9^inYl9M|p{&dU-U$IT&N6AB4}WS558aiptpI`-RDzdf_^upoKB1 z7Mql#kcZl`4{bh&+OAntC5J1PNAaafj>}6Ly@(JYU@($M)zt=*^cI9IP0HBX%>OORk>tB4 z`C@e(yiPKJw+p^`#Y*}6a!qob@uXRQferJW3is-}QI8!bSD@&v@)TP4xc}D^)ZZg7 zE0wSEOJgO;^Or36+cy<`8P_7*-Kak$Fdy|>;>Y9GOUzXC;DF4dPa}sC+$aaeq=W8p zXVfd`!NMD;l^v$k-Cvw$)q^*sepDFyt|5mU`2oRI0Cik^62ZXGx9iS6O$!3+-Bc28 z-OVSxC9Ox*Rp!PWd*~Y`WBEk7WrIZnqe1Pd?sr>Hh_@g#Tyq#Aosq=(OQzIq_OqS4 z48w4Bbm_4h(Ue*{J#mg!yAl#MDI%Aq)CqXc6adh+^&83d+q6_R(Lvft*j+jC{N&B+BUjOx{co)t-1qbz}35ygw=G%S- z<|z&9Ri^V~ING@ySz2p4h^2xp8+Z_;Ja=lyFz|{cVP?pM58&$zc5e+gQgn#`x>W~1 z>0?t!a&rx+TCjzBXc*=YhOo}Kx5?MXV2|1~KQTmCYsikYm>1Y;JyBtC+<)k(-4#(` zTw4iaXeH(>XG;J>M#uRs@0qt4L~8{LZdh$e1Iw4xE!ReZ1FusLPosx$BZEs<#_aL= z3wdUzLd~D+9Y}myM+OOMx z0w;~i%!im*OEc2_hmvDg(0vjeGPXI-fE;Otit6YLV>*Adhh4^33?4q&B&7W?`|N2f zm2wTAF;sZrSZ~cw`?KVScz$;N{*!DDnXzv|lL0R)e;0HFgCk>nJd=;07GjC>xx5 zDd6L~Lk*a)Nyi{zuN#6hU9@EX5-wuo-}pUN{3ZK7fXQRSRJ|bm>Og&=5STz1KI?a3 zpHTT(g_@R;Q*+pjeD%>fyRO)HYfNI^>s95cFyzH6_6b(^&UN6j4^e4CTG|xVRpy-C z)vP4fd~0@9_^g8o%^iQBSHRV|(!^}2ZQgU9N9wux{?-X=#^SD0$2c8AhM-XfR=S<^ zo{EIy#`E~r6F&+Gz|6GWHUyEu9qw$37v_SMISxA^7vXrPnX1*Zkx0srL12S(U83e1 z_nD-=+8@JH_Fb3MyLJz<!nGh<9JLsU| z<9ZV!d$x3P;iqKHxUz91YSV4G@%gr~l41$|v)L=^Hkx;tR@j;;p`WX*0kB5%bdkyT zHG^N*IOKAP^HvG(%WysiP`6Buw{ZRxrqvK{qCO1i-)l2H|LMF+oez*;+YMuv=I^+t zVw9We_td`0m{IzkP1)2vN?osF-en%I02`eBmf|BnLW~_w#<~&%M{m05Fu`+RAX!ln zeOUJNI1DASU=YK&GNFS91OW7EsI}qq_tpuSJS)UujeDVRVTWICG!SeX)e&8?&?;V zmcAsYJUgeRIZ*+Qach1oe#qCg}+?D0>Gprb*A^k-DJ8&~}e`&-q49ePqP z9xN`_i5Z*M?~P^+J!JxuyHqnZJR*;e=u8bpp32W=Ntgqt-X|% zDpg-H$_Wd)?2SwH$Pmo<913UhzK+6{gR3Xd#h|jUNr$DlJ{4f|k|vYJ!_1% zo~CZfVAKw!T18K0<1Y#G3o;4HTdXdbdefa%c(dG)b0j=!EZ>y)Y8*37QqY*`^De2( zy*QtGU8Jsx7ZUa-FQcrVvw8F56bz`dc#zt+>l~Jwwev;!s2PMl{|db!1x0A0;0!0b z;iy;Q2G6H&6*%mFwH$(NcHc!tiOp4XZbcLa`Z63PAier-gX!O@&E*=^yWsSxE`*~9 zCM{P2IQiVGX2^qrj$yc?|j5{w-z96BsJIWBnru{MHm3fM; ziy=FcyjzI&=<>+r#4LN#Q$4&yT&`x71fN}8xne>4bhbjZGuX3Je%8C;tiU-eU} zncyOL8OWF0*N-aKF06BHGJb(Fj7@wNToQ!rPFa>kehbVLsKGtnfOJU`=lco<%ED{S zd~lvh&ODCsO-WFvTxN!?P}WJdJmq8sGmfyde|%{s>JN}VDI_e0BP?sQ(jY556udpj zbsFVsXgafyU+5Syu2jx$WBFjV|AeHP2h@ZQF7ObZjghZHjn=sK=vkCLW6Y6dHYnBM z7gRfU$=niaHHyYzs4>xdyz!&55@8C?c{3ksp{jQT8y_M#i@_Jjyy*cQup^IX_=uwb zBWusp$fyhM-R^B|lH_w=9u=6+?bH)T-9E_LtCA+$yKFs=7rXa@!-CJRE#M<|E`;O9 z`VULt;1$aK><2rt3PV4}g!!xk(J*7dsCl4bzla!Lf0n-o>mZQrBMy5{u>E_ewx?DY z*3;Av79PC#a&;@TV02@u7?MMH3Lvb^;${be*;cvK52Pk_3;yjIw!Fe}o+7HV!qYvw za*!zk%Lf2(z=pPzgwDeAl={7An9A9p1@w3{{hELh5v

zjf5$Q(e20Qg zNG@2wC=m1)%OV24k?zD$oL8 zfd!f4wJ3X8DgOJN+xvgjY%ZrFxDdS3!Z4mnhASxOz@X4Y^8Tl`FMqmBt^t>P9^2v< zB_#iUgMj?JAKJG_*1U{2x_pSh+Qw{XTqAce`meeO@PXCk|5k$QW4s^rh`ttn$e^t( z9CiVgG>X4M^S>GDnZYO5sM7U^pL(LRuhkq_S;5ct`oXK)=8RC?{pyLfBlwRbmHZXJ zIzX@?911(KeXl2EOqnc>`j5I8#u9+_42L}H8rxUl@A|camj;&GA`gPC#fN*upZ-kY z$3IQK<@_Us2j~zOl{YEyfx$Qv`#^j`^1yYs7i3~BTwd~jrY2(cSHKD$h(ciN1}~)^ zSSOFzEy|MPFDp{*ZB3xJUhkX1rz^_TMgG_^wR9a>Flss7MYKwZLbZkovd)pztUV%pdB&t010Z{Cmh#nZdi)yx!nWir%Yi@sTP zi{ZE5e;k4MXEBi3{>s&PO!XJ+_K zAB^#J53q+a`YM77sr7KfOS;N(j`ya@JtuEz8(F3P;+|W<2cSQAQo8p4K%$-9y($>i z_0`*|)2{@e);cg8J%ISK=%e(@P;m9Y@I{@r&OaK8f zMsqQ7EPr5LcV(B+Cw^|hCq29)i0m@j2vx3r~@`|-ZZ#U?MaHCfL$Sbq<%Zkw3-2YmeR7y{OWBQUdCIT|a90Im-b5QH*U9@TZ-;KyFT-X+6|gY0h`~Df(Qi{(5qO z66giw&05^x$eJkSLd?|>7PV&|)y8Pi+!Oq3@DROVDOJ7W)xzz!`%8jR`1TI0ium69 zhVG9@zm7w`kbSuf`4S}bM0s$Anf<2?mh}x=ZyS)6qo3MqG0PgEdh6*M2^5r_pTO0< z+qT}%M~4%tIn@p zIhc1IruKdT|LxE)_OI#)5rW4uVf~Humlq8E*B_9Ffpul0i>RO{(S^$VA4RiIM@IIC zxQ=Oo+=rHi@BZu4d62;Cg$z;>1)KZx4-P2lWO?TQxDRmWVE17j2X&SCW(`VzTgHmL zwFJdNsxBpE{VQ`0Lks zBZxzf{wg~CUpMpNubT!FYB2{@-2euItQVF|yCz zPyU|R`IC74p9U6i~iC#IKBG5WgH_Jx?{CVfg8Nih%c_$-@b*C+pq^ zC?L`HG!{dQASb9QHU}&&?>s%&=(E9LU8Rv2k1(I5qf(R_w4cg^%zt`8a3i2jemP2Z zZ>bC(`UMr>kcN}?VHlt`@adDMi0U^yL;7PS1c{&bq06;dB-TF#j6u)`yg~l^@QT|_ zJyuQ~MasQ}RWUeJEV)(_QPEe=?Sh}!t) zOvrJ@OT>O15aaMCPvyu9Q;UAl_z3|&1lW6|n&&S9Ct5t$vH%Mvxo|*vSC`)D7kD5@ zLhBCQe@0a8ZYALUz-&MkpeUglUTgB1;+OFYeN{Wu8dEJ@uu2L5PZfaHeB`dfy&0qA z6Mv^Bo)dzC+W>zffsO~;U7f*Vax%F*Gz;=zTqXDJc)du<-fNlfBw3}DRDd50EH3*7C$n;-D#BE^xukxJ*S=U+6U`EdM+)_aNR zqr8$BP9MFt`IB}ad@W6<^{POZ<22sFle`TB~ViN=-!%6zc z5Wk51w**hn8jKeKt_aRq3xStBc|pNiT{l(udpwvqc>y$YH$%7i0KPI%zM24|P#8(r zA7dEr0mf-iLgz=71||~m*FolyBobrB!=D9yn=o)9<(?Cy`p_6ltU;^zib6gAEocs? zcMEDl7?FrpxglUsR8IoLQb8?n7)tmP0nLJ{+pjzh%)l?dOw79gtaZb)3na*!gd`N7 zpm@U^)C)k$uL&=wf}SVs&4S5Wo{avzB9Izr&5X+3+y~TwAm;Y~M|rFZL;fUreqN!gCDd3zY}Dqi2?j@r>GspCy`ii-#cm%aqWQ()fGGM~@#H z+u9!MFpJC;?&UZdsOZYka`qe1k%JzAk+vH0aMNwNSH_=1`>6ru{q#UVI_w>H$z%EO z(|t@oBT_Y<>$v({;tc44r0`o+?VMqgMxy$dEUbaBGF0wJld7Sl_mXQ@v0|m~8co&(=*Q)g`6pb9SmvLieSbnz(wPE9huezMW@?F5Sg z)Abbh`U8Yl&Fha;Y3xJNve3!Oghax+xYyM7jrEOS@Dw@pv4Jp@_x*6L9{??`OcF`* zNu5j_=e9`_SR%0mR6@8LPbv8U>H!te{#KE0yU?Af($DNaoO~S&%cfQjS(Yc&Q#^jVOM`iVdDwF2VN7VzX#&|NDlmfv`v?!@XSw$vX%r~C7IwP zo9p@UfpW){&8fz$`TVDQn~%-+n*XpoAbpA~I8G0w_<%pX0X#*On^x0EWJk*W_e@VI zI0GoT_$Atf3=J5m}ZwFPVT5N~@J(j^|n3qbtausO{9irVSG_~?u#S)cy_tAmNIeuM0tORKW*?bdqn1_9A}ce1ltvH#w+JF z>z9}OkrmJSRuh|b{>TNx<2{cER>$}^m*M@n{`VRy{04o69H!dCvIb3rtPgt# zGWzJ}hmI%M}1N>owy(PUbQym56eN zVZ^B>O)seT*A?BnH`Gw)ulx$T z-iLY4{*+#GeC_ho+4(5scK`DIOJL80y^D$dFl^0&g?2i_vkPDU%k$W1pr&^{CU4%j zwIh;ea6c=#cE9Xw{iT2&Xn(f-Uv{h{lDodpOFK;b3uA< zPW?QIHzqinuk7ZX-D&?-lWOcyS=YMYmb!AJwH19acD!r5HGL$k`l8eY?$EXJBL@4Y zWDh#j(A;k0PW`=AUhVFa)nn;yV>eg(7DV4WJ-AV_Bek7AinHBLg|pT4Y_nCBub-D) z%MY7?jcnPAuZgXWr^|Za_78A`?kRk7(Jlddj#-LEJI4*4ZmO-Sjlw;z98f*tcVR1o z@0o5F@+uin0E#VlMyjkCVTO!ckK@J*c+YBcm-j8DSCQyX+0&VOd~|(gIny*&wWd_D zH)o1jPEYa^&q#t+>Yl&*=n-YR%oYp(?J}P}BlpTMbI1>HFpvf^g?K~3-u4Cd=DYA; z_48~C=y{>-W3FnI$KdOuSebp-9UejWzSXKXZaGeOAe+m1OO`EQ&*D^72m@|x29r~K zAhw;zoruD5u!lqsdbMYhv1I=|_jpj6#4Nt~*2y zl&Hk6kdi_zrelb&RG5lj`0g6G|Ol=Gs4f&@BsFG?rQ(7;Piayir{h@`U^XOI3JpdH5jJ6 zkNnj)w=2*|S0n#)>A;nYFLYZFr3wtiHYN!kyn;J$y0^7FUQ<_WjZmiHQv@yP?F&<}C` zDMAd`x~1=qC}HiKP{xhsjyt*?IAW~awUl zTxTV{Hda#7_>Bf~ghH9;P4vF(tM7jb+b82cC_J+1Ph+EISjkz`AFw3R?s}Yk`?J8^ zgwn7rck1=vp?wL=7o$ zv(ja3o7=CuPpna3c3~xhs)KD=&$P)59anQ!k0GR49|5lb zH~I|gEL!_mD;#FnfZn{n*yxaeTI7aK`S%9;IESW>kvk;IE?aEN@8-GYpW;St4>>JS z%~|nnyln5$2+c5gW0@j5|6LXB2)5eV9R2DCz=ZN6kWfmHCNe5&Q2a`Hyg!3PrQd-B zY%iRw2ICCVz+@2B8*p#xu+a*YA(>qi`!yT}WPwcQFZ+V~M{5b3`3^wxK$#7A1hp48 z$%}5U-ykG(<6RFeCCT&VDQjF+33}!Z6Cp!pl~v^i{qjgzuFKGYOk_&mLXm z-6%g>&VE0uc}(So|3%ijbwKV|q6pB+)PhiRRi9q@(IWzi?@yEfYMlrd59`OR!q&0TrFq7Xo32S*IwZjc2vy?Ds zEhMmMLh(#Q=QR)Kt@_rh=3en)#}wbU9Uz|-|l0~HSg zuiS183srbb65tj6-@benK9!@@LVhU+G%rN&%q_X zhP%%V9~3aTBqWgNygPm|j>@gtNH4W3_a(cKtq6i&W3#sCa7%+t?r^55F;Dns!XL0k zNdc`TMK8EK{FRL;8{sD)(?S{|m4LUOWdSt>UKnT_>Yn1Dgc+qUSLE>c!F< z-SUFqmkC`1S`zqEAtlf70XY<-7qkeM%?r#a{?!YXR!R5t;!7d6i+#7~HMe(1;IE1W=NIpdj5!yb8p;Wtm zI5G{??JVWp*L9K+zl*GU2w-RH(}iOYw!_V`l8pb!@hAD#d;OLm)2Iu;e#`$5U1$sh zV|_RXj8&xG{|6pTA9+aoZb={DiXEqc8*{csHrq#%sXZ8-dw_?<)%1=yk5=hKjxf;K zl<71)9lWIQj^5_1_m@*A{gm#p5v6*VWopes?h?q!9|`n)t>Nc$fsE)yxDV}7A)8%S z_=3;nOQhUgvbUU<4)$$iJ>w$^`kZ!rYrVk-$hG|m(q~Kv>qOsM5Ktbb_VC| z7==g1A=G1s?|K#vh)vePojh6(2+`sZ4oEUG;5f~GJuwT4;K!SRl>?IBr<`}66agVr z1xI|f$^UBHf((X+h=<3$3-V{vuuV=AW!0;ldT|; zZuHcHg=XtJUfnh(Ji^!`><8@GG&k&iYP*uH3uoR$VaSy>G?CHxgmWh*&wL+*Kqu~>5ftzKe|sXV2x6N z>Eh~IolM+KMyy}k;}iUG*+aR85Dq8>E`i!*-=5`WXQGfTdil?M+>f>6^H>e)JnN-^ zae=1KngkmOa1sc}-Q4Iq&7hv+Pa+`W)!yR1$8Eg;k~DyIp^kd<)b9RL{8GT5wDxN5 za6$-3`?(O1OEnWuYU=t|82~=-9E9o7BMB&2NTY#OH=mLfQG&wf0VISzM|+ku#)^eB z2l^g&WT^Ch^?geljw*cOR%tTmSTHpNEY=MKy*QNiO@sUKCG&;&v(a%HGH^<>tD-$v zL77lHy7)^`_d9w(>N7XJYc2s6lBWQCz{11w`GP!k1;LtNei z;&bWEXIZOMKCk+lgJ4OHF62E;64`Fr@HDQJ{9{9 zs}ecKC7v;u+Kkx&^G(>XZ4=P2kS5^^4$XV?EM<%>3uzQ6-}gKBaQ9?wUhm)=i3pBE z*_com&qxNW@g(PSso`pJ?Zs7UScQ$p2D}0t5N2IZP>e4)n>`P;n#O%Jq6AdEbvt|y zz7_@u5#O<;)uqu8>XHS3&k`xeMaLFaYUB*QJ3GRR$eDBj;Q3ex3fT7X63bwn1RP&( zmpCVyF8N(RpQaXB2IdoKBMrOb14V-z{HcdiEWQN99Ba>@HMRf)USjEs=`B3eA6xLW z8Xm=J#&cuL4=R3V5HvWsLFx~#EbGDlXhFb@$B+@mKaN;q0a%@0trb9`5!Qe}{sKob z%L|C)rlE1*FTkj=HoiSR+hAxbXqbNz_jU(%i~QItKqmbT0Cm=1i@YDP!wx0^k!UW# zynP`=9CyM1gCc&GM9$dg6(;^w1kn8(^LPxIsyHn*j1;lBar6-rh&~`_*Qzt#fC#mV z)1C)Lap|so#(s7gM=anYxA`zZv=^}(fK!hTEzUq+s%g`@Z3W*(Zgg)~W*EDO2SL+8 zfJk3M(I5dp#aF7x4RJtOB~zeMMU57XS{SHLjR4|xt|Zd;12`C?BOnZ~XOHA@x$_Jv zK9&k9Rn2g>-WIJ%i%(iIhU^l$&H^=&Cl0Jw!bacclu$Clg3st#!C1{Z7+sedf^xu7 z{cmHpY1~;b>G-~Yl@8aub3p)LlnO*bWJfpyfSep$xixRoNu3 zNkd=J6MSD7f14e2tjOC!{Hr9W1^ayrjhi^F0X}hF`jj_jFBJc+1rJAjxgi}fso|cd zsmBl}0UM#&zxLKhTFk9<5uZ5Xux4T!lcrI@LojDMGwPJReJGLmhj7O8V3cwOskVqJTwUD2~;cnXGTiFVSgqrr1GH_^3)Rz-~Ljq#y`@#sHgV` z<5=Pi4YUV9;%GC2J31IzgCB5CiNoB>D+Q;RGD z!$ew$jmE%C0Zd;03j6;hFJRm^j)r6F*kMEXE>@onl_q9d^95mi173TfeX+eom>P(U zf72Eq1~VjQ1W^Y$2ND+%ExT&4O=tIy?&fqyQ}G z4#F_@6>JkWO#mCR#hb0Z(p%b>$<_~AV+XP-k-M1N!ux+^l@4T8Eq0tNtmYVtco&|( zh6~fA(9sJ5S>K<2L;ODzc!yySC5-!6AMA@i!k>(moIZ}2Vz3d;l40{Yc>|v1yiV)V zuV4)UEZ+v-Qcl1#G>|A#AQSHZGjWB6a84qQhLUKrEuNrdE8M@3)Sj8nJ*6 zGv)_!(Y3^WfL^j~Ue|2E%N$PcbL@k4mgkv&(x8dn*v63R26h&+N%F$dCebc2?CsDJNq6x@BxdTRMoS? zEXmITCQ%FepO5Xxx6v3!7ECX`6(Rw>ZB>f1C<0b<494y{-R(;%lT z0p$157aVB%7|k?@DtP@*jiFAro)XaKKj8*?pmkTSr4av+T`Qg$(FU>f1+g>+7s!D* ztF^>g{xwPKZ$NP1vuwc>=KuOz8ejUxZ@y?_rSfHJ)iwciLt%*eyk-aMN*j$A;|M z^1P0N$rN6;Yt2AO_pAj@eX7?piiqRo*092M$1}}Q8}WSVI)*BKfT+JqXXA-W#&wLV z-P*7(^n4F{nK-5g?}k3ON9#fB0r+34X9wjlm$Rs3o}^by0_=v`io7GQX&%f|#w>NTtXnO1#bE5&aWov}bY z%WEXDAPLeinzPrsZPQN!$nLKe(2bJqWNTweB;!5U$>`g?cOV+y%EgSFoBIyiV;(Sk zS${>6l&($|qKg4gJ`34ta+;YlyGjxg1`7#epMG@#xY-2ifbRkM&Zx9IUT|unQG$Xt zg#&v8&~4)SiTVU#_?}1RwkGf0$}-_`8Aj1a<+oEWIInuOE24? z1Q-9zh!HgVM><5r*`(teV;@IZ1e5)5L4ADHY`Uy0h1lXLgZ{x>xEzlglC@;g~J|nB(;lyr?!!x22uKM`xtV=eXIt^rlHH82Gyomi$EMvV%0S4|<{|F(rGw)(* zh2>DwkN&3T9egY~`V0yuW?2h>0p{b$q@lFjPpJ9b=W@e@k zjM-8U%mseE^X5=B-msSu5nO9EhE7gSmxKs4d5xThH_A54awKyPeA6vwUg2ID#Y(k$ zx9KPrPi~RS4_Z}cQ!!usRH68DE-RL^JUr$ikZ%=Ew(BzDyu86%Mxk;)89QXJ%7#Ns zObkg7K&Ev)MN?b*xU0<>G@1ko5(1s}nZu1H62EQJB|EI(;+cRdxOo zvg^vQ=Fxl-!aoKb_N5Q;Q5ojH0ki#ur@t@!@e5)M zuqL_hDCNYA_3)X~F^#_@`%A=N;N=8fU`WAxd!hhj@tX9Ej=$2Ia3!krZq9#e9&&kf z3h3Yb$__zd|9BIDZIV+o6_bJ2Xq*gRm;K-gX?U6IrJYccC4U@Z9h>wkZc zLs|j2k0KlLv(mj`rF${F)8v2i|Nk%Zq?u4(g&=zlT)-yVIgP8T$(=OT6i{zh|DZ^H z>npzUBNzGP<>iHnYiloAavI;6-uv{NE0O)OHIK{QjTD0{cGV*uJ|D+21qg9lMGy~e zX`r(X$ZUTZ(eeE5Qom7#68mJv%+T<>H0N!Guy4r@Z;EUw1ijyONZD;QJBvCG*UauS z(^OdZ_^|D5t=znN)vxIBU|KcqU}fOLeTrg;u%K;)MIS$_xHZQKq!aqN6SV>Ps9VI@ z=o3#~Kztze5#ENEpR7t*k&}zp9yyc~$^zDsj$?uai6EVd*tRW-+}3v8LJShpJJ=^J zD2q`-jD=^^)T*P?Jy#}YJBl|gzIHx(+{*tfk*ZUp3Ai%NxV5FFyUKMh1x~{%`F3c? zz>?s>o$3Ce>$At>_Po5jbP}k%l+i<`N6{J;Tf%><(KB4)PHotf{&%~c$%Ng{NgqTP zx-PLw>!nV-`8(@H+T@@EV|p@I5&3IWMv8@)hrxXHO=JY`t92*Jv}`{W}E|IEiQ2reiFy(4X90A z%;s!}qHCEv>PPA-?06Eri8zQj_}n6bxaqfi-*`Moj4=g`+Pce=Y=!-6kEY|pxuQ1% zH+ALePNevW_C8vaG{_MvreDBaA3Z&BS$S(}aq-boe?Hgl*74&dbQ8>JNmEl(9m+8=nbTFx zTm^GvPe0cn=q9jDLhJEyTjgA$?hr#LVXV`GM9`jrEt>0)C&u5YSta#8-xuJt)M?pw zWC0%Z*sPDutRzDeSq^7?`Esr86nVb#18fMa(Laif!I~$YK=1s1z`=TLDw6u>e-qC< zkZY;9V09Q{sDZ$#XsL8u#Udb1M;Ld8R9N<--DtXbs<~*$I|dbAe)Nl*{0+`7U889$syv9U4K0$eB4b|A71WQ^nichZHr=kAZ>kc+Dl=?iPa8u zvDgzX^=vb~%0wKTybs4!#J5U!lvsai0qor%!lB{Ew5QHpca?9R4(t1xd|7SSFN`sh z>D|^j(E_dK$Fzg!(#~zXQ4?_-A-VrD@?AF(eb4crMQogoKw@%wqTAKruAq;6)z8!F zJzsP6>UQIpvLL72LxMi=dQ=4=sT-+*xJH- z*a&H1{9RJXif?bkWHzs(7mu6}buNrbeUQa*RJ|~Ig(kF29p{>!k2~f;Ylz8Y`4760 z^N1VJ@c9V^?ZjeD9?g|rRFaDkgP}`4f9QzhY^Rk$GQS#s-^Z;Fk?wDGpUc>aY?boN zJ1wxJ9*>&Olc=m%fBoIaU8{Y+C{EJQrjX5zOO4mzm`6RusKIu3)x2&MxrR~SjIetq zZ?#jYWa9VnyY{oY7Ou8qQeXJ_x0+(;Lob#Zie&SbbX%_(rYiP0xUOrsQ>}EWGdM8i zC>R=~FKM$SRZe6uQwdA$?PURabZ#F%%1C}rjUo&A!G=A_@Tb#zz*$HiLNqYnng_%; zRPC#rB1tMs^y0p+*`I|Q?dPZt_P{hG%tNy3fBKlQ_F!d*D3d8C&o;Og323xZ=~z zFG<+iJI=~otPsp zb)2@b=nUr8;q(e?9>Z)oz^N}mfF|S5q)Q0q#o(dEd-PlON8bt2H!~r-s|D{w9S_`& z%b(<~o-Rh*myaua(qDOE$m*@7(>CAIj!SG>oG`*NCiSBXyLr!ou*j6-)+-kmuXpyO>=zxr4^Ow^A&o=@d`qFnl3)L@jeg|Ma=@xmw>kL|BI|YC>}=G{o$r zcV4|cHQX(BtKCI6W6@q%bY<1KhmS`oI<|TR`7&qwfq+cm!)n=q-Td#m(E4P^TRrVm zrvcdw9hG=Vb)2xto2ZTID{9nES7g#GZyK7vRK3zZ^eRKYd^Fc^xO}cy=0*2h=c&{7 z;%d=GSo?!}y{ZROZwe(}^+q<;_xj&T&h};A_+A-p_Gv7=XDeai9DmqZjZ*D~Te(>) z_Z=VBzmDE`$kn#DB=h;1KaiRDs7?LGS!ugZb#(bwpt*9~D-?`_nCIM( zxQe5_3!?67W$H`qBQKlC3RJbUGqT<*0>y%8@qu&XR-?(&yF;h!PkgvkYIMDCs0ny* z+kj&yRKTi-Ic_bI!Sy;^M)poXl|#GBHc+nQtYFMfZASbk&w<=lUC%gefuMo7+K|{bQN_qdO7=3L_9al(KE5`H`P?) zwqK;V-g=vI|6slQn0L=A|HS1?auvu6A;V&a#pF>LA^n1?Pny%o(o>IhGqP>nGL;2b zU+*Ql=vbvc>kA2yIrBKk@>yBFq4Squtq&iQ{NQ48(bPMNr43U-i%%6wn_=^vdkp5? zFRI_QG%H(=FG}&b(mb490k+GK(tJn*Tz$~$S|;yLVE;Jci6G(FU=WpgqbqRp)CWD~ zq{O!h0~`u*228IEnFo& zUu$KCU9%zQ+f$qE8}_(m6TKHUSLUWaq;->(ZIru;B3m>njp)>UODl55G+D8WP8(+K zxop^Bb`jGCB72-FSJ*8X`C;eyeZSXVOtJ=K^aVl_-m(opIJaaS*a?rxjwHL?^Z0I- z;r>Sym0$kB#H8BasV>lI=mtd`GyOek#@;zBb5|r+%gOZp=#ld44?eght!G4~UhfXa z(qs-2imb%`}2>o+Tujb z$lk9ecc~25uY24Ze%jHn+eXZ4XS^;H*MC|lnwMwJc*FI{+o*)y$fVqwkeOWe<#)2{ z&%gJEX@)Jo5qVTAlsdVn>Cm?DbSh9`W5Gcta$h~McS+YhD)(aB4V&eoR27)3R12=v zjRG+#mSVlQ-3esag;9g`eC)*sUL>xSxrWVOx|oBLdMvhFZ+nll_B>Ijt_gzpcr|r- z`Kz_+;WC*hjem3&#>$|c6o`}g&H5w@o}rHB1C1oTtK#-CEn344byrejMG=i^8fvzm zTRaV1cWTaOGup;U!m&kX-Va=cbk?63>Kh%hIeEK5B6y>}q1e3NLwxkh5qpzlL%01S z!{2uJL-d{}_eiZpI-b>ZiaTRI-Zf!g_pLT$nuOzlYZ&uYi}m%F1Ci0`m-Cw+r@+Iq z%vNBM^(Q#m7Tt+?);_M5F7&MKuWhK|>~i>Lzsj*n#=l#u-WAxLuXgC(Xn)-8_0nDW z2IOwlgJJ`z5tihJEu*)d&A2Rocd1)Yfu;0@Zw&*}vtqhC9FVzlYuXob*k_sG4d?z# zwYtS=D?KaS#4{Zfh0V{Vuk2)tN!VJ`F3R^Y%!)3fvY!nWq7Z;(TKS8h&~rnf&|capu&1;!m-K#eGNKq;{q@sc*}@^Wcshw`6?Bocr{KHwjgj(P&Z%n^=z&^etH!&-T8yYyOz(!FZMI?&@u| zIaAlDv)Lv4AFZUmvsX**$tN6iJS%ui7@mXQ5@H6w3=uw%B;MgZ*E!hQ;IwhCi zF;MkVY}xff1za#k)X_3E{$Ayxbj&T z00hwvD)kX+||*_Gq+@?G}E>_ z6`#FpF>vHKtBhW`WnH#yq>gS@-H~H z7eu2kJY$6$u0`?p>{q+I?lV+Yx3moE?Q=}yjQ;Y${=99rAuC)*(x2aig0?t= zO3O|=q*6qq>YZ%EV9)oC?(rOV0nU{CD5*vyX(u7|S8JB%FV;OF33#_Q(OFVyrk6mD zh&{$Ha{qR8n)LMf!S_RDS8nBE^`eI*l)dTSp6iO=u#0Lc8;bnMi=kOrS+o1jM?A(}44PVf>{a=%og|(b@=t3Fc!=|CwdqQ4hNzQXajr;SuuD-9 zBhB~G^m{KK&X?7dxsI?^e#G7hUZ{b>sLyh7U53%Hb?2KjS${^Wjq1;r$81$pNG}bQ zYW{3B4Wa#4+yAdkGTj0hqlsRYuVD-i9=5=C2Ew(^*Qf(>I`rZ4{G|(s$lm>`1=spF;I)hc3F=*lP)BNZK~40X3c7NGs63 z{k~?CnJTBDi{n26mjNiwz3R0*tnGm6@WHjTw4CNX28q;xo7M)f z;O0`|NVx~brB&iLvee(v%;os*rL0*=e`@1>Xd|PmrA7DnX=^G)8d+OwYlt65QyBYA zCnt$w4w>N;U zLx}#~COO=PAY1|VYhJ(%zo(t@l=iD<#2?}X+n9MBgC;fBuY}Mt#wKm%`-#S@Iz?JT%CV z(6*-sccjv`vE>#K$6FUXx%~LpCMjq#-D1{g{2^4BFkCgE`bgy(%>hh&k5H*LHp-_4 zIC}giVTZrVIiT(_PakEBu#Z3DVW+qo>(-z8z_&ZBFPn>qbMA-P;%VQyjUdAO6{hYU z%aTCZb_=Bb)XCAZdFKw;#?Dl3ytAjAY7X-8se*sk0uMo7PctT@jj-vK*_)`?RBH~uJ!KOxp$*b#JQC8ji@5$h*fWyPj9LX$A7+k(|FnB*f)sWh@(hWJh z@$@|oqLL(`$*Yso4WLGX!~wC~33?)a@N5OX3_A!SlwLi$3#hZ>eeFH^X(H-^w@opC zPbVJO^g`-=IHsR66_|aZDK}uCl52@bbXa)eYNxGT@Zp?T^@Wn02O}**Hr@o(L?fOS zWd__o_kwYf2$`!YLC_qDv0`lKYWx?L`I)2BxZ62h#W}l{B6Whdt}af74kX#MK`zh; zxzm-$G^n>a&KTNnxX;4fG4A%Qg|{Di)7FN0_`!23i#5l;o5*E4!ZwiFmkuwqFUVH@7-$68NGsYzY;XZn5VJ%T-V!+9W*+h|aXSR;bmzOjAS~ zOe~GHF)21CQ^ECa-T4^HT%&AFZa@8^^bo+TSo2(;IUx7C`-nK`Sw!r#Myqgz*Id)Leq>LIw)QkRDAZhZ)?chUmIxTNp%m&u zPJ?Mlkvvu1#aRiLNknaJV9{)LT-Sp0X8!=@O@6b{{B6Rn{`-PamuTBjBEl$h3b~^n zsZJpI4{SOK7C0~I25aU9yCjA+0^67z0n|PljB+Yd_f)3dJdl01{~pFzv}?*c7{cHd zk6jWtv(Etu6jLH2=N`E0PddR&l^a9YkOfVqw({zq#l)J8*`SiBeZ+mtmTdg|UJ0{U tzrIENQNBGY?{WQt4b;(S4H}N4fj!P_ieb6w1p)pk$*W$;xpc?t{{fDE0ZRY? diff --git a/src/Tests/dotnet-MsiInstallation.Tests/images/virtual-switch-manager.png b/src/Tests/dotnet-MsiInstallation.Tests/images/virtual-switch-manager.png index 8e4dae7febb0b4a30855f27b499da2fc29176493..313078f1e82a741a9b075e4e392b9cd40eead00c 100644 GIT binary patch literal 97752 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℞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 literal 151492 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�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 f+=mZM%X| From 9effdac6fb994aa82e5ab2a14c24ae501a3ba624 Mon Sep 17 00:00:00 2001 From: Daniel Plaisted Date: Fri, 8 Mar 2024 17:40:41 -0500 Subject: [PATCH 413/577] Update test to work whether or not VS is pre-installed on VM --- .../MsiInstallerTests.cs | 26 ++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-) diff --git a/src/Tests/dotnet-MsiInstallation.Tests/MsiInstallerTests.cs b/src/Tests/dotnet-MsiInstallation.Tests/MsiInstallerTests.cs index 90c71dffe39c..1d870afb6549 100644 --- a/src/Tests/dotnet-MsiInstallation.Tests/MsiInstallerTests.cs +++ b/src/Tests/dotnet-MsiInstallation.Tests/MsiInstallerTests.cs @@ -74,7 +74,6 @@ string SdkInstallerVersion } """; - //VMControl VM { get; } VirtualMachine VM { get; } public WorkloadTests(ITestOutputHelper log) : base(log) @@ -171,7 +170,19 @@ public void InstallAndroidAndWasm() [Fact] public void SdkInstallation() { - GetInstalledSdkVersion().Should().Be("7.0.401"); + var command = VM.CreateRunCommand("dotnet", "--version"); + command.IsReadOnly = true; + + string originalSdkVersion; + var versionResult = command.Execute(); + if (versionResult.ExitCode == 0) + { + originalSdkVersion = versionResult.StdOut; + } + else + { + originalSdkVersion = null; + } InstallSdk(deployStage2: false); @@ -187,7 +198,16 @@ public void SdkInstallation() .Should() .NotExist(); - GetInstalledSdkVersion().Should().Be("7.0.401"); + if (originalSdkVersion != null) + { + GetInstalledSdkVersion().Should().Be(originalSdkVersion); + } + else + { + VM.GetRemoteDirectory($@"c:\Program Files\dotnet") + .Should() + .NotExist(); + } } From 0ebc0551741b5e2bcd417bdd38c4da0bad84c4e8 Mon Sep 17 00:00:00 2001 From: Daniel Plaisted Date: Mon, 11 Mar 2024 13:27:38 -0400 Subject: [PATCH 414/577] Comment cleanup --- .../MsiInstallerTests.cs | 13 --- .../RemoteFile.cs | 2 - .../dotnet-MsiInstallation.Tests/VMAction.cs | 16 ---- .../dotnet-MsiInstallation.Tests/VMControl.cs | 81 +------------------ 4 files changed, 1 insertion(+), 111 deletions(-) diff --git a/src/Tests/dotnet-MsiInstallation.Tests/MsiInstallerTests.cs b/src/Tests/dotnet-MsiInstallation.Tests/MsiInstallerTests.cs index 1d870afb6549..88ba72eb0f85 100644 --- a/src/Tests/dotnet-MsiInstallation.Tests/MsiInstallerTests.cs +++ b/src/Tests/dotnet-MsiInstallation.Tests/MsiInstallerTests.cs @@ -8,19 +8,6 @@ namespace Microsoft.DotNet.MsiInstallerTests { public class WorkloadTests : SdkTest, IDisposable { - // Remote execution notes: - // psexec / uses Admin share (C$) - // ddrits / cloudtest - // sysinternals: filemon / regmon - // May need to run winrm quickconfig to use WMI - // How to apply snapshot via C#: https://stackoverflow.com/questions/60173096/hyperv-wmi-apply-snapshot-in-c-sharp - // Also see https://stackoverflow.com/questions/1735978/manipulate-hyper-v-from-net - // Official documentation?: https://learn.microsoft.com/en-us/windows/win32/hyperv_v2/exporting-virtual-machines - // How to rename a snapshot: https://stackoverflow.com/questions/7599217/setting-hyper-v-snapshots-name-programmatically - // There is a 50 checkpoint max - - - // Reminder: Enable "Remote Service Management" firewall rule so that PSExec will run more quickly. Make sure network is set to "Private" in Windows settings (or enable the firewall rule for public networks). string SdkInstallerVersion { diff --git a/src/Tests/dotnet-MsiInstallation.Tests/RemoteFile.cs b/src/Tests/dotnet-MsiInstallation.Tests/RemoteFile.cs index 008fdf53474b..0c09dd4f6657 100644 --- a/src/Tests/dotnet-MsiInstallation.Tests/RemoteFile.cs +++ b/src/Tests/dotnet-MsiInstallation.Tests/RemoteFile.cs @@ -11,8 +11,6 @@ namespace Microsoft.DotNet.MsiInstallerTests { - // TODO: Add VMAction for reading remote file, to allow read of file to be cached, avoiding the need to apply a snapshot to read the file on subsequent runs - abstract class RemoteFile { public RemoteFile(string path) diff --git a/src/Tests/dotnet-MsiInstallation.Tests/VMAction.cs b/src/Tests/dotnet-MsiInstallation.Tests/VMAction.cs index 53555acfdee7..a6591b1b7a53 100644 --- a/src/Tests/dotnet-MsiInstallation.Tests/VMAction.cs +++ b/src/Tests/dotnet-MsiInstallation.Tests/VMAction.cs @@ -12,21 +12,6 @@ namespace Microsoft.DotNet.MsiInstallerTests { - // Core actions: - // - Run command - // - Copy file to VM - // - Enumerate and read files / directories - // - Is this actually an action? - - // Run command - // - Install .NET SDK (From SdkTesting folder) - // - Uninstall .NET SDK - // - Workload install / uninstall - // - Apply rollback file - // - Get .NET version - this shouldn't change state - // Copy file to VM - // - Deploy stage 2 SDK - abstract class VMAction { public VirtualMachine VM { get; } @@ -316,7 +301,6 @@ public override int GetHashCode() public static bool operator !=(SerializedVMAction left, SerializedVMAction right) => !(left == right); } - // Do we need a separate VMActionResult, or should we just use CommandResult? class VMActionResult { public string Filename { get; set; } diff --git a/src/Tests/dotnet-MsiInstallation.Tests/VMControl.cs b/src/Tests/dotnet-MsiInstallation.Tests/VMControl.cs index c184fc98d1ef..e1547f7978ba 100644 --- a/src/Tests/dotnet-MsiInstallation.Tests/VMControl.cs +++ b/src/Tests/dotnet-MsiInstallation.Tests/VMControl.cs @@ -159,8 +159,6 @@ public async Task CreateSnapshotAsync(string snapshotName) var snapshotService = _session.EnumerateInstances(virtNamespace, "Msvm_VirtualSystemSnapshotService").First(); - //var settingData = _session.CreateInstance(virtNamespace, new CimInstance("CIM_SettingData")); - CimMethodParametersCollection cimMethodParameters = new CimMethodParametersCollection { CimMethodParameter.Create("AffectedSystem", VMInstance, CimType.Reference, CimFlags.In), CimMethodParameter.Create("SnapshotType", 2, CimType.UInt16, CimFlags.In), @@ -173,15 +171,6 @@ public async Task CreateSnapshotAsync(string snapshotName) await WaitForJobSuccess(result); - //var updatedSnapshots = GetSnapshots().ToDictionary(s => s.id, s => s.name); - //foreach (var snapshot in updatedSnapshots) - //{ - // if (!existingSnapshots.ContainsKey(snapshot.Key)) - // { - // Log.WriteLine($"Created snapshot {snapshot.Value} ({snapshot.Key})"); - // } - //} - var newSnapshot = GetSnapshots().Single(s => !existingSnapshots.ContainsKey(s.id)); @@ -250,12 +239,6 @@ VMEnabledState getCurrentState() return; } - //bool isAlreadyRunning = getCurrentState() == 2; - //if (running == isAlreadyRunning) - //{ - // return; - //} - Log.WriteLine($"Changing EnabledState from {getCurrentState()} to {targetState}"); var methodParameters = new CimMethodParametersCollection() @@ -359,71 +342,9 @@ enum VMEnabledState : UInt16 ShuttingDown = 4, NotApplicable = 5, EnabledButOffline = 6, - //NoContact = 7, - //LostCommunication = 8, - //DisabledNoRedundancy = 9, - //InTest = 10, - //Deferred = 11, - //Quiesce = 12, - //Starting = 13, - //Snapshotting = 14, - //Saving = 15, - //Stopping = 16, - //Pausing = 17, - //Resuming = 18, - //FastSnapshotting = 19, - //FastSaving = 20, - //StartingUp = 21, - //PoweringDown = 22, - //PoweringUp = 23, - //SavingState = 24, - //RestoringState = 25, - //Paused = 26, - //Resumed = 27, - //Suspended = 28, - //StartingUpService = 29, - //UndoingSnapshot = 30, - //ImportingSnapshot = 31, - //ExportingSnapshot = 32, - //MergingSnapshot = 33, - //RemovingSnapshot = 34, - //ApplyingSnapshot = 35, - //Killing = 36, - //StoppingService = 37, - //SuspendedWithSavedState = 38, - //StartingUpWithSavedState = 39, - //InService = 40, - //NoRecovery = 41, - //Last = 42 + } - //private class CimObserver : IObserver - //{ - // TaskCompletionSource _tcs; - // Management.Infrastructure.Generic.CimAsyncResult _result; - - // public Task Task => _tcs.Task; - - // public CimObserver(Management.Infrastructure.Generic.CimAsyncResult result) - // { - // _tcs = new TaskCompletionSource(); - // _result = result; - // _result.Subscribe(this); - // } - - // public void OnCompleted() - // { - // } - // public void OnError(Exception error) - // { - // _tcs.SetException(error); - // } - // public void OnNext(T value) - // { - // _tcs.SetResult(value); - // } - //} - class RemoteCommand : TestCommand { string _targetMachineName; From 2b79b4b7a75369c4954aed3c15402b461e82fa93 Mon Sep 17 00:00:00 2001 From: Daniel Plaisted Date: Fri, 15 Mar 2024 17:14:54 -0400 Subject: [PATCH 415/577] Apply code review feedback --- .../dotnet-MsiInstallation.Tests/VMControl.cs | 28 ------------------- .../VMStateTree.cs | 18 ++++-------- .../VirtualMachine.cs | 11 +------- 3 files changed, 7 insertions(+), 50 deletions(-) diff --git a/src/Tests/dotnet-MsiInstallation.Tests/VMControl.cs b/src/Tests/dotnet-MsiInstallation.Tests/VMControl.cs index e1547f7978ba..07406fb2588f 100644 --- a/src/Tests/dotnet-MsiInstallation.Tests/VMControl.cs +++ b/src/Tests/dotnet-MsiInstallation.Tests/VMControl.cs @@ -1,16 +1,10 @@ // Licensed to the .NET Foundation under one or more agreements. // 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 Microsoft.DotNet.Cli.Utils; using Microsoft.DotNet.Installer.Windows; using Microsoft.Management.Infrastructure; using Microsoft.Management.Infrastructure.Serialization; -using static Microsoft.ApplicationInsights.MetricDimensionNames.TelemetryContext; namespace Microsoft.DotNet.MsiInstallerTests { @@ -101,16 +95,6 @@ public CommandResult RunCommandOnVM(string[] args, string workingDirectory = nul private IEnumerable GetSnapshotInstances() { var snapshots = _session.QueryInstances(virtNamespace, "WQL", $"SELECT * FROM Msvm_VirtualSystemSettingData WHERE VirtualSystemIdentifier='{VMInstance.CimInstanceProperties["Name"].Value}' And IsSaved='True'").ToList(); - //Log.WriteLine("Snapshot count: " + snapshots.Count); - //foreach (var snapshot in snapshots) - //{ - // Log.WriteLine(snapshot.CimInstanceProperties["ElementName"].Value.ToString()); - // //Log.WriteLine(snapshot.ToString()); - // //foreach (var prop in snapshot.CimInstanceProperties) - // //{ - // // Log.WriteLine($"\t{prop.Name}: {prop.Value}"); - // //} - //} return snapshots; } @@ -126,20 +110,12 @@ public async Task RenameSnapshotAsync(string snapshotId, string newName) var managementService = _session.QueryInstances(@"root\virtualization\v2", "WQL", "SELECT * FROM Msvm_VirtualSystemManagementService").Single(); var modifyVmMethod = managementService.CimClass.CimClassMethods.Single(m => m.Name == "ModifySystemSettings"); - //foreach (var param in modifyVmMethod.Parameters) - //{ - // Log.WriteLine($"{param.Name}: {param.CimType}"); - //} var snapshot = snapshots.Single(s => s.CimInstanceProperties["ConfigurationID"].Value.ToString() == snapshotId); snapshot.CimInstanceProperties["ElementName"].Value = newName; Log.WriteLine("Renaming snapshot " + snapshotId + " to " + newName); - //foreach (var prop in snapshot.CimInstanceProperties) - //{ - // Log.WriteLine($"\t{prop.Name}: {prop.Value}"); - //} CimSerializer serializer = CimSerializer.Create(); var snapshotString = Encoding.Unicode.GetString(serializer.Serialize(snapshot, InstanceSerializationOptions.None)); @@ -279,10 +255,6 @@ private async Task WaitForJobSuccess(CimMethodResult result) if (jobState != JobState.Completed && jobState != JobState.CompletedWithWarnings) { Log.WriteLine("Job failed: " + jobState); - //foreach (var prop in job.CimInstanceProperties) - //{ - // Log.WriteLine($"\t{prop.Name}: {prop.Value}"); - //} string exceptionText = "Job failed: " + jobState; diff --git a/src/Tests/dotnet-MsiInstallation.Tests/VMStateTree.cs b/src/Tests/dotnet-MsiInstallation.Tests/VMStateTree.cs index 78701ec8990f..1c08293addff 100644 --- a/src/Tests/dotnet-MsiInstallation.Tests/VMStateTree.cs +++ b/src/Tests/dotnet-MsiInstallation.Tests/VMStateTree.cs @@ -1,12 +1,6 @@ // Licensed to the .NET Foundation under one or more agreements. // 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; - namespace Microsoft.DotNet.MsiInstallerTests { internal class VMStateTree @@ -18,18 +12,18 @@ internal class VMStateTree public Dictionary ReadOnlyActions { get; set; } = new(); - public SerializeableVMStateTree ToSerializeable() + public SerializableVMStateTree ToSerializeable() { - return new SerializeableVMStateTree() + return new SerializableVMStateTree() { SnapshotId = SnapshotId, SnapshotName = SnapshotName, - Actions = Actions.Select(a => new SerializeableVMStateTree.Entry() { + Actions = Actions.Select(a => new SerializableVMStateTree.Entry() { Action = a.Key, ActionResult = a.Value.actionResult, ResultingState = a.Value.resultingState.ToSerializeable() }).ToList(), - ReadOnlyActions = ReadOnlyActions.Select(a => new SerializeableVMStateTree.ReadOnlyEntry() + ReadOnlyActions = ReadOnlyActions.Select(a => new SerializableVMStateTree.ReadOnlyEntry() { Action = a.Key, ActionResult = a.Value @@ -39,7 +33,7 @@ public SerializeableVMStateTree ToSerializeable() } } - internal class SerializeableVMStateTree + internal class SerializableVMStateTree { public string SnapshotId { get; set; } public string SnapshotName { get; set; } @@ -53,7 +47,7 @@ public class Entry { public SerializedVMAction Action { get; set; } public VMActionResult ActionResult { get; set; } - public SerializeableVMStateTree ResultingState { get; set; } + public SerializableVMStateTree ResultingState { get; set; } } public class ReadOnlyEntry diff --git a/src/Tests/dotnet-MsiInstallation.Tests/VirtualMachine.cs b/src/Tests/dotnet-MsiInstallation.Tests/VirtualMachine.cs index 4480d03e442f..8ebeda0d4ec4 100644 --- a/src/Tests/dotnet-MsiInstallation.Tests/VirtualMachine.cs +++ b/src/Tests/dotnet-MsiInstallation.Tests/VirtualMachine.cs @@ -1,16 +1,8 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.Linq; -using System.Text; using System.Text.Json; using System.Text.Json.Serialization; -using System.Threading.Tasks; -using Microsoft.Build.Execution; -using Microsoft.DotNet.Cli.Utils; namespace Microsoft.DotNet.MsiInstallerTests { @@ -77,7 +69,7 @@ public VirtualMachine(ITestOutputHelper log) if (File.Exists(_stateFile)) { string json = File.ReadAllText(_stateFile); - _rootState = JsonSerializer.Deserialize(json, GetSerializerOptions()).ToVMStateTree(); + _rootState = JsonSerializer.Deserialize(json, GetSerializerOptions()).ToVMStateTree(); } else { @@ -440,7 +432,6 @@ string VMPathToSharePath(string vmPath) return $@"\\{VMControl.VMMachineName}\{driveLetter}$\{pathUnderDrive}"; } - // Copilot wrote the entire body of this method string SharePathToVMPath(string sharePath) { if (!sharePath.StartsWith($@"\\{VMControl.VMMachineName}\")) From a8d57fd7b0843bb09d58d6f2c9ba491db184e1b0 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" Date: Sat, 16 Mar 2024 12:30:11 +0000 Subject: [PATCH 416/577] Update dependencies from https://github.com/dotnet/razor build Microsoft.AspNetCore.Mvc.Razor.Extensions.Tooling.Internal , Microsoft.CodeAnalysis.Razor.Tooling.Internal , Microsoft.NET.Sdk.Razor.SourceGenerators.Transport From Version 7.0.0-preview.24164.2 -> To Version 7.0.0-preview.24165.3 --- eng/Version.Details.xml | 12 ++++++------ eng/Versions.props | 6 +++--- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index d5e5298e2960..26ddb1fa1292 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -277,18 +277,18 @@ https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore da7e9894ce22ef8cc02e5acc56e95a6f8cf8f644 - + https://github.com/dotnet/razor - 55e0597a2090de3b98a4985346eb687b0aeda06f + 08af6175499b0615a266b11c46e6220880a186d1 - + https://github.com/dotnet/razor - 55e0597a2090de3b98a4985346eb687b0aeda06f + 08af6175499b0615a266b11c46e6220880a186d1 - + https://github.com/dotnet/razor - 55e0597a2090de3b98a4985346eb687b0aeda06f + 08af6175499b0615a266b11c46e6220880a186d1 https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore diff --git a/eng/Versions.props b/eng/Versions.props index 79acc1495acc..97763a74b0b2 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -175,9 +175,9 @@ - 7.0.0-preview.24164.4 - 7.0.0-preview.24164.4 - 7.0.0-preview.24164.4 + 7.0.0-preview.24165.3 + 7.0.0-preview.24165.3 + 7.0.0-preview.24165.3 From e22f0bd3e8fa7db2c9903df2ec4062a5614d840d Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" Date: Sat, 16 Mar 2024 12:31:55 +0000 Subject: [PATCH 417/577] Update dependencies from https://github.com/dotnet/roslyn build Microsoft.CodeAnalysis , Microsoft.CodeAnalysis.CSharp , Microsoft.CodeAnalysis.CSharp.CodeStyle , Microsoft.CodeAnalysis.CSharp.Features , Microsoft.CodeAnalysis.CSharp.Workspaces , Microsoft.CodeAnalysis.Workspaces.MSBuild , Microsoft.Net.Compilers.Toolset From Version 4.10.0-3.24164.3 -> To Version 4.10.0-3.24165.5 --- eng/Version.Details.xml | 28 ++++++++++++++-------------- eng/Versions.props | 14 +++++++------- 2 files changed, 21 insertions(+), 21 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 13ff7981a545..578a8f65ae8e 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -78,34 +78,34 @@ ac0d85557969d51bca72181514ddb7d5796fbbe2 - + https://github.com/dotnet/roslyn - 711e122c86db37658d2924f2499c775ce6007b68 + 93fb58100f90efe96051fe8531a008823f39c81b - + https://github.com/dotnet/roslyn - 711e122c86db37658d2924f2499c775ce6007b68 + 93fb58100f90efe96051fe8531a008823f39c81b - + https://github.com/dotnet/roslyn - 711e122c86db37658d2924f2499c775ce6007b68 + 93fb58100f90efe96051fe8531a008823f39c81b - + https://github.com/dotnet/roslyn - 711e122c86db37658d2924f2499c775ce6007b68 + 93fb58100f90efe96051fe8531a008823f39c81b - + https://github.com/dotnet/roslyn - 711e122c86db37658d2924f2499c775ce6007b68 + 93fb58100f90efe96051fe8531a008823f39c81b - + https://github.com/dotnet/roslyn - 711e122c86db37658d2924f2499c775ce6007b68 + 93fb58100f90efe96051fe8531a008823f39c81b - + https://github.com/dotnet/roslyn - 711e122c86db37658d2924f2499c775ce6007b68 + 93fb58100f90efe96051fe8531a008823f39c81b https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore diff --git a/eng/Versions.props b/eng/Versions.props index cd74bc459a70..bfd5c30e2cfb 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -154,13 +154,13 @@ - 4.10.0-3.24164.3 - 4.10.0-3.24164.3 - 4.10.0-3.24164.3 - 4.10.0-3.24164.3 - 4.10.0-3.24164.3 - 4.10.0-3.24164.3 - 4.10.0-3.24164.3 + 4.10.0-3.24165.5 + 4.10.0-3.24165.5 + 4.10.0-3.24165.5 + 4.10.0-3.24165.5 + 4.10.0-3.24165.5 + 4.10.0-3.24165.5 + 4.10.0-3.24165.5 $(MicrosoftNetCompilersToolsetPackageVersion) From ed52c413a0ad27e662c627a5518007b369941140 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" Date: Sat, 16 Mar 2024 12:33:30 +0000 Subject: [PATCH 418/577] Update dependencies from https://github.com/dotnet/arcade build Microsoft.DotNet.Arcade.Sdk , Microsoft.DotNet.Helix.Sdk , Microsoft.DotNet.SignTool , Microsoft.DotNet.XUnitExtensions From Version 8.0.0-beta.24161.7 -> To Version 8.0.0-beta.24165.4 --- eng/Version.Details.xml | 16 ++++++++-------- eng/Versions.props | 4 ++-- .../job/publish-build-assets.yml | 10 ++++++---- global.json | 4 ++-- 4 files changed, 18 insertions(+), 16 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 13ff7981a545..c778a2231a72 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -475,22 +475,22 @@ - + https://github.com/dotnet/arcade - cd10e5d3748676d70ae2b4d9c84f073eeb203cac + f311667e0587f19c3fa9553a909975662107a351 - + https://github.com/dotnet/arcade - cd10e5d3748676d70ae2b4d9c84f073eeb203cac + f311667e0587f19c3fa9553a909975662107a351 - + https://github.com/dotnet/arcade - cd10e5d3748676d70ae2b4d9c84f073eeb203cac + f311667e0587f19c3fa9553a909975662107a351 - + https://github.com/dotnet/arcade - cd10e5d3748676d70ae2b4d9c84f073eeb203cac + f311667e0587f19c3fa9553a909975662107a351 https://dev.azure.com/dnceng/internal/_git/dotnet-runtime diff --git a/eng/Versions.props b/eng/Versions.props index cd74bc459a70..b78049f79b84 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -34,7 +34,7 @@ 7.0.0 4.0.0 7.0.0 - 8.0.0-beta.24161.7 + 8.0.0-beta.24165.4 7.0.0-preview.22423.2 8.0.0 4.3.0 @@ -209,7 +209,7 @@ 6.12.0 6.1.0 - 8.0.0-beta.24161.7 + 8.0.0-beta.24165.4 4.18.4 1.3.2 8.0.0-beta.23607.1 diff --git a/eng/common/templates-official/job/publish-build-assets.yml b/eng/common/templates-official/job/publish-build-assets.yml index ea5104625fac..53138622fe7a 100644 --- a/eng/common/templates-official/job/publish-build-assets.yml +++ b/eng/common/templates-official/job/publish-build-assets.yml @@ -94,14 +94,16 @@ jobs: inputs: targetType: inline script: | - Add-Content -Path "$(Build.StagingDirectory)/ReleaseConfigs.txt" -Value $(BARBuildId) - Add-Content -Path "$(Build.StagingDirectory)/ReleaseConfigs.txt" -Value "$(DefaultChannels)" - Add-Content -Path "$(Build.StagingDirectory)/ReleaseConfigs.txt" -Value $(IsStableBuild) + New-Item -Path "$(Build.StagingDirectory)/ReleaseConfigs" -ItemType Directory -Force + $filePath = "$(Build.StagingDirectory)/ReleaseConfigs/ReleaseConfigs.txt" + Add-Content -Path $filePath -Value $(BARBuildId) + Add-Content -Path $filePath -Value "$(DefaultChannels)" + Add-Content -Path $filePath -Value $(IsStableBuild) - task: 1ES.PublishBuildArtifacts@1 displayName: Publish ReleaseConfigs Artifact inputs: - PathtoPublish: '$(Build.StagingDirectory)/ReleaseConfigs.txt' + PathtoPublish: '$(Build.StagingDirectory)/ReleaseConfigs' PublishLocation: Container ArtifactName: ReleaseConfigs diff --git a/global.json b/global.json index 985d3f491224..46226ea53fdb 100644 --- a/global.json +++ b/global.json @@ -14,7 +14,7 @@ } }, "msbuild-sdks": { - "Microsoft.DotNet.Arcade.Sdk": "8.0.0-beta.24161.7", - "Microsoft.DotNet.Helix.Sdk": "8.0.0-beta.24161.7" + "Microsoft.DotNet.Arcade.Sdk": "8.0.0-beta.24165.4", + "Microsoft.DotNet.Helix.Sdk": "8.0.0-beta.24165.4" } } From fdc59219c663cfa807401388f6f66b7f26e9a5b8 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" Date: Sun, 17 Mar 2024 12:20:26 +0000 Subject: [PATCH 419/577] Update dependencies from https://github.com/nuget/nuget.client build Microsoft.Build.NuGetSdkResolver , NuGet.Build.Tasks , NuGet.Build.Tasks.Console , NuGet.Build.Tasks.Pack , NuGet.CommandLine.XPlat , NuGet.Commands , NuGet.Common , NuGet.Configuration , NuGet.Credentials , NuGet.DependencyResolver.Core , NuGet.Frameworks , NuGet.LibraryModel , NuGet.Packaging , NuGet.ProjectModel , NuGet.Protocol , NuGet.Versioning From Version 6.10.0-preview.2.78 -> To Version 6.10.0-preview.2.81 --- eng/Version.Details.xml | 64 ++++++++++++++++++++--------------------- eng/Versions.props | 22 +++++++------- 2 files changed, 43 insertions(+), 43 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 13ff7981a545..aca80538ff08 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -115,69 +115,69 @@ https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore da7e9894ce22ef8cc02e5acc56e95a6f8cf8f644 - + https://github.com/nuget/nuget.client - 2fdd0d41e33c3354de2750fe154b56751a6682aa + 1845d6bd450a7453d573035371c9fec43683d1ef - + https://github.com/nuget/nuget.client - 2fdd0d41e33c3354de2750fe154b56751a6682aa + 1845d6bd450a7453d573035371c9fec43683d1ef - + https://github.com/nuget/nuget.client - 2fdd0d41e33c3354de2750fe154b56751a6682aa + 1845d6bd450a7453d573035371c9fec43683d1ef - + https://github.com/nuget/nuget.client - 2fdd0d41e33c3354de2750fe154b56751a6682aa + 1845d6bd450a7453d573035371c9fec43683d1ef - + https://github.com/nuget/nuget.client - 2fdd0d41e33c3354de2750fe154b56751a6682aa + 1845d6bd450a7453d573035371c9fec43683d1ef - + https://github.com/nuget/nuget.client - 2fdd0d41e33c3354de2750fe154b56751a6682aa + 1845d6bd450a7453d573035371c9fec43683d1ef - + https://github.com/nuget/nuget.client - 2fdd0d41e33c3354de2750fe154b56751a6682aa + 1845d6bd450a7453d573035371c9fec43683d1ef - + https://github.com/nuget/nuget.client - 2fdd0d41e33c3354de2750fe154b56751a6682aa + 1845d6bd450a7453d573035371c9fec43683d1ef - + https://github.com/nuget/nuget.client - 2fdd0d41e33c3354de2750fe154b56751a6682aa + 1845d6bd450a7453d573035371c9fec43683d1ef - + https://github.com/nuget/nuget.client - 2fdd0d41e33c3354de2750fe154b56751a6682aa + 1845d6bd450a7453d573035371c9fec43683d1ef - + https://github.com/nuget/nuget.client - 2fdd0d41e33c3354de2750fe154b56751a6682aa + 1845d6bd450a7453d573035371c9fec43683d1ef - + https://github.com/nuget/nuget.client - 2fdd0d41e33c3354de2750fe154b56751a6682aa + 1845d6bd450a7453d573035371c9fec43683d1ef - + https://github.com/nuget/nuget.client - 2fdd0d41e33c3354de2750fe154b56751a6682aa + 1845d6bd450a7453d573035371c9fec43683d1ef - + https://github.com/nuget/nuget.client - 2fdd0d41e33c3354de2750fe154b56751a6682aa + 1845d6bd450a7453d573035371c9fec43683d1ef - + https://github.com/nuget/nuget.client - 2fdd0d41e33c3354de2750fe154b56751a6682aa + 1845d6bd450a7453d573035371c9fec43683d1ef - + https://github.com/nuget/nuget.client - 2fdd0d41e33c3354de2750fe154b56751a6682aa + 1845d6bd450a7453d573035371c9fec43683d1ef https://github.com/microsoft/vstest diff --git a/eng/Versions.props b/eng/Versions.props index cd74bc459a70..b89a0e25e539 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -82,18 +82,18 @@ - 6.10.0-preview.2.78 - 6.10.0-preview.2.78 + 6.10.0-preview.2.81 + 6.10.0-preview.2.81 6.0.0-rc.278 - 6.10.0-preview.2.78 - 6.10.0-preview.2.78 - 6.10.0-preview.2.78 - 6.10.0-preview.2.78 - 6.10.0-preview.2.78 - 6.10.0-preview.2.78 - 6.10.0-preview.2.78 - 6.10.0-preview.2.78 - 6.10.0-preview.2.78 + 6.10.0-preview.2.81 + 6.10.0-preview.2.81 + 6.10.0-preview.2.81 + 6.10.0-preview.2.81 + 6.10.0-preview.2.81 + 6.10.0-preview.2.81 + 6.10.0-preview.2.81 + 6.10.0-preview.2.81 + 6.10.0-preview.2.81 $(NuGetPackagingPackageVersion) $(NuGetProjectModelPackageVersion) From c8b0a121d2aa6cf7d07bd60a4146e4a689697c80 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" Date: Sun, 17 Mar 2024 12:22:49 +0000 Subject: [PATCH 420/577] Update dependencies from https://github.com/dotnet/razor build Microsoft.AspNetCore.Mvc.Razor.Extensions.Tooling.Internal , Microsoft.CodeAnalysis.Razor.Tooling.Internal , Microsoft.NET.Sdk.Razor.SourceGenerators.Transport From Version 7.0.0-preview.24164.2 -> To Version 7.0.0-preview.24166.1 --- eng/Version.Details.xml | 12 ++++++------ eng/Versions.props | 6 +++--- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 26ddb1fa1292..67ac252ac9ee 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -277,18 +277,18 @@ https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore da7e9894ce22ef8cc02e5acc56e95a6f8cf8f644 - + https://github.com/dotnet/razor - 08af6175499b0615a266b11c46e6220880a186d1 + 69e4d09f1e7054646ea601e488d3ccdce96c1069 - + https://github.com/dotnet/razor - 08af6175499b0615a266b11c46e6220880a186d1 + 69e4d09f1e7054646ea601e488d3ccdce96c1069 - + https://github.com/dotnet/razor - 08af6175499b0615a266b11c46e6220880a186d1 + 69e4d09f1e7054646ea601e488d3ccdce96c1069 https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore diff --git a/eng/Versions.props b/eng/Versions.props index 97763a74b0b2..3f0c41efc919 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -175,9 +175,9 @@ - 7.0.0-preview.24165.3 - 7.0.0-preview.24165.3 - 7.0.0-preview.24165.3 + 7.0.0-preview.24166.1 + 7.0.0-preview.24166.1 + 7.0.0-preview.24166.1 From 855b129f6f86b01cf1e0f3e48b867cdcd5ba7f1d Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" Date: Sun, 17 Mar 2024 12:24:38 +0000 Subject: [PATCH 421/577] Update dependencies from https://github.com/dotnet/roslyn build Microsoft.CodeAnalysis , Microsoft.CodeAnalysis.CSharp , Microsoft.CodeAnalysis.CSharp.CodeStyle , Microsoft.CodeAnalysis.CSharp.Features , Microsoft.CodeAnalysis.CSharp.Workspaces , Microsoft.CodeAnalysis.Workspaces.MSBuild , Microsoft.Net.Compilers.Toolset From Version 4.10.0-3.24164.3 -> To Version 4.10.0-3.24165.5 From 56ab9fb68174f6da0d1548d203a0b848ad0cbabe Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" Date: Sun, 17 Mar 2024 12:26:14 +0000 Subject: [PATCH 422/577] Update dependencies from https://github.com/dotnet/arcade build Microsoft.DotNet.Arcade.Sdk , Microsoft.DotNet.Helix.Sdk , Microsoft.DotNet.SignTool , Microsoft.DotNet.XUnitExtensions From Version 8.0.0-beta.24161.7 -> To Version 8.0.0-beta.24165.4 From f1534e94aee506b61ed71cd13ae0c9b69321ef31 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" Date: Mon, 18 Mar 2024 12:14:13 +0000 Subject: [PATCH 423/577] Update dependencies from https://github.com/dotnet/fsharp build Microsoft.SourceBuild.Intermediate.fsharp , Microsoft.FSharp.Compiler From Version 8.0.300-beta.24163.4 -> To Version 8.0.300-beta.24165.2 --- eng/Version.Details.xml | 8 ++++---- eng/Versions.props | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 6b4138a7545a..f47f7c121035 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -64,13 +64,13 @@ 0326fd7c9e131c4c26bac3c0f72a43ef9fd2812c - + https://github.com/dotnet/fsharp - 2c03643199368f07a3326709fc68abcbfc482a06 + a0081443628b0c582abe66f83944519378d2a5dd - + https://github.com/dotnet/fsharp - 2c03643199368f07a3326709fc68abcbfc482a06 + a0081443628b0c582abe66f83944519378d2a5dd diff --git a/eng/Versions.props b/eng/Versions.props index 82bb88ee7633..b70f9cd00030 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -150,7 +150,7 @@ - 12.8.300-beta.24163.4 + 12.8.300-beta.24165.2 From 2d73d5d2d21e0843b7dd77ea7abe8fe21f8892de Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" Date: Mon, 18 Mar 2024 12:14:37 +0000 Subject: [PATCH 424/577] Update dependencies from https://github.com/dotnet/roslyn build Microsoft.CodeAnalysis , Microsoft.CodeAnalysis.CSharp , Microsoft.CodeAnalysis.CSharp.CodeStyle , Microsoft.CodeAnalysis.CSharp.Features , Microsoft.CodeAnalysis.CSharp.Workspaces , Microsoft.CodeAnalysis.Workspaces.MSBuild , Microsoft.Net.Compilers.Toolset From Version 4.10.0-3.24165.5 -> To Version 4.10.0-3.24168.1 --- eng/Version.Details.xml | 28 ++++++++++++++-------------- eng/Versions.props | 14 +++++++------- 2 files changed, 21 insertions(+), 21 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 6b4138a7545a..c0e6e03261a8 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -78,34 +78,34 @@ ac0d85557969d51bca72181514ddb7d5796fbbe2 - + https://github.com/dotnet/roslyn - 93fb58100f90efe96051fe8531a008823f39c81b + 2348a50bb566b39305c474793b43edb5635db6f4 - + https://github.com/dotnet/roslyn - 93fb58100f90efe96051fe8531a008823f39c81b + 2348a50bb566b39305c474793b43edb5635db6f4 - + https://github.com/dotnet/roslyn - 93fb58100f90efe96051fe8531a008823f39c81b + 2348a50bb566b39305c474793b43edb5635db6f4 - + https://github.com/dotnet/roslyn - 93fb58100f90efe96051fe8531a008823f39c81b + 2348a50bb566b39305c474793b43edb5635db6f4 - + https://github.com/dotnet/roslyn - 93fb58100f90efe96051fe8531a008823f39c81b + 2348a50bb566b39305c474793b43edb5635db6f4 - + https://github.com/dotnet/roslyn - 93fb58100f90efe96051fe8531a008823f39c81b + 2348a50bb566b39305c474793b43edb5635db6f4 - + https://github.com/dotnet/roslyn - 93fb58100f90efe96051fe8531a008823f39c81b + 2348a50bb566b39305c474793b43edb5635db6f4 https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore diff --git a/eng/Versions.props b/eng/Versions.props index 82bb88ee7633..814f9da7ac31 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -154,13 +154,13 @@ - 4.10.0-3.24165.5 - 4.10.0-3.24165.5 - 4.10.0-3.24165.5 - 4.10.0-3.24165.5 - 4.10.0-3.24165.5 - 4.10.0-3.24165.5 - 4.10.0-3.24165.5 + 4.10.0-3.24168.1 + 4.10.0-3.24168.1 + 4.10.0-3.24168.1 + 4.10.0-3.24168.1 + 4.10.0-3.24168.1 + 4.10.0-3.24168.1 + 4.10.0-3.24168.1 $(MicrosoftNetCompilersToolsetPackageVersion) From b1b2adaa926fb610f814472ddbfcfb24e55d5262 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" Date: Mon, 18 Mar 2024 12:15:01 +0000 Subject: [PATCH 425/577] Update dependencies from https://github.com/dotnet/templating build Microsoft.TemplateEngine.Abstractions , Microsoft.TemplateEngine.Mocks From Version 8.0.300-preview.24163.5 -> To Version 8.0.300-preview.24167.2 --- eng/Version.Details.xml | 8 ++++---- eng/Versions.props | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 6b4138a7545a..f6e2f6ea7797 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -1,14 +1,14 @@ - + https://github.com/dotnet/templating - 5a3dcbc8022122914aee42fbe0f5143576b2d848 + ca94dec30109197c31f2431c3b3941aa8ea21512 - + https://github.com/dotnet/templating - 5a3dcbc8022122914aee42fbe0f5143576b2d848 + ca94dec30109197c31f2431c3b3941aa8ea21512 https://dev.azure.com/dnceng/internal/_git/dotnet-runtime diff --git a/eng/Versions.props b/eng/Versions.props index 82bb88ee7633..423305a7d528 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -137,13 +137,13 @@ - 8.0.300-preview.24163.5 + 8.0.300-preview.24167.2 $(MicrosoftTemplateEngineAbstractionsPackageVersion) $(MicrosoftTemplateEngineAbstractionsPackageVersion) $(MicrosoftTemplateEngineAbstractionsPackageVersion) $(MicrosoftTemplateEngineAbstractionsPackageVersion) - 8.0.300-preview.24163.5 + 8.0.300-preview.24167.2 $(MicrosoftTemplateEngineMocksPackageVersion) $(MicrosoftTemplateEngineAbstractionsPackageVersion) $(MicrosoftTemplateEngineMocksPackageVersion) From ef46918440f2135488e344d07e76847d3ef134a4 Mon Sep 17 00:00:00 2001 From: Forgind <12969783+Forgind@users.noreply.github.com> Date: Mon, 18 Mar 2024 11:23:16 -0700 Subject: [PATCH 426/577] Tell MSBuild to fail when enumerating a drive --- src/Cli/dotnet/Program.cs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/Cli/dotnet/Program.cs b/src/Cli/dotnet/Program.cs index 3f178fda6490..6a4635225d5a 100644 --- a/src/Cli/dotnet/Program.cs +++ b/src/Cli/dotnet/Program.cs @@ -42,6 +42,11 @@ public static int Main(string[] args) bool perfLogEnabled = Env.GetEnvironmentVariableAsBool("DOTNET_CLI_PERF_LOG", false); + if (string.IsNullOrEmpty(Env.GetEnvironmentVariable("MSBUILDFAILONDRIVEENUMERATINGWILDCARD"))) + { + Environment.SetEnvironmentVariable("MSBUILDFAILONDRIVEENUMERATINGWILDCARD", "1"); + } + // Avoid create temp directory with root permission and later prevent access in non sudo if (SudoEnvironmentDirectoryOverride.IsRunningUnderSudo()) { From a0ce729589330c9138fab1c0312792c6ea272f6d Mon Sep 17 00:00:00 2001 From: Marc Paine Date: Mon, 18 Mar 2024 12:20:17 -0700 Subject: [PATCH 427/577] Add nuget.localization to codeflow --- eng/Version.Details.xml | 4 ++++ eng/Versions.props | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 6149169fc7d7..474acaf3a619 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -179,6 +179,10 @@ https://github.com/nuget/nuget.client 1845d6bd450a7453d573035371c9fec43683d1ef + + https://github.com/nuget/nuget.client + 1845d6bd450a7453d573035371c9fec43683d1ef + https://github.com/microsoft/vstest c609e2c022b0087b227436a4debf45525eed00e9 diff --git a/eng/Versions.props b/eng/Versions.props index 8155a5213178..3a15a234a462 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -84,7 +84,7 @@ 6.10.0-preview.2.81 6.10.0-preview.2.81 - 6.0.0-rc.278 + 6.10.0-preview.2.81 6.10.0-preview.2.81 6.10.0-preview.2.81 6.10.0-preview.2.81 From 90cd2f5e826b2c394005c76e69f4f7b0a8b7345e Mon Sep 17 00:00:00 2001 From: Daniel Plaisted Date: Mon, 18 Mar 2024 17:34:29 -0400 Subject: [PATCH 428/577] Show workload version even if no workload set is installed --- .../SdkDirectoryWorkloadManifestProvider.cs | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/SdkDirectoryWorkloadManifestProvider.cs b/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/SdkDirectoryWorkloadManifestProvider.cs index eeefd7dee1c7..3ec592ccd955 100644 --- a/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/SdkDirectoryWorkloadManifestProvider.cs +++ b/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/SdkDirectoryWorkloadManifestProvider.cs @@ -159,11 +159,6 @@ public void RefreshWorkloadManifests() return _workloadSet?.Version!; } - if (InstallStateContents.FromPath(Path.Combine(WorkloadInstallType.GetInstallStateFolder(_sdkVersionBand, _sdkRootPath), "default.json")).UseWorkloadSets == true) - { - return null; - } - using (SHA256 sha256Hash = SHA256.Create()) { byte[] bytes = sha256Hash.ComputeHash(Encoding.UTF8.GetBytes(string.Join(";", From ae688137f9a8db206b2fc1f2b68d3a9dca66cbf1 Mon Sep 17 00:00:00 2001 From: Daniel Plaisted Date: Mon, 18 Mar 2024 17:35:35 -0400 Subject: [PATCH 429/577] Move VM testing framework to subfolder --- .../{ => Framework}/RemoteDirectory.cs | 2 +- .../{ => Framework}/RemoteFile.cs | 2 +- .../{ => Framework}/VMAction.cs | 2 +- .../{ => Framework}/VMControl.cs | 18 +-- .../{ => Framework}/VMStateTree.cs | 7 +- .../Framework/VMTestBase.cs | 123 ++++++++++++++++++ .../{ => Framework}/VMTestSettings.cs | 2 +- .../{ => Framework}/VirtualMachine.cs | 6 +- .../MsiInstallerTests.cs | 110 +--------------- 9 files changed, 145 insertions(+), 127 deletions(-) rename src/Tests/dotnet-MsiInstallation.Tests/{ => Framework}/RemoteDirectory.cs (96%) rename src/Tests/dotnet-MsiInstallation.Tests/{ => Framework}/RemoteFile.cs (96%) rename src/Tests/dotnet-MsiInstallation.Tests/{ => Framework}/VMAction.cs (99%) rename src/Tests/dotnet-MsiInstallation.Tests/{ => Framework}/VMControl.cs (95%) rename src/Tests/dotnet-MsiInstallation.Tests/{ => Framework}/VMStateTree.cs (94%) create mode 100644 src/Tests/dotnet-MsiInstallation.Tests/Framework/VMTestBase.cs rename src/Tests/dotnet-MsiInstallation.Tests/{ => Framework}/VMTestSettings.cs (90%) rename src/Tests/dotnet-MsiInstallation.Tests/{ => Framework}/VirtualMachine.cs (99%) diff --git a/src/Tests/dotnet-MsiInstallation.Tests/RemoteDirectory.cs b/src/Tests/dotnet-MsiInstallation.Tests/Framework/RemoteDirectory.cs similarity index 96% rename from src/Tests/dotnet-MsiInstallation.Tests/RemoteDirectory.cs rename to src/Tests/dotnet-MsiInstallation.Tests/Framework/RemoteDirectory.cs index 1c4762e1385e..f84cdbfc8867 100644 --- a/src/Tests/dotnet-MsiInstallation.Tests/RemoteDirectory.cs +++ b/src/Tests/dotnet-MsiInstallation.Tests/Framework/RemoteDirectory.cs @@ -8,7 +8,7 @@ using System.Threading.Tasks; using FluentAssertions.Execution; -namespace Microsoft.DotNet.MsiInstallerTests +namespace Microsoft.DotNet.MsiInstallerTests.Framework { abstract class RemoteDirectory { diff --git a/src/Tests/dotnet-MsiInstallation.Tests/RemoteFile.cs b/src/Tests/dotnet-MsiInstallation.Tests/Framework/RemoteFile.cs similarity index 96% rename from src/Tests/dotnet-MsiInstallation.Tests/RemoteFile.cs rename to src/Tests/dotnet-MsiInstallation.Tests/Framework/RemoteFile.cs index 0c09dd4f6657..fcdba5a6a00c 100644 --- a/src/Tests/dotnet-MsiInstallation.Tests/RemoteFile.cs +++ b/src/Tests/dotnet-MsiInstallation.Tests/Framework/RemoteFile.cs @@ -9,7 +9,7 @@ using System.Threading.Tasks; using FluentAssertions.Execution; -namespace Microsoft.DotNet.MsiInstallerTests +namespace Microsoft.DotNet.MsiInstallerTests.Framework { abstract class RemoteFile { diff --git a/src/Tests/dotnet-MsiInstallation.Tests/VMAction.cs b/src/Tests/dotnet-MsiInstallation.Tests/Framework/VMAction.cs similarity index 99% rename from src/Tests/dotnet-MsiInstallation.Tests/VMAction.cs rename to src/Tests/dotnet-MsiInstallation.Tests/Framework/VMAction.cs index a6591b1b7a53..34ca1f806ebf 100644 --- a/src/Tests/dotnet-MsiInstallation.Tests/VMAction.cs +++ b/src/Tests/dotnet-MsiInstallation.Tests/Framework/VMAction.cs @@ -10,7 +10,7 @@ using System.Threading.Tasks; using Microsoft.DotNet.Cli.Utils; -namespace Microsoft.DotNet.MsiInstallerTests +namespace Microsoft.DotNet.MsiInstallerTests.Framework { abstract class VMAction { diff --git a/src/Tests/dotnet-MsiInstallation.Tests/VMControl.cs b/src/Tests/dotnet-MsiInstallation.Tests/Framework/VMControl.cs similarity index 95% rename from src/Tests/dotnet-MsiInstallation.Tests/VMControl.cs rename to src/Tests/dotnet-MsiInstallation.Tests/Framework/VMControl.cs index 07406fb2588f..b619124f24e8 100644 --- a/src/Tests/dotnet-MsiInstallation.Tests/VMControl.cs +++ b/src/Tests/dotnet-MsiInstallation.Tests/Framework/VMControl.cs @@ -6,7 +6,7 @@ using Microsoft.Management.Infrastructure; using Microsoft.Management.Infrastructure.Serialization; -namespace Microsoft.DotNet.MsiInstallerTests +namespace Microsoft.DotNet.MsiInstallerTests.Framework { internal class VMControl : IDisposable { @@ -73,7 +73,7 @@ public CommandResult RunCommandOnVM(string[] args, string workingDirectory = nul { var remoteCommand = new RemoteCommand(Log, VMMachineName, _psExecPath, workingDirectory, args); - for (int i=0; i<3; i++) + for (int i = 0; i < 3; i++) { var result = remoteCommand.Execute(); if (result.ExitCode != 6 && !result.StdErr.Contains("The handle is invalid")) @@ -204,7 +204,7 @@ public async Task SetRunningAsync(bool running) { VMEnabledState getCurrentState() { - var state = (VMEnabledState) (UInt16)VMInstance.CimInstanceProperties["EnabledState"].Value; + var state = (VMEnabledState)(ushort)VMInstance.CimInstanceProperties["EnabledState"].Value; return state; } @@ -219,7 +219,7 @@ VMEnabledState getCurrentState() var methodParameters = new CimMethodParametersCollection() { - CimMethodParameter.Create("RequestedState", (UInt16) targetState, CimFlags.In) + CimMethodParameter.Create("RequestedState", (ushort) targetState, CimFlags.In) }; @@ -245,13 +245,13 @@ private async Task WaitForJobSuccess(CimMethodResult result) { CimInstance job = (CimInstance)result.OutParameters["Job"].Value; job = _session.GetInstance(virtNamespace, job); - while (IsRunning((JobState)(UInt16)job.CimInstanceProperties["JobState"].Value)) + while (IsRunning((JobState)(ushort)job.CimInstanceProperties["JobState"].Value)) { await Task.Delay(100); job = _session.GetInstance(job.CimSystemProperties.Namespace, job); } - var jobState = (JobState)(UInt16)job.CimInstanceProperties["JobState"].Value; + var jobState = (JobState)(ushort)job.CimInstanceProperties["JobState"].Value; if (jobState != JobState.Completed && jobState != JobState.CompletedWithWarnings) { Log.WriteLine("Job failed: " + jobState); @@ -271,7 +271,7 @@ private async Task WaitForJobSuccess(CimMethodResult result) } else { - if (result.ReturnValue.Value is UInt32 returnValue) + if (result.ReturnValue.Value is uint returnValue) { if (returnValue != 0) { @@ -305,7 +305,7 @@ enum JobState CompletedWithWarnings = 32768 } - enum VMEnabledState : UInt16 + enum VMEnabledState : ushort { Unknown = 0, Other = 1, @@ -314,7 +314,7 @@ enum VMEnabledState : UInt16 ShuttingDown = 4, NotApplicable = 5, EnabledButOffline = 6, - + } class RemoteCommand : TestCommand diff --git a/src/Tests/dotnet-MsiInstallation.Tests/VMStateTree.cs b/src/Tests/dotnet-MsiInstallation.Tests/Framework/VMStateTree.cs similarity index 94% rename from src/Tests/dotnet-MsiInstallation.Tests/VMStateTree.cs rename to src/Tests/dotnet-MsiInstallation.Tests/Framework/VMStateTree.cs index 1c08293addff..aba8555d4e6c 100644 --- a/src/Tests/dotnet-MsiInstallation.Tests/VMStateTree.cs +++ b/src/Tests/dotnet-MsiInstallation.Tests/Framework/VMStateTree.cs @@ -1,11 +1,11 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -namespace Microsoft.DotNet.MsiInstallerTests +namespace Microsoft.DotNet.MsiInstallerTests.Framework { internal class VMStateTree { - public string SnapshotId { get; set; } + public string SnapshotId { get; set; } public string SnapshotName { get; set; } public Dictionary Actions { get; set; } = new(); @@ -18,7 +18,8 @@ public SerializableVMStateTree ToSerializeable() { SnapshotId = SnapshotId, SnapshotName = SnapshotName, - Actions = Actions.Select(a => new SerializableVMStateTree.Entry() { + Actions = Actions.Select(a => new SerializableVMStateTree.Entry() + { Action = a.Key, ActionResult = a.Value.actionResult, ResultingState = a.Value.resultingState.ToSerializeable() diff --git a/src/Tests/dotnet-MsiInstallation.Tests/Framework/VMTestBase.cs b/src/Tests/dotnet-MsiInstallation.Tests/Framework/VMTestBase.cs new file mode 100644 index 000000000000..ea73e4c54f41 --- /dev/null +++ b/src/Tests/dotnet-MsiInstallation.Tests/Framework/VMTestBase.cs @@ -0,0 +1,123 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using Microsoft.NET.Sdk.WorkloadManifestReader; + +namespace Microsoft.DotNet.MsiInstallerTests.Framework +{ + public class VMTestBase : SdkTest, IDisposable + { + internal VirtualMachine VM { get; } + + public VMTestBase(ITestOutputHelper log) : base(log) + { + VM = new VirtualMachine(Log); + } + + public virtual void Dispose() + { + VM.Dispose(); + } + + protected string SdkInstallerVersion + { + get + { + if (!string.IsNullOrEmpty(VM.VMTestSettings.SdkInstallerVersion)) + { + return VM.VMTestSettings.SdkInstallerVersion; + } + else + { + return "8.0.203"; + } + } + } + + protected string SdkInstallerFileName => $"dotnet-sdk-{SdkInstallerVersion}-win-x64.exe"; + + protected void InstallSdk(bool deployStage2 = true) + { + VM.CreateRunCommand("setx", "DOTNET_NOLOGO", "true") + .WithDescription("Disable .NET SDK first run message") + .Execute() + .Should() + .Pass(); + + VM.CreateRunCommand($@"c:\SdkTesting\{SdkInstallerFileName}", "/quiet") + .WithDescription($"Install SDK {SdkInstallerVersion}") + .Execute() + .Should() + .Pass(); + + if (deployStage2) + { + DeployStage2Sdk(); + } + } + + protected void UninstallSdk() + { + VM.CreateRunCommand($@"c:\SdkTesting\{SdkInstallerFileName}", "/quiet", "/uninstall") + .WithDescription($"Uninstall SDK {SdkInstallerVersion}") + .Execute() + .Should() + .Pass(); + } + + protected void DeployStage2Sdk() + { + if (!VM.VMTestSettings.ShouldTestStage2) + { + return; + } + + var installedSdkFolder = $@"c:\Program Files\dotnet\sdk\{SdkInstallerVersion}"; + + Log.WriteLine($"Deploying SDK from {TestContext.Current.ToolsetUnderTest.SdkFolderUnderTest} to {installedSdkFolder} on VM."); + + var vmVersionFilePath = Path.Combine(installedSdkFolder, ".version"); + + var existingVersionFileContents = VM.GetRemoteFile(vmVersionFilePath).ReadAllText().Split(Environment.NewLine); + var newVersionFileContents = File.ReadAllLines(Path.Combine(TestContext.Current.ToolsetUnderTest.SdkFolderUnderTest, ".version")); + newVersionFileContents[1] = existingVersionFileContents[1]; + + // TODO: It would be nice if the description included the date/time of the SDK build, to distinguish different snapshots + VM.CreateActionGroup("Deploy Stage 2 SDK", + VM.CopyFolder(TestContext.Current.ToolsetUnderTest.SdkFolderUnderTest, installedSdkFolder), + VM.WriteFile(vmVersionFilePath, string.Join(Environment.NewLine, newVersionFileContents))) + .Execute() + .Should() + .Pass(); + } + + protected string GetInstalledSdkVersion() + { + var command = VM.CreateRunCommand("dotnet", "--version"); + command.IsReadOnly = true; + var result = command.Execute(); + result.Should().Pass(); + return result.StdOut; + } + + protected WorkloadSet GetRollback() + { + var result = VM.CreateRunCommand("dotnet", "workload", "update", "--print-rollback") + .WithIsReadOnly(true) + .Execute(); + + result.Should().Pass(); + + return ParseRollbackOutput(result.StdOut); + } + + protected WorkloadSet ParseRollbackOutput(string output) + { + var filteredOutput = string.Join(Environment.NewLine, + output.Split(Environment.NewLine) + .Except(["==workloadRollbackDefinitionJsonOutputStart==", "==workloadRollbackDefinitionJsonOutputEnd=="])); + + return WorkloadSet.FromJson(filteredOutput, defaultFeatureBand: new SdkFeatureBand(SdkInstallerVersion)); + } + } +} diff --git a/src/Tests/dotnet-MsiInstallation.Tests/VMTestSettings.cs b/src/Tests/dotnet-MsiInstallation.Tests/Framework/VMTestSettings.cs similarity index 90% rename from src/Tests/dotnet-MsiInstallation.Tests/VMTestSettings.cs rename to src/Tests/dotnet-MsiInstallation.Tests/Framework/VMTestSettings.cs index 22fbdf22e83d..82670bfd72e2 100644 --- a/src/Tests/dotnet-MsiInstallation.Tests/VMTestSettings.cs +++ b/src/Tests/dotnet-MsiInstallation.Tests/Framework/VMTestSettings.cs @@ -7,7 +7,7 @@ using System.Text; using System.Threading.Tasks; -namespace Microsoft.DotNet.MsiInstallerTests +namespace Microsoft.DotNet.MsiInstallerTests.Framework { internal class VMTestSettings { diff --git a/src/Tests/dotnet-MsiInstallation.Tests/VirtualMachine.cs b/src/Tests/dotnet-MsiInstallation.Tests/Framework/VirtualMachine.cs similarity index 99% rename from src/Tests/dotnet-MsiInstallation.Tests/VirtualMachine.cs rename to src/Tests/dotnet-MsiInstallation.Tests/Framework/VirtualMachine.cs index 8ebeda0d4ec4..b075df512e4a 100644 --- a/src/Tests/dotnet-MsiInstallation.Tests/VirtualMachine.cs +++ b/src/Tests/dotnet-MsiInstallation.Tests/Framework/VirtualMachine.cs @@ -4,7 +4,7 @@ using System.Text.Json; using System.Text.Json.Serialization; -namespace Microsoft.DotNet.MsiInstallerTests +namespace Microsoft.DotNet.MsiInstallerTests.Framework { class VirtualMachine : IDisposable { @@ -130,7 +130,7 @@ void Recurse(VMStateTree node) Log.WriteLine($"Removing missing snapshot from tree: {nodeToRemove.Value.resultingState.SnapshotName}"); node.Actions.Remove(nodeToRemove.Key); } - + foreach (var result in node.Actions.Select(a => a.Value.resultingState)) { Recurse(result); @@ -211,7 +211,7 @@ void LogActionResult(SerializedVMAction action, VMActionResult result) } else if (action.Type == VMActionType.ActionGroup && result.GroupedResults != null) { - for (int i=0; i $"dotnet-sdk-{SdkInstallerVersion}-win-x64.exe"; - const string RollbackRC1 = """ { "microsoft.net.sdk.android": "34.0.0-rc.1.432/8.0.100-rc.1", @@ -61,45 +44,8 @@ string SdkInstallerVersion } """; - VirtualMachine VM { get; } - public WorkloadTests(ITestOutputHelper log) : base(log) { - VM = new VirtualMachine(Log); - } - - public void Dispose() - { - VM.Dispose(); - } - - void InstallSdk(bool deployStage2 = true) - { - VM.CreateRunCommand("setx", "DOTNET_NOLOGO", "true") - .WithDescription("Disable .NET SDK first run message") - .Execute() - .Should() - .Pass(); - - VM.CreateRunCommand($@"c:\SdkTesting\{SdkInstallerFileName}", "/quiet") - .WithDescription($"Install SDK {SdkInstallerVersion}") - .Execute() - .Should() - .Pass(); - - if (deployStage2) - { - DeployStage2Sdk(); - } - } - - void UninstallSdk() - { - VM.CreateRunCommand($@"c:\SdkTesting\{SdkInstallerFileName}", "/quiet", "/uninstall") - .WithDescription($"Uninstall SDK {SdkInstallerVersion}") - .Execute() - .Should() - .Pass(); } private CommandResult ApplyManifests(string manifestContents, string rollbackID) @@ -286,14 +232,6 @@ public void ApplyRollbackShouldNotUpdateAdvertisingManifests() throw new NotImplementedException(); } - string GetInstalledSdkVersion() - { - var command = VM.CreateRunCommand("dotnet", "--version"); - command.IsReadOnly = true; - var result = command.Execute(); - result.Should().Pass(); - return result.StdOut; - } void TestWasmWorkload() { @@ -372,31 +310,7 @@ void CheckForDuplicateManifests() return installedManifestVersions; } - void DeployStage2Sdk() - { - if (!VM.VMTestSettings.ShouldTestStage2) - { - return; - } - - var installedSdkFolder = $@"c:\Program Files\dotnet\sdk\{SdkInstallerVersion}"; - Log.WriteLine($"Deploying SDK from {TestContext.Current.ToolsetUnderTest.SdkFolderUnderTest} to {installedSdkFolder} on VM."); - - var vmVersionFilePath = Path.Combine(installedSdkFolder, ".version"); - - var existingVersionFileContents = VM.GetRemoteFile(vmVersionFilePath).ReadAllText().Split(Environment.NewLine); - var newVersionFileContents = File.ReadAllLines(Path.Combine(TestContext.Current.ToolsetUnderTest.SdkFolderUnderTest, ".version")); - newVersionFileContents[1] = existingVersionFileContents[1]; - - // TODO: It would be nice if the description included the date/time of the SDK build, to distinguish different snapshots - VM.CreateActionGroup("Deploy Stage 2 SDK", - VM.CopyFolder(TestContext.Current.ToolsetUnderTest.SdkFolderUnderTest, installedSdkFolder), - VM.WriteFile(vmVersionFilePath, string.Join(Environment.NewLine, newVersionFileContents))) - .Execute() - .Should() - .Pass(); - } CommandResult InstallWorkload(string workloadName) { @@ -419,25 +333,5 @@ string ListWorkloads() return result.StdOut; } - - WorkloadSet GetRollback() - { - var result = VM.CreateRunCommand("dotnet", "workload", "update", "--print-rollback") - .WithIsReadOnly(true) - .Execute(); - - result.Should().Pass(); - - return ParseRollbackOutput(result.StdOut); - } - - WorkloadSet ParseRollbackOutput(string output) - { - var filteredOutput = string.Join(Environment.NewLine, - output.Split(Environment.NewLine) - .Except(["==workloadRollbackDefinitionJsonOutputStart==", "==workloadRollbackDefinitionJsonOutputEnd=="])); - - return WorkloadSet.FromJson(filteredOutput, defaultFeatureBand: new SdkFeatureBand(SdkInstallerVersion)); - } } } From 25e052eb36fa9ba18d943bfdd7390649838974ec Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" Date: Tue, 19 Mar 2024 12:28:32 +0000 Subject: [PATCH 430/577] Update dependencies from https://github.com/dotnet/fsharp build Microsoft.SourceBuild.Intermediate.fsharp , Microsoft.FSharp.Compiler From Version 8.0.300-beta.24165.2 -> To Version 8.0.300-beta.24168.9 --- eng/Version.Details.xml | 8 ++++---- eng/Versions.props | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 6149169fc7d7..e90922330b90 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -64,13 +64,13 @@ 0326fd7c9e131c4c26bac3c0f72a43ef9fd2812c - + https://github.com/dotnet/fsharp - a0081443628b0c582abe66f83944519378d2a5dd + e18404fcaf90b0ee9bbf588ec32d07f466f16fe7 - + https://github.com/dotnet/fsharp - a0081443628b0c582abe66f83944519378d2a5dd + e18404fcaf90b0ee9bbf588ec32d07f466f16fe7 diff --git a/eng/Versions.props b/eng/Versions.props index 8155a5213178..6dbe5199ef79 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -150,7 +150,7 @@ - 12.8.300-beta.24165.2 + 12.8.300-beta.24168.9 From 515b07a1aa5e449183f7ade2ad4602eb316e1220 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" Date: Tue, 19 Mar 2024 12:28:54 +0000 Subject: [PATCH 431/577] Update dependencies from https://github.com/dotnet/razor build Microsoft.AspNetCore.Mvc.Razor.Extensions.Tooling.Internal , Microsoft.CodeAnalysis.Razor.Tooling.Internal , Microsoft.NET.Sdk.Razor.SourceGenerators.Transport From Version 7.0.0-preview.24166.1 -> To Version 7.0.0-preview.24169.1 --- eng/Version.Details.xml | 12 ++++++------ eng/Versions.props | 6 +++--- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 6149169fc7d7..e895cbcb6a30 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -277,18 +277,18 @@ https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore da7e9894ce22ef8cc02e5acc56e95a6f8cf8f644 - + https://github.com/dotnet/razor - 69e4d09f1e7054646ea601e488d3ccdce96c1069 + 12e83cdb9342aa1be480089f96e4c58e41c091e5 - + https://github.com/dotnet/razor - 69e4d09f1e7054646ea601e488d3ccdce96c1069 + 12e83cdb9342aa1be480089f96e4c58e41c091e5 - + https://github.com/dotnet/razor - 69e4d09f1e7054646ea601e488d3ccdce96c1069 + 12e83cdb9342aa1be480089f96e4c58e41c091e5 https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore diff --git a/eng/Versions.props b/eng/Versions.props index 8155a5213178..7cc2eaa0c0ca 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -175,9 +175,9 @@ - 7.0.0-preview.24166.1 - 7.0.0-preview.24166.1 - 7.0.0-preview.24166.1 + 7.0.0-preview.24169.1 + 7.0.0-preview.24169.1 + 7.0.0-preview.24169.1 From a220610303010f7fb81c7faee3b300b735ab679e Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" Date: Tue, 19 Mar 2024 12:29:17 +0000 Subject: [PATCH 432/577] Update dependencies from https://github.com/dotnet/roslyn build Microsoft.CodeAnalysis , Microsoft.CodeAnalysis.CSharp , Microsoft.CodeAnalysis.CSharp.CodeStyle , Microsoft.CodeAnalysis.CSharp.Features , Microsoft.CodeAnalysis.CSharp.Workspaces , Microsoft.CodeAnalysis.Workspaces.MSBuild , Microsoft.Net.Compilers.Toolset From Version 4.10.0-3.24168.1 -> To Version 4.10.0-3.24168.9 --- eng/Version.Details.xml | 28 ++++++++++++++-------------- eng/Versions.props | 14 +++++++------- 2 files changed, 21 insertions(+), 21 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 6149169fc7d7..11516ef9c808 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -78,34 +78,34 @@ ac0d85557969d51bca72181514ddb7d5796fbbe2 - + https://github.com/dotnet/roslyn - 2348a50bb566b39305c474793b43edb5635db6f4 + 134bc2e6f0edbe13c7cc465d97592d75f9d1a197 - + https://github.com/dotnet/roslyn - 2348a50bb566b39305c474793b43edb5635db6f4 + 134bc2e6f0edbe13c7cc465d97592d75f9d1a197 - + https://github.com/dotnet/roslyn - 2348a50bb566b39305c474793b43edb5635db6f4 + 134bc2e6f0edbe13c7cc465d97592d75f9d1a197 - + https://github.com/dotnet/roslyn - 2348a50bb566b39305c474793b43edb5635db6f4 + 134bc2e6f0edbe13c7cc465d97592d75f9d1a197 - + https://github.com/dotnet/roslyn - 2348a50bb566b39305c474793b43edb5635db6f4 + 134bc2e6f0edbe13c7cc465d97592d75f9d1a197 - + https://github.com/dotnet/roslyn - 2348a50bb566b39305c474793b43edb5635db6f4 + 134bc2e6f0edbe13c7cc465d97592d75f9d1a197 - + https://github.com/dotnet/roslyn - 2348a50bb566b39305c474793b43edb5635db6f4 + 134bc2e6f0edbe13c7cc465d97592d75f9d1a197 https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore diff --git a/eng/Versions.props b/eng/Versions.props index 8155a5213178..f8fb4d90fab4 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -154,13 +154,13 @@ - 4.10.0-3.24168.1 - 4.10.0-3.24168.1 - 4.10.0-3.24168.1 - 4.10.0-3.24168.1 - 4.10.0-3.24168.1 - 4.10.0-3.24168.1 - 4.10.0-3.24168.1 + 4.10.0-3.24168.9 + 4.10.0-3.24168.9 + 4.10.0-3.24168.9 + 4.10.0-3.24168.9 + 4.10.0-3.24168.9 + 4.10.0-3.24168.9 + 4.10.0-3.24168.9 $(MicrosoftNetCompilersToolsetPackageVersion) From a871ba2c44607c3db4879ecb2c04cbb398676716 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" Date: Tue, 19 Mar 2024 12:29:59 +0000 Subject: [PATCH 433/577] Update dependencies from https://github.com/dotnet/source-build-externals build Microsoft.SourceBuild.Intermediate.source-build-externals From Version 8.0.0-alpha.1.24161.1 -> To Version 8.0.0-alpha.1.24168.2 --- eng/Version.Details.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 6149169fc7d7..ff19816c0c93 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -333,9 +333,9 @@ 02fe27cd6a9b001c8feb7938e6ef4b3799745759 - + https://github.com/dotnet/source-build-externals - 00fb7841c80b44262646e57bcfbe90a1b7bc3151 + 0fac378047750fa8bd850a98b159560f9f7627c3 From a32dc3458151bab1b379adfaee9b45fb181e8078 Mon Sep 17 00:00:00 2001 From: dotnet bot Date: Tue, 19 Mar 2024 08:12:30 -0700 Subject: [PATCH 434/577] Localized file check-in by OneLocBuild Task: Build definition ID 140: Build ID 2408134 --- .../dotnet-workload/install/xlf/LocalizableStrings.cs.xlf | 6 +++--- .../dotnet-workload/install/xlf/LocalizableStrings.es.xlf | 6 +++--- .../dotnet-workload/install/xlf/LocalizableStrings.fr.xlf | 6 +++--- .../dotnet-workload/install/xlf/LocalizableStrings.it.xlf | 6 +++--- .../dotnet-workload/install/xlf/LocalizableStrings.ja.xlf | 6 +++--- .../dotnet-workload/install/xlf/LocalizableStrings.ko.xlf | 6 +++--- .../dotnet-workload/install/xlf/LocalizableStrings.pl.xlf | 6 +++--- .../install/xlf/LocalizableStrings.pt-BR.xlf | 6 +++--- .../dotnet-workload/install/xlf/LocalizableStrings.ru.xlf | 6 +++--- .../dotnet-workload/install/xlf/LocalizableStrings.tr.xlf | 6 +++--- .../install/xlf/LocalizableStrings.zh-Hans.xlf | 6 +++--- .../install/xlf/LocalizableStrings.zh-Hant.xlf | 6 +++--- .../dotnet-workload/list/xlf/LocalizableStrings.cs.xlf | 2 +- .../dotnet-workload/list/xlf/LocalizableStrings.es.xlf | 2 +- .../dotnet-workload/list/xlf/LocalizableStrings.fr.xlf | 2 +- .../dotnet-workload/list/xlf/LocalizableStrings.it.xlf | 2 +- .../dotnet-workload/list/xlf/LocalizableStrings.ja.xlf | 2 +- .../dotnet-workload/list/xlf/LocalizableStrings.ko.xlf | 2 +- .../dotnet-workload/list/xlf/LocalizableStrings.pl.xlf | 2 +- .../dotnet-workload/list/xlf/LocalizableStrings.pt-BR.xlf | 2 +- .../dotnet-workload/list/xlf/LocalizableStrings.ru.xlf | 2 +- .../dotnet-workload/list/xlf/LocalizableStrings.tr.xlf | 2 +- .../dotnet-workload/list/xlf/LocalizableStrings.zh-Hans.xlf | 2 +- .../dotnet-workload/list/xlf/LocalizableStrings.zh-Hant.xlf | 2 +- 24 files changed, 48 insertions(+), 48 deletions(-) diff --git a/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.cs.xlf b/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.cs.xlf index 16d19acff6fe..edc035dc5b84 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.cs.xlf +++ b/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.cs.xlf @@ -184,7 +184,7 @@ Installing workload version {0}. - Installing workload version {0}. + Probíhá instalace verze úlohy {0}. @@ -374,12 +374,12 @@ Updating workload version from {0} to {1}. - Updating workload version from {0} to {1}. + Aktualizuje se verze úlohy z {0} na {1}. Update to the specified workload version. - Update to the specified workload version. + Aktualizuje verzi na zadanou verzi úlohy. diff --git a/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.es.xlf b/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.es.xlf index b85299b2a989..3bfc70f3513d 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.es.xlf +++ b/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.es.xlf @@ -184,7 +184,7 @@ Installing workload version {0}. - Installing workload version {0}. + Instalando la versión de carga de trabajo {0}. @@ -374,12 +374,12 @@ Updating workload version from {0} to {1}. - Updating workload version from {0} to {1}. + Actualizando la versión de carga de trabajo de {0} a {1}. Update to the specified workload version. - Update to the specified workload version. + Actualice a la versión de carga de trabajo especificada. diff --git a/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.fr.xlf b/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.fr.xlf index 22f5c5ee64e0..90a3b2211a5c 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.fr.xlf +++ b/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.fr.xlf @@ -184,7 +184,7 @@ Installing workload version {0}. - Installing workload version {0}. + Installation de la charge de travail {0}. @@ -374,12 +374,12 @@ Updating workload version from {0} to {1}. - Updating workload version from {0} to {1}. + Mise à jour de la version de la charge de travail de {0} à {1}. Update to the specified workload version. - Update to the specified workload version. + Mettre à jour vers la version de charge de travail spécifiée. diff --git a/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.it.xlf b/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.it.xlf index 0f2b45bf6774..904083600d81 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.it.xlf +++ b/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.it.xlf @@ -184,7 +184,7 @@ Installing workload version {0}. - Installing workload version {0}. + Installazione del carico di lavoro {0}. @@ -374,12 +374,12 @@ Updating workload version from {0} to {1}. - Updating workload version from {0} to {1}. + Aggiornamento della versione del carico di lavoro da {0} a {1}. Update to the specified workload version. - Update to the specified workload version. + Eseguire l'aggiornamento alla versione del carico di lavoro specificata. diff --git a/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.ja.xlf b/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.ja.xlf index 029a1695d244..0a11234fc8d5 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.ja.xlf +++ b/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.ja.xlf @@ -184,7 +184,7 @@ Installing workload version {0}. - Installing workload version {0}. + ワークロードのバージョン {0} をインストールしています。 @@ -374,12 +374,12 @@ Updating workload version from {0} to {1}. - Updating workload version from {0} to {1}. + ワークロードのバージョンを {0} から {1} に更新しています。 Update to the specified workload version. - Update to the specified workload version. + 指定されたワークロード バージョンに更新します。 diff --git a/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.ko.xlf b/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.ko.xlf index 928954891bfd..5a1a593eb4f4 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.ko.xlf +++ b/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.ko.xlf @@ -184,7 +184,7 @@ Installing workload version {0}. - Installing workload version {0}. + 작업 버전 {0}을(를) 설치하는 중입니다. @@ -374,12 +374,12 @@ Updating workload version from {0} to {1}. - Updating workload version from {0} to {1}. + 워크로드 버전을 {0}에서 {1}(으)로 업데이트하는 중입니다. Update to the specified workload version. - Update to the specified workload version. + 지정된 워크로드 버전으로 업데이트합니다. diff --git a/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.pl.xlf b/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.pl.xlf index b2fc232366d5..9bd2f142bd6d 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.pl.xlf +++ b/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.pl.xlf @@ -184,7 +184,7 @@ Installing workload version {0}. - Installing workload version {0}. + Instalowanie wersji obciążenia {0}. @@ -374,12 +374,12 @@ Updating workload version from {0} to {1}. - Updating workload version from {0} to {1}. + Aktualizowanie wersji obciążenia z {0} do {1}. Update to the specified workload version. - Update to the specified workload version. + Zaktualizuj do określonej wersji obciążenia. diff --git a/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.pt-BR.xlf b/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.pt-BR.xlf index f28bacbe2588..762ee625556a 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.pt-BR.xlf +++ b/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.pt-BR.xlf @@ -184,7 +184,7 @@ Installing workload version {0}. - Installing workload version {0}. + Instalando a versão da carga de trabalho {0}. @@ -374,12 +374,12 @@ Updating workload version from {0} to {1}. - Updating workload version from {0} to {1}. + Atualizando a versão da carga de trabalho {0} para {1}. Update to the specified workload version. - Update to the specified workload version. + Atualize para a versão de carga de trabalho especificada. diff --git a/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.ru.xlf b/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.ru.xlf index ed236e9b4434..4fff4d220590 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.ru.xlf +++ b/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.ru.xlf @@ -184,7 +184,7 @@ Installing workload version {0}. - Installing workload version {0}. + Установка версии рабочей нагрузки {0}. @@ -374,12 +374,12 @@ Updating workload version from {0} to {1}. - Updating workload version from {0} to {1}. + Обновление версии рабочей нагрузки с {0} до {1}. Update to the specified workload version. - Update to the specified workload version. + Обновление до указанной версии рабочей нагрузки. diff --git a/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.tr.xlf b/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.tr.xlf index 8bfc444dd456..e24de92ad1dc 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.tr.xlf +++ b/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.tr.xlf @@ -184,7 +184,7 @@ Installing workload version {0}. - Installing workload version {0}. + {0} iş yükü sürümü yükleniyor. @@ -374,12 +374,12 @@ Updating workload version from {0} to {1}. - Updating workload version from {0} to {1}. + İş yükü {0} sürümünden {1} sürümüne güncelleştiriliyor. Update to the specified workload version. - Update to the specified workload version. + Belirtilen iş yükü sürümünde güncelleştirme var. diff --git a/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.zh-Hans.xlf b/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.zh-Hans.xlf index afc5f7b4f3d7..e9d4dfa8deb9 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.zh-Hans.xlf +++ b/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.zh-Hans.xlf @@ -184,7 +184,7 @@ Installing workload version {0}. - Installing workload version {0}. + 正在安装工作负载版本 {0}。 @@ -374,12 +374,12 @@ Updating workload version from {0} to {1}. - Updating workload version from {0} to {1}. + 正在将工作负载版本从 {0} 更新为 {1}。 Update to the specified workload version. - Update to the specified workload version. + 更新到指定的工作负载版本。 diff --git a/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.zh-Hant.xlf b/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.zh-Hant.xlf index b1c547749558..7f59f2cdda4d 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.zh-Hant.xlf +++ b/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.zh-Hant.xlf @@ -184,7 +184,7 @@ Installing workload version {0}. - Installing workload version {0}. + 正在安裝工作負載版本 {0}。 @@ -374,12 +374,12 @@ Updating workload version from {0} to {1}. - Updating workload version from {0} to {1}. + 正在將工作負載版本從 {0} 更新為 {1}。 Update to the specified workload version. - Update to the specified workload version. + 更新至指定的工作負載版本。 diff --git a/src/Cli/dotnet/commands/dotnet-workload/list/xlf/LocalizableStrings.cs.xlf b/src/Cli/dotnet/commands/dotnet-workload/list/xlf/LocalizableStrings.cs.xlf index 66284edd36c8..d7357b6c0252 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/list/xlf/LocalizableStrings.cs.xlf +++ b/src/Cli/dotnet/commands/dotnet-workload/list/xlf/LocalizableStrings.cs.xlf @@ -14,7 +14,7 @@ Workload version: {0} - Workload version: {0} + Verze úlohy: {0} diff --git a/src/Cli/dotnet/commands/dotnet-workload/list/xlf/LocalizableStrings.es.xlf b/src/Cli/dotnet/commands/dotnet-workload/list/xlf/LocalizableStrings.es.xlf index 80f0a9398d5e..8218b465574c 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/list/xlf/LocalizableStrings.es.xlf +++ b/src/Cli/dotnet/commands/dotnet-workload/list/xlf/LocalizableStrings.es.xlf @@ -14,7 +14,7 @@ Workload version: {0} - Workload version: {0} + Versión de carga de trabajo: {0} diff --git a/src/Cli/dotnet/commands/dotnet-workload/list/xlf/LocalizableStrings.fr.xlf b/src/Cli/dotnet/commands/dotnet-workload/list/xlf/LocalizableStrings.fr.xlf index 3f4c46ae97ca..048b86c1be46 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/list/xlf/LocalizableStrings.fr.xlf +++ b/src/Cli/dotnet/commands/dotnet-workload/list/xlf/LocalizableStrings.fr.xlf @@ -14,7 +14,7 @@ Workload version: {0} - Workload version: {0} + Version de la charge de travail : {0} diff --git a/src/Cli/dotnet/commands/dotnet-workload/list/xlf/LocalizableStrings.it.xlf b/src/Cli/dotnet/commands/dotnet-workload/list/xlf/LocalizableStrings.it.xlf index caa33f6a522b..3c864a9ac70e 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/list/xlf/LocalizableStrings.it.xlf +++ b/src/Cli/dotnet/commands/dotnet-workload/list/xlf/LocalizableStrings.it.xlf @@ -14,7 +14,7 @@ Workload version: {0} - Workload version: {0} + Versione carico di lavoro: {0} diff --git a/src/Cli/dotnet/commands/dotnet-workload/list/xlf/LocalizableStrings.ja.xlf b/src/Cli/dotnet/commands/dotnet-workload/list/xlf/LocalizableStrings.ja.xlf index 58eaa7887ce4..cfa7663bd2c1 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/list/xlf/LocalizableStrings.ja.xlf +++ b/src/Cli/dotnet/commands/dotnet-workload/list/xlf/LocalizableStrings.ja.xlf @@ -14,7 +14,7 @@ Workload version: {0} - Workload version: {0} + ワークロードのバージョン: {0} diff --git a/src/Cli/dotnet/commands/dotnet-workload/list/xlf/LocalizableStrings.ko.xlf b/src/Cli/dotnet/commands/dotnet-workload/list/xlf/LocalizableStrings.ko.xlf index 7b93e295c32c..133c3c43265c 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/list/xlf/LocalizableStrings.ko.xlf +++ b/src/Cli/dotnet/commands/dotnet-workload/list/xlf/LocalizableStrings.ko.xlf @@ -14,7 +14,7 @@ Workload version: {0} - Workload version: {0} + 워크로드 버전: {0} diff --git a/src/Cli/dotnet/commands/dotnet-workload/list/xlf/LocalizableStrings.pl.xlf b/src/Cli/dotnet/commands/dotnet-workload/list/xlf/LocalizableStrings.pl.xlf index 6dab03cac48a..73887307cace 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/list/xlf/LocalizableStrings.pl.xlf +++ b/src/Cli/dotnet/commands/dotnet-workload/list/xlf/LocalizableStrings.pl.xlf @@ -14,7 +14,7 @@ Workload version: {0} - Workload version: {0} + Wersja obciążenia: {0} diff --git a/src/Cli/dotnet/commands/dotnet-workload/list/xlf/LocalizableStrings.pt-BR.xlf b/src/Cli/dotnet/commands/dotnet-workload/list/xlf/LocalizableStrings.pt-BR.xlf index bfd92a1420d3..f6fadc51c77f 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/list/xlf/LocalizableStrings.pt-BR.xlf +++ b/src/Cli/dotnet/commands/dotnet-workload/list/xlf/LocalizableStrings.pt-BR.xlf @@ -14,7 +14,7 @@ Workload version: {0} - Workload version: {0} + Versão da carga de trabalho: {0} diff --git a/src/Cli/dotnet/commands/dotnet-workload/list/xlf/LocalizableStrings.ru.xlf b/src/Cli/dotnet/commands/dotnet-workload/list/xlf/LocalizableStrings.ru.xlf index 8001bc04e0f0..c5eaafb29ba7 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/list/xlf/LocalizableStrings.ru.xlf +++ b/src/Cli/dotnet/commands/dotnet-workload/list/xlf/LocalizableStrings.ru.xlf @@ -14,7 +14,7 @@ Workload version: {0} - Workload version: {0} + Версия рабочей нагрузки: {0} diff --git a/src/Cli/dotnet/commands/dotnet-workload/list/xlf/LocalizableStrings.tr.xlf b/src/Cli/dotnet/commands/dotnet-workload/list/xlf/LocalizableStrings.tr.xlf index 3b0ac98ba2d2..d06bed8d2488 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/list/xlf/LocalizableStrings.tr.xlf +++ b/src/Cli/dotnet/commands/dotnet-workload/list/xlf/LocalizableStrings.tr.xlf @@ -14,7 +14,7 @@ Workload version: {0} - Workload version: {0} + İş yükü sürümü: {0} diff --git a/src/Cli/dotnet/commands/dotnet-workload/list/xlf/LocalizableStrings.zh-Hans.xlf b/src/Cli/dotnet/commands/dotnet-workload/list/xlf/LocalizableStrings.zh-Hans.xlf index 35e9756641e4..fb1e4caff827 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/list/xlf/LocalizableStrings.zh-Hans.xlf +++ b/src/Cli/dotnet/commands/dotnet-workload/list/xlf/LocalizableStrings.zh-Hans.xlf @@ -14,7 +14,7 @@ Workload version: {0} - Workload version: {0} + 工作负载版本:{0} diff --git a/src/Cli/dotnet/commands/dotnet-workload/list/xlf/LocalizableStrings.zh-Hant.xlf b/src/Cli/dotnet/commands/dotnet-workload/list/xlf/LocalizableStrings.zh-Hant.xlf index 424fdf614a55..c17b8f9ccd3b 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/list/xlf/LocalizableStrings.zh-Hant.xlf +++ b/src/Cli/dotnet/commands/dotnet-workload/list/xlf/LocalizableStrings.zh-Hant.xlf @@ -14,7 +14,7 @@ Workload version: {0} - Workload version: {0} + 工作負載版本: {0} From 4cdac4649b0f291311e2b7e39d4d249b2c053b02 Mon Sep 17 00:00:00 2001 From: dotnet bot Date: Tue, 19 Mar 2024 08:14:41 -0700 Subject: [PATCH 435/577] Localized file check-in by OneLocBuild Task: Build definition ID 140: Build ID 2408134 --- .../dotnet-workload/update/xlf/LocalizableStrings.cs.xlf | 2 +- .../dotnet-workload/update/xlf/LocalizableStrings.es.xlf | 2 +- .../dotnet-workload/update/xlf/LocalizableStrings.fr.xlf | 2 +- .../dotnet-workload/update/xlf/LocalizableStrings.it.xlf | 2 +- .../dotnet-workload/update/xlf/LocalizableStrings.ja.xlf | 2 +- .../dotnet-workload/update/xlf/LocalizableStrings.ko.xlf | 2 +- .../dotnet-workload/update/xlf/LocalizableStrings.pl.xlf | 2 +- .../dotnet-workload/update/xlf/LocalizableStrings.pt-BR.xlf | 2 +- .../dotnet-workload/update/xlf/LocalizableStrings.ru.xlf | 2 +- .../dotnet-workload/update/xlf/LocalizableStrings.tr.xlf | 2 +- .../dotnet-workload/update/xlf/LocalizableStrings.zh-Hans.xlf | 2 +- .../dotnet-workload/update/xlf/LocalizableStrings.zh-Hant.xlf | 2 +- .../commands/dotnet-workload/xlf/LocalizableStrings.cs.xlf | 2 +- .../commands/dotnet-workload/xlf/LocalizableStrings.de.xlf | 2 +- .../commands/dotnet-workload/xlf/LocalizableStrings.es.xlf | 2 +- .../commands/dotnet-workload/xlf/LocalizableStrings.fr.xlf | 2 +- .../commands/dotnet-workload/xlf/LocalizableStrings.it.xlf | 2 +- .../commands/dotnet-workload/xlf/LocalizableStrings.ja.xlf | 2 +- .../commands/dotnet-workload/xlf/LocalizableStrings.ko.xlf | 2 +- .../commands/dotnet-workload/xlf/LocalizableStrings.pl.xlf | 2 +- .../commands/dotnet-workload/xlf/LocalizableStrings.pt-BR.xlf | 2 +- .../commands/dotnet-workload/xlf/LocalizableStrings.ru.xlf | 2 +- .../commands/dotnet-workload/xlf/LocalizableStrings.tr.xlf | 2 +- .../commands/dotnet-workload/xlf/LocalizableStrings.zh-Hans.xlf | 2 +- .../commands/dotnet-workload/xlf/LocalizableStrings.zh-Hant.xlf | 2 +- 25 files changed, 25 insertions(+), 25 deletions(-) diff --git a/src/Cli/dotnet/commands/dotnet-workload/update/xlf/LocalizableStrings.cs.xlf b/src/Cli/dotnet/commands/dotnet-workload/update/xlf/LocalizableStrings.cs.xlf index 0cc940248598..977f612e55c7 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/update/xlf/LocalizableStrings.cs.xlf +++ b/src/Cli/dotnet/commands/dotnet-workload/update/xlf/LocalizableStrings.cs.xlf @@ -44,7 +44,7 @@ Updating to a rollback file is not compatible with workload sets. Install and Update will now use loose manifests. To update to a specific workload version, use --version. - Updating to a rollback file is not compatible with workload sets. Install and Update will now use loose manifests. To update to a specific workload version, use --version. + Aktualizace na soubor vrácení zpět není kompatibilní se sadami úloh. Instalace a aktualizace teď budou používat volné manifesty. Pokud chcete provést aktualizaci na konkrétní verzi úlohy, použijte možnost --version. diff --git a/src/Cli/dotnet/commands/dotnet-workload/update/xlf/LocalizableStrings.es.xlf b/src/Cli/dotnet/commands/dotnet-workload/update/xlf/LocalizableStrings.es.xlf index 5fd3c603769c..89eccf8ab9f1 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/update/xlf/LocalizableStrings.es.xlf +++ b/src/Cli/dotnet/commands/dotnet-workload/update/xlf/LocalizableStrings.es.xlf @@ -44,7 +44,7 @@ Updating to a rollback file is not compatible with workload sets. Install and Update will now use loose manifests. To update to a specific workload version, use --version. - Updating to a rollback file is not compatible with workload sets. Install and Update will now use loose manifests. To update to a specific workload version, use --version. + La actualización a un archivo de reversión no es compatible con los conjuntos de cargas de trabajo. Instalar y actualizar ahora usará manifiestos dinámicos. Para actualizar a una versión de carga de trabajo específica, use --versión. diff --git a/src/Cli/dotnet/commands/dotnet-workload/update/xlf/LocalizableStrings.fr.xlf b/src/Cli/dotnet/commands/dotnet-workload/update/xlf/LocalizableStrings.fr.xlf index 767a9f67a439..c364e36206ec 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/update/xlf/LocalizableStrings.fr.xlf +++ b/src/Cli/dotnet/commands/dotnet-workload/update/xlf/LocalizableStrings.fr.xlf @@ -44,7 +44,7 @@ Updating to a rollback file is not compatible with workload sets. Install and Update will now use loose manifests. To update to a specific workload version, use --version. - Updating to a rollback file is not compatible with workload sets. Install and Update will now use loose manifests. To update to a specific workload version, use --version. + La mise à jour vers un fichier de restauration n’est pas compatible avec les jeux de charge de travail. L’installation et la mise à jour utiliseront désormais des manifestes libres. Pour effectuer une mise à jour vers une version de charge de travail spécifique, utilisez --version. diff --git a/src/Cli/dotnet/commands/dotnet-workload/update/xlf/LocalizableStrings.it.xlf b/src/Cli/dotnet/commands/dotnet-workload/update/xlf/LocalizableStrings.it.xlf index f3d40db0dc9b..f623260c5ea4 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/update/xlf/LocalizableStrings.it.xlf +++ b/src/Cli/dotnet/commands/dotnet-workload/update/xlf/LocalizableStrings.it.xlf @@ -44,7 +44,7 @@ Updating to a rollback file is not compatible with workload sets. Install and Update will now use loose manifests. To update to a specific workload version, use --version. - Updating to a rollback file is not compatible with workload sets. Install and Update will now use loose manifests. To update to a specific workload version, use --version. + L'aggiornamento a un file di rollback non è compatibile con i set di carico di lavoro. L'installazione e l'aggiornamento useranno ora manifesti separati. Per eseguire l'aggiornamento a una versione specifica del carico di lavoro, usare --version. diff --git a/src/Cli/dotnet/commands/dotnet-workload/update/xlf/LocalizableStrings.ja.xlf b/src/Cli/dotnet/commands/dotnet-workload/update/xlf/LocalizableStrings.ja.xlf index 27a35287eee3..7fbe935ab64a 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/update/xlf/LocalizableStrings.ja.xlf +++ b/src/Cli/dotnet/commands/dotnet-workload/update/xlf/LocalizableStrings.ja.xlf @@ -44,7 +44,7 @@ Updating to a rollback file is not compatible with workload sets. Install and Update will now use loose manifests. To update to a specific workload version, use --version. - Updating to a rollback file is not compatible with workload sets. Install and Update will now use loose manifests. To update to a specific workload version, use --version. + ロールバック ファイルへの更新は、ワークロード セットと互換性がありません。インストールと更新にルーズ マニフェストが使用されるようになりました。特定のワークロードのバージョンに更新するには、--version を使用します。 diff --git a/src/Cli/dotnet/commands/dotnet-workload/update/xlf/LocalizableStrings.ko.xlf b/src/Cli/dotnet/commands/dotnet-workload/update/xlf/LocalizableStrings.ko.xlf index 2dcea44b5860..94339a424af4 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/update/xlf/LocalizableStrings.ko.xlf +++ b/src/Cli/dotnet/commands/dotnet-workload/update/xlf/LocalizableStrings.ko.xlf @@ -44,7 +44,7 @@ Updating to a rollback file is not compatible with workload sets. Install and Update will now use loose manifests. To update to a specific workload version, use --version. - Updating to a rollback file is not compatible with workload sets. Install and Update will now use loose manifests. To update to a specific workload version, use --version. + 롤백 파일로 업데이트하는 것은 워크로드 집합과 호환되지 않습니다. 이제 설치 및 업데이트에서 느슨한 매니페스트를 사용합니다. 특정 워크로드 버전으로 업데이트하려면 --version을 사용합니다. diff --git a/src/Cli/dotnet/commands/dotnet-workload/update/xlf/LocalizableStrings.pl.xlf b/src/Cli/dotnet/commands/dotnet-workload/update/xlf/LocalizableStrings.pl.xlf index 96c9a3f67371..8be9f85b5d9b 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/update/xlf/LocalizableStrings.pl.xlf +++ b/src/Cli/dotnet/commands/dotnet-workload/update/xlf/LocalizableStrings.pl.xlf @@ -44,7 +44,7 @@ Updating to a rollback file is not compatible with workload sets. Install and Update will now use loose manifests. To update to a specific workload version, use --version. - Updating to a rollback file is not compatible with workload sets. Install and Update will now use loose manifests. To update to a specific workload version, use --version. + Aktualizacja do pliku wycofywania nie jest zgodna z zestawami obciążeń. Zainstaluj i zaktualizuj będzie teraz używać luźnych manifestów. Aby zaktualizować do określonej wersji obciążenia, użyj opcji --version. diff --git a/src/Cli/dotnet/commands/dotnet-workload/update/xlf/LocalizableStrings.pt-BR.xlf b/src/Cli/dotnet/commands/dotnet-workload/update/xlf/LocalizableStrings.pt-BR.xlf index 235954d94f87..16e079b66c49 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/update/xlf/LocalizableStrings.pt-BR.xlf +++ b/src/Cli/dotnet/commands/dotnet-workload/update/xlf/LocalizableStrings.pt-BR.xlf @@ -44,7 +44,7 @@ Updating to a rollback file is not compatible with workload sets. Install and Update will now use loose manifests. To update to a specific workload version, use --version. - Updating to a rollback file is not compatible with workload sets. Install and Update will now use loose manifests. To update to a specific workload version, use --version. + Atualizar em um arquivo de reversão não é compatível com os conjuntos de carga de trabalho. A instalação e a atualização agora usarão manifestos flexíveis. Para atualizar para uma versão de carga de trabalho específica, use --versão. diff --git a/src/Cli/dotnet/commands/dotnet-workload/update/xlf/LocalizableStrings.ru.xlf b/src/Cli/dotnet/commands/dotnet-workload/update/xlf/LocalizableStrings.ru.xlf index b3b7e621533e..2dc67f8b32f1 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/update/xlf/LocalizableStrings.ru.xlf +++ b/src/Cli/dotnet/commands/dotnet-workload/update/xlf/LocalizableStrings.ru.xlf @@ -44,7 +44,7 @@ Updating to a rollback file is not compatible with workload sets. Install and Update will now use loose manifests. To update to a specific workload version, use --version. - Updating to a rollback file is not compatible with workload sets. Install and Update will now use loose manifests. To update to a specific workload version, use --version. + Обновление до файла отката несовместимо с наборами рабочих нагрузок. Теперь установка и обновление будут использовать свободные манифесты. Чтобы выполнить обновление до определенной версии рабочей нагрузки, используйте "--version". diff --git a/src/Cli/dotnet/commands/dotnet-workload/update/xlf/LocalizableStrings.tr.xlf b/src/Cli/dotnet/commands/dotnet-workload/update/xlf/LocalizableStrings.tr.xlf index 670f5d690df9..e3329bd11b94 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/update/xlf/LocalizableStrings.tr.xlf +++ b/src/Cli/dotnet/commands/dotnet-workload/update/xlf/LocalizableStrings.tr.xlf @@ -44,7 +44,7 @@ Updating to a rollback file is not compatible with workload sets. Install and Update will now use loose manifests. To update to a specific workload version, use --version. - Updating to a rollback file is not compatible with workload sets. Install and Update will now use loose manifests. To update to a specific workload version, use --version. + Geri alma dosyasının güncelleştirilmesi iş yükü kümeleriyle uyumlu değil. Yükle ve Güncelleştir özelliği artık bağımsız bildirimler kullanıyor. Belirli bir iş yükü sürümünde güncelleştirmek için “--version” komutunu kullanın. diff --git a/src/Cli/dotnet/commands/dotnet-workload/update/xlf/LocalizableStrings.zh-Hans.xlf b/src/Cli/dotnet/commands/dotnet-workload/update/xlf/LocalizableStrings.zh-Hans.xlf index 3beaaebc1acf..cb8c213dc67a 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/update/xlf/LocalizableStrings.zh-Hans.xlf +++ b/src/Cli/dotnet/commands/dotnet-workload/update/xlf/LocalizableStrings.zh-Hans.xlf @@ -44,7 +44,7 @@ Updating to a rollback file is not compatible with workload sets. Install and Update will now use loose manifests. To update to a specific workload version, use --version. - Updating to a rollback file is not compatible with workload sets. Install and Update will now use loose manifests. To update to a specific workload version, use --version. + 更新回退文件与工作负载集不兼容。安装和更新现在会使用松散清单。若要更新到特定工作负载版本,请使用 --version。 diff --git a/src/Cli/dotnet/commands/dotnet-workload/update/xlf/LocalizableStrings.zh-Hant.xlf b/src/Cli/dotnet/commands/dotnet-workload/update/xlf/LocalizableStrings.zh-Hant.xlf index 914b6a666c8a..a9be808c2e2c 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/update/xlf/LocalizableStrings.zh-Hant.xlf +++ b/src/Cli/dotnet/commands/dotnet-workload/update/xlf/LocalizableStrings.zh-Hant.xlf @@ -44,7 +44,7 @@ Updating to a rollback file is not compatible with workload sets. Install and Update will now use loose manifests. To update to a specific workload version, use --version. - Updating to a rollback file is not compatible with workload sets. Install and Update will now use loose manifests. To update to a specific workload version, use --version. + 更新至復原檔案與工作負載集不相容。安裝和更新現在將使用鬆散的資訊清單。若要更新至特定工作負載版本,請使用 --version。 diff --git a/src/Cli/dotnet/commands/dotnet-workload/xlf/LocalizableStrings.cs.xlf b/src/Cli/dotnet/commands/dotnet-workload/xlf/LocalizableStrings.cs.xlf index b62a0c004942..9d3ee2cb1094 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/xlf/LocalizableStrings.cs.xlf +++ b/src/Cli/dotnet/commands/dotnet-workload/xlf/LocalizableStrings.cs.xlf @@ -79,7 +79,7 @@ Writing install records for Visual Studio workloads: '{0}' - Writing install records for Visual Studio workloads: '{0}' + Probíhá zápis záznamů o instalaci pro úlohy sady Visual Studio: {0} diff --git a/src/Cli/dotnet/commands/dotnet-workload/xlf/LocalizableStrings.de.xlf b/src/Cli/dotnet/commands/dotnet-workload/xlf/LocalizableStrings.de.xlf index 21238fd7c686..453816e69e82 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/xlf/LocalizableStrings.de.xlf +++ b/src/Cli/dotnet/commands/dotnet-workload/xlf/LocalizableStrings.de.xlf @@ -79,7 +79,7 @@ Writing install records for Visual Studio workloads: '{0}' - Writing install records for Visual Studio workloads: '{0}' + Installationseinträge für Visual Studio Workloads werden geschrieben: „{0}“ diff --git a/src/Cli/dotnet/commands/dotnet-workload/xlf/LocalizableStrings.es.xlf b/src/Cli/dotnet/commands/dotnet-workload/xlf/LocalizableStrings.es.xlf index ae265fe80ab4..c5fd8ad0476b 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/xlf/LocalizableStrings.es.xlf +++ b/src/Cli/dotnet/commands/dotnet-workload/xlf/LocalizableStrings.es.xlf @@ -79,7 +79,7 @@ Writing install records for Visual Studio workloads: '{0}' - Writing install records for Visual Studio workloads: '{0}' + Escritura de registros de instalación para cargas de trabajo de Visual Studio: '{0}' diff --git a/src/Cli/dotnet/commands/dotnet-workload/xlf/LocalizableStrings.fr.xlf b/src/Cli/dotnet/commands/dotnet-workload/xlf/LocalizableStrings.fr.xlf index e369b84cefbf..c40a780132d1 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/xlf/LocalizableStrings.fr.xlf +++ b/src/Cli/dotnet/commands/dotnet-workload/xlf/LocalizableStrings.fr.xlf @@ -79,7 +79,7 @@ Writing install records for Visual Studio workloads: '{0}' - Writing install records for Visual Studio workloads: '{0}' + Écriture des enregistrements d'installation pour les charges de travail Visual Studio : « {0} » diff --git a/src/Cli/dotnet/commands/dotnet-workload/xlf/LocalizableStrings.it.xlf b/src/Cli/dotnet/commands/dotnet-workload/xlf/LocalizableStrings.it.xlf index 6e8ce642e3eb..daadd3104207 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/xlf/LocalizableStrings.it.xlf +++ b/src/Cli/dotnet/commands/dotnet-workload/xlf/LocalizableStrings.it.xlf @@ -79,7 +79,7 @@ Writing install records for Visual Studio workloads: '{0}' - Writing install records for Visual Studio workloads: '{0}' + Scrittura dei record di installazione per carichi di lavoro Visual Studio: '{0}' diff --git a/src/Cli/dotnet/commands/dotnet-workload/xlf/LocalizableStrings.ja.xlf b/src/Cli/dotnet/commands/dotnet-workload/xlf/LocalizableStrings.ja.xlf index fc606569d8f6..b4e97801db18 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/xlf/LocalizableStrings.ja.xlf +++ b/src/Cli/dotnet/commands/dotnet-workload/xlf/LocalizableStrings.ja.xlf @@ -79,7 +79,7 @@ Writing install records for Visual Studio workloads: '{0}' - Writing install records for Visual Studio workloads: '{0}' + Visual Studio ワークロードのインストール レコードを書き込み中: '{0}' diff --git a/src/Cli/dotnet/commands/dotnet-workload/xlf/LocalizableStrings.ko.xlf b/src/Cli/dotnet/commands/dotnet-workload/xlf/LocalizableStrings.ko.xlf index e83463876937..1ffd8e5a758b 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/xlf/LocalizableStrings.ko.xlf +++ b/src/Cli/dotnet/commands/dotnet-workload/xlf/LocalizableStrings.ko.xlf @@ -79,7 +79,7 @@ Writing install records for Visual Studio workloads: '{0}' - Writing install records for Visual Studio workloads: '{0}' + Visual Studio 워크로드에 대한 설치 레코드를 쓰는 중: '{0}' diff --git a/src/Cli/dotnet/commands/dotnet-workload/xlf/LocalizableStrings.pl.xlf b/src/Cli/dotnet/commands/dotnet-workload/xlf/LocalizableStrings.pl.xlf index 2e0f5552b264..2708cf27c116 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/xlf/LocalizableStrings.pl.xlf +++ b/src/Cli/dotnet/commands/dotnet-workload/xlf/LocalizableStrings.pl.xlf @@ -79,7 +79,7 @@ Writing install records for Visual Studio workloads: '{0}' - Writing install records for Visual Studio workloads: '{0}' + Pisanie rekordów instalacji dla obciążeń w usłudze Visual Studio: „{0}” diff --git a/src/Cli/dotnet/commands/dotnet-workload/xlf/LocalizableStrings.pt-BR.xlf b/src/Cli/dotnet/commands/dotnet-workload/xlf/LocalizableStrings.pt-BR.xlf index 4d53c2a6cf6c..3c84f2c5723b 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/xlf/LocalizableStrings.pt-BR.xlf +++ b/src/Cli/dotnet/commands/dotnet-workload/xlf/LocalizableStrings.pt-BR.xlf @@ -79,7 +79,7 @@ Writing install records for Visual Studio workloads: '{0}' - Writing install records for Visual Studio workloads: '{0}' + Gravando registros de instalação para cargas de trabalho do Visual Studio: "{0}" diff --git a/src/Cli/dotnet/commands/dotnet-workload/xlf/LocalizableStrings.ru.xlf b/src/Cli/dotnet/commands/dotnet-workload/xlf/LocalizableStrings.ru.xlf index fcff9c193c6a..49ff5ab06b35 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/xlf/LocalizableStrings.ru.xlf +++ b/src/Cli/dotnet/commands/dotnet-workload/xlf/LocalizableStrings.ru.xlf @@ -79,7 +79,7 @@ Writing install records for Visual Studio workloads: '{0}' - Writing install records for Visual Studio workloads: '{0}' + Запись сведений об установках для рабочих нагрузок Visual Studio: "{0}" diff --git a/src/Cli/dotnet/commands/dotnet-workload/xlf/LocalizableStrings.tr.xlf b/src/Cli/dotnet/commands/dotnet-workload/xlf/LocalizableStrings.tr.xlf index 139c2d32216e..44d20344db1b 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/xlf/LocalizableStrings.tr.xlf +++ b/src/Cli/dotnet/commands/dotnet-workload/xlf/LocalizableStrings.tr.xlf @@ -79,7 +79,7 @@ Writing install records for Visual Studio workloads: '{0}' - Writing install records for Visual Studio workloads: '{0}' + Visual Studio iş yükleri için yükleme yazma: '{0}' diff --git a/src/Cli/dotnet/commands/dotnet-workload/xlf/LocalizableStrings.zh-Hans.xlf b/src/Cli/dotnet/commands/dotnet-workload/xlf/LocalizableStrings.zh-Hans.xlf index 276c9d67ef93..85a900b6d835 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/xlf/LocalizableStrings.zh-Hans.xlf +++ b/src/Cli/dotnet/commands/dotnet-workload/xlf/LocalizableStrings.zh-Hans.xlf @@ -79,7 +79,7 @@ Writing install records for Visual Studio workloads: '{0}' - Writing install records for Visual Studio workloads: '{0}' + 写入 Visual Studio 工作负载的安装记录:“{0}” diff --git a/src/Cli/dotnet/commands/dotnet-workload/xlf/LocalizableStrings.zh-Hant.xlf b/src/Cli/dotnet/commands/dotnet-workload/xlf/LocalizableStrings.zh-Hant.xlf index 4f22ad3dede2..959ae6515f23 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/xlf/LocalizableStrings.zh-Hant.xlf +++ b/src/Cli/dotnet/commands/dotnet-workload/xlf/LocalizableStrings.zh-Hant.xlf @@ -79,7 +79,7 @@ Writing install records for Visual Studio workloads: '{0}' - Writing install records for Visual Studio workloads: '{0}' + 正在寫入 Visual Studio 工作負載的安裝紀錄:'{0}' From 56efa35499a8e58d977a7cadc439dab56188834e Mon Sep 17 00:00:00 2001 From: Daniel Plaisted Date: Tue, 19 Mar 2024 12:43:37 -0400 Subject: [PATCH 436/577] Add workload config command --- .../dotnet-workload/WorkloadCommandParser.cs | 1 + .../config/LocalizableStrings.resx | 123 ++++++++++++++++++ .../config/WorkloadConfigCommand.cs | 96 ++++++++++++++ .../config/WorkloadConfigCommandParser.cs | 45 +++++++ .../config/xlf/LocalizableStrings.cs.xlf | 12 ++ .../config/xlf/LocalizableStrings.de.xlf | 12 ++ .../config/xlf/LocalizableStrings.es.xlf | 12 ++ .../config/xlf/LocalizableStrings.fr.xlf | 12 ++ .../config/xlf/LocalizableStrings.it.xlf | 12 ++ .../config/xlf/LocalizableStrings.ja.xlf | 12 ++ .../config/xlf/LocalizableStrings.ko.xlf | 12 ++ .../config/xlf/LocalizableStrings.pl.xlf | 12 ++ .../config/xlf/LocalizableStrings.pt-BR.xlf | 12 ++ .../config/xlf/LocalizableStrings.ru.xlf | 12 ++ .../config/xlf/LocalizableStrings.tr.xlf | 12 ++ .../config/xlf/LocalizableStrings.zh-Hans.xlf | 12 ++ .../config/xlf/LocalizableStrings.zh-Hant.xlf | 12 ++ src/Cli/dotnet/dotnet.csproj | 5 +- 18 files changed, 424 insertions(+), 2 deletions(-) create mode 100644 src/Cli/dotnet/commands/dotnet-workload/config/LocalizableStrings.resx create mode 100644 src/Cli/dotnet/commands/dotnet-workload/config/WorkloadConfigCommand.cs create mode 100644 src/Cli/dotnet/commands/dotnet-workload/config/WorkloadConfigCommandParser.cs create mode 100644 src/Cli/dotnet/commands/dotnet-workload/config/xlf/LocalizableStrings.cs.xlf create mode 100644 src/Cli/dotnet/commands/dotnet-workload/config/xlf/LocalizableStrings.de.xlf create mode 100644 src/Cli/dotnet/commands/dotnet-workload/config/xlf/LocalizableStrings.es.xlf create mode 100644 src/Cli/dotnet/commands/dotnet-workload/config/xlf/LocalizableStrings.fr.xlf create mode 100644 src/Cli/dotnet/commands/dotnet-workload/config/xlf/LocalizableStrings.it.xlf create mode 100644 src/Cli/dotnet/commands/dotnet-workload/config/xlf/LocalizableStrings.ja.xlf create mode 100644 src/Cli/dotnet/commands/dotnet-workload/config/xlf/LocalizableStrings.ko.xlf create mode 100644 src/Cli/dotnet/commands/dotnet-workload/config/xlf/LocalizableStrings.pl.xlf create mode 100644 src/Cli/dotnet/commands/dotnet-workload/config/xlf/LocalizableStrings.pt-BR.xlf create mode 100644 src/Cli/dotnet/commands/dotnet-workload/config/xlf/LocalizableStrings.ru.xlf create mode 100644 src/Cli/dotnet/commands/dotnet-workload/config/xlf/LocalizableStrings.tr.xlf create mode 100644 src/Cli/dotnet/commands/dotnet-workload/config/xlf/LocalizableStrings.zh-Hans.xlf create mode 100644 src/Cli/dotnet/commands/dotnet-workload/config/xlf/LocalizableStrings.zh-Hant.xlf diff --git a/src/Cli/dotnet/commands/dotnet-workload/WorkloadCommandParser.cs b/src/Cli/dotnet/commands/dotnet-workload/WorkloadCommandParser.cs index 58a178422aea..27da8f82f71a 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/WorkloadCommandParser.cs +++ b/src/Cli/dotnet/commands/dotnet-workload/WorkloadCommandParser.cs @@ -124,6 +124,7 @@ private static CliCommand ConstructCommand() command.Subcommands.Add(WorkloadRestoreCommandParser.GetCommand()); command.Subcommands.Add(WorkloadCleanCommandParser.GetCommand()); command.Subcommands.Add(WorkloadElevateCommandParser.GetCommand()); + command.Subcommands.Add(WorkloadConfigCommandParser.GetCommand()); command.Validators.Add(commandResult => { diff --git a/src/Cli/dotnet/commands/dotnet-workload/config/LocalizableStrings.resx b/src/Cli/dotnet/commands/dotnet-workload/config/LocalizableStrings.resx new file mode 100644 index 000000000000..f3f1deee1532 --- /dev/null +++ b/src/Cli/dotnet/commands/dotnet-workload/config/LocalizableStrings.resx @@ -0,0 +1,123 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Modify or display workload configuration values. + + diff --git a/src/Cli/dotnet/commands/dotnet-workload/config/WorkloadConfigCommand.cs b/src/Cli/dotnet/commands/dotnet-workload/config/WorkloadConfigCommand.cs new file mode 100644 index 000000000000..003242b5073c --- /dev/null +++ b/src/Cli/dotnet/commands/dotnet-workload/config/WorkloadConfigCommand.cs @@ -0,0 +1,96 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System; +using System.Collections.Generic; +using System.CommandLine; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Microsoft.Deployment.DotNet.Releases; +using Microsoft.DotNet.Cli; +using Microsoft.DotNet.Cli.Utils; +using Microsoft.DotNet.Workloads.Workload; +using Microsoft.DotNet.Workloads.Workload.Install; +using Microsoft.NET.Sdk.WorkloadManifestReader; + +#nullable enable + +namespace Microsoft.DotNet.Workloads.Workload.Config +{ + internal class WorkloadConfigCommand : WorkloadCommandBase + { + bool _hasUpdateMode; + string? _updateMode; + readonly IWorkloadResolverFactory _workloadResolverFactory; + + private string? _dotnetPath; + private string _userProfileDir; + private readonly IWorkloadResolver _workloadResolver; + private readonly ReleaseVersion _sdkVersion; + private readonly SdkFeatureBand _sdkFeatureBand; + + readonly IInstaller _workloadInstaller; + + public WorkloadConfigCommand( + ParseResult parseResult, + IReporter? reporter = null, + IWorkloadResolverFactory? workloadResolverFactory = null + ) : base(parseResult, CommonOptions.HiddenVerbosityOption, reporter) + { + // TODO: Is it possible to check the order of the options? This would allow us to print the values out in the same order they are specified on the command line + _hasUpdateMode = parseResult.HasOption(WorkloadConfigCommandParser.UpdateMode); + _updateMode = parseResult.GetValue(WorkloadConfigCommandParser.UpdateMode); + + _workloadResolverFactory = workloadResolverFactory ?? new WorkloadResolverFactory(); + + var creationResult = _workloadResolverFactory.Create(); + + _dotnetPath = creationResult.DotnetPath; + _userProfileDir = creationResult.UserProfileDir; + _workloadResolver = creationResult.WorkloadResolver; + _sdkVersion = creationResult.SdkVersion; + + _sdkFeatureBand = new SdkFeatureBand(_sdkVersion); + _workloadInstaller = WorkloadInstallerFactory.GetWorkloadInstaller(Reporter, _sdkFeatureBand, creationResult.WorkloadResolver, Verbosity, creationResult.UserProfileDir, VerifySignatures, PackageDownloader, creationResult.DotnetPath); + } + + public override int Execute() + { + if (_hasUpdateMode) + { + if (_updateMode == WorkloadConfigCommandParser.UpdateMode_WorkloadSet) + { + _workloadInstaller.UpdateInstallMode(_sdkFeatureBand, true); + } + else if (_updateMode == WorkloadConfigCommandParser.UpdateMode_Manifests) + { + _workloadInstaller.UpdateInstallMode(_sdkFeatureBand, false); + } + else if (string.IsNullOrEmpty(_updateMode)) + { + if (InstallingWorkloadCommand.ShouldUseWorkloadSetMode(_sdkFeatureBand, _dotnetPath)) + { + Reporter.WriteLine(WorkloadConfigCommandParser.UpdateMode_WorkloadSet); + } + else + { + Reporter.WriteLine(WorkloadConfigCommandParser.UpdateMode_Manifests); + } + } + else + { + Reporter.WriteLine($"Invalid update mode: {_updateMode}"); + return 1; + } + } + else + { + Reporter.WriteLine("No update mode specified"); + } + + return 0; + } + } + +} diff --git a/src/Cli/dotnet/commands/dotnet-workload/config/WorkloadConfigCommandParser.cs b/src/Cli/dotnet/commands/dotnet-workload/config/WorkloadConfigCommandParser.cs new file mode 100644 index 000000000000..af4ef1cd0038 --- /dev/null +++ b/src/Cli/dotnet/commands/dotnet-workload/config/WorkloadConfigCommandParser.cs @@ -0,0 +1,45 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.CommandLine; +using Microsoft.DotNet.Workloads.Workload.Config; + +namespace Microsoft.DotNet.Cli +{ + internal static class WorkloadConfigCommandParser + { + // dotnet workload config --update-mode workload-set + + public static readonly string UpdateMode_WorkloadSet = "workload-set"; + public static readonly string UpdateMode_Manifests = "manifests"; + + public static readonly CliOption UpdateMode = new("--update-mode") + { + Description = "Set the update mode for the workload manifest", + //Hidden = true, + Arity = ArgumentArity.ZeroOrOne + }; + + private static readonly CliCommand Command = ConstructCommand(); + + public static CliCommand GetCommand() + { + return Command; + } + + private static CliCommand ConstructCommand() + { + UpdateMode.AcceptOnlyFromAmong(UpdateMode_WorkloadSet, UpdateMode_Manifests); + + CliCommand command = new("config", LocalizableStrings.CommandDescription); + command.Options.Add(UpdateMode); + + command.SetAction(parseResult => + { + new WorkloadConfigCommand(parseResult).Execute(); + }); + + return command; + } + } +} diff --git a/src/Cli/dotnet/commands/dotnet-workload/config/xlf/LocalizableStrings.cs.xlf b/src/Cli/dotnet/commands/dotnet-workload/config/xlf/LocalizableStrings.cs.xlf new file mode 100644 index 000000000000..b791dc2c462c --- /dev/null +++ b/src/Cli/dotnet/commands/dotnet-workload/config/xlf/LocalizableStrings.cs.xlf @@ -0,0 +1,12 @@ + + + + + + Modify or display workload configuration values. + Modify or display workload configuration values. + + + + + \ No newline at end of file diff --git a/src/Cli/dotnet/commands/dotnet-workload/config/xlf/LocalizableStrings.de.xlf b/src/Cli/dotnet/commands/dotnet-workload/config/xlf/LocalizableStrings.de.xlf new file mode 100644 index 000000000000..2df8dd41fb44 --- /dev/null +++ b/src/Cli/dotnet/commands/dotnet-workload/config/xlf/LocalizableStrings.de.xlf @@ -0,0 +1,12 @@ + + + + + + Modify or display workload configuration values. + Modify or display workload configuration values. + + + + + \ No newline at end of file diff --git a/src/Cli/dotnet/commands/dotnet-workload/config/xlf/LocalizableStrings.es.xlf b/src/Cli/dotnet/commands/dotnet-workload/config/xlf/LocalizableStrings.es.xlf new file mode 100644 index 000000000000..6fa38eb732a9 --- /dev/null +++ b/src/Cli/dotnet/commands/dotnet-workload/config/xlf/LocalizableStrings.es.xlf @@ -0,0 +1,12 @@ + + + + + + Modify or display workload configuration values. + Modify or display workload configuration values. + + + + + \ No newline at end of file diff --git a/src/Cli/dotnet/commands/dotnet-workload/config/xlf/LocalizableStrings.fr.xlf b/src/Cli/dotnet/commands/dotnet-workload/config/xlf/LocalizableStrings.fr.xlf new file mode 100644 index 000000000000..628665bd2a50 --- /dev/null +++ b/src/Cli/dotnet/commands/dotnet-workload/config/xlf/LocalizableStrings.fr.xlf @@ -0,0 +1,12 @@ + + + + + + Modify or display workload configuration values. + Modify or display workload configuration values. + + + + + \ No newline at end of file diff --git a/src/Cli/dotnet/commands/dotnet-workload/config/xlf/LocalizableStrings.it.xlf b/src/Cli/dotnet/commands/dotnet-workload/config/xlf/LocalizableStrings.it.xlf new file mode 100644 index 000000000000..8e2cf902ddda --- /dev/null +++ b/src/Cli/dotnet/commands/dotnet-workload/config/xlf/LocalizableStrings.it.xlf @@ -0,0 +1,12 @@ + + + + + + Modify or display workload configuration values. + Modify or display workload configuration values. + + + + + \ No newline at end of file diff --git a/src/Cli/dotnet/commands/dotnet-workload/config/xlf/LocalizableStrings.ja.xlf b/src/Cli/dotnet/commands/dotnet-workload/config/xlf/LocalizableStrings.ja.xlf new file mode 100644 index 000000000000..e7f3662d459f --- /dev/null +++ b/src/Cli/dotnet/commands/dotnet-workload/config/xlf/LocalizableStrings.ja.xlf @@ -0,0 +1,12 @@ + + + + + + Modify or display workload configuration values. + Modify or display workload configuration values. + + + + + \ No newline at end of file diff --git a/src/Cli/dotnet/commands/dotnet-workload/config/xlf/LocalizableStrings.ko.xlf b/src/Cli/dotnet/commands/dotnet-workload/config/xlf/LocalizableStrings.ko.xlf new file mode 100644 index 000000000000..fe593ef40e37 --- /dev/null +++ b/src/Cli/dotnet/commands/dotnet-workload/config/xlf/LocalizableStrings.ko.xlf @@ -0,0 +1,12 @@ + + + + + + Modify or display workload configuration values. + Modify or display workload configuration values. + + + + + \ No newline at end of file diff --git a/src/Cli/dotnet/commands/dotnet-workload/config/xlf/LocalizableStrings.pl.xlf b/src/Cli/dotnet/commands/dotnet-workload/config/xlf/LocalizableStrings.pl.xlf new file mode 100644 index 000000000000..58f4dc222a50 --- /dev/null +++ b/src/Cli/dotnet/commands/dotnet-workload/config/xlf/LocalizableStrings.pl.xlf @@ -0,0 +1,12 @@ + + + + + + Modify or display workload configuration values. + Modify or display workload configuration values. + + + + + \ No newline at end of file diff --git a/src/Cli/dotnet/commands/dotnet-workload/config/xlf/LocalizableStrings.pt-BR.xlf b/src/Cli/dotnet/commands/dotnet-workload/config/xlf/LocalizableStrings.pt-BR.xlf new file mode 100644 index 000000000000..3100530fcd84 --- /dev/null +++ b/src/Cli/dotnet/commands/dotnet-workload/config/xlf/LocalizableStrings.pt-BR.xlf @@ -0,0 +1,12 @@ + + + + + + Modify or display workload configuration values. + Modify or display workload configuration values. + + + + + \ No newline at end of file diff --git a/src/Cli/dotnet/commands/dotnet-workload/config/xlf/LocalizableStrings.ru.xlf b/src/Cli/dotnet/commands/dotnet-workload/config/xlf/LocalizableStrings.ru.xlf new file mode 100644 index 000000000000..15a9601c79e1 --- /dev/null +++ b/src/Cli/dotnet/commands/dotnet-workload/config/xlf/LocalizableStrings.ru.xlf @@ -0,0 +1,12 @@ + + + + + + Modify or display workload configuration values. + Modify or display workload configuration values. + + + + + \ No newline at end of file diff --git a/src/Cli/dotnet/commands/dotnet-workload/config/xlf/LocalizableStrings.tr.xlf b/src/Cli/dotnet/commands/dotnet-workload/config/xlf/LocalizableStrings.tr.xlf new file mode 100644 index 000000000000..0e8ae5ca53ec --- /dev/null +++ b/src/Cli/dotnet/commands/dotnet-workload/config/xlf/LocalizableStrings.tr.xlf @@ -0,0 +1,12 @@ + + + + + + Modify or display workload configuration values. + Modify or display workload configuration values. + + + + + \ No newline at end of file diff --git a/src/Cli/dotnet/commands/dotnet-workload/config/xlf/LocalizableStrings.zh-Hans.xlf b/src/Cli/dotnet/commands/dotnet-workload/config/xlf/LocalizableStrings.zh-Hans.xlf new file mode 100644 index 000000000000..886acc5bc439 --- /dev/null +++ b/src/Cli/dotnet/commands/dotnet-workload/config/xlf/LocalizableStrings.zh-Hans.xlf @@ -0,0 +1,12 @@ + + + + + + Modify or display workload configuration values. + Modify or display workload configuration values. + + + + + \ No newline at end of file diff --git a/src/Cli/dotnet/commands/dotnet-workload/config/xlf/LocalizableStrings.zh-Hant.xlf b/src/Cli/dotnet/commands/dotnet-workload/config/xlf/LocalizableStrings.zh-Hant.xlf new file mode 100644 index 000000000000..ad00159d81f4 --- /dev/null +++ b/src/Cli/dotnet/commands/dotnet-workload/config/xlf/LocalizableStrings.zh-Hant.xlf @@ -0,0 +1,12 @@ + + + + + + Modify or display workload configuration values. + Modify or display workload configuration values. + + + + + \ No newline at end of file diff --git a/src/Cli/dotnet/dotnet.csproj b/src/Cli/dotnet/dotnet.csproj index de27955804a3..e2f8fe965719 100644 --- a/src/Cli/dotnet/dotnet.csproj +++ b/src/Cli/dotnet/dotnet.csproj @@ -74,6 +74,7 @@ + @@ -88,7 +89,7 @@ - + @@ -115,7 +116,7 @@ - + From 321b6d460cd62809d8cbc7a0a88599bb7bf7f55e Mon Sep 17 00:00:00 2001 From: Daniel Plaisted Date: Tue, 19 Mar 2024 12:43:53 -0400 Subject: [PATCH 437/577] Add initial workload set tests --- .../WorkloadSetTests.cs | 139 ++++++++++++++++++ 1 file changed, 139 insertions(+) create mode 100644 src/Tests/dotnet-MsiInstallation.Tests/WorkloadSetTests.cs diff --git a/src/Tests/dotnet-MsiInstallation.Tests/WorkloadSetTests.cs b/src/Tests/dotnet-MsiInstallation.Tests/WorkloadSetTests.cs new file mode 100644 index 000000000000..994ba0160c49 --- /dev/null +++ b/src/Tests/dotnet-MsiInstallation.Tests/WorkloadSetTests.cs @@ -0,0 +1,139 @@ +// Licensed to the .NET Foundation under one or more agreements. +// 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 Microsoft.DotNet.MsiInstallerTests.Framework; + +namespace Microsoft.DotNet.MsiInstallerTests +{ + public class WorkloadSetTests : VMTestBase + { + public WorkloadSetTests(ITestOutputHelper log) : base(log) + { + } + + // dotnet nuget add source c:\SdkTesting\WorkloadSets + // dotnet workload update --mode workloadset + + // Show workload mode in dotnet workload --info + + + // dotnet workload update-mode set workload-set + + // dotnet workload config --update-mode workload-set + + // dotnet workload config update-mode + // dotnet workload config update-mode workload-set + // dotnet workload config update-mode manifests + + // dotnet workload config update-band [default|release|preview|daily] + + // dotnet config workload.update-mode workload-set + + // dotnet setconfig --workload-update-mode workload-set + + [Fact] + public void DoesNotUseWorkloadSetsByDefault() + { + InstallSdk(); + + VM.CreateRunCommand("dotnet", "workload", "update") + .Execute() + .Should() + .Pass(); + + var originalRollback = GetRollback(); + + VM.CreateRunCommand("dotnet", "nuget", "add", "source", @"c:\SdkTesting\WorkloadSets") + .WithDescription("Add WorkloadSets to NuGet.config") + .Execute() + .Should() + .Pass(); + + VM.CreateRunCommand("dotnet", "workload", "update") + .Execute() + .Should() + .Pass(); + + var newRollback = GetRollback(); + + newRollback.ManifestVersions.Should().BeEquivalentTo(originalRollback.ManifestVersions); + + } + + [Fact] + public void UpdateWithWorkloadSets() + { + InstallSdk(); + + var originalWorkloadVersion = GetWorkloadVersion(); + originalWorkloadVersion.Should().StartWith("8.0.200-manifests."); + + VM.CreateRunCommand("dotnet", "workload", "update") + .Execute() + .Should() + .Pass(); + + var originalRollback = GetRollback(); + var updatedWorkloadVersion = GetWorkloadVersion(); + updatedWorkloadVersion.Should().StartWith("8.0.200-manifests."); + updatedWorkloadVersion.Should().NotBe(originalWorkloadVersion); + + VM.CreateRunCommand("dotnet", "nuget", "add", "source", @"c:\SdkTesting\WorkloadSets") + .WithDescription("Add WorkloadSets to NuGet.config") + .Execute() + .Should() + .Pass(); + + GetUpdateMode().Should().Be("manifests"); + + VM.CreateRunCommand("dotnet", "workload", "config", "--update-mode", "workload-set") + .WithDescription("Switch mode to workload-set") + .Execute() + .Should() + .Pass(); + + GetWorkloadVersion().Should().Be(updatedWorkloadVersion); + + GetUpdateMode().Should().Be("workload-set"); + + VM.CreateRunCommand("dotnet", "workload", "update") + .Execute() + .Should() + .Pass(); + + var newRollback = GetRollback(); + + newRollback.ManifestVersions.Should().NotBeEquivalentTo(originalRollback.ManifestVersions); + + GetWorkloadVersion().Should().Be("8.0.201"); + + } + + string GetWorkloadVersion() + { + var result = VM.CreateRunCommand("dotnet", "workload", "--version") + .WithIsReadOnly(true) + .Execute(); + + result.Should().Pass(); + + return result.StdOut; + } + + string GetUpdateMode() + { + var result = VM.CreateRunCommand("dotnet", "workload", "config", "--update-mode") + .WithIsReadOnly(true) + .Execute(); + + result.Should().Pass(); + + return result.StdOut; + } + } +} From 1595cecee7d89d4d3026a9483310c10f56c68a54 Mon Sep 17 00:00:00 2001 From: dotnet bot Date: Tue, 19 Mar 2024 23:14:02 -0700 Subject: [PATCH 438/577] Localized file check-in by OneLocBuild Task: Build definition ID 140: Build ID 2409193 --- .../dotnet-workload/install/xlf/LocalizableStrings.de.xlf | 6 +++--- .../dotnet-workload/list/xlf/LocalizableStrings.de.xlf | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.de.xlf b/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.de.xlf index 3684392e233f..c223b4f5ee51 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.de.xlf +++ b/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.de.xlf @@ -184,7 +184,7 @@ Installing workload version {0}. - Installing workload version {0}. + Die Workloadversion {0} wird installiert. @@ -374,12 +374,12 @@ Updating workload version from {0} to {1}. - Updating workload version from {0} to {1}. + Die Workloadversion wird von {0} auf {1} aktualisiert. Update to the specified workload version. - Update to the specified workload version. + Aktualisieren Sie auf die angegebene Workloadversion. diff --git a/src/Cli/dotnet/commands/dotnet-workload/list/xlf/LocalizableStrings.de.xlf b/src/Cli/dotnet/commands/dotnet-workload/list/xlf/LocalizableStrings.de.xlf index df59aa34bd89..b1f539bb2690 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/list/xlf/LocalizableStrings.de.xlf +++ b/src/Cli/dotnet/commands/dotnet-workload/list/xlf/LocalizableStrings.de.xlf @@ -14,7 +14,7 @@ Workload version: {0} - Workload version: {0} + Workloadversion: {0} From 37bafb7f789ba7fc2d656d583cdd33d4c0f88c27 Mon Sep 17 00:00:00 2001 From: dotnet bot Date: Tue, 19 Mar 2024 23:16:12 -0700 Subject: [PATCH 439/577] Localized file check-in by OneLocBuild Task: Build definition ID 140: Build ID 2409193 --- .../dotnet-workload/update/xlf/LocalizableStrings.de.xlf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Cli/dotnet/commands/dotnet-workload/update/xlf/LocalizableStrings.de.xlf b/src/Cli/dotnet/commands/dotnet-workload/update/xlf/LocalizableStrings.de.xlf index eec11ddc74e8..8f13b36509a4 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/update/xlf/LocalizableStrings.de.xlf +++ b/src/Cli/dotnet/commands/dotnet-workload/update/xlf/LocalizableStrings.de.xlf @@ -44,7 +44,7 @@ Updating to a rollback file is not compatible with workload sets. Install and Update will now use loose manifests. To update to a specific workload version, use --version. - Updating to a rollback file is not compatible with workload sets. Install and Update will now use loose manifests. To update to a specific workload version, use --version. + Das Aktualisieren auf eine Rollbackdatei ist nicht mit Workloadsätzen kompatibel. Installation und Update verwenden jetzt lose Manifeste. Verwenden Sie „--version“, um auf eine bestimmte Workloadversion zu aktualisieren. From 458470637cc844f67c3e769a6b3fd03a9ba843e2 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" Date: Wed, 20 Mar 2024 12:51:04 +0000 Subject: [PATCH 440/577] Update dependencies from https://github.com/dotnet/msbuild build Microsoft.SourceBuild.Intermediate.msbuild , Microsoft.Build , Microsoft.Build.Localization From Version 17.10.0-preview-24162-02 -> To Version 17.10.0-preview-24169-03 --- eng/Version.Details.xml | 12 ++++++------ eng/Versions.props | 4 ++-- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 864c1d7b9644..934deace18e5 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -51,17 +51,17 @@ https://github.com/dotnet/emsdk 2fc2ffd960930318f33fcaa690cbdbc55d72f52d - + https://github.com/dotnet/msbuild - 0326fd7c9e131c4c26bac3c0f72a43ef9fd2812c + cd64b7b4a690d809cf14fe2af807a328cce04e54 - + https://github.com/dotnet/msbuild - 0326fd7c9e131c4c26bac3c0f72a43ef9fd2812c + cd64b7b4a690d809cf14fe2af807a328cce04e54 - + https://github.com/dotnet/msbuild - 0326fd7c9e131c4c26bac3c0f72a43ef9fd2812c + cd64b7b4a690d809cf14fe2af807a328cce04e54 diff --git a/eng/Versions.props b/eng/Versions.props index 43556d7b0b3e..c8598361f805 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -120,7 +120,7 @@ - 17.10.0-preview-24162-02 + 17.10.0-preview-24169-03 $(MicrosoftBuildPackageVersion) - 17.10.0-preview-24163-01 - 17.10.0-preview-24163-01 - 17.10.0-preview-24163-01 + 17.10.0-preview-24169-03 + 17.10.0-preview-24169-03 + 17.10.0-preview-24169-03 From 60265195f7c5e2ba5fefa6c2f05c5a37e4ace361 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" Date: Wed, 20 Mar 2024 12:51:53 +0000 Subject: [PATCH 442/577] Update dependencies from https://github.com/dotnet/razor build Microsoft.AspNetCore.Mvc.Razor.Extensions.Tooling.Internal , Microsoft.CodeAnalysis.Razor.Tooling.Internal , Microsoft.NET.Sdk.Razor.SourceGenerators.Transport From Version 7.0.0-preview.24169.1 -> To Version 7.0.0-preview.24169.3 --- eng/Version.Details.xml | 12 ++++++------ eng/Versions.props | 6 +++--- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 864c1d7b9644..7712d5576c46 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -281,18 +281,18 @@ https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore da7e9894ce22ef8cc02e5acc56e95a6f8cf8f644 - + https://github.com/dotnet/razor - 12e83cdb9342aa1be480089f96e4c58e41c091e5 + eb9363d4f10d99cb81e9695156beef20e04866c7 - + https://github.com/dotnet/razor - 12e83cdb9342aa1be480089f96e4c58e41c091e5 + eb9363d4f10d99cb81e9695156beef20e04866c7 - + https://github.com/dotnet/razor - 12e83cdb9342aa1be480089f96e4c58e41c091e5 + eb9363d4f10d99cb81e9695156beef20e04866c7 https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore diff --git a/eng/Versions.props b/eng/Versions.props index 43556d7b0b3e..bbfe605bb7e2 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -175,9 +175,9 @@ - 7.0.0-preview.24169.1 - 7.0.0-preview.24169.1 - 7.0.0-preview.24169.1 + 7.0.0-preview.24169.3 + 7.0.0-preview.24169.3 + 7.0.0-preview.24169.3 From bcc7037cc2569e50a6e1f5defe0315ec999312d1 Mon Sep 17 00:00:00 2001 From: Daniel Plaisted Date: Wed, 20 Mar 2024 07:39:04 -0400 Subject: [PATCH 443/577] Updates to workload config command --- .../dotnet-workload/config/LocalizableStrings.resx | 6 +++++- .../dotnet-workload/config/WorkloadConfigCommand.cs | 6 +++--- .../config/WorkloadConfigCommandParser.cs | 2 +- .../config/xlf/LocalizableStrings.cs.xlf | 11 +++++++++-- .../config/xlf/LocalizableStrings.de.xlf | 11 +++++++++-- .../config/xlf/LocalizableStrings.es.xlf | 11 +++++++++-- .../config/xlf/LocalizableStrings.fr.xlf | 11 +++++++++-- .../config/xlf/LocalizableStrings.it.xlf | 11 +++++++++-- .../config/xlf/LocalizableStrings.ja.xlf | 11 +++++++++-- .../config/xlf/LocalizableStrings.ko.xlf | 11 +++++++++-- .../config/xlf/LocalizableStrings.pl.xlf | 11 +++++++++-- .../config/xlf/LocalizableStrings.pt-BR.xlf | 11 +++++++++-- .../config/xlf/LocalizableStrings.ru.xlf | 11 +++++++++-- .../config/xlf/LocalizableStrings.tr.xlf | 11 +++++++++-- .../config/xlf/LocalizableStrings.zh-Hans.xlf | 11 +++++++++-- .../config/xlf/LocalizableStrings.zh-Hant.xlf | 11 +++++++++-- 16 files changed, 126 insertions(+), 31 deletions(-) diff --git a/src/Cli/dotnet/commands/dotnet-workload/config/LocalizableStrings.resx b/src/Cli/dotnet/commands/dotnet-workload/config/LocalizableStrings.resx index f3f1deee1532..4e1d34189dd2 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/config/LocalizableStrings.resx +++ b/src/Cli/dotnet/commands/dotnet-workload/config/LocalizableStrings.resx @@ -118,6 +118,10 @@ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - Modify or display workload configuration values. + Modify or display workload configuration values. +To display a value, specify the corresponding command-line option without providing a value. For example: "dotnet workload config --update-mode" + + + Controls whether updates should look for workload sets or the latest version of each individual manifest. diff --git a/src/Cli/dotnet/commands/dotnet-workload/config/WorkloadConfigCommand.cs b/src/Cli/dotnet/commands/dotnet-workload/config/WorkloadConfigCommand.cs index 003242b5073c..0329b3770bca 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/config/WorkloadConfigCommand.cs +++ b/src/Cli/dotnet/commands/dotnet-workload/config/WorkloadConfigCommand.cs @@ -80,13 +80,13 @@ public override int Execute() } else { - Reporter.WriteLine($"Invalid update mode: {_updateMode}"); - return 1; + // This should not be hit, as parser sets the accepted values and should error before getting here if the value is not valid + throw new InvalidOperationException($"Invalid update mode: {_updateMode}"); } } else { - Reporter.WriteLine("No update mode specified"); + _parseResult.ShowHelp(); } return 0; diff --git a/src/Cli/dotnet/commands/dotnet-workload/config/WorkloadConfigCommandParser.cs b/src/Cli/dotnet/commands/dotnet-workload/config/WorkloadConfigCommandParser.cs index af4ef1cd0038..ee1a96ba73a5 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/config/WorkloadConfigCommandParser.cs +++ b/src/Cli/dotnet/commands/dotnet-workload/config/WorkloadConfigCommandParser.cs @@ -15,7 +15,7 @@ internal static class WorkloadConfigCommandParser public static readonly CliOption UpdateMode = new("--update-mode") { - Description = "Set the update mode for the workload manifest", + Description = LocalizableStrings.UpdateModeDescription, //Hidden = true, Arity = ArgumentArity.ZeroOrOne }; diff --git a/src/Cli/dotnet/commands/dotnet-workload/config/xlf/LocalizableStrings.cs.xlf b/src/Cli/dotnet/commands/dotnet-workload/config/xlf/LocalizableStrings.cs.xlf index b791dc2c462c..8d6be7eaaf81 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/config/xlf/LocalizableStrings.cs.xlf +++ b/src/Cli/dotnet/commands/dotnet-workload/config/xlf/LocalizableStrings.cs.xlf @@ -3,8 +3,15 @@ - Modify or display workload configuration values. - Modify or display workload configuration values. + Modify or display workload configuration values. +To display a value, specify the corresponding command-line option without providing a value. For example: "dotnet workload config --update-mode" + Modify or display workload configuration values. +To display a value, specify the corresponding command-line option without providing a value. For example: "dotnet workload config --update-mode" + + + + Controls whether updates should look for workload sets or the latest version of each individual manifest. + Controls whether updates should look for workload sets or the latest version of each individual manifest. diff --git a/src/Cli/dotnet/commands/dotnet-workload/config/xlf/LocalizableStrings.de.xlf b/src/Cli/dotnet/commands/dotnet-workload/config/xlf/LocalizableStrings.de.xlf index 2df8dd41fb44..88aee0f67512 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/config/xlf/LocalizableStrings.de.xlf +++ b/src/Cli/dotnet/commands/dotnet-workload/config/xlf/LocalizableStrings.de.xlf @@ -3,8 +3,15 @@ - Modify or display workload configuration values. - Modify or display workload configuration values. + Modify or display workload configuration values. +To display a value, specify the corresponding command-line option without providing a value. For example: "dotnet workload config --update-mode" + Modify or display workload configuration values. +To display a value, specify the corresponding command-line option without providing a value. For example: "dotnet workload config --update-mode" + + + + Controls whether updates should look for workload sets or the latest version of each individual manifest. + Controls whether updates should look for workload sets or the latest version of each individual manifest. diff --git a/src/Cli/dotnet/commands/dotnet-workload/config/xlf/LocalizableStrings.es.xlf b/src/Cli/dotnet/commands/dotnet-workload/config/xlf/LocalizableStrings.es.xlf index 6fa38eb732a9..55b10d407fc2 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/config/xlf/LocalizableStrings.es.xlf +++ b/src/Cli/dotnet/commands/dotnet-workload/config/xlf/LocalizableStrings.es.xlf @@ -3,8 +3,15 @@ - Modify or display workload configuration values. - Modify or display workload configuration values. + Modify or display workload configuration values. +To display a value, specify the corresponding command-line option without providing a value. For example: "dotnet workload config --update-mode" + Modify or display workload configuration values. +To display a value, specify the corresponding command-line option without providing a value. For example: "dotnet workload config --update-mode" + + + + Controls whether updates should look for workload sets or the latest version of each individual manifest. + Controls whether updates should look for workload sets or the latest version of each individual manifest. diff --git a/src/Cli/dotnet/commands/dotnet-workload/config/xlf/LocalizableStrings.fr.xlf b/src/Cli/dotnet/commands/dotnet-workload/config/xlf/LocalizableStrings.fr.xlf index 628665bd2a50..c7cc788430d4 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/config/xlf/LocalizableStrings.fr.xlf +++ b/src/Cli/dotnet/commands/dotnet-workload/config/xlf/LocalizableStrings.fr.xlf @@ -3,8 +3,15 @@ - Modify or display workload configuration values. - Modify or display workload configuration values. + Modify or display workload configuration values. +To display a value, specify the corresponding command-line option without providing a value. For example: "dotnet workload config --update-mode" + Modify or display workload configuration values. +To display a value, specify the corresponding command-line option without providing a value. For example: "dotnet workload config --update-mode" + + + + Controls whether updates should look for workload sets or the latest version of each individual manifest. + Controls whether updates should look for workload sets or the latest version of each individual manifest. diff --git a/src/Cli/dotnet/commands/dotnet-workload/config/xlf/LocalizableStrings.it.xlf b/src/Cli/dotnet/commands/dotnet-workload/config/xlf/LocalizableStrings.it.xlf index 8e2cf902ddda..ba98130db0bf 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/config/xlf/LocalizableStrings.it.xlf +++ b/src/Cli/dotnet/commands/dotnet-workload/config/xlf/LocalizableStrings.it.xlf @@ -3,8 +3,15 @@ - Modify or display workload configuration values. - Modify or display workload configuration values. + Modify or display workload configuration values. +To display a value, specify the corresponding command-line option without providing a value. For example: "dotnet workload config --update-mode" + Modify or display workload configuration values. +To display a value, specify the corresponding command-line option without providing a value. For example: "dotnet workload config --update-mode" + + + + Controls whether updates should look for workload sets or the latest version of each individual manifest. + Controls whether updates should look for workload sets or the latest version of each individual manifest. diff --git a/src/Cli/dotnet/commands/dotnet-workload/config/xlf/LocalizableStrings.ja.xlf b/src/Cli/dotnet/commands/dotnet-workload/config/xlf/LocalizableStrings.ja.xlf index e7f3662d459f..882fdf49f5d9 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/config/xlf/LocalizableStrings.ja.xlf +++ b/src/Cli/dotnet/commands/dotnet-workload/config/xlf/LocalizableStrings.ja.xlf @@ -3,8 +3,15 @@ - Modify or display workload configuration values. - Modify or display workload configuration values. + Modify or display workload configuration values. +To display a value, specify the corresponding command-line option without providing a value. For example: "dotnet workload config --update-mode" + Modify or display workload configuration values. +To display a value, specify the corresponding command-line option without providing a value. For example: "dotnet workload config --update-mode" + + + + Controls whether updates should look for workload sets or the latest version of each individual manifest. + Controls whether updates should look for workload sets or the latest version of each individual manifest. diff --git a/src/Cli/dotnet/commands/dotnet-workload/config/xlf/LocalizableStrings.ko.xlf b/src/Cli/dotnet/commands/dotnet-workload/config/xlf/LocalizableStrings.ko.xlf index fe593ef40e37..b8773e9b116c 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/config/xlf/LocalizableStrings.ko.xlf +++ b/src/Cli/dotnet/commands/dotnet-workload/config/xlf/LocalizableStrings.ko.xlf @@ -3,8 +3,15 @@ - Modify or display workload configuration values. - Modify or display workload configuration values. + Modify or display workload configuration values. +To display a value, specify the corresponding command-line option without providing a value. For example: "dotnet workload config --update-mode" + Modify or display workload configuration values. +To display a value, specify the corresponding command-line option without providing a value. For example: "dotnet workload config --update-mode" + + + + Controls whether updates should look for workload sets or the latest version of each individual manifest. + Controls whether updates should look for workload sets or the latest version of each individual manifest. diff --git a/src/Cli/dotnet/commands/dotnet-workload/config/xlf/LocalizableStrings.pl.xlf b/src/Cli/dotnet/commands/dotnet-workload/config/xlf/LocalizableStrings.pl.xlf index 58f4dc222a50..06ccf667f917 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/config/xlf/LocalizableStrings.pl.xlf +++ b/src/Cli/dotnet/commands/dotnet-workload/config/xlf/LocalizableStrings.pl.xlf @@ -3,8 +3,15 @@ - Modify or display workload configuration values. - Modify or display workload configuration values. + Modify or display workload configuration values. +To display a value, specify the corresponding command-line option without providing a value. For example: "dotnet workload config --update-mode" + Modify or display workload configuration values. +To display a value, specify the corresponding command-line option without providing a value. For example: "dotnet workload config --update-mode" + + + + Controls whether updates should look for workload sets or the latest version of each individual manifest. + Controls whether updates should look for workload sets or the latest version of each individual manifest. diff --git a/src/Cli/dotnet/commands/dotnet-workload/config/xlf/LocalizableStrings.pt-BR.xlf b/src/Cli/dotnet/commands/dotnet-workload/config/xlf/LocalizableStrings.pt-BR.xlf index 3100530fcd84..27459bb8c5fb 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/config/xlf/LocalizableStrings.pt-BR.xlf +++ b/src/Cli/dotnet/commands/dotnet-workload/config/xlf/LocalizableStrings.pt-BR.xlf @@ -3,8 +3,15 @@ - Modify or display workload configuration values. - Modify or display workload configuration values. + Modify or display workload configuration values. +To display a value, specify the corresponding command-line option without providing a value. For example: "dotnet workload config --update-mode" + Modify or display workload configuration values. +To display a value, specify the corresponding command-line option without providing a value. For example: "dotnet workload config --update-mode" + + + + Controls whether updates should look for workload sets or the latest version of each individual manifest. + Controls whether updates should look for workload sets or the latest version of each individual manifest. diff --git a/src/Cli/dotnet/commands/dotnet-workload/config/xlf/LocalizableStrings.ru.xlf b/src/Cli/dotnet/commands/dotnet-workload/config/xlf/LocalizableStrings.ru.xlf index 15a9601c79e1..5a490dbba2f5 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/config/xlf/LocalizableStrings.ru.xlf +++ b/src/Cli/dotnet/commands/dotnet-workload/config/xlf/LocalizableStrings.ru.xlf @@ -3,8 +3,15 @@ - Modify or display workload configuration values. - Modify or display workload configuration values. + Modify or display workload configuration values. +To display a value, specify the corresponding command-line option without providing a value. For example: "dotnet workload config --update-mode" + Modify or display workload configuration values. +To display a value, specify the corresponding command-line option without providing a value. For example: "dotnet workload config --update-mode" + + + + Controls whether updates should look for workload sets or the latest version of each individual manifest. + Controls whether updates should look for workload sets or the latest version of each individual manifest. diff --git a/src/Cli/dotnet/commands/dotnet-workload/config/xlf/LocalizableStrings.tr.xlf b/src/Cli/dotnet/commands/dotnet-workload/config/xlf/LocalizableStrings.tr.xlf index 0e8ae5ca53ec..07fe44de371f 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/config/xlf/LocalizableStrings.tr.xlf +++ b/src/Cli/dotnet/commands/dotnet-workload/config/xlf/LocalizableStrings.tr.xlf @@ -3,8 +3,15 @@ - Modify or display workload configuration values. - Modify or display workload configuration values. + Modify or display workload configuration values. +To display a value, specify the corresponding command-line option without providing a value. For example: "dotnet workload config --update-mode" + Modify or display workload configuration values. +To display a value, specify the corresponding command-line option without providing a value. For example: "dotnet workload config --update-mode" + + + + Controls whether updates should look for workload sets or the latest version of each individual manifest. + Controls whether updates should look for workload sets or the latest version of each individual manifest. diff --git a/src/Cli/dotnet/commands/dotnet-workload/config/xlf/LocalizableStrings.zh-Hans.xlf b/src/Cli/dotnet/commands/dotnet-workload/config/xlf/LocalizableStrings.zh-Hans.xlf index 886acc5bc439..41a4543b7566 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/config/xlf/LocalizableStrings.zh-Hans.xlf +++ b/src/Cli/dotnet/commands/dotnet-workload/config/xlf/LocalizableStrings.zh-Hans.xlf @@ -3,8 +3,15 @@ - Modify or display workload configuration values. - Modify or display workload configuration values. + Modify or display workload configuration values. +To display a value, specify the corresponding command-line option without providing a value. For example: "dotnet workload config --update-mode" + Modify or display workload configuration values. +To display a value, specify the corresponding command-line option without providing a value. For example: "dotnet workload config --update-mode" + + + + Controls whether updates should look for workload sets or the latest version of each individual manifest. + Controls whether updates should look for workload sets or the latest version of each individual manifest. diff --git a/src/Cli/dotnet/commands/dotnet-workload/config/xlf/LocalizableStrings.zh-Hant.xlf b/src/Cli/dotnet/commands/dotnet-workload/config/xlf/LocalizableStrings.zh-Hant.xlf index ad00159d81f4..8a8598849d60 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/config/xlf/LocalizableStrings.zh-Hant.xlf +++ b/src/Cli/dotnet/commands/dotnet-workload/config/xlf/LocalizableStrings.zh-Hant.xlf @@ -3,8 +3,15 @@ - Modify or display workload configuration values. - Modify or display workload configuration values. + Modify or display workload configuration values. +To display a value, specify the corresponding command-line option without providing a value. For example: "dotnet workload config --update-mode" + Modify or display workload configuration values. +To display a value, specify the corresponding command-line option without providing a value. For example: "dotnet workload config --update-mode" + + + + Controls whether updates should look for workload sets or the latest version of each individual manifest. + Controls whether updates should look for workload sets or the latest version of each individual manifest. From ee2350bdd8d395d638065fc080b843301e800807 Mon Sep 17 00:00:00 2001 From: Forgind <12969783+Forgind@users.noreply.github.com> Date: Wed, 20 Mar 2024 16:29:30 -0700 Subject: [PATCH 444/577] Consider global.json for workload* commands --- .../install/LocalizableStrings.resx | 3 +++ .../install/WorkloadInstallCommand.cs | 20 +++++++++++++++++-- .../restore/WorkloadRestoreCommand.cs | 6 +++++- .../update/WorkloadUpdateCommand.cs | 14 +++++++++++++ ...rkloadManifestProvider.GlobalJsonReader.cs | 2 +- 5 files changed, 41 insertions(+), 4 deletions(-) diff --git a/src/Cli/dotnet/commands/dotnet-workload/install/LocalizableStrings.resx b/src/Cli/dotnet/commands/dotnet-workload/install/LocalizableStrings.resx index 6fddf990e564..496dc7a1e7be 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/install/LocalizableStrings.resx +++ b/src/Cli/dotnet/commands/dotnet-workload/install/LocalizableStrings.resx @@ -355,4 +355,7 @@ Updating workload version from {0} to {1}. + + Cannot specify a particular workload version on the command line via --version or --from-history when there is already a version specified in the global.json file. + diff --git a/src/Cli/dotnet/commands/dotnet-workload/install/WorkloadInstallCommand.cs b/src/Cli/dotnet/commands/dotnet-workload/install/WorkloadInstallCommand.cs index 7025e5a5bf2b..73ed6ea4a02d 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/install/WorkloadInstallCommand.cs +++ b/src/Cli/dotnet/commands/dotnet-workload/install/WorkloadInstallCommand.cs @@ -11,6 +11,7 @@ using Microsoft.DotNet.Cli.NuGetPackageDownloader; using Microsoft.Extensions.EnvironmentAbstractions; using static Microsoft.NET.Sdk.WorkloadManifestReader.WorkloadResolver; +using System.Text; namespace Microsoft.DotNet.Workloads.Workload.Install { @@ -27,7 +28,8 @@ public WorkloadInstallCommand( INuGetPackageDownloader nugetPackageDownloader = null, IWorkloadManifestUpdater workloadManifestUpdater = null, string tempDirPath = null, - IReadOnlyCollection workloadIds = null) + IReadOnlyCollection workloadIds = null, + string workloadSetVersion = null) : base(parseResult, reporter: reporter, workloadResolverFactory: workloadResolverFactory, workloadInstaller: workloadInstaller, nugetPackageDownloader: nugetPackageDownloader, workloadManifestUpdater: workloadManifestUpdater, tempDirPath: tempDirPath) @@ -43,7 +45,7 @@ public WorkloadInstallCommand( _workloadManifestUpdater = _workloadManifestUpdaterFromConstructor ?? new WorkloadManifestUpdater(Reporter, _workloadResolver, PackageDownloader, _userProfileDir, _workloadInstaller.GetWorkloadInstallationRecordRepository(), _workloadInstaller, _packageSourceLocation, displayManifestUpdates: Verbosity.IsDetailedOrDiagnostic()); - _workloadSetVersion = parseResult.GetValue(InstallingWorkloadCommandParser.WorkloadSetVersionOption); + _workloadSetVersion = workloadSetVersion ?? parseResult.GetValue(InstallingWorkloadCommandParser.WorkloadSetVersionOption); if (string.IsNullOrWhiteSpace(_workloadSetVersion)) { // If the version of the workload set is currently pinned, treat it as if it were freshly pinned. @@ -113,6 +115,20 @@ public override int Execute() } else { + var globaljsonPath = SdkDirectoryWorkloadManifestProvider.GetGlobalJsonPath(_userProfileDir); + var workloadVersion = SdkDirectoryWorkloadManifestProvider.GlobalJsonReader.GetWorkloadVersionFromGlobalJson(globaljsonPath); + if (workloadVersion is not null) + { + if (string.IsNullOrWhiteSpace(_workloadSetVersion)) + { + _workloadSetVersion = workloadVersion; + } + else if (!workloadVersion.Equals(_workloadSetVersion)) + { + throw new Exception(string.Format(LocalizableStrings.CannotSpecifyVersionOnCommandLineAndInGlobalJson)); + } + } + try { DirectoryPath? offlineCache = string.IsNullOrWhiteSpace(_fromCacheOption) ? null : new DirectoryPath(_fromCacheOption); diff --git a/src/Cli/dotnet/commands/dotnet-workload/restore/WorkloadRestoreCommand.cs b/src/Cli/dotnet/commands/dotnet-workload/restore/WorkloadRestoreCommand.cs index 4913aca803b0..ec404df2c4aa 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/restore/WorkloadRestoreCommand.cs +++ b/src/Cli/dotnet/commands/dotnet-workload/restore/WorkloadRestoreCommand.cs @@ -36,8 +36,12 @@ public override int Execute() List allWorkloadId = RunTargetToGetWorkloadIds(allProjects); Reporter.WriteLine(string.Format(LocalizableStrings.InstallingWorkloads, string.Join(" ", allWorkloadId))); + var globaljsonPath = SdkDirectoryWorkloadManifestProvider.GetGlobalJsonPath(Directory.GetCurrentDirectory()); + var workloadVersion = SdkDirectoryWorkloadManifestProvider.GlobalJsonReader.GetWorkloadVersionFromGlobalJson(globaljsonPath); + var workloadInstallCommand = new WorkloadInstallCommand(_result, - workloadIds: allWorkloadId.Select(a => a.ToString()).ToList().AsReadOnly()); + workloadIds: allWorkloadId.Select(a => a.ToString()).ToList().AsReadOnly(), + workloadSetVersion: workloadVersion); workloadInstallCommand.Execute(); return 0; diff --git a/src/Cli/dotnet/commands/dotnet-workload/update/WorkloadUpdateCommand.cs b/src/Cli/dotnet/commands/dotnet-workload/update/WorkloadUpdateCommand.cs index 0d14b1fc84f7..92820e5260da 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/update/WorkloadUpdateCommand.cs +++ b/src/Cli/dotnet/commands/dotnet-workload/update/WorkloadUpdateCommand.cs @@ -110,6 +110,20 @@ public override int Execute() } else { + var globaljsonPath = SdkDirectoryWorkloadManifestProvider.GetGlobalJsonPath(_userProfileDir); + var workloadVersion = SdkDirectoryWorkloadManifestProvider.GlobalJsonReader.GetWorkloadVersionFromGlobalJson(globaljsonPath); + if (workloadVersion is not null) + { + if (string.IsNullOrWhiteSpace(_workloadSetVersion)) + { + _workloadSetVersion = workloadVersion; + } + else if (!workloadVersion.Equals(_workloadSetVersion)) + { + // Consider setting this in the global.json? Or logging a warning? + } + } + try { DirectoryPath? offlineCache = string.IsNullOrWhiteSpace(_fromCacheOption) ? null : new DirectoryPath(_fromCacheOption); diff --git a/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/SdkDirectoryWorkloadManifestProvider.GlobalJsonReader.cs b/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/SdkDirectoryWorkloadManifestProvider.GlobalJsonReader.cs index 43dd03f24073..bd09adbfcdc8 100644 --- a/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/SdkDirectoryWorkloadManifestProvider.GlobalJsonReader.cs +++ b/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/SdkDirectoryWorkloadManifestProvider.GlobalJsonReader.cs @@ -16,7 +16,7 @@ namespace Microsoft.NET.Sdk.WorkloadManifestReader { public partial class SdkDirectoryWorkloadManifestProvider { - static class GlobalJsonReader + public static class GlobalJsonReader { public static string? GetWorkloadVersionFromGlobalJson(string? globalJsonPath) { From b4a66963d4ee0e1a62780663a584456946879c3e Mon Sep 17 00:00:00 2001 From: Forgind <12969783+Forgind@users.noreply.github.com> Date: Wed, 20 Mar 2024 16:34:33 -0700 Subject: [PATCH 445/577] build --- .../dotnet-workload/install/xlf/LocalizableStrings.cs.xlf | 5 +++++ .../dotnet-workload/install/xlf/LocalizableStrings.de.xlf | 5 +++++ .../dotnet-workload/install/xlf/LocalizableStrings.es.xlf | 5 +++++ .../dotnet-workload/install/xlf/LocalizableStrings.fr.xlf | 5 +++++ .../dotnet-workload/install/xlf/LocalizableStrings.it.xlf | 5 +++++ .../dotnet-workload/install/xlf/LocalizableStrings.ja.xlf | 5 +++++ .../dotnet-workload/install/xlf/LocalizableStrings.ko.xlf | 5 +++++ .../dotnet-workload/install/xlf/LocalizableStrings.pl.xlf | 5 +++++ .../dotnet-workload/install/xlf/LocalizableStrings.pt-BR.xlf | 5 +++++ .../dotnet-workload/install/xlf/LocalizableStrings.ru.xlf | 5 +++++ .../dotnet-workload/install/xlf/LocalizableStrings.tr.xlf | 5 +++++ .../install/xlf/LocalizableStrings.zh-Hans.xlf | 5 +++++ .../install/xlf/LocalizableStrings.zh-Hant.xlf | 5 +++++ 13 files changed, 65 insertions(+) diff --git a/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.cs.xlf b/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.cs.xlf index 16d19acff6fe..658c56c0e07a 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.cs.xlf +++ b/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.cs.xlf @@ -22,6 +22,11 @@ Možnosti {0} a {1} nelze použít společně. Při instalaci ze souboru vráceného zpět odeberte {0}. V opačném případě odeberte {1}. + + Cannot specify a particular workload version on the command line via --version or --from-history when there is already a version specified in the global.json file. + Cannot specify a particular workload version on the command line via --version or --from-history when there is already a version specified in the global.json file. + + Checking for updated workload manifests. Kontrolují se aktualizované manifesty úloh. diff --git a/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.de.xlf b/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.de.xlf index 3684392e233f..38a75f0d51b8 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.de.xlf +++ b/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.de.xlf @@ -22,6 +22,11 @@ Die Optionen {0} und {1} können nicht zusammen verwendet werden. Entfernen Sie bei der Installation aus einer Rollbackdatei {0}. Entfernen Sie andernfalls {1} + + Cannot specify a particular workload version on the command line via --version or --from-history when there is already a version specified in the global.json file. + Cannot specify a particular workload version on the command line via --version or --from-history when there is already a version specified in the global.json file. + + Checking for updated workload manifests. Es wird nach aktualisierten Workloadmanifesten gesucht. diff --git a/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.es.xlf b/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.es.xlf index b85299b2a989..b23b63cc963b 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.es.xlf +++ b/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.es.xlf @@ -22,6 +22,11 @@ No se pueden usar las opciones {0} y {1} juntas. Si se instala desde un archivo de reversión, quite {0}. De lo contrario, quite {1} + + Cannot specify a particular workload version on the command line via --version or --from-history when there is already a version specified in the global.json file. + Cannot specify a particular workload version on the command line via --version or --from-history when there is already a version specified in the global.json file. + + Checking for updated workload manifests. Comprobando si hay manifiestos de carga de trabajo actualizados. diff --git a/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.fr.xlf b/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.fr.xlf index 22f5c5ee64e0..6dfef0eb9957 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.fr.xlf +++ b/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.fr.xlf @@ -22,6 +22,11 @@ Impossible d’utiliser les options {0} et {1} ensemble. Si vous installez à partir d’un fichier de restauration, supprimez {0}. Sinon, supprimez {1}. + + Cannot specify a particular workload version on the command line via --version or --from-history when there is already a version specified in the global.json file. + Cannot specify a particular workload version on the command line via --version or --from-history when there is already a version specified in the global.json file. + + Checking for updated workload manifests. Recherche de manifestes de charge de travail mis à jour diff --git a/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.it.xlf b/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.it.xlf index 0f2b45bf6774..31779e922eb5 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.it.xlf +++ b/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.it.xlf @@ -22,6 +22,11 @@ Impossibile utilizzare contemporaneamente le opzioni {0} e {1}. Se si esegue l'installazione da un file di rollback, rimuovere {0}. In caso contrario, rimuovere {1} + + Cannot specify a particular workload version on the command line via --version or --from-history when there is already a version specified in the global.json file. + Cannot specify a particular workload version on the command line via --version or --from-history when there is already a version specified in the global.json file. + + Checking for updated workload manifests. Verifica della disponibilità di manifesti del carico di lavoro aggiornati. diff --git a/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.ja.xlf b/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.ja.xlf index 029a1695d244..008eb7b47407 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.ja.xlf +++ b/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.ja.xlf @@ -22,6 +22,11 @@ {0} オプションと {1} オプションを併用することはできません。ロールバック ファイルからインストールする場合、{0} を削除してください。その他の場合には、{1} を削除します + + Cannot specify a particular workload version on the command line via --version or --from-history when there is already a version specified in the global.json file. + Cannot specify a particular workload version on the command line via --version or --from-history when there is already a version specified in the global.json file. + + Checking for updated workload manifests. 更新されたワークロード マニフェストを確認しています。 diff --git a/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.ko.xlf b/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.ko.xlf index 928954891bfd..ea71690bb4bd 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.ko.xlf +++ b/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.ko.xlf @@ -22,6 +22,11 @@ {0} 및 {1} 옵션을 함께 사용할 수 없습니다. 롤백 파일에서 설치하는 경우 {0}을(를) 제거합니다. 그렇지 않으면 {1}을(를) 제거합니다. + + Cannot specify a particular workload version on the command line via --version or --from-history when there is already a version specified in the global.json file. + Cannot specify a particular workload version on the command line via --version or --from-history when there is already a version specified in the global.json file. + + Checking for updated workload manifests. 업데이트된 워크로드 매니페스트를 확인하는 중입니다. diff --git a/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.pl.xlf b/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.pl.xlf index b2fc232366d5..5a0682d2a5cd 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.pl.xlf +++ b/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.pl.xlf @@ -22,6 +22,11 @@ Nie można jednocześnie używać poleceń {0} i {1}. W przypadku instalowania z pliku wycofywania usuń polecenie {0}. W przeciwnym razie usuń polecenie {1} + + Cannot specify a particular workload version on the command line via --version or --from-history when there is already a version specified in the global.json file. + Cannot specify a particular workload version on the command line via --version or --from-history when there is already a version specified in the global.json file. + + Checking for updated workload manifests. Sprawdzanie zaktualizowanych manifestów obciążenia. diff --git a/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.pt-BR.xlf b/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.pt-BR.xlf index f28bacbe2588..d3a73961036e 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.pt-BR.xlf +++ b/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.pt-BR.xlf @@ -22,6 +22,11 @@ Não é possível usar as opções {0} e {1} juntas. Se estiver instalando a partir de um arquivo de reversão, remova {0}. Caso contrário, remova {1} + + Cannot specify a particular workload version on the command line via --version or --from-history when there is already a version specified in the global.json file. + Cannot specify a particular workload version on the command line via --version or --from-history when there is already a version specified in the global.json file. + + Checking for updated workload manifests. Verificando manifestos de carga de trabalho atualizados. diff --git a/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.ru.xlf b/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.ru.xlf index ed236e9b4434..62356ca51a45 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.ru.xlf +++ b/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.ru.xlf @@ -22,6 +22,11 @@ Невозможно использовать параметры {0} и {1} одновременно. При установке из файла отката удалите {0}, в противном случае удалите {1}. + + Cannot specify a particular workload version on the command line via --version or --from-history when there is already a version specified in the global.json file. + Cannot specify a particular workload version on the command line via --version or --from-history when there is already a version specified in the global.json file. + + Checking for updated workload manifests. Проверка обновленных манифестов рабочей нагрузки. diff --git a/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.tr.xlf b/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.tr.xlf index 8bfc444dd456..55fe81630033 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.tr.xlf +++ b/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.tr.xlf @@ -22,6 +22,11 @@ {0} ve {1} seçenekleri birlikte kullanılamıyor. Bir geri alma dosyasından yükleniyorsa {0} seçeneğini kaldırın. Aksi takdirde, {1} seçeneğini kaldırın + + Cannot specify a particular workload version on the command line via --version or --from-history when there is already a version specified in the global.json file. + Cannot specify a particular workload version on the command line via --version or --from-history when there is already a version specified in the global.json file. + + Checking for updated workload manifests. Güncelleştirilmiş iş yükü bildirimleri denetleniyor. diff --git a/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.zh-Hans.xlf b/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.zh-Hans.xlf index afc5f7b4f3d7..dc293ac624df 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.zh-Hans.xlf +++ b/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.zh-Hans.xlf @@ -22,6 +22,11 @@ 不能同时使用 {0} 和 {1} 选项。如果从回滚文件安装,请删除 {0}。否则,请删除 {1} + + Cannot specify a particular workload version on the command line via --version or --from-history when there is already a version specified in the global.json file. + Cannot specify a particular workload version on the command line via --version or --from-history when there is already a version specified in the global.json file. + + Checking for updated workload manifests. 正在检查更新的工作负载清单。 diff --git a/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.zh-Hant.xlf b/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.zh-Hant.xlf index b1c547749558..0da7fda038d0 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.zh-Hant.xlf +++ b/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.zh-Hant.xlf @@ -22,6 +22,11 @@ 無法同時使用 {0} 與 {1} 選項。如果從復原檔案安裝,請移除 {0}。否則,請移除 {1} + + Cannot specify a particular workload version on the command line via --version or --from-history when there is already a version specified in the global.json file. + Cannot specify a particular workload version on the command line via --version or --from-history when there is already a version specified in the global.json file. + + Checking for updated workload manifests. 正在檢查更新的工作負載資訊清單。 From 7fc0f87a87715e41f5c6606e44ba8e974c321d45 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" Date: Thu, 21 Mar 2024 12:47:38 +0000 Subject: [PATCH 446/577] Update dependencies from https://github.com/dotnet/msbuild build Microsoft.SourceBuild.Intermediate.msbuild , Microsoft.Build , Microsoft.Build.Localization From Version 17.10.0-preview-24162-02 -> To Version 17.10.0-preview-24171-01 --- NuGet.config | 1 + eng/Version.Details.xml | 12 ++++++------ eng/Versions.props | 4 ++-- 3 files changed, 9 insertions(+), 8 deletions(-) diff --git a/NuGet.config b/NuGet.config index 324130e31c31..047e1cd427aa 100644 --- a/NuGet.config +++ b/NuGet.config @@ -7,6 +7,7 @@ + diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 934deace18e5..79b8ee6eabc5 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -51,17 +51,17 @@ https://github.com/dotnet/emsdk 2fc2ffd960930318f33fcaa690cbdbc55d72f52d - + https://github.com/dotnet/msbuild - cd64b7b4a690d809cf14fe2af807a328cce04e54 + de776177f6d540e656e6b0c6d5bb07f2ff518c19 - + https://github.com/dotnet/msbuild - cd64b7b4a690d809cf14fe2af807a328cce04e54 + de776177f6d540e656e6b0c6d5bb07f2ff518c19 - + https://github.com/dotnet/msbuild - cd64b7b4a690d809cf14fe2af807a328cce04e54 + de776177f6d540e656e6b0c6d5bb07f2ff518c19 diff --git a/eng/Versions.props b/eng/Versions.props index c8598361f805..15b46011f67c 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -120,7 +120,7 @@ - 17.10.0-preview-24169-03 + 17.10.0-preview-24171-01 $(MicrosoftBuildPackageVersion) + diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 51d032e26dfa..1389a67cdec4 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -183,18 +183,18 @@ https://github.com/nuget/nuget.client 1845d6bd450a7453d573035371c9fec43683d1ef - + https://github.com/microsoft/vstest - fb859a78be3d76ee38d5630ad86a17ab124ebbcf + 6957756d70d6ade74e239a38ad709db5cb39fe0d - + https://github.com/microsoft/vstest - fb859a78be3d76ee38d5630ad86a17ab124ebbcf + 6957756d70d6ade74e239a38ad709db5cb39fe0d - + https://github.com/microsoft/vstest - fb859a78be3d76ee38d5630ad86a17ab124ebbcf + 6957756d70d6ade74e239a38ad709db5cb39fe0d https://dev.azure.com/dnceng/internal/_git/dotnet-runtime diff --git a/eng/Versions.props b/eng/Versions.props index 4435cc6a0293..dcbfc6f48a7b 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -99,9 +99,9 @@ - 17.10.0-preview-24169-03 - 17.10.0-preview-24169-03 - 17.10.0-preview-24169-03 + 17.10.0-preview-24170-01 + 17.10.0-preview-24170-01 + 17.10.0-preview-24170-01 From 27bc94664c7c7127346a36f98fcb75de7cbdf605 Mon Sep 17 00:00:00 2001 From: annie <59816815+JL03-Yue@users.noreply.github.com> Date: Thu, 21 Mar 2024 13:38:55 -0700 Subject: [PATCH 448/577] add allowthousands to NumberStyles in DotnetNewSearchTests --- src/Tests/dotnet-new.Tests/DotnetNewSearchTests.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Tests/dotnet-new.Tests/DotnetNewSearchTests.cs b/src/Tests/dotnet-new.Tests/DotnetNewSearchTests.cs index 9af440f09564..04703cdff671 100644 --- a/src/Tests/dotnet-new.Tests/DotnetNewSearchTests.cs +++ b/src/Tests/dotnet-new.Tests/DotnetNewSearchTests.cs @@ -994,11 +994,11 @@ public int Compare(string? x, string? y) if (x != "<1k") { - _ = int.TryParse(x.Trim().AsSpan(0, x.Length - 1), out xInt); + _ = int.TryParse(x.Trim().AsSpan(0, x.Length - 1), System.Globalization.NumberStyles.AllowThousands, null, out xInt); } if (y != "<1k") { - _ = int.TryParse(y.Trim().AsSpan(0, y.Length - 1), out yInt); + _ = int.TryParse(y.Trim().AsSpan(0, y.Length - 1), System.Globalization.NumberStyles.AllowThousands, null, out yInt); } return xInt.CompareTo(yInt); } From 080f0122d9828bd69410a1260cac6daedc93afb3 Mon Sep 17 00:00:00 2001 From: annie <59816815+JL03-Yue@users.noreply.github.com> Date: Thu, 21 Mar 2024 17:21:30 -0700 Subject: [PATCH 449/577] add a fix for namecomparer for DotnetNewSearchTests --- src/Tests/dotnet-new.Tests/DotnetNewSearchTests.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/Tests/dotnet-new.Tests/DotnetNewSearchTests.cs b/src/Tests/dotnet-new.Tests/DotnetNewSearchTests.cs index 04703cdff671..8c25c11dcaf7 100644 --- a/src/Tests/dotnet-new.Tests/DotnetNewSearchTests.cs +++ b/src/Tests/dotnet-new.Tests/DotnetNewSearchTests.cs @@ -958,6 +958,7 @@ public int Compare(string? left, string? right) bool rightIsShrunk = right.EndsWith("..."); if (!(leftIsShrunk ^ rightIsShrunk)) { + // return string.Compare(left, right, StringComparison.CurrentCultureIgnoreCase); return string.Compare(left, right, StringComparison.CurrentCultureIgnoreCase); } @@ -967,8 +968,9 @@ public int Compare(string? left, string? right) } if (leftIsShrunk && right.StartsWith(left.Substring(0, left.Length - 3), StringComparison.CurrentCultureIgnoreCase)) { - return 1; + return -1; } + // return string.Compare(left, right, StringComparison.CurrentCultureIgnoreCase); return string.Compare(left, right, StringComparison.CurrentCultureIgnoreCase); } } From 7c6a6d94bc00dce39b5816587146189d9449a655 Mon Sep 17 00:00:00 2001 From: annie <59816815+JL03-Yue@users.noreply.github.com> Date: Thu, 21 Mar 2024 13:38:55 -0700 Subject: [PATCH 450/577] add allowthousands to NumberStyles in DotnetNewSearchTests --- src/Tests/dotnet-new.Tests/DotnetNewSearchTests.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Tests/dotnet-new.Tests/DotnetNewSearchTests.cs b/src/Tests/dotnet-new.Tests/DotnetNewSearchTests.cs index 9af440f09564..04703cdff671 100644 --- a/src/Tests/dotnet-new.Tests/DotnetNewSearchTests.cs +++ b/src/Tests/dotnet-new.Tests/DotnetNewSearchTests.cs @@ -994,11 +994,11 @@ public int Compare(string? x, string? y) if (x != "<1k") { - _ = int.TryParse(x.Trim().AsSpan(0, x.Length - 1), out xInt); + _ = int.TryParse(x.Trim().AsSpan(0, x.Length - 1), System.Globalization.NumberStyles.AllowThousands, null, out xInt); } if (y != "<1k") { - _ = int.TryParse(y.Trim().AsSpan(0, y.Length - 1), out yInt); + _ = int.TryParse(y.Trim().AsSpan(0, y.Length - 1), System.Globalization.NumberStyles.AllowThousands, null, out yInt); } return xInt.CompareTo(yInt); } From 25ac3a33f45dc791deefd4132ff87dad7ad01ec3 Mon Sep 17 00:00:00 2001 From: annie <59816815+JL03-Yue@users.noreply.github.com> Date: Thu, 21 Mar 2024 17:21:30 -0700 Subject: [PATCH 451/577] add a fix for namecomparer for DotnetNewSearchTests --- src/Tests/dotnet-new.Tests/DotnetNewSearchTests.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/Tests/dotnet-new.Tests/DotnetNewSearchTests.cs b/src/Tests/dotnet-new.Tests/DotnetNewSearchTests.cs index 04703cdff671..8c25c11dcaf7 100644 --- a/src/Tests/dotnet-new.Tests/DotnetNewSearchTests.cs +++ b/src/Tests/dotnet-new.Tests/DotnetNewSearchTests.cs @@ -958,6 +958,7 @@ public int Compare(string? left, string? right) bool rightIsShrunk = right.EndsWith("..."); if (!(leftIsShrunk ^ rightIsShrunk)) { + // return string.Compare(left, right, StringComparison.CurrentCultureIgnoreCase); return string.Compare(left, right, StringComparison.CurrentCultureIgnoreCase); } @@ -967,8 +968,9 @@ public int Compare(string? left, string? right) } if (leftIsShrunk && right.StartsWith(left.Substring(0, left.Length - 3), StringComparison.CurrentCultureIgnoreCase)) { - return 1; + return -1; } + // return string.Compare(left, right, StringComparison.CurrentCultureIgnoreCase); return string.Compare(left, right, StringComparison.CurrentCultureIgnoreCase); } } From 37deb25818285993d508fdf4f6ed5062a2c926d6 Mon Sep 17 00:00:00 2001 From: dotnet bot Date: Thu, 21 Mar 2024 21:58:47 -0700 Subject: [PATCH 452/577] Localized file check-in by OneLocBuild Task: Build definition ID 140: Build ID 2411480 --- .../Microsoft.NET.Build.Containers/Resources/xlf/Strings.cs.xlf | 2 +- .../Microsoft.NET.Build.Containers/Resources/xlf/Strings.de.xlf | 2 +- .../Microsoft.NET.Build.Containers/Resources/xlf/Strings.it.xlf | 2 +- .../Microsoft.NET.Build.Containers/Resources/xlf/Strings.pl.xlf | 2 +- .../Resources/xlf/Strings.pt-BR.xlf | 2 +- .../Microsoft.NET.Build.Containers/Resources/xlf/Strings.ru.xlf | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/Containers/Microsoft.NET.Build.Containers/Resources/xlf/Strings.cs.xlf b/src/Containers/Microsoft.NET.Build.Containers/Resources/xlf/Strings.cs.xlf index 055a9be19bd8..a7ab528afa57 100644 --- a/src/Containers/Microsoft.NET.Build.Containers/Resources/xlf/Strings.cs.xlf +++ b/src/Containers/Microsoft.NET.Build.Containers/Resources/xlf/Strings.cs.xlf @@ -144,7 +144,7 @@ CONTAINER2030: GenerateLabels was disabled but GenerateDigestLabel was enabled - no digest label will be created. - CONTAINER2030: GenerateLabels was disabled but GenerateDigestLabel was enabled - no digest label will be created. + CONTAINER2030: GenerateLabels bylo zakázáno, ale bylo povoleno GenerateDigestLabel – nebude vytvořen žádný popisek přehledu. {StrBegin="CONTAINER2030: "} diff --git a/src/Containers/Microsoft.NET.Build.Containers/Resources/xlf/Strings.de.xlf b/src/Containers/Microsoft.NET.Build.Containers/Resources/xlf/Strings.de.xlf index fbed5b0d3e1c..ca0c0bc89860 100644 --- a/src/Containers/Microsoft.NET.Build.Containers/Resources/xlf/Strings.de.xlf +++ b/src/Containers/Microsoft.NET.Build.Containers/Resources/xlf/Strings.de.xlf @@ -144,7 +144,7 @@ CONTAINER2030: GenerateLabels was disabled but GenerateDigestLabel was enabled - no digest label will be created. - CONTAINER2030: GenerateLabels was disabled but GenerateDigestLabel was enabled - no digest label will be created. + CONTAINER2030: GenerateLabels wurde deaktiviert, aber GenerateDigestLabel wurde aktiviert. Es wird keine Digestbezeichnung erstellt. {StrBegin="CONTAINER2030: "} diff --git a/src/Containers/Microsoft.NET.Build.Containers/Resources/xlf/Strings.it.xlf b/src/Containers/Microsoft.NET.Build.Containers/Resources/xlf/Strings.it.xlf index a730bd5e1543..221d1e81045b 100644 --- a/src/Containers/Microsoft.NET.Build.Containers/Resources/xlf/Strings.it.xlf +++ b/src/Containers/Microsoft.NET.Build.Containers/Resources/xlf/Strings.it.xlf @@ -144,7 +144,7 @@ CONTAINER2030: GenerateLabels was disabled but GenerateDigestLabel was enabled - no digest label will be created. - CONTAINER2030: GenerateLabels was disabled but GenerateDigestLabel was enabled - no digest label will be created. + CONTAINER2030: GenerateLabels è stato disabilitato ma GenerateDigestLabel è stato abilitato. Non verrà creata alcuna etichetta digest. {StrBegin="CONTAINER2030: "} diff --git a/src/Containers/Microsoft.NET.Build.Containers/Resources/xlf/Strings.pl.xlf b/src/Containers/Microsoft.NET.Build.Containers/Resources/xlf/Strings.pl.xlf index 88ed0a462dcd..e3c49fb635fe 100644 --- a/src/Containers/Microsoft.NET.Build.Containers/Resources/xlf/Strings.pl.xlf +++ b/src/Containers/Microsoft.NET.Build.Containers/Resources/xlf/Strings.pl.xlf @@ -144,7 +144,7 @@ CONTAINER2030: GenerateLabels was disabled but GenerateDigestLabel was enabled - no digest label will be created. - CONTAINER2030: GenerateLabels was disabled but GenerateDigestLabel was enabled - no digest label will be created. + CONTAINER2030: Funkcja GenerateLabels była wyłączona, ale funkcja GenerateDigestLabel była włączona — etykieta skrótu nie zostanie utworzona. {StrBegin="CONTAINER2030: "} diff --git a/src/Containers/Microsoft.NET.Build.Containers/Resources/xlf/Strings.pt-BR.xlf b/src/Containers/Microsoft.NET.Build.Containers/Resources/xlf/Strings.pt-BR.xlf index c42f53aa4e90..6eddb9edf822 100644 --- a/src/Containers/Microsoft.NET.Build.Containers/Resources/xlf/Strings.pt-BR.xlf +++ b/src/Containers/Microsoft.NET.Build.Containers/Resources/xlf/Strings.pt-BR.xlf @@ -144,7 +144,7 @@ CONTAINER2030: GenerateLabels was disabled but GenerateDigestLabel was enabled - no digest label will be created. - CONTAINER2030: GenerateLabels was disabled but GenerateDigestLabel was enabled - no digest label will be created. + CONTAINER2030: GenerateLabels foi desabilitado, mas GenerateDigestLabel foi habilitado - não serão criados rótulos de resumo. {StrBegin="CONTAINER2030: "} diff --git a/src/Containers/Microsoft.NET.Build.Containers/Resources/xlf/Strings.ru.xlf b/src/Containers/Microsoft.NET.Build.Containers/Resources/xlf/Strings.ru.xlf index 8c7e84485486..43493637de2d 100644 --- a/src/Containers/Microsoft.NET.Build.Containers/Resources/xlf/Strings.ru.xlf +++ b/src/Containers/Microsoft.NET.Build.Containers/Resources/xlf/Strings.ru.xlf @@ -144,7 +144,7 @@ CONTAINER2030: GenerateLabels was disabled but GenerateDigestLabel was enabled - no digest label will be created. - CONTAINER2030: GenerateLabels was disabled but GenerateDigestLabel was enabled - no digest label will be created. + CONTAINER2030: параметр GenerateLabels был отключен, но параметр GenerateDigestLabel был включен — метка дайджеста не будет создана. {StrBegin="CONTAINER2030: "} From 666492ffb3e9795ec6623f6b1b6bdfd78d29e715 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Fri, 22 Mar 2024 06:17:34 +0000 Subject: [PATCH 453/577] [release/8.0.3xx] Update dependencies from dotnet/roslyn (#39634) [release/8.0.3xx] Update dependencies from dotnet/roslyn - add allowthousands to NumberStyles in DotnetNewSearchTests - add a fix for namecomparer for DotnetNewSearchTests --- eng/Version.Details.xml | 28 ++++++++++++++-------------- eng/Versions.props | 14 +++++++------- 2 files changed, 21 insertions(+), 21 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 1389a67cdec4..6ce486e321c7 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -78,34 +78,34 @@ ac0d85557969d51bca72181514ddb7d5796fbbe2 - + https://github.com/dotnet/roslyn - 134bc2e6f0edbe13c7cc465d97592d75f9d1a197 + c8dd474b73167a0f1b07514082d162c7febdf33f - + https://github.com/dotnet/roslyn - 134bc2e6f0edbe13c7cc465d97592d75f9d1a197 + c8dd474b73167a0f1b07514082d162c7febdf33f - + https://github.com/dotnet/roslyn - 134bc2e6f0edbe13c7cc465d97592d75f9d1a197 + c8dd474b73167a0f1b07514082d162c7febdf33f - + https://github.com/dotnet/roslyn - 134bc2e6f0edbe13c7cc465d97592d75f9d1a197 + c8dd474b73167a0f1b07514082d162c7febdf33f - + https://github.com/dotnet/roslyn - 134bc2e6f0edbe13c7cc465d97592d75f9d1a197 + c8dd474b73167a0f1b07514082d162c7febdf33f - + https://github.com/dotnet/roslyn - 134bc2e6f0edbe13c7cc465d97592d75f9d1a197 + c8dd474b73167a0f1b07514082d162c7febdf33f - + https://github.com/dotnet/roslyn - 134bc2e6f0edbe13c7cc465d97592d75f9d1a197 + c8dd474b73167a0f1b07514082d162c7febdf33f https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore diff --git a/eng/Versions.props b/eng/Versions.props index dcbfc6f48a7b..a72a0154cc1d 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -154,13 +154,13 @@ - 4.10.0-3.24168.9 - 4.10.0-3.24168.9 - 4.10.0-3.24168.9 - 4.10.0-3.24168.9 - 4.10.0-3.24168.9 - 4.10.0-3.24168.9 - 4.10.0-3.24168.9 + 4.10.0-3.24171.1 + 4.10.0-3.24171.1 + 4.10.0-3.24171.1 + 4.10.0-3.24171.1 + 4.10.0-3.24171.1 + 4.10.0-3.24171.1 + 4.10.0-3.24171.1 $(MicrosoftNetCompilersToolsetPackageVersion) From e4511a1b2620628d333ceb4a600e2ea9e020a3e3 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Fri, 22 Mar 2024 06:21:29 +0000 Subject: [PATCH 454/577] [release/8.0.3xx] Update dependencies from dotnet/razor (#39657) [release/8.0.3xx] Update dependencies from dotnet/razor - add a fix for namecomparer for DotnetNewSearchTests - add allowthousands to NumberStyles in DotnetNewSearchTests --- eng/Version.Details.xml | 12 ++++++------ eng/Versions.props | 6 +++--- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 6ce486e321c7..8978e0a70de0 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -281,18 +281,18 @@ https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore da7e9894ce22ef8cc02e5acc56e95a6f8cf8f644 - + https://github.com/dotnet/razor - eb9363d4f10d99cb81e9695156beef20e04866c7 + f7afe2cf267453cb8d95c9a98e94b1f7d5c18af6 - + https://github.com/dotnet/razor - eb9363d4f10d99cb81e9695156beef20e04866c7 + f7afe2cf267453cb8d95c9a98e94b1f7d5c18af6 - + https://github.com/dotnet/razor - eb9363d4f10d99cb81e9695156beef20e04866c7 + f7afe2cf267453cb8d95c9a98e94b1f7d5c18af6 https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore diff --git a/eng/Versions.props b/eng/Versions.props index a72a0154cc1d..bc72a4d356b6 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -175,9 +175,9 @@ - 7.0.0-preview.24169.3 - 7.0.0-preview.24169.3 - 7.0.0-preview.24169.3 + 7.0.0-preview.24171.4 + 7.0.0-preview.24171.4 + 7.0.0-preview.24171.4 From 2860178f3e5877ff7a12bb7fdbd54142f2012c5e Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" Date: Fri, 22 Mar 2024 12:59:20 +0000 Subject: [PATCH 455/577] Update dependencies from https://github.com/dotnet/fsharp build Microsoft.SourceBuild.Intermediate.fsharp , Microsoft.FSharp.Compiler From Version 8.0.300-beta.24168.9 -> To Version 8.0.300-beta.24171.7 --- eng/Version.Details.xml | 8 ++++---- eng/Versions.props | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 20a1cea27caf..bf2b08c15ae6 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -64,13 +64,13 @@ de776177f6d540e656e6b0c6d5bb07f2ff518c19 - + https://github.com/dotnet/fsharp - e18404fcaf90b0ee9bbf588ec32d07f466f16fe7 + 891a53ae87f77e25d42d4abe7f26822024f18bb4 - + https://github.com/dotnet/fsharp - e18404fcaf90b0ee9bbf588ec32d07f466f16fe7 + 891a53ae87f77e25d42d4abe7f26822024f18bb4 diff --git a/eng/Versions.props b/eng/Versions.props index be3892bd62a7..c69dc3aaca44 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -150,7 +150,7 @@ - 12.8.300-beta.24168.9 + 12.8.300-beta.24171.7 From ba8e3e96bad981a03a6d3496f769c496f79c52dc Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" Date: Fri, 22 Mar 2024 12:59:45 +0000 Subject: [PATCH 456/577] Update dependencies from https://github.com/dotnet/razor build Microsoft.AspNetCore.Mvc.Razor.Extensions.Tooling.Internal , Microsoft.CodeAnalysis.Razor.Tooling.Internal , Microsoft.NET.Sdk.Razor.SourceGenerators.Transport From Version 7.0.0-preview.24171.4 -> To Version 7.0.0-preview.24171.8 --- eng/Version.Details.xml | 12 ++++++------ eng/Versions.props | 6 +++--- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 20a1cea27caf..96d03f6ea999 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -281,18 +281,18 @@ https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore da7e9894ce22ef8cc02e5acc56e95a6f8cf8f644 - + https://github.com/dotnet/razor - f7afe2cf267453cb8d95c9a98e94b1f7d5c18af6 + 66658cab3e3ca105e4b9a9086dc8f998e31b7f82 - + https://github.com/dotnet/razor - f7afe2cf267453cb8d95c9a98e94b1f7d5c18af6 + 66658cab3e3ca105e4b9a9086dc8f998e31b7f82 - + https://github.com/dotnet/razor - f7afe2cf267453cb8d95c9a98e94b1f7d5c18af6 + 66658cab3e3ca105e4b9a9086dc8f998e31b7f82 https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore diff --git a/eng/Versions.props b/eng/Versions.props index be3892bd62a7..d44b1bc711ef 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -175,9 +175,9 @@ - 7.0.0-preview.24171.4 - 7.0.0-preview.24171.4 - 7.0.0-preview.24171.4 + 7.0.0-preview.24171.8 + 7.0.0-preview.24171.8 + 7.0.0-preview.24171.8 From cf7e3df85042be23cfb05b9529eb507a8b7cba20 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" Date: Fri, 22 Mar 2024 13:02:06 +0000 Subject: [PATCH 457/577] Update dependencies from https://github.com/dotnet/templating build Microsoft.TemplateEngine.Abstractions , Microsoft.TemplateEngine.Mocks From Version 8.0.300-preview.24167.2 -> To Version 8.0.300-preview.24171.9 --- eng/Version.Details.xml | 8 ++++---- eng/Versions.props | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 20a1cea27caf..e75867f514e1 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -1,14 +1,14 @@ - + https://github.com/dotnet/templating - ca94dec30109197c31f2431c3b3941aa8ea21512 + 333afbe4b2a2b19171053492909b3c31d206cd2d - + https://github.com/dotnet/templating - ca94dec30109197c31f2431c3b3941aa8ea21512 + 333afbe4b2a2b19171053492909b3c31d206cd2d https://dev.azure.com/dnceng/internal/_git/dotnet-runtime diff --git a/eng/Versions.props b/eng/Versions.props index be3892bd62a7..c2e24946e047 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -137,13 +137,13 @@ - 8.0.300-preview.24167.2 + 8.0.300-preview.24171.9 $(MicrosoftTemplateEngineAbstractionsPackageVersion) $(MicrosoftTemplateEngineAbstractionsPackageVersion) $(MicrosoftTemplateEngineAbstractionsPackageVersion) $(MicrosoftTemplateEngineAbstractionsPackageVersion) - 8.0.300-preview.24167.2 + 8.0.300-preview.24171.9 $(MicrosoftTemplateEngineMocksPackageVersion) $(MicrosoftTemplateEngineAbstractionsPackageVersion) $(MicrosoftTemplateEngineMocksPackageVersion) From 24e05899134e7268297a216cefe3cec286f6ef73 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" Date: Fri, 22 Mar 2024 13:03:58 +0000 Subject: [PATCH 458/577] Update dependencies from https://github.com/dotnet/arcade build Microsoft.DotNet.Arcade.Sdk , Microsoft.DotNet.Helix.Sdk , Microsoft.DotNet.SignTool , Microsoft.DotNet.XUnitExtensions From Version 8.0.0-beta.24165.4 -> To Version 8.0.0-beta.24170.6 --- eng/Version.Details.xml | 16 ++++++++-------- eng/Versions.props | 4 ++-- global.json | 4 ++-- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 20a1cea27caf..8652fb1a2482 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -479,22 +479,22 @@ - + https://github.com/dotnet/arcade - f311667e0587f19c3fa9553a909975662107a351 + 8e3e00a76f467cc262dc14f6466ab884b2c4eb96 - + https://github.com/dotnet/arcade - f311667e0587f19c3fa9553a909975662107a351 + 8e3e00a76f467cc262dc14f6466ab884b2c4eb96 - + https://github.com/dotnet/arcade - f311667e0587f19c3fa9553a909975662107a351 + 8e3e00a76f467cc262dc14f6466ab884b2c4eb96 - + https://github.com/dotnet/arcade - f311667e0587f19c3fa9553a909975662107a351 + 8e3e00a76f467cc262dc14f6466ab884b2c4eb96 https://dev.azure.com/dnceng/internal/_git/dotnet-runtime diff --git a/eng/Versions.props b/eng/Versions.props index be3892bd62a7..3b57560d79f9 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -34,7 +34,7 @@ 7.0.0 4.0.0 7.0.0 - 8.0.0-beta.24165.4 + 8.0.0-beta.24170.6 7.0.0-preview.22423.2 8.0.0 4.3.0 @@ -209,7 +209,7 @@ 6.12.0 6.1.0 - 8.0.0-beta.24165.4 + 8.0.0-beta.24170.6 4.18.4 1.3.2 8.0.0-beta.23607.1 diff --git a/global.json b/global.json index 46226ea53fdb..5d9847cf6182 100644 --- a/global.json +++ b/global.json @@ -14,7 +14,7 @@ } }, "msbuild-sdks": { - "Microsoft.DotNet.Arcade.Sdk": "8.0.0-beta.24165.4", - "Microsoft.DotNet.Helix.Sdk": "8.0.0-beta.24165.4" + "Microsoft.DotNet.Arcade.Sdk": "8.0.0-beta.24170.6", + "Microsoft.DotNet.Helix.Sdk": "8.0.0-beta.24170.6" } } From 862fc122d43550541bc5b3dcd14c22e79027a5cb Mon Sep 17 00:00:00 2001 From: dotnet bot Date: Fri, 22 Mar 2024 10:50:33 -0700 Subject: [PATCH 459/577] Localized file check-in by OneLocBuild Task: Build definition ID 140: Build ID 2412092 --- .../Microsoft.NET.Build.Containers/Resources/xlf/Strings.es.xlf | 2 +- .../Resources/xlf/Strings.zh-Hans.xlf | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Containers/Microsoft.NET.Build.Containers/Resources/xlf/Strings.es.xlf b/src/Containers/Microsoft.NET.Build.Containers/Resources/xlf/Strings.es.xlf index 7364cbdbfe7b..aa6aa5811e9e 100644 --- a/src/Containers/Microsoft.NET.Build.Containers/Resources/xlf/Strings.es.xlf +++ b/src/Containers/Microsoft.NET.Build.Containers/Resources/xlf/Strings.es.xlf @@ -144,7 +144,7 @@ CONTAINER2030: GenerateLabels was disabled but GenerateDigestLabel was enabled - no digest label will be created. - CONTAINER2030: GenerateLabels was disabled but GenerateDigestLabel was enabled - no digest label will be created. + CONTAINER2030: GenerateLabels se deshabilitó, pero GenerateDigestLabel se deshabilitó; no se creará ninguna etiqueta de resumen. {StrBegin="CONTAINER2030: "} diff --git a/src/Containers/Microsoft.NET.Build.Containers/Resources/xlf/Strings.zh-Hans.xlf b/src/Containers/Microsoft.NET.Build.Containers/Resources/xlf/Strings.zh-Hans.xlf index fadd6de7ab1c..db2a708c4b70 100644 --- a/src/Containers/Microsoft.NET.Build.Containers/Resources/xlf/Strings.zh-Hans.xlf +++ b/src/Containers/Microsoft.NET.Build.Containers/Resources/xlf/Strings.zh-Hans.xlf @@ -144,7 +144,7 @@ CONTAINER2030: GenerateLabels was disabled but GenerateDigestLabel was enabled - no digest label will be created. - CONTAINER2030: GenerateLabels was disabled but GenerateDigestLabel was enabled - no digest label will be created. + CONTAINER2030: 已禁用 GenerateLabels,但已启用 GenerateDigestLabel - 不会创建任何摘要标签。 {StrBegin="CONTAINER2030: "} From 58e38a5602c1fa66e7e7c9f85a92526d34ecb911 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" Date: Sat, 23 Mar 2024 12:54:46 +0000 Subject: [PATCH 460/577] Update dependencies from https://github.com/dotnet/fsharp build Microsoft.SourceBuild.Intermediate.fsharp , Microsoft.FSharp.Compiler From Version 8.0.300-beta.24171.7 -> To Version 8.0.300-beta.24172.5 --- eng/Version.Details.xml | 8 ++++---- eng/Versions.props | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 9cbe389cb981..bd39556f7380 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -64,13 +64,13 @@ de776177f6d540e656e6b0c6d5bb07f2ff518c19 - + https://github.com/dotnet/fsharp - 891a53ae87f77e25d42d4abe7f26822024f18bb4 + 8d852e43d35fdac96b1ba52e3bd4b35350035914 - + https://github.com/dotnet/fsharp - 891a53ae87f77e25d42d4abe7f26822024f18bb4 + 8d852e43d35fdac96b1ba52e3bd4b35350035914 diff --git a/eng/Versions.props b/eng/Versions.props index cf0d794228f8..259002f252af 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -150,7 +150,7 @@ - 12.8.300-beta.24171.7 + 12.8.300-beta.24172.5 From 5a0a2139f6cafa3deb2c4d09b1d08c8168220871 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" Date: Sat, 23 Mar 2024 12:55:12 +0000 Subject: [PATCH 461/577] Update dependencies from https://github.com/dotnet/razor build Microsoft.AspNetCore.Mvc.Razor.Extensions.Tooling.Internal , Microsoft.CodeAnalysis.Razor.Tooling.Internal , Microsoft.NET.Sdk.Razor.SourceGenerators.Transport From Version 7.0.0-preview.24171.8 -> To Version 7.0.0-preview.24172.2 --- eng/Version.Details.xml | 12 ++++++------ eng/Versions.props | 6 +++--- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 9cbe389cb981..94029caf6245 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -281,18 +281,18 @@ https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore da7e9894ce22ef8cc02e5acc56e95a6f8cf8f644 - + https://github.com/dotnet/razor - 66658cab3e3ca105e4b9a9086dc8f998e31b7f82 + 7a445a4daf6fe80bc42668b48498d8aabed3da37 - + https://github.com/dotnet/razor - 66658cab3e3ca105e4b9a9086dc8f998e31b7f82 + 7a445a4daf6fe80bc42668b48498d8aabed3da37 - + https://github.com/dotnet/razor - 66658cab3e3ca105e4b9a9086dc8f998e31b7f82 + 7a445a4daf6fe80bc42668b48498d8aabed3da37 https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore diff --git a/eng/Versions.props b/eng/Versions.props index cf0d794228f8..e00bca9c5547 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -175,9 +175,9 @@ - 7.0.0-preview.24171.8 - 7.0.0-preview.24171.8 - 7.0.0-preview.24171.8 + 7.0.0-preview.24172.2 + 7.0.0-preview.24172.2 + 7.0.0-preview.24172.2 From d07aedbc090393f55cb6d3db42461dd48ba2c25f Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" Date: Sun, 24 Mar 2024 12:46:52 +0000 Subject: [PATCH 462/577] Update dependencies from https://github.com/dotnet/fsharp build Microsoft.SourceBuild.Intermediate.fsharp , Microsoft.FSharp.Compiler From Version 8.0.300-beta.24171.7 -> To Version 8.0.300-beta.24172.5 From ccf4536731f394538e288f7d3afaefcd80dda513 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" Date: Sun, 24 Mar 2024 12:47:22 +0000 Subject: [PATCH 463/577] Update dependencies from https://github.com/dotnet/razor build Microsoft.AspNetCore.Mvc.Razor.Extensions.Tooling.Internal , Microsoft.CodeAnalysis.Razor.Tooling.Internal , Microsoft.NET.Sdk.Razor.SourceGenerators.Transport From Version 7.0.0-preview.24171.8 -> To Version 7.0.0-preview.24173.2 --- eng/Version.Details.xml | 12 ++++++------ eng/Versions.props | 6 +++--- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 94029caf6245..1b65f76cf7e0 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -281,18 +281,18 @@ https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore da7e9894ce22ef8cc02e5acc56e95a6f8cf8f644 - + https://github.com/dotnet/razor - 7a445a4daf6fe80bc42668b48498d8aabed3da37 + 9a645a8f4ae7d7e48522f6dac442897b9a67690a - + https://github.com/dotnet/razor - 7a445a4daf6fe80bc42668b48498d8aabed3da37 + 9a645a8f4ae7d7e48522f6dac442897b9a67690a - + https://github.com/dotnet/razor - 7a445a4daf6fe80bc42668b48498d8aabed3da37 + 9a645a8f4ae7d7e48522f6dac442897b9a67690a https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore diff --git a/eng/Versions.props b/eng/Versions.props index e00bca9c5547..7a10e280563d 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -175,9 +175,9 @@ - 7.0.0-preview.24172.2 - 7.0.0-preview.24172.2 - 7.0.0-preview.24172.2 + 7.0.0-preview.24173.2 + 7.0.0-preview.24173.2 + 7.0.0-preview.24173.2 From 7350125e398988e6891c6cbbd6e39ad4911acc48 Mon Sep 17 00:00:00 2001 From: dotnet bot Date: Sun, 24 Mar 2024 20:20:34 -0700 Subject: [PATCH 464/577] Localized file check-in by OneLocBuild Task: Build definition ID 140: Build ID 2413249 --- .../Microsoft.NET.Build.Containers/Resources/xlf/Strings.fr.xlf | 2 +- .../Microsoft.NET.Build.Containers/Resources/xlf/Strings.ja.xlf | 2 +- .../Microsoft.NET.Build.Containers/Resources/xlf/Strings.ko.xlf | 2 +- .../Resources/xlf/Strings.zh-Hant.xlf | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Containers/Microsoft.NET.Build.Containers/Resources/xlf/Strings.fr.xlf b/src/Containers/Microsoft.NET.Build.Containers/Resources/xlf/Strings.fr.xlf index 8afbdbf783fc..a187efdabcfe 100644 --- a/src/Containers/Microsoft.NET.Build.Containers/Resources/xlf/Strings.fr.xlf +++ b/src/Containers/Microsoft.NET.Build.Containers/Resources/xlf/Strings.fr.xlf @@ -144,7 +144,7 @@ CONTAINER2030: GenerateLabels was disabled but GenerateDigestLabel was enabled - no digest label will be created. - CONTAINER2030: GenerateLabels was disabled but GenerateDigestLabel was enabled - no digest label will be created. + CONTAINER2030: GenerateLabels était désactivé, mais GenerateDigestLabel était activé : aucune étiquette digest ne sera créée. {StrBegin="CONTAINER2030: "} diff --git a/src/Containers/Microsoft.NET.Build.Containers/Resources/xlf/Strings.ja.xlf b/src/Containers/Microsoft.NET.Build.Containers/Resources/xlf/Strings.ja.xlf index 34b1388a710d..777153a9a363 100644 --- a/src/Containers/Microsoft.NET.Build.Containers/Resources/xlf/Strings.ja.xlf +++ b/src/Containers/Microsoft.NET.Build.Containers/Resources/xlf/Strings.ja.xlf @@ -144,7 +144,7 @@ CONTAINER2030: GenerateLabels was disabled but GenerateDigestLabel was enabled - no digest label will be created. - CONTAINER2030: GenerateLabels was disabled but GenerateDigestLabel was enabled - no digest label will be created. + CONTAINER2030: GenerateLabels は無効にされましたが、GenerateDigestLabel が有効になりました。ダイジェスト ラベルは作成されません。 {StrBegin="CONTAINER2030: "} diff --git a/src/Containers/Microsoft.NET.Build.Containers/Resources/xlf/Strings.ko.xlf b/src/Containers/Microsoft.NET.Build.Containers/Resources/xlf/Strings.ko.xlf index c91c2674d3fe..d0d124c24860 100644 --- a/src/Containers/Microsoft.NET.Build.Containers/Resources/xlf/Strings.ko.xlf +++ b/src/Containers/Microsoft.NET.Build.Containers/Resources/xlf/Strings.ko.xlf @@ -144,7 +144,7 @@ CONTAINER2030: GenerateLabels was disabled but GenerateDigestLabel was enabled - no digest label will be created. - CONTAINER2030: GenerateLabels was disabled but GenerateDigestLabel was enabled - no digest label will be created. + CONTAINER2030: GenerateLabels를 사용하지 않도록 설정했지만 GenerateDigestLabel을 사용하도록 설정했습니다. 다이제스트 레이블이 만들어지지 않습니다. {StrBegin="CONTAINER2030: "} diff --git a/src/Containers/Microsoft.NET.Build.Containers/Resources/xlf/Strings.zh-Hant.xlf b/src/Containers/Microsoft.NET.Build.Containers/Resources/xlf/Strings.zh-Hant.xlf index 901f86ed7c37..70ff889b2f3f 100644 --- a/src/Containers/Microsoft.NET.Build.Containers/Resources/xlf/Strings.zh-Hant.xlf +++ b/src/Containers/Microsoft.NET.Build.Containers/Resources/xlf/Strings.zh-Hant.xlf @@ -144,7 +144,7 @@ CONTAINER2030: GenerateLabels was disabled but GenerateDigestLabel was enabled - no digest label will be created. - CONTAINER2030: GenerateLabels was disabled but GenerateDigestLabel was enabled - no digest label will be created. + CONTAINER2030: GenerateLabels 已停用,但 GenerateDigestLabel 已啟用 - 將不會建立摘要標籤。 {StrBegin="CONTAINER2030: "} From 8099562dc4e17ef78c17a3d418d648279e6edaf0 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" Date: Mon, 25 Mar 2024 12:48:13 +0000 Subject: [PATCH 465/577] Update dependencies from https://github.com/dotnet/razor build Microsoft.AspNetCore.Mvc.Razor.Extensions.Tooling.Internal , Microsoft.CodeAnalysis.Razor.Tooling.Internal , Microsoft.NET.Sdk.Razor.SourceGenerators.Transport From Version 7.0.0-preview.24173.2 -> To Version 7.0.0-preview.24175.1 --- eng/Version.Details.xml | 12 ++++++------ eng/Versions.props | 6 +++--- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 79e6fce420d8..ed62e288018d 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -281,18 +281,18 @@ https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore da7e9894ce22ef8cc02e5acc56e95a6f8cf8f644 - + https://github.com/dotnet/razor - 9a645a8f4ae7d7e48522f6dac442897b9a67690a + 0294056d5b40faada727e267ec6e44150d199b71 - + https://github.com/dotnet/razor - 9a645a8f4ae7d7e48522f6dac442897b9a67690a + 0294056d5b40faada727e267ec6e44150d199b71 - + https://github.com/dotnet/razor - 9a645a8f4ae7d7e48522f6dac442897b9a67690a + 0294056d5b40faada727e267ec6e44150d199b71 https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore diff --git a/eng/Versions.props b/eng/Versions.props index b719d4dcd326..6308b360eb25 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -175,9 +175,9 @@ - 7.0.0-preview.24173.2 - 7.0.0-preview.24173.2 - 7.0.0-preview.24173.2 + 7.0.0-preview.24175.1 + 7.0.0-preview.24175.1 + 7.0.0-preview.24175.1 From faef54f9f26af2574d75438bd5a8da13f3900d90 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" Date: Mon, 25 Mar 2024 12:52:45 +0000 Subject: [PATCH 466/577] Update dependencies from https://github.com/dotnet/arcade build Microsoft.DotNet.Arcade.Sdk , Microsoft.DotNet.Helix.Sdk , Microsoft.DotNet.SignTool , Microsoft.DotNet.XUnitExtensions From Version 8.0.0-beta.24170.6 -> To Version 8.0.0-beta.24172.5 --- eng/Version.Details.xml | 16 ++++++++-------- eng/Versions.props | 4 ++-- eng/common/templates-official/job/job.yml | 2 +- global.json | 4 ++-- 4 files changed, 13 insertions(+), 13 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 79e6fce420d8..5d6bbf885482 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -479,22 +479,22 @@ - + https://github.com/dotnet/arcade - 8e3e00a76f467cc262dc14f6466ab884b2c4eb96 + ceb071c1060b8e6de404c065b4045442570caa18 - + https://github.com/dotnet/arcade - 8e3e00a76f467cc262dc14f6466ab884b2c4eb96 + ceb071c1060b8e6de404c065b4045442570caa18 - + https://github.com/dotnet/arcade - 8e3e00a76f467cc262dc14f6466ab884b2c4eb96 + ceb071c1060b8e6de404c065b4045442570caa18 - + https://github.com/dotnet/arcade - 8e3e00a76f467cc262dc14f6466ab884b2c4eb96 + ceb071c1060b8e6de404c065b4045442570caa18 https://dev.azure.com/dnceng/internal/_git/dotnet-runtime diff --git a/eng/Versions.props b/eng/Versions.props index b719d4dcd326..dbf03b615f12 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -34,7 +34,7 @@ 7.0.0 4.0.0 7.0.0 - 8.0.0-beta.24170.6 + 8.0.0-beta.24172.5 7.0.0-preview.22423.2 8.0.0 4.3.0 @@ -209,7 +209,7 @@ 6.12.0 6.1.0 - 8.0.0-beta.24170.6 + 8.0.0-beta.24172.5 4.18.4 1.3.2 8.0.0-beta.23607.1 diff --git a/eng/common/templates-official/job/job.yml b/eng/common/templates-official/job/job.yml index a2709d10562c..0604277a2ff5 100644 --- a/eng/common/templates-official/job/job.yml +++ b/eng/common/templates-official/job/job.yml @@ -128,7 +128,7 @@ jobs: - ${{ if and(eq(parameters.runAsPublic, 'false'), ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest')) }}: - ${{ if eq(parameters.enableMicrobuild, 'true') }}: - - task: MicroBuildSigningPlugin@3 + - task: MicroBuildSigningPlugin@4 displayName: Install MicroBuild plugin inputs: signType: $(_SignType) diff --git a/global.json b/global.json index 5d9847cf6182..6337455b7bab 100644 --- a/global.json +++ b/global.json @@ -14,7 +14,7 @@ } }, "msbuild-sdks": { - "Microsoft.DotNet.Arcade.Sdk": "8.0.0-beta.24170.6", - "Microsoft.DotNet.Helix.Sdk": "8.0.0-beta.24170.6" + "Microsoft.DotNet.Arcade.Sdk": "8.0.0-beta.24172.5", + "Microsoft.DotNet.Helix.Sdk": "8.0.0-beta.24172.5" } } From be4043e75c7261f0316194240d39834e5a805d5b Mon Sep 17 00:00:00 2001 From: Chet Husk Date: Tue, 26 Mar 2024 11:10:07 -0500 Subject: [PATCH 467/577] skip CanSortByDownloadCountAndThenByName because it's blocking --- src/Tests/dotnet-new.Tests/DotnetNewSearchTests.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/Tests/dotnet-new.Tests/DotnetNewSearchTests.cs b/src/Tests/dotnet-new.Tests/DotnetNewSearchTests.cs index 8c25c11dcaf7..c125b4160150 100644 --- a/src/Tests/dotnet-new.Tests/DotnetNewSearchTests.cs +++ b/src/Tests/dotnet-new.Tests/DotnetNewSearchTests.cs @@ -436,7 +436,9 @@ public void CanFilterPackage_WithoutName(string testCase) Assert.True(AtLeastOneRowIsNotEmpty(tableOutput, "Downloads"), "'Downloads' column contains empty values"); } - [Theory] +#pragma warning disable xUnit1004 + [Theory(Skip = "https://github.com/dotnet/sdk/issues/39772")] +#pragma warning restore xUnit1004 [InlineData("console --search")] [InlineData("--search console")] [InlineData("search console")] From f2f59be833e7e2ab508f649ddeb6e39d64255660 Mon Sep 17 00:00:00 2001 From: Chet Husk Date: Tue, 26 Mar 2024 17:12:09 -0500 Subject: [PATCH 468/577] Create a new label with TFM of the app and the SDK used to build the image (#39196) --- .../Resources/Strings.Designer.cs | 22 ++++++------- .../Microsoft.NET.Build.Containers.targets | 5 ++- .../ProjectInitializer.cs | 2 +- .../TargetsTests.cs | 33 +++++++++++++++++++ 4 files changed, 49 insertions(+), 13 deletions(-) diff --git a/src/Containers/Microsoft.NET.Build.Containers/Resources/Strings.Designer.cs b/src/Containers/Microsoft.NET.Build.Containers/Resources/Strings.Designer.cs index 7d9ee2b0048d..45607eb642a2 100644 --- a/src/Containers/Microsoft.NET.Build.Containers/Resources/Strings.Designer.cs +++ b/src/Containers/Microsoft.NET.Build.Containers/Resources/Strings.Designer.cs @@ -388,6 +388,17 @@ internal static string FailedRetrievingCredentials } } + ///

+ /// Looks up a localized string similar to CONTAINER2030: GenerateLabels was disabled but GenerateDigestLabel was enabled - no digest label will be created. + /// + internal static string GenerateDigestLabelWithoutGenerateLabels + { + get + { + return ResourceManager.GetString("GenerateDigestLabelWithoutGenerateLabels", resourceCulture); + } + } + /// /// Looks up a localized string similar to No host object detected.. /// @@ -893,16 +904,5 @@ internal static string UnrecognizedMediaType return ResourceManager.GetString("UnrecognizedMediaType", resourceCulture); } } - - /// - /// Looks up a localized string similar to CONTAINER2030: GenerateLabels was disabled but GenerateDigestLabel was enabled - no digest label will be created.. - /// - internal static string GenerateDigestLabelWithoutGenerateLabels - { - get - { - return ResourceManager.GetString("GenerateDigestLabelWithoutGenerateLabels", resourceCulture); - } - } } } diff --git a/src/Containers/packaging/build/Microsoft.NET.Build.Containers.targets b/src/Containers/packaging/build/Microsoft.NET.Build.Containers.targets index cd8dd876f0b5..f2c3397aaabd 100644 --- a/src/Containers/packaging/build/Microsoft.NET.Build.Containers.targets +++ b/src/Containers/packaging/build/Microsoft.NET.Build.Containers.targets @@ -141,6 +141,7 @@ true true true + true @@ -167,6 +168,8 @@ + + - 7.0.0-preview.24175.1 - 7.0.0-preview.24175.1 - 7.0.0-preview.24175.1 + 7.0.0-preview.24176.4 + 7.0.0-preview.24176.4 + 7.0.0-preview.24176.4 From a35de7ab95f5c93d18687170ba0048fca634cd86 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Wed, 27 Mar 2024 12:18:58 -0700 Subject: [PATCH 486/577] [release/8.0.3xx] Update dependencies from dotnet/fsharp (#39810) Co-authored-by: dotnet-maestro[bot] --- eng/Version.Details.xml | 8 ++++---- eng/Versions.props | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 8aedee25aae3..967ab6e01e14 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -64,13 +64,13 @@ de776177f6d540e656e6b0c6d5bb07f2ff518c19 - + https://github.com/dotnet/fsharp - 8d852e43d35fdac96b1ba52e3bd4b35350035914 + 4a394198efadc455334ae272954ece372aea4de2 - + https://github.com/dotnet/fsharp - 8d852e43d35fdac96b1ba52e3bd4b35350035914 + 4a394198efadc455334ae272954ece372aea4de2 diff --git a/eng/Versions.props b/eng/Versions.props index 184469b4a0d9..2a5de80a5c9c 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -150,7 +150,7 @@ - 12.8.300-beta.24172.5 + 12.8.300-beta.24175.1 From aaa4eba3e193f7f3b7a7f8bf2707b51704a341c1 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Wed, 27 Mar 2024 12:19:17 -0700 Subject: [PATCH 487/577] [release/8.0.3xx] Update dependencies from dotnet/msbuild (#39809) Co-authored-by: dotnet-maestro[bot] --- eng/Version.Details.xml | 12 ++++++------ eng/Versions.props | 4 ++-- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 967ab6e01e14..be17fde3e57e 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -51,17 +51,17 @@ https://github.com/dotnet/emsdk 2fc2ffd960930318f33fcaa690cbdbc55d72f52d - + https://github.com/dotnet/msbuild - de776177f6d540e656e6b0c6d5bb07f2ff518c19 + 6064d9c8fe7beb06ffc10f8ff27ce967039a2c0d - + https://github.com/dotnet/msbuild - de776177f6d540e656e6b0c6d5bb07f2ff518c19 + 6064d9c8fe7beb06ffc10f8ff27ce967039a2c0d - + https://github.com/dotnet/msbuild - de776177f6d540e656e6b0c6d5bb07f2ff518c19 + 6064d9c8fe7beb06ffc10f8ff27ce967039a2c0d diff --git a/eng/Versions.props b/eng/Versions.props index 2a5de80a5c9c..16ea9a81d602 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -120,7 +120,7 @@ - 17.10.0-preview-24171-01 + 17.10.0-preview-24177-05 $(MicrosoftBuildPackageVersion) - 6.10.0-preview.2.81 - 6.10.0-preview.2.81 - 6.10.0-preview.2.81 - 6.10.0-preview.2.81 - 6.10.0-preview.2.81 - 6.10.0-preview.2.81 - 6.10.0-preview.2.81 - 6.10.0-preview.2.81 - 6.10.0-preview.2.81 - 6.10.0-preview.2.81 - 6.10.0-preview.2.81 - 6.10.0-preview.2.81 + 6.10.0-preview.2.97 + 6.10.0-preview.2.97 + 6.10.0-preview.2.97 + 6.10.0-preview.2.97 + 6.10.0-preview.2.97 + 6.10.0-preview.2.97 + 6.10.0-preview.2.97 + 6.10.0-preview.2.97 + 6.10.0-preview.2.97 + 6.10.0-preview.2.97 + 6.10.0-preview.2.97 + 6.10.0-preview.2.97 $(NuGetPackagingPackageVersion) $(NuGetProjectModelPackageVersion) From 68bbab255a5ee7d21d3bf46ce1cab0cf1b698c1a Mon Sep 17 00:00:00 2001 From: dotnet bot Date: Wed, 27 Mar 2024 12:57:45 -0700 Subject: [PATCH 489/577] Localized file check-in by OneLocBuild Task: Build definition ID 140: Build ID 2416376 --- .../Microsoft.NET.Build.Containers/Resources/xlf/Strings.tr.xlf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Containers/Microsoft.NET.Build.Containers/Resources/xlf/Strings.tr.xlf b/src/Containers/Microsoft.NET.Build.Containers/Resources/xlf/Strings.tr.xlf index 961fcff03a61..861c53cf7423 100644 --- a/src/Containers/Microsoft.NET.Build.Containers/Resources/xlf/Strings.tr.xlf +++ b/src/Containers/Microsoft.NET.Build.Containers/Resources/xlf/Strings.tr.xlf @@ -144,7 +144,7 @@ CONTAINER2030: GenerateLabels was disabled but GenerateDigestLabel was enabled - no digest label will be created. - CONTAINER2030: GenerateLabels was disabled but GenerateDigestLabel was enabled - no digest label will be created. + CONTAINER2030: GenerateLabels devre dışı bırakıldı ancak GenerateDigestLabel etkinleştirildi; özet etiketi oluşturulmayacak. {StrBegin="CONTAINER2030: "} From 049918f85f5485e0f827709aeb36f5dc61810429 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Wed, 27 Mar 2024 21:32:45 +0000 Subject: [PATCH 490/577] [release/8.0.3xx] Update dependencies from dotnet/roslyn (#39693) [release/8.0.3xx] Update dependencies from dotnet/roslyn - Try to fix failed tests to unblock the build - Merge branch 'release/8.0.3xx' of https://github.com/dotnet/sdk into darc-release/8.0.3xx-a8a8bd12-266d-4c08-a579-66895d8fc8f0 --- eng/Version.Details.xml | 28 +++++++++---------- eng/Versions.props | 14 +++++----- .../CSharpFileBuilderTests.cs | 10 +++---- 3 files changed, 26 insertions(+), 26 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index cdb9a835c7f6..fae6c687889c 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -78,34 +78,34 @@ ac0d85557969d51bca72181514ddb7d5796fbbe2 - + https://github.com/dotnet/roslyn - c8dd474b73167a0f1b07514082d162c7febdf33f + 5fae9589875f09f3e77c9480f5f3cb1d12f5a02f - + https://github.com/dotnet/roslyn - c8dd474b73167a0f1b07514082d162c7febdf33f + 5fae9589875f09f3e77c9480f5f3cb1d12f5a02f - + https://github.com/dotnet/roslyn - c8dd474b73167a0f1b07514082d162c7febdf33f + 5fae9589875f09f3e77c9480f5f3cb1d12f5a02f - + https://github.com/dotnet/roslyn - c8dd474b73167a0f1b07514082d162c7febdf33f + 5fae9589875f09f3e77c9480f5f3cb1d12f5a02f - + https://github.com/dotnet/roslyn - c8dd474b73167a0f1b07514082d162c7febdf33f + 5fae9589875f09f3e77c9480f5f3cb1d12f5a02f - + https://github.com/dotnet/roslyn - c8dd474b73167a0f1b07514082d162c7febdf33f + 5fae9589875f09f3e77c9480f5f3cb1d12f5a02f - + https://github.com/dotnet/roslyn - c8dd474b73167a0f1b07514082d162c7febdf33f + 5fae9589875f09f3e77c9480f5f3cb1d12f5a02f https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore diff --git a/eng/Versions.props b/eng/Versions.props index 25240b63ff5d..595ba5beacca 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -154,13 +154,13 @@ - 4.10.0-3.24171.1 - 4.10.0-3.24171.1 - 4.10.0-3.24171.1 - 4.10.0-3.24171.1 - 4.10.0-3.24171.1 - 4.10.0-3.24171.1 - 4.10.0-3.24171.1 + 4.11.0-1.24176.16 + 4.11.0-1.24176.16 + 4.11.0-1.24176.16 + 4.11.0-1.24176.16 + 4.11.0-1.24176.16 + 4.11.0-1.24176.16 + 4.11.0-1.24176.16 $(MicrosoftNetCompilersToolsetPackageVersion) diff --git a/src/Tests/Microsoft.DotNet.GenAPI.Tests/CSharpFileBuilderTests.cs b/src/Tests/Microsoft.DotNet.GenAPI.Tests/CSharpFileBuilderTests.cs index 2d7fb43dcd25..8b497719dd0a 100644 --- a/src/Tests/Microsoft.DotNet.GenAPI.Tests/CSharpFileBuilderTests.cs +++ b/src/Tests/Microsoft.DotNet.GenAPI.Tests/CSharpFileBuilderTests.cs @@ -269,23 +269,23 @@ private SealedRecordWithPrivateDefaultConstructor() { } expected: """ namespace Foo { - public partial record DerivedRecord(string s, int i, double d) : RecordClass2(default(string)!, default(int)) + public partial record DerivedRecord(string s, int i, double d) : RecordClass2(default!, default) { } - public partial record DerivedRecord2(string x, int i, double d) : RecordClass2(default(string)!, default(int)) + public partial record DerivedRecord2(string x, int i, double d) : RecordClass2(default!, default) { } - public partial record DerivedRecord3(string x, int i, double d) : RecordClass2(default(string)!, default(int)) + public partial record DerivedRecord3(string x, int i, double d) : RecordClass2(default!, default) { } - public partial record DerivedRecord4(double d) : RecordClass2(default(string)!, default(int)) + public partial record DerivedRecord4(double d) : RecordClass2(default!, default) { } - public partial record DerivedRecord5() : RecordClass2(default(string)!, default(int)) + public partial record DerivedRecord5() : RecordClass2(default!, default) { } From 67b09cf4a06cfdd3f48bbf897d9849bec902ab47 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" Date: Thu, 28 Mar 2024 13:10:53 +0000 Subject: [PATCH 491/577] Update dependencies from https://github.com/dotnet/msbuild build 20240328.7 Microsoft.SourceBuild.Intermediate.msbuild , Microsoft.Build , Microsoft.Build.Localization From Version 17.10.0-preview-24177-05 -> To Version 17.11.0-preview-24178-07 --- eng/Version.Details.xml | 12 ++++++------ eng/Versions.props | 4 ++-- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index fae6c687889c..54c064360353 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -51,17 +51,17 @@ https://github.com/dotnet/emsdk 2fc2ffd960930318f33fcaa690cbdbc55d72f52d - + https://github.com/dotnet/msbuild - 6064d9c8fe7beb06ffc10f8ff27ce967039a2c0d + 1e513b346acdf40dd2586a463e38f89fa72a69e9 - + https://github.com/dotnet/msbuild - 6064d9c8fe7beb06ffc10f8ff27ce967039a2c0d + 1e513b346acdf40dd2586a463e38f89fa72a69e9 - + https://github.com/dotnet/msbuild - 6064d9c8fe7beb06ffc10f8ff27ce967039a2c0d + 1e513b346acdf40dd2586a463e38f89fa72a69e9 diff --git a/eng/Versions.props b/eng/Versions.props index 595ba5beacca..7fa41bfeed63 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -120,7 +120,7 @@ - 17.10.0-preview-24177-05 + 17.11.0-preview-24178-07 $(MicrosoftBuildPackageVersion) - 17.10.0-preview-24170-01 - 17.10.0-preview-24170-01 - 17.10.0-preview-24170-01 + 17.10.0-release-24177-07 + 17.10.0-release-24177-07 + 17.10.0-release-24177-07 From 157204bf9097e966233ed78d6f7c7945eac50aac Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" Date: Thu, 28 Mar 2024 13:13:41 +0000 Subject: [PATCH 493/577] Update dependencies from https://github.com/dotnet/roslyn build 20240327.10 Microsoft.CodeAnalysis , Microsoft.CodeAnalysis.CSharp , Microsoft.CodeAnalysis.CSharp.CodeStyle , Microsoft.CodeAnalysis.CSharp.Features , Microsoft.CodeAnalysis.CSharp.Workspaces , Microsoft.CodeAnalysis.Workspaces.MSBuild , Microsoft.Net.Compilers.Toolset From Version 4.11.0-1.24176.16 -> To Version 4.11.0-1.24177.10 --- eng/Version.Details.xml | 28 ++++++++++++++-------------- eng/Versions.props | 14 +++++++------- 2 files changed, 21 insertions(+), 21 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index fae6c687889c..5ec8d00133b7 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -78,34 +78,34 @@ ac0d85557969d51bca72181514ddb7d5796fbbe2 - + https://github.com/dotnet/roslyn - 5fae9589875f09f3e77c9480f5f3cb1d12f5a02f + 70c173446a3b354fb586e51301fc79aa809fafb4 - + https://github.com/dotnet/roslyn - 5fae9589875f09f3e77c9480f5f3cb1d12f5a02f + 70c173446a3b354fb586e51301fc79aa809fafb4 - + https://github.com/dotnet/roslyn - 5fae9589875f09f3e77c9480f5f3cb1d12f5a02f + 70c173446a3b354fb586e51301fc79aa809fafb4 - + https://github.com/dotnet/roslyn - 5fae9589875f09f3e77c9480f5f3cb1d12f5a02f + 70c173446a3b354fb586e51301fc79aa809fafb4 - + https://github.com/dotnet/roslyn - 5fae9589875f09f3e77c9480f5f3cb1d12f5a02f + 70c173446a3b354fb586e51301fc79aa809fafb4 - + https://github.com/dotnet/roslyn - 5fae9589875f09f3e77c9480f5f3cb1d12f5a02f + 70c173446a3b354fb586e51301fc79aa809fafb4 - + https://github.com/dotnet/roslyn - 5fae9589875f09f3e77c9480f5f3cb1d12f5a02f + 70c173446a3b354fb586e51301fc79aa809fafb4 https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore diff --git a/eng/Versions.props b/eng/Versions.props index 595ba5beacca..1da34766a8f9 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -154,13 +154,13 @@ - 4.11.0-1.24176.16 - 4.11.0-1.24176.16 - 4.11.0-1.24176.16 - 4.11.0-1.24176.16 - 4.11.0-1.24176.16 - 4.11.0-1.24176.16 - 4.11.0-1.24176.16 + 4.11.0-1.24177.10 + 4.11.0-1.24177.10 + 4.11.0-1.24177.10 + 4.11.0-1.24177.10 + 4.11.0-1.24177.10 + 4.11.0-1.24177.10 + 4.11.0-1.24177.10 $(MicrosoftNetCompilersToolsetPackageVersion) From 948474beea00489c268841cd75f51d880f23c1d2 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" Date: Thu, 28 Mar 2024 13:18:45 +0000 Subject: [PATCH 494/577] Update dependencies from https://github.com/dotnet/arcade build 20240327.1 Microsoft.DotNet.Arcade.Sdk , Microsoft.DotNet.Helix.Sdk , Microsoft.DotNet.SignTool , Microsoft.DotNet.XUnitExtensions From Version 8.0.0-beta.24176.8 -> To Version 8.0.0-beta.24177.1 --- eng/Version.Details.xml | 16 ++++++++-------- eng/Versions.props | 4 ++-- eng/common/native/init-compiler.sh | 2 +- global.json | 4 ++-- 4 files changed, 13 insertions(+), 13 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index fae6c687889c..0025be82fc19 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -479,22 +479,22 @@ - + https://github.com/dotnet/arcade - 48e9e0d2164de0535446809364724da8962123a6 + b17b2a1bb7da23253043dee059f374b00f3e321a - + https://github.com/dotnet/arcade - 48e9e0d2164de0535446809364724da8962123a6 + b17b2a1bb7da23253043dee059f374b00f3e321a - + https://github.com/dotnet/arcade - 48e9e0d2164de0535446809364724da8962123a6 + b17b2a1bb7da23253043dee059f374b00f3e321a - + https://github.com/dotnet/arcade - 48e9e0d2164de0535446809364724da8962123a6 + b17b2a1bb7da23253043dee059f374b00f3e321a https://dev.azure.com/dnceng/internal/_git/dotnet-runtime diff --git a/eng/Versions.props b/eng/Versions.props index 595ba5beacca..d444a9f8a002 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -34,7 +34,7 @@ 7.0.0 4.0.0 7.0.0 - 8.0.0-beta.24176.8 + 8.0.0-beta.24177.1 7.0.0-preview.22423.2 8.0.0 4.3.0 @@ -209,7 +209,7 @@ 6.12.0 6.1.0 - 8.0.0-beta.24176.8 + 8.0.0-beta.24177.1 4.18.4 1.3.2 8.0.0-beta.23607.1 diff --git a/eng/common/native/init-compiler.sh b/eng/common/native/init-compiler.sh index f5c1ec7eafeb..2d5660642b8d 100644 --- a/eng/common/native/init-compiler.sh +++ b/eng/common/native/init-compiler.sh @@ -63,7 +63,7 @@ if [ -z "$CLR_CC" ]; then # Set default versions if [ -z "$majorVersion" ]; then # note: gcc (all versions) and clang versions higher than 6 do not have minor version in file name, if it is zero. - if [ "$compiler" = "clang" ]; then versions="17 16 15 14 13 12 11 10 9 8 7 6.0 5.0 4.0 3.9 3.8 3.7 3.6 3.5" + if [ "$compiler" = "clang" ]; then versions="18 17 16 15 14 13 12 11 10 9 8 7 6.0 5.0 4.0 3.9 3.8 3.7 3.6 3.5" elif [ "$compiler" = "gcc" ]; then versions="13 12 11 10 9 8 7 6 5 4.9"; fi for version in $versions; do diff --git a/global.json b/global.json index 09c7c987a6a4..551b79149203 100644 --- a/global.json +++ b/global.json @@ -14,7 +14,7 @@ } }, "msbuild-sdks": { - "Microsoft.DotNet.Arcade.Sdk": "8.0.0-beta.24176.8", - "Microsoft.DotNet.Helix.Sdk": "8.0.0-beta.24176.8" + "Microsoft.DotNet.Arcade.Sdk": "8.0.0-beta.24177.1", + "Microsoft.DotNet.Helix.Sdk": "8.0.0-beta.24177.1" } } From dba01f7749cf1f0b74c922db0743c0573390968e Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Thu, 28 Mar 2024 15:50:41 +0000 Subject: [PATCH 495/577] [release/8.0.3xx] Update dependencies from dotnet/templating (#39720) [release/8.0.3xx] Update dependencies from dotnet/templating --- eng/Version.Details.xml | 8 ++++---- eng/Versions.props | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index fae6c687889c..c976e62eb4c9 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -1,14 +1,14 @@ - + https://github.com/dotnet/templating - 333afbe4b2a2b19171053492909b3c31d206cd2d + eaef194ef84f0bae7a49ac3b6d96505086130cea - + https://github.com/dotnet/templating - 333afbe4b2a2b19171053492909b3c31d206cd2d + eaef194ef84f0bae7a49ac3b6d96505086130cea https://dev.azure.com/dnceng/internal/_git/dotnet-runtime diff --git a/eng/Versions.props b/eng/Versions.props index 595ba5beacca..fc96705a189d 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -137,13 +137,13 @@ - 8.0.300-preview.24171.9 + 8.0.300-preview.24177.3 $(MicrosoftTemplateEngineAbstractionsPackageVersion) $(MicrosoftTemplateEngineAbstractionsPackageVersion) $(MicrosoftTemplateEngineAbstractionsPackageVersion) $(MicrosoftTemplateEngineAbstractionsPackageVersion) - 8.0.300-preview.24171.9 + 8.0.300-preview.24177.3 $(MicrosoftTemplateEngineMocksPackageVersion) $(MicrosoftTemplateEngineAbstractionsPackageVersion) $(MicrosoftTemplateEngineMocksPackageVersion) From 68118be2a4bca991bf02d7896d296229fee2076d Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Fri, 29 Mar 2024 08:00:07 +0000 Subject: [PATCH 496/577] [release/8.0.3xx] Update dependencies from dotnet/razor (#39860) [release/8.0.3xx] Update dependencies from dotnet/razor --- eng/Version.Details.xml | 12 ++++++------ eng/Versions.props | 6 +++--- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 347b6a08fc44..eb34234fc438 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -281,18 +281,18 @@ https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore da7e9894ce22ef8cc02e5acc56e95a6f8cf8f644 - + https://github.com/dotnet/razor - e832b1d125c2d73f7ea7e17b81c0cb4a622257a9 + 95d21239fc7a81d0c7e6a6c7abf4748f0553a23d - + https://github.com/dotnet/razor - e832b1d125c2d73f7ea7e17b81c0cb4a622257a9 + 95d21239fc7a81d0c7e6a6c7abf4748f0553a23d - + https://github.com/dotnet/razor - e832b1d125c2d73f7ea7e17b81c0cb4a622257a9 + 95d21239fc7a81d0c7e6a6c7abf4748f0553a23d https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore diff --git a/eng/Versions.props b/eng/Versions.props index 02580d39232a..11c10fa4b76f 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -175,9 +175,9 @@ - 7.0.0-preview.24176.4 - 7.0.0-preview.24176.4 - 7.0.0-preview.24176.4 + 7.0.0-preview.24178.2 + 7.0.0-preview.24178.2 + 7.0.0-preview.24178.2 From 6d79a3ed0d5b47b71805baed255f46247d607bf6 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" Date: Fri, 29 Mar 2024 13:00:21 +0000 Subject: [PATCH 497/577] Update dependencies from https://github.com/dotnet/msbuild build 20240328.16 Microsoft.SourceBuild.Intermediate.msbuild , Microsoft.Build , Microsoft.Build.Localization From Version 17.11.0-preview-24178-07 -> To Version 17.11.0-preview-24178-16 --- eng/Version.Details.xml | 12 ++++++------ eng/Versions.props | 4 ++-- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 1dd75af6d27b..45970e3cc7f5 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -51,17 +51,17 @@ https://github.com/dotnet/emsdk 2fc2ffd960930318f33fcaa690cbdbc55d72f52d - + https://github.com/dotnet/msbuild - 1e513b346acdf40dd2586a463e38f89fa72a69e9 + 7ca3c98fad986066bbf2802c863236b4a0f4e34a - + https://github.com/dotnet/msbuild - 1e513b346acdf40dd2586a463e38f89fa72a69e9 + 7ca3c98fad986066bbf2802c863236b4a0f4e34a - + https://github.com/dotnet/msbuild - 1e513b346acdf40dd2586a463e38f89fa72a69e9 + 7ca3c98fad986066bbf2802c863236b4a0f4e34a diff --git a/eng/Versions.props b/eng/Versions.props index b24602f0c17b..104d4402cdcd 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -120,7 +120,7 @@ - 17.11.0-preview-24178-07 + 17.11.0-preview-24178-16 $(MicrosoftBuildPackageVersion) - 4.11.0-1.24177.10 - 4.11.0-1.24177.10 - 4.11.0-1.24177.10 - 4.11.0-1.24177.10 - 4.11.0-1.24177.10 - 4.11.0-1.24177.10 - 4.11.0-1.24177.10 + 4.11.0-1.24179.2 + 4.11.0-1.24179.2 + 4.11.0-1.24179.2 + 4.11.0-1.24179.2 + 4.11.0-1.24179.2 + 4.11.0-1.24179.2 + 4.11.0-1.24179.2 $(MicrosoftNetCompilersToolsetPackageVersion) From d2cbbe1a2a1f4be1f103306ae1799ce86b5a782a Mon Sep 17 00:00:00 2001 From: Marc Paine Date: Fri, 29 Mar 2024 16:38:40 -0700 Subject: [PATCH 499/577] Pin to 8.0.0 in framework builds for two components loading in VS --- .../Microsoft.DotNet.TemplateLocator.csproj | 5 ++++- .../Microsoft.DotNet.MSBuildSdkResolver.csproj | 1 + 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/Microsoft.DotNet.TemplateLocator/Microsoft.DotNet.TemplateLocator.csproj b/src/Microsoft.DotNet.TemplateLocator/Microsoft.DotNet.TemplateLocator.csproj index 84bd3a16954c..00a88bf144fc 100644 --- a/src/Microsoft.DotNet.TemplateLocator/Microsoft.DotNet.TemplateLocator.csproj +++ b/src/Microsoft.DotNet.TemplateLocator/Microsoft.DotNet.TemplateLocator.csproj @@ -58,8 +58,11 @@ + + + + - diff --git a/src/Resolvers/Microsoft.DotNet.MSBuildSdkResolver/Microsoft.DotNet.MSBuildSdkResolver.csproj b/src/Resolvers/Microsoft.DotNet.MSBuildSdkResolver/Microsoft.DotNet.MSBuildSdkResolver.csproj index 600d5decb5e7..82e9e7edd70b 100644 --- a/src/Resolvers/Microsoft.DotNet.MSBuildSdkResolver/Microsoft.DotNet.MSBuildSdkResolver.csproj +++ b/src/Resolvers/Microsoft.DotNet.MSBuildSdkResolver/Microsoft.DotNet.MSBuildSdkResolver.csproj @@ -91,6 +91,7 @@ + From fbcd5bd3ed5c0a75389d31b088e7bae8dba0a6f2 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" Date: Sat, 30 Mar 2024 13:05:36 +0000 Subject: [PATCH 500/577] Update dependencies from https://github.com/dotnet/msbuild build 20240328.16 Microsoft.SourceBuild.Intermediate.msbuild , Microsoft.Build , Microsoft.Build.Localization From Version 17.11.0-preview-24178-07 -> To Version 17.11.0-preview-24178-16 From 7bb622ec60f31b264ec9121bf119dc61485dd4c2 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" Date: Sat, 30 Mar 2024 13:08:04 +0000 Subject: [PATCH 501/577] Update dependencies from https://github.com/dotnet/roslyn build 20240329.14 Microsoft.CodeAnalysis , Microsoft.CodeAnalysis.CSharp , Microsoft.CodeAnalysis.CSharp.CodeStyle , Microsoft.CodeAnalysis.CSharp.Features , Microsoft.CodeAnalysis.CSharp.Workspaces , Microsoft.CodeAnalysis.Workspaces.MSBuild , Microsoft.Net.Compilers.Toolset From Version 4.11.0-1.24177.10 -> To Version 4.11.0-1.24179.14 --- eng/Version.Details.xml | 28 ++++++++++++++-------------- eng/Versions.props | 14 +++++++------- 2 files changed, 21 insertions(+), 21 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index b8c416d9f880..e27b7d0a3e60 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -78,34 +78,34 @@ ac0d85557969d51bca72181514ddb7d5796fbbe2 - + https://github.com/dotnet/roslyn - 7040e04698e10896823fb51c92bbfdc4130d1730 + b081f5a01d4a96dd26ce5605ff4035d184f1907f - + https://github.com/dotnet/roslyn - 7040e04698e10896823fb51c92bbfdc4130d1730 + b081f5a01d4a96dd26ce5605ff4035d184f1907f - + https://github.com/dotnet/roslyn - 7040e04698e10896823fb51c92bbfdc4130d1730 + b081f5a01d4a96dd26ce5605ff4035d184f1907f - + https://github.com/dotnet/roslyn - 7040e04698e10896823fb51c92bbfdc4130d1730 + b081f5a01d4a96dd26ce5605ff4035d184f1907f - + https://github.com/dotnet/roslyn - 7040e04698e10896823fb51c92bbfdc4130d1730 + b081f5a01d4a96dd26ce5605ff4035d184f1907f - + https://github.com/dotnet/roslyn - 7040e04698e10896823fb51c92bbfdc4130d1730 + b081f5a01d4a96dd26ce5605ff4035d184f1907f - + https://github.com/dotnet/roslyn - 7040e04698e10896823fb51c92bbfdc4130d1730 + b081f5a01d4a96dd26ce5605ff4035d184f1907f https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore diff --git a/eng/Versions.props b/eng/Versions.props index e4136a68db8a..16ce6d63b1c7 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -154,13 +154,13 @@ - 4.11.0-1.24179.2 - 4.11.0-1.24179.2 - 4.11.0-1.24179.2 - 4.11.0-1.24179.2 - 4.11.0-1.24179.2 - 4.11.0-1.24179.2 - 4.11.0-1.24179.2 + 4.11.0-1.24179.14 + 4.11.0-1.24179.14 + 4.11.0-1.24179.14 + 4.11.0-1.24179.14 + 4.11.0-1.24179.14 + 4.11.0-1.24179.14 + 4.11.0-1.24179.14 $(MicrosoftNetCompilersToolsetPackageVersion) From d9aaa98f1b0f3a24a6fd685a5b46d10ffca07afa Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" Date: Sun, 31 Mar 2024 12:57:08 +0000 Subject: [PATCH 502/577] Update dependencies from https://github.com/dotnet/msbuild build 20240328.16 Microsoft.SourceBuild.Intermediate.msbuild , Microsoft.Build , Microsoft.Build.Localization From Version 17.11.0-preview-24178-07 -> To Version 17.11.0-preview-24178-16 From 0b06e81603fb4e3bcd5a393cc536dbe3fe38a8ec Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" Date: Mon, 1 Apr 2024 12:55:24 +0000 Subject: [PATCH 503/577] Update dependencies from https://github.com/dotnet/msbuild build 20240328.16 Microsoft.SourceBuild.Intermediate.msbuild , Microsoft.Build , Microsoft.Build.Localization From Version 17.11.0-preview-24178-07 -> To Version 17.11.0-preview-24178-16 From 038d2b27f13495c160779dbea7fc8673517b98fc Mon Sep 17 00:00:00 2001 From: Rainer Sigwald Date: Mon, 1 Apr 2024 16:16:40 -0500 Subject: [PATCH 504/577] Move back to first 17.10.0 branded build --- NuGet.config | 1 + eng/Version.Details.xml | 12 ++++++------ eng/Versions.props | 4 ++-- 3 files changed, 9 insertions(+), 8 deletions(-) diff --git a/NuGet.config b/NuGet.config index 047e1cd427aa..51639cc36b97 100644 --- a/NuGet.config +++ b/NuGet.config @@ -12,6 +12,7 @@ + diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 45970e3cc7f5..27c946854a1f 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -51,17 +51,17 @@ https://github.com/dotnet/emsdk 2fc2ffd960930318f33fcaa690cbdbc55d72f52d - + https://github.com/dotnet/msbuild - 7ca3c98fad986066bbf2802c863236b4a0f4e34a + 4f6b1bb283f7418cc8c342d9f91aabb428357715 - + https://github.com/dotnet/msbuild - 7ca3c98fad986066bbf2802c863236b4a0f4e34a + 4f6b1bb283f7418cc8c342d9f91aabb428357715 - + https://github.com/dotnet/msbuild - 7ca3c98fad986066bbf2802c863236b4a0f4e34a + 4f6b1bb283f7418cc8c342d9f91aabb428357715 diff --git a/eng/Versions.props b/eng/Versions.props index 104d4402cdcd..179af0be9e17 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -120,7 +120,7 @@ - 17.11.0-preview-24178-16 + 17.10.0 $(MicrosoftBuildPackageVersion) - 4.11.0-1.24179.14 - 4.11.0-1.24179.14 - 4.11.0-1.24179.14 - 4.11.0-1.24179.14 - 4.11.0-1.24179.14 - 4.11.0-1.24179.14 - 4.11.0-1.24179.14 + 4.11.0-1.24201.2 + 4.11.0-1.24201.2 + 4.11.0-1.24201.2 + 4.11.0-1.24201.2 + 4.11.0-1.24201.2 + 4.11.0-1.24201.2 + 4.11.0-1.24201.2 $(MicrosoftNetCompilersToolsetPackageVersion) From 1d839bbb7742ee177e0f8e169cb6a688292ac59a Mon Sep 17 00:00:00 2001 From: Marc Paine Date: Mon, 1 Apr 2024 15:28:14 -0700 Subject: [PATCH 506/577] Run update dependencies for barid 219952 --- eng/Version.Details.xml | 28 ++++++++++++++-------------- eng/Versions.props | 14 +++++++------- 2 files changed, 21 insertions(+), 21 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 0e4cd57fa2bd..9258656b2407 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -78,34 +78,34 @@ ac0d85557969d51bca72181514ddb7d5796fbbe2 - + https://github.com/dotnet/roslyn - 6e2ac12e4c38780953fc41afb848e80c728075e5 + 3d8fee7fc84f6488f053bdc9ab7717b6822a8166 - + https://github.com/dotnet/roslyn - 6e2ac12e4c38780953fc41afb848e80c728075e5 + 3d8fee7fc84f6488f053bdc9ab7717b6822a8166 - + https://github.com/dotnet/roslyn - 6e2ac12e4c38780953fc41afb848e80c728075e5 + 3d8fee7fc84f6488f053bdc9ab7717b6822a8166 - + https://github.com/dotnet/roslyn - 6e2ac12e4c38780953fc41afb848e80c728075e5 + 3d8fee7fc84f6488f053bdc9ab7717b6822a8166 - + https://github.com/dotnet/roslyn - 6e2ac12e4c38780953fc41afb848e80c728075e5 + 3d8fee7fc84f6488f053bdc9ab7717b6822a8166 - + https://github.com/dotnet/roslyn - 6e2ac12e4c38780953fc41afb848e80c728075e5 + 3d8fee7fc84f6488f053bdc9ab7717b6822a8166 - + https://github.com/dotnet/roslyn - 6e2ac12e4c38780953fc41afb848e80c728075e5 + 3d8fee7fc84f6488f053bdc9ab7717b6822a8166 https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore diff --git a/eng/Versions.props b/eng/Versions.props index 8a5a9457fa8e..1fa990b90fcd 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -154,13 +154,13 @@ - 4.11.0-1.24201.2 - 4.11.0-1.24201.2 - 4.11.0-1.24201.2 - 4.11.0-1.24201.2 - 4.11.0-1.24201.2 - 4.11.0-1.24201.2 - 4.11.0-1.24201.2 + 4.10.0-3.24179.15 + 4.10.0-3.24179.15 + 4.10.0-3.24179.15 + 4.10.0-3.24179.15 + 4.10.0-3.24179.15 + 4.10.0-3.24179.15 + 4.10.0-3.24179.15 $(MicrosoftNetCompilersToolsetPackageVersion) From 706599927aeff5d2c3b1e2d577f77780b7de619f Mon Sep 17 00:00:00 2001 From: Forgind <12969783+Forgind@users.noreply.github.com> Date: Mon, 1 Apr 2024 15:59:39 -0700 Subject: [PATCH 507/577] Various changes --- .../install/FileBasedInstaller.cs | 1 + .../install/LocalizableStrings.resx | 3 ++ .../install/NetSdkMsiInstallerClient.cs | 6 +++- .../install/WorkloadInstallCommand.cs | 9 +++++ .../install/xlf/LocalizableStrings.cs.xlf | 5 +++ .../install/xlf/LocalizableStrings.de.xlf | 5 +++ .../install/xlf/LocalizableStrings.es.xlf | 5 +++ .../install/xlf/LocalizableStrings.fr.xlf | 5 +++ .../install/xlf/LocalizableStrings.it.xlf | 5 +++ .../install/xlf/LocalizableStrings.ja.xlf | 5 +++ .../install/xlf/LocalizableStrings.ko.xlf | 5 +++ .../install/xlf/LocalizableStrings.pl.xlf | 5 +++ .../install/xlf/LocalizableStrings.pt-BR.xlf | 5 +++ .../install/xlf/LocalizableStrings.ru.xlf | 5 +++ .../install/xlf/LocalizableStrings.tr.xlf | 5 +++ .../xlf/LocalizableStrings.zh-Hans.xlf | 5 +++ .../xlf/LocalizableStrings.zh-Hant.xlf | 5 +++ .../IWorkloadManifestProvider.cs | 2 +- .../SdkDirectoryWorkloadManifestProvider.cs | 33 ++++++++++--------- .../TempDirectoryWorkloadManifestProvider.cs | 2 +- .../WorkloadResolver.cs | 2 +- .../FakeManifestProvider.cs | 4 +-- .../MockManifestProvider.cs | 2 +- 23 files changed, 107 insertions(+), 22 deletions(-) diff --git a/src/Cli/dotnet/commands/dotnet-workload/install/FileBasedInstaller.cs b/src/Cli/dotnet/commands/dotnet-workload/install/FileBasedInstaller.cs index 170dda6cccd4..6f65aabc795d 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/install/FileBasedInstaller.cs +++ b/src/Cli/dotnet/commands/dotnet-workload/install/FileBasedInstaller.cs @@ -514,6 +514,7 @@ public void UpdateInstallMode(SdkFeatureBand sdkFeatureBand, bool newMode) var installStateContents = InstallStateContents.FromPath(path); installStateContents.UseWorkloadSets = newMode; File.WriteAllText(path, installStateContents.ToString()); + _reporter.WriteLine(string.Format(LocalizableStrings.UpdatedWorkloadMode, newMode ? "workload sets" : "loose manifests")); } /// diff --git a/src/Cli/dotnet/commands/dotnet-workload/install/LocalizableStrings.resx b/src/Cli/dotnet/commands/dotnet-workload/install/LocalizableStrings.resx index 496dc7a1e7be..f0723e03765e 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/install/LocalizableStrings.resx +++ b/src/Cli/dotnet/commands/dotnet-workload/install/LocalizableStrings.resx @@ -358,4 +358,7 @@ Cannot specify a particular workload version on the command line via --version or --from-history when there is already a version specified in the global.json file. + + Successfully updated workload install mode to use {0}. + diff --git a/src/Cli/dotnet/commands/dotnet-workload/install/NetSdkMsiInstallerClient.cs b/src/Cli/dotnet/commands/dotnet-workload/install/NetSdkMsiInstallerClient.cs index 5e22f6bb329d..73b24e66f98e 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/install/NetSdkMsiInstallerClient.cs +++ b/src/Cli/dotnet/commands/dotnet-workload/install/NetSdkMsiInstallerClient.cs @@ -1081,6 +1081,10 @@ private void OnProcessExit(object sender, EventArgs e) } } - void IInstaller.UpdateInstallMode(SdkFeatureBand sdkFeatureBand, bool newMode) => UpdateInstallMode(sdkFeatureBand, newMode); + void IInstaller.UpdateInstallMode(SdkFeatureBand sdkFeatureBand, bool newMode) + { + UpdateInstallMode(sdkFeatureBand, newMode); + Reporter.WriteLine(string.Format(LocalizableStrings.UpdatedWorkloadMode, newMode ? "workload sets" : "loose manifests")); + } } } diff --git a/src/Cli/dotnet/commands/dotnet-workload/install/WorkloadInstallCommand.cs b/src/Cli/dotnet/commands/dotnet-workload/install/WorkloadInstallCommand.cs index 73ed6ea4a02d..741a2ce422fe 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/install/WorkloadInstallCommand.cs +++ b/src/Cli/dotnet/commands/dotnet-workload/install/WorkloadInstallCommand.cs @@ -128,6 +128,15 @@ public override int Execute() throw new Exception(string.Format(LocalizableStrings.CannotSpecifyVersionOnCommandLineAndInGlobalJson)); } } + else if (string.IsNullOrWhiteSpace(_workloadSetVersion)) + { + var installStateFilePath = Path.Combine(WorkloadInstallType.GetInstallStateFolder(_sdkFeatureBand, _dotnetPath), "default.json"); + if (File.Exists(installStateFilePath)) + { + var installStateContents = InstallStateContents.FromPath(installStateFilePath); + _workloadSetVersion = installStateContents.WorkloadVersion; + } + } try { diff --git a/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.cs.xlf b/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.cs.xlf index 658c56c0e07a..e0b35b429d89 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.cs.xlf +++ b/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.cs.xlf @@ -287,6 +287,11 @@ Vytiskne pouze seznam odkazů, které se mají stáhnout, aniž by se tento seznam stahoval. + + Successfully updated workload install mode to use {0}. + Successfully updated workload install mode to use {0}. + + Installing package {0} version {1} from offline cache {2}. Instaluje se balíček {0} verze {1} z offline mezipaměti {2}. diff --git a/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.de.xlf b/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.de.xlf index 38a75f0d51b8..9e753ef72ae3 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.de.xlf +++ b/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.de.xlf @@ -287,6 +287,11 @@ Drucken Sie nur die Liste der Links zum Herunterladen, ohne sie herunterzuladen. + + Successfully updated workload install mode to use {0}. + Successfully updated workload install mode to use {0}. + + Installing package {0} version {1} from offline cache {2}. Das Paket "{0}", Version {1}, aus dem Offlinecache "{2}" wird installiert. diff --git a/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.es.xlf b/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.es.xlf index b23b63cc963b..cfef2f68093c 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.es.xlf +++ b/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.es.xlf @@ -287,6 +287,11 @@ Imprima solo la lista de vínculos para descargar, sin descargarla. + + Successfully updated workload install mode to use {0}. + Successfully updated workload install mode to use {0}. + + Installing package {0} version {1} from offline cache {2}. Instalando el paquete {0}, versión {1} desde la caché sin conexión {2}. diff --git a/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.fr.xlf b/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.fr.xlf index 6dfef0eb9957..5434d15c0201 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.fr.xlf +++ b/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.fr.xlf @@ -287,6 +287,11 @@ Imprimer uniquement la liste des liens à télécharger sans télécharger. + + Successfully updated workload install mode to use {0}. + Successfully updated workload install mode to use {0}. + + Installing package {0} version {1} from offline cache {2}. Installation du {0} de {1} la version du package à partir du {2} de cache hors connexion. diff --git a/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.it.xlf b/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.it.xlf index 31779e922eb5..23f029de2410 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.it.xlf +++ b/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.it.xlf @@ -287,6 +287,11 @@ Stampa solo l'elenco dei collegamenti da scaricare senza scaricarlo. + + Successfully updated workload install mode to use {0}. + Successfully updated workload install mode to use {0}. + + Installing package {0} version {1} from offline cache {2}. Installazione del pacchetto {0}, versione {1}, dalla cache offline {2}. diff --git a/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.ja.xlf b/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.ja.xlf index 008eb7b47407..fb94130ad6ca 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.ja.xlf +++ b/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.ja.xlf @@ -287,6 +287,11 @@ ダウンロードするリンクの一覧をダウンロードせず、印刷だけを行います。 + + Successfully updated workload install mode to use {0}. + Successfully updated workload install mode to use {0}. + + Installing package {0} version {1} from offline cache {2}. オフライン キャッシュ {2} でパッケージ {0} のバージョン {1} をインストールしています。 diff --git a/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.ko.xlf b/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.ko.xlf index ea71690bb4bd..0edf0af0dcac 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.ko.xlf +++ b/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.ko.xlf @@ -287,6 +287,11 @@ 다운로드할 링크 목록을 다운로드하지 않고 인쇄만 합니다. + + Successfully updated workload install mode to use {0}. + Successfully updated workload install mode to use {0}. + + Installing package {0} version {1} from offline cache {2}. 오프라인 캐시 {2}에서 패키지 {0} 버전 {1}(을)를 설치하는 중입니다. diff --git a/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.pl.xlf b/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.pl.xlf index 5a0682d2a5cd..7a455e78c0b9 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.pl.xlf +++ b/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.pl.xlf @@ -287,6 +287,11 @@ Drukuj tylko listę linków do pobrania bez ich pobierania. + + Successfully updated workload install mode to use {0}. + Successfully updated workload install mode to use {0}. + + Installing package {0} version {1} from offline cache {2}. Instalowanie pakietu {0} w wersji {1} z pamięci podręcznej w trybie offline {2}. diff --git a/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.pt-BR.xlf b/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.pt-BR.xlf index d3a73961036e..f0b38439353c 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.pt-BR.xlf +++ b/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.pt-BR.xlf @@ -287,6 +287,11 @@ Somente imprimir a lista de links para download sem baixá-la. + + Successfully updated workload install mode to use {0}. + Successfully updated workload install mode to use {0}. + + Installing package {0} version {1} from offline cache {2}. Instalando o pacote {0} versão {1} do cache offline {2}. diff --git a/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.ru.xlf b/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.ru.xlf index 62356ca51a45..60927e55eef7 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.ru.xlf +++ b/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.ru.xlf @@ -287,6 +287,11 @@ Печатать только список ссылок для скачивания, не выполняя загрузку. + + Successfully updated workload install mode to use {0}. + Successfully updated workload install mode to use {0}. + + Installing package {0} version {1} from offline cache {2}. Установка пакета {0} версии {1} из автономного кэша {2}. diff --git a/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.tr.xlf b/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.tr.xlf index 55fe81630033..62b2294c0303 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.tr.xlf +++ b/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.tr.xlf @@ -287,6 +287,11 @@ İndirmeden, yalnızca indirilecek bağlantıların listesini yazdırın. + + Successfully updated workload install mode to use {0}. + Successfully updated workload install mode to use {0}. + + Installing package {0} version {1} from offline cache {2}. {0} paketi sürüm {1}, {2} çevrimdışı önbelleğinden yükleniyor. diff --git a/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.zh-Hans.xlf b/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.zh-Hans.xlf index dc293ac624df..1e32954ba2eb 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.zh-Hans.xlf +++ b/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.zh-Hans.xlf @@ -287,6 +287,11 @@ 仅打印要下载的链接的列表,而不下载列表。 + + Successfully updated workload install mode to use {0}. + Successfully updated workload install mode to use {0}. + + Installing package {0} version {1} from offline cache {2}. 正在从脱机缓存 {2} 安装程序包 {0} 版本 {1}。 diff --git a/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.zh-Hant.xlf b/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.zh-Hant.xlf index 0da7fda038d0..3d4413a58a1e 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.zh-Hant.xlf +++ b/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.zh-Hant.xlf @@ -287,6 +287,11 @@ 只列印要下載的連結清單,而不下載。 + + Successfully updated workload install mode to use {0}. + Successfully updated workload install mode to use {0}. + + Installing package {0} version {1} from offline cache {2}. 正在從離線快取 {2} 安裝套件 {0} 版本 {1}。 diff --git a/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/IWorkloadManifestProvider.cs b/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/IWorkloadManifestProvider.cs index f6a5e9676624..78c7ea97bc96 100644 --- a/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/IWorkloadManifestProvider.cs +++ b/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/IWorkloadManifestProvider.cs @@ -9,7 +9,7 @@ namespace Microsoft.NET.Sdk.WorkloadManifestReader /// public interface IWorkloadManifestProvider { - void RefreshWorkloadManifests(); + void RefreshWorkloadManifests(bool error = false); IEnumerable GetManifests(); string GetSdkFeatureBand(); diff --git a/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/SdkDirectoryWorkloadManifestProvider.cs b/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/SdkDirectoryWorkloadManifestProvider.cs index eeefd7dee1c7..d204cf9ec673 100644 --- a/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/SdkDirectoryWorkloadManifestProvider.cs +++ b/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/SdkDirectoryWorkloadManifestProvider.cs @@ -105,43 +105,46 @@ internal SdkDirectoryWorkloadManifestProvider(string sdkRootPath, string sdkVers RefreshWorkloadManifests(); } - public void RefreshWorkloadManifests() + public void RefreshWorkloadManifests(bool error = false) { + _workloadSet = null; var availableWorkloadSets = GetAvailableWorkloadSets(); if (_workloadSetVersionFromConstructor != null) { - if (!availableWorkloadSets.TryGetValue(_workloadSetVersionFromConstructor, out _workloadSet)) + if (!availableWorkloadSets.TryGetValue(_workloadSetVersionFromConstructor, out _workloadSet) && error) { throw new FileNotFoundException(string.Format(Strings.WorkloadVersionNotFound, _workloadSetVersionFromConstructor)); } } - else + + if (_workloadSet is null) { string? globalJsonWorkloadSetVersion = GlobalJsonReader.GetWorkloadVersionFromGlobalJson(_globalJsonPathFromConstructor); if (globalJsonWorkloadSetVersion != null) { - if (!availableWorkloadSets.TryGetValue(globalJsonWorkloadSetVersion, out _workloadSet)) + if (!availableWorkloadSets.TryGetValue(globalJsonWorkloadSetVersion, out _workloadSet) && error) { throw new FileNotFoundException(string.Format(Strings.WorkloadVersionFromGlobalJsonNotFound, globalJsonWorkloadSetVersion, _globalJsonPathFromConstructor)); } } - else + } + + if (_workloadSet is null) + { + var installStateFilePath = Path.Combine(WorkloadInstallType.GetInstallStateFolder(_sdkVersionBand, _sdkRootPath), "default.json"); + if (File.Exists(installStateFilePath)) { - var installStateFilePath = Path.Combine(WorkloadInstallType.GetInstallStateFolder(_sdkVersionBand, _sdkRootPath), "default.json"); - if (File.Exists(installStateFilePath)) + var installState = InstallStateContents.FromPath(installStateFilePath); + if (!string.IsNullOrEmpty(installState.WorkloadVersion)) { - var installState = InstallStateContents.FromPath(installStateFilePath); - if (!string.IsNullOrEmpty(installState.WorkloadVersion)) + if (!availableWorkloadSets.TryGetValue(installState.WorkloadVersion!, out _workloadSet) && error) { - if (!availableWorkloadSets.TryGetValue(installState.WorkloadVersion!, out _workloadSet)) - { - throw new FileNotFoundException(string.Format(Strings.WorkloadVersionFromInstallStateNotFound, installState.WorkloadVersion, installStateFilePath)); - } + throw new FileNotFoundException(string.Format(Strings.WorkloadVersionFromInstallStateNotFound, installState.WorkloadVersion, installStateFilePath)); } - _manifestsFromInstallState = installState.Manifests is null ? new WorkloadSet() : WorkloadSet.FromDictionaryForJson(installState.Manifests, _sdkVersionBand); - _installStateFilePath = installStateFilePath; } + _manifestsFromInstallState = installState.Manifests is null ? null : WorkloadSet.FromDictionaryForJson(installState.Manifests, _sdkVersionBand); + _installStateFilePath = installStateFilePath; } } diff --git a/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/TempDirectoryWorkloadManifestProvider.cs b/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/TempDirectoryWorkloadManifestProvider.cs index a764fb2d9fb5..79e09b85b887 100644 --- a/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/TempDirectoryWorkloadManifestProvider.cs +++ b/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/TempDirectoryWorkloadManifestProvider.cs @@ -14,7 +14,7 @@ public TempDirectoryWorkloadManifestProvider(string manifestsPath, string sdkFea _sdkVersionBand = sdkFeatureBand; } - public void RefreshWorkloadManifests() { } + public void RefreshWorkloadManifests(bool error = false) { } public IEnumerable GetManifests() diff --git a/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/WorkloadResolver.cs b/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/WorkloadResolver.cs index 81fdae3f4c2d..ae4413f23ef8 100644 --- a/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/WorkloadResolver.cs +++ b/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/WorkloadResolver.cs @@ -739,7 +739,7 @@ public EmptyWorkloadManifestProvider(string sdkFeatureBand) _sdkFeatureBand = sdkFeatureBand; } - public void RefreshWorkloadManifests() { } + public void RefreshWorkloadManifests(bool error = false) { } public Dictionary GetAvailableWorkloadSets() => new(); public IEnumerable GetManifests() => Enumerable.Empty(); public string GetSdkFeatureBand() => _sdkFeatureBand; diff --git a/src/Tests/Microsoft.NET.Sdk.WorkloadManifestReader.Tests/FakeManifestProvider.cs b/src/Tests/Microsoft.NET.Sdk.WorkloadManifestReader.Tests/FakeManifestProvider.cs index 7c8fa003a368..d05add9219af 100644 --- a/src/Tests/Microsoft.NET.Sdk.WorkloadManifestReader.Tests/FakeManifestProvider.cs +++ b/src/Tests/Microsoft.NET.Sdk.WorkloadManifestReader.Tests/FakeManifestProvider.cs @@ -20,7 +20,7 @@ public FakeManifestProvider(params (string manifest, string? localizationCatalog _filePaths = filePaths; } - public void RefreshWorkloadManifests() { } + public void RefreshWorkloadManifests(bool error = false) { } public IEnumerable GetManifests() { @@ -49,7 +49,7 @@ internal class InMemoryFakeManifestProvider : IWorkloadManifestProvider, IEnumer public void Add(string id, string content) => _manifests.Add((id, Encoding.UTF8.GetBytes(content))); - public void RefreshWorkloadManifests() { } + public void RefreshWorkloadManifests(bool error = false) { } public IEnumerable GetManifests() => _manifests.Select(m => new ReadableWorkloadManifest( diff --git a/src/Tests/dotnet-workload-install.Tests/MockManifestProvider.cs b/src/Tests/dotnet-workload-install.Tests/MockManifestProvider.cs index 935fb9addfe8..cbae092ee31d 100644 --- a/src/Tests/dotnet-workload-install.Tests/MockManifestProvider.cs +++ b/src/Tests/dotnet-workload-install.Tests/MockManifestProvider.cs @@ -29,7 +29,7 @@ public MockManifestProvider(params (string name, string path, string featureBand public Dictionary GetAvailableWorkloadSets() => new(); - public void RefreshWorkloadManifests() { } + public void RefreshWorkloadManifests(bool error = false) { } public IEnumerable GetManifests() { From e077e981e1ff1da6f7fc34337a7f2001547a639b Mon Sep 17 00:00:00 2001 From: Chet Husk Date: Tue, 2 Apr 2024 12:10:15 -0500 Subject: [PATCH 508/577] update warning message for containers package inclusion --- .../Microsoft.NET.Build.Containers.targets | 23 ++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/src/Containers/packaging/build/Microsoft.NET.Build.Containers.targets b/src/Containers/packaging/build/Microsoft.NET.Build.Containers.targets index f2c3397aaabd..ed96d1154c4b 100644 --- a/src/Containers/packaging/build/Microsoft.NET.Build.Containers.targets +++ b/src/Containers/packaging/build/Microsoft.NET.Build.Containers.targets @@ -195,12 +195,29 @@ - Microsoft.NET.Build.Containers + <_ContainersPackageIdentity>Microsoft.NET.Build.Containers + <_WebDefaultSdkVersion>7.0.300 + <_WorkerDefaultSdkVersion>8.0.100 + <_ConsoleDefaultSdkVersion>8.0.200 + <_SdkCanPublishWeb Condition="$([MSBuild]::VersionGreaterThanOrEquals('$(NETCoreSdkVersion)', '$(_WebDefaultSdkVersion)'))" >true + <_SdkCanPublishWorker Condition="$([MSBuild]::VersionGreaterThanOrEquals('$(NETCoreSdkVersion)', '$(_WorkerDefaultSdkVersion)'))">true + <_SdkCanPublishConsole Condition="$([MSBuild]::VersionGreaterThanOrEquals('$(NETCoreSdkVersion)', '$(_ConsoleDefaultSdkVersion)'))">true - + <_ContainersPackage Include="@(PackageReference)" Condition="'%(Identity)' == '$(ContainersPackageIdentity)'"/> + <_WebCapability Include="@(ProjectCapability)" Condition="'%(Identity)' == 'DotNetCoreWeb'" /> + <_WorkerCapability Include="@(ProjectCapability)" Condition="'%(Identity)' == 'DotNetCoreWorker'" /> - + + + true From abed0303e3498a573f9266a97d74da9034829bf2 Mon Sep 17 00:00:00 2001 From: Chet Husk Date: Tue, 2 Apr 2024 14:47:52 -0500 Subject: [PATCH 509/577] more comprehensive and targeted message --- .../Microsoft.NET.Build.Containers.targets | 27 ++++++++++++------- 1 file changed, 18 insertions(+), 9 deletions(-) diff --git a/src/Containers/packaging/build/Microsoft.NET.Build.Containers.targets b/src/Containers/packaging/build/Microsoft.NET.Build.Containers.targets index ed96d1154c4b..2e54b7067a25 100644 --- a/src/Containers/packaging/build/Microsoft.NET.Build.Containers.targets +++ b/src/Containers/packaging/build/Microsoft.NET.Build.Containers.targets @@ -199,24 +199,33 @@ <_WebDefaultSdkVersion>7.0.300 <_WorkerDefaultSdkVersion>8.0.100 <_ConsoleDefaultSdkVersion>8.0.200 - <_SdkCanPublishWeb Condition="$([MSBuild]::VersionGreaterThanOrEquals('$(NETCoreSdkVersion)', '$(_WebDefaultSdkVersion)'))" >true - <_SdkCanPublishWorker Condition="$([MSBuild]::VersionGreaterThanOrEquals('$(NETCoreSdkVersion)', '$(_WorkerDefaultSdkVersion)'))">true - <_SdkCanPublishConsole Condition="$([MSBuild]::VersionGreaterThanOrEquals('$(NETCoreSdkVersion)', '$(_ConsoleDefaultSdkVersion)'))">true + <_SdkCanPublishWeb>$([MSBuild]::VersionGreaterThanOrEquals('$(NETCoreSdkVersion)', '$(_WebDefaultSdkVersion)')) + <_SdkCanPublishWorker>$([MSBuild]::VersionGreaterThanOrEquals('$(NETCoreSdkVersion)', '$(_WorkerDefaultSdkVersion)')) + <_SdkCanPublishConsole>$([MSBuild]::VersionGreaterThanOrEquals('$(NETCoreSdkVersion)', '$(_ConsoleDefaultSdkVersion)')) - <_ContainersPackage Include="@(PackageReference)" Condition="'%(Identity)' == '$(ContainersPackageIdentity)'"/> + <_ContainersPackage Include="@(PackageReference)" Condition="'%(Identity)' == '$(_ContainersPackageIdentity)'"/> <_WebCapability Include="@(ProjectCapability)" Condition="'%(Identity)' == 'DotNetCoreWeb'" /> <_WorkerCapability Include="@(ProjectCapability)" Condition="'%(Identity)' == 'DotNetCoreWorker'" /> + + <_ContainerPackageIsPresent>false + <_ContainerPackageIsPresent Condition="'@(_ContainersPackage)' != ''">true + <_IsWebProject>false + <_IsWebProject Condition="'@(_WebCapability)' != ''">true + <_IsWorkerProject>false + <_IsWorkerProject Condition="'@(_WorkerCapability)' != ''">true + + + Text="The Microsoft.NET.Build.Containers NuGet package is explicitly referenced but the current SDK can natively publish the project as a container. Consider removing the package reference to Microsoft.NET.Build.Containers as it no longer needed." /> true From b7a0a09070a160b172442f0107442fc7bd0ad5a7 Mon Sep 17 00:00:00 2001 From: Chet Husk Date: Tue, 2 Apr 2024 15:51:48 -0500 Subject: [PATCH 510/577] Update src/Containers/packaging/build/Microsoft.NET.Build.Containers.targets Co-authored-by: Rainer Sigwald --- .../packaging/build/Microsoft.NET.Build.Containers.targets | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Containers/packaging/build/Microsoft.NET.Build.Containers.targets b/src/Containers/packaging/build/Microsoft.NET.Build.Containers.targets index 2e54b7067a25..7f1b31391544 100644 --- a/src/Containers/packaging/build/Microsoft.NET.Build.Containers.targets +++ b/src/Containers/packaging/build/Microsoft.NET.Build.Containers.targets @@ -211,7 +211,7 @@ <_ContainerPackageIsPresent>false - <_ContainerPackageIsPresent Condition="'@(_ContainersPackage)' != ''">true + <_ContainerPackageIsPresent Condition="'@(PackageReference->AnyHaveMetadataValue('Identity', '$(_ContainersPackageIdentity)')) != ''">true <_IsWebProject>false <_IsWebProject Condition="'@(_WebCapability)' != ''">true <_IsWorkerProject>false From 708a46021bef8af05e58929d55e5f6e1f4daf77c Mon Sep 17 00:00:00 2001 From: Chet Husk Date: Tue, 2 Apr 2024 15:53:50 -0500 Subject: [PATCH 511/577] Update src/Containers/packaging/build/Microsoft.NET.Build.Containers.targets Co-authored-by: Rainer Sigwald --- .../packaging/build/Microsoft.NET.Build.Containers.targets | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Containers/packaging/build/Microsoft.NET.Build.Containers.targets b/src/Containers/packaging/build/Microsoft.NET.Build.Containers.targets index 7f1b31391544..37ce7a136874 100644 --- a/src/Containers/packaging/build/Microsoft.NET.Build.Containers.targets +++ b/src/Containers/packaging/build/Microsoft.NET.Build.Containers.targets @@ -211,7 +211,7 @@ <_ContainerPackageIsPresent>false - <_ContainerPackageIsPresent Condition="'@(PackageReference->AnyHaveMetadataValue('Identity', '$(_ContainersPackageIdentity)')) != ''">true + <_ContainerPackageIsPresent Condition="'@(PackageReference->AnyHaveMetadataValue('Identity', '$(_ContainersPackageIdentity)'))">true <_IsWebProject>false <_IsWebProject Condition="'@(_WebCapability)' != ''">true <_IsWorkerProject>false From 4d6c540370c9b72e84a5061aa4e9f2d281a93981 Mon Sep 17 00:00:00 2001 From: Chet Husk Date: Tue, 2 Apr 2024 16:12:06 -0500 Subject: [PATCH 512/577] fix grammar --- .../packaging/build/Microsoft.NET.Build.Containers.targets | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Containers/packaging/build/Microsoft.NET.Build.Containers.targets b/src/Containers/packaging/build/Microsoft.NET.Build.Containers.targets index 37ce7a136874..a59f06decf48 100644 --- a/src/Containers/packaging/build/Microsoft.NET.Build.Containers.targets +++ b/src/Containers/packaging/build/Microsoft.NET.Build.Containers.targets @@ -211,7 +211,7 @@ <_ContainerPackageIsPresent>false - <_ContainerPackageIsPresent Condition="'@(PackageReference->AnyHaveMetadataValue('Identity', '$(_ContainersPackageIdentity)'))">true + <_ContainerPackageIsPresent Condition="@(PackageReference->AnyHaveMetadataValue('Identity', '$(_ContainersPackageIdentity)'))">true <_IsWebProject>false <_IsWebProject Condition="'@(_WebCapability)' != ''">true <_IsWorkerProject>false From 8d26bd442c5b93d097e94790d4206d0fd8221313 Mon Sep 17 00:00:00 2001 From: Chet Husk Date: Tue, 2 Apr 2024 18:54:57 -0500 Subject: [PATCH 513/577] simplify the MSBuild logic greatly --- .../Microsoft.NET.Build.Containers.targets | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/src/Containers/packaging/build/Microsoft.NET.Build.Containers.targets b/src/Containers/packaging/build/Microsoft.NET.Build.Containers.targets index a59f06decf48..ce3b261af52c 100644 --- a/src/Containers/packaging/build/Microsoft.NET.Build.Containers.targets +++ b/src/Containers/packaging/build/Microsoft.NET.Build.Containers.targets @@ -195,27 +195,24 @@ + <_ContainersPackageIdentity>Microsoft.NET.Build.Containers <_WebDefaultSdkVersion>7.0.300 <_WorkerDefaultSdkVersion>8.0.100 <_ConsoleDefaultSdkVersion>8.0.200 + + <_SdkCanPublishWeb>$([MSBuild]::VersionGreaterThanOrEquals('$(NETCoreSdkVersion)', '$(_WebDefaultSdkVersion)')) <_SdkCanPublishWorker>$([MSBuild]::VersionGreaterThanOrEquals('$(NETCoreSdkVersion)', '$(_WorkerDefaultSdkVersion)')) <_SdkCanPublishConsole>$([MSBuild]::VersionGreaterThanOrEquals('$(NETCoreSdkVersion)', '$(_ConsoleDefaultSdkVersion)')) - - - <_ContainersPackage Include="@(PackageReference)" Condition="'%(Identity)' == '$(_ContainersPackageIdentity)'"/> - <_WebCapability Include="@(ProjectCapability)" Condition="'%(Identity)' == 'DotNetCoreWeb'" /> - <_WorkerCapability Include="@(ProjectCapability)" Condition="'%(Identity)' == 'DotNetCoreWorker'" /> - - + <_ContainerPackageIsPresent>false <_ContainerPackageIsPresent Condition="@(PackageReference->AnyHaveMetadataValue('Identity', '$(_ContainersPackageIdentity)'))">true <_IsWebProject>false - <_IsWebProject Condition="'@(_WebCapability)' != ''">true + <_IsWebProject Condition="@(ProjectCapability->AnyHaveMetadataValue('Identity', 'DotNetCoreWeb'))">true <_IsWorkerProject>false - <_IsWorkerProject Condition="'@(_WorkerCapability)' != ''">true + <_IsWorkerProject Condition="@(ProjectCapability->AnyHaveMetadataValue('Identity', 'DotNetCoreWorker'))">true + Text="The $(_ContainersPackageIdentity) NuGet package is explicitly referenced but the current SDK can natively publish the project as a container. Consider removing the package reference to $(_ContainersPackageIdentity) as it no longer needed." /> true From 9fd8326033a5718695df1c3cf05e6228b8b86ebe Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" Date: Wed, 3 Apr 2024 12:58:35 +0000 Subject: [PATCH 514/577] Update dependencies from https://github.com/dotnet/roslyn build 20240402.15 Microsoft.CodeAnalysis , Microsoft.CodeAnalysis.CSharp , Microsoft.CodeAnalysis.CSharp.CodeStyle , Microsoft.CodeAnalysis.CSharp.Features , Microsoft.CodeAnalysis.CSharp.Workspaces , Microsoft.CodeAnalysis.Workspaces.MSBuild , Microsoft.Net.Compilers.Toolset From Version 4.10.0-3.24179.15 -> To Version 4.10.0-3.24202.15 --- eng/Version.Details.xml | 28 ++++++++++++++-------------- eng/Versions.props | 14 +++++++------- 2 files changed, 21 insertions(+), 21 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 2ee9a9d6e936..124887fd8cd1 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -78,34 +78,34 @@ ac0d85557969d51bca72181514ddb7d5796fbbe2 - + https://github.com/dotnet/roslyn - 3d8fee7fc84f6488f053bdc9ab7717b6822a8166 + cbca41cad4e21c29548e9e57d7135740b6f78df9 - + https://github.com/dotnet/roslyn - 3d8fee7fc84f6488f053bdc9ab7717b6822a8166 + cbca41cad4e21c29548e9e57d7135740b6f78df9 - + https://github.com/dotnet/roslyn - 3d8fee7fc84f6488f053bdc9ab7717b6822a8166 + cbca41cad4e21c29548e9e57d7135740b6f78df9 - + https://github.com/dotnet/roslyn - 3d8fee7fc84f6488f053bdc9ab7717b6822a8166 + cbca41cad4e21c29548e9e57d7135740b6f78df9 - + https://github.com/dotnet/roslyn - 3d8fee7fc84f6488f053bdc9ab7717b6822a8166 + cbca41cad4e21c29548e9e57d7135740b6f78df9 - + https://github.com/dotnet/roslyn - 3d8fee7fc84f6488f053bdc9ab7717b6822a8166 + cbca41cad4e21c29548e9e57d7135740b6f78df9 - + https://github.com/dotnet/roslyn - 3d8fee7fc84f6488f053bdc9ab7717b6822a8166 + cbca41cad4e21c29548e9e57d7135740b6f78df9 https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore diff --git a/eng/Versions.props b/eng/Versions.props index 73ee3bf058bb..a2e54456fd8e 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -154,13 +154,13 @@ - 4.10.0-3.24179.15 - 4.10.0-3.24179.15 - 4.10.0-3.24179.15 - 4.10.0-3.24179.15 - 4.10.0-3.24179.15 - 4.10.0-3.24179.15 - 4.10.0-3.24179.15 + 4.10.0-3.24202.15 + 4.10.0-3.24202.15 + 4.10.0-3.24202.15 + 4.10.0-3.24202.15 + 4.10.0-3.24202.15 + 4.10.0-3.24202.15 + 4.10.0-3.24202.15 $(MicrosoftNetCompilersToolsetPackageVersion) From 82f070036d6852b024d0217562e4f40586b0a4c3 Mon Sep 17 00:00:00 2001 From: Chet Husk Date: Wed, 3 Apr 2024 09:10:40 -0500 Subject: [PATCH 515/577] fix the test expectation --- .../packaging/build/Microsoft.NET.Build.Containers.targets | 2 +- .../EndToEndTests.cs | 2 +- 2 files changed, 2 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 ce3b261af52c..ebafd8df55d0 100644 --- a/src/Containers/packaging/build/Microsoft.NET.Build.Containers.targets +++ b/src/Containers/packaging/build/Microsoft.NET.Build.Containers.targets @@ -222,7 +222,7 @@ ($(_SdkCanPublishWorker) and $(_IsWorkerProject)) or ($(_SdkCanPublishConsole) and '$(EnableSdkContainerSupport)' == 'true') )" - Text="The $(_ContainersPackageIdentity) NuGet package is explicitly referenced but the current SDK can natively publish the project as a container. Consider removing the package reference to $(_ContainersPackageIdentity) as it no longer needed." /> + Text="The $(_ContainersPackageIdentity) NuGet package is explicitly referenced but the current SDK can natively publish the project as a container. Consider removing the package reference to $(_ContainersPackageIdentity) because it is no longer needed." /> true diff --git a/src/Tests/Microsoft.NET.Build.Containers.IntegrationTests/EndToEndTests.cs b/src/Tests/Microsoft.NET.Build.Containers.IntegrationTests/EndToEndTests.cs index 24c4f202d07d..44fb455f0453 100644 --- a/src/Tests/Microsoft.NET.Build.Containers.IntegrationTests/EndToEndTests.cs +++ b/src/Tests/Microsoft.NET.Build.Containers.IntegrationTests/EndToEndTests.cs @@ -369,7 +369,7 @@ public async Task EndToEnd_NoAPI_ProjectType(string projectType, bool addPackage if (addPackageReference) { - commandResult.Should().HaveStdOutContaining("warning : Microsoft.NET.Build.Containers NuGet package is explicitly referenced. Consider removing the package reference to Microsoft.NET.Build.Containers as it is now part of .NET SDK."); + commandResult.Should().HaveStdOutContaining("warning : The Microsoft.NET.Build.Containers NuGet package is explicitly referenced but the current SDK can natively publish the project as a container. Consider removing the package reference to Microsoft.NET.Build.Containers because it is no longer needed."); } else { From e216d3314de398268a14600c7408ac1c41589567 Mon Sep 17 00:00:00 2001 From: Forgind <12969783+Forgind@users.noreply.github.com> Date: Wed, 3 Apr 2024 14:44:50 -0700 Subject: [PATCH 516/577] Also reset install state manifests --- .../SdkDirectoryWorkloadManifestProvider.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/SdkDirectoryWorkloadManifestProvider.cs b/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/SdkDirectoryWorkloadManifestProvider.cs index d204cf9ec673..b55ab12badb5 100644 --- a/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/SdkDirectoryWorkloadManifestProvider.cs +++ b/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/SdkDirectoryWorkloadManifestProvider.cs @@ -108,6 +108,8 @@ internal SdkDirectoryWorkloadManifestProvider(string sdkRootPath, string sdkVers public void RefreshWorkloadManifests(bool error = false) { _workloadSet = null; + _manifestsFromInstallState = null; + _installStateFilePath = null; var availableWorkloadSets = GetAvailableWorkloadSets(); if (_workloadSetVersionFromConstructor != null) From e656c662ea8d01f958223c2b1c9eb802025fbcbb Mon Sep 17 00:00:00 2001 From: Forgind <12969783+Forgind@users.noreply.github.com> Date: Wed, 3 Apr 2024 14:47:08 -0700 Subject: [PATCH 517/577] Remove tests --- ...kDirectoryWorkloadManifestProviderTests.cs | 64 ------------------- 1 file changed, 64 deletions(-) diff --git a/src/Tests/Microsoft.NET.Sdk.WorkloadManifestReader.Tests/SdkDirectoryWorkloadManifestProviderTests.cs b/src/Tests/Microsoft.NET.Sdk.WorkloadManifestReader.Tests/SdkDirectoryWorkloadManifestProviderTests.cs index 44bf3f961184..dee5914b1304 100644 --- a/src/Tests/Microsoft.NET.Sdk.WorkloadManifestReader.Tests/SdkDirectoryWorkloadManifestProviderTests.cs +++ b/src/Tests/Microsoft.NET.Sdk.WorkloadManifestReader.Tests/SdkDirectoryWorkloadManifestProviderTests.cs @@ -526,36 +526,6 @@ var sdkDirectoryWorkloadManifestProvider .BeEquivalentTo("ios: 11.0.2/8.0.100"); } - [Fact] - public void ItFailsIfWorkloadSetFromGlobalJsonIsNotInstalled() - { - Initialize("8.0.200"); - - string? globalJsonPath = Path.Combine(_testDirectory, "global.json"); - File.WriteAllText(globalJsonPath, """ - { - "sdk": { - "version": "8.0.200", - "workloadVersion": "8.0.201" - }, - "msbuild-sdks": { - "Microsoft.DotNet.Arcade.Sdk": "7.0.0-beta.23254.2", - } - } - """); - - CreateMockManifest(_manifestRoot, "8.0.200", "ios", "12.0.1", true); - - CreateMockWorkloadSet(_manifestRoot, "8.0.200", "8.0.202", """ -{ - "ios": "12.0.1/8.0.200" -} -"""); - - var ex = Assert.Throws(() => new SdkDirectoryWorkloadManifestProvider(sdkRootPath: _fakeDotnetRootDirectory, sdkVersion: "8.0.200", userProfileDir: null, globalJsonPath: globalJsonPath)); - ex.Message.Should().Be(string.Format(Strings.WorkloadVersionFromGlobalJsonNotFound, "8.0.201", globalJsonPath)); - } - [Fact] public void ItFailsIfGlobalJsonIsMalformed() { @@ -618,40 +588,6 @@ var sdkDirectoryWorkloadManifestProvider .BeEquivalentTo("ios: 11.0.2/8.0.100"); } - [Fact] - public void ItFailsIfWorkloadSetFromInstallStateIsNotInstalled() - { - Initialize("8.0.200"); - - CreateMockManifest(_manifestRoot, "8.0.100", "ios", "11.0.1", true); - CreateMockManifest(_manifestRoot, "8.0.100", "ios", "11.0.2", true); - CreateMockManifest(_manifestRoot, "8.0.200", "ios", "12.0.1", true); - - CreateMockWorkloadSet(_manifestRoot, "8.0.200", "8.0.201", """ -{ - "ios": "11.0.2/8.0.100" -} -"""); - - CreateMockWorkloadSet(_manifestRoot, "8.0.200", "8.0.202", """ -{ - "ios": "12.0.1/8.0.200" -} -"""); - var installStatePath = CreateMockInstallState("8.0.200", - """ - { - "workloadVersion": "8.0.203" - } - """); - - - var ex = Assert.Throws( - () => new SdkDirectoryWorkloadManifestProvider(sdkRootPath: _fakeDotnetRootDirectory, sdkVersion: "8.0.200", userProfileDir: null, globalJsonPath: null)); - - ex.Message.Should().Be(string.Format(Strings.WorkloadVersionFromInstallStateNotFound, "8.0.203", installStatePath)); - } - [Fact] public void ItFailsIfManifestFromWorkloadSetFromInstallStateIsNotInstalled() { From 2939733013845b26a1d75b5326601037456fe1a3 Mon Sep 17 00:00:00 2001 From: Forgind <12969783+Forgind@users.noreply.github.com> Date: Wed, 3 Apr 2024 16:42:04 -0700 Subject: [PATCH 518/577] Fix directory --- .../commands/dotnet-workload/install/WorkloadInstallCommand.cs | 2 +- .../commands/dotnet-workload/update/WorkloadUpdateCommand.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Cli/dotnet/commands/dotnet-workload/install/WorkloadInstallCommand.cs b/src/Cli/dotnet/commands/dotnet-workload/install/WorkloadInstallCommand.cs index 741a2ce422fe..7a6e281088f9 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/install/WorkloadInstallCommand.cs +++ b/src/Cli/dotnet/commands/dotnet-workload/install/WorkloadInstallCommand.cs @@ -115,7 +115,7 @@ public override int Execute() } else { - var globaljsonPath = SdkDirectoryWorkloadManifestProvider.GetGlobalJsonPath(_userProfileDir); + var globaljsonPath = SdkDirectoryWorkloadManifestProvider.GetGlobalJsonPath(Environment.CurrentDirectory); var workloadVersion = SdkDirectoryWorkloadManifestProvider.GlobalJsonReader.GetWorkloadVersionFromGlobalJson(globaljsonPath); if (workloadVersion is not null) { diff --git a/src/Cli/dotnet/commands/dotnet-workload/update/WorkloadUpdateCommand.cs b/src/Cli/dotnet/commands/dotnet-workload/update/WorkloadUpdateCommand.cs index 92820e5260da..2552f3d13296 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/update/WorkloadUpdateCommand.cs +++ b/src/Cli/dotnet/commands/dotnet-workload/update/WorkloadUpdateCommand.cs @@ -110,7 +110,7 @@ public override int Execute() } else { - var globaljsonPath = SdkDirectoryWorkloadManifestProvider.GetGlobalJsonPath(_userProfileDir); + var globaljsonPath = SdkDirectoryWorkloadManifestProvider.GetGlobalJsonPath(Environment.CurrentDirectory); var workloadVersion = SdkDirectoryWorkloadManifestProvider.GlobalJsonReader.GetWorkloadVersionFromGlobalJson(globaljsonPath); if (workloadVersion is not null) { From 7ecfc8a565ec251f286301a22b9fa2bc7f549b2c Mon Sep 17 00:00:00 2001 From: Daniel Plaisted Date: Wed, 3 Apr 2024 23:42:47 -0400 Subject: [PATCH 519/577] Code review feedback and cleanup --- .../config/WorkloadConfigCommand.cs | 13 ++++++------ .../config/WorkloadConfigCommandParser.cs | 1 - .../WorkloadSetTests.cs | 20 ------------------- 3 files changed, 7 insertions(+), 27 deletions(-) diff --git a/src/Cli/dotnet/commands/dotnet-workload/config/WorkloadConfigCommand.cs b/src/Cli/dotnet/commands/dotnet-workload/config/WorkloadConfigCommand.cs index 0329b3770bca..1923511703e8 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/config/WorkloadConfigCommand.cs +++ b/src/Cli/dotnet/commands/dotnet-workload/config/WorkloadConfigCommand.cs @@ -20,9 +20,9 @@ namespace Microsoft.DotNet.Workloads.Workload.Config { internal class WorkloadConfigCommand : WorkloadCommandBase { - bool _hasUpdateMode; - string? _updateMode; - readonly IWorkloadResolverFactory _workloadResolverFactory; + private bool _hasUpdateMode; + private string? _updateMode; + private readonly IWorkloadResolverFactory _workloadResolverFactory; private string? _dotnetPath; private string _userProfileDir; @@ -38,7 +38,6 @@ public WorkloadConfigCommand( IWorkloadResolverFactory? workloadResolverFactory = null ) : base(parseResult, CommonOptions.HiddenVerbosityOption, reporter) { - // TODO: Is it possible to check the order of the options? This would allow us to print the values out in the same order they are specified on the command line _hasUpdateMode = parseResult.HasOption(WorkloadConfigCommandParser.UpdateMode); _updateMode = parseResult.GetValue(WorkloadConfigCommandParser.UpdateMode); @@ -57,13 +56,15 @@ public WorkloadConfigCommand( public override int Execute() { + // When we support multiple configuration values, it would be nice if we could process and display them in the order they are passed. + // It seems that the parser doesn't give us a good way to do that, however if (_hasUpdateMode) { - if (_updateMode == WorkloadConfigCommandParser.UpdateMode_WorkloadSet) + if (WorkloadConfigCommandParser.UpdateMode_WorkloadSet.Equals(_updateMode, StringComparison.InvariantCultureIgnoreCase)) { _workloadInstaller.UpdateInstallMode(_sdkFeatureBand, true); } - else if (_updateMode == WorkloadConfigCommandParser.UpdateMode_Manifests) + else if (WorkloadConfigCommandParser.UpdateMode_Manifests.Equals(_updateMode, StringComparison.InvariantCultureIgnoreCase)) { _workloadInstaller.UpdateInstallMode(_sdkFeatureBand, false); } diff --git a/src/Cli/dotnet/commands/dotnet-workload/config/WorkloadConfigCommandParser.cs b/src/Cli/dotnet/commands/dotnet-workload/config/WorkloadConfigCommandParser.cs index ee1a96ba73a5..22114beef478 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/config/WorkloadConfigCommandParser.cs +++ b/src/Cli/dotnet/commands/dotnet-workload/config/WorkloadConfigCommandParser.cs @@ -16,7 +16,6 @@ internal static class WorkloadConfigCommandParser public static readonly CliOption UpdateMode = new("--update-mode") { Description = LocalizableStrings.UpdateModeDescription, - //Hidden = true, Arity = ArgumentArity.ZeroOrOne }; diff --git a/src/Tests/dotnet-MsiInstallation.Tests/WorkloadSetTests.cs b/src/Tests/dotnet-MsiInstallation.Tests/WorkloadSetTests.cs index 926688a175c8..2718d39cedc1 100644 --- a/src/Tests/dotnet-MsiInstallation.Tests/WorkloadSetTests.cs +++ b/src/Tests/dotnet-MsiInstallation.Tests/WorkloadSetTests.cs @@ -17,26 +17,6 @@ public WorkloadSetTests(ITestOutputHelper log) : base(log) { } - // dotnet nuget add source c:\SdkTesting\WorkloadSets - // dotnet workload update --mode workloadset - - // Show workload mode in dotnet workload --info - - - // dotnet workload update-mode set workload-set - - // dotnet workload config --update-mode workload-set - - // dotnet workload config update-mode - // dotnet workload config update-mode workload-set - // dotnet workload config update-mode manifests - - // dotnet workload config update-band [default|release|preview|daily] - - // dotnet config workload.update-mode workload-set - - // dotnet setconfig --workload-update-mode workload-set - [Fact] public void DoesNotUseWorkloadSetsByDefault() { From 2167cd323fb877426facb4aca3437a36976f93bb Mon Sep 17 00:00:00 2001 From: dotnet bot Date: Thu, 4 Apr 2024 05:06:46 -0700 Subject: [PATCH 520/577] Localized file check-in by OneLocBuild Task: Build definition ID 140: Build ID 2422523 --- .../config/xlf/LocalizableStrings.cs.xlf | 19 +++++++++++++++++++ .../config/xlf/LocalizableStrings.de.xlf | 19 +++++++++++++++++++ .../config/xlf/LocalizableStrings.es.xlf | 19 +++++++++++++++++++ .../config/xlf/LocalizableStrings.fr.xlf | 19 +++++++++++++++++++ .../config/xlf/LocalizableStrings.it.xlf | 19 +++++++++++++++++++ .../config/xlf/LocalizableStrings.ja.xlf | 19 +++++++++++++++++++ .../config/xlf/LocalizableStrings.ko.xlf | 19 +++++++++++++++++++ .../config/xlf/LocalizableStrings.pl.xlf | 19 +++++++++++++++++++ .../config/xlf/LocalizableStrings.pt-BR.xlf | 19 +++++++++++++++++++ .../config/xlf/LocalizableStrings.ru.xlf | 19 +++++++++++++++++++ .../config/xlf/LocalizableStrings.tr.xlf | 19 +++++++++++++++++++ .../config/xlf/LocalizableStrings.zh-Hans.xlf | 19 +++++++++++++++++++ .../config/xlf/LocalizableStrings.zh-Hant.xlf | 19 +++++++++++++++++++ .../install/xlf/LocalizableStrings.cs.xlf | 5 ----- .../install/xlf/LocalizableStrings.de.xlf | 5 ----- .../install/xlf/LocalizableStrings.es.xlf | 5 ----- .../install/xlf/LocalizableStrings.fr.xlf | 5 ----- .../install/xlf/LocalizableStrings.it.xlf | 5 ----- .../install/xlf/LocalizableStrings.ja.xlf | 5 ----- .../install/xlf/LocalizableStrings.ko.xlf | 5 ----- .../install/xlf/LocalizableStrings.pl.xlf | 5 ----- .../install/xlf/LocalizableStrings.pt-BR.xlf | 5 ----- .../install/xlf/LocalizableStrings.ru.xlf | 5 ----- .../install/xlf/LocalizableStrings.tr.xlf | 5 ----- .../xlf/LocalizableStrings.zh-Hans.xlf | 5 ----- .../xlf/LocalizableStrings.zh-Hant.xlf | 5 ----- 26 files changed, 247 insertions(+), 65 deletions(-) create mode 100644 src/Cli/dotnet/commands/dotnet-workload/config/xlf/LocalizableStrings.cs.xlf create mode 100644 src/Cli/dotnet/commands/dotnet-workload/config/xlf/LocalizableStrings.de.xlf create mode 100644 src/Cli/dotnet/commands/dotnet-workload/config/xlf/LocalizableStrings.es.xlf create mode 100644 src/Cli/dotnet/commands/dotnet-workload/config/xlf/LocalizableStrings.fr.xlf create mode 100644 src/Cli/dotnet/commands/dotnet-workload/config/xlf/LocalizableStrings.it.xlf create mode 100644 src/Cli/dotnet/commands/dotnet-workload/config/xlf/LocalizableStrings.ja.xlf create mode 100644 src/Cli/dotnet/commands/dotnet-workload/config/xlf/LocalizableStrings.ko.xlf create mode 100644 src/Cli/dotnet/commands/dotnet-workload/config/xlf/LocalizableStrings.pl.xlf create mode 100644 src/Cli/dotnet/commands/dotnet-workload/config/xlf/LocalizableStrings.pt-BR.xlf create mode 100644 src/Cli/dotnet/commands/dotnet-workload/config/xlf/LocalizableStrings.ru.xlf create mode 100644 src/Cli/dotnet/commands/dotnet-workload/config/xlf/LocalizableStrings.tr.xlf create mode 100644 src/Cli/dotnet/commands/dotnet-workload/config/xlf/LocalizableStrings.zh-Hans.xlf create mode 100644 src/Cli/dotnet/commands/dotnet-workload/config/xlf/LocalizableStrings.zh-Hant.xlf diff --git a/src/Cli/dotnet/commands/dotnet-workload/config/xlf/LocalizableStrings.cs.xlf b/src/Cli/dotnet/commands/dotnet-workload/config/xlf/LocalizableStrings.cs.xlf new file mode 100644 index 000000000000..8d6be7eaaf81 --- /dev/null +++ b/src/Cli/dotnet/commands/dotnet-workload/config/xlf/LocalizableStrings.cs.xlf @@ -0,0 +1,19 @@ + + + + + + Modify or display workload configuration values. +To display a value, specify the corresponding command-line option without providing a value. For example: "dotnet workload config --update-mode" + Modify or display workload configuration values. +To display a value, specify the corresponding command-line option without providing a value. For example: "dotnet workload config --update-mode" + + + + Controls whether updates should look for workload sets or the latest version of each individual manifest. + Controls whether updates should look for workload sets or the latest version of each individual manifest. + + + + + \ No newline at end of file diff --git a/src/Cli/dotnet/commands/dotnet-workload/config/xlf/LocalizableStrings.de.xlf b/src/Cli/dotnet/commands/dotnet-workload/config/xlf/LocalizableStrings.de.xlf new file mode 100644 index 000000000000..88aee0f67512 --- /dev/null +++ b/src/Cli/dotnet/commands/dotnet-workload/config/xlf/LocalizableStrings.de.xlf @@ -0,0 +1,19 @@ + + + + + + Modify or display workload configuration values. +To display a value, specify the corresponding command-line option without providing a value. For example: "dotnet workload config --update-mode" + Modify or display workload configuration values. +To display a value, specify the corresponding command-line option without providing a value. For example: "dotnet workload config --update-mode" + + + + Controls whether updates should look for workload sets or the latest version of each individual manifest. + Controls whether updates should look for workload sets or the latest version of each individual manifest. + + + + + \ No newline at end of file diff --git a/src/Cli/dotnet/commands/dotnet-workload/config/xlf/LocalizableStrings.es.xlf b/src/Cli/dotnet/commands/dotnet-workload/config/xlf/LocalizableStrings.es.xlf new file mode 100644 index 000000000000..55b10d407fc2 --- /dev/null +++ b/src/Cli/dotnet/commands/dotnet-workload/config/xlf/LocalizableStrings.es.xlf @@ -0,0 +1,19 @@ + + + + + + Modify or display workload configuration values. +To display a value, specify the corresponding command-line option without providing a value. For example: "dotnet workload config --update-mode" + Modify or display workload configuration values. +To display a value, specify the corresponding command-line option without providing a value. For example: "dotnet workload config --update-mode" + + + + Controls whether updates should look for workload sets or the latest version of each individual manifest. + Controls whether updates should look for workload sets or the latest version of each individual manifest. + + + + + \ No newline at end of file diff --git a/src/Cli/dotnet/commands/dotnet-workload/config/xlf/LocalizableStrings.fr.xlf b/src/Cli/dotnet/commands/dotnet-workload/config/xlf/LocalizableStrings.fr.xlf new file mode 100644 index 000000000000..c7cc788430d4 --- /dev/null +++ b/src/Cli/dotnet/commands/dotnet-workload/config/xlf/LocalizableStrings.fr.xlf @@ -0,0 +1,19 @@ + + + + + + Modify or display workload configuration values. +To display a value, specify the corresponding command-line option without providing a value. For example: "dotnet workload config --update-mode" + Modify or display workload configuration values. +To display a value, specify the corresponding command-line option without providing a value. For example: "dotnet workload config --update-mode" + + + + Controls whether updates should look for workload sets or the latest version of each individual manifest. + Controls whether updates should look for workload sets or the latest version of each individual manifest. + + + + + \ No newline at end of file diff --git a/src/Cli/dotnet/commands/dotnet-workload/config/xlf/LocalizableStrings.it.xlf b/src/Cli/dotnet/commands/dotnet-workload/config/xlf/LocalizableStrings.it.xlf new file mode 100644 index 000000000000..ba98130db0bf --- /dev/null +++ b/src/Cli/dotnet/commands/dotnet-workload/config/xlf/LocalizableStrings.it.xlf @@ -0,0 +1,19 @@ + + + + + + Modify or display workload configuration values. +To display a value, specify the corresponding command-line option without providing a value. For example: "dotnet workload config --update-mode" + Modify or display workload configuration values. +To display a value, specify the corresponding command-line option without providing a value. For example: "dotnet workload config --update-mode" + + + + Controls whether updates should look for workload sets or the latest version of each individual manifest. + Controls whether updates should look for workload sets or the latest version of each individual manifest. + + + + + \ No newline at end of file diff --git a/src/Cli/dotnet/commands/dotnet-workload/config/xlf/LocalizableStrings.ja.xlf b/src/Cli/dotnet/commands/dotnet-workload/config/xlf/LocalizableStrings.ja.xlf new file mode 100644 index 000000000000..882fdf49f5d9 --- /dev/null +++ b/src/Cli/dotnet/commands/dotnet-workload/config/xlf/LocalizableStrings.ja.xlf @@ -0,0 +1,19 @@ + + + + + + Modify or display workload configuration values. +To display a value, specify the corresponding command-line option without providing a value. For example: "dotnet workload config --update-mode" + Modify or display workload configuration values. +To display a value, specify the corresponding command-line option without providing a value. For example: "dotnet workload config --update-mode" + + + + Controls whether updates should look for workload sets or the latest version of each individual manifest. + Controls whether updates should look for workload sets or the latest version of each individual manifest. + + + + + \ No newline at end of file diff --git a/src/Cli/dotnet/commands/dotnet-workload/config/xlf/LocalizableStrings.ko.xlf b/src/Cli/dotnet/commands/dotnet-workload/config/xlf/LocalizableStrings.ko.xlf new file mode 100644 index 000000000000..b8773e9b116c --- /dev/null +++ b/src/Cli/dotnet/commands/dotnet-workload/config/xlf/LocalizableStrings.ko.xlf @@ -0,0 +1,19 @@ + + + + + + Modify or display workload configuration values. +To display a value, specify the corresponding command-line option without providing a value. For example: "dotnet workload config --update-mode" + Modify or display workload configuration values. +To display a value, specify the corresponding command-line option without providing a value. For example: "dotnet workload config --update-mode" + + + + Controls whether updates should look for workload sets or the latest version of each individual manifest. + Controls whether updates should look for workload sets or the latest version of each individual manifest. + + + + + \ No newline at end of file diff --git a/src/Cli/dotnet/commands/dotnet-workload/config/xlf/LocalizableStrings.pl.xlf b/src/Cli/dotnet/commands/dotnet-workload/config/xlf/LocalizableStrings.pl.xlf new file mode 100644 index 000000000000..06ccf667f917 --- /dev/null +++ b/src/Cli/dotnet/commands/dotnet-workload/config/xlf/LocalizableStrings.pl.xlf @@ -0,0 +1,19 @@ + + + + + + Modify or display workload configuration values. +To display a value, specify the corresponding command-line option without providing a value. For example: "dotnet workload config --update-mode" + Modify or display workload configuration values. +To display a value, specify the corresponding command-line option without providing a value. For example: "dotnet workload config --update-mode" + + + + Controls whether updates should look for workload sets or the latest version of each individual manifest. + Controls whether updates should look for workload sets or the latest version of each individual manifest. + + + + + \ No newline at end of file diff --git a/src/Cli/dotnet/commands/dotnet-workload/config/xlf/LocalizableStrings.pt-BR.xlf b/src/Cli/dotnet/commands/dotnet-workload/config/xlf/LocalizableStrings.pt-BR.xlf new file mode 100644 index 000000000000..27459bb8c5fb --- /dev/null +++ b/src/Cli/dotnet/commands/dotnet-workload/config/xlf/LocalizableStrings.pt-BR.xlf @@ -0,0 +1,19 @@ + + + + + + Modify or display workload configuration values. +To display a value, specify the corresponding command-line option without providing a value. For example: "dotnet workload config --update-mode" + Modify or display workload configuration values. +To display a value, specify the corresponding command-line option without providing a value. For example: "dotnet workload config --update-mode" + + + + Controls whether updates should look for workload sets or the latest version of each individual manifest. + Controls whether updates should look for workload sets or the latest version of each individual manifest. + + + + + \ No newline at end of file diff --git a/src/Cli/dotnet/commands/dotnet-workload/config/xlf/LocalizableStrings.ru.xlf b/src/Cli/dotnet/commands/dotnet-workload/config/xlf/LocalizableStrings.ru.xlf new file mode 100644 index 000000000000..5a490dbba2f5 --- /dev/null +++ b/src/Cli/dotnet/commands/dotnet-workload/config/xlf/LocalizableStrings.ru.xlf @@ -0,0 +1,19 @@ + + + + + + Modify or display workload configuration values. +To display a value, specify the corresponding command-line option without providing a value. For example: "dotnet workload config --update-mode" + Modify or display workload configuration values. +To display a value, specify the corresponding command-line option without providing a value. For example: "dotnet workload config --update-mode" + + + + Controls whether updates should look for workload sets or the latest version of each individual manifest. + Controls whether updates should look for workload sets or the latest version of each individual manifest. + + + + + \ No newline at end of file diff --git a/src/Cli/dotnet/commands/dotnet-workload/config/xlf/LocalizableStrings.tr.xlf b/src/Cli/dotnet/commands/dotnet-workload/config/xlf/LocalizableStrings.tr.xlf new file mode 100644 index 000000000000..07fe44de371f --- /dev/null +++ b/src/Cli/dotnet/commands/dotnet-workload/config/xlf/LocalizableStrings.tr.xlf @@ -0,0 +1,19 @@ + + + + + + Modify or display workload configuration values. +To display a value, specify the corresponding command-line option without providing a value. For example: "dotnet workload config --update-mode" + Modify or display workload configuration values. +To display a value, specify the corresponding command-line option without providing a value. For example: "dotnet workload config --update-mode" + + + + Controls whether updates should look for workload sets or the latest version of each individual manifest. + Controls whether updates should look for workload sets or the latest version of each individual manifest. + + + + + \ No newline at end of file diff --git a/src/Cli/dotnet/commands/dotnet-workload/config/xlf/LocalizableStrings.zh-Hans.xlf b/src/Cli/dotnet/commands/dotnet-workload/config/xlf/LocalizableStrings.zh-Hans.xlf new file mode 100644 index 000000000000..41a4543b7566 --- /dev/null +++ b/src/Cli/dotnet/commands/dotnet-workload/config/xlf/LocalizableStrings.zh-Hans.xlf @@ -0,0 +1,19 @@ + + + + + + Modify or display workload configuration values. +To display a value, specify the corresponding command-line option without providing a value. For example: "dotnet workload config --update-mode" + Modify or display workload configuration values. +To display a value, specify the corresponding command-line option without providing a value. For example: "dotnet workload config --update-mode" + + + + Controls whether updates should look for workload sets or the latest version of each individual manifest. + Controls whether updates should look for workload sets or the latest version of each individual manifest. + + + + + \ No newline at end of file diff --git a/src/Cli/dotnet/commands/dotnet-workload/config/xlf/LocalizableStrings.zh-Hant.xlf b/src/Cli/dotnet/commands/dotnet-workload/config/xlf/LocalizableStrings.zh-Hant.xlf new file mode 100644 index 000000000000..8a8598849d60 --- /dev/null +++ b/src/Cli/dotnet/commands/dotnet-workload/config/xlf/LocalizableStrings.zh-Hant.xlf @@ -0,0 +1,19 @@ + + + + + + Modify or display workload configuration values. +To display a value, specify the corresponding command-line option without providing a value. For example: "dotnet workload config --update-mode" + Modify or display workload configuration values. +To display a value, specify the corresponding command-line option without providing a value. For example: "dotnet workload config --update-mode" + + + + Controls whether updates should look for workload sets or the latest version of each individual manifest. + Controls whether updates should look for workload sets or the latest version of each individual manifest. + + + + + \ No newline at end of file diff --git a/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.cs.xlf b/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.cs.xlf index edc035dc5b84..76013b91be7c 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.cs.xlf +++ b/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.cs.xlf @@ -367,11 +367,6 @@ CESTA - - Control whether future workload operations should use workload sets or loose manifests. - Určete, jestli by budoucí operace úloh měly používat sady úloh nebo volné manifesty. - - Updating workload version from {0} to {1}. Aktualizuje se verze úlohy z {0} na {1}. diff --git a/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.de.xlf b/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.de.xlf index c223b4f5ee51..a44263689d79 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.de.xlf +++ b/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.de.xlf @@ -367,11 +367,6 @@ PFAD - - Control whether future workload operations should use workload sets or loose manifests. - Hiermit wird gesteuert, ob zukünftige Workloadvorgänge Workloadsätze oder lose Manifeste verwenden sollen. - - Updating workload version from {0} to {1}. Die Workloadversion wird von {0} auf {1} aktualisiert. diff --git a/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.es.xlf b/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.es.xlf index 3bfc70f3513d..a75cebc92ce9 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.es.xlf +++ b/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.es.xlf @@ -367,11 +367,6 @@ RUTA DE ACCESO - - Control whether future workload operations should use workload sets or loose manifests. - Controle si las operaciones de carga de trabajo futuras deben usar conjuntos de cargas de trabajo o manifiestos flexibles. - - Updating workload version from {0} to {1}. Actualizando la versión de carga de trabajo de {0} a {1}. diff --git a/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.fr.xlf b/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.fr.xlf index 90a3b2211a5c..6c6090b6f272 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.fr.xlf +++ b/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.fr.xlf @@ -367,11 +367,6 @@ PATH - - Control whether future workload operations should use workload sets or loose manifests. - Contrôlez si les futures opérations de charge de travail doivent utiliser des ensembles de charges de travail ou des manifestes lâches. - - Updating workload version from {0} to {1}. Mise à jour de la version de la charge de travail de {0} à {1}. diff --git a/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.it.xlf b/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.it.xlf index 904083600d81..7a5067400e8a 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.it.xlf +++ b/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.it.xlf @@ -367,11 +367,6 @@ PERCORSO - - Control whether future workload operations should use workload sets or loose manifests. - Controllare se le operazioni future del carico di lavoro devono usare set di carichi di lavoro o manifesti separati. - - Updating workload version from {0} to {1}. Aggiornamento della versione del carico di lavoro da {0} a {1}. diff --git a/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.ja.xlf b/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.ja.xlf index 0a11234fc8d5..a31e86c77a7d 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.ja.xlf +++ b/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.ja.xlf @@ -367,11 +367,6 @@ パス - - Control whether future workload operations should use workload sets or loose manifests. - 将来のワークロード操作でワークロード セットを使用するか、ルーズ マニフェストを使用するかを制御します。 - - Updating workload version from {0} to {1}. ワークロードのバージョンを {0} から {1} に更新しています。 diff --git a/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.ko.xlf b/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.ko.xlf index 5a1a593eb4f4..12407ab1d966 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.ko.xlf +++ b/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.ko.xlf @@ -367,11 +367,6 @@ 경로 - - Control whether future workload operations should use workload sets or loose manifests. - 향후 워크로드 작업에서 워크로드 집합을 사용할지, 매니페스트를 완화할지를 제어합니다. - - Updating workload version from {0} to {1}. 워크로드 버전을 {0}에서 {1}(으)로 업데이트하는 중입니다. diff --git a/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.pl.xlf b/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.pl.xlf index 9bd2f142bd6d..a784788b99f0 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.pl.xlf +++ b/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.pl.xlf @@ -367,11 +367,6 @@ ŚCIEŻKA - - Control whether future workload operations should use workload sets or loose manifests. - Określ, czy przyszłe operacje związane z obciążeniami powinny wykorzystywać zestawy obciążeń, czy luźne manifesty. - - Updating workload version from {0} to {1}. Aktualizowanie wersji obciążenia z {0} do {1}. diff --git a/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.pt-BR.xlf b/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.pt-BR.xlf index 762ee625556a..3868ca862661 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.pt-BR.xlf +++ b/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.pt-BR.xlf @@ -367,11 +367,6 @@ CAMINHO - - Control whether future workload operations should use workload sets or loose manifests. - Controle se as operações de carga de trabalho futuras devem usar conjuntos de carga de trabalho ou manifestos flexíveis. - - Updating workload version from {0} to {1}. Atualizando a versão da carga de trabalho {0} para {1}. diff --git a/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.ru.xlf b/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.ru.xlf index 4fff4d220590..118f305e080c 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.ru.xlf +++ b/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.ru.xlf @@ -367,11 +367,6 @@ PATH - - Control whether future workload operations should use workload sets or loose manifests. - Укажите, должны ли будущие операции рабочей нагрузки использовать наборы рабочей нагрузки или свободные манифесты. - - Updating workload version from {0} to {1}. Обновление версии рабочей нагрузки с {0} до {1}. diff --git a/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.tr.xlf b/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.tr.xlf index e24de92ad1dc..7e3b417ba5d8 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.tr.xlf +++ b/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.tr.xlf @@ -367,11 +367,6 @@ YOL - - Control whether future workload operations should use workload sets or loose manifests. - Gelecekteki iş yükü işlemlerinin iş yükü kümelerini mi yoksa gevşek bildirimleri mi kullanması gerektiğini kontrol edin. - - Updating workload version from {0} to {1}. İş yükü {0} sürümünden {1} sürümüne güncelleştiriliyor. diff --git a/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.zh-Hans.xlf b/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.zh-Hans.xlf index e9d4dfa8deb9..fddbca0c8a49 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.zh-Hans.xlf +++ b/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.zh-Hans.xlf @@ -367,11 +367,6 @@ 路径 - - Control whether future workload operations should use workload sets or loose manifests. - 控制未来的工作负载操作应该使用工作负载集还是松散清单。 - - Updating workload version from {0} to {1}. 正在将工作负载版本从 {0} 更新为 {1}。 diff --git a/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.zh-Hant.xlf b/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.zh-Hant.xlf index 7f59f2cdda4d..43d76325d2dd 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.zh-Hant.xlf +++ b/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.zh-Hant.xlf @@ -367,11 +367,6 @@ 路徑 - - Control whether future workload operations should use workload sets or loose manifests. - 控制未來的工作負載作業應該使用工作負載集合還是鬆散資訊清單。 - - Updating workload version from {0} to {1}. 正在將工作負載版本從 {0} 更新為 {1}。 From b69652a0cd370848d925fc88dbe6317733d34294 Mon Sep 17 00:00:00 2001 From: dotnet bot Date: Thu, 4 Apr 2024 05:08:53 -0700 Subject: [PATCH 521/577] Localized file check-in by OneLocBuild Task: Build definition ID 140: Build ID 2422523 --- .../dotnet-workload/update/xlf/LocalizableStrings.cs.xlf | 5 ----- .../dotnet-workload/update/xlf/LocalizableStrings.de.xlf | 5 ----- .../dotnet-workload/update/xlf/LocalizableStrings.es.xlf | 5 ----- .../dotnet-workload/update/xlf/LocalizableStrings.fr.xlf | 5 ----- .../dotnet-workload/update/xlf/LocalizableStrings.it.xlf | 5 ----- .../dotnet-workload/update/xlf/LocalizableStrings.ja.xlf | 5 ----- .../dotnet-workload/update/xlf/LocalizableStrings.ko.xlf | 5 ----- .../dotnet-workload/update/xlf/LocalizableStrings.pl.xlf | 5 ----- .../dotnet-workload/update/xlf/LocalizableStrings.pt-BR.xlf | 5 ----- .../dotnet-workload/update/xlf/LocalizableStrings.ru.xlf | 5 ----- .../dotnet-workload/update/xlf/LocalizableStrings.tr.xlf | 5 ----- .../update/xlf/LocalizableStrings.zh-Hans.xlf | 5 ----- .../update/xlf/LocalizableStrings.zh-Hant.xlf | 5 ----- 13 files changed, 65 deletions(-) diff --git a/src/Cli/dotnet/commands/dotnet-workload/update/xlf/LocalizableStrings.cs.xlf b/src/Cli/dotnet/commands/dotnet-workload/update/xlf/LocalizableStrings.cs.xlf index 977f612e55c7..2bda96c4722a 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/update/xlf/LocalizableStrings.cs.xlf +++ b/src/Cli/dotnet/commands/dotnet-workload/update/xlf/LocalizableStrings.cs.xlf @@ -57,11 +57,6 @@ Nepovedlo se stáhnout balíčky aktualizace úlohy do mezipaměti: {0}. - - Invalid argument "{0}" to the --mode argument for dotnet workload update. Only supported modes are "workloadset", "loosemanifest", and "auto". - Neplatný argument „{0}“ argumentu --mode pro aktualizaci úlohy dotnet. Jediné podporované režimy jsou workloadset, loosemanifest a auto. - - Successfully updated advertising manifests. Manifesty reklamy se úspěšně aktualizovaly. diff --git a/src/Cli/dotnet/commands/dotnet-workload/update/xlf/LocalizableStrings.de.xlf b/src/Cli/dotnet/commands/dotnet-workload/update/xlf/LocalizableStrings.de.xlf index 8f13b36509a4..05b1a8b2e007 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/update/xlf/LocalizableStrings.de.xlf +++ b/src/Cli/dotnet/commands/dotnet-workload/update/xlf/LocalizableStrings.de.xlf @@ -57,11 +57,6 @@ Fehler beim Herunterladen von Paketen zur Workloadaktualisierung in den Cache: {0} - - Invalid argument "{0}" to the --mode argument for dotnet workload update. Only supported modes are "workloadset", "loosemanifest", and "auto". - Ungültiges Argument "{0}" zum Argument --mode für das Dotnet Workload-Update. Es werden nur die Modi "workloadset", "loosemanifest" und "auto" unterstützt. - - Successfully updated advertising manifests. Werbemanifeste wurden erfolgreich aktualisiert. diff --git a/src/Cli/dotnet/commands/dotnet-workload/update/xlf/LocalizableStrings.es.xlf b/src/Cli/dotnet/commands/dotnet-workload/update/xlf/LocalizableStrings.es.xlf index 89eccf8ab9f1..a3b8b2e1d792 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/update/xlf/LocalizableStrings.es.xlf +++ b/src/Cli/dotnet/commands/dotnet-workload/update/xlf/LocalizableStrings.es.xlf @@ -57,11 +57,6 @@ No se pudieron descargar los paquetes de actualización de la carga de trabajo en caché: {0} - - Invalid argument "{0}" to the --mode argument for dotnet workload update. Only supported modes are "workloadset", "loosemanifest", and "auto". - Argumento "{0}" no válido para el argumento --mode para la actualización de la carga de trabajo de dotnet. Solo los modos admitidos son "workloadset", "loosemanifest" y "auto". - - Successfully updated advertising manifests. Los manifiestos de publicidad se han actualizado correctamente. diff --git a/src/Cli/dotnet/commands/dotnet-workload/update/xlf/LocalizableStrings.fr.xlf b/src/Cli/dotnet/commands/dotnet-workload/update/xlf/LocalizableStrings.fr.xlf index c364e36206ec..08c5734fb317 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/update/xlf/LocalizableStrings.fr.xlf +++ b/src/Cli/dotnet/commands/dotnet-workload/update/xlf/LocalizableStrings.fr.xlf @@ -57,11 +57,6 @@ Échec du téléchargement des packages de mise à jour de charge de travail dans le cache : {0} - - Invalid argument "{0}" to the --mode argument for dotnet workload update. Only supported modes are "workloadset", "loosemanifest", and "auto". - Argument «{0}» non valide à l’argument --mode pour la mise à jour de charge de travail dotnet. Seuls les modes pris en charge sont « workloadset », « loosemanifest » et « auto ». - - Successfully updated advertising manifests. Les manifestes de publicité ont été mis à jour. diff --git a/src/Cli/dotnet/commands/dotnet-workload/update/xlf/LocalizableStrings.it.xlf b/src/Cli/dotnet/commands/dotnet-workload/update/xlf/LocalizableStrings.it.xlf index f623260c5ea4..3040c6880e23 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/update/xlf/LocalizableStrings.it.xlf +++ b/src/Cli/dotnet/commands/dotnet-workload/update/xlf/LocalizableStrings.it.xlf @@ -57,11 +57,6 @@ Non è stato possibile scaricare i pacchetti di aggiornamento del carico di lavoro nella cache: {0} - - Invalid argument "{0}" to the --mode argument for dotnet workload update. Only supported modes are "workloadset", "loosemanifest", and "auto". - Argomento non valido "{0}" per l'argomento --mode per l'aggiornamento del carico di lavoro dotnet. Le uniche modalità supportate sono "workloadset", "loosemanifest" e "auto". - - Successfully updated advertising manifests. I manifesti pubblicitari sono stati aggiornati. diff --git a/src/Cli/dotnet/commands/dotnet-workload/update/xlf/LocalizableStrings.ja.xlf b/src/Cli/dotnet/commands/dotnet-workload/update/xlf/LocalizableStrings.ja.xlf index 7fbe935ab64a..d7c572c9aa44 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/update/xlf/LocalizableStrings.ja.xlf +++ b/src/Cli/dotnet/commands/dotnet-workload/update/xlf/LocalizableStrings.ja.xlf @@ -57,11 +57,6 @@ ワークロード更新パッケージをキャッシュにダウンロードできませんでした: {0} - - Invalid argument "{0}" to the --mode argument for dotnet workload update. Only supported modes are "workloadset", "loosemanifest", and "auto". - .NET ワークロード更新の --mode 引数に対する引数 "{0}" が無効です。サポートされているモードは、"workloadset"、"loosemanifest"、および "auto" のみです。 - - Successfully updated advertising manifests. 広告マニフェストを正常に更新しました。 diff --git a/src/Cli/dotnet/commands/dotnet-workload/update/xlf/LocalizableStrings.ko.xlf b/src/Cli/dotnet/commands/dotnet-workload/update/xlf/LocalizableStrings.ko.xlf index 94339a424af4..68df940257eb 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/update/xlf/LocalizableStrings.ko.xlf +++ b/src/Cli/dotnet/commands/dotnet-workload/update/xlf/LocalizableStrings.ko.xlf @@ -57,11 +57,6 @@ 캐시할 워크로드 업데이트 패키지를 다운로드하지 못했습니다. {0} - - Invalid argument "{0}" to the --mode argument for dotnet workload update. Only supported modes are "workloadset", "loosemanifest", and "auto". - dotnet 워크로드 업데이트의 --mode 인수에 대한 "{0}" 인수가 잘못되었습니다. "workloadset", "loosemanifest", "auto" 모드만 지원됩니다. - - Successfully updated advertising manifests. 알림 매니페스트를 업데이트했습니다. diff --git a/src/Cli/dotnet/commands/dotnet-workload/update/xlf/LocalizableStrings.pl.xlf b/src/Cli/dotnet/commands/dotnet-workload/update/xlf/LocalizableStrings.pl.xlf index 8be9f85b5d9b..968f9e2b24fb 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/update/xlf/LocalizableStrings.pl.xlf +++ b/src/Cli/dotnet/commands/dotnet-workload/update/xlf/LocalizableStrings.pl.xlf @@ -57,11 +57,6 @@ Nie można pobrać pakietów aktualizacji pakietów roboczych do pamięci podręcznej: {0} - - Invalid argument "{0}" to the --mode argument for dotnet workload update. Only supported modes are "workloadset", "loosemanifest", and "auto". - Nieprawidłowy argument „{0}” argumentu --mode dla aktualizacji obciążenia dotnet. Obsługiwane tryby to „workloadset”, „loosemanifest” i „auto”. - - Successfully updated advertising manifests. Pomyślnie zaktualizowano manifesty reklam. diff --git a/src/Cli/dotnet/commands/dotnet-workload/update/xlf/LocalizableStrings.pt-BR.xlf b/src/Cli/dotnet/commands/dotnet-workload/update/xlf/LocalizableStrings.pt-BR.xlf index 16e079b66c49..9580e9b05508 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/update/xlf/LocalizableStrings.pt-BR.xlf +++ b/src/Cli/dotnet/commands/dotnet-workload/update/xlf/LocalizableStrings.pt-BR.xlf @@ -57,11 +57,6 @@ Falha ao baixar pacotes de atualização de carga de trabalho para o cache: {0} - - Invalid argument "{0}" to the --mode argument for dotnet workload update. Only supported modes are "workloadset", "loosemanifest", and "auto". - Argumento "{0}" inválido para o argumento --mode para atualização de carga de trabalho dotnet. Os únicos modos com suporte são "workloadset", "loosemanifest" e "auto". - - Successfully updated advertising manifests. Manifestos de anúncio atualizados com êxito. diff --git a/src/Cli/dotnet/commands/dotnet-workload/update/xlf/LocalizableStrings.ru.xlf b/src/Cli/dotnet/commands/dotnet-workload/update/xlf/LocalizableStrings.ru.xlf index 2dc67f8b32f1..1b13510a65be 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/update/xlf/LocalizableStrings.ru.xlf +++ b/src/Cli/dotnet/commands/dotnet-workload/update/xlf/LocalizableStrings.ru.xlf @@ -57,11 +57,6 @@ Не удалось скачать пакеты обновления рабочей нагрузки в кэш: {0} - - Invalid argument "{0}" to the --mode argument for dotnet workload update. Only supported modes are "workloadset", "loosemanifest", and "auto". - Недопустимый аргумент "{0}" для аргумента --mode для обновления рабочей нагрузки dotnet. Поддерживаются только режимы "workloadset", "loosemanifest" и "auto". - - Successfully updated advertising manifests. Манифесты рекламы успешно обновлены. diff --git a/src/Cli/dotnet/commands/dotnet-workload/update/xlf/LocalizableStrings.tr.xlf b/src/Cli/dotnet/commands/dotnet-workload/update/xlf/LocalizableStrings.tr.xlf index e3329bd11b94..fdb8fb481136 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/update/xlf/LocalizableStrings.tr.xlf +++ b/src/Cli/dotnet/commands/dotnet-workload/update/xlf/LocalizableStrings.tr.xlf @@ -57,11 +57,6 @@ İş yükü güncelleştirme paketleri önbelleğe yüklenemedi: {0} - - Invalid argument "{0}" to the --mode argument for dotnet workload update. Only supported modes are "workloadset", "loosemanifest", and "auto". - Dotnet iş yükü güncelleştirmesi için --mod bağımsız değişkeninde geçersiz "{0}" bağımsız değişkeni. Yalnızca "workloadset", "loosemanifest" ve "auto" modları desteklenir. - - Successfully updated advertising manifests. Reklam bildirimleri başarıyla güncelleştirildi. diff --git a/src/Cli/dotnet/commands/dotnet-workload/update/xlf/LocalizableStrings.zh-Hans.xlf b/src/Cli/dotnet/commands/dotnet-workload/update/xlf/LocalizableStrings.zh-Hans.xlf index cb8c213dc67a..8d5aac17dab2 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/update/xlf/LocalizableStrings.zh-Hans.xlf +++ b/src/Cli/dotnet/commands/dotnet-workload/update/xlf/LocalizableStrings.zh-Hans.xlf @@ -57,11 +57,6 @@ 未能将工作负载更新程序包下载到缓存: {0} - - Invalid argument "{0}" to the --mode argument for dotnet workload update. Only supported modes are "workloadset", "loosemanifest", and "auto". - dotnet 工作负载更新的 --mode 参数的参数“{0}”无效。仅支持“workloadset”、“loosemanifest”和“auto”模式。 - - Successfully updated advertising manifests. 成功更新广告清单。 diff --git a/src/Cli/dotnet/commands/dotnet-workload/update/xlf/LocalizableStrings.zh-Hant.xlf b/src/Cli/dotnet/commands/dotnet-workload/update/xlf/LocalizableStrings.zh-Hant.xlf index a9be808c2e2c..ef0d84b155cd 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/update/xlf/LocalizableStrings.zh-Hant.xlf +++ b/src/Cli/dotnet/commands/dotnet-workload/update/xlf/LocalizableStrings.zh-Hant.xlf @@ -57,11 +57,6 @@ 無法將工作負載更新套件下載到快取: {0} - - Invalid argument "{0}" to the --mode argument for dotnet workload update. Only supported modes are "workloadset", "loosemanifest", and "auto". - dotnet 工作負載更新的 --mode 引數之引數 "{0}" 無效。僅支援 "workloadset"、"loosemanifest" 和 "auto" 模式。 - - Successfully updated advertising manifests. 已成功更新廣告資訊清單。 From 7b4a1c4de5448df9e1bdbf7e25c6db0099ce0072 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Thu, 4 Apr 2024 20:09:08 +0000 Subject: [PATCH 522/577] [release/8.0.3xx] Update dependencies from dotnet/templating (#39887) [release/8.0.3xx] Update dependencies from dotnet/templating --- NuGet.config | 2 ++ eng/Version.Details.xml | 8 ++++---- eng/Versions.props | 4 ++-- 3 files changed, 8 insertions(+), 6 deletions(-) diff --git a/NuGet.config b/NuGet.config index 51639cc36b97..9a490d633d72 100644 --- a/NuGet.config +++ b/NuGet.config @@ -7,6 +7,8 @@ + + diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 124887fd8cd1..e92ecdcd383d 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -1,14 +1,14 @@ - + https://github.com/dotnet/templating - eaef194ef84f0bae7a49ac3b6d96505086130cea + 851bd635e5410504884df80d2c9b32ccb4add61d - + https://github.com/dotnet/templating - eaef194ef84f0bae7a49ac3b6d96505086130cea + 851bd635e5410504884df80d2c9b32ccb4add61d https://dev.azure.com/dnceng/internal/_git/dotnet-runtime diff --git a/eng/Versions.props b/eng/Versions.props index a2e54456fd8e..7d3f6b0cc6df 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -137,13 +137,13 @@ - 8.0.300-preview.24177.3 + 8.0.300-preview.24203.2 $(MicrosoftTemplateEngineAbstractionsPackageVersion) $(MicrosoftTemplateEngineAbstractionsPackageVersion) $(MicrosoftTemplateEngineAbstractionsPackageVersion) $(MicrosoftTemplateEngineAbstractionsPackageVersion) - 8.0.300-preview.24177.3 + 8.0.300-preview.24203.2 $(MicrosoftTemplateEngineMocksPackageVersion) $(MicrosoftTemplateEngineAbstractionsPackageVersion) $(MicrosoftTemplateEngineMocksPackageVersion) From b0dcaeb95308db379e6ffe93e6b9eba3615fafea Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Thu, 4 Apr 2024 20:09:13 +0000 Subject: [PATCH 523/577] [release/8.0.3xx] Update dependencies from dotnet/msbuild (#39986) [release/8.0.3xx] Update dependencies from dotnet/msbuild --- NuGet.config | 2 +- eng/Version.Details.xml | 10 +++++----- eng/Versions.props | 2 +- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/NuGet.config b/NuGet.config index 9a490d633d72..09dae3a2170f 100644 --- a/NuGet.config +++ b/NuGet.config @@ -14,7 +14,7 @@ - + diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index e92ecdcd383d..412341555f64 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -53,15 +53,15 @@ https://github.com/dotnet/msbuild - 4f6b1bb283f7418cc8c342d9f91aabb428357715 + dbf652edbedb4e6c612a79cc6907d211c74329d6 - + https://github.com/dotnet/msbuild - 4f6b1bb283f7418cc8c342d9f91aabb428357715 + dbf652edbedb4e6c612a79cc6907d211c74329d6 - + https://github.com/dotnet/msbuild - 4f6b1bb283f7418cc8c342d9f91aabb428357715 + dbf652edbedb4e6c612a79cc6907d211c74329d6 diff --git a/eng/Versions.props b/eng/Versions.props index 7d3f6b0cc6df..67a2dd38f5a6 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -129,7 +129,7 @@ $([System.IO.File]::ReadAllText('$(RepoRoot)\src\Layout\redist\minimumMSBuildVersion').Trim()) $(MicrosoftBuildPackageVersion) $(MicrosoftBuildPackageVersion) - 17.10.0-preview-24178-10 + 17.10.0-preview-24202-03 $(MicrosoftBuildPackageVersion) $(MicrosoftBuildPackageVersion) $(MicrosoftBuildTasksCorePackageVersion) From 54e3a1c1ee79611c144f283d79708cc7f92c2669 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Thu, 4 Apr 2024 16:54:18 -0700 Subject: [PATCH 524/577] [release/8.0.3xx] Update dependencies from dotnet/arcade (#39905) Co-authored-by: dotnet-maestro[bot] --- eng/Version.Details.xml | 16 ++++++++-------- eng/Versions.props | 4 ++-- .../templates-official/job/onelocbuild.yml | 2 +- .../job/publish-build-assets.yml | 4 ++-- .../templates-official/job/source-build.yml | 2 +- .../job/source-index-stage1.yml | 2 +- .../templates-official/post-build/post-build.yml | 10 +++++----- .../variables/pool-providers.yml | 2 +- global.json | 4 ++-- 9 files changed, 23 insertions(+), 23 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 412341555f64..a882a7d23ba6 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -479,22 +479,22 @@ - + https://github.com/dotnet/arcade - b17b2a1bb7da23253043dee059f374b00f3e321a + fc2b7849b25c4a21457feb6da5fc7c9806a80976 - + https://github.com/dotnet/arcade - b17b2a1bb7da23253043dee059f374b00f3e321a + fc2b7849b25c4a21457feb6da5fc7c9806a80976 - + https://github.com/dotnet/arcade - b17b2a1bb7da23253043dee059f374b00f3e321a + fc2b7849b25c4a21457feb6da5fc7c9806a80976 - + https://github.com/dotnet/arcade - b17b2a1bb7da23253043dee059f374b00f3e321a + fc2b7849b25c4a21457feb6da5fc7c9806a80976 https://dev.azure.com/dnceng/internal/_git/dotnet-runtime diff --git a/eng/Versions.props b/eng/Versions.props index 67a2dd38f5a6..a005cef4966d 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -34,7 +34,7 @@ 7.0.0 4.0.0 7.0.0 - 8.0.0-beta.24177.1 + 8.0.0-beta.24179.4 7.0.0-preview.22423.2 8.0.0 4.3.0 @@ -209,7 +209,7 @@ 6.12.0 6.1.0 - 8.0.0-beta.24177.1 + 8.0.0-beta.24179.4 4.18.4 1.3.2 8.0.0-beta.23607.1 diff --git a/eng/common/templates-official/job/onelocbuild.yml b/eng/common/templates-official/job/onelocbuild.yml index ba9ba4930329..52b4d05d3f8d 100644 --- a/eng/common/templates-official/job/onelocbuild.yml +++ b/eng/common/templates-official/job/onelocbuild.yml @@ -56,7 +56,7 @@ jobs: # If it's not devdiv, it's dnceng ${{ if ne(variables['System.TeamProject'], 'DevDiv') }}: name: $(DncEngInternalBuildPool) - image: 1es-windows-2022-pt + image: 1es-windows-2022 os: windows steps: diff --git a/eng/common/templates-official/job/publish-build-assets.yml b/eng/common/templates-official/job/publish-build-assets.yml index 53138622fe7a..589ac80a18b7 100644 --- a/eng/common/templates-official/job/publish-build-assets.yml +++ b/eng/common/templates-official/job/publish-build-assets.yml @@ -60,8 +60,8 @@ jobs: os: windows # If it's not devdiv, it's dnceng ${{ if ne(variables['System.TeamProject'], 'DevDiv') }}: - name: $(DncEngInternalBuildPool) - image: 1es-windows-2022-pt + name: NetCore1ESPool-Publishing-Internal + image: windows.vs2019.amd64 os: windows steps: - ${{ if and(eq(parameters.runAsPublic, 'false'), ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest')) }}: diff --git a/eng/common/templates-official/job/source-build.yml b/eng/common/templates-official/job/source-build.yml index 8aba3b44bb25..f193dfbe2366 100644 --- a/eng/common/templates-official/job/source-build.yml +++ b/eng/common/templates-official/job/source-build.yml @@ -52,7 +52,7 @@ jobs: ${{ if eq(variables['System.TeamProject'], 'internal') }}: name: $[replace(replace(eq(contains(coalesce(variables['System.PullRequest.TargetBranch'], variables['Build.SourceBranch'], 'refs/heads/main'), 'release'), 'true'), True, 'NetCore1ESPool-Svc-Internal'), False, 'NetCore1ESPool-Internal')] - image: 1es-mariner-2-pt + image: 1es-mariner-2 os: linux ${{ if ne(parameters.platform.pool, '') }}: diff --git a/eng/common/templates-official/job/source-index-stage1.yml b/eng/common/templates-official/job/source-index-stage1.yml index 4b6337391708..f0513aee5b0d 100644 --- a/eng/common/templates-official/job/source-index-stage1.yml +++ b/eng/common/templates-official/job/source-index-stage1.yml @@ -33,7 +33,7 @@ jobs: demands: ImageOverride -equals windows.vs2019.amd64.open ${{ if eq(variables['System.TeamProject'], 'internal') }}: name: $(DncEngInternalBuildPool) - image: 1es-windows-2022-pt + image: windows.vs2022.amd64 os: windows steps: diff --git a/eng/common/templates-official/post-build/post-build.yml b/eng/common/templates-official/post-build/post-build.yml index 5c98fe1c0f3a..da1f40958b45 100644 --- a/eng/common/templates-official/post-build/post-build.yml +++ b/eng/common/templates-official/post-build/post-build.yml @@ -110,7 +110,7 @@ stages: # If it's not devdiv, it's dnceng ${{ else }}: name: $(DncEngInternalBuildPool) - image: 1es-windows-2022-pt + image: 1es-windows-2022 os: windows steps: @@ -150,7 +150,7 @@ stages: # If it's not devdiv, it's dnceng ${{ else }}: name: $(DncEngInternalBuildPool) - image: 1es-windows-2022-pt + image: 1es-windows-2022 os: windows steps: - template: setup-maestro-vars.yml @@ -208,7 +208,7 @@ stages: # If it's not devdiv, it's dnceng ${{ else }}: name: $(DncEngInternalBuildPool) - image: 1es-windows-2022-pt + image: 1es-windows-2022 os: windows steps: - template: setup-maestro-vars.yml @@ -261,8 +261,8 @@ stages: os: windows # If it's not devdiv, it's dnceng ${{ else }}: - name: $(DncEngInternalBuildPool) - image: 1es-windows-2022-pt + name: NetCore1ESPool-Publishing-Internal + image: windows.vs2019.amd64 os: windows steps: - template: setup-maestro-vars.yml diff --git a/eng/common/templates-official/variables/pool-providers.yml b/eng/common/templates-official/variables/pool-providers.yml index beab7d1bfba0..1f308b24efc4 100644 --- a/eng/common/templates-official/variables/pool-providers.yml +++ b/eng/common/templates-official/variables/pool-providers.yml @@ -23,7 +23,7 @@ # # pool: # name: $(DncEngInternalBuildPool) -# image: 1es-windows-2022-pt +# image: 1es-windows-2022 variables: # Coalesce the target and source branches so we know when a PR targets a release branch diff --git a/global.json b/global.json index 551b79149203..eeb185f138b1 100644 --- a/global.json +++ b/global.json @@ -14,7 +14,7 @@ } }, "msbuild-sdks": { - "Microsoft.DotNet.Arcade.Sdk": "8.0.0-beta.24177.1", - "Microsoft.DotNet.Helix.Sdk": "8.0.0-beta.24177.1" + "Microsoft.DotNet.Arcade.Sdk": "8.0.0-beta.24179.4", + "Microsoft.DotNet.Helix.Sdk": "8.0.0-beta.24179.4" } } From 70284e8c135386edaab3f309d438df115ad1e8d8 Mon Sep 17 00:00:00 2001 From: Forgind <12969783+Forgind@users.noreply.github.com> Date: Fri, 5 Apr 2024 13:27:01 -0700 Subject: [PATCH 525/577] Address feedback --- .../commands/InstallingWorkloadCommand.cs | 11 +++- .../install/FileBasedInstaller.cs | 2 +- .../install/LocalizableStrings.resx | 2 +- .../install/WorkloadInstallCommand.cs | 35 ++++------ .../install/xlf/LocalizableStrings.cs.xlf | 4 +- .../install/xlf/LocalizableStrings.de.xlf | 4 +- .../install/xlf/LocalizableStrings.es.xlf | 4 +- .../install/xlf/LocalizableStrings.fr.xlf | 4 +- .../install/xlf/LocalizableStrings.it.xlf | 4 +- .../install/xlf/LocalizableStrings.ja.xlf | 4 +- .../install/xlf/LocalizableStrings.ko.xlf | 4 +- .../install/xlf/LocalizableStrings.pl.xlf | 4 +- .../install/xlf/LocalizableStrings.pt-BR.xlf | 4 +- .../install/xlf/LocalizableStrings.ru.xlf | 4 +- .../install/xlf/LocalizableStrings.tr.xlf | 4 +- .../xlf/LocalizableStrings.zh-Hans.xlf | 4 +- .../xlf/LocalizableStrings.zh-Hant.xlf | 4 +- .../restore/WorkloadRestoreCommand.cs | 6 +- .../update/WorkloadUpdateCommand.cs | 21 ++---- .../IWorkloadManifestProvider.cs | 2 +- .../SdkDirectoryWorkloadManifestProvider.cs | 23 +++++-- .../TempDirectoryWorkloadManifestProvider.cs | 2 +- .../WorkloadResolver.cs | 35 ++++++++-- .../FakeManifestProvider.cs | 4 +- ...kDirectoryWorkloadManifestProviderTests.cs | 64 +++++++++++++++++++ .../MockManifestProvider.cs | 2 +- 26 files changed, 174 insertions(+), 87 deletions(-) diff --git a/src/Cli/dotnet/commands/InstallingWorkloadCommand.cs b/src/Cli/dotnet/commands/InstallingWorkloadCommand.cs index bfd2105e20ec..ad20210f9b62 100644 --- a/src/Cli/dotnet/commands/InstallingWorkloadCommand.cs +++ b/src/Cli/dotnet/commands/InstallingWorkloadCommand.cs @@ -35,6 +35,7 @@ internal abstract class InstallingWorkloadCommand : WorkloadCommandBase protected readonly ReleaseVersion _targetSdkVersion; protected readonly string _fromRollbackDefinition; protected string _workloadSetVersion; + protected string _workloadSetVersionFromGlobalJson; protected readonly PackageSourceLocation _packageSourceLocation; protected readonly IWorkloadResolverFactory _workloadResolverFactory; protected IWorkloadResolver _workloadResolver; @@ -104,6 +105,14 @@ public static bool ShouldUseWorkloadSetMode(SdkFeatureBand sdkFeatureBand, strin return installStateContents.UseWorkloadSets ?? false; } + protected void ErrorIfGlobalJsonAndCommandLineMismatch(string globaljsonPath) + { + if (!string.IsNullOrWhiteSpace(_workloadSetVersionFromGlobalJson) && !string.IsNullOrWhiteSpace(_workloadSetVersion) && !_workloadSetVersion.Equals(_workloadSetVersionFromGlobalJson)) + { + throw new Exception(string.Format(Strings.CannotSpecifyVersionOnCommandLineAndInGlobalJson, globaljsonPath)); + } + } + protected IEnumerable HandleWorkloadUpdateFromVersion(ITransactionContext context, DirectoryPath? offlineCache) { // Ensure workload set mode is set to 'workloadset' @@ -114,7 +123,7 @@ protected IEnumerable HandleWorkloadUpdateFromVersion(ITr _workloadInstaller.UpdateInstallMode(_sdkFeatureBand, true); } - _workloadManifestUpdater.DownloadWorkloadSet(_workloadSetVersion, offlineCache); + _workloadManifestUpdater.DownloadWorkloadSet(_workloadSetVersionFromGlobalJson ?? _workloadSetVersion, offlineCache); return InstallWorkloadSet(context); } diff --git a/src/Cli/dotnet/commands/dotnet-workload/install/FileBasedInstaller.cs b/src/Cli/dotnet/commands/dotnet-workload/install/FileBasedInstaller.cs index 6f65aabc795d..800078f10e37 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/install/FileBasedInstaller.cs +++ b/src/Cli/dotnet/commands/dotnet-workload/install/FileBasedInstaller.cs @@ -514,7 +514,7 @@ public void UpdateInstallMode(SdkFeatureBand sdkFeatureBand, bool newMode) var installStateContents = InstallStateContents.FromPath(path); installStateContents.UseWorkloadSets = newMode; File.WriteAllText(path, installStateContents.ToString()); - _reporter.WriteLine(string.Format(LocalizableStrings.UpdatedWorkloadMode, newMode ? "workload sets" : "loose manifests")); + _reporter.WriteLine(string.Format(LocalizableStrings.UpdatedWorkloadMode, newMode ? WorkloadConfigCommandParser.UpdateMode_WorkloadSet : WorkloadConfigCommandParser.UpdateMode_Manifests)); } /// diff --git a/src/Cli/dotnet/commands/dotnet-workload/install/LocalizableStrings.resx b/src/Cli/dotnet/commands/dotnet-workload/install/LocalizableStrings.resx index be5162dd7ed0..f354a3120a2c 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/install/LocalizableStrings.resx +++ b/src/Cli/dotnet/commands/dotnet-workload/install/LocalizableStrings.resx @@ -353,7 +353,7 @@ Updating workload version from {0} to {1}. - Cannot specify a particular workload version on the command line via --version or --from-history when there is already a version specified in the global.json file. + Cannot specify a particular workload version on the command line via --version or --from-history when there is already a version specified in global.json file {0}. To update the globally installed workload version, run the command outside of the path containing that global.json file or update the version specified in the global.json file and run "dotnet workload update." Successfully updated workload install mode to use {0}. diff --git a/src/Cli/dotnet/commands/dotnet-workload/install/WorkloadInstallCommand.cs b/src/Cli/dotnet/commands/dotnet-workload/install/WorkloadInstallCommand.cs index 7a6e281088f9..bdbf3ac154b9 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/install/WorkloadInstallCommand.cs +++ b/src/Cli/dotnet/commands/dotnet-workload/install/WorkloadInstallCommand.cs @@ -28,8 +28,7 @@ public WorkloadInstallCommand( INuGetPackageDownloader nugetPackageDownloader = null, IWorkloadManifestUpdater workloadManifestUpdater = null, string tempDirPath = null, - IReadOnlyCollection workloadIds = null, - string workloadSetVersion = null) + IReadOnlyCollection workloadIds = null) : base(parseResult, reporter: reporter, workloadResolverFactory: workloadResolverFactory, workloadInstaller: workloadInstaller, nugetPackageDownloader: nugetPackageDownloader, workloadManifestUpdater: workloadManifestUpdater, tempDirPath: tempDirPath) @@ -45,13 +44,7 @@ public WorkloadInstallCommand( _workloadManifestUpdater = _workloadManifestUpdaterFromConstructor ?? new WorkloadManifestUpdater(Reporter, _workloadResolver, PackageDownloader, _userProfileDir, _workloadInstaller.GetWorkloadInstallationRecordRepository(), _workloadInstaller, _packageSourceLocation, displayManifestUpdates: Verbosity.IsDetailedOrDiagnostic()); - _workloadSetVersion = workloadSetVersion ?? parseResult.GetValue(InstallingWorkloadCommandParser.WorkloadSetVersionOption); - if (string.IsNullOrWhiteSpace(_workloadSetVersion)) - { - // If the version of the workload set is currently pinned, treat it as if it were freshly pinned. - var installStateContents = InstallStateContents.FromPath(Path.Combine(WorkloadInstallType.GetInstallStateFolder(_sdkFeatureBand, _dotnetPath), "default.json")); - _workloadSetVersion = installStateContents.WorkloadVersion; - } + _workloadSetVersion = parseResult.GetValue(InstallingWorkloadCommandParser.WorkloadSetVersionOption); ValidateWorkloadIdsInput(); } @@ -116,19 +109,10 @@ public override int Execute() else { var globaljsonPath = SdkDirectoryWorkloadManifestProvider.GetGlobalJsonPath(Environment.CurrentDirectory); - var workloadVersion = SdkDirectoryWorkloadManifestProvider.GlobalJsonReader.GetWorkloadVersionFromGlobalJson(globaljsonPath); - if (workloadVersion is not null) - { - if (string.IsNullOrWhiteSpace(_workloadSetVersion)) - { - _workloadSetVersion = workloadVersion; - } - else if (!workloadVersion.Equals(_workloadSetVersion)) - { - throw new Exception(string.Format(LocalizableStrings.CannotSpecifyVersionOnCommandLineAndInGlobalJson)); - } - } - else if (string.IsNullOrWhiteSpace(_workloadSetVersion)) + _workloadSetVersionFromGlobalJson = SdkDirectoryWorkloadManifestProvider.GlobalJsonReader.GetWorkloadVersionFromGlobalJson(globaljsonPath); + ErrorIfGlobalJsonAndCommandLineMismatch(globaljsonPath); + + if (string.IsNullOrWhiteSpace(_workloadSetVersion) && string.IsNullOrWhiteSpace(_workloadSetVersionFromGlobalJson)) { var installStateFilePath = Path.Combine(WorkloadInstallType.GetInstallStateFolder(_sdkFeatureBand, _dotnetPath), "default.json"); if (File.Exists(installStateFilePath)) @@ -142,7 +126,7 @@ public override int Execute() { DirectoryPath? offlineCache = string.IsNullOrWhiteSpace(_fromCacheOption) ? null : new DirectoryPath(_fromCacheOption); var workloadIds = _workloadIds.Select(id => new WorkloadId(id)); - if (string.IsNullOrWhiteSpace(_workloadSetVersion)) + if (string.IsNullOrWhiteSpace(_workloadSetVersion) && string.IsNullOrWhiteSpace(_workloadSetVersionFromGlobalJson)) { InstallWorkloads( workloadIds, @@ -290,7 +274,10 @@ private void InstallWorkloadsWithInstallRecord( installer.SaveInstallStateManifestVersions(sdkFeatureBand, GetInstallStateContents(manifestsToUpdate)); } - installer.AdjustWorkloadSetInInstallState(sdkFeatureBand, string.IsNullOrWhiteSpace(_workloadSetVersion) ? null : _workloadSetVersion); + if (string.IsNullOrWhiteSpace(_workloadSetVersionFromGlobalJson)) + { + installer.AdjustWorkloadSetInInstallState(sdkFeatureBand, string.IsNullOrWhiteSpace(_workloadSetVersion) ? null : _workloadSetVersion); + } _workloadResolver.RefreshWorkloadManifests(); diff --git a/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.cs.xlf b/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.cs.xlf index 7fb21dffd3b2..1df9e9ebb634 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.cs.xlf +++ b/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.cs.xlf @@ -23,8 +23,8 @@ - Cannot specify a particular workload version on the command line via --version or --from-history when there is already a version specified in the global.json file. - Cannot specify a particular workload version on the command line via --version or --from-history when there is already a version specified in the global.json file. + Cannot specify a particular workload version on the command line via --version or --from-history when there is already a version specified in global.json file {0}. To update the globally installed workload version, run the command outside of the path containing that global.json file or update the version specified in the global.json file and run "dotnet workload update." + Cannot specify a particular workload version on the command line via --version or --from-history when there is already a version specified in global.json file {0}. To update the globally installed workload version, run the command outside of the path containing that global.json file or update the version specified in the global.json file and run "dotnet workload update." diff --git a/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.de.xlf b/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.de.xlf index 3edf77d21004..cdf67e7336ef 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.de.xlf +++ b/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.de.xlf @@ -23,8 +23,8 @@ - Cannot specify a particular workload version on the command line via --version or --from-history when there is already a version specified in the global.json file. - Cannot specify a particular workload version on the command line via --version or --from-history when there is already a version specified in the global.json file. + Cannot specify a particular workload version on the command line via --version or --from-history when there is already a version specified in global.json file {0}. To update the globally installed workload version, run the command outside of the path containing that global.json file or update the version specified in the global.json file and run "dotnet workload update." + Cannot specify a particular workload version on the command line via --version or --from-history when there is already a version specified in global.json file {0}. To update the globally installed workload version, run the command outside of the path containing that global.json file or update the version specified in the global.json file and run "dotnet workload update." diff --git a/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.es.xlf b/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.es.xlf index 4a29802a3ce4..8fc65b98a8f4 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.es.xlf +++ b/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.es.xlf @@ -23,8 +23,8 @@ - Cannot specify a particular workload version on the command line via --version or --from-history when there is already a version specified in the global.json file. - Cannot specify a particular workload version on the command line via --version or --from-history when there is already a version specified in the global.json file. + Cannot specify a particular workload version on the command line via --version or --from-history when there is already a version specified in global.json file {0}. To update the globally installed workload version, run the command outside of the path containing that global.json file or update the version specified in the global.json file and run "dotnet workload update." + Cannot specify a particular workload version on the command line via --version or --from-history when there is already a version specified in global.json file {0}. To update the globally installed workload version, run the command outside of the path containing that global.json file or update the version specified in the global.json file and run "dotnet workload update." diff --git a/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.fr.xlf b/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.fr.xlf index 08d600692883..294d00289573 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.fr.xlf +++ b/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.fr.xlf @@ -23,8 +23,8 @@ - Cannot specify a particular workload version on the command line via --version or --from-history when there is already a version specified in the global.json file. - Cannot specify a particular workload version on the command line via --version or --from-history when there is already a version specified in the global.json file. + Cannot specify a particular workload version on the command line via --version or --from-history when there is already a version specified in global.json file {0}. To update the globally installed workload version, run the command outside of the path containing that global.json file or update the version specified in the global.json file and run "dotnet workload update." + Cannot specify a particular workload version on the command line via --version or --from-history when there is already a version specified in global.json file {0}. To update the globally installed workload version, run the command outside of the path containing that global.json file or update the version specified in the global.json file and run "dotnet workload update." diff --git a/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.it.xlf b/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.it.xlf index 2770b382d4a9..e397bc436373 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.it.xlf +++ b/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.it.xlf @@ -23,8 +23,8 @@ - Cannot specify a particular workload version on the command line via --version or --from-history when there is already a version specified in the global.json file. - Cannot specify a particular workload version on the command line via --version or --from-history when there is already a version specified in the global.json file. + Cannot specify a particular workload version on the command line via --version or --from-history when there is already a version specified in global.json file {0}. To update the globally installed workload version, run the command outside of the path containing that global.json file or update the version specified in the global.json file and run "dotnet workload update." + Cannot specify a particular workload version on the command line via --version or --from-history when there is already a version specified in global.json file {0}. To update the globally installed workload version, run the command outside of the path containing that global.json file or update the version specified in the global.json file and run "dotnet workload update." diff --git a/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.ja.xlf b/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.ja.xlf index 0a9d4438e048..d5ea9b1cb78d 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.ja.xlf +++ b/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.ja.xlf @@ -23,8 +23,8 @@ - Cannot specify a particular workload version on the command line via --version or --from-history when there is already a version specified in the global.json file. - Cannot specify a particular workload version on the command line via --version or --from-history when there is already a version specified in the global.json file. + Cannot specify a particular workload version on the command line via --version or --from-history when there is already a version specified in global.json file {0}. To update the globally installed workload version, run the command outside of the path containing that global.json file or update the version specified in the global.json file and run "dotnet workload update." + Cannot specify a particular workload version on the command line via --version or --from-history when there is already a version specified in global.json file {0}. To update the globally installed workload version, run the command outside of the path containing that global.json file or update the version specified in the global.json file and run "dotnet workload update." diff --git a/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.ko.xlf b/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.ko.xlf index 15db704f0fab..ebd44f012d73 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.ko.xlf +++ b/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.ko.xlf @@ -23,8 +23,8 @@ - Cannot specify a particular workload version on the command line via --version or --from-history when there is already a version specified in the global.json file. - Cannot specify a particular workload version on the command line via --version or --from-history when there is already a version specified in the global.json file. + Cannot specify a particular workload version on the command line via --version or --from-history when there is already a version specified in global.json file {0}. To update the globally installed workload version, run the command outside of the path containing that global.json file or update the version specified in the global.json file and run "dotnet workload update." + Cannot specify a particular workload version on the command line via --version or --from-history when there is already a version specified in global.json file {0}. To update the globally installed workload version, run the command outside of the path containing that global.json file or update the version specified in the global.json file and run "dotnet workload update." diff --git a/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.pl.xlf b/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.pl.xlf index 815e76288524..3e61746bc72c 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.pl.xlf +++ b/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.pl.xlf @@ -23,8 +23,8 @@ - Cannot specify a particular workload version on the command line via --version or --from-history when there is already a version specified in the global.json file. - Cannot specify a particular workload version on the command line via --version or --from-history when there is already a version specified in the global.json file. + Cannot specify a particular workload version on the command line via --version or --from-history when there is already a version specified in global.json file {0}. To update the globally installed workload version, run the command outside of the path containing that global.json file or update the version specified in the global.json file and run "dotnet workload update." + Cannot specify a particular workload version on the command line via --version or --from-history when there is already a version specified in global.json file {0}. To update the globally installed workload version, run the command outside of the path containing that global.json file or update the version specified in the global.json file and run "dotnet workload update." diff --git a/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.pt-BR.xlf b/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.pt-BR.xlf index 89a8ed283f91..a583d3c85863 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.pt-BR.xlf +++ b/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.pt-BR.xlf @@ -23,8 +23,8 @@ - Cannot specify a particular workload version on the command line via --version or --from-history when there is already a version specified in the global.json file. - Cannot specify a particular workload version on the command line via --version or --from-history when there is already a version specified in the global.json file. + Cannot specify a particular workload version on the command line via --version or --from-history when there is already a version specified in global.json file {0}. To update the globally installed workload version, run the command outside of the path containing that global.json file or update the version specified in the global.json file and run "dotnet workload update." + Cannot specify a particular workload version on the command line via --version or --from-history when there is already a version specified in global.json file {0}. To update the globally installed workload version, run the command outside of the path containing that global.json file or update the version specified in the global.json file and run "dotnet workload update." diff --git a/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.ru.xlf b/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.ru.xlf index 88f303953acb..2b15f6ee5ea6 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.ru.xlf +++ b/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.ru.xlf @@ -23,8 +23,8 @@ - Cannot specify a particular workload version on the command line via --version or --from-history when there is already a version specified in the global.json file. - Cannot specify a particular workload version on the command line via --version or --from-history when there is already a version specified in the global.json file. + Cannot specify a particular workload version on the command line via --version or --from-history when there is already a version specified in global.json file {0}. To update the globally installed workload version, run the command outside of the path containing that global.json file or update the version specified in the global.json file and run "dotnet workload update." + Cannot specify a particular workload version on the command line via --version or --from-history when there is already a version specified in global.json file {0}. To update the globally installed workload version, run the command outside of the path containing that global.json file or update the version specified in the global.json file and run "dotnet workload update." diff --git a/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.tr.xlf b/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.tr.xlf index 304aa1ea1b8f..af3e34522f43 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.tr.xlf +++ b/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.tr.xlf @@ -23,8 +23,8 @@ - Cannot specify a particular workload version on the command line via --version or --from-history when there is already a version specified in the global.json file. - Cannot specify a particular workload version on the command line via --version or --from-history when there is already a version specified in the global.json file. + Cannot specify a particular workload version on the command line via --version or --from-history when there is already a version specified in global.json file {0}. To update the globally installed workload version, run the command outside of the path containing that global.json file or update the version specified in the global.json file and run "dotnet workload update." + Cannot specify a particular workload version on the command line via --version or --from-history when there is already a version specified in global.json file {0}. To update the globally installed workload version, run the command outside of the path containing that global.json file or update the version specified in the global.json file and run "dotnet workload update." diff --git a/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.zh-Hans.xlf b/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.zh-Hans.xlf index 8cf1491e94ba..ecfae003c7a1 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.zh-Hans.xlf +++ b/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.zh-Hans.xlf @@ -23,8 +23,8 @@ - Cannot specify a particular workload version on the command line via --version or --from-history when there is already a version specified in the global.json file. - Cannot specify a particular workload version on the command line via --version or --from-history when there is already a version specified in the global.json file. + Cannot specify a particular workload version on the command line via --version or --from-history when there is already a version specified in global.json file {0}. To update the globally installed workload version, run the command outside of the path containing that global.json file or update the version specified in the global.json file and run "dotnet workload update." + Cannot specify a particular workload version on the command line via --version or --from-history when there is already a version specified in global.json file {0}. To update the globally installed workload version, run the command outside of the path containing that global.json file or update the version specified in the global.json file and run "dotnet workload update." diff --git a/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.zh-Hant.xlf b/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.zh-Hant.xlf index 96c06b58c519..cc996102fd0b 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.zh-Hant.xlf +++ b/src/Cli/dotnet/commands/dotnet-workload/install/xlf/LocalizableStrings.zh-Hant.xlf @@ -23,8 +23,8 @@ - Cannot specify a particular workload version on the command line via --version or --from-history when there is already a version specified in the global.json file. - Cannot specify a particular workload version on the command line via --version or --from-history when there is already a version specified in the global.json file. + Cannot specify a particular workload version on the command line via --version or --from-history when there is already a version specified in global.json file {0}. To update the globally installed workload version, run the command outside of the path containing that global.json file or update the version specified in the global.json file and run "dotnet workload update." + Cannot specify a particular workload version on the command line via --version or --from-history when there is already a version specified in global.json file {0}. To update the globally installed workload version, run the command outside of the path containing that global.json file or update the version specified in the global.json file and run "dotnet workload update." diff --git a/src/Cli/dotnet/commands/dotnet-workload/restore/WorkloadRestoreCommand.cs b/src/Cli/dotnet/commands/dotnet-workload/restore/WorkloadRestoreCommand.cs index ec404df2c4aa..4913aca803b0 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/restore/WorkloadRestoreCommand.cs +++ b/src/Cli/dotnet/commands/dotnet-workload/restore/WorkloadRestoreCommand.cs @@ -36,12 +36,8 @@ public override int Execute() List allWorkloadId = RunTargetToGetWorkloadIds(allProjects); Reporter.WriteLine(string.Format(LocalizableStrings.InstallingWorkloads, string.Join(" ", allWorkloadId))); - var globaljsonPath = SdkDirectoryWorkloadManifestProvider.GetGlobalJsonPath(Directory.GetCurrentDirectory()); - var workloadVersion = SdkDirectoryWorkloadManifestProvider.GlobalJsonReader.GetWorkloadVersionFromGlobalJson(globaljsonPath); - var workloadInstallCommand = new WorkloadInstallCommand(_result, - workloadIds: allWorkloadId.Select(a => a.ToString()).ToList().AsReadOnly(), - workloadSetVersion: workloadVersion); + workloadIds: allWorkloadId.Select(a => a.ToString()).ToList().AsReadOnly()); workloadInstallCommand.Execute(); return 0; diff --git a/src/Cli/dotnet/commands/dotnet-workload/update/WorkloadUpdateCommand.cs b/src/Cli/dotnet/commands/dotnet-workload/update/WorkloadUpdateCommand.cs index 931d067ed5bc..77e6a2cac57d 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/update/WorkloadUpdateCommand.cs +++ b/src/Cli/dotnet/commands/dotnet-workload/update/WorkloadUpdateCommand.cs @@ -92,23 +92,13 @@ public override int Execute() else { var globaljsonPath = SdkDirectoryWorkloadManifestProvider.GetGlobalJsonPath(Environment.CurrentDirectory); - var workloadVersion = SdkDirectoryWorkloadManifestProvider.GlobalJsonReader.GetWorkloadVersionFromGlobalJson(globaljsonPath); - if (workloadVersion is not null) - { - if (string.IsNullOrWhiteSpace(_workloadSetVersion)) - { - _workloadSetVersion = workloadVersion; - } - else if (!workloadVersion.Equals(_workloadSetVersion)) - { - // Consider setting this in the global.json? Or logging a warning? - } - } + _workloadSetVersionFromGlobalJson = SdkDirectoryWorkloadManifestProvider.GlobalJsonReader.GetWorkloadVersionFromGlobalJson(globaljsonPath); + ErrorIfGlobalJsonAndCommandLineMismatch(globaljsonPath); try { DirectoryPath? offlineCache = string.IsNullOrWhiteSpace(_fromCacheOption) ? null : new DirectoryPath(_fromCacheOption); - if (string.IsNullOrWhiteSpace(_workloadSetVersion)) + if (string.IsNullOrWhiteSpace(_workloadSetVersion) && string.IsNullOrWhiteSpace(_workloadSetVersionFromGlobalJson)) { CalculateManifestUpdatesAndUpdateWorkloads(_includePreviews, offlineCache); } @@ -217,7 +207,10 @@ private void UpdateWorkloadsWithInstallRecord( _workloadInstaller.RemoveManifestsFromInstallState(sdkFeatureBand); } - _workloadInstaller.AdjustWorkloadSetInInstallState(sdkFeatureBand, string.IsNullOrWhiteSpace(_workloadSetVersion) ? null : _workloadSetVersion); + if (string.IsNullOrWhiteSpace(_workloadSetVersionFromGlobalJson)) + { + _workloadInstaller.AdjustWorkloadSetInInstallState(sdkFeatureBand, string.IsNullOrWhiteSpace(_workloadSetVersion) ? null : _workloadSetVersion); + } _workloadResolver.RefreshWorkloadManifests(); diff --git a/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/IWorkloadManifestProvider.cs b/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/IWorkloadManifestProvider.cs index 78c7ea97bc96..f6a5e9676624 100644 --- a/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/IWorkloadManifestProvider.cs +++ b/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/IWorkloadManifestProvider.cs @@ -9,7 +9,7 @@ namespace Microsoft.NET.Sdk.WorkloadManifestReader /// public interface IWorkloadManifestProvider { - void RefreshWorkloadManifests(bool error = false); + void RefreshWorkloadManifests(); IEnumerable GetManifests(); string GetSdkFeatureBand(); diff --git a/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/SdkDirectoryWorkloadManifestProvider.cs b/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/SdkDirectoryWorkloadManifestProvider.cs index ea75a7199683..5d93cc39c90c 100644 --- a/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/SdkDirectoryWorkloadManifestProvider.cs +++ b/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/SdkDirectoryWorkloadManifestProvider.cs @@ -26,6 +26,7 @@ public partial class SdkDirectoryWorkloadManifestProvider : IWorkloadManifestPro private WorkloadSet? _workloadSet; private WorkloadSet? _manifestsFromInstallState; private string? _installStateFilePath; + private bool _initializedManifests = false; public SdkDirectoryWorkloadManifestProvider(string sdkRootPath, string sdkVersion, string? userProfileDir, string? globalJsonPath) : this(sdkRootPath, sdkVersion, Environment.GetEnvironmentVariable, userProfileDir, globalJsonPath) @@ -101,11 +102,9 @@ internal SdkDirectoryWorkloadManifestProvider(string sdkRootPath, string sdkVers } _manifestRoots ??= Array.Empty(); - - RefreshWorkloadManifests(); } - public void RefreshWorkloadManifests(bool error = false) + public void RefreshWorkloadManifests() { _workloadSet = null; _manifestsFromInstallState = null; @@ -114,7 +113,7 @@ public void RefreshWorkloadManifests(bool error = false) if (_workloadSetVersionFromConstructor != null) { - if (!availableWorkloadSets.TryGetValue(_workloadSetVersionFromConstructor, out _workloadSet) && error) + if (!availableWorkloadSets.TryGetValue(_workloadSetVersionFromConstructor, out _workloadSet)) { throw new FileNotFoundException(string.Format(Strings.WorkloadVersionNotFound, _workloadSetVersionFromConstructor)); } @@ -125,7 +124,7 @@ public void RefreshWorkloadManifests(bool error = false) string? globalJsonWorkloadSetVersion = GlobalJsonReader.GetWorkloadVersionFromGlobalJson(_globalJsonPathFromConstructor); if (globalJsonWorkloadSetVersion != null) { - if (!availableWorkloadSets.TryGetValue(globalJsonWorkloadSetVersion, out _workloadSet) && error) + if (!availableWorkloadSets.TryGetValue(globalJsonWorkloadSetVersion, out _workloadSet)) { throw new FileNotFoundException(string.Format(Strings.WorkloadVersionFromGlobalJsonNotFound, globalJsonWorkloadSetVersion, _globalJsonPathFromConstructor)); } @@ -140,7 +139,7 @@ public void RefreshWorkloadManifests(bool error = false) var installState = InstallStateContents.FromPath(installStateFilePath); if (!string.IsNullOrEmpty(installState.WorkloadVersion)) { - if (!availableWorkloadSets.TryGetValue(installState.WorkloadVersion!, out _workloadSet) && error) + if (!availableWorkloadSets.TryGetValue(installState.WorkloadVersion!, out _workloadSet)) { throw new FileNotFoundException(string.Format(Strings.WorkloadVersionFromInstallStateNotFound, installState.WorkloadVersion, installStateFilePath)); } @@ -155,10 +154,17 @@ public void RefreshWorkloadManifests(bool error = false) var maxWorkloadSetVersion = availableWorkloadSets.Keys.Select(k => new ReleaseVersion(k)).Max()!; _workloadSet = availableWorkloadSets[maxWorkloadSetVersion.ToString()]; } + + _initializedManifests = true; } public string? GetWorkloadVersion() { + if (!_initializedManifests) + { + RefreshWorkloadManifests(); + } + if (_workloadSet?.Version is not null) { return _workloadSet?.Version!; @@ -184,6 +190,11 @@ public void RefreshWorkloadManifests(bool error = false) public IEnumerable GetManifests() { + if (!_initializedManifests) + { + RefreshWorkloadManifests(); + } + // Scan manifest directories var manifestIdsToManifests = new Dictionary(StringComparer.OrdinalIgnoreCase); diff --git a/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/TempDirectoryWorkloadManifestProvider.cs b/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/TempDirectoryWorkloadManifestProvider.cs index 79e09b85b887..a764fb2d9fb5 100644 --- a/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/TempDirectoryWorkloadManifestProvider.cs +++ b/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/TempDirectoryWorkloadManifestProvider.cs @@ -14,7 +14,7 @@ public TempDirectoryWorkloadManifestProvider(string manifestsPath, string sdkFea _sdkVersionBand = sdkFeatureBand; } - public void RefreshWorkloadManifests(bool error = false) { } + public void RefreshWorkloadManifests() { } public IEnumerable GetManifests() diff --git a/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/WorkloadResolver.cs b/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/WorkloadResolver.cs index ae4413f23ef8..afb07924ba21 100644 --- a/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/WorkloadResolver.cs +++ b/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/WorkloadResolver.cs @@ -23,6 +23,7 @@ public class WorkloadResolver : IWorkloadResolver private IWorkloadManifestProvider _manifestProvider; private string[] _currentRuntimeIdentifiers; private readonly (string path, bool installable)[] _dotnetRootPaths; + private bool _initializedManifests = false; private Func? _fileExistOverride; private Func? _directoryExistOverride; @@ -81,9 +82,16 @@ private WorkloadResolver(IWorkloadManifestProvider manifestProvider, (string pat : this(dotnetRootPaths, currentRuntimeIdentifiers, manifestProvider.GetSdkFeatureBand()) { _manifestProvider = manifestProvider; + } - LoadManifestsFromProvider(manifestProvider); - ComposeWorkloadManifests(); + private void InitializeManifests() + { + if (!_initializedManifests) + { + LoadManifestsFromProvider(_manifestProvider); + ComposeWorkloadManifests(); + _initializedManifests = true; + } } /// @@ -232,6 +240,7 @@ private void ComposeWorkloadManifests() /// public IEnumerable GetInstalledWorkloadPacksOfKind(WorkloadPackKind kind) { + InitializeManifests(); foreach ((var pack, _) in _packs.Values) { if (pack.Kind != kind) @@ -361,6 +370,7 @@ string GetPackPath(WorkloadPackId resolvedPackageId, string packageVersion, Work /// private HashSet GetInstalledPacks() { + InitializeManifests(); var installedPacks = new HashSet(); foreach ((WorkloadPackId id, (WorkloadPack pack, WorkloadManifest _)) in _packs) { @@ -380,6 +390,8 @@ public IEnumerable GetPacksInWorkload(WorkloadId workloadId) throw new ArgumentException($"'{nameof(workloadId)}' cannot be null or empty", nameof(workloadId)); } + InitializeManifests(); + if (!_workloads.TryGetValue(workloadId, out var value)) { throw new Exception($"Workload not found: {workloadId}. Known workloads: {string.Join(" ", _workloads.Select(workload => workload.Key.ToString()))}"); @@ -418,6 +430,7 @@ public IEnumerable GetExtendedWorkloads(IEnumerable wo IEnumerable<(WorkloadDefinition workload, WorkloadManifest workloadManifest)> EnumerateWorkloadWithExtendsRec(WorkloadId workloadId, IEnumerable extends, WorkloadManifest? manifest) { + InitializeManifests(); dedup ??= new HashSet { workloadId }; foreach (var baseWorkloadId in extends) @@ -482,6 +495,7 @@ public IEnumerable GetExtendedWorkloads(IEnumerable wo throw new ArgumentException($"'{nameof(packId)}' cannot be null or empty", nameof(packId)); } + InitializeManifests(); if (_packs.TryGetValue(packId) is (WorkloadPack pack, _)) { if (ResolvePackPath(pack, out WorkloadPackId resolvedPackageId, out bool isInstalled) is string aliasedPath) @@ -501,6 +515,7 @@ public IEnumerable GetExtendedWorkloads(IEnumerable wo /// public ISet? GetWorkloadSuggestionForMissingPacks(IList packIds, out ISet unsatisfiablePacks) { + InitializeManifests(); var requestedPacks = new HashSet(packIds); var availableWorkloads = GetAvailableWorkloadDefinitions(); @@ -540,6 +555,7 @@ public IEnumerable GetAvailableWorkloads() private IEnumerable<(WorkloadDefinition workload, WorkloadManifest manifest)> GetAvailableWorkloadDefinitions() { + InitializeManifests(); foreach ((WorkloadId _, (WorkloadDefinition workload, WorkloadManifest manifest)) in _workloads) { if (!workload.IsAbstract && IsWorkloadPlatformCompatible(workload, manifest) && !IsWorkloadImplicitlyAbstract(workload, manifest)) @@ -557,6 +573,7 @@ public IEnumerable GetAvailableWorkloads() /// public IEnumerable GetUpdatedWorkloads(WorkloadResolver advertisingManifestResolver, IEnumerable installedWorkloads) { + InitializeManifests(); foreach (var workloadId in installedWorkloads) { if (!_workloads.ContainsKey(workloadId) || !advertisingManifestResolver._workloads.ContainsKey(workloadId)) @@ -608,11 +625,14 @@ private bool PackHasChanged(WorkloadPack oldPack, WorkloadPack newPack) /// ArgumentNullException public WorkloadManifest GetManifestFromWorkload(WorkloadId workloadId) { + InitializeManifests(); return _workloads[workloadId].manifest; } public WorkloadResolver CreateOverlayResolver(IWorkloadManifestProvider overlayManifestProvider) { + InitializeManifests(); + // we specifically don't assign the overlayManifestProvider to the new resolver // because it's not possible to refresh an overlay resolver var overlayResolver = new WorkloadResolver(_dotnetRootPaths, _currentRuntimeIdentifiers, GetSdkFeatureBand()); @@ -696,6 +716,7 @@ public WorkloadInfo(WorkloadId id, string? description) public WorkloadInfo GetWorkloadInfo(WorkloadId workloadId) { + InitializeManifests(); if (_workloads.TryGetValue(workloadId) is not (WorkloadDefinition workload, _)) { throw new ArgumentException($"Workload '{workloadId}' not found", nameof(workloadId)); @@ -705,6 +726,7 @@ public WorkloadInfo GetWorkloadInfo(WorkloadId workloadId) public bool IsPlatformIncompatibleWorkload(WorkloadId workloadId) { + InitializeManifests(); if (_workloads.TryGetValue(workloadId) is not (WorkloadDefinition workload, WorkloadManifest manifest)) { // Not a recognized workload @@ -721,6 +743,7 @@ private bool IsWorkloadPlatformCompatible(WorkloadDefinition workload, WorkloadM public string GetManifestVersion(string manifestId) { + InitializeManifests(); if (_manifests.TryGetValue(manifestId, out var value)) { return value.manifest.Version; @@ -728,7 +751,11 @@ public string GetManifestVersion(string manifestId) throw new Exception($"Manifest with id {manifestId} does not exist."); } - public IEnumerable GetInstalledManifests() => _manifests.Select(t => t.Value.info); + public IEnumerable GetInstalledManifests() + { + InitializeManifests(); + return _manifests.Select(t => t.Value.info); + } private class EmptyWorkloadManifestProvider : IWorkloadManifestProvider { @@ -739,7 +766,7 @@ public EmptyWorkloadManifestProvider(string sdkFeatureBand) _sdkFeatureBand = sdkFeatureBand; } - public void RefreshWorkloadManifests(bool error = false) { } + public void RefreshWorkloadManifests() { } public Dictionary GetAvailableWorkloadSets() => new(); public IEnumerable GetManifests() => Enumerable.Empty(); public string GetSdkFeatureBand() => _sdkFeatureBand; diff --git a/src/Tests/Microsoft.NET.Sdk.WorkloadManifestReader.Tests/FakeManifestProvider.cs b/src/Tests/Microsoft.NET.Sdk.WorkloadManifestReader.Tests/FakeManifestProvider.cs index d05add9219af..7c8fa003a368 100644 --- a/src/Tests/Microsoft.NET.Sdk.WorkloadManifestReader.Tests/FakeManifestProvider.cs +++ b/src/Tests/Microsoft.NET.Sdk.WorkloadManifestReader.Tests/FakeManifestProvider.cs @@ -20,7 +20,7 @@ public FakeManifestProvider(params (string manifest, string? localizationCatalog _filePaths = filePaths; } - public void RefreshWorkloadManifests(bool error = false) { } + public void RefreshWorkloadManifests() { } public IEnumerable GetManifests() { @@ -49,7 +49,7 @@ internal class InMemoryFakeManifestProvider : IWorkloadManifestProvider, IEnumer public void Add(string id, string content) => _manifests.Add((id, Encoding.UTF8.GetBytes(content))); - public void RefreshWorkloadManifests(bool error = false) { } + public void RefreshWorkloadManifests() { } public IEnumerable GetManifests() => _manifests.Select(m => new ReadableWorkloadManifest( diff --git a/src/Tests/Microsoft.NET.Sdk.WorkloadManifestReader.Tests/SdkDirectoryWorkloadManifestProviderTests.cs b/src/Tests/Microsoft.NET.Sdk.WorkloadManifestReader.Tests/SdkDirectoryWorkloadManifestProviderTests.cs index dee5914b1304..44bf3f961184 100644 --- a/src/Tests/Microsoft.NET.Sdk.WorkloadManifestReader.Tests/SdkDirectoryWorkloadManifestProviderTests.cs +++ b/src/Tests/Microsoft.NET.Sdk.WorkloadManifestReader.Tests/SdkDirectoryWorkloadManifestProviderTests.cs @@ -526,6 +526,36 @@ var sdkDirectoryWorkloadManifestProvider .BeEquivalentTo("ios: 11.0.2/8.0.100"); } + [Fact] + public void ItFailsIfWorkloadSetFromGlobalJsonIsNotInstalled() + { + Initialize("8.0.200"); + + string? globalJsonPath = Path.Combine(_testDirectory, "global.json"); + File.WriteAllText(globalJsonPath, """ + { + "sdk": { + "version": "8.0.200", + "workloadVersion": "8.0.201" + }, + "msbuild-sdks": { + "Microsoft.DotNet.Arcade.Sdk": "7.0.0-beta.23254.2", + } + } + """); + + CreateMockManifest(_manifestRoot, "8.0.200", "ios", "12.0.1", true); + + CreateMockWorkloadSet(_manifestRoot, "8.0.200", "8.0.202", """ +{ + "ios": "12.0.1/8.0.200" +} +"""); + + var ex = Assert.Throws(() => new SdkDirectoryWorkloadManifestProvider(sdkRootPath: _fakeDotnetRootDirectory, sdkVersion: "8.0.200", userProfileDir: null, globalJsonPath: globalJsonPath)); + ex.Message.Should().Be(string.Format(Strings.WorkloadVersionFromGlobalJsonNotFound, "8.0.201", globalJsonPath)); + } + [Fact] public void ItFailsIfGlobalJsonIsMalformed() { @@ -588,6 +618,40 @@ var sdkDirectoryWorkloadManifestProvider .BeEquivalentTo("ios: 11.0.2/8.0.100"); } + [Fact] + public void ItFailsIfWorkloadSetFromInstallStateIsNotInstalled() + { + Initialize("8.0.200"); + + CreateMockManifest(_manifestRoot, "8.0.100", "ios", "11.0.1", true); + CreateMockManifest(_manifestRoot, "8.0.100", "ios", "11.0.2", true); + CreateMockManifest(_manifestRoot, "8.0.200", "ios", "12.0.1", true); + + CreateMockWorkloadSet(_manifestRoot, "8.0.200", "8.0.201", """ +{ + "ios": "11.0.2/8.0.100" +} +"""); + + CreateMockWorkloadSet(_manifestRoot, "8.0.200", "8.0.202", """ +{ + "ios": "12.0.1/8.0.200" +} +"""); + var installStatePath = CreateMockInstallState("8.0.200", + """ + { + "workloadVersion": "8.0.203" + } + """); + + + var ex = Assert.Throws( + () => new SdkDirectoryWorkloadManifestProvider(sdkRootPath: _fakeDotnetRootDirectory, sdkVersion: "8.0.200", userProfileDir: null, globalJsonPath: null)); + + ex.Message.Should().Be(string.Format(Strings.WorkloadVersionFromInstallStateNotFound, "8.0.203", installStatePath)); + } + [Fact] public void ItFailsIfManifestFromWorkloadSetFromInstallStateIsNotInstalled() { diff --git a/src/Tests/dotnet-workload-install.Tests/MockManifestProvider.cs b/src/Tests/dotnet-workload-install.Tests/MockManifestProvider.cs index cbae092ee31d..935fb9addfe8 100644 --- a/src/Tests/dotnet-workload-install.Tests/MockManifestProvider.cs +++ b/src/Tests/dotnet-workload-install.Tests/MockManifestProvider.cs @@ -29,7 +29,7 @@ public MockManifestProvider(params (string name, string path, string featureBand public Dictionary GetAvailableWorkloadSets() => new(); - public void RefreshWorkloadManifests(bool error = false) { } + public void RefreshWorkloadManifests() { } public IEnumerable GetManifests() { From 73f55634ccad1ddfbb46ba8e62a7450992af9d2f Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Fri, 5 Apr 2024 20:53:00 +0000 Subject: [PATCH 526/577] [release/8.0.3xx] Update dependencies from dotnet/fsharp (#39987) [release/8.0.3xx] Update dependencies from dotnet/fsharp --- eng/Version.Details.xml | 8 ++++---- eng/Versions.props | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index a882a7d23ba6..42eac2bc681a 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -64,13 +64,13 @@ dbf652edbedb4e6c612a79cc6907d211c74329d6 - + https://github.com/dotnet/fsharp - 4a394198efadc455334ae272954ece372aea4de2 + b2b9c946d36e8174c4a7d8e675d2c65f9f2a47c9 - + https://github.com/dotnet/fsharp - 4a394198efadc455334ae272954ece372aea4de2 + b2b9c946d36e8174c4a7d8e675d2c65f9f2a47c9 diff --git a/eng/Versions.props b/eng/Versions.props index a005cef4966d..2150c534dab5 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -150,7 +150,7 @@ - 12.8.300-beta.24175.1 + 12.8.300-beta.24205.1 From 7ff5f93126e96a5c0a0a470639f70d69a390cd75 Mon Sep 17 00:00:00 2001 From: Forgind <12969783+Forgind@users.noreply.github.com> Date: Fri, 5 Apr 2024 16:23:43 -0700 Subject: [PATCH 527/577] More exemptions in install/udate --- .../commands/InstallingWorkloadCommand.cs | 2 +- .../install/WorkloadManifestUpdater.cs | 2 +- .../IWorkloadManifestProvider.cs | 6 ++--- .../IWorkloadResolver.cs | 4 +-- .../SdkDirectoryWorkloadManifestProvider.cs | 27 ++++++++++--------- .../TempDirectoryWorkloadManifestProvider.cs | 6 ++--- .../WorkloadResolver.cs | 20 +++++++------- .../FakeManifestProvider.cs | 12 ++++----- .../MockManifestProvider.cs | 6 ++--- .../MockWorkloadResolver.cs | 4 +-- 10 files changed, 46 insertions(+), 43 deletions(-) diff --git a/src/Cli/dotnet/commands/InstallingWorkloadCommand.cs b/src/Cli/dotnet/commands/InstallingWorkloadCommand.cs index ad20210f9b62..742fb4618647 100644 --- a/src/Cli/dotnet/commands/InstallingWorkloadCommand.cs +++ b/src/Cli/dotnet/commands/InstallingWorkloadCommand.cs @@ -142,7 +142,7 @@ public IEnumerable InstallWorkloadSet(ITransactionContext private void PrintWorkloadSetTransition(string newVersion) { - var currentVersion = _workloadResolver.GetWorkloadVersion(); + var currentVersion = _workloadResolver.GetWorkloadVersion(error: false); if (currentVersion == null) { Reporter.WriteLine(string.Format(Strings.NewWorkloadSet, newVersion)); diff --git a/src/Cli/dotnet/commands/dotnet-workload/install/WorkloadManifestUpdater.cs b/src/Cli/dotnet/commands/dotnet-workload/install/WorkloadManifestUpdater.cs index bb91d359cdab..ffd9e3949d9f 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/install/WorkloadManifestUpdater.cs +++ b/src/Cli/dotnet/commands/dotnet-workload/install/WorkloadManifestUpdater.cs @@ -301,7 +301,7 @@ public async Task> GetManifestPackageDownloadsAsyn return downloads; } - private IEnumerable GetInstalledManifestIds() => _workloadResolver.GetInstalledManifests().Select(manifest => new ManifestId(manifest.Id)); + private IEnumerable GetInstalledManifestIds() => _workloadResolver.GetInstalledManifests(error: false).Select(manifest => new ManifestId(manifest.Id)); private async Task UpdateManifestWithVersionAsync(string id, bool includePreviews, SdkFeatureBand band, NuGetVersion packageVersion = null, DirectoryPath? offlineCache = null) { diff --git a/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/IWorkloadManifestProvider.cs b/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/IWorkloadManifestProvider.cs index f6a5e9676624..a396a0a35204 100644 --- a/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/IWorkloadManifestProvider.cs +++ b/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/IWorkloadManifestProvider.cs @@ -9,12 +9,12 @@ namespace Microsoft.NET.Sdk.WorkloadManifestReader ///

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 z zZ9FIOh_;$5p+Wx~TSq1pV2Rh^7$6|&oAET;;2}uALECySz_-{?m<`dxclaN)X>M){ zQg1r$1yH=;uE%z^GZV*snUx#tw)b-PeQxOTOz}L&5VFDV8`t&q?{e|nM2*jf&X9~k z?3$!CoTy2a*bYW(LrSli;h#=C;UlJW$o)HvO5-qCB`4nb0{G)8%(=kFQltxJ5dcg= zFacm9VX?9F&ZvluxuLlX0(@?$gqr07DO8|j`&iB1&un}T*5o8;9vweEkyP#8jZZe8 z=(+Wp!6QZg-auA#@(E66Uh;m%SbFoW9Ry-br`SaaskQVk!fg-uUao;2QWZA;-RyQ{ z+U?-w%x*tF{26VxBOf^@xgmp_M&&z6h)D(RK@+krn+p+6^q`>U6_`z_~0D-F_pma^=fWwz~k1G(rL?Jqbu&qumgjmKyxFyhHj z@ML6Ui5hRllTg!%K7{ee*z$j^bTer1z5V?byL!x4>4|#)NBmc?2Llz6;`vO_ZTwP@ zyYG+XhQ`b126|SX6`|S80541`l0ueMFYu%u3Qw`7v^jX}Vs>#b&#_Tt%CwJ7WU*Rp z0vBgs?uD4W{WN-RPeLwve;3L@9uZFF%xo_gK8!c1_3+x?)uaoD>Ud!7>26#?V zDg@2YshL#DbC0H6uceazMBN#D_%OmQ5zUDzYlX}=^ZyPjk`NN^1WswSQ$RF_PtZDE zWuz*eLD=qgrEwku;JUtm;U#PX4S(DX`wSdI+R^Kob=UQq0T!D`pK|i->h64J|3u=G zR&{|$>N5h)cq}$)uIN`cr+;z*K7pAmt85RbWYdH^FqyO#qyKKK_hizsTmc@&b1~S* zq}5~fL?kKb7cv19HJ{!0qRh0d_Si#k<-m}0;d^~8N%Q0hH2eQ>zCCHsK)9>jP&ph zndd)*8ThI%G53;|BS*wag&>a{FClr`|MQH$m)qk(zDy~OvY(iY1o(HCD#PK^{CWJ1 zMNnT624b82U1uvHUxS1?9IoQjL>YMnwU7o_5int!A0po~l5Oi1{9IP-L{$DHHU(ky zir-+jS7`ytj};bR+m3T&48k^u%7o$b#b5A~zV)Ebxd{+Jhev|F^K#|1nY!_T2i+l;Ms+DF`9iLs_bDvPbD%~1z z1O$WyJ$7{dTFdY~Zn)llbj5S|U;X#B(?m47Ezs$6G(Geu{6cy2?VYWld}%T6lb<4o zf;x+p&pDf6blX?ar1_sP5|S(X*dQS}erm(EKnpXNO}J?#7TcNck$K%u!HPcEFVsTc zqK0k_NFszGTy<@AEahErpD>R4kmBJX7|wV5xQYIPkz#3$rKyon|HASK74)mtos1F* z+NFe5))Z>=>)HDKf(5h?Oft?KHW7TszJKsnHp`SsZ3gHQ&5kIxz~c?{R1o(l!sAe{ zP%-JWt!3otDw(Qlc7-ass&xQ0fWXsA2jWz(HED+qv@S26f6+4vRDejytG)4Tgt za-TCQ?p7}d%Jc9i!R)+0egE}H?dPf^%3W^2MzcOsv#S>_JT6~2B`#Yp?n#S5{~T)E zr&>S`Yy*OLq%60=_JeprcIgYkW{V49_H^rZnyI?_)F&fARbnl?@9j~H3OsIZSAy); zZwl#ilhC!4>dRsZFOf_Xbsm0Mz#Yq540d;~;(ixE@zf!A)O&)Dvmp)m#H@#UNA3o@ zQ`=jC4=dEjQ&HQmlJB(iexxgX4Wt9UWmLOY>U<@RXK;&mtN^zvf+<2)j0N~suWG?rwJ{HWB2B~0CB zj`?FU-UtH-{RoQ(U=OizuV)${0B1Zw>ehiK*$~ib$bwekJL@dxS(f1m34{8`1aq+U zvjdn|q3;5`?XGrNwOZ^!`MUHa5~(A&QmGib8ttDD489SbC=PFJ>^VZNZAzv&0f-!q z<>w?6M&!E<*Q-J{{s!9~N-_{h2W{bgBK~=sPD&!U@McTuZ%71xl-+(J1_-}gUz*qf zd|*&3Z*I3*jE0Q{?XSkYg+y9mg#nb@qV^Bye2%5ikHw)zlCehgqxLFmjaVcMpzR*A-}rGKUWhv)&cEA;&Q9P}>MX{6qt%ci_qwfRuO_%A(eR(J z3B;=R1%Tpr2z!1&IPN1Sdx3~?mI&aNz<>Qxs`1e-<+SAdqdKUH;r+P_O3pnYdqw^K zz5wV<1Pm*n-pTGR_7nVXwe zkum)5?Uq8#o4@=ak*x%f_Ha0CHCUgv+w30`*=?T0h~>*ehN2j4f17GuIF@9~Tn?;q zuh}_Y3D&Zp*I4`x1t#3>$~{Tja@Gk|n@@QvPD`EpjPN{G^6QSYqv4@VyNC51&ft?k zRCV+{U>|Q>=s=vOfaIxiRH%p&sIuis39zx6U#OV!KPSo+J7tif&sdQEp>p_?J4U?Z z$k^pbs|!}ecQ}1T8^7;8D;N0J*cD4GM&TR&Y~7(!HSTa6 za-E<F z*dfLT_sKWU=sOy7SE>aNL)|&KJIp*|RjpsB&~_ePOGaE}$gw^bKtnm>go6un=Q$tE zrIr7>@q$}MjaV=OmqzOG*nOK3!Jm2WMiO8Xd!`)@^*uvMpb2V55|nHbwR-JH|K?!5 zO49>ne%2ztbT$s0K=iy_|NgW?SHCmmM$Jt-I$w!(rbbf&Y9WGu{Rdc!d}P9&pLvo|?XMt0o0_ zW&QoA&8m|`H0)jqAxk9-^qB~urn^&-XBS)=U*fRYlOg!`E9xozDfQrKUtZlQ$AbKnDix24sV|R#4c`{O%s}JwPepBxbQ1J0+Mj+1 z0V{7liLdmwibtr4TJo(1hTlN@~$QDrK*;%@hCyqZ5>WalWiK8eBT7iUHV?J zBNSgi$R0kPR@?p)71rGZ8v_3fPi>`t&ZK>UaSogSDqqGv|hzK4%e>dc>KxGW13+T$BFSN>#J?8C>-y%8&TRHZMb33pOij?3uOzHTHhMvh{X(^zfF zrE=#59i8P3P2YBjq2axT@G`Fze09Uo29cl2wR8}x*0EZcny6QP1Q%gfN~*R}g8zt# zutz_%%t?g;GSu%rx1XbCD&@%z)6){d-D#9Y#QWNJsHB@k(&11%i)n9hgSJp>6U`R< z@bc4|TZ+>SefWgBt4bE}nMa?6?`;Z!;*7MdCQPo5$Q&f#hgj|c@2vZ$CHUpQvXD(f z^4k3A4jqo==N*pI9U#k`acP9}ONY*L5}T|XYh3%Y#to%s=VOLe*{7SHPHacU^E+Dd zp8abUTbA+1bx`1f@n96w;)hs%@uOEu23`8`G&w$PiO3U&=UIK^mcw^xoHAzz6VfH z4|V-1H0tXUQ}D8ilk?%btgV)Z zTWG!~6Qs4{8k}T-E2c&el}+XG;hlyY2a~p&+f&8?gAj>ybgy~i)AybrwAZ1o_Sq$?wOxc%q`V2ak)u|-IRGs~ zpq;p?#NKZ@MiBZYWWRkbbd2{1oW}kHRL=K`!w>fen{fBIoo}0)2~2X2RhEZd#e3*~ zMO`k<3@tgq9a|Bf8I;lzy4hsOA?9)zsLOKm>2L}rLDj0OzRahwv6*G8z-)X6D1i6m zB17GKO|*4|P<5WRGXjv#D~+n62VSP*ePP+b&**Z++NjkM3TBMcOnG4W*4gCD@%AVY{dZ&!?tzED;p7&TkLM?wJWcC?p{5G2-Kj zAqrQ@4jA-hfB}x>6?Qo0TyRc}psj!0^c=8XR%_a=3@ksgUg2UaGipP8gr{zx?Pjoa zyh}zD`Ua<(U$f$!uONwRZ;hZ5l@(BtMcYj!$<%#wlyMgAb++H`d#|B8640y$$PG1V zUjgJJ{^t^4;rHpAp}ng%`vP6PX!0yynDk|T(@SWT)v?2h42K`>QGazSp;#hCr0MW4oaNQ8%-dt>VfNh#VkfJ{C;S!56 zXVHdM+O3HAYxnxTl}y%A{f0*nvlv@V$VnnE2Tc-*&UvdVj6MMg%^(5n9Db*CIOKO{ zbGY>19$fP~s;w#^IUMyg##C_ZzqA{{GBGhXTlOFfSI|uHz88{+mWQ0>2y-ymlf;mb zb*l2)8uTg(k;z2ag0zS-GaMFUJ>-Q9ErV~$^h`L_!kXAD-VQc0_euYlPJxh0T3zsQ zTn9~W5Hhe}#j{^+v8>kbHFC0Gfr;rtaida}kd)|zmfr>ax`A>K5Fec5CH~D|v#y!C ze&M<|ZgTs)ND=SW)00$iD}Yfu+3?rNR_;0PD2z&k(I>b)AbC+z^)3IT{zL779Gbgi zL2WE!HH=ZrRq>^`ANj?4c-VJL5E_UgzrrbzQi#7*FtbPn#ucBoD zX7B0sB8r?SIN^}e^@77hg-Py;<^c^K@Txs(#c~V+&c%*7jcTj!Aqb9cz0z%c+NE~e z8V<&4dq5G2b{2rkvNy;V**CGuX-(JE*vNFL0!2F-1{{N{U{;i`o;|JdIau4;QKZIDYrF}YwMWi!(o(MA#h z&O%`k6|vwcBF}gmU|?IUh9n{yDHDlLs&Q-uEgj3 zzmXCjHP92J7i+Fr>D|;o$K}fg%;u zfvDuD!P82CNwyRiVsN$^pa+oLd|_j>TEo_FJxHi{an_RQx}`ih>3E$xH%XJIu#l&K z5gLN%eBb0P!6-d8PNB7r)i@v(`=tS=yiGG$Uz$lN69!d6o^@+bEXel)#iMgD+zGz= zDDPf)Ul=}@YQ>H5o0QOr)oFt>r_#e2tzB&db3?RLx2+rfI7jUK-J@w|>HZr83;fPSuAVv4OSsB-&!(0L{-ElD@}oOk)M18R&(1 zkJ0v)5saUP5YwBUtPh;z*q@Q6o~BpoMwii9!QEr{{!)oZ8MINQ2$cU`A=~;GEWMJs zsJwOkl6BE2So1ksONI0KA&SKKb1w5b%ZB9`eU|r0)g}i5AXCt$GUE z2^2yGk3uRzH@$c~+f}T7`|u%m2k-Oc!xQP56;;@mV2q?aoP zowJ)g7G0~{x@NC|5M-V}nG3DEAIk^q`g_p|DPru-y#m6}fC+3AdYXPcRp00%#f+~3 zT}?mf;TnYS*U4;-bhVv3F2s~9(Y#cN%1o z9zUVu0z=u;dqy}I=_-(Wq;s1A(Q*$wSm7;)?+F*1f`(Y~goDe&6x(&S6k2T<+sVp^ ze=)+??eqtnuQzy;uquq8wPnVOvh3e2vl&lyx6IRsI6yqbt+*MtM*zz=rPU-xB zN?ZS(h&eT{1Df5@mC!!ja({A1uUu5H(MJzH6rFt!aqu8J?ruckk9BBg9VjD=S(b8}|3n z;Zwa1=r>B?_AD10Hber+K)3QaaLvpC#al2JiT6=rHeL)!AWOfthb&J)NGwSHSZl+y zuxMr6s+G%^k}*9XPbpYTxDf$)<4b-Nj9?;&x zsu*FP1PJt8Z_Wp#9Csljn5($tfuCDOFd4VjlO67awXY83QHDn45Z$d;6mVlj;~Q0v z23paqq3xUQi+c{vVnH+zjkjNKv;*8lD?n#whogiuk-As3{y;G=CNdsb`x?j$%U)bS zGBX+`pr_O(`z0JQFlm5Vqr#5hI%0_xS#40CcQfAXaFpf2Us;w_%}{`=NIeqpuZA!S zkS$c0tZ?Gri;+x=xj%8%KMY9B6m-@F^TuL<{$cysfZsWE%e8fc(qZ)|BkP6)DxK*s zX6vWb?u8B5oEfM#9Ei)xdXs^Sf{Vj3#OCt*fR_foV&2R4|f*zpS+XavlIhwa}UftNy0n7g!`bynqSB zDRN%UGt~M3pZGn{pJ`~WijdZS+fyeQ{6i49-U{rv{1$>53vMTCppq&nG}CvW_R9^r zU7j0g&(wrradd1LzW1BBI1?R+kYm1sS;JNrhpZ?j0av6&+Ik$f{tmA#MFY>m1E z_o@e#aG)Ys-nbWc^MP78H?Q-lB8tn+w}!u(4$}bOUEO7Yr(U>5*banD!ysZFp*GUUM%f%=Oo<5_^2k?g$U>?-9sj z7Z}UrjSPfDtii=5s*4cb*Hd_h+M%|8p`~A#?Xwh2$mpg2KC=?)5`;-r6gn}rDwupD zEg0Ky&Rh{>$oN{!dX!;&Vk-4p8{~86=mre|q=x?QO4us<7dAX5);>{1MJz(CK;hLkwkO{Y@T^w4!14%t`$q4yP+bMjd~#M zFBZn<4N$DrmVt`K9BwBzCl#xHvBJul$6@f}XCU%Ecq-t~>e4r;=NxM}dE1C|^nh4% z;q6%E`=i?9>_oYLaslvZvW$t2Qt>MYrU#~U_YB`2t~mPkhvswGs2He#B`(_nb~>bb z0pBQ_XfcAoJ>viykZel>CZMaCaGnXl0$jkL*n7JJd+UHV~P zFN4cZ<&I}c@LYFOz9x@spnZ>_oV3l!c@Rv|U5P>_z5T5#8oZ7fNO}&(+W6z3avErpq3NCl(H;s8mKx^Z|VbO#+E zX&eJ|KFYrD5<~_52YJ?e9A%yJ1XjU}G3*0i7+n$(c1+S^+loeYN-Y1HGgGr8C&N-O{7S@?75cTz1c(fsjaP7XCg6c z-{FQKa|?0r83=4txFm^7+RBJjgx7xH-m3*`cs?@^8#`jt!%v55KjIm8zccMR6^Lav z1;^q6O7{6P47=@G5TFu~7g*se2ToZ62EgzHPSDH_AtZ7mk+p84x>OBs_4>?BgX{&3 zb78^gxET)0=2EyUnVlMEby8kVAsHoKh^`A__f8Nc!uzB%Zd1yqP-rzH8t6bF^!A?% zu(+lKwi>$Tmi4%b$lJ|kQM6}N^}gw2fsHuSK0|9)u^LG4WxrsSFI@83%))@~jdV?v zc*tcLLAg=@@-B8OtTINb9T_ZtDRDt`Xq|fM;7y@w*{MmxLwJ6kc3EI!c)P+ifyz@x zWvDX#>NWD67f82u-rw9^1HNS|YLo0|+C*Ld>zC`Vz4^>3!bNR3*D60k^xd1|!VW4Q z6lztORiY|TxQYpbTAl=tmtCtAPz!yvo(gV%l?5fnP7aiJba&#@ah&`hD)DUM zd-hmla~K?!)i&5N%XUDQVHVqu7)^dJ;(0P=U2j>{%-bQ zZ&{1iDEzbOhoOe|B!T0Q>Vmr={LT+p5+6eHM+ab?>O!^ESJ>jjEZLF!VP0L1id0z@ zM^LFp3#z%RaquSRiwe+IhkR@~{(XeIz{6Q4-EC)q+}Np`i0SK}4Ws=(zSB;YwyuBs z=`di`IaNu~)hP;OO2HbXy($U0%(lN-CK+P4S%KJUiRN0Ka5_(xYSkc8HdoGQI)EUh zUA*u>9_ib6_^q{`LH2@yT1?$G;gHnU%4k;fX^@NrA`JmFdJV|^@tO)yQP!76bPXnP z0)oty_Oa$Zs$`eo5_Q*dq^ z5TG%52gx|vE)i!pzW(c}ohzp88ZaLHKgO@F^ID6k+AQVueL)F}HN%U|r8MSwb0QlwWJbtZgal?^0&+zWQLjXn9J>ce|{ zx5T28DpU!RgT)cGUQvjyj#m29Q{eOKQZGDSdeyLz1t1X!chy>X9bafkkD5OmS zzx`scUdOjz!`G@v>c(348jQ_f_L1-+M@H0mJTWv&pr=(UUKF0L+zhW5dSHR8Qzax4 zm@d2KR}WnwZy z*~JR5ylKU0VxDnzQj4egZ!BEnq*h*V5lxC8cr?w#G6bpqaD}__QfV^GMLIwaSdc=V z3fgiF4f{rlgpUqS|9T?`fjjl`ZM2@7hld9V88>5#k;ZqKo+eYo6I542v^p5QWNCxN_+eryIUf&-hYu)#zua zY7%6JvZnQKHY~*C5MjUuepo~hVg8SLet=t07#aDo+{i^eiUUH*O*s%Y(GX*kK7n+D z)+7NnjiEiQ1m~j`VFFuepc=_P*RI6?GYJd=m7Lv&9+HAf0F$c#?$pp?&i-8z@ye`u zL(5z?%t7El4lLNW@# zA%XUGKAHHzAu$OYa=+$0N&qVegrfs4qu@L9+!DS)4g9B>-zAd(1Qehy5HCW0UJ_U# zyB*L>#GMk4Wih{+@*g|H{O?BJ34)imx4yY~c$sQt!1u25Gr5ots}-_c044~bX5H~# zt!AfixHu0)<6@x?E@DvxxQ6AzeI1psGz*LDAM+BE-}y3+_ahqM zc-HRGboSpsCE9pG;t3z({p|ncpX^CoB6)fFpAY(`rs9C)mQW@o;t$j66alVFyKg-U zN1T;~L;1(2L&NVr$mDSc>3^=Ot0M=^cd>`Um;P8m+NcE}!Y*Yv%xWYJW#9e(*D#!= z`%~!oiFA*RVbs^N14jBzF61*AV5I;5K9evK;jr{sY19{nkT}^w`aAr1r~=H|$*`L+ zO6bpgN8VomTw{L^S>aHKfhWAG#s^gczAG2W-v7|>7JTG zd3=0asL}@oRPI=C&KC6mAn{HD?_oYA0DsF&icCqgY78paD9i#PM=?s==x2uq4*1T+@86@sa#9d9yeJGOLHr&zE(4TbGtLoDAkCU4fUQ-z z43B|rt=b5}xq&4m#>Yf;2&8M$mdGL>g{A%n{_v6ShzJS->w0`-bs+`K-vsBLA^E2( zfxz7<*y3k=eYTX(lgf9<8nlkR;*oggo6n(UY-hlH6Fz>sSA;cB9qQWw1imeX!#5H< za59BO0wVC1-$W8ra1j52c(ys?#65i6hJaRwPxR^_&}Jz1b;ie95mF?e$Sz>;?bqVW z_mY9<3FjBmxpO_K*u#2XT8B<7P{QLjZ18bP^Fa&+t|*B_NO_G<-JpSXdp1ZYfSS}< zrP26fkw1lCU7LbP&%#^rpHYY_OKy`MMJXu%p5LA(@A&QVe{J*`jQ~8_+^q|tF6{l; z!0jN?i$K3eQ8$}aL3VM#Yh=BYOg#o48+?{|tHwz1eq(p1fo|{+2XQVAjtvQ^B+=rk zt1lw$QejE#?Fc1Oin!DxH8r`j&TA8*V(N2=1uyGg zXyM0j_Nv15G^KBaB03mVXjnty zgDG=ygn)FiAfSr&I1OoZED#69V0oIiYfGRyHs z9IZW7ecqimj$vrT4i?`mxuhii!CAG7cx^cin>RzL-IiEnNImFPx2`R8wE;Tc^OZu6{X$8WX7)*o&)V|nMXz3bz+D&JKXqT!HyQUupO zCaIYl%)6CT!eOaJAm=Y)Yo7eIr<=m%-20_hNX;1f=ROo7_U713B9)s2Nr67;85a-V zJk8klWP*XG3^s*}aoo0Zzy5p<59$W?q;qhriBCxCYgY}DoYdF-(_c9LhbUb-;ddaz zE%BE2HKR){Up--4sNYW-BdDvm;evjN`~@RY@s#1hc?NT4t)(yqO4!9k&cPvr@7L%g zMLZcItsP9#p%2zF6^;1rO+tU5Q=Kw~d`%Tx7cLzwB>Xp*zSGKp8ys#X_sqywm&znL z5&J~Q5r}lNK!GA|_sV!j5qM(BjDxv-PYAR!*)9UF-hqlAy^i;mg}kcx&I9$!abbqo zgs?1J#6qEoV&sBp`3I=}4^WhRMLh?{xSm7x%%R?w@7T;TzG+s&{NfV0Qz3r^Pyqnn zTL-$h3D}vX281Gs9$1%R(T`Ykj&4>8A>n0#;Inp#l||$HlYuz}Em;p-DS%PXK^JX1!W5;D;0C#nnIgzoc z4Q%NIK_$ItNAQ213cjZj`aLLh+nprJd$CM^a&b_!zSYs@X*d#vozmtGX)?|YnMa)& zHZ&R(C(X?j6-;{9MaKq?oNHuM2(~#C;oa!7L-50qIlhmer_vH4BxVKDa`*nTwMy57 zAZ~VxH>TAp97BXBq=XDt5FMnQK~L$BQlSKW{ymm{-#++4_dX%HP_vwWk>?+&S2I!2 zshGb9OC1|PD8jO0DQPM-ssL{(o*4q$KNk6kbF}x-(y~Bk*FK8yr9+~39&Z2RbZT9z z;{XYK;Xdf8PQ!@RSMVmRbm;h#1zzwM|4C=z@QA0MuNi-*cqD$+iHFfB#Ne(o)~YM< zZAJ@J-f*&g>T<<;XrDHJuW9pU*J3mWhxsS5v8JdOj5W73)W{8L4~`lOR+HCy{N%uH zyHO{0DU558B3qBG4t~U*d;VR6=q6G+9hSa~6U%D7A++a;5@_jB-5gFAoLXmDy}WQt z124qw_eb8YuU840GGWlD1uiOt~P zcbpHLbqFO;>29ly)3)JwV8EkV%sJ<2!wpTQ?WCzkOq=*|PHpm98a!*ttG|OC(nzMeqQ;G-(c_sb zovwq$=tE*ssUB4a*`U`=ubJ(8PRA2`AmOkSq)7c;&tYAe10@cmA< zb|VEJ4{D1!WO$pltL{a)J%ybAEur>@2WXH*b&pY$Tbp_xDqyJv>e7HmB@ zLqEJaF}r8OmGySGqg}e5lqPQba7p6`yP!^Y${9XFgz|zA4uUTbVKp)8 z`3zkqA3@E%{cg`ZnQVQV*RGY0ZjdlT&RRb(WcLOP8J zDQdO-SaIR>k+*|hwg>dzG8H+nRR}~>-62IWf&kwqZIUF6T(0n2OmMqrF#mi2Vg!!Y ze}V7G=yA>0*o3WjS7VR$tj;~c9Nt$)geCJ9qd{Qu4A>sHbX@9un!(ym*NDLHmp|F~9U#ebyuTGz?E?s}Sv`S+< zh2MI$Jx7Z^0CBp}?z@szFi-+ta>-R@=G{~qKIw4qE`Zj#e9dWjz&RErxwz~&<~Z%@b;+yNdpH=X&ZFe{lSP>i zZ!Y{76($ONUt8Tg`TEge9RX{rNIzVf^IOQ-+ZC68I z^2FVGt#t&?p(2DSex-et`CNk%pw}UYN?nA|c?bHaKk^wBuLC=x@#p26;3kM29XKgF zXtxvqVwApZqQw%o_J|j~oRYvlG#&VM$P@bW^se}$ z9BwTPF8uMv4~2Fos}XN9uG3yQWl*bSSE$q28^(jHnEfkfRi|y0p@Ror50|rmw`Xx& zjb$r4-ISQ0pCKeDm=Z|r-M>?e{b1=1_cK~3*A6NhP}!<&sNrKLpYERo%O8zkJ6-J%|dd2)Tsm*o3LnPmgEB>*SY^q@x$1J=o~-siN} zcdDt7-9r`c2-* zCdK9g!fia#Cdc&q%m!@Dr8u2Q?%g8IUKO@e*1O+Nch1(Wf!Oz~|c^fskudg#CchNaJLXH6F_YD{(xuTZ^L8{px;C+pXPA1BYeiM zHymPv{L#<|;(r|}m0HhqVm}wUvO9|8D+12}e`M4F{Li^D`U|>=XzarRKYDh}y z%MOVdf|pAXET*`M)B{1qRw+Xu)9JtZ*r`p zIH5Ep|rIw zzgU4`(&D{b${zGl4!pd^wuZCiC1}wGv-^U?&-)G23ysqCq{r+Oi%Kz<?XH)npzT5^U!?KY90!|I?qPR!c&q0fMp##S}V$h42dot`>+T3RMQ% z5q+$T8vn{p*nxif0d;)q6kW~W0ye5D2bX|OZ~p%1ImnKRRyRn%tm$81i>!88^hgN*{|!z zSTAq%$M{vb-P6=CA$6qFXPcsIB(vfRk+pyQnf*ATGZuDXClwSWAwwdca-|zMiF~0> z4Aay0EO?GyV z%RrJRPDjHdmnec}*oLeEQjJeSHYO;!(k23?7bvx=tbSL^e83LJEIhem`aVT(28#i0 z3+nBUQ6l^)eD>BlZP0mKhuxpqz;i}w>Nw2@o!0%SpD+zhXHv299C1TjN#eg_Al~7Z z*}1f_Ik8oAt0bfGgxv}|%y7~qmQp`dGxEfkXZOq`EVx~hk#IQnPsEoC56+A;JJz2y z1ZWn+B9tq1J>qLt&G5hkI1!6jHOC>V#N;UJl|~U}eSM^J&-_M^5BU)`l(F95{}{5H zrs%c@4Vx4a{a?tIsAoX*k)5u7{ld|_&nI;Cuwub*H)(ZCYo9hO^_3;v#@~dwB70Ga znkC&D(xgP|w67?O)>Y`NJa!Z7TR;n6dfm28Dg6kTX*zPVv<-$*W zeS6II3)zir zf_rdxhd_|v?jGEo;O?#o65Q>ZkiGUg=REiFhhOvU?&_}Ysxe9qjn2*nVC07-K7ksuGtPl}aeTWKe)#538SS7%ewl}=B z5Is2F_g6+lZwE`#i-4U>(lX({T++NO2`$BPya7`)gRe-|$|nNNi=Lyeuz>kw0QDsN z24wXpXBFcTr)e7OlXZ5(liZHKlY9)&gq7$z20sqLZk$GQPu!FmMOX8=FqI9iis!0T zBA|V*rJ@5_Aa3TlWD<X(V1!ME^m69bWJ6 z^TAorq)}P@FTY8F)J?{@Y|J+chdBEc2>Ln|bQDi~F$T3=DE9{rhxk1fkN%W_UYh$U z!bktI?^M(y55z1+D0qY*dg|(pYKwfEe^5h{N65v3fOenN(B1K3Qif{gKhZ=I(4(nH zHeHX-Af!oATeM^|nDC@GD`3u?fu=*ykA^I$nF)buGoNppn!DrmLd;P3z>H#3Z~_Vy zj8F#4xq4*j8|!JR1XWKVV6(p+yEr-q=(%z|`sbifS9;oj4VQ&~#RM1Z!0zoW3`+_( zd6sh*oF_CdUs>5azzU#hT{k^n+Qzwr5Vprb3HwUydJcg~C>;6|okVVM`cztF*Mj%4 zU1nxiy|~tCdFPslMZ3c-T;NN z5sMIcH^P5x_`l#;GL`UDje~s`4WPqHqtk@Fc&Ul}?Y@7=kuu51G~vh%qdNDt zB)>}}^J!NcufiD@OWly%caNGtf!#dt$=>K>l7CRrP(LlEiC>5)ScMPzBgo3}@Bmuh zsu7|k_Im1l1Hp#$eeF!eT}3dhydZA3Rfz9xE`(As#`H6;^>v-@uk;v_T?dg{taCT8 zzbiE@Nxrw)_{4uHy$AD;eIx`}y5Y>PBbW_%82d^EVqHT21-sNiO<06#9L_uGWAM;Z zyDAR02;<=9t5h0;3b*Wyaa&$A9XOO~9e(@R4Bq}bT~Na;LhR3vP@z2ppIDkerX%)$ z!^Q^VT__H}y<7Siij?4i&r}lCFJUCdk~!@R`TojdlHO=@_`?jCcWj~ziZV2_>9l~%6e${B_SGQ|CK$c`I~}lR1jEtV`p;a zPzm9>?}#41QXcv0uLyOhl!DkVTSNbUEFxm4gEs_srNan*8(yN(?im5#D2TM;Kwf=@ zi8m^P>x#WA+dY*1-=)WzX2D_;bLx9OBQT`#$^md%jAxM-@I}_;8$p5kI}GMYPWHd( ze6Nt#>yE{?T+fx=**_oAum~jx{2&E=HEXj0Kp#fV?!eMt^a{oDAG!pDnfQ$ei5$b; z>I4NpTJMMfiXsx;DLw$-2>pJW7wHrl>V4{PeCR*10IA9U#p(gF$nX`mH5*IodVYFX zd@m?SbfVNaG9s&?r6r=LM})^=B?NSun}TK}e+9&2!EAG1x1h@{>BgKk!u7w*QK;Y2 z>v4_^4TV{0v=0FAU$@k%KyR71JACzR?n)M{(%D7;%J9Zgy>bPvN&k@GU%q^KMY~p^ z8CAgl$1q`TN%7eKcNl=!kP=`@0K4EYKzd4i^RY_+agx4dYxS2TM7`CQ^eoagao|#cGHZhr$!2Nei ze3h7EzkUTXWyl-!!Tre_{KjEXk7OIZft*DpfHZ8)d|@EKzVxw5NG?f%|GPXzN~mOY zT_#5ox4mG}ho2xo14D~I5sx>0DI$YRPG!4*0Cxm`Sbup|KR(|T5D;jz+XQ>QKV$?d zO0~|8M*D~w6Qct3hY?eaQK`#e8#rw|!~p#H<=^!iRQcaHcCf@CLU&3#N3>HGTX z!k+#CwteR~6BsY>xj`Z2xgqBML+gL22s?yW&~u9K!0mS;Ae8;??;_|Rlku?mLC^On zVfaBs;)QJ9NoDqe{Z%jD8s;}b&KVuGpdmyyKmE0q=IAOw0NZ- zKi0$IT_yRW|0Btb<2QyemIqd`Nb&9JIQRg%x2N#R6SBd2K1dUrOX2>96{E%jf7@Pl zX1H&E4_`WU=SmSkz`=v(q4!nlZL{0b(J~ZI@1E)IlW+7drgMFvgSiXZb^eAyB+q56i4Z_7esui*!}xcFDE-J6zV zJqFvbUMD@7BVKnn-7`q%5}7A?iN1SG`)ys7z^$)Sl#?A(Tl20uDuM5~x9{Yg6Zh%^ z2TW5mjNCqjEt6~~Prb{7=IfrUv$UU?BXV2e?l!8aL7q+T$fu@Zkm$qis4$3>iTJ3Z z5~-wlm5`Xzn9NILNgeX?FtugTpL34SNSipSYkzmA)fVhI`rCs7FAvgO7~%B)OJ)MaBwq?*fr` z@61&au`3C0tl=$oGOpSb}+w`@0 zSkOn$G^p!*!C>S&lOMr$9NB=VZ49i)y9?Tdy&+l}x3Gm}Dkj@I9=;C=HivZNfomaM z>$OZ432-VB(E}pfyLP+wnIc4JviFYJN7Wl+XI*4jZHGKH6eGDT=wT3zRo_;CaLZ zRBADu3OxnerczMhDMHk|aLX@85ygZniupHGr*i>B?cSCD#!bIyg@ zn4skglXAV1gt`9QA_OV

public interface IWorkloadManifestProvider { - void RefreshWorkloadManifests(); - IEnumerable GetManifests(); + void RefreshWorkloadManifests(bool error = true); + IEnumerable GetManifests(bool initializeManifests = true); string GetSdkFeatureBand(); - string? GetWorkloadVersion(); + string? GetWorkloadVersion(bool error = true); Dictionary GetAvailableWorkloadSets(); } diff --git a/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/IWorkloadResolver.cs b/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/IWorkloadResolver.cs index 05a86f60d3b5..df44773f4a68 100644 --- a/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/IWorkloadResolver.cs +++ b/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/IWorkloadResolver.cs @@ -17,9 +17,9 @@ public interface IWorkloadResolver IEnumerable GetAvailableWorkloads(); bool IsPlatformIncompatibleWorkload(WorkloadId workloadId); string GetManifestVersion(string manifestId); - IEnumerable GetInstalledManifests(); + IEnumerable GetInstalledManifests(bool error = true); string GetSdkFeatureBand(); - string? GetWorkloadVersion(); + string? GetWorkloadVersion(bool error = true); IEnumerable GetUpdatedWorkloads(WorkloadResolver advertisingManifestResolver, IEnumerable installedWorkloads); WorkloadManifest GetManifestFromWorkload(WorkloadId workloadId); diff --git a/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/SdkDirectoryWorkloadManifestProvider.cs b/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/SdkDirectoryWorkloadManifestProvider.cs index 5d93cc39c90c..13fe69a1e01c 100644 --- a/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/SdkDirectoryWorkloadManifestProvider.cs +++ b/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/SdkDirectoryWorkloadManifestProvider.cs @@ -104,7 +104,7 @@ internal SdkDirectoryWorkloadManifestProvider(string sdkRootPath, string sdkVers _manifestRoots ??= Array.Empty(); } - public void RefreshWorkloadManifests() + public void RefreshWorkloadManifests(bool error = true) { _workloadSet = null; _manifestsFromInstallState = null; @@ -113,7 +113,7 @@ public void RefreshWorkloadManifests() if (_workloadSetVersionFromConstructor != null) { - if (!availableWorkloadSets.TryGetValue(_workloadSetVersionFromConstructor, out _workloadSet)) + if (!availableWorkloadSets.TryGetValue(_workloadSetVersionFromConstructor, out _workloadSet) && error) { throw new FileNotFoundException(string.Format(Strings.WorkloadVersionNotFound, _workloadSetVersionFromConstructor)); } @@ -124,7 +124,7 @@ public void RefreshWorkloadManifests() string? globalJsonWorkloadSetVersion = GlobalJsonReader.GetWorkloadVersionFromGlobalJson(_globalJsonPathFromConstructor); if (globalJsonWorkloadSetVersion != null) { - if (!availableWorkloadSets.TryGetValue(globalJsonWorkloadSetVersion, out _workloadSet)) + if (!availableWorkloadSets.TryGetValue(globalJsonWorkloadSetVersion, out _workloadSet) && error) { throw new FileNotFoundException(string.Format(Strings.WorkloadVersionFromGlobalJsonNotFound, globalJsonWorkloadSetVersion, _globalJsonPathFromConstructor)); } @@ -139,13 +139,16 @@ public void RefreshWorkloadManifests() var installState = InstallStateContents.FromPath(installStateFilePath); if (!string.IsNullOrEmpty(installState.WorkloadVersion)) { - if (!availableWorkloadSets.TryGetValue(installState.WorkloadVersion!, out _workloadSet)) + if (availableWorkloadSets.TryGetValue(installState.WorkloadVersion!, out _workloadSet)) + { + _manifestsFromInstallState = installState.Manifests is null ? null : WorkloadSet.FromDictionaryForJson(installState.Manifests, _sdkVersionBand); + _installStateFilePath = installStateFilePath; + } + else if (error) { throw new FileNotFoundException(string.Format(Strings.WorkloadVersionFromInstallStateNotFound, installState.WorkloadVersion, installStateFilePath)); } } - _manifestsFromInstallState = installState.Manifests is null ? null : WorkloadSet.FromDictionaryForJson(installState.Manifests, _sdkVersionBand); - _installStateFilePath = installStateFilePath; } } @@ -155,14 +158,14 @@ public void RefreshWorkloadManifests() _workloadSet = availableWorkloadSets[maxWorkloadSetVersion.ToString()]; } - _initializedManifests = true; + _initializedManifests |= error; } - public string? GetWorkloadVersion() + public string? GetWorkloadVersion(bool error = true) { if (!_initializedManifests) { - RefreshWorkloadManifests(); + RefreshWorkloadManifests(error); } if (_workloadSet?.Version is not null) @@ -173,7 +176,7 @@ public void RefreshWorkloadManifests() using (SHA256 sha256Hash = SHA256.Create()) { byte[] bytes = sha256Hash.ComputeHash(Encoding.UTF8.GetBytes(string.Join(";", - GetManifests().OrderBy(m => m.ManifestId).Select(m => $"{m.ManifestId}.{m.ManifestFeatureBand}.{m.ManifestVersion}").ToArray() + GetManifests(initializeManifests: false).OrderBy(m => m.ManifestId).Select(m => $"{m.ManifestId}.{m.ManifestFeatureBand}.{m.ManifestVersion}").ToArray() ))); // Only append the first four bytes to the version hash. @@ -188,9 +191,9 @@ public void RefreshWorkloadManifests() } } - public IEnumerable GetManifests() + public IEnumerable GetManifests(bool initializeManifests = true) { - if (!_initializedManifests) + if (!_initializedManifests && initializeManifests) { RefreshWorkloadManifests(); } diff --git a/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/TempDirectoryWorkloadManifestProvider.cs b/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/TempDirectoryWorkloadManifestProvider.cs index a764fb2d9fb5..10f4dd077795 100644 --- a/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/TempDirectoryWorkloadManifestProvider.cs +++ b/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/TempDirectoryWorkloadManifestProvider.cs @@ -14,10 +14,10 @@ public TempDirectoryWorkloadManifestProvider(string manifestsPath, string sdkFea _sdkVersionBand = sdkFeatureBand; } - public void RefreshWorkloadManifests() { } + public void RefreshWorkloadManifests(bool error = true) { } public IEnumerable - GetManifests() + GetManifests(bool initializeManifests = true) { foreach (var workloadManifestDirectory in GetManifestDirectories()) { @@ -54,7 +54,7 @@ public IEnumerable GetManifestDirectories() } public string GetSdkFeatureBand() => _sdkVersionBand; - public string? GetWorkloadVersion() => _sdkVersionBand.ToString() + ".2"; + public string? GetWorkloadVersion(bool error = true) => _sdkVersionBand.ToString() + ".2"; public Dictionary GetAvailableWorkloadSets() => new(); } } diff --git a/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/WorkloadResolver.cs b/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/WorkloadResolver.cs index afb07924ba21..a46362ad5287 100644 --- a/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/WorkloadResolver.cs +++ b/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/WorkloadResolver.cs @@ -84,11 +84,11 @@ private WorkloadResolver(IWorkloadManifestProvider manifestProvider, (string pat _manifestProvider = manifestProvider; } - private void InitializeManifests() + private void InitializeManifests(bool error = true) { if (!_initializedManifests) { - LoadManifestsFromProvider(_manifestProvider); + LoadManifestsFromProvider(_manifestProvider, error); ComposeWorkloadManifests(); _initializedManifests = true; } @@ -117,11 +117,11 @@ public void RefreshWorkloadManifests() ComposeWorkloadManifests(); } - public string? GetWorkloadVersion() => _manifestProvider.GetWorkloadVersion(); + public string? GetWorkloadVersion(bool error = true) => _manifestProvider.GetWorkloadVersion(error: error); - private void LoadManifestsFromProvider(IWorkloadManifestProvider manifestProvider) + private void LoadManifestsFromProvider(IWorkloadManifestProvider manifestProvider, bool error = true) { - foreach (var readableManifest in manifestProvider.GetManifests()) + foreach (var readableManifest in manifestProvider.GetManifests(initializeManifests: error)) { using (Stream manifestStream = readableManifest.OpenManifestStream()) using (Stream? localizationStream = readableManifest.OpenLocalizationStream()) @@ -751,9 +751,9 @@ public string GetManifestVersion(string manifestId) throw new Exception($"Manifest with id {manifestId} does not exist."); } - public IEnumerable GetInstalledManifests() + public IEnumerable GetInstalledManifests(bool error = true) { - InitializeManifests(); + InitializeManifests(error); return _manifests.Select(t => t.Value.info); } @@ -766,11 +766,11 @@ public EmptyWorkloadManifestProvider(string sdkFeatureBand) _sdkFeatureBand = sdkFeatureBand; } - public void RefreshWorkloadManifests() { } + public void RefreshWorkloadManifests(bool error = true) { } public Dictionary GetAvailableWorkloadSets() => new(); - public IEnumerable GetManifests() => Enumerable.Empty(); + public IEnumerable GetManifests(bool initializeManifests = true) => Enumerable.Empty(); public string GetSdkFeatureBand() => _sdkFeatureBand; - public string? GetWorkloadVersion() => _sdkFeatureBand.ToString() + ".2"; + public string? GetWorkloadVersion(bool error = true) => _sdkFeatureBand.ToString() + ".2"; } } diff --git a/src/Tests/Microsoft.NET.Sdk.WorkloadManifestReader.Tests/FakeManifestProvider.cs b/src/Tests/Microsoft.NET.Sdk.WorkloadManifestReader.Tests/FakeManifestProvider.cs index 7c8fa003a368..f91445d664a7 100644 --- a/src/Tests/Microsoft.NET.Sdk.WorkloadManifestReader.Tests/FakeManifestProvider.cs +++ b/src/Tests/Microsoft.NET.Sdk.WorkloadManifestReader.Tests/FakeManifestProvider.cs @@ -20,9 +20,9 @@ public FakeManifestProvider(params (string manifest, string? localizationCatalog _filePaths = filePaths; } - public void RefreshWorkloadManifests() { } + public void RefreshWorkloadManifests(bool error = true) { } - public IEnumerable GetManifests() + public IEnumerable GetManifests(bool initializeManifests = true) { foreach (var filePath in _filePaths) { @@ -40,7 +40,7 @@ public IEnumerable GetManifests() public string GetSdkFeatureBand() => "8.0.100"; public Dictionary GetAvailableWorkloadSets() => throw new NotImplementedException(); - public string? GetWorkloadVersion() => "8.0.100.2"; + public string? GetWorkloadVersion(bool error = true) => "8.0.100.2"; } internal class InMemoryFakeManifestProvider : IWorkloadManifestProvider, IEnumerable<(string id, string content)> @@ -49,9 +49,9 @@ internal class InMemoryFakeManifestProvider : IWorkloadManifestProvider, IEnumer public void Add(string id, string content) => _manifests.Add((id, Encoding.UTF8.GetBytes(content))); - public void RefreshWorkloadManifests() { } + public void RefreshWorkloadManifests(bool error = true) { } - public IEnumerable GetManifests() + public IEnumerable GetManifests(bool initializeManifests = true) => _manifests.Select(m => new ReadableWorkloadManifest( m.id, $@"C:\fake\{m.id}", @@ -67,6 +67,6 @@ public IEnumerable GetManifests() IEnumerator IEnumerable.GetEnumerator() => throw new NotImplementedException(); public string GetSdkFeatureBand() => "8.0.100"; public Dictionary GetAvailableWorkloadSets() => throw new NotImplementedException(); - public string? GetWorkloadVersion() => "8.0.100.2"; + public string? GetWorkloadVersion(bool error = true) => "8.0.100.2"; } } diff --git a/src/Tests/dotnet-workload-install.Tests/MockManifestProvider.cs b/src/Tests/dotnet-workload-install.Tests/MockManifestProvider.cs index 935fb9addfe8..85dfa0d64354 100644 --- a/src/Tests/dotnet-workload-install.Tests/MockManifestProvider.cs +++ b/src/Tests/dotnet-workload-install.Tests/MockManifestProvider.cs @@ -29,9 +29,9 @@ public MockManifestProvider(params (string name, string path, string featureBand public Dictionary GetAvailableWorkloadSets() => new(); - public void RefreshWorkloadManifests() { } + public void RefreshWorkloadManifests(bool error = true) { } - public IEnumerable GetManifests() + public IEnumerable GetManifests(bool initializeManifests = true) { foreach ((var id, var path, var featureBand) in _manifests) { @@ -48,6 +48,6 @@ public IEnumerable GetManifests() } public string GetSdkFeatureBand() => SdkFeatureBand.ToString(); - public string GetWorkloadVersion() => SdkFeatureBand.ToString() + ".2"; + public string GetWorkloadVersion(bool error = true) => SdkFeatureBand.ToString() + ".2"; } } diff --git a/src/Tests/dotnet-workload-search.Tests/MockWorkloadResolver.cs b/src/Tests/dotnet-workload-search.Tests/MockWorkloadResolver.cs index 5a9bdd9cb706..1ae09f7f7803 100644 --- a/src/Tests/dotnet-workload-search.Tests/MockWorkloadResolver.cs +++ b/src/Tests/dotnet-workload-search.Tests/MockWorkloadResolver.cs @@ -25,10 +25,10 @@ public void RefreshWorkloadManifests() { } public WorkloadResolver.PackInfo TryGetPackInfo(WorkloadPackId packId) => throw new NotImplementedException(); public bool IsPlatformIncompatibleWorkload(WorkloadId workloadId) => throw new NotImplementedException(); public string GetManifestVersion(string manifestId) => throw new NotImplementedException(); - public IEnumerable GetInstalledManifests() => throw new NotImplementedException(); + public IEnumerable GetInstalledManifests(bool error = true) => throw new NotImplementedException(); public IWorkloadResolver CreateOverlayResolver(IWorkloadManifestProvider overlayManifestProvider) => throw new NotImplementedException(); public string GetSdkFeatureBand() => "12.0.400"; - public string GetWorkloadVersion() => "12.0.400.2"; + public string GetWorkloadVersion(bool error = true) => "12.0.400.2"; public IEnumerable GetUpdatedWorkloads(WorkloadResolver advertisingManifestResolver, IEnumerable installedWorkloads) => throw new NotImplementedException(); WorkloadResolver IWorkloadResolver.CreateOverlayResolver(IWorkloadManifestProvider overlayManifestProvider) => throw new NotImplementedException(); WorkloadManifest IWorkloadResolver.GetManifestFromWorkload(WorkloadId workloadId) => throw new NotImplementedException(); From c149f127534c5b56608c7ae257137a0cea68352e Mon Sep 17 00:00:00 2001 From: Forgind <12969783+Forgind@users.noreply.github.com> Date: Fri, 5 Apr 2024 16:43:16 -0700 Subject: [PATCH 528/577] Make Install happy, too --- .../dotnet-workload/install/WorkloadInstallCommand.cs | 2 +- .../IWorkloadResolver.cs | 2 +- .../WorkloadResolver.cs | 8 ++++---- .../dotnet-workload-search.Tests/MockWorkloadResolver.cs | 2 +- .../dotnet.Tests/dotnet-new/WorkloadsInfoProviderTests.cs | 2 +- 5 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/Cli/dotnet/commands/dotnet-workload/install/WorkloadInstallCommand.cs b/src/Cli/dotnet/commands/dotnet-workload/install/WorkloadInstallCommand.cs index bdbf3ac154b9..12c1d0bfd377 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/install/WorkloadInstallCommand.cs +++ b/src/Cli/dotnet/commands/dotnet-workload/install/WorkloadInstallCommand.cs @@ -51,7 +51,7 @@ public WorkloadInstallCommand( private void ValidateWorkloadIdsInput() { - var availableWorkloads = _workloadResolver.GetAvailableWorkloads(); + var availableWorkloads = _workloadResolver.GetAvailableWorkloads(error: false); foreach (var workloadId in _workloadIds) { if (!availableWorkloads.Select(workload => workload.Id.ToString()).Contains(workloadId)) diff --git a/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/IWorkloadResolver.cs b/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/IWorkloadResolver.cs index df44773f4a68..0004dccc1e60 100644 --- a/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/IWorkloadResolver.cs +++ b/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/IWorkloadResolver.cs @@ -14,7 +14,7 @@ public interface IWorkloadResolver /// Deduplicated enumeration of workload infos. IEnumerable GetExtendedWorkloads(IEnumerable workloadIds); ISet? GetWorkloadSuggestionForMissingPacks(IList packId, out ISet unsatisfiablePacks); - IEnumerable GetAvailableWorkloads(); + IEnumerable GetAvailableWorkloads(bool error = true); bool IsPlatformIncompatibleWorkload(WorkloadId workloadId); string GetManifestVersion(string manifestId); IEnumerable GetInstalledManifests(bool error = true); diff --git a/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/WorkloadResolver.cs b/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/WorkloadResolver.cs index a46362ad5287..66b7c1f33cd0 100644 --- a/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/WorkloadResolver.cs +++ b/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/WorkloadResolver.cs @@ -550,12 +550,12 @@ public IEnumerable GetExtendedWorkloads(IEnumerable wo /// /// Returns the list of workloads available (installed or not) on the current platform, defined by the manifests on disk /// - public IEnumerable GetAvailableWorkloads() - => GetAvailableWorkloadDefinitions().Select(w => new WorkloadInfo(w.workload.Id, w.workload.Description)); + public IEnumerable GetAvailableWorkloads(bool error = true) + => GetAvailableWorkloadDefinitions(error).Select(w => new WorkloadInfo(w.workload.Id, w.workload.Description)); - private IEnumerable<(WorkloadDefinition workload, WorkloadManifest manifest)> GetAvailableWorkloadDefinitions() + private IEnumerable<(WorkloadDefinition workload, WorkloadManifest manifest)> GetAvailableWorkloadDefinitions(bool error = true) { - InitializeManifests(); + InitializeManifests(error); foreach ((WorkloadId _, (WorkloadDefinition workload, WorkloadManifest manifest)) in _workloads) { if (!workload.IsAbstract && IsWorkloadPlatformCompatible(workload, manifest) && !IsWorkloadImplicitlyAbstract(workload, manifest)) diff --git a/src/Tests/dotnet-workload-search.Tests/MockWorkloadResolver.cs b/src/Tests/dotnet-workload-search.Tests/MockWorkloadResolver.cs index 1ae09f7f7803..45d7ca3479c4 100644 --- a/src/Tests/dotnet-workload-search.Tests/MockWorkloadResolver.cs +++ b/src/Tests/dotnet-workload-search.Tests/MockWorkloadResolver.cs @@ -14,7 +14,7 @@ public MockWorkloadResolver(IEnumerable available _availableWorkloads = availableWorkloads; } - public IEnumerable GetAvailableWorkloads() => _availableWorkloads; + public IEnumerable GetAvailableWorkloads(bool error = true) => _availableWorkloads; public IEnumerable GetInstalledWorkloadPacksOfKind(WorkloadPackKind kind) => throw new NotImplementedException(); public IEnumerable GetPacksInWorkload(WorkloadId workloadId) => Array.Empty(); diff --git a/src/Tests/dotnet.Tests/dotnet-new/WorkloadsInfoProviderTests.cs b/src/Tests/dotnet.Tests/dotnet-new/WorkloadsInfoProviderTests.cs index 8dc621494ff7..eddfcfb2b6d0 100644 --- a/src/Tests/dotnet.Tests/dotnet-new/WorkloadsInfoProviderTests.cs +++ b/src/Tests/dotnet.Tests/dotnet-new/WorkloadsInfoProviderTests.cs @@ -23,7 +23,7 @@ public void InstalledWorkloads_ShouldReturnExpectedWorkloads() var repoMock = new Mock(); resolverMock - .Setup(r => r.GetAvailableWorkloads()) + .Setup(r => r.GetAvailableWorkloads(true)) .Returns(Enumerable.Empty()); repoMock From 8b594c7410879a9460e099cdca1d3cca6e71cd32 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Sun, 7 Apr 2024 08:26:23 +0000 Subject: [PATCH 529/577] [release/8.0.3xx] Update dependencies from dotnet/templating (#40033) [release/8.0.3xx] Update dependencies from dotnet/templating - Skip the ChangeFileInDependency test --- eng/Version.Details.xml | 8 ++++---- eng/Versions.props | 4 ++-- src/Tests/dotnet-watch.Tests/Watch/AppWithDepsTests.cs | 2 +- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 42eac2bc681a..f6326c925dbd 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -1,14 +1,14 @@ - + https://github.com/dotnet/templating - 851bd635e5410504884df80d2c9b32ccb4add61d + 8108ceec56abdcb34c7289ba4a470cb432ef1ccb - + https://github.com/dotnet/templating - 851bd635e5410504884df80d2c9b32ccb4add61d + 8108ceec56abdcb34c7289ba4a470cb432ef1ccb https://dev.azure.com/dnceng/internal/_git/dotnet-runtime diff --git a/eng/Versions.props b/eng/Versions.props index 2150c534dab5..c996f0d81374 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -137,13 +137,13 @@ - 8.0.300-preview.24203.2 + 8.0.300-preview.24205.1 $(MicrosoftTemplateEngineAbstractionsPackageVersion) $(MicrosoftTemplateEngineAbstractionsPackageVersion) $(MicrosoftTemplateEngineAbstractionsPackageVersion) $(MicrosoftTemplateEngineAbstractionsPackageVersion) - 8.0.300-preview.24203.2 + 8.0.300-preview.24205.1 $(MicrosoftTemplateEngineMocksPackageVersion) $(MicrosoftTemplateEngineAbstractionsPackageVersion) $(MicrosoftTemplateEngineMocksPackageVersion) diff --git a/src/Tests/dotnet-watch.Tests/Watch/AppWithDepsTests.cs b/src/Tests/dotnet-watch.Tests/Watch/AppWithDepsTests.cs index 9191d9933a2b..12b7631e3143 100644 --- a/src/Tests/dotnet-watch.Tests/Watch/AppWithDepsTests.cs +++ b/src/Tests/dotnet-watch.Tests/Watch/AppWithDepsTests.cs @@ -10,7 +10,7 @@ public AppWithDepsTests(ITestOutputHelper logger) { } - [Fact] + [Fact(Skip = "https://github.com/dotnet/sdk/issues/40006")] public async Task ChangeFileInDependency() { var testAsset = TestAssets.CopyTestAsset("WatchAppWithProjectDeps") From acae6a835665289646be9f7dadccb38d60c31185 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Sun, 7 Apr 2024 09:00:04 +0000 Subject: [PATCH 530/577] [release/8.0.3xx] Update dependencies from microsoft/vstest (#40009) [release/8.0.3xx] Update dependencies from microsoft/vstest - Skip the ChangeFileInDependency test --- eng/Version.Details.xml | 12 ++++++------ eng/Versions.props | 6 +++--- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index f6326c925dbd..8d1256be42b7 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -183,18 +183,18 @@ https://github.com/nuget/nuget.client fb50d1a45ed10b39b5f335bc3a4bdcaea9b951cf - + https://github.com/microsoft/vstest - 1cd0d8998250d36c95ed65a76304ef5d1b33e98f + 56d28849af08dc3143d019694aa92f186b89d2ac - + https://github.com/microsoft/vstest - 1cd0d8998250d36c95ed65a76304ef5d1b33e98f + 56d28849af08dc3143d019694aa92f186b89d2ac - + https://github.com/microsoft/vstest - 1cd0d8998250d36c95ed65a76304ef5d1b33e98f + 56d28849af08dc3143d019694aa92f186b89d2ac https://dev.azure.com/dnceng/internal/_git/dotnet-runtime diff --git a/eng/Versions.props b/eng/Versions.props index c996f0d81374..44b4e552ecae 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -99,9 +99,9 @@ - 17.10.0-release-24177-07 - 17.10.0-release-24177-07 - 17.10.0-release-24177-07 + 17.10.0-release-24203-04 + 17.10.0-release-24203-04 + 17.10.0-release-24203-04 From b0590605d5e9cbd4af52e6a90c6ff2d7a00695ca Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Sun, 7 Apr 2024 09:00:18 +0000 Subject: [PATCH 531/577] [release/8.0.3xx] Update dependencies from dotnet/arcade (#40034) [release/8.0.3xx] Update dependencies from dotnet/arcade - Skip the ChangeFileInDependency test --- eng/Version.Details.xml | 16 ++++++++-------- eng/Versions.props | 4 ++-- .../steps/component-governance.yml | 2 +- .../templates/steps/component-governance.yml | 2 +- global.json | 4 ++-- 5 files changed, 14 insertions(+), 14 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 8d1256be42b7..07b51c0c830c 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -479,22 +479,22 @@ - + https://github.com/dotnet/arcade - fc2b7849b25c4a21457feb6da5fc7c9806a80976 + 188340e12c0a372b1681ad6a5e72c608021efdba - + https://github.com/dotnet/arcade - fc2b7849b25c4a21457feb6da5fc7c9806a80976 + 188340e12c0a372b1681ad6a5e72c608021efdba - + https://github.com/dotnet/arcade - fc2b7849b25c4a21457feb6da5fc7c9806a80976 + 188340e12c0a372b1681ad6a5e72c608021efdba - + https://github.com/dotnet/arcade - fc2b7849b25c4a21457feb6da5fc7c9806a80976 + 188340e12c0a372b1681ad6a5e72c608021efdba https://dev.azure.com/dnceng/internal/_git/dotnet-runtime diff --git a/eng/Versions.props b/eng/Versions.props index 44b4e552ecae..825bd3fff589 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -34,7 +34,7 @@ 7.0.0 4.0.0 7.0.0 - 8.0.0-beta.24179.4 + 8.0.0-beta.24204.3 7.0.0-preview.22423.2 8.0.0 4.3.0 @@ -209,7 +209,7 @@ 6.12.0 6.1.0 - 8.0.0-beta.24179.4 + 8.0.0-beta.24204.3 4.18.4 1.3.2 8.0.0-beta.23607.1 diff --git a/eng/common/templates-official/steps/component-governance.yml b/eng/common/templates-official/steps/component-governance.yml index 0ecec47b0c91..cbba0596709d 100644 --- a/eng/common/templates-official/steps/component-governance.yml +++ b/eng/common/templates-official/steps/component-governance.yml @@ -4,7 +4,7 @@ parameters: steps: - ${{ if eq(parameters.disableComponentGovernance, 'true') }}: - - script: "echo ##vso[task.setvariable variable=skipComponentGovernanceDetection]true" + - script: echo "##vso[task.setvariable variable=skipComponentGovernanceDetection]true" displayName: Set skipComponentGovernanceDetection variable - ${{ if ne(parameters.disableComponentGovernance, 'true') }}: - task: ComponentGovernanceComponentDetection@0 diff --git a/eng/common/templates/steps/component-governance.yml b/eng/common/templates/steps/component-governance.yml index 0ecec47b0c91..cbba0596709d 100644 --- a/eng/common/templates/steps/component-governance.yml +++ b/eng/common/templates/steps/component-governance.yml @@ -4,7 +4,7 @@ parameters: steps: - ${{ if eq(parameters.disableComponentGovernance, 'true') }}: - - script: "echo ##vso[task.setvariable variable=skipComponentGovernanceDetection]true" + - script: echo "##vso[task.setvariable variable=skipComponentGovernanceDetection]true" displayName: Set skipComponentGovernanceDetection variable - ${{ if ne(parameters.disableComponentGovernance, 'true') }}: - task: ComponentGovernanceComponentDetection@0 diff --git a/global.json b/global.json index eeb185f138b1..942d61e6a9bc 100644 --- a/global.json +++ b/global.json @@ -14,7 +14,7 @@ } }, "msbuild-sdks": { - "Microsoft.DotNet.Arcade.Sdk": "8.0.0-beta.24179.4", - "Microsoft.DotNet.Helix.Sdk": "8.0.0-beta.24179.4" + "Microsoft.DotNet.Arcade.Sdk": "8.0.0-beta.24204.3", + "Microsoft.DotNet.Helix.Sdk": "8.0.0-beta.24204.3" } } From 36b8833b78fde27492cf2c61f244505c2c46799b Mon Sep 17 00:00:00 2001 From: dotnet bot Date: Sun, 7 Apr 2024 02:00:52 -0700 Subject: [PATCH 532/577] Localized file check-in by OneLocBuild Task: Build definition ID 140: Build ID 2424415 --- .../dotnet-workload/config/xlf/LocalizableStrings.cs.xlf | 6 +++--- .../dotnet-workload/config/xlf/LocalizableStrings.de.xlf | 6 +++--- .../dotnet-workload/config/xlf/LocalizableStrings.es.xlf | 6 +++--- .../dotnet-workload/config/xlf/LocalizableStrings.fr.xlf | 6 +++--- .../dotnet-workload/config/xlf/LocalizableStrings.it.xlf | 6 +++--- .../dotnet-workload/config/xlf/LocalizableStrings.ja.xlf | 6 +++--- .../dotnet-workload/config/xlf/LocalizableStrings.ko.xlf | 6 +++--- .../dotnet-workload/config/xlf/LocalizableStrings.pl.xlf | 6 +++--- .../dotnet-workload/config/xlf/LocalizableStrings.pt-BR.xlf | 6 +++--- .../dotnet-workload/config/xlf/LocalizableStrings.ru.xlf | 6 +++--- .../config/xlf/LocalizableStrings.zh-Hans.xlf | 6 +++--- .../config/xlf/LocalizableStrings.zh-Hant.xlf | 6 +++--- 12 files changed, 36 insertions(+), 36 deletions(-) diff --git a/src/Cli/dotnet/commands/dotnet-workload/config/xlf/LocalizableStrings.cs.xlf b/src/Cli/dotnet/commands/dotnet-workload/config/xlf/LocalizableStrings.cs.xlf index 8d6be7eaaf81..ed4919133932 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/config/xlf/LocalizableStrings.cs.xlf +++ b/src/Cli/dotnet/commands/dotnet-workload/config/xlf/LocalizableStrings.cs.xlf @@ -5,13 +5,13 @@ Modify or display workload configuration values. To display a value, specify the corresponding command-line option without providing a value. For example: "dotnet workload config --update-mode" - Modify or display workload configuration values. -To display a value, specify the corresponding command-line option without providing a value. For example: "dotnet workload config --update-mode" + Upravit nebo zobrazit hodnoty konfigurace úlohy. +Pokud chcete zobrazit hodnotu, zadejte odpovídající volbu příkazového řádku bez zadání hodnoty. Například: dotnet workload config --update-mode Controls whether updates should look for workload sets or the latest version of each individual manifest. - Controls whether updates should look for workload sets or the latest version of each individual manifest. + Určuje, zda mají aktualizace vyhledávat sady úloh nebo nejnovější verzi každého jednotlivého manifestu. diff --git a/src/Cli/dotnet/commands/dotnet-workload/config/xlf/LocalizableStrings.de.xlf b/src/Cli/dotnet/commands/dotnet-workload/config/xlf/LocalizableStrings.de.xlf index 88aee0f67512..f1d74dd02c20 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/config/xlf/LocalizableStrings.de.xlf +++ b/src/Cli/dotnet/commands/dotnet-workload/config/xlf/LocalizableStrings.de.xlf @@ -5,13 +5,13 @@ Modify or display workload configuration values. To display a value, specify the corresponding command-line option without providing a value. For example: "dotnet workload config --update-mode" - Modify or display workload configuration values. -To display a value, specify the corresponding command-line option without providing a value. For example: "dotnet workload config --update-mode" + Workloadkonfigurationswerte ändern oder anzeigen. +Um einen Wert anzuzeigen, geben Sie die entsprechende Befehlszeilenoption an, ohne einen Wert anzugeben. Beispiel: „dotnet workload config --update-mode“ Controls whether updates should look for workload sets or the latest version of each individual manifest. - Controls whether updates should look for workload sets or the latest version of each individual manifest. + Steuert, ob Updates nach Workloadsätzen oder der neuesten Version jedes einzelnen Manifests suchen sollen. diff --git a/src/Cli/dotnet/commands/dotnet-workload/config/xlf/LocalizableStrings.es.xlf b/src/Cli/dotnet/commands/dotnet-workload/config/xlf/LocalizableStrings.es.xlf index 55b10d407fc2..63e4ee76820b 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/config/xlf/LocalizableStrings.es.xlf +++ b/src/Cli/dotnet/commands/dotnet-workload/config/xlf/LocalizableStrings.es.xlf @@ -5,13 +5,13 @@ Modify or display workload configuration values. To display a value, specify the corresponding command-line option without providing a value. For example: "dotnet workload config --update-mode" - Modify or display workload configuration values. -To display a value, specify the corresponding command-line option without providing a value. For example: "dotnet workload config --update-mode" + Modificar o mostrar los valores de configuración de la carga de trabajo. +Para mostrar un valor, especifique la opción de línea de comandos correspondiente sin proporcionar un valor. Por ejemplo: "dotnet workload config --update-mode" Controls whether updates should look for workload sets or the latest version of each individual manifest. - Controls whether updates should look for workload sets or the latest version of each individual manifest. + Controla si las actualizaciones deben buscar conjuntos de cargas de trabajo o la versión más reciente de cada manifiesto individual. diff --git a/src/Cli/dotnet/commands/dotnet-workload/config/xlf/LocalizableStrings.fr.xlf b/src/Cli/dotnet/commands/dotnet-workload/config/xlf/LocalizableStrings.fr.xlf index c7cc788430d4..0fb8129902c1 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/config/xlf/LocalizableStrings.fr.xlf +++ b/src/Cli/dotnet/commands/dotnet-workload/config/xlf/LocalizableStrings.fr.xlf @@ -5,13 +5,13 @@ Modify or display workload configuration values. To display a value, specify the corresponding command-line option without providing a value. For example: "dotnet workload config --update-mode" - Modify or display workload configuration values. -To display a value, specify the corresponding command-line option without providing a value. For example: "dotnet workload config --update-mode" + Modifiez ou affichez les valeurs de configuration de la charge de travail. +Pour afficher une valeur, spécifiez l’option de ligne de commande correspondante sans fournir de valeur. Par exemple : « dotnet workload config --update-mode » Controls whether updates should look for workload sets or the latest version of each individual manifest. - Controls whether updates should look for workload sets or the latest version of each individual manifest. + Contrôle si les mises à jour doivent rechercher des ensembles de charge de travail ou la dernière version de chaque manifeste individuel. diff --git a/src/Cli/dotnet/commands/dotnet-workload/config/xlf/LocalizableStrings.it.xlf b/src/Cli/dotnet/commands/dotnet-workload/config/xlf/LocalizableStrings.it.xlf index ba98130db0bf..82cdd2e1049e 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/config/xlf/LocalizableStrings.it.xlf +++ b/src/Cli/dotnet/commands/dotnet-workload/config/xlf/LocalizableStrings.it.xlf @@ -5,13 +5,13 @@ Modify or display workload configuration values. To display a value, specify the corresponding command-line option without providing a value. For example: "dotnet workload config --update-mode" - Modify or display workload configuration values. -To display a value, specify the corresponding command-line option without providing a value. For example: "dotnet workload config --update-mode" + Modifica o mostra i valori di configurazione del carico di lavoro. +Per mostrare un valore, specifica l'opzione della riga di comando corrispondente senza fornire un valore. Ad esempio: "dotnet workload config --update-mode" Controls whether updates should look for workload sets or the latest version of each individual manifest. - Controls whether updates should look for workload sets or the latest version of each individual manifest. + Controlla se gli aggiornamenti devono cercare i set di carichi di lavoro o la versione più recente di ogni singolo manifesto. diff --git a/src/Cli/dotnet/commands/dotnet-workload/config/xlf/LocalizableStrings.ja.xlf b/src/Cli/dotnet/commands/dotnet-workload/config/xlf/LocalizableStrings.ja.xlf index 882fdf49f5d9..ef9d4d7394e4 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/config/xlf/LocalizableStrings.ja.xlf +++ b/src/Cli/dotnet/commands/dotnet-workload/config/xlf/LocalizableStrings.ja.xlf @@ -5,13 +5,13 @@ Modify or display workload configuration values. To display a value, specify the corresponding command-line option without providing a value. For example: "dotnet workload config --update-mode" - Modify or display workload configuration values. -To display a value, specify the corresponding command-line option without providing a value. For example: "dotnet workload config --update-mode" + ワークロード構成値を変更または表示します。 +値を表示するには、値を指定せずに対応するコマンド ライン オプションを指定します。例: "dotnet workload config --update-mode" Controls whether updates should look for workload sets or the latest version of each individual manifest. - Controls whether updates should look for workload sets or the latest version of each individual manifest. + 更新プログラムでワークロード セットを検索するか、各個別マニフェストの最新バージョンを検索するかを制御します。 diff --git a/src/Cli/dotnet/commands/dotnet-workload/config/xlf/LocalizableStrings.ko.xlf b/src/Cli/dotnet/commands/dotnet-workload/config/xlf/LocalizableStrings.ko.xlf index b8773e9b116c..42cbb2665afe 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/config/xlf/LocalizableStrings.ko.xlf +++ b/src/Cli/dotnet/commands/dotnet-workload/config/xlf/LocalizableStrings.ko.xlf @@ -5,13 +5,13 @@ Modify or display workload configuration values. To display a value, specify the corresponding command-line option without providing a value. For example: "dotnet workload config --update-mode" - Modify or display workload configuration values. -To display a value, specify the corresponding command-line option without providing a value. For example: "dotnet workload config --update-mode" + 워크로드 구성 값을 수정하거나 표시합니다. +값을 표시하려면 값을 제공하지 않고 해당 명령줄 옵션을 지정합니다. 예: "dotnet workload config --update-mode" Controls whether updates should look for workload sets or the latest version of each individual manifest. - Controls whether updates should look for workload sets or the latest version of each individual manifest. + 업데이트에서 워크로드 집합을 찾을지 또는 각 개별 매니페스트의 최신 버전을 찾을지 여부를 제어합니다. diff --git a/src/Cli/dotnet/commands/dotnet-workload/config/xlf/LocalizableStrings.pl.xlf b/src/Cli/dotnet/commands/dotnet-workload/config/xlf/LocalizableStrings.pl.xlf index 06ccf667f917..856c390bd95c 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/config/xlf/LocalizableStrings.pl.xlf +++ b/src/Cli/dotnet/commands/dotnet-workload/config/xlf/LocalizableStrings.pl.xlf @@ -5,13 +5,13 @@ Modify or display workload configuration values. To display a value, specify the corresponding command-line option without providing a value. For example: "dotnet workload config --update-mode" - Modify or display workload configuration values. -To display a value, specify the corresponding command-line option without providing a value. For example: "dotnet workload config --update-mode" + Modyfikuj lub wyświetlaj wartości konfiguracji obciążenia. +Aby wyświetlić wartość, należy podać odpowiednią opcję wiersza poleceń bez podawania wartości. Na przykład: „dotnet workload config --update-mode” Controls whether updates should look for workload sets or the latest version of each individual manifest. - Controls whether updates should look for workload sets or the latest version of each individual manifest. + Kontroluje, czy aktualizacje powinny szukać zestawów obciążeń, czy najnowszej wersji każdego pojedynczego manifestu. diff --git a/src/Cli/dotnet/commands/dotnet-workload/config/xlf/LocalizableStrings.pt-BR.xlf b/src/Cli/dotnet/commands/dotnet-workload/config/xlf/LocalizableStrings.pt-BR.xlf index 27459bb8c5fb..338f1ba19c04 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/config/xlf/LocalizableStrings.pt-BR.xlf +++ b/src/Cli/dotnet/commands/dotnet-workload/config/xlf/LocalizableStrings.pt-BR.xlf @@ -5,13 +5,13 @@ Modify or display workload configuration values. To display a value, specify the corresponding command-line option without providing a value. For example: "dotnet workload config --update-mode" - Modify or display workload configuration values. -To display a value, specify the corresponding command-line option without providing a value. For example: "dotnet workload config --update-mode" + Modifique ou exiba valores de configuração de carga de trabalho. +Para exibir um valor, especifique a opção de linha de comando correspondente sem fornecer um valor. Por exemplo: "dotnet workload config --update-mode" Controls whether updates should look for workload sets or the latest version of each individual manifest. - Controls whether updates should look for workload sets or the latest version of each individual manifest. + Controla se as atualizações devem procurar conjuntos de cargas de trabalho ou a versão mais recente de cada manifesto individual. diff --git a/src/Cli/dotnet/commands/dotnet-workload/config/xlf/LocalizableStrings.ru.xlf b/src/Cli/dotnet/commands/dotnet-workload/config/xlf/LocalizableStrings.ru.xlf index 5a490dbba2f5..c56f33db3664 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/config/xlf/LocalizableStrings.ru.xlf +++ b/src/Cli/dotnet/commands/dotnet-workload/config/xlf/LocalizableStrings.ru.xlf @@ -5,13 +5,13 @@ Modify or display workload configuration values. To display a value, specify the corresponding command-line option without providing a value. For example: "dotnet workload config --update-mode" - Modify or display workload configuration values. -To display a value, specify the corresponding command-line option without providing a value. For example: "dotnet workload config --update-mode" + Изменение или отображение значений конфигурации рабочей нагрузки. +Чтобы отобразить значение, укажите соответствующий параметр командной строки без значения. Например: "dotnet workload config --update-mode" Controls whether updates should look for workload sets or the latest version of each individual manifest. - Controls whether updates should look for workload sets or the latest version of each individual manifest. + Управляет тем, должны ли обновления искать наборы рабочих нагрузок или последнюю версию каждого отдельного манифеста. diff --git a/src/Cli/dotnet/commands/dotnet-workload/config/xlf/LocalizableStrings.zh-Hans.xlf b/src/Cli/dotnet/commands/dotnet-workload/config/xlf/LocalizableStrings.zh-Hans.xlf index 41a4543b7566..56efa42aa583 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/config/xlf/LocalizableStrings.zh-Hans.xlf +++ b/src/Cli/dotnet/commands/dotnet-workload/config/xlf/LocalizableStrings.zh-Hans.xlf @@ -5,13 +5,13 @@ Modify or display workload configuration values. To display a value, specify the corresponding command-line option without providing a value. For example: "dotnet workload config --update-mode" - Modify or display workload configuration values. -To display a value, specify the corresponding command-line option without providing a value. For example: "dotnet workload config --update-mode" + 修改或显示工作负载配置值。 +若要显示值,请指定相应的命令行选项,而不用提供值。例如,“dotnet workload config --update-mode” Controls whether updates should look for workload sets or the latest version of each individual manifest. - Controls whether updates should look for workload sets or the latest version of each individual manifest. + 控制更新是应查找工作负载集还是每个单个清单的最新版本。 diff --git a/src/Cli/dotnet/commands/dotnet-workload/config/xlf/LocalizableStrings.zh-Hant.xlf b/src/Cli/dotnet/commands/dotnet-workload/config/xlf/LocalizableStrings.zh-Hant.xlf index 8a8598849d60..daaac13ba765 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/config/xlf/LocalizableStrings.zh-Hant.xlf +++ b/src/Cli/dotnet/commands/dotnet-workload/config/xlf/LocalizableStrings.zh-Hant.xlf @@ -5,13 +5,13 @@ Modify or display workload configuration values. To display a value, specify the corresponding command-line option without providing a value. For example: "dotnet workload config --update-mode" - Modify or display workload configuration values. -To display a value, specify the corresponding command-line option without providing a value. For example: "dotnet workload config --update-mode" + 修改或顯示工作負載設定值。 +若要顯示值,請指定對應的命令列選項而不提供值。例如: "dotnet workload config --update-mode" Controls whether updates should look for workload sets or the latest version of each individual manifest. - Controls whether updates should look for workload sets or the latest version of each individual manifest. + 控制更新是否應尋找工作負載集或每個單獨資訊清單的最新版本。 From 45571b5104036012cc5d1590b4d78ecaca619c57 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Sun, 7 Apr 2024 10:50:43 +0000 Subject: [PATCH 533/577] [release/8.0.3xx] Update dependencies from dotnet/razor (#39885) [release/8.0.3xx] Update dependencies from dotnet/razor - Skip the ChangeFileInDependency test --- eng/Version.Details.xml | 12 ++++++------ eng/Versions.props | 6 +++--- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 07b51c0c830c..63969664891d 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -281,18 +281,18 @@ https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore da7e9894ce22ef8cc02e5acc56e95a6f8cf8f644 - + https://github.com/dotnet/razor - 95d21239fc7a81d0c7e6a6c7abf4748f0553a23d + d7dd4362430dab37e07408195c76a105b08f1cc0 - + https://github.com/dotnet/razor - 95d21239fc7a81d0c7e6a6c7abf4748f0553a23d + d7dd4362430dab37e07408195c76a105b08f1cc0 - + https://github.com/dotnet/razor - 95d21239fc7a81d0c7e6a6c7abf4748f0553a23d + d7dd4362430dab37e07408195c76a105b08f1cc0 https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore diff --git a/eng/Versions.props b/eng/Versions.props index 825bd3fff589..a549a295d33c 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -175,9 +175,9 @@ - 7.0.0-preview.24178.2 - 7.0.0-preview.24178.2 - 7.0.0-preview.24178.2 + 7.0.0-preview.24205.6 + 7.0.0-preview.24205.6 + 7.0.0-preview.24205.6 From d868780276cffe5333ad0095d34d0305e1f0d739 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Sun, 7 Apr 2024 11:00:51 +0000 Subject: [PATCH 534/577] [release/8.0.3xx] Update dependencies from dotnet/fsharp (#40032) [release/8.0.3xx] Update dependencies from dotnet/fsharp - Skip the ChangeFileInDependency test --- eng/Version.Details.xml | 8 ++++---- eng/Versions.props | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 63969664891d..cf8ba633d520 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -64,13 +64,13 @@ dbf652edbedb4e6c612a79cc6907d211c74329d6 - + https://github.com/dotnet/fsharp - b2b9c946d36e8174c4a7d8e675d2c65f9f2a47c9 + 838941fa57f6c200e4cbb47e6d32575828b398f5 - + https://github.com/dotnet/fsharp - b2b9c946d36e8174c4a7d8e675d2c65f9f2a47c9 + 838941fa57f6c200e4cbb47e6d32575828b398f5 diff --git a/eng/Versions.props b/eng/Versions.props index a549a295d33c..c1cf4caf49d4 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -150,7 +150,7 @@ - 12.8.300-beta.24205.1 + 12.8.300-beta.24205.4 From d07c4c542f19f22e6741760d938577d1b2cdcb8e Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" Date: Sun, 7 Apr 2024 12:57:30 +0000 Subject: [PATCH 535/577] Update dependencies from https://github.com/dotnet/razor build 20240406.1 Microsoft.AspNetCore.Mvc.Razor.Extensions.Tooling.Internal , Microsoft.CodeAnalysis.Razor.Tooling.Internal , Microsoft.NET.Sdk.Razor.SourceGenerators.Transport From Version 7.0.0-preview.24205.6 -> To Version 7.0.0-preview.24206.1 --- eng/Version.Details.xml | 12 ++++++------ eng/Versions.props | 6 +++--- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index cf8ba633d520..84557b79b395 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -281,18 +281,18 @@ https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore da7e9894ce22ef8cc02e5acc56e95a6f8cf8f644 - + https://github.com/dotnet/razor - d7dd4362430dab37e07408195c76a105b08f1cc0 + 8a58a749566788cc7e828daf8b39e35b247fa117 - + https://github.com/dotnet/razor - d7dd4362430dab37e07408195c76a105b08f1cc0 + 8a58a749566788cc7e828daf8b39e35b247fa117 - + https://github.com/dotnet/razor - d7dd4362430dab37e07408195c76a105b08f1cc0 + 8a58a749566788cc7e828daf8b39e35b247fa117 https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore diff --git a/eng/Versions.props b/eng/Versions.props index c1cf4caf49d4..2b081f73ccd8 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -175,9 +175,9 @@ - 7.0.0-preview.24205.6 - 7.0.0-preview.24205.6 - 7.0.0-preview.24205.6 + 7.0.0-preview.24206.1 + 7.0.0-preview.24206.1 + 7.0.0-preview.24206.1 From 6611f0a855f15f371543068d887da974d83efec6 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" Date: Sun, 7 Apr 2024 12:58:08 +0000 Subject: [PATCH 536/577] Update dependencies from https://github.com/dotnet/templating build 20240406.1 Microsoft.TemplateEngine.Abstractions , Microsoft.TemplateEngine.Mocks From Version 8.0.300-preview.24205.1 -> To Version 8.0.300-preview.24206.1 --- eng/Version.Details.xml | 8 ++++---- eng/Versions.props | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index cf8ba633d520..1fcac951f94f 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -1,14 +1,14 @@ - + https://github.com/dotnet/templating - 8108ceec56abdcb34c7289ba4a470cb432ef1ccb + 40c69ed5c711955baf5a624ec83a12e9cd1a8484 - + https://github.com/dotnet/templating - 8108ceec56abdcb34c7289ba4a470cb432ef1ccb + 40c69ed5c711955baf5a624ec83a12e9cd1a8484 https://dev.azure.com/dnceng/internal/_git/dotnet-runtime diff --git a/eng/Versions.props b/eng/Versions.props index c1cf4caf49d4..fe19f9e9a9bf 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -137,13 +137,13 @@ - 8.0.300-preview.24205.1 + 8.0.300-preview.24206.1 $(MicrosoftTemplateEngineAbstractionsPackageVersion) $(MicrosoftTemplateEngineAbstractionsPackageVersion) $(MicrosoftTemplateEngineAbstractionsPackageVersion) $(MicrosoftTemplateEngineAbstractionsPackageVersion) - 8.0.300-preview.24205.1 + 8.0.300-preview.24206.1 $(MicrosoftTemplateEngineMocksPackageVersion) $(MicrosoftTemplateEngineAbstractionsPackageVersion) $(MicrosoftTemplateEngineMocksPackageVersion) From 40759cfc9c10cb3a39af76464afa8abad1c1dba3 Mon Sep 17 00:00:00 2001 From: dotnet bot Date: Sun, 7 Apr 2024 19:45:05 -0700 Subject: [PATCH 537/577] Localized file check-in by OneLocBuild Task: Build definition ID 140: Build ID 2424678 --- .../dotnet-workload/config/xlf/LocalizableStrings.tr.xlf | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Cli/dotnet/commands/dotnet-workload/config/xlf/LocalizableStrings.tr.xlf b/src/Cli/dotnet/commands/dotnet-workload/config/xlf/LocalizableStrings.tr.xlf index 07fe44de371f..f9b20872dda2 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/config/xlf/LocalizableStrings.tr.xlf +++ b/src/Cli/dotnet/commands/dotnet-workload/config/xlf/LocalizableStrings.tr.xlf @@ -5,13 +5,13 @@ Modify or display workload configuration values. To display a value, specify the corresponding command-line option without providing a value. For example: "dotnet workload config --update-mode" - Modify or display workload configuration values. -To display a value, specify the corresponding command-line option without providing a value. For example: "dotnet workload config --update-mode" + İş yükü yapılandırması değerlerini değiştirin veya görüntüleyin. +Bir değeri görüntülemek için, bir değer sağlamadan ilgili komut satırı seçeneğini belirtin. Örnek: "dotnet workload config --update-mode" Controls whether updates should look for workload sets or the latest version of each individual manifest. - Controls whether updates should look for workload sets or the latest version of each individual manifest. + Güncelleştirmelerin iş yükü kümelerini mi yoksa her bir bildirimin en son sürümünü mü araması gerektiğini denetler. From e966d38d0cdf86ff8db69fecce725aed68b273d2 Mon Sep 17 00:00:00 2001 From: Daniel Plaisted Date: Mon, 8 Apr 2024 00:14:21 -0400 Subject: [PATCH 538/577] Delay error when workload set version isn't found --- .../commands/InstallingWorkloadCommand.cs | 2 +- .../install/WorkloadInstallCommand.cs | 16 ++++-- .../install/WorkloadManifestUpdater.cs | 2 +- .../IWorkloadManifestProvider.cs | 6 +-- .../IWorkloadResolver.cs | 6 +-- .../SdkDirectoryWorkloadManifestProvider.cs | 53 ++++++++++++------- .../TempDirectoryWorkloadManifestProvider.cs | 7 ++- .../WorkloadResolver.cs | 28 +++++----- .../FakeManifestProvider.cs | 12 ++--- 9 files changed, 79 insertions(+), 53 deletions(-) diff --git a/src/Cli/dotnet/commands/InstallingWorkloadCommand.cs b/src/Cli/dotnet/commands/InstallingWorkloadCommand.cs index 742fb4618647..ad20210f9b62 100644 --- a/src/Cli/dotnet/commands/InstallingWorkloadCommand.cs +++ b/src/Cli/dotnet/commands/InstallingWorkloadCommand.cs @@ -142,7 +142,7 @@ public IEnumerable InstallWorkloadSet(ITransactionContext private void PrintWorkloadSetTransition(string newVersion) { - var currentVersion = _workloadResolver.GetWorkloadVersion(error: false); + var currentVersion = _workloadResolver.GetWorkloadVersion(); if (currentVersion == null) { Reporter.WriteLine(string.Format(Strings.NewWorkloadSet, newVersion)); diff --git a/src/Cli/dotnet/commands/dotnet-workload/install/WorkloadInstallCommand.cs b/src/Cli/dotnet/commands/dotnet-workload/install/WorkloadInstallCommand.cs index 12c1d0bfd377..78982d9360bc 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/install/WorkloadInstallCommand.cs +++ b/src/Cli/dotnet/commands/dotnet-workload/install/WorkloadInstallCommand.cs @@ -45,13 +45,11 @@ public WorkloadInstallCommand( _workloadInstaller.GetWorkloadInstallationRecordRepository(), _workloadInstaller, _packageSourceLocation, displayManifestUpdates: Verbosity.IsDetailedOrDiagnostic()); _workloadSetVersion = parseResult.GetValue(InstallingWorkloadCommandParser.WorkloadSetVersionOption); - - ValidateWorkloadIdsInput(); } private void ValidateWorkloadIdsInput() { - var availableWorkloads = _workloadResolver.GetAvailableWorkloads(error: false); + var availableWorkloads = _workloadResolver.GetAvailableWorkloads(); foreach (var workloadId in _workloadIds) { if (!availableWorkloads.Select(workload => workload.Id.ToString()).Contains(workloadId)) @@ -69,6 +67,8 @@ public override int Execute() bool usedRollback = !string.IsNullOrWhiteSpace(_fromRollbackDefinition); if (_printDownloadLinkOnly) { + ValidateWorkloadIdsInput(); + Reporter.WriteLine(string.Format(LocalizableStrings.ResolvingPackageUrls, string.Join(", ", _workloadIds))); // Take the union of the currently installed workloads and the ones that are being requested. This is so that if there are updates to the manifests @@ -85,6 +85,8 @@ public override int Execute() } else if (!string.IsNullOrWhiteSpace(_downloadToCacheOption)) { + ValidateWorkloadIdsInput(); + try { // Take the union of the currently installed workloads and the ones that are being requested. This is so that if there are updates to the manifests @@ -112,6 +114,14 @@ public override int Execute() _workloadSetVersionFromGlobalJson = SdkDirectoryWorkloadManifestProvider.GlobalJsonReader.GetWorkloadVersionFromGlobalJson(globaljsonPath); ErrorIfGlobalJsonAndCommandLineMismatch(globaljsonPath); + // Normally we want to validate that the workload IDs specified were valid. However, if there is a global.json file with a workload + // set version specified, and we might update the workload version, then we don't do that check here, because we might not have the right + // workload set installed yet, and trying to list the available workloads would throw an error + if (_skipManifestUpdate || string.IsNullOrEmpty(_workloadSetVersionFromGlobalJson)) + { + ValidateWorkloadIdsInput(); + } + if (string.IsNullOrWhiteSpace(_workloadSetVersion) && string.IsNullOrWhiteSpace(_workloadSetVersionFromGlobalJson)) { var installStateFilePath = Path.Combine(WorkloadInstallType.GetInstallStateFolder(_sdkFeatureBand, _dotnetPath), "default.json"); diff --git a/src/Cli/dotnet/commands/dotnet-workload/install/WorkloadManifestUpdater.cs b/src/Cli/dotnet/commands/dotnet-workload/install/WorkloadManifestUpdater.cs index ffd9e3949d9f..bb91d359cdab 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/install/WorkloadManifestUpdater.cs +++ b/src/Cli/dotnet/commands/dotnet-workload/install/WorkloadManifestUpdater.cs @@ -301,7 +301,7 @@ public async Task> GetManifestPackageDownloadsAsyn return downloads; } - private IEnumerable GetInstalledManifestIds() => _workloadResolver.GetInstalledManifests(error: false).Select(manifest => new ManifestId(manifest.Id)); + private IEnumerable GetInstalledManifestIds() => _workloadResolver.GetInstalledManifests().Select(manifest => new ManifestId(manifest.Id)); private async Task UpdateManifestWithVersionAsync(string id, bool includePreviews, SdkFeatureBand band, NuGetVersion packageVersion = null, DirectoryPath? offlineCache = null) { diff --git a/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/IWorkloadManifestProvider.cs b/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/IWorkloadManifestProvider.cs index a396a0a35204..f6a5e9676624 100644 --- a/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/IWorkloadManifestProvider.cs +++ b/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/IWorkloadManifestProvider.cs @@ -9,12 +9,12 @@ namespace Microsoft.NET.Sdk.WorkloadManifestReader ///
public interface IWorkloadManifestProvider { - void RefreshWorkloadManifests(bool error = true); - IEnumerable GetManifests(bool initializeManifests = true); + void RefreshWorkloadManifests(); + IEnumerable GetManifests(); string GetSdkFeatureBand(); - string? GetWorkloadVersion(bool error = true); + string? GetWorkloadVersion(); Dictionary GetAvailableWorkloadSets(); } diff --git a/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/IWorkloadResolver.cs b/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/IWorkloadResolver.cs index 0004dccc1e60..05a86f60d3b5 100644 --- a/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/IWorkloadResolver.cs +++ b/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/IWorkloadResolver.cs @@ -14,12 +14,12 @@ public interface IWorkloadResolver /// Deduplicated enumeration of workload infos. IEnumerable GetExtendedWorkloads(IEnumerable workloadIds); ISet? GetWorkloadSuggestionForMissingPacks(IList packId, out ISet unsatisfiablePacks); - IEnumerable GetAvailableWorkloads(bool error = true); + IEnumerable GetAvailableWorkloads(); bool IsPlatformIncompatibleWorkload(WorkloadId workloadId); string GetManifestVersion(string manifestId); - IEnumerable GetInstalledManifests(bool error = true); + IEnumerable GetInstalledManifests(); string GetSdkFeatureBand(); - string? GetWorkloadVersion(bool error = true); + string? GetWorkloadVersion(); IEnumerable GetUpdatedWorkloads(WorkloadResolver advertisingManifestResolver, IEnumerable installedWorkloads); WorkloadManifest GetManifestFromWorkload(WorkloadId workloadId); diff --git a/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/SdkDirectoryWorkloadManifestProvider.cs b/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/SdkDirectoryWorkloadManifestProvider.cs index 13fe69a1e01c..55a9931aff17 100644 --- a/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/SdkDirectoryWorkloadManifestProvider.cs +++ b/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/SdkDirectoryWorkloadManifestProvider.cs @@ -26,7 +26,12 @@ public partial class SdkDirectoryWorkloadManifestProvider : IWorkloadManifestPro private WorkloadSet? _workloadSet; private WorkloadSet? _manifestsFromInstallState; private string? _installStateFilePath; - private bool _initializedManifests = false; + + // This will be non-null if there is an error loading manifests that should be thrown when they need to be accessed. + // We delay throwing the error so that in the case where global.json specifies a workload set that isn't installed, + // we can successfully construct a resolver and install that workload set + private Exception? _exceptionToThrow = null; + string? _globalJsonWorkloadSetVersion; public SdkDirectoryWorkloadManifestProvider(string sdkRootPath, string sdkVersion, string? userProfileDir, string? globalJsonPath) : this(sdkRootPath, sdkVersion, Environment.GetEnvironmentVariable, userProfileDir, globalJsonPath) @@ -102,10 +107,16 @@ internal SdkDirectoryWorkloadManifestProvider(string sdkRootPath, string sdkVers } _manifestRoots ??= Array.Empty(); + + RefreshWorkloadManifests(); } - public void RefreshWorkloadManifests(bool error = true) + public void RefreshWorkloadManifests() { + // Reset exception state, we may be refreshing manifests after a missing workload set was installed + _exceptionToThrow = null; + _globalJsonWorkloadSetVersion = null; + _workloadSet = null; _manifestsFromInstallState = null; _installStateFilePath = null; @@ -113,7 +124,7 @@ public void RefreshWorkloadManifests(bool error = true) if (_workloadSetVersionFromConstructor != null) { - if (!availableWorkloadSets.TryGetValue(_workloadSetVersionFromConstructor, out _workloadSet) && error) + if (!availableWorkloadSets.TryGetValue(_workloadSetVersionFromConstructor, out _workloadSet)) { throw new FileNotFoundException(string.Format(Strings.WorkloadVersionNotFound, _workloadSetVersionFromConstructor)); } @@ -121,12 +132,13 @@ public void RefreshWorkloadManifests(bool error = true) if (_workloadSet is null) { - string? globalJsonWorkloadSetVersion = GlobalJsonReader.GetWorkloadVersionFromGlobalJson(_globalJsonPathFromConstructor); - if (globalJsonWorkloadSetVersion != null) + _globalJsonWorkloadSetVersion = GlobalJsonReader.GetWorkloadVersionFromGlobalJson(_globalJsonPathFromConstructor); + if (_globalJsonWorkloadSetVersion != null) { - if (!availableWorkloadSets.TryGetValue(globalJsonWorkloadSetVersion, out _workloadSet) && error) + if (!availableWorkloadSets.TryGetValue(_globalJsonWorkloadSetVersion, out _workloadSet)) { - throw new FileNotFoundException(string.Format(Strings.WorkloadVersionFromGlobalJsonNotFound, globalJsonWorkloadSetVersion, _globalJsonPathFromConstructor)); + _exceptionToThrow = new FileNotFoundException(string.Format(Strings.WorkloadVersionFromGlobalJsonNotFound, _globalJsonWorkloadSetVersion, _globalJsonPathFromConstructor)); + return; } } } @@ -144,7 +156,7 @@ public void RefreshWorkloadManifests(bool error = true) _manifestsFromInstallState = installState.Manifests is null ? null : WorkloadSet.FromDictionaryForJson(installState.Manifests, _sdkVersionBand); _installStateFilePath = installStateFilePath; } - else if (error) + else { throw new FileNotFoundException(string.Format(Strings.WorkloadVersionFromInstallStateNotFound, installState.WorkloadVersion, installStateFilePath)); } @@ -157,17 +169,25 @@ public void RefreshWorkloadManifests(bool error = true) var maxWorkloadSetVersion = availableWorkloadSets.Keys.Select(k => new ReleaseVersion(k)).Max()!; _workloadSet = availableWorkloadSets[maxWorkloadSetVersion.ToString()]; } + } - _initializedManifests |= error; + void ThrowExceptionIfManifestsNotAvailable() + { + if (_exceptionToThrow != null) + { + throw _exceptionToThrow; + } } - public string? GetWorkloadVersion(bool error = true) + public string? GetWorkloadVersion() { - if (!_initializedManifests) + if (_globalJsonWorkloadSetVersion != null) { - RefreshWorkloadManifests(error); + return _globalJsonWorkloadSetVersion; } + ThrowExceptionIfManifestsNotAvailable(); + if (_workloadSet?.Version is not null) { return _workloadSet?.Version!; @@ -176,7 +196,7 @@ public void RefreshWorkloadManifests(bool error = true) using (SHA256 sha256Hash = SHA256.Create()) { byte[] bytes = sha256Hash.ComputeHash(Encoding.UTF8.GetBytes(string.Join(";", - GetManifests(initializeManifests: false).OrderBy(m => m.ManifestId).Select(m => $"{m.ManifestId}.{m.ManifestFeatureBand}.{m.ManifestVersion}").ToArray() + GetManifests().OrderBy(m => m.ManifestId).Select(m => $"{m.ManifestId}.{m.ManifestFeatureBand}.{m.ManifestVersion}").ToArray() ))); // Only append the first four bytes to the version hash. @@ -191,12 +211,9 @@ public void RefreshWorkloadManifests(bool error = true) } } - public IEnumerable GetManifests(bool initializeManifests = true) + public IEnumerable GetManifests() { - if (!_initializedManifests && initializeManifests) - { - RefreshWorkloadManifests(); - } + ThrowExceptionIfManifestsNotAvailable(); // Scan manifest directories var manifestIdsToManifests = new Dictionary(StringComparer.OrdinalIgnoreCase); diff --git a/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/TempDirectoryWorkloadManifestProvider.cs b/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/TempDirectoryWorkloadManifestProvider.cs index 10f4dd077795..79d1351d9f90 100644 --- a/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/TempDirectoryWorkloadManifestProvider.cs +++ b/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/TempDirectoryWorkloadManifestProvider.cs @@ -14,10 +14,9 @@ public TempDirectoryWorkloadManifestProvider(string manifestsPath, string sdkFea _sdkVersionBand = sdkFeatureBand; } - public void RefreshWorkloadManifests(bool error = true) { } + public void RefreshWorkloadManifests() { } - public IEnumerable - GetManifests(bool initializeManifests = true) + public IEnumerable GetManifests() { foreach (var workloadManifestDirectory in GetManifestDirectories()) { @@ -54,7 +53,7 @@ public IEnumerable GetManifestDirectories() } public string GetSdkFeatureBand() => _sdkVersionBand; - public string? GetWorkloadVersion(bool error = true) => _sdkVersionBand.ToString() + ".2"; + public string? GetWorkloadVersion() => _sdkVersionBand.ToString() + ".2"; public Dictionary GetAvailableWorkloadSets() => new(); } } diff --git a/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/WorkloadResolver.cs b/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/WorkloadResolver.cs index 66b7c1f33cd0..afb07924ba21 100644 --- a/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/WorkloadResolver.cs +++ b/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/WorkloadResolver.cs @@ -84,11 +84,11 @@ private WorkloadResolver(IWorkloadManifestProvider manifestProvider, (string pat _manifestProvider = manifestProvider; } - private void InitializeManifests(bool error = true) + private void InitializeManifests() { if (!_initializedManifests) { - LoadManifestsFromProvider(_manifestProvider, error); + LoadManifestsFromProvider(_manifestProvider); ComposeWorkloadManifests(); _initializedManifests = true; } @@ -117,11 +117,11 @@ public void RefreshWorkloadManifests() ComposeWorkloadManifests(); } - public string? GetWorkloadVersion(bool error = true) => _manifestProvider.GetWorkloadVersion(error: error); + public string? GetWorkloadVersion() => _manifestProvider.GetWorkloadVersion(); - private void LoadManifestsFromProvider(IWorkloadManifestProvider manifestProvider, bool error = true) + private void LoadManifestsFromProvider(IWorkloadManifestProvider manifestProvider) { - foreach (var readableManifest in manifestProvider.GetManifests(initializeManifests: error)) + foreach (var readableManifest in manifestProvider.GetManifests()) { using (Stream manifestStream = readableManifest.OpenManifestStream()) using (Stream? localizationStream = readableManifest.OpenLocalizationStream()) @@ -550,12 +550,12 @@ public IEnumerable GetExtendedWorkloads(IEnumerable wo /// /// Returns the list of workloads available (installed or not) on the current platform, defined by the manifests on disk /// - public IEnumerable GetAvailableWorkloads(bool error = true) - => GetAvailableWorkloadDefinitions(error).Select(w => new WorkloadInfo(w.workload.Id, w.workload.Description)); + public IEnumerable GetAvailableWorkloads() + => GetAvailableWorkloadDefinitions().Select(w => new WorkloadInfo(w.workload.Id, w.workload.Description)); - private IEnumerable<(WorkloadDefinition workload, WorkloadManifest manifest)> GetAvailableWorkloadDefinitions(bool error = true) + private IEnumerable<(WorkloadDefinition workload, WorkloadManifest manifest)> GetAvailableWorkloadDefinitions() { - InitializeManifests(error); + InitializeManifests(); foreach ((WorkloadId _, (WorkloadDefinition workload, WorkloadManifest manifest)) in _workloads) { if (!workload.IsAbstract && IsWorkloadPlatformCompatible(workload, manifest) && !IsWorkloadImplicitlyAbstract(workload, manifest)) @@ -751,9 +751,9 @@ public string GetManifestVersion(string manifestId) throw new Exception($"Manifest with id {manifestId} does not exist."); } - public IEnumerable GetInstalledManifests(bool error = true) + public IEnumerable GetInstalledManifests() { - InitializeManifests(error); + InitializeManifests(); return _manifests.Select(t => t.Value.info); } @@ -766,11 +766,11 @@ public EmptyWorkloadManifestProvider(string sdkFeatureBand) _sdkFeatureBand = sdkFeatureBand; } - public void RefreshWorkloadManifests(bool error = true) { } + public void RefreshWorkloadManifests() { } public Dictionary GetAvailableWorkloadSets() => new(); - public IEnumerable GetManifests(bool initializeManifests = true) => Enumerable.Empty(); + public IEnumerable GetManifests() => Enumerable.Empty(); public string GetSdkFeatureBand() => _sdkFeatureBand; - public string? GetWorkloadVersion(bool error = true) => _sdkFeatureBand.ToString() + ".2"; + public string? GetWorkloadVersion() => _sdkFeatureBand.ToString() + ".2"; } } diff --git a/src/Tests/Microsoft.NET.Sdk.WorkloadManifestReader.Tests/FakeManifestProvider.cs b/src/Tests/Microsoft.NET.Sdk.WorkloadManifestReader.Tests/FakeManifestProvider.cs index f91445d664a7..7c8fa003a368 100644 --- a/src/Tests/Microsoft.NET.Sdk.WorkloadManifestReader.Tests/FakeManifestProvider.cs +++ b/src/Tests/Microsoft.NET.Sdk.WorkloadManifestReader.Tests/FakeManifestProvider.cs @@ -20,9 +20,9 @@ public FakeManifestProvider(params (string manifest, string? localizationCatalog _filePaths = filePaths; } - public void RefreshWorkloadManifests(bool error = true) { } + public void RefreshWorkloadManifests() { } - public IEnumerable GetManifests(bool initializeManifests = true) + public IEnumerable GetManifests() { foreach (var filePath in _filePaths) { @@ -40,7 +40,7 @@ public IEnumerable GetManifests(bool initializeManifes public string GetSdkFeatureBand() => "8.0.100"; public Dictionary GetAvailableWorkloadSets() => throw new NotImplementedException(); - public string? GetWorkloadVersion(bool error = true) => "8.0.100.2"; + public string? GetWorkloadVersion() => "8.0.100.2"; } internal class InMemoryFakeManifestProvider : IWorkloadManifestProvider, IEnumerable<(string id, string content)> @@ -49,9 +49,9 @@ internal class InMemoryFakeManifestProvider : IWorkloadManifestProvider, IEnumer public void Add(string id, string content) => _manifests.Add((id, Encoding.UTF8.GetBytes(content))); - public void RefreshWorkloadManifests(bool error = true) { } + public void RefreshWorkloadManifests() { } - public IEnumerable GetManifests(bool initializeManifests = true) + public IEnumerable GetManifests() => _manifests.Select(m => new ReadableWorkloadManifest( m.id, $@"C:\fake\{m.id}", @@ -67,6 +67,6 @@ public IEnumerable GetManifests(bool initializeManifes IEnumerator IEnumerable.GetEnumerator() => throw new NotImplementedException(); public string GetSdkFeatureBand() => "8.0.100"; public Dictionary GetAvailableWorkloadSets() => throw new NotImplementedException(); - public string? GetWorkloadVersion(bool error = true) => "8.0.100.2"; + public string? GetWorkloadVersion() => "8.0.100.2"; } } From e4788f5a37ae50f733c822c6d6c0275d71581e51 Mon Sep 17 00:00:00 2001 From: Daniel Plaisted Date: Mon, 8 Apr 2024 07:06:00 -0400 Subject: [PATCH 539/577] Fix build breaks --- .../dotnet-workload-install.Tests/MockManifestProvider.cs | 6 +++--- .../dotnet-workload-search.Tests/MockWorkloadResolver.cs | 6 +++--- .../dotnet.Tests/dotnet-new/WorkloadsInfoProviderTests.cs | 2 +- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/Tests/dotnet-workload-install.Tests/MockManifestProvider.cs b/src/Tests/dotnet-workload-install.Tests/MockManifestProvider.cs index 85dfa0d64354..935fb9addfe8 100644 --- a/src/Tests/dotnet-workload-install.Tests/MockManifestProvider.cs +++ b/src/Tests/dotnet-workload-install.Tests/MockManifestProvider.cs @@ -29,9 +29,9 @@ public MockManifestProvider(params (string name, string path, string featureBand public Dictionary GetAvailableWorkloadSets() => new(); - public void RefreshWorkloadManifests(bool error = true) { } + public void RefreshWorkloadManifests() { } - public IEnumerable GetManifests(bool initializeManifests = true) + public IEnumerable GetManifests() { foreach ((var id, var path, var featureBand) in _manifests) { @@ -48,6 +48,6 @@ public IEnumerable GetManifests(bool initializeManifes } public string GetSdkFeatureBand() => SdkFeatureBand.ToString(); - public string GetWorkloadVersion(bool error = true) => SdkFeatureBand.ToString() + ".2"; + public string GetWorkloadVersion() => SdkFeatureBand.ToString() + ".2"; } } diff --git a/src/Tests/dotnet-workload-search.Tests/MockWorkloadResolver.cs b/src/Tests/dotnet-workload-search.Tests/MockWorkloadResolver.cs index 45d7ca3479c4..5a9bdd9cb706 100644 --- a/src/Tests/dotnet-workload-search.Tests/MockWorkloadResolver.cs +++ b/src/Tests/dotnet-workload-search.Tests/MockWorkloadResolver.cs @@ -14,7 +14,7 @@ public MockWorkloadResolver(IEnumerable available _availableWorkloads = availableWorkloads; } - public IEnumerable GetAvailableWorkloads(bool error = true) => _availableWorkloads; + public IEnumerable GetAvailableWorkloads() => _availableWorkloads; public IEnumerable GetInstalledWorkloadPacksOfKind(WorkloadPackKind kind) => throw new NotImplementedException(); public IEnumerable GetPacksInWorkload(WorkloadId workloadId) => Array.Empty(); @@ -25,10 +25,10 @@ public void RefreshWorkloadManifests() { } public WorkloadResolver.PackInfo TryGetPackInfo(WorkloadPackId packId) => throw new NotImplementedException(); public bool IsPlatformIncompatibleWorkload(WorkloadId workloadId) => throw new NotImplementedException(); public string GetManifestVersion(string manifestId) => throw new NotImplementedException(); - public IEnumerable GetInstalledManifests(bool error = true) => throw new NotImplementedException(); + public IEnumerable GetInstalledManifests() => throw new NotImplementedException(); public IWorkloadResolver CreateOverlayResolver(IWorkloadManifestProvider overlayManifestProvider) => throw new NotImplementedException(); public string GetSdkFeatureBand() => "12.0.400"; - public string GetWorkloadVersion(bool error = true) => "12.0.400.2"; + public string GetWorkloadVersion() => "12.0.400.2"; public IEnumerable GetUpdatedWorkloads(WorkloadResolver advertisingManifestResolver, IEnumerable installedWorkloads) => throw new NotImplementedException(); WorkloadResolver IWorkloadResolver.CreateOverlayResolver(IWorkloadManifestProvider overlayManifestProvider) => throw new NotImplementedException(); WorkloadManifest IWorkloadResolver.GetManifestFromWorkload(WorkloadId workloadId) => throw new NotImplementedException(); diff --git a/src/Tests/dotnet.Tests/dotnet-new/WorkloadsInfoProviderTests.cs b/src/Tests/dotnet.Tests/dotnet-new/WorkloadsInfoProviderTests.cs index eddfcfb2b6d0..8dc621494ff7 100644 --- a/src/Tests/dotnet.Tests/dotnet-new/WorkloadsInfoProviderTests.cs +++ b/src/Tests/dotnet.Tests/dotnet-new/WorkloadsInfoProviderTests.cs @@ -23,7 +23,7 @@ public void InstalledWorkloads_ShouldReturnExpectedWorkloads() var repoMock = new Mock(); resolverMock - .Setup(r => r.GetAvailableWorkloads(true)) + .Setup(r => r.GetAvailableWorkloads()) .Returns(Enumerable.Empty()); repoMock From 25f3049a0dcb6754d7f282bf151666edfbadfd04 Mon Sep 17 00:00:00 2001 From: Daniel Plaisted Date: Mon, 8 Apr 2024 11:18:43 -0400 Subject: [PATCH 540/577] Fix tests --- .../SdkDirectoryWorkloadManifestProvider.cs | 12 ++++++------ .../WorkloadResolver.cs | 7 +++++-- .../ManifestTests.cs | 7 +++++-- .../SdkDirectoryWorkloadManifestProviderTests.cs | 3 ++- .../GivenDotnetWorkloadInstall.cs | 6 ++++-- 5 files changed, 22 insertions(+), 13 deletions(-) diff --git a/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/SdkDirectoryWorkloadManifestProvider.cs b/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/SdkDirectoryWorkloadManifestProvider.cs index 55a9931aff17..9ff6a1a9f829 100644 --- a/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/SdkDirectoryWorkloadManifestProvider.cs +++ b/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/SdkDirectoryWorkloadManifestProvider.cs @@ -151,16 +151,16 @@ public void RefreshWorkloadManifests() var installState = InstallStateContents.FromPath(installStateFilePath); if (!string.IsNullOrEmpty(installState.WorkloadVersion)) { - if (availableWorkloadSets.TryGetValue(installState.WorkloadVersion!, out _workloadSet)) - { - _manifestsFromInstallState = installState.Manifests is null ? null : WorkloadSet.FromDictionaryForJson(installState.Manifests, _sdkVersionBand); - _installStateFilePath = installStateFilePath; - } - else + if (!availableWorkloadSets.TryGetValue(installState.WorkloadVersion!, out _workloadSet)) { throw new FileNotFoundException(string.Format(Strings.WorkloadVersionFromInstallStateNotFound, installState.WorkloadVersion, installStateFilePath)); } } + + // Note: It is possible here to have both a workload set and loose manifests listed in the install state. This might happen if there is a + // third-party workload manifest installed that's not part of the workload set + _manifestsFromInstallState = installState.Manifests is null ? null : WorkloadSet.FromDictionaryForJson(installState.Manifests, _sdkVersionBand); + _installStateFilePath = installStateFilePath; } } diff --git a/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/WorkloadResolver.cs b/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/WorkloadResolver.cs index afb07924ba21..90a3137c9ded 100644 --- a/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/WorkloadResolver.cs +++ b/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/WorkloadResolver.cs @@ -113,8 +113,8 @@ public void RefreshWorkloadManifests() _manifestProvider.RefreshWorkloadManifests(); _manifests.Clear(); - LoadManifestsFromProvider(_manifestProvider); - ComposeWorkloadManifests(); + _initializedManifests = false; + InitializeManifests(); } public string? GetWorkloadVersion() => _manifestProvider.GetWorkloadVersion(); @@ -647,6 +647,9 @@ public WorkloadResolver CreateOverlayResolver(IWorkloadManifestProvider overlayM overlayResolver.ComposeWorkloadManifests(); + // Because we're injecting additional manifests, InitializeManifests isn't used for the overlay resolver + overlayResolver._initializedManifests = true; + return overlayResolver; } diff --git a/src/Tests/Microsoft.NET.Sdk.WorkloadManifestReader.Tests/ManifestTests.cs b/src/Tests/Microsoft.NET.Sdk.WorkloadManifestReader.Tests/ManifestTests.cs index bbef970d5fd6..48c65e70846f 100644 --- a/src/Tests/Microsoft.NET.Sdk.WorkloadManifestReader.Tests/ManifestTests.cs +++ b/src/Tests/Microsoft.NET.Sdk.WorkloadManifestReader.Tests/ManifestTests.cs @@ -179,7 +179,9 @@ static string MakeManifest(string version, params (string id, string version)[] { "AAA", MakeManifest("20.0.0", ("BBB", "5.0.0"), ("CCC", "63.0.0"), ("DDD", "25.0.0")) } }; - var missingManifestEx = Assert.Throws(() => WorkloadResolver.CreateForTests(missingManifestProvider, fakeRootPath)); + var missingManifestResolver = WorkloadResolver.CreateForTests(missingManifestProvider, fakeRootPath); + + var missingManifestEx = Assert.Throws(() => missingManifestResolver.GetAvailableWorkloads().ToList()); Assert.StartsWith("Did not find workload manifest dependency 'BBB' required by manifest 'AAA'", missingManifestEx.Message); var inconsistentManifestProvider = new InMemoryFakeManifestProvider @@ -190,7 +192,8 @@ static string MakeManifest(string version, params (string id, string version)[] { "DDD", MakeManifest("30.0.0") }, }; - var inconsistentManifestEx = Assert.Throws(() => WorkloadResolver.CreateForTests(inconsistentManifestProvider, fakeRootPath)); + var inconsistentManifestResolver = WorkloadResolver.CreateForTests(inconsistentManifestProvider, fakeRootPath); + var inconsistentManifestEx = Assert.Throws(() => inconsistentManifestResolver.GetAvailableWorkloads().ToList()); Assert.StartsWith("Workload manifest dependency 'DDD' version '30.0.0' is lower than version '39.0.0' required by manifest 'BBB'", inconsistentManifestEx.Message); } diff --git a/src/Tests/Microsoft.NET.Sdk.WorkloadManifestReader.Tests/SdkDirectoryWorkloadManifestProviderTests.cs b/src/Tests/Microsoft.NET.Sdk.WorkloadManifestReader.Tests/SdkDirectoryWorkloadManifestProviderTests.cs index 44bf3f961184..2c78771b8838 100644 --- a/src/Tests/Microsoft.NET.Sdk.WorkloadManifestReader.Tests/SdkDirectoryWorkloadManifestProviderTests.cs +++ b/src/Tests/Microsoft.NET.Sdk.WorkloadManifestReader.Tests/SdkDirectoryWorkloadManifestProviderTests.cs @@ -552,7 +552,8 @@ public void ItFailsIfWorkloadSetFromGlobalJsonIsNotInstalled() } """); - var ex = Assert.Throws(() => new SdkDirectoryWorkloadManifestProvider(sdkRootPath: _fakeDotnetRootDirectory, sdkVersion: "8.0.200", userProfileDir: null, globalJsonPath: globalJsonPath)); + var manifestProvider = new SdkDirectoryWorkloadManifestProvider(sdkRootPath: _fakeDotnetRootDirectory, sdkVersion: "8.0.200", userProfileDir: null, globalJsonPath: globalJsonPath); + var ex = Assert.Throws(() => manifestProvider.GetManifests()); ex.Message.Should().Be(string.Format(Strings.WorkloadVersionFromGlobalJsonNotFound, "8.0.201", globalJsonPath)); } diff --git a/src/Tests/dotnet-workload-install.Tests/GivenDotnetWorkloadInstall.cs b/src/Tests/dotnet-workload-install.Tests/GivenDotnetWorkloadInstall.cs index 476a5f49894c..8e20301388a3 100644 --- a/src/Tests/dotnet-workload-install.Tests/GivenDotnetWorkloadInstall.cs +++ b/src/Tests/dotnet-workload-install.Tests/GivenDotnetWorkloadInstall.cs @@ -326,8 +326,10 @@ public void GivenWorkloadInstallItErrorsOnUnsupportedPlatform() var parseResult = Parser.Instance.Parse(new string[] { "dotnet", "workload", "install", mockWorkloadId }); var workloadResolverFactory = new MockWorkloadResolverFactory(dotnetRoot, "6.0.100", workloadResolver, userProfileDir: testDirectory); - var exceptionThrown = Assert.Throws(() => new WorkloadInstallCommand(parseResult, reporter: _reporter, workloadResolverFactory, workloadInstaller: installer, - nugetPackageDownloader: nugetDownloader, workloadManifestUpdater: manifestUpdater)); + var command = new WorkloadInstallCommand(parseResult, reporter: _reporter, workloadResolverFactory, workloadInstaller: installer, + nugetPackageDownloader: nugetDownloader, workloadManifestUpdater: manifestUpdater); + + var exceptionThrown = Assert.Throws(() => command.Execute()); exceptionThrown.Message.Should().Be(String.Format(Workloads.Workload.Install.LocalizableStrings.WorkloadNotSupportedOnPlatform, mockWorkloadId)); } From cdd883744d684856f78120e34010a1529bd02c8a Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Mon, 8 Apr 2024 19:54:19 +0000 Subject: [PATCH 541/577] [release/8.0.3xx] Update dependencies from dotnet/razor (#40050) [release/8.0.3xx] Update dependencies from dotnet/razor --- eng/Version.Details.xml | 12 ++++++------ eng/Versions.props | 6 +++--- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 8d7971bd44e6..ddf692b09a5e 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -281,18 +281,18 @@ https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore da7e9894ce22ef8cc02e5acc56e95a6f8cf8f644
- + https://github.com/dotnet/razor - 8a58a749566788cc7e828daf8b39e35b247fa117 + 07e194a65a1a9f85fec3af041aace521300381b7 - + https://github.com/dotnet/razor - 8a58a749566788cc7e828daf8b39e35b247fa117 + 07e194a65a1a9f85fec3af041aace521300381b7 - + https://github.com/dotnet/razor - 8a58a749566788cc7e828daf8b39e35b247fa117 + 07e194a65a1a9f85fec3af041aace521300381b7 https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore diff --git a/eng/Versions.props b/eng/Versions.props index 41f5eac29a0a..7ab00500dd5e 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -175,9 +175,9 @@ - 7.0.0-preview.24206.1 - 7.0.0-preview.24206.1 - 7.0.0-preview.24206.1 + 7.0.0-preview.24208.1 + 7.0.0-preview.24208.1 + 7.0.0-preview.24208.1 From aa42250d2e85b39c6c31c8af859ede4389916ef8 Mon Sep 17 00:00:00 2001 From: Forgind <12969783+Forgind@users.noreply.github.com> Date: Mon, 8 Apr 2024 14:17:00 -0700 Subject: [PATCH 542/577] Skip manifest check for g.j install/update --- .../commands/InstallingWorkloadCommand.cs | 2 +- .../install/WorkloadManifestUpdater.cs | 29 +++++++++---------- 2 files changed, 14 insertions(+), 17 deletions(-) diff --git a/src/Cli/dotnet/commands/InstallingWorkloadCommand.cs b/src/Cli/dotnet/commands/InstallingWorkloadCommand.cs index ad20210f9b62..213c47eb3c05 100644 --- a/src/Cli/dotnet/commands/InstallingWorkloadCommand.cs +++ b/src/Cli/dotnet/commands/InstallingWorkloadCommand.cs @@ -143,7 +143,7 @@ public IEnumerable InstallWorkloadSet(ITransactionContext private void PrintWorkloadSetTransition(string newVersion) { var currentVersion = _workloadResolver.GetWorkloadVersion(); - if (currentVersion == null) + if (currentVersion == null || !string.IsNullOrWhiteSpace(_workloadSetVersionFromGlobalJson)) { Reporter.WriteLine(string.Format(Strings.NewWorkloadSet, newVersion)); } diff --git a/src/Cli/dotnet/commands/dotnet-workload/install/WorkloadManifestUpdater.cs b/src/Cli/dotnet/commands/dotnet-workload/install/WorkloadManifestUpdater.cs index bb91d359cdab..341da5aefda8 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/install/WorkloadManifestUpdater.cs +++ b/src/Cli/dotnet/commands/dotnet-workload/install/WorkloadManifestUpdater.cs @@ -247,14 +247,12 @@ public IEnumerable CalculateManifestRollbacks(string roll private IEnumerable CalculateManifestRollbacks(IEnumerable<(ManifestId Id, ManifestVersionWithBand ManifestWithBand)> versionUpdates) { - var manifestUpdates = versionUpdates.Select(manifest => + return versionUpdates.Select(manifest => { var (id, (version, band)) = manifest; var (installedVersion, installedBand) = GetInstalledManifestVersion(id); return new ManifestVersionUpdate(id, installedVersion, installedBand.ToString(), version, band.ToString()); }); - - return manifestUpdates; } public async Task> GetManifestPackageDownloadsAsync(bool includePreviews, SdkFeatureBand providedSdkFeatureBand, SdkFeatureBand installedSdkFeatureBand) @@ -475,26 +473,21 @@ private async Task NewerManifestPackageExists(ManifestId manifest) public IEnumerable ParseRollbackDefinitionFiles(IEnumerable rollbackFilePaths) { + var zeroVersion = new ManifestVersion("0.0.0"); if (rollbackFilePaths.Count() == 1) { - return CalculateManifestRollbacks(rollbackFilePaths.Single()); + return ParseRollbackDefinitionFile(rollbackFilePaths.Single(), _sdkFeatureBand).Select(manifest => + { + var (id, (version, band)) = manifest; + return new ManifestVersionUpdate(id, zeroVersion, band.ToString(), version, band.ToString()); + }); } - var currentManifestIds = GetInstalledManifestIds(); // Create a single workload set that includes all the others List<(ManifestId, ManifestVersionWithBand)> fullSet = new(); foreach (var rollbackFile in rollbackFilePaths) { - var rollbacks = ParseRollbackDefinitionFile(rollbackFile, _sdkFeatureBand); - - var unrecognizedManifestIds = rollbacks.Where(rollbackManifest => !currentManifestIds.Contains(rollbackManifest.Id)); - if (unrecognizedManifestIds.Any()) - { - _reporter.WriteLine(string.Format(LocalizableStrings.RollbackDefinitionContainsExtraneousManifestIds, rollbackFile, string.Join(" ", unrecognizedManifestIds)).Yellow()); - rollbacks = rollbacks.Where(rollbackManifest => currentManifestIds.Contains(rollbackManifest.Id)); - } - - fullSet.AddRange(rollbacks); + fullSet.AddRange(ParseRollbackDefinitionFile(rollbackFile, _sdkFeatureBand)); } var reducedFullSet = fullSet.DistinctBy<(ManifestId, ManifestVersionWithBand), ManifestId>(update => update.Item1).ToList(); @@ -504,7 +497,11 @@ public IEnumerable ParseRollbackDefinitionFiles(IEnumerab throw new ArgumentException("There were duplicates of the following manifests between the workload set files: " + string.Join(", ", duplicates)); } - return CalculateManifestRollbacks(fullSet); + return fullSet.Select(manifest => + { + var (id, (version, band)) = manifest; + return new ManifestVersionUpdate(id, zeroVersion, band.ToString(), version, band.ToString()); + }); } private static IEnumerable<(ManifestId Id, ManifestVersionWithBand ManifestWithBand)> ParseRollbackDefinitionFile(string rollbackDefinitionFilePath, SdkFeatureBand featureBand) From 2a228126496d61853ecce4278c30ceeb796ad3c2 Mon Sep 17 00:00:00 2001 From: Forgind <12969783+Forgind@users.noreply.github.com> Date: Mon, 8 Apr 2024 14:28:34 -0700 Subject: [PATCH 543/577] Narrow "skip" condition --- .../commands/dotnet-workload/install/WorkloadInstallCommand.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Cli/dotnet/commands/dotnet-workload/install/WorkloadInstallCommand.cs b/src/Cli/dotnet/commands/dotnet-workload/install/WorkloadInstallCommand.cs index 78982d9360bc..cbca81c1c9ec 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/install/WorkloadInstallCommand.cs +++ b/src/Cli/dotnet/commands/dotnet-workload/install/WorkloadInstallCommand.cs @@ -176,7 +176,8 @@ public void InstallWorkloads(IEnumerable workloadIds, bool skipManif if (!skipManifestUpdate) { var installStateFilePath = Path.Combine(WorkloadInstallType.GetInstallStateFolder(_sdkFeatureBand, _dotnetPath), "default.json"); - if (string.IsNullOrWhiteSpace(_fromRollbackDefinition) && File.Exists(installStateFilePath) && InstallStateContents.FromString(File.ReadAllText(installStateFilePath)).Manifests is not null) + if (string.IsNullOrWhiteSpace(_fromRollbackDefinition) && string.IsNullOrWhiteSpace(_workloadSetVersion) && string.IsNullOrWhiteSpace(_workloadSetVersionFromGlobalJson) && + (InstallStateContents.FromPath(installStateFilePath)?.Manifests is not null) || InstallStateContents.FromPath(installStateFilePath)?.WorkloadVersion is not null) { // If there is a rollback state file, then we don't want to automatically update workloads when a workload is installed // To update to a new version, the user would need to run "dotnet workload update" From b37d2a86193bcd5179d791cc833912fdc0b48fa3 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Tue, 9 Apr 2024 21:13:49 +0000 Subject: [PATCH 544/577] [release/8.0.3xx] Update dependencies from dotnet/fsharp (#40066) [release/8.0.3xx] Update dependencies from dotnet/fsharp --- eng/Version.Details.xml | 8 ++++---- eng/Versions.props | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index ddf692b09a5e..4f7174d38add 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -64,13 +64,13 @@ dbf652edbedb4e6c612a79cc6907d211c74329d6 - + https://github.com/dotnet/fsharp - 838941fa57f6c200e4cbb47e6d32575828b398f5 + 111eeb61b14b3453342b135733cc571cd1dcec3f - + https://github.com/dotnet/fsharp - 838941fa57f6c200e4cbb47e6d32575828b398f5 + 111eeb61b14b3453342b135733cc571cd1dcec3f diff --git a/eng/Versions.props b/eng/Versions.props index 7ab00500dd5e..0b833209bf32 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -150,7 +150,7 @@ - 12.8.300-beta.24205.4 + 12.8.300-beta.24208.5 From 88db8af9f8d9515b118e285715b172a00ece0f57 Mon Sep 17 00:00:00 2001 From: Forgind <12969783+Forgind@users.noreply.github.com> Date: Tue, 9 Apr 2024 15:26:13 -0700 Subject: [PATCH 545/577] Download workload set synchronously --- .../dotnet-workload/install/WorkloadManifestUpdater.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Cli/dotnet/commands/dotnet-workload/install/WorkloadManifestUpdater.cs b/src/Cli/dotnet/commands/dotnet-workload/install/WorkloadManifestUpdater.cs index 341da5aefda8..4c60548cebb4 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/install/WorkloadManifestUpdater.cs +++ b/src/Cli/dotnet/commands/dotnet-workload/install/WorkloadManifestUpdater.cs @@ -88,10 +88,10 @@ public async Task UpdateAdvertisingManifestsAsync(bool includePreviews, bool use } } - public async void DownloadWorkloadSet(string version, DirectoryPath? offlineCache = null) + public void DownloadWorkloadSet(string version, DirectoryPath? offlineCache = null) { var correctedVersion = WorkloadSetVersionToWorkloadSetPackageVersion(version); - await UpdateManifestWithVersionAsync("Microsoft.NET.Workloads", includePreviews: true, _sdkFeatureBand, new NuGetVersion(correctedVersion), offlineCache); + Task.Run(() => UpdateManifestWithVersionAsync("Microsoft.NET.Workloads", includePreviews: true, _sdkFeatureBand, new NuGetVersion(correctedVersion), offlineCache)).Wait(); } public async static Task BackgroundUpdateAdvertisingManifestsAsync(string userProfileDir) From adf2df2fb0b2bfb9fc248a30f5a868d0244dffab Mon Sep 17 00:00:00 2001 From: Forgind <12969783+Forgind@users.noreply.github.com> Date: Tue, 9 Apr 2024 15:26:27 -0700 Subject: [PATCH 546/577] Don't GC global.json-derived workload sets --- .../dotnet-workload/install/WorkloadGarbageCollector.cs | 9 ++++++++- .../SdkDirectoryWorkloadManifestProvider.cs | 8 +++++++- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/src/Cli/dotnet/commands/dotnet-workload/install/WorkloadGarbageCollector.cs b/src/Cli/dotnet/commands/dotnet-workload/install/WorkloadGarbageCollector.cs index 8b75adb64743..96512270be82 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/install/WorkloadGarbageCollector.cs +++ b/src/Cli/dotnet/commands/dotnet-workload/install/WorkloadGarbageCollector.cs @@ -73,7 +73,14 @@ void GarbageCollectWorkloadSets() var resolver = GetResolver(); var installedWorkloadSets = resolver.GetWorkloadManifestProvider().GetAvailableWorkloadSets(); - + + // This version corresponds to the version currently in use, whether from a global.json, install state, etc. + var versionInUse = resolver.GetWorkloadVersion(); + if (installedWorkloadSets.ContainsKey(versionInUse)) + { + WorkloadSetsToKeep.Add(versionInUse); + } + var installStateFilePath = Path.Combine(WorkloadInstallType.GetInstallStateFolder(_sdkFeatureBand, _dotnetDir), "default.json"); if (File.Exists(installStateFilePath)) { diff --git a/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/SdkDirectoryWorkloadManifestProvider.cs b/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/SdkDirectoryWorkloadManifestProvider.cs index 9ff6a1a9f829..2f44b1350083 100644 --- a/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/SdkDirectoryWorkloadManifestProvider.cs +++ b/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/SdkDirectoryWorkloadManifestProvider.cs @@ -40,7 +40,13 @@ public SdkDirectoryWorkloadManifestProvider(string sdkRootPath, string sdkVersio public static SdkDirectoryWorkloadManifestProvider ForWorkloadSet(string sdkRootPath, string sdkVersion, string? userProfileDir, string workloadSetVersion) { - return new SdkDirectoryWorkloadManifestProvider(sdkRootPath, sdkVersion, Environment.GetEnvironmentVariable, userProfileDir, globalJsonPath: null, workloadSetVersion); + return new SdkDirectoryWorkloadManifestProvider( + sdkRootPath, + sdkVersion, + Environment.GetEnvironmentVariable, + userProfileDir, + globalJsonPath: workloadSetVersion is null ? GetGlobalJsonPath(Environment.CurrentDirectory) : null, + workloadSetVersion); } internal SdkDirectoryWorkloadManifestProvider(string sdkRootPath, string sdkVersion, Func getEnvironmentVariable, string? userProfileDir, string? globalJsonPath = null, string? workloadSetVersion = null) From 06478758bbb7a47c9ba3c22a84a405f34b64355a Mon Sep 17 00:00:00 2001 From: Forgind <12969783+Forgind@users.noreply.github.com> Date: Tue, 9 Apr 2024 16:09:38 -0700 Subject: [PATCH 547/577] Use proper string --- .../dotnet-workload/install/NetSdkMsiInstallerClient.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Cli/dotnet/commands/dotnet-workload/install/NetSdkMsiInstallerClient.cs b/src/Cli/dotnet/commands/dotnet-workload/install/NetSdkMsiInstallerClient.cs index 73b24e66f98e..9d3a44e67f11 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/install/NetSdkMsiInstallerClient.cs +++ b/src/Cli/dotnet/commands/dotnet-workload/install/NetSdkMsiInstallerClient.cs @@ -1084,7 +1084,7 @@ private void OnProcessExit(object sender, EventArgs e) void IInstaller.UpdateInstallMode(SdkFeatureBand sdkFeatureBand, bool newMode) { UpdateInstallMode(sdkFeatureBand, newMode); - Reporter.WriteLine(string.Format(LocalizableStrings.UpdatedWorkloadMode, newMode ? "workload sets" : "loose manifests")); + Reporter.WriteLine(string.Format(LocalizableStrings.UpdatedWorkloadMode, newMode ? WorkloadConfigCommandParser.UpdateMode_WorkloadSet : WorkloadConfigCommandParser.UpdateMode_Manifests)); } } } From 3fcaa447cddcbacc175599a46628202787e6e05f Mon Sep 17 00:00:00 2001 From: Forgind <12969783+Forgind@users.noreply.github.com> Date: Wed, 10 Apr 2024 14:34:54 -0700 Subject: [PATCH 548/577] Comments --- .../install/WorkloadGarbageCollector.cs | 6 +-- .../install/WorkloadInstallCommand.cs | 3 +- .../list/LocalizableStrings.resx | 6 +++ .../list/WorkloadListCommand.cs | 49 ++++++++++++------- .../list/xlf/LocalizableStrings.cs.xlf | 10 ++++ .../list/xlf/LocalizableStrings.de.xlf | 10 ++++ .../list/xlf/LocalizableStrings.es.xlf | 10 ++++ .../list/xlf/LocalizableStrings.fr.xlf | 10 ++++ .../list/xlf/LocalizableStrings.it.xlf | 10 ++++ .../list/xlf/LocalizableStrings.ja.xlf | 10 ++++ .../list/xlf/LocalizableStrings.ko.xlf | 10 ++++ .../list/xlf/LocalizableStrings.pl.xlf | 10 ++++ .../list/xlf/LocalizableStrings.pt-BR.xlf | 10 ++++ .../list/xlf/LocalizableStrings.ru.xlf | 10 ++++ .../list/xlf/LocalizableStrings.tr.xlf | 10 ++++ .../list/xlf/LocalizableStrings.zh-Hans.xlf | 10 ++++ .../list/xlf/LocalizableStrings.zh-Hant.xlf | 10 ++++ .../SdkDirectoryWorkloadManifestProvider.cs | 28 ++++++++--- 18 files changed, 192 insertions(+), 30 deletions(-) diff --git a/src/Cli/dotnet/commands/dotnet-workload/install/WorkloadGarbageCollector.cs b/src/Cli/dotnet/commands/dotnet-workload/install/WorkloadGarbageCollector.cs index 96512270be82..88f0bda5a856 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/install/WorkloadGarbageCollector.cs +++ b/src/Cli/dotnet/commands/dotnet-workload/install/WorkloadGarbageCollector.cs @@ -74,11 +74,9 @@ void GarbageCollectWorkloadSets() var installedWorkloadSets = resolver.GetWorkloadManifestProvider().GetAvailableWorkloadSets(); - // This version corresponds to the version currently in use, whether from a global.json, install state, etc. - var versionInUse = resolver.GetWorkloadVersion(); - if (installedWorkloadSets.ContainsKey(versionInUse)) + foreach (var set in installedWorkloadSets.Keys) { - WorkloadSetsToKeep.Add(versionInUse); + WorkloadSetsToKeep.Add(set); } var installStateFilePath = Path.Combine(WorkloadInstallType.GetInstallStateFolder(_sdkFeatureBand, _dotnetDir), "default.json"); diff --git a/src/Cli/dotnet/commands/dotnet-workload/install/WorkloadInstallCommand.cs b/src/Cli/dotnet/commands/dotnet-workload/install/WorkloadInstallCommand.cs index cbca81c1c9ec..930cec725373 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/install/WorkloadInstallCommand.cs +++ b/src/Cli/dotnet/commands/dotnet-workload/install/WorkloadInstallCommand.cs @@ -176,8 +176,9 @@ public void InstallWorkloads(IEnumerable workloadIds, bool skipManif if (!skipManifestUpdate) { var installStateFilePath = Path.Combine(WorkloadInstallType.GetInstallStateFolder(_sdkFeatureBand, _dotnetPath), "default.json"); + var installState = InstallStateContents.FromPath(installStateFilePath); if (string.IsNullOrWhiteSpace(_fromRollbackDefinition) && string.IsNullOrWhiteSpace(_workloadSetVersion) && string.IsNullOrWhiteSpace(_workloadSetVersionFromGlobalJson) && - (InstallStateContents.FromPath(installStateFilePath)?.Manifests is not null) || InstallStateContents.FromPath(installStateFilePath)?.WorkloadVersion is not null) + (installState?.Manifests is not null || installState?.WorkloadVersion is not null)) { // If there is a rollback state file, then we don't want to automatically update workloads when a workload is installed // To update to a new version, the user would need to run "dotnet workload update" diff --git a/src/Cli/dotnet/commands/dotnet-workload/list/LocalizableStrings.resx b/src/Cli/dotnet/commands/dotnet-workload/list/LocalizableStrings.resx index dbb30fdcd881..4ba629fee8d5 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/list/LocalizableStrings.resx +++ b/src/Cli/dotnet/commands/dotnet-workload/list/LocalizableStrings.resx @@ -131,4 +131,10 @@ Workload version: {0} + + Found workload version {0} pinned in the global.json file at {1}. + + + Found workload version {0} pinned in the global.json file at {1}, but it was not installed. Running `dotnet workload install`, `dotnet workload update`, or `dotnet workload restore` may fix this. + \ No newline at end of file diff --git a/src/Cli/dotnet/commands/dotnet-workload/list/WorkloadListCommand.cs b/src/Cli/dotnet/commands/dotnet-workload/list/WorkloadListCommand.cs index 93dcc18f90f3..71a081a028a9 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/list/WorkloadListCommand.cs +++ b/src/Cli/dotnet/commands/dotnet-workload/list/WorkloadListCommand.cs @@ -77,29 +77,42 @@ public override int Execute() } else { - var manifestInfoDict = _workloadListHelper.WorkloadResolver.GetInstalledManifests().ToDictionary(info => info.Id, StringComparer.OrdinalIgnoreCase); - - InstalledWorkloadsCollection installedWorkloads = _workloadListHelper.AddInstalledVsWorkloads(installedList); + var globalJsonInformation = _workloadListHelper.ManifestProvider.GetGlobalJsonInformation(); Reporter.WriteLine(); - PrintableTable> table = new(); - table.AddColumn(InformationStrings.WorkloadIdColumn, workload => workload.Key); - table.AddColumn(InformationStrings.WorkloadManfiestVersionColumn, workload => + if (globalJsonInformation is not null) + { + Reporter.WriteLine(string.Format( + globalJsonInformation.WorkloadVersionInstalled ? + LocalizableStrings.WorkloadSetFromGlobalJsonInstalled : + LocalizableStrings.WorkloadSetFromGlobalJsonNotInstalled, + globalJsonInformation.GlobalJsonVersion, + globalJsonInformation.GlobalJsonPath)); + } + else { - var m = _workloadListHelper.WorkloadResolver.GetManifestFromWorkload(new WorkloadId(workload.Key)); - var manifestInfo = manifestInfoDict[m.Id]; - return m.Version + "/" + manifestInfo.ManifestFeatureBand; - }); - table.AddColumn(InformationStrings.WorkloadSourceColumn, workload => workload.Value); + var manifestInfoDict = _workloadListHelper.WorkloadResolver.GetInstalledManifests().ToDictionary(info => info.Id, StringComparer.OrdinalIgnoreCase); - table.PrintRows(installedWorkloads.AsEnumerable(), l => Reporter.WriteLine(l)); + InstalledWorkloadsCollection installedWorkloads = _workloadListHelper.AddInstalledVsWorkloads(installedList); + PrintableTable> table = new(); + table.AddColumn(InformationStrings.WorkloadIdColumn, workload => workload.Key); + table.AddColumn(InformationStrings.WorkloadManfiestVersionColumn, workload => + { + var m = _workloadListHelper.WorkloadResolver.GetManifestFromWorkload(new WorkloadId(workload.Key)); + var manifestInfo = manifestInfoDict[m.Id]; + return m.Version + "/" + manifestInfo.ManifestFeatureBand; + }); + table.AddColumn(InformationStrings.WorkloadSourceColumn, workload => workload.Value); - var installState = InstallStateContents.FromPath(Path.Combine(WorkloadInstallType.GetInstallStateFolder(_workloadListHelper._currentSdkFeatureBand, _workloadListHelper.DotnetPath), "default.json")); - if (installState.UseWorkloadSets == true) - { - Reporter.WriteLine(); - Reporter.WriteLine(string.Format(LocalizableStrings.WorkloadSetVersion, _workloadListHelper.WorkloadResolver.GetWorkloadVersion() ?? "unknown")); + table.PrintRows(installedWorkloads.AsEnumerable(), l => Reporter.WriteLine(l)); + + var installState = InstallStateContents.FromPath(Path.Combine(WorkloadInstallType.GetInstallStateFolder(_workloadListHelper._currentSdkFeatureBand, _workloadListHelper.DotnetPath), "default.json")); + if (installState.UseWorkloadSets == true) + { + Reporter.WriteLine(); + Reporter.WriteLine(string.Format(LocalizableStrings.WorkloadSetVersion, _workloadListHelper.WorkloadResolver.GetWorkloadVersion() ?? "unknown")); + } } - + Reporter.WriteLine(); Reporter.WriteLine(LocalizableStrings.WorkloadListFooter); Reporter.WriteLine(); diff --git a/src/Cli/dotnet/commands/dotnet-workload/list/xlf/LocalizableStrings.cs.xlf b/src/Cli/dotnet/commands/dotnet-workload/list/xlf/LocalizableStrings.cs.xlf index d7357b6c0252..8388d4cf809b 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/list/xlf/LocalizableStrings.cs.xlf +++ b/src/Cli/dotnet/commands/dotnet-workload/list/xlf/LocalizableStrings.cs.xlf @@ -12,6 +12,16 @@ Pokud chcete najít další úlohy, které se mají nainstalovat, použijte `dotnet workload search`. {Locked="dotnet workload search"}
+ + Found workload version {0} pinned in the global.json file at {1}. + Found workload version {0} pinned in the global.json file at {1}. + + + + Found workload version {0} pinned in the global.json file at {1}, but it was not installed. Running `dotnet workload install`, `dotnet workload update`, or `dotnet workload restore` may fix this. + Found workload version {0} pinned in the global.json file at {1}, but it was not installed. Running `dotnet workload install`, `dotnet workload update`, or `dotnet workload restore` may fix this. + + Workload version: {0} Verze úlohy: {0} diff --git a/src/Cli/dotnet/commands/dotnet-workload/list/xlf/LocalizableStrings.de.xlf b/src/Cli/dotnet/commands/dotnet-workload/list/xlf/LocalizableStrings.de.xlf index b1f539bb2690..2b7cae8f5685 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/list/xlf/LocalizableStrings.de.xlf +++ b/src/Cli/dotnet/commands/dotnet-workload/list/xlf/LocalizableStrings.de.xlf @@ -12,6 +12,16 @@ Verwenden Sie „dotnet workload search“, um zusätzliche zu installierende Workloads zu finden. {Locked="dotnet workload search"} + + Found workload version {0} pinned in the global.json file at {1}. + Found workload version {0} pinned in the global.json file at {1}. + + + + Found workload version {0} pinned in the global.json file at {1}, but it was not installed. Running `dotnet workload install`, `dotnet workload update`, or `dotnet workload restore` may fix this. + Found workload version {0} pinned in the global.json file at {1}, but it was not installed. Running `dotnet workload install`, `dotnet workload update`, or `dotnet workload restore` may fix this. + + Workload version: {0} Workloadversion: {0} diff --git a/src/Cli/dotnet/commands/dotnet-workload/list/xlf/LocalizableStrings.es.xlf b/src/Cli/dotnet/commands/dotnet-workload/list/xlf/LocalizableStrings.es.xlf index 8218b465574c..61884ae6ed7e 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/list/xlf/LocalizableStrings.es.xlf +++ b/src/Cli/dotnet/commands/dotnet-workload/list/xlf/LocalizableStrings.es.xlf @@ -12,6 +12,16 @@ Use "dotnet workload search" para buscar cargas de trabajo adicionales para instalar. {Locked="dotnet workload search"} + + Found workload version {0} pinned in the global.json file at {1}. + Found workload version {0} pinned in the global.json file at {1}. + + + + Found workload version {0} pinned in the global.json file at {1}, but it was not installed. Running `dotnet workload install`, `dotnet workload update`, or `dotnet workload restore` may fix this. + Found workload version {0} pinned in the global.json file at {1}, but it was not installed. Running `dotnet workload install`, `dotnet workload update`, or `dotnet workload restore` may fix this. + + Workload version: {0} Versión de carga de trabajo: {0} diff --git a/src/Cli/dotnet/commands/dotnet-workload/list/xlf/LocalizableStrings.fr.xlf b/src/Cli/dotnet/commands/dotnet-workload/list/xlf/LocalizableStrings.fr.xlf index 048b86c1be46..d2e2ea674228 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/list/xlf/LocalizableStrings.fr.xlf +++ b/src/Cli/dotnet/commands/dotnet-workload/list/xlf/LocalizableStrings.fr.xlf @@ -12,6 +12,16 @@ Utilisez `dotnet workload search` pour rechercher d’autres charges de travail à installer. {Locked="dotnet workload search"} + + Found workload version {0} pinned in the global.json file at {1}. + Found workload version {0} pinned in the global.json file at {1}. + + + + Found workload version {0} pinned in the global.json file at {1}, but it was not installed. Running `dotnet workload install`, `dotnet workload update`, or `dotnet workload restore` may fix this. + Found workload version {0} pinned in the global.json file at {1}, but it was not installed. Running `dotnet workload install`, `dotnet workload update`, or `dotnet workload restore` may fix this. + + Workload version: {0} Version de la charge de travail : {0} diff --git a/src/Cli/dotnet/commands/dotnet-workload/list/xlf/LocalizableStrings.it.xlf b/src/Cli/dotnet/commands/dotnet-workload/list/xlf/LocalizableStrings.it.xlf index 3c864a9ac70e..91f794a602b6 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/list/xlf/LocalizableStrings.it.xlf +++ b/src/Cli/dotnet/commands/dotnet-workload/list/xlf/LocalizableStrings.it.xlf @@ -12,6 +12,16 @@ Utilizzare la `dotnet workload search` per trovare i carichi di lavoro aggiuntivi da installare. {Locked="dotnet workload search"} + + Found workload version {0} pinned in the global.json file at {1}. + Found workload version {0} pinned in the global.json file at {1}. + + + + Found workload version {0} pinned in the global.json file at {1}, but it was not installed. Running `dotnet workload install`, `dotnet workload update`, or `dotnet workload restore` may fix this. + Found workload version {0} pinned in the global.json file at {1}, but it was not installed. Running `dotnet workload install`, `dotnet workload update`, or `dotnet workload restore` may fix this. + + Workload version: {0} Versione carico di lavoro: {0} diff --git a/src/Cli/dotnet/commands/dotnet-workload/list/xlf/LocalizableStrings.ja.xlf b/src/Cli/dotnet/commands/dotnet-workload/list/xlf/LocalizableStrings.ja.xlf index cfa7663bd2c1..3acc87707e82 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/list/xlf/LocalizableStrings.ja.xlf +++ b/src/Cli/dotnet/commands/dotnet-workload/list/xlf/LocalizableStrings.ja.xlf @@ -12,6 +12,16 @@ `dotnet workload search` を使用して追加ワークロードを検出し、インストールします。 {Locked="dotnet workload search"} + + Found workload version {0} pinned in the global.json file at {1}. + Found workload version {0} pinned in the global.json file at {1}. + + + + Found workload version {0} pinned in the global.json file at {1}, but it was not installed. Running `dotnet workload install`, `dotnet workload update`, or `dotnet workload restore` may fix this. + Found workload version {0} pinned in the global.json file at {1}, but it was not installed. Running `dotnet workload install`, `dotnet workload update`, or `dotnet workload restore` may fix this. + + Workload version: {0} ワークロードのバージョン: {0} diff --git a/src/Cli/dotnet/commands/dotnet-workload/list/xlf/LocalizableStrings.ko.xlf b/src/Cli/dotnet/commands/dotnet-workload/list/xlf/LocalizableStrings.ko.xlf index 133c3c43265c..ce709a90f339 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/list/xlf/LocalizableStrings.ko.xlf +++ b/src/Cli/dotnet/commands/dotnet-workload/list/xlf/LocalizableStrings.ko.xlf @@ -12,6 +12,16 @@ `dotnet workload search`을 사용하여 설치할 추가 워크로드를 찾습니다. {Locked="dotnet workload search"} + + Found workload version {0} pinned in the global.json file at {1}. + Found workload version {0} pinned in the global.json file at {1}. + + + + Found workload version {0} pinned in the global.json file at {1}, but it was not installed. Running `dotnet workload install`, `dotnet workload update`, or `dotnet workload restore` may fix this. + Found workload version {0} pinned in the global.json file at {1}, but it was not installed. Running `dotnet workload install`, `dotnet workload update`, or `dotnet workload restore` may fix this. + + Workload version: {0} 워크로드 버전: {0} diff --git a/src/Cli/dotnet/commands/dotnet-workload/list/xlf/LocalizableStrings.pl.xlf b/src/Cli/dotnet/commands/dotnet-workload/list/xlf/LocalizableStrings.pl.xlf index 73887307cace..be461cd2b5cf 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/list/xlf/LocalizableStrings.pl.xlf +++ b/src/Cli/dotnet/commands/dotnet-workload/list/xlf/LocalizableStrings.pl.xlf @@ -12,6 +12,16 @@ Użyj polecenia „dotnet workload search”, aby znaleźć dodatkowe obciążenia do zainstalowania. {Locked="dotnet workload search"} + + Found workload version {0} pinned in the global.json file at {1}. + Found workload version {0} pinned in the global.json file at {1}. + + + + Found workload version {0} pinned in the global.json file at {1}, but it was not installed. Running `dotnet workload install`, `dotnet workload update`, or `dotnet workload restore` may fix this. + Found workload version {0} pinned in the global.json file at {1}, but it was not installed. Running `dotnet workload install`, `dotnet workload update`, or `dotnet workload restore` may fix this. + + Workload version: {0} Wersja obciążenia: {0} diff --git a/src/Cli/dotnet/commands/dotnet-workload/list/xlf/LocalizableStrings.pt-BR.xlf b/src/Cli/dotnet/commands/dotnet-workload/list/xlf/LocalizableStrings.pt-BR.xlf index f6fadc51c77f..a13ba8c15c7f 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/list/xlf/LocalizableStrings.pt-BR.xlf +++ b/src/Cli/dotnet/commands/dotnet-workload/list/xlf/LocalizableStrings.pt-BR.xlf @@ -12,6 +12,16 @@ Use `dotnet workload search` para encontrar cargas de trabalho adicionais a serem instaladas. {Locked="dotnet workload search"} + + Found workload version {0} pinned in the global.json file at {1}. + Found workload version {0} pinned in the global.json file at {1}. + + + + Found workload version {0} pinned in the global.json file at {1}, but it was not installed. Running `dotnet workload install`, `dotnet workload update`, or `dotnet workload restore` may fix this. + Found workload version {0} pinned in the global.json file at {1}, but it was not installed. Running `dotnet workload install`, `dotnet workload update`, or `dotnet workload restore` may fix this. + + Workload version: {0} Versão da carga de trabalho: {0} diff --git a/src/Cli/dotnet/commands/dotnet-workload/list/xlf/LocalizableStrings.ru.xlf b/src/Cli/dotnet/commands/dotnet-workload/list/xlf/LocalizableStrings.ru.xlf index c5eaafb29ba7..9e3f006b8719 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/list/xlf/LocalizableStrings.ru.xlf +++ b/src/Cli/dotnet/commands/dotnet-workload/list/xlf/LocalizableStrings.ru.xlf @@ -12,6 +12,16 @@ Используйте `dotnet workload search`, чтобы найти дополнительные рабочие нагрузки для установки. {Locked="dotnet workload search"} + + Found workload version {0} pinned in the global.json file at {1}. + Found workload version {0} pinned in the global.json file at {1}. + + + + Found workload version {0} pinned in the global.json file at {1}, but it was not installed. Running `dotnet workload install`, `dotnet workload update`, or `dotnet workload restore` may fix this. + Found workload version {0} pinned in the global.json file at {1}, but it was not installed. Running `dotnet workload install`, `dotnet workload update`, or `dotnet workload restore` may fix this. + + Workload version: {0} Версия рабочей нагрузки: {0} diff --git a/src/Cli/dotnet/commands/dotnet-workload/list/xlf/LocalizableStrings.tr.xlf b/src/Cli/dotnet/commands/dotnet-workload/list/xlf/LocalizableStrings.tr.xlf index d06bed8d2488..e289bc9ebf2c 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/list/xlf/LocalizableStrings.tr.xlf +++ b/src/Cli/dotnet/commands/dotnet-workload/list/xlf/LocalizableStrings.tr.xlf @@ -12,6 +12,16 @@ Yüklenecek ek iş yüklerini bulmak için `dotnet workload search` kullanın. {Locked="dotnet workload search"} + + Found workload version {0} pinned in the global.json file at {1}. + Found workload version {0} pinned in the global.json file at {1}. + + + + Found workload version {0} pinned in the global.json file at {1}, but it was not installed. Running `dotnet workload install`, `dotnet workload update`, or `dotnet workload restore` may fix this. + Found workload version {0} pinned in the global.json file at {1}, but it was not installed. Running `dotnet workload install`, `dotnet workload update`, or `dotnet workload restore` may fix this. + + Workload version: {0} İş yükü sürümü: {0} diff --git a/src/Cli/dotnet/commands/dotnet-workload/list/xlf/LocalizableStrings.zh-Hans.xlf b/src/Cli/dotnet/commands/dotnet-workload/list/xlf/LocalizableStrings.zh-Hans.xlf index fb1e4caff827..34c6cab624a8 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/list/xlf/LocalizableStrings.zh-Hans.xlf +++ b/src/Cli/dotnet/commands/dotnet-workload/list/xlf/LocalizableStrings.zh-Hans.xlf @@ -12,6 +12,16 @@ 使用`dotnet workload search`查找要安装的其他工作负载。 {Locked="dotnet workload search"} + + Found workload version {0} pinned in the global.json file at {1}. + Found workload version {0} pinned in the global.json file at {1}. + + + + Found workload version {0} pinned in the global.json file at {1}, but it was not installed. Running `dotnet workload install`, `dotnet workload update`, or `dotnet workload restore` may fix this. + Found workload version {0} pinned in the global.json file at {1}, but it was not installed. Running `dotnet workload install`, `dotnet workload update`, or `dotnet workload restore` may fix this. + + Workload version: {0} 工作负载版本:{0} diff --git a/src/Cli/dotnet/commands/dotnet-workload/list/xlf/LocalizableStrings.zh-Hant.xlf b/src/Cli/dotnet/commands/dotnet-workload/list/xlf/LocalizableStrings.zh-Hant.xlf index c17b8f9ccd3b..95b3e8cb3d85 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/list/xlf/LocalizableStrings.zh-Hant.xlf +++ b/src/Cli/dotnet/commands/dotnet-workload/list/xlf/LocalizableStrings.zh-Hant.xlf @@ -12,6 +12,16 @@ 使用 `dotnet workload search` 尋找其他要安裝的工作負載。 {Locked="dotnet workload search"} + + Found workload version {0} pinned in the global.json file at {1}. + Found workload version {0} pinned in the global.json file at {1}. + + + + Found workload version {0} pinned in the global.json file at {1}, but it was not installed. Running `dotnet workload install`, `dotnet workload update`, or `dotnet workload restore` may fix this. + Found workload version {0} pinned in the global.json file at {1}, but it was not installed. Running `dotnet workload install`, `dotnet workload update`, or `dotnet workload restore` may fix this. + + Workload version: {0} 工作負載版本: {0} diff --git a/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/SdkDirectoryWorkloadManifestProvider.cs b/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/SdkDirectoryWorkloadManifestProvider.cs index 2f44b1350083..564af9deb780 100644 --- a/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/SdkDirectoryWorkloadManifestProvider.cs +++ b/src/Resolvers/Microsoft.NET.Sdk.WorkloadManifestReader/SdkDirectoryWorkloadManifestProvider.cs @@ -40,13 +40,7 @@ public SdkDirectoryWorkloadManifestProvider(string sdkRootPath, string sdkVersio public static SdkDirectoryWorkloadManifestProvider ForWorkloadSet(string sdkRootPath, string sdkVersion, string? userProfileDir, string workloadSetVersion) { - return new SdkDirectoryWorkloadManifestProvider( - sdkRootPath, - sdkVersion, - Environment.GetEnvironmentVariable, - userProfileDir, - globalJsonPath: workloadSetVersion is null ? GetGlobalJsonPath(Environment.CurrentDirectory) : null, - workloadSetVersion); + return new SdkDirectoryWorkloadManifestProvider(sdkRootPath, sdkVersion, Environment.GetEnvironmentVariable, userProfileDir, globalJsonPath: null, workloadSetVersion); } internal SdkDirectoryWorkloadManifestProvider(string sdkRootPath, string sdkVersion, Func getEnvironmentVariable, string? userProfileDir, string? globalJsonPath = null, string? workloadSetVersion = null) @@ -509,5 +503,25 @@ public string GetSdkFeatureBand() } return null; } + + public GlobalJsonInformation? GetGlobalJsonInformation() + { + return _globalJsonWorkloadSetVersion is null || _globalJsonPathFromConstructor is null ? + null : + new GlobalJsonInformation(_globalJsonPathFromConstructor, _globalJsonWorkloadSetVersion, _exceptionToThrow is null); + } + + public record GlobalJsonInformation + { + public string GlobalJsonPath { get; } + public string GlobalJsonVersion { get; } + public bool WorkloadVersionInstalled { get; } + public GlobalJsonInformation(string path, string version, bool installed) + { + GlobalJsonPath = path; + GlobalJsonVersion = version; + WorkloadVersionInstalled = installed; + } + } } } From 78de29e554704a1270da63efc9654fae202c8f85 Mon Sep 17 00:00:00 2001 From: Forgind <12969783+Forgind@users.noreply.github.com> Date: Wed, 10 Apr 2024 15:50:40 -0700 Subject: [PATCH 549/577] Don't error on workload set not found --- .../commands/InstallingWorkloadCommand.cs | 17 +++++++++++++---- .../install/WorkloadInstallCommand.cs | 10 ++++++++-- .../update/LocalizableStrings.resx | 3 +++ .../update/WorkloadUpdateCommand.cs | 10 ++++++++-- .../update/xlf/LocalizableStrings.cs.xlf | 5 +++++ .../update/xlf/LocalizableStrings.de.xlf | 5 +++++ .../update/xlf/LocalizableStrings.es.xlf | 5 +++++ .../update/xlf/LocalizableStrings.fr.xlf | 5 +++++ .../update/xlf/LocalizableStrings.it.xlf | 5 +++++ .../update/xlf/LocalizableStrings.ja.xlf | 5 +++++ .../update/xlf/LocalizableStrings.ko.xlf | 5 +++++ .../update/xlf/LocalizableStrings.pl.xlf | 5 +++++ .../update/xlf/LocalizableStrings.pt-BR.xlf | 5 +++++ .../update/xlf/LocalizableStrings.ru.xlf | 5 +++++ .../update/xlf/LocalizableStrings.tr.xlf | 5 +++++ .../update/xlf/LocalizableStrings.zh-Hans.xlf | 5 +++++ .../update/xlf/LocalizableStrings.zh-Hant.xlf | 5 +++++ 17 files changed, 97 insertions(+), 8 deletions(-) diff --git a/src/Cli/dotnet/commands/InstallingWorkloadCommand.cs b/src/Cli/dotnet/commands/InstallingWorkloadCommand.cs index 213c47eb3c05..fe836666aee5 100644 --- a/src/Cli/dotnet/commands/InstallingWorkloadCommand.cs +++ b/src/Cli/dotnet/commands/InstallingWorkloadCommand.cs @@ -113,7 +113,7 @@ protected void ErrorIfGlobalJsonAndCommandLineMismatch(string globaljsonPath) } } - protected IEnumerable HandleWorkloadUpdateFromVersion(ITransactionContext context, DirectoryPath? offlineCache) + protected bool TryHandleWorkloadUpdateFromVersion(ITransactionContext context, DirectoryPath? offlineCache, out IEnumerable updates) { // Ensure workload set mode is set to 'workloadset' // Do not skip checking the mode first, as setting it triggers @@ -124,10 +124,10 @@ protected IEnumerable HandleWorkloadUpdateFromVersion(ITr } _workloadManifestUpdater.DownloadWorkloadSet(_workloadSetVersionFromGlobalJson ?? _workloadSetVersion, offlineCache); - return InstallWorkloadSet(context); + return TryInstallWorkloadSet(context, out updates); } - public IEnumerable InstallWorkloadSet(ITransactionContext context) + public bool TryInstallWorkloadSet(ITransactionContext context, out IEnumerable updates) { var advertisingPackagePath = Path.Combine(_userProfileDir, "sdk-advertising", _sdkFeatureBand.ToString(), "microsoft.net.workloads"); if (File.Exists(Path.Combine(advertisingPackagePath, Constants.workloadSetVersionFileName))) @@ -135,9 +135,18 @@ public IEnumerable InstallWorkloadSet(ITransactionContext // This file isn't created in tests. PrintWorkloadSetTransition(File.ReadAllText(Path.Combine(advertisingPackagePath, Constants.workloadSetVersionFileName))); } + else if (_workloadInstaller is FileBasedInstaller || _workloadInstaller is NetSdkMsiInstallerClient) + { + // No workload sets found + Reporter.WriteLine(Update.LocalizableStrings.NoWorkloadUpdateFound); + updates = null; + return false; + } + var workloadSetPath = _workloadInstaller.InstallWorkloadSet(context, advertisingPackagePath); var files = Directory.EnumerateFiles(workloadSetPath, "*.workloadset.json"); - return _workloadManifestUpdater.ParseRollbackDefinitionFiles(files); + updates = _workloadManifestUpdater.ParseRollbackDefinitionFiles(files); + return true; } private void PrintWorkloadSetTransition(string newVersion) diff --git a/src/Cli/dotnet/commands/dotnet-workload/install/WorkloadInstallCommand.cs b/src/Cli/dotnet/commands/dotnet-workload/install/WorkloadInstallCommand.cs index 930cec725373..36b70150d406 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/install/WorkloadInstallCommand.cs +++ b/src/Cli/dotnet/commands/dotnet-workload/install/WorkloadInstallCommand.cs @@ -148,7 +148,10 @@ public override int Execute() { RunInNewTransaction(context => { - var manifests = HandleWorkloadUpdateFromVersion(context, offlineCache); + if (!TryHandleWorkloadUpdateFromVersion(context, offlineCache, out var manifests)) + { + return; + } InstallWorkloadsAndGarbageCollect(context, workloadIds, manifests, offlineCache, false); }); } @@ -210,7 +213,10 @@ public void InstallWorkloads(IEnumerable workloadIds, bool skipManif if (useWorkloadSets) { - manifestsToUpdate = InstallWorkloadSet(context); + if (!TryInstallWorkloadSet(context, out manifestsToUpdate)) + { + return; + } } else { diff --git a/src/Cli/dotnet/commands/dotnet-workload/update/LocalizableStrings.resx b/src/Cli/dotnet/commands/dotnet-workload/update/LocalizableStrings.resx index 7121fc1dab52..324afaefc484 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/update/LocalizableStrings.resx +++ b/src/Cli/dotnet/commands/dotnet-workload/update/LocalizableStrings.resx @@ -156,4 +156,7 @@ Updating to a rollback file is not compatible with workload sets. Install and Update will now use loose manifests. To update to a specific workload version, use --version. + + No workload update found. + diff --git a/src/Cli/dotnet/commands/dotnet-workload/update/WorkloadUpdateCommand.cs b/src/Cli/dotnet/commands/dotnet-workload/update/WorkloadUpdateCommand.cs index 77e6a2cac57d..abd839dd6118 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/update/WorkloadUpdateCommand.cs +++ b/src/Cli/dotnet/commands/dotnet-workload/update/WorkloadUpdateCommand.cs @@ -106,7 +106,10 @@ public override int Execute() { RunInNewTransaction(context => { - var manifestUpdates = HandleWorkloadUpdateFromVersion(context, offlineCache); + if (!TryHandleWorkloadUpdateFromVersion(context, offlineCache, out var manifestUpdates)) + { + return; + } UpdateWorkloads(false, manifestUpdates, offlineCache, context); }); } @@ -146,7 +149,10 @@ public void CalculateManifestUpdatesAndUpdateWorkloads(bool includePreviews = fa { if (useWorkloadSets) { - manifestsToUpdate = InstallWorkloadSet(context); + if (!TryInstallWorkloadSet(context, out manifestsToUpdate)) + { + return; + } } else { diff --git a/src/Cli/dotnet/commands/dotnet-workload/update/xlf/LocalizableStrings.cs.xlf b/src/Cli/dotnet/commands/dotnet-workload/update/xlf/LocalizableStrings.cs.xlf index 2bda96c4722a..24be3f66a912 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/update/xlf/LocalizableStrings.cs.xlf +++ b/src/Cli/dotnet/commands/dotnet-workload/update/xlf/LocalizableStrings.cs.xlf @@ -22,6 +22,11 @@ Aktualizuje úlohy na základě zadaného souboru definice vrácení zpět. + + No workload update found. + No workload update found. + + No workloads installed for this feature band. To update workloads installed with earlier SDK versions, include the --from-previous-sdk option. Pro toto pásmo funkcí nejsou nainstalované žádné úlohy. Pokud chcete provést aktualizaci úlohy nainstalované z předchozí sady SDK, přidejte možnost --from-previous-sdk. diff --git a/src/Cli/dotnet/commands/dotnet-workload/update/xlf/LocalizableStrings.de.xlf b/src/Cli/dotnet/commands/dotnet-workload/update/xlf/LocalizableStrings.de.xlf index 05b1a8b2e007..8e8e3bd1d83a 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/update/xlf/LocalizableStrings.de.xlf +++ b/src/Cli/dotnet/commands/dotnet-workload/update/xlf/LocalizableStrings.de.xlf @@ -22,6 +22,11 @@ Aktualisieren Sie Workloads basierend auf der angegebenen Rollbackdefinitionsdatei. + + No workload update found. + No workload update found. + + No workloads installed for this feature band. To update workloads installed with earlier SDK versions, include the --from-previous-sdk option. Für diesen Featurebereich sind keine Workloads installiert. Um Workloads zu aktualisieren, die mit früheren SDK-Versionen installiert wurden, schließen Sie die Option „--from-previous-sdk“ ein. diff --git a/src/Cli/dotnet/commands/dotnet-workload/update/xlf/LocalizableStrings.es.xlf b/src/Cli/dotnet/commands/dotnet-workload/update/xlf/LocalizableStrings.es.xlf index a3b8b2e1d792..c0ce635a45f8 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/update/xlf/LocalizableStrings.es.xlf +++ b/src/Cli/dotnet/commands/dotnet-workload/update/xlf/LocalizableStrings.es.xlf @@ -22,6 +22,11 @@ Actualice las cargas de trabajo en función del archivo de definición de reversión especificado. + + No workload update found. + No workload update found. + + No workloads installed for this feature band. To update workloads installed with earlier SDK versions, include the --from-previous-sdk option. No hay cargas de trabajo instaladas para esta banda de características. Para actualizar las cargas de trabajo instaladas con versiones anteriores del SDK, incluya la opción --from-previous-sdk. diff --git a/src/Cli/dotnet/commands/dotnet-workload/update/xlf/LocalizableStrings.fr.xlf b/src/Cli/dotnet/commands/dotnet-workload/update/xlf/LocalizableStrings.fr.xlf index 08c5734fb317..f27d84da20d2 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/update/xlf/LocalizableStrings.fr.xlf +++ b/src/Cli/dotnet/commands/dotnet-workload/update/xlf/LocalizableStrings.fr.xlf @@ -22,6 +22,11 @@ Mettez à jour les charges de travail en fonction du fichier de définition de restauration spécifié. + + No workload update found. + No workload update found. + + No workloads installed for this feature band. To update workloads installed with earlier SDK versions, include the --from-previous-sdk option. Aucune charge de travail installée pour cette bande de fonctionnalités. Pour mettre à jour les charges de travail installées avec des versions antérieures du SDK, incluez l'option --from-previous-sdk. diff --git a/src/Cli/dotnet/commands/dotnet-workload/update/xlf/LocalizableStrings.it.xlf b/src/Cli/dotnet/commands/dotnet-workload/update/xlf/LocalizableStrings.it.xlf index 3040c6880e23..653623c16e96 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/update/xlf/LocalizableStrings.it.xlf +++ b/src/Cli/dotnet/commands/dotnet-workload/update/xlf/LocalizableStrings.it.xlf @@ -22,6 +22,11 @@ Aggiornare i carichi di lavoro in base al file di definizione di ripristino dello stato precedente specificato. + + No workload update found. + No workload update found. + + No workloads installed for this feature band. To update workloads installed with earlier SDK versions, include the --from-previous-sdk option. Nessun carico di lavoro installato per questa banda di caratteristiche. Per eseguire l'aggiornamento da un SDK precedente, includere l'opzione --from-previous-sdk. diff --git a/src/Cli/dotnet/commands/dotnet-workload/update/xlf/LocalizableStrings.ja.xlf b/src/Cli/dotnet/commands/dotnet-workload/update/xlf/LocalizableStrings.ja.xlf index d7c572c9aa44..610bdd4af408 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/update/xlf/LocalizableStrings.ja.xlf +++ b/src/Cli/dotnet/commands/dotnet-workload/update/xlf/LocalizableStrings.ja.xlf @@ -22,6 +22,11 @@ 指定されたロールバック定義ファイルに基づいてワークロードを更新します。 + + No workload update found. + No workload update found. + + No workloads installed for this feature band. To update workloads installed with earlier SDK versions, include the --from-previous-sdk option. この機能バンドにはワークロードがインストールされていません。以前の SDK バージョンでインストールしたワークロードを更新するには、--from-previous-sdk オプションを含めます。 diff --git a/src/Cli/dotnet/commands/dotnet-workload/update/xlf/LocalizableStrings.ko.xlf b/src/Cli/dotnet/commands/dotnet-workload/update/xlf/LocalizableStrings.ko.xlf index 68df940257eb..baca0da297dd 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/update/xlf/LocalizableStrings.ko.xlf +++ b/src/Cli/dotnet/commands/dotnet-workload/update/xlf/LocalizableStrings.ko.xlf @@ -22,6 +22,11 @@ 지정된 롤백 정의 파일을 기반으로 워크로드를 업데이트합니다. + + No workload update found. + No workload update found. + + No workloads installed for this feature band. To update workloads installed with earlier SDK versions, include the --from-previous-sdk option. 이 기능 밴드에 대해 설치된 워크로드가 없습니다. 이전 SDK 버전으로 설치된 워크로드를 업데이트하려면 --from-previous-sdk 옵션을 포함합니다. diff --git a/src/Cli/dotnet/commands/dotnet-workload/update/xlf/LocalizableStrings.pl.xlf b/src/Cli/dotnet/commands/dotnet-workload/update/xlf/LocalizableStrings.pl.xlf index 968f9e2b24fb..40d51a642576 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/update/xlf/LocalizableStrings.pl.xlf +++ b/src/Cli/dotnet/commands/dotnet-workload/update/xlf/LocalizableStrings.pl.xlf @@ -22,6 +22,11 @@ Zaktualizuj obciążenia na podstawie określonego pliku definicji wycofywania. + + No workload update found. + No workload update found. + + No workloads installed for this feature band. To update workloads installed with earlier SDK versions, include the --from-previous-sdk option. Nie zainstalowano żadnych obciążeń dla tego pasma funkcji. Aby zaktualizować obciążenia zainstalowane przy użyciu wcześniejszych wersji zestawu SDK, dołącz opcję --from-previous-sdk. diff --git a/src/Cli/dotnet/commands/dotnet-workload/update/xlf/LocalizableStrings.pt-BR.xlf b/src/Cli/dotnet/commands/dotnet-workload/update/xlf/LocalizableStrings.pt-BR.xlf index 9580e9b05508..0e22c2eced52 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/update/xlf/LocalizableStrings.pt-BR.xlf +++ b/src/Cli/dotnet/commands/dotnet-workload/update/xlf/LocalizableStrings.pt-BR.xlf @@ -22,6 +22,11 @@ Atualizar cargas de trabalho com base no arquivo de definição de reversão especificado. + + No workload update found. + No workload update found. + + No workloads installed for this feature band. To update workloads installed with earlier SDK versions, include the --from-previous-sdk option. Nenhuma carga de trabalho instalada para esta faixa de recursos. Para atualizar cargas de trabalho instaladas com versões anteriores do SDK, inclua a opção --from-previous-sdk. diff --git a/src/Cli/dotnet/commands/dotnet-workload/update/xlf/LocalizableStrings.ru.xlf b/src/Cli/dotnet/commands/dotnet-workload/update/xlf/LocalizableStrings.ru.xlf index 1b13510a65be..a7a92ade80f8 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/update/xlf/LocalizableStrings.ru.xlf +++ b/src/Cli/dotnet/commands/dotnet-workload/update/xlf/LocalizableStrings.ru.xlf @@ -22,6 +22,11 @@ Обновление рабочих нагрузок на основе указанного файла определения отката. + + No workload update found. + No workload update found. + + No workloads installed for this feature band. To update workloads installed with earlier SDK versions, include the --from-previous-sdk option. Для этого диапазона функций не установлены рабочие нагрузки. Чтобы обновить рабочие нагрузки, установленные в более ранних версиях SDK, включите параметр --from-previous-sdk. diff --git a/src/Cli/dotnet/commands/dotnet-workload/update/xlf/LocalizableStrings.tr.xlf b/src/Cli/dotnet/commands/dotnet-workload/update/xlf/LocalizableStrings.tr.xlf index fdb8fb481136..954b8372a770 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/update/xlf/LocalizableStrings.tr.xlf +++ b/src/Cli/dotnet/commands/dotnet-workload/update/xlf/LocalizableStrings.tr.xlf @@ -22,6 +22,11 @@ İş yüklerini belirtilen geri alma tanım dosyasına göre güncelleştirin. + + No workload update found. + No workload update found. + + No workloads installed for this feature band. To update workloads installed with earlier SDK versions, include the --from-previous-sdk option. Bu özellik bandı için iş yükü yüklenmedi. Önceki SDK sürümleriyle yüklenen iş yüklerini güncelleştirmek için --from-previous-sdk seçeneğini ekleyin. diff --git a/src/Cli/dotnet/commands/dotnet-workload/update/xlf/LocalizableStrings.zh-Hans.xlf b/src/Cli/dotnet/commands/dotnet-workload/update/xlf/LocalizableStrings.zh-Hans.xlf index 8d5aac17dab2..0c6848bd6867 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/update/xlf/LocalizableStrings.zh-Hans.xlf +++ b/src/Cli/dotnet/commands/dotnet-workload/update/xlf/LocalizableStrings.zh-Hans.xlf @@ -22,6 +22,11 @@ 基于指定的回滚定义文件更新工作负载。 + + No workload update found. + No workload update found. + + No workloads installed for this feature band. To update workloads installed with earlier SDK versions, include the --from-previous-sdk option. 没有为此功能带安装工作负载。若要使用更早的 SDK 版本更新已安装的工作负载,请包括“the --from-previous-sdk”选项。 diff --git a/src/Cli/dotnet/commands/dotnet-workload/update/xlf/LocalizableStrings.zh-Hant.xlf b/src/Cli/dotnet/commands/dotnet-workload/update/xlf/LocalizableStrings.zh-Hant.xlf index ef0d84b155cd..f17b6f00fa5c 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/update/xlf/LocalizableStrings.zh-Hant.xlf +++ b/src/Cli/dotnet/commands/dotnet-workload/update/xlf/LocalizableStrings.zh-Hant.xlf @@ -22,6 +22,11 @@ 根據指定的復原定義檔更新工作負載。 + + No workload update found. + No workload update found. + + No workloads installed for this feature band. To update workloads installed with earlier SDK versions, include the --from-previous-sdk option. 此功能帶未安裝任何工作負載。若要更新與舊版本 SDK 一起安裝的工作負載,請包含 --from-previous-sdk 選項。 From 1341d45a2f298957a633fc95f390f32c3fc16b2a Mon Sep 17 00:00:00 2001 From: Forgind <12969783+Forgind@users.noreply.github.com> Date: Wed, 10 Apr 2024 17:06:13 -0700 Subject: [PATCH 550/577] Hide stacks --- .../install/WorkloadInstallCommand.cs | 33 ++++++++++--------- .../update/WorkloadUpdateCommand.cs | 2 +- 2 files changed, 18 insertions(+), 17 deletions(-) diff --git a/src/Cli/dotnet/commands/dotnet-workload/install/WorkloadInstallCommand.cs b/src/Cli/dotnet/commands/dotnet-workload/install/WorkloadInstallCommand.cs index 36b70150d406..02bcd6129b8e 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/install/WorkloadInstallCommand.cs +++ b/src/Cli/dotnet/commands/dotnet-workload/install/WorkloadInstallCommand.cs @@ -112,28 +112,29 @@ public override int Execute() { var globaljsonPath = SdkDirectoryWorkloadManifestProvider.GetGlobalJsonPath(Environment.CurrentDirectory); _workloadSetVersionFromGlobalJson = SdkDirectoryWorkloadManifestProvider.GlobalJsonReader.GetWorkloadVersionFromGlobalJson(globaljsonPath); - ErrorIfGlobalJsonAndCommandLineMismatch(globaljsonPath); - // Normally we want to validate that the workload IDs specified were valid. However, if there is a global.json file with a workload - // set version specified, and we might update the workload version, then we don't do that check here, because we might not have the right - // workload set installed yet, and trying to list the available workloads would throw an error - if (_skipManifestUpdate || string.IsNullOrEmpty(_workloadSetVersionFromGlobalJson)) + try { - ValidateWorkloadIdsInput(); - } + ErrorIfGlobalJsonAndCommandLineMismatch(globaljsonPath); - if (string.IsNullOrWhiteSpace(_workloadSetVersion) && string.IsNullOrWhiteSpace(_workloadSetVersionFromGlobalJson)) - { - var installStateFilePath = Path.Combine(WorkloadInstallType.GetInstallStateFolder(_sdkFeatureBand, _dotnetPath), "default.json"); - if (File.Exists(installStateFilePath)) + // Normally we want to validate that the workload IDs specified were valid. However, if there is a global.json file with a workload + // set version specified, and we might update the workload version, then we don't do that check here, because we might not have the right + // workload set installed yet, and trying to list the available workloads would throw an error + if (_skipManifestUpdate || string.IsNullOrEmpty(_workloadSetVersionFromGlobalJson)) { - var installStateContents = InstallStateContents.FromPath(installStateFilePath); - _workloadSetVersion = installStateContents.WorkloadVersion; + ValidateWorkloadIdsInput(); + } + + if (string.IsNullOrWhiteSpace(_workloadSetVersion) && string.IsNullOrWhiteSpace(_workloadSetVersionFromGlobalJson)) + { + var installStateFilePath = Path.Combine(WorkloadInstallType.GetInstallStateFolder(_sdkFeatureBand, _dotnetPath), "default.json"); + if (File.Exists(installStateFilePath)) + { + var installStateContents = InstallStateContents.FromPath(installStateFilePath); + _workloadSetVersion = installStateContents.WorkloadVersion; + } } - } - try - { DirectoryPath? offlineCache = string.IsNullOrWhiteSpace(_fromCacheOption) ? null : new DirectoryPath(_fromCacheOption); var workloadIds = _workloadIds.Select(id => new WorkloadId(id)); if (string.IsNullOrWhiteSpace(_workloadSetVersion) && string.IsNullOrWhiteSpace(_workloadSetVersionFromGlobalJson)) diff --git a/src/Cli/dotnet/commands/dotnet-workload/update/WorkloadUpdateCommand.cs b/src/Cli/dotnet/commands/dotnet-workload/update/WorkloadUpdateCommand.cs index abd839dd6118..9c3cc9f794e3 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/update/WorkloadUpdateCommand.cs +++ b/src/Cli/dotnet/commands/dotnet-workload/update/WorkloadUpdateCommand.cs @@ -93,10 +93,10 @@ public override int Execute() { var globaljsonPath = SdkDirectoryWorkloadManifestProvider.GetGlobalJsonPath(Environment.CurrentDirectory); _workloadSetVersionFromGlobalJson = SdkDirectoryWorkloadManifestProvider.GlobalJsonReader.GetWorkloadVersionFromGlobalJson(globaljsonPath); - ErrorIfGlobalJsonAndCommandLineMismatch(globaljsonPath); try { + ErrorIfGlobalJsonAndCommandLineMismatch(globaljsonPath); DirectoryPath? offlineCache = string.IsNullOrWhiteSpace(_fromCacheOption) ? null : new DirectoryPath(_fromCacheOption); if (string.IsNullOrWhiteSpace(_workloadSetVersion) && string.IsNullOrWhiteSpace(_workloadSetVersionFromGlobalJson)) { From e6f74fa1ff733cf37935aa8419b8ffb146765be0 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" Date: Thu, 11 Apr 2024 12:50:51 +0000 Subject: [PATCH 551/577] Update dependencies from https://github.com/dotnet/msbuild build 20240411.3 Microsoft.SourceBuild.Intermediate.msbuild , Microsoft.Build , Microsoft.Build.Localization From Version 17.10.0-preview-24202-03 -> To Version 17.10.2-preview-24211-03 --- NuGet.config | 2 +- eng/Version.Details.xml | 12 ++++++------ eng/Versions.props | 4 ++-- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/NuGet.config b/NuGet.config index 09dae3a2170f..195781574335 100644 --- a/NuGet.config +++ b/NuGet.config @@ -14,7 +14,7 @@ - + diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 4f7174d38add..9160c21bc2ed 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -51,17 +51,17 @@ https://github.com/dotnet/emsdk 2fc2ffd960930318f33fcaa690cbdbc55d72f52d - + https://github.com/dotnet/msbuild - dbf652edbedb4e6c612a79cc6907d211c74329d6 + d08d5e4155f737845380a75b3cfcb68b5a9f05c5 - + https://github.com/dotnet/msbuild - dbf652edbedb4e6c612a79cc6907d211c74329d6 + d08d5e4155f737845380a75b3cfcb68b5a9f05c5 - + https://github.com/dotnet/msbuild - dbf652edbedb4e6c612a79cc6907d211c74329d6 + d08d5e4155f737845380a75b3cfcb68b5a9f05c5 diff --git a/eng/Versions.props b/eng/Versions.props index 0b833209bf32..fc1c8568d736 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -120,7 +120,7 @@ - 17.10.0 + 17.10.2 $(MicrosoftBuildPackageVersion) - 12.8.300-beta.24208.5 + 12.8.300-beta.24211.1 From 29b8303b54dc1f547cb0dc75d7e795050fd413a8 Mon Sep 17 00:00:00 2001 From: Chet Husk Date: Thu, 11 Apr 2024 22:56:58 -0500 Subject: [PATCH 553/577] Update EndToEndTests.cs with property --- .../EndToEndTests.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Tests/Microsoft.NET.Build.Containers.IntegrationTests/EndToEndTests.cs b/src/Tests/Microsoft.NET.Build.Containers.IntegrationTests/EndToEndTests.cs index 44fb455f0453..9dc7db0b6586 100644 --- a/src/Tests/Microsoft.NET.Build.Containers.IntegrationTests/EndToEndTests.cs +++ b/src/Tests/Microsoft.NET.Build.Containers.IntegrationTests/EndToEndTests.cs @@ -518,7 +518,8 @@ public void EndToEnd_NoAPI_Console() $"/p:ContainerBaseImage={DockerRegistryManager.FullyQualifiedBaseImageAspNet}", $"/p:ContainerRegistry={DockerRegistryManager.LocalRegistry}", $"/p:ContainerRepository={imageName}", - $"/p:ContainerImageTag={imageTag}") + $"/p:ContainerImageTag={imageTag}", + "/p:EnableSdkContainerSupport=true") .WithEnvironmentVariable("NUGET_PACKAGES", privateNuGetAssets.FullName) .WithWorkingDirectory(newProjectDir.FullName) .Execute() From 7d26871a85ce36f85972b0529c9c6cc47c023f7d Mon Sep 17 00:00:00 2001 From: Forgind <12969783+Forgind@users.noreply.github.com> Date: Fri, 12 Apr 2024 12:10:05 -0700 Subject: [PATCH 554/577] Failure is inside "workload install failed" message --- .../dotnet-workload-install.Tests/GivenDotnetWorkloadInstall.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Tests/dotnet-workload-install.Tests/GivenDotnetWorkloadInstall.cs b/src/Tests/dotnet-workload-install.Tests/GivenDotnetWorkloadInstall.cs index 8e20301388a3..ac2f2c199f50 100644 --- a/src/Tests/dotnet-workload-install.Tests/GivenDotnetWorkloadInstall.cs +++ b/src/Tests/dotnet-workload-install.Tests/GivenDotnetWorkloadInstall.cs @@ -330,7 +330,7 @@ public void GivenWorkloadInstallItErrorsOnUnsupportedPlatform() nugetPackageDownloader: nugetDownloader, workloadManifestUpdater: manifestUpdater); var exceptionThrown = Assert.Throws(() => command.Execute()); - exceptionThrown.Message.Should().Be(String.Format(Workloads.Workload.Install.LocalizableStrings.WorkloadNotSupportedOnPlatform, mockWorkloadId)); + exceptionThrown.Message.Should().Be(String.Format(Workloads.Workload.Install.LocalizableStrings.WorkloadInstallationFailed, String.Format(Workloads.Workload.Install.LocalizableStrings.WorkloadNotSupportedOnPlatform, mockWorkloadId))); } [Theory] From 4d37ff360716535fe4466fbf4394776ca0ff0c39 Mon Sep 17 00:00:00 2001 From: Forgind <12969783+Forgind@users.noreply.github.com> Date: Fri, 12 Apr 2024 13:46:09 -0700 Subject: [PATCH 555/577] Uninstall new MSI if not finished installing --- .../install/FileBasedInstaller.cs | 2 ++ .../dotnet-workload/install/IInstaller.cs | 2 ++ .../install/NetSdkMsiInstallerClient.cs | 16 +++++++++++++--- .../MockPackWorkloadInstaller.cs | 2 ++ 4 files changed, 19 insertions(+), 3 deletions(-) diff --git a/src/Cli/dotnet/commands/dotnet-workload/install/FileBasedInstaller.cs b/src/Cli/dotnet/commands/dotnet-workload/install/FileBasedInstaller.cs index 800078f10e37..4ffe72bfba54 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/install/FileBasedInstaller.cs +++ b/src/Cli/dotnet/commands/dotnet-workload/install/FileBasedInstaller.cs @@ -74,6 +74,8 @@ public void ReplaceWorkloadResolver(IWorkloadResolver workloadResolver) _workloadResolver = workloadResolver; } + public void NotifyInstallComplete() { } + IEnumerable GetPacksInWorkloads(IEnumerable workloadIds) { var packs = workloadIds diff --git a/src/Cli/dotnet/commands/dotnet-workload/install/IInstaller.cs b/src/Cli/dotnet/commands/dotnet-workload/install/IInstaller.cs index 275d5ecbcdce..7d3b44458a44 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/install/IInstaller.cs +++ b/src/Cli/dotnet/commands/dotnet-workload/install/IInstaller.cs @@ -29,6 +29,8 @@ internal interface IInstaller : IWorkloadManifestInstaller void AdjustWorkloadSetInInstallState(SdkFeatureBand sdkFeatureBand, string workloadVersion); + void NotifyInstallComplete(); + /// /// Replace the workload resolver used by this installer. Typically used to call /// for a set of workload manifests that isn't currently installed diff --git a/src/Cli/dotnet/commands/dotnet-workload/install/NetSdkMsiInstallerClient.cs b/src/Cli/dotnet/commands/dotnet-workload/install/NetSdkMsiInstallerClient.cs index 9d3a44e67f11..573ebd55e1f7 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/install/NetSdkMsiInstallerClient.cs +++ b/src/Cli/dotnet/commands/dotnet-workload/install/NetSdkMsiInstallerClient.cs @@ -35,6 +35,8 @@ internal partial class NetSdkMsiInstallerClient : MsiInstallerBase, IInstaller private readonly string _dependent; + private bool _installComplete = false; + public int ExitCode => Restart ? unchecked((int)Error.SUCCESS_REBOOT_REQUIRED) : unchecked((int)Error.SUCCESS); public NetSdkMsiInstallerClient(InstallElevationContextBase elevationContext, @@ -100,6 +102,11 @@ public IEnumerable GetDownloads(IEnumerable worklo return msis.ToList(); ; } + public void NotifyInstallComplete() + { + _installComplete = true; + } + // Wrap the setup logger in an IReporter so it can be passed to the garbage collector private class SetupLogReporter : IReporter { @@ -462,7 +469,10 @@ public void InstallWorkloadManifest(ManifestVersionUpdate manifestUpdate, ITrans }, rollback: () => { - InstallWorkloadManifestImplementation(manifestUpdate.Reverse(), offlineCache: null, isRollback: true); + if (!_installComplete) + { + InstallWorkloadManifestImplementation(manifestUpdate, offlineCache: null, isRollback: true, action: InstallAction.Uninstall); + } }); } catch (Exception e) @@ -472,7 +482,7 @@ public void InstallWorkloadManifest(ManifestVersionUpdate manifestUpdate, ITrans } } - void InstallWorkloadManifestImplementation(ManifestVersionUpdate manifestUpdate, DirectoryPath? offlineCache = null, bool isRollback = false) + void InstallWorkloadManifestImplementation(ManifestVersionUpdate manifestUpdate, DirectoryPath? offlineCache = null, bool isRollback = false, InstallAction action = InstallAction.Install) { ReportPendingReboot(); @@ -491,7 +501,7 @@ void InstallWorkloadManifestImplementation(ManifestVersionUpdate manifestUpdate, MsiPayload msi = GetCachedMsiPayload(msiPackageId, msiPackageVersion, offlineCache); VerifyPackage(msi); DetectState state = DetectPackage(msi.ProductCode, out Version installedVersion); - InstallAction plannedAction = PlanPackage(msi, state, InstallAction.Install, installedVersion); + InstallAction plannedAction = PlanPackage(msi, state, action, installedVersion); ExecutePackage(msi, plannedAction, msiPackageId); diff --git a/src/Tests/dotnet-workload-install.Tests/MockPackWorkloadInstaller.cs b/src/Tests/dotnet-workload-install.Tests/MockPackWorkloadInstaller.cs index fb4b3924dea5..a753b9ecaa5a 100644 --- a/src/Tests/dotnet-workload-install.Tests/MockPackWorkloadInstaller.cs +++ b/src/Tests/dotnet-workload-install.Tests/MockPackWorkloadInstaller.cs @@ -75,6 +75,8 @@ public void AdjustWorkloadSetInInstallState(SdkFeatureBand sdkFeatureBand, strin } } + public void NotifyInstallComplete() { } + public void InstallWorkloads(IEnumerable workloadIds, SdkFeatureBand sdkFeatureBand, ITransactionContext transactionContext, DirectoryPath? offlineCache = null) { List packs = new List(); From b8c24c4cf0164f2f661b958938c96a66c854a8c5 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" Date: Sat, 13 Apr 2024 12:51:58 +0000 Subject: [PATCH 556/577] Update dependencies from https://github.com/dotnet/roslyn build 20240412.1 Microsoft.CodeAnalysis , Microsoft.CodeAnalysis.CSharp , Microsoft.CodeAnalysis.CSharp.CodeStyle , Microsoft.CodeAnalysis.CSharp.Features , Microsoft.CodeAnalysis.CSharp.Workspaces , Microsoft.CodeAnalysis.Workspaces.MSBuild , Microsoft.Net.Compilers.Toolset From Version 4.10.0-3.24202.15 -> To Version 4.10.0-3.24212.1 --- eng/Version.Details.xml | 28 ++++++++++++++-------------- eng/Versions.props | 14 +++++++------- 2 files changed, 21 insertions(+), 21 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index b81469ff72e4..a9a7e4ddfd3d 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -78,34 +78,34 @@ ac0d85557969d51bca72181514ddb7d5796fbbe2 - + https://github.com/dotnet/roslyn - cbca41cad4e21c29548e9e57d7135740b6f78df9 + 0b1fefc344701f2669b2190fbfda5ca588083605 - + https://github.com/dotnet/roslyn - cbca41cad4e21c29548e9e57d7135740b6f78df9 + 0b1fefc344701f2669b2190fbfda5ca588083605 - + https://github.com/dotnet/roslyn - cbca41cad4e21c29548e9e57d7135740b6f78df9 + 0b1fefc344701f2669b2190fbfda5ca588083605 - + https://github.com/dotnet/roslyn - cbca41cad4e21c29548e9e57d7135740b6f78df9 + 0b1fefc344701f2669b2190fbfda5ca588083605 - + https://github.com/dotnet/roslyn - cbca41cad4e21c29548e9e57d7135740b6f78df9 + 0b1fefc344701f2669b2190fbfda5ca588083605 - + https://github.com/dotnet/roslyn - cbca41cad4e21c29548e9e57d7135740b6f78df9 + 0b1fefc344701f2669b2190fbfda5ca588083605 - + https://github.com/dotnet/roslyn - cbca41cad4e21c29548e9e57d7135740b6f78df9 + 0b1fefc344701f2669b2190fbfda5ca588083605 https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore diff --git a/eng/Versions.props b/eng/Versions.props index 7531c04b0ba1..fb95a8f2ca39 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -154,13 +154,13 @@ - 4.10.0-3.24202.15 - 4.10.0-3.24202.15 - 4.10.0-3.24202.15 - 4.10.0-3.24202.15 - 4.10.0-3.24202.15 - 4.10.0-3.24202.15 - 4.10.0-3.24202.15 + 4.10.0-3.24212.1 + 4.10.0-3.24212.1 + 4.10.0-3.24212.1 + 4.10.0-3.24212.1 + 4.10.0-3.24212.1 + 4.10.0-3.24212.1 + 4.10.0-3.24212.1 $(MicrosoftNetCompilersToolsetPackageVersion) From e191cc9159f7b66cf1cb0ec0fc7541df58cee3a5 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" Date: Sun, 14 Apr 2024 12:40:43 +0000 Subject: [PATCH 557/577] Update dependencies from https://github.com/dotnet/roslyn build 20240412.1 Microsoft.CodeAnalysis , Microsoft.CodeAnalysis.CSharp , Microsoft.CodeAnalysis.CSharp.CodeStyle , Microsoft.CodeAnalysis.CSharp.Features , Microsoft.CodeAnalysis.CSharp.Workspaces , Microsoft.CodeAnalysis.Workspaces.MSBuild , Microsoft.Net.Compilers.Toolset From Version 4.10.0-3.24202.15 -> To Version 4.10.0-3.24212.1 From e79b11b8c2a258d32e8b0cd09166c0475c486715 Mon Sep 17 00:00:00 2001 From: Chet Husk Date: Sun, 14 Apr 2024 21:07:56 -0500 Subject: [PATCH 558/577] Containers 8.0.3xx Package Release Notes (#39942) Co-authored-by: Rainer Sigwald --- src/Containers/docs/ReleaseNotes/v8.0.200.md | 15 +++++++++++++++ src/Containers/docs/ReleaseNotes/v8.0.300.md | 14 ++++++++++++++ src/Containers/packaging/package.csproj | 2 +- 3 files changed, 30 insertions(+), 1 deletion(-) create mode 100644 src/Containers/docs/ReleaseNotes/v8.0.200.md create mode 100644 src/Containers/docs/ReleaseNotes/v8.0.300.md diff --git a/src/Containers/docs/ReleaseNotes/v8.0.200.md b/src/Containers/docs/ReleaseNotes/v8.0.200.md new file mode 100644 index 000000000000..9bb17b6e87cb --- /dev/null +++ b/src/Containers/docs/ReleaseNotes/v8.0.200.md @@ -0,0 +1,15 @@ +# Microsoft.NET.Build.Containers 8.0.200 + +This version brings the following new features and enhancements: + +* The .NET SDK now natively supports containerizing any kind of publishable project! Web and Worker projects work with no modifications, but console applications will need to add an MSBuild property to signal support. Supported projects must: + * Set `true`, and + * Set `true` + +* Improved support for applications targeting `alpine` base images (meaning those publishing for `linux-musl` Runtime Identifiers). Now when you specify a `linux-musl` RuntimeIdentifier, the containers tooling will automatically look for `-alpine` variants of the base images. This means that you can now target `alpine` base images without needing to specify the `ContainerFamily` property at all. + +* Projects that target Native AOT and projects that opt into Invariant Globalization have improved base image selection. Native AOT projects will use the `-aot` variants of relevant base images, and if `InvariantGlobalization` is true will use the `-extra` variants of relevant base images, so that required localization dependencies are included in the image. This means that for these projects you can now target these base images without needing to specify the `ContainerFamily` property at all. + +* Better error messages and stack traces when communicating with registries where authentication has failed, and when the container creation is canceled by users. + +* Better support for more kinds of registries - we now support registries that send CSRF tokens unconditionally, like Harbor and Harbor-derived registries. diff --git a/src/Containers/docs/ReleaseNotes/v8.0.300.md b/src/Containers/docs/ReleaseNotes/v8.0.300.md new file mode 100644 index 000000000000..afccd147e83e --- /dev/null +++ b/src/Containers/docs/ReleaseNotes/v8.0.300.md @@ -0,0 +1,14 @@ +# Microsoft.NET.Build.Containers 8.0.300 + +This version brings the following new features and enhancements: + +* The SDK will generate additional container metadata labels now. + * The `org.opencontainers.image.base.digest` label will be added to uniquely identify the image used as a base for the application container. + * The `net.dot.runtime.majorminor` label will be added to identify the major and minor version of the .NET Runtime that the application runs against. + * The `net.dot.sdk.version` label will be added to identify the .NET SDK version used to build the application container. + +* The SDK can use and produce OCI base image layers, not just Docker base image layers. This will happen automatically based on the kind of base image digest you use. + +* The SDK will automatically use the `-extra` variant of base images when the application needs globalization/ICU support. So if you set `jammy-chiseled` and `false` in your project file, the SDK will behave as if you set `jammy-chiseled-extra` - this ensures that your application has the required ICU/Globalization support libraries. + +* The SDK will use the runtime-deps base images for Trimmed applications, in addition to AOT applications. diff --git a/src/Containers/packaging/package.csproj b/src/Containers/packaging/package.csproj index 590b15e874d3..8332258c96f6 100644 --- a/src/Containers/packaging/package.csproj +++ b/src/Containers/packaging/package.csproj @@ -41,7 +41,7 @@ - ../docs/ReleaseNotes/v8.0.100.md + ../docs/ReleaseNotes/v8.0.300.md $([System.IO.File]::ReadAllText($(PackageReleaseNotesFile))) From dd9814befe9b85f3f4725d938d2e16aebd54a257 Mon Sep 17 00:00:00 2001 From: Forgind <12969783+Forgind@users.noreply.github.com> Date: Mon, 15 Apr 2024 16:16:42 -0700 Subject: [PATCH 559/577] NotifyInstallComplete --- .../commands/dotnet-workload/install/WorkloadInstallCommand.cs | 2 +- .../commands/dotnet-workload/update/WorkloadUpdateCommand.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Cli/dotnet/commands/dotnet-workload/install/WorkloadInstallCommand.cs b/src/Cli/dotnet/commands/dotnet-workload/install/WorkloadInstallCommand.cs index 02bcd6129b8e..2e899dae537c 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/install/WorkloadInstallCommand.cs +++ b/src/Cli/dotnet/commands/dotnet-workload/install/WorkloadInstallCommand.cs @@ -233,7 +233,7 @@ public void InstallWorkloads(IEnumerable workloadIds, bool skipManif private void InstallWorkloadsAndGarbageCollect(ITransactionContext context, IEnumerable workloadIds, IEnumerable manifestsToUpdate, DirectoryPath? offlineCache, bool useRollback) { InstallWorkloadsWithInstallRecord(context, _workloadInstaller, workloadIds, _sdkFeatureBand, manifestsToUpdate, offlineCache, useRollback); - + _workloadInstaller.NotifyInstallComplete(); TryRunGarbageCollection(_workloadInstaller, Reporter, Verbosity, workloadSetVersion => _workloadResolverFactory.CreateForWorkloadSet(_dotnetPath, _sdkVersion.ToString(), _userProfileDir, workloadSetVersion), offlineCache); Reporter.WriteLine(); diff --git a/src/Cli/dotnet/commands/dotnet-workload/update/WorkloadUpdateCommand.cs b/src/Cli/dotnet/commands/dotnet-workload/update/WorkloadUpdateCommand.cs index 9c3cc9f794e3..66455ee3c711 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/update/WorkloadUpdateCommand.cs +++ b/src/Cli/dotnet/commands/dotnet-workload/update/WorkloadUpdateCommand.cs @@ -173,7 +173,7 @@ private void UpdateWorkloads(bool useRollback, IEnumerable _workloadResolverFactory.CreateForWorkloadSet(_dotnetPath, _sdkVersion.ToString(), _userProfileDir, workloadSetVersion), offlineCache); _workloadManifestUpdater.DeleteUpdatableWorkloadsFile(); From f1c426c7a6783dd0c709a3d7d565ad850f588d1b Mon Sep 17 00:00:00 2001 From: Forgind <12969783+Forgind@users.noreply.github.com> Date: Mon, 15 Apr 2024 17:07:27 -0700 Subject: [PATCH 560/577] Feedback --- .../install/FileBasedInstaller.cs | 2 -- .../dotnet-workload/install/IInstaller.cs | 2 -- .../install/NetSdkMsiInstallerClient.cs | 12 +----------- .../install/WorkloadInstallCommand.cs | 15 ++++++++------- .../dotnet-workload/list/WorkloadListCommand.cs | 14 +++++++++----- .../update/WorkloadUpdateCommand.cs | 16 ++++++++-------- .../MockPackWorkloadInstaller.cs | 2 -- 7 files changed, 26 insertions(+), 37 deletions(-) diff --git a/src/Cli/dotnet/commands/dotnet-workload/install/FileBasedInstaller.cs b/src/Cli/dotnet/commands/dotnet-workload/install/FileBasedInstaller.cs index 4ffe72bfba54..800078f10e37 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/install/FileBasedInstaller.cs +++ b/src/Cli/dotnet/commands/dotnet-workload/install/FileBasedInstaller.cs @@ -74,8 +74,6 @@ public void ReplaceWorkloadResolver(IWorkloadResolver workloadResolver) _workloadResolver = workloadResolver; } - public void NotifyInstallComplete() { } - IEnumerable GetPacksInWorkloads(IEnumerable workloadIds) { var packs = workloadIds diff --git a/src/Cli/dotnet/commands/dotnet-workload/install/IInstaller.cs b/src/Cli/dotnet/commands/dotnet-workload/install/IInstaller.cs index 7d3b44458a44..275d5ecbcdce 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/install/IInstaller.cs +++ b/src/Cli/dotnet/commands/dotnet-workload/install/IInstaller.cs @@ -29,8 +29,6 @@ internal interface IInstaller : IWorkloadManifestInstaller void AdjustWorkloadSetInInstallState(SdkFeatureBand sdkFeatureBand, string workloadVersion); - void NotifyInstallComplete(); - /// /// Replace the workload resolver used by this installer. Typically used to call /// for a set of workload manifests that isn't currently installed diff --git a/src/Cli/dotnet/commands/dotnet-workload/install/NetSdkMsiInstallerClient.cs b/src/Cli/dotnet/commands/dotnet-workload/install/NetSdkMsiInstallerClient.cs index 573ebd55e1f7..82d68b6e1fea 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/install/NetSdkMsiInstallerClient.cs +++ b/src/Cli/dotnet/commands/dotnet-workload/install/NetSdkMsiInstallerClient.cs @@ -35,8 +35,6 @@ internal partial class NetSdkMsiInstallerClient : MsiInstallerBase, IInstaller private readonly string _dependent; - private bool _installComplete = false; - public int ExitCode => Restart ? unchecked((int)Error.SUCCESS_REBOOT_REQUIRED) : unchecked((int)Error.SUCCESS); public NetSdkMsiInstallerClient(InstallElevationContextBase elevationContext, @@ -102,11 +100,6 @@ public IEnumerable GetDownloads(IEnumerable worklo return msis.ToList(); ; } - public void NotifyInstallComplete() - { - _installComplete = true; - } - // Wrap the setup logger in an IReporter so it can be passed to the garbage collector private class SetupLogReporter : IReporter { @@ -469,10 +462,7 @@ public void InstallWorkloadManifest(ManifestVersionUpdate manifestUpdate, ITrans }, rollback: () => { - if (!_installComplete) - { - InstallWorkloadManifestImplementation(manifestUpdate, offlineCache: null, isRollback: true, action: InstallAction.Uninstall); - } + InstallWorkloadManifestImplementation(manifestUpdate, offlineCache: null, isRollback: true, action: InstallAction.Uninstall); }); } catch (Exception e) diff --git a/src/Cli/dotnet/commands/dotnet-workload/install/WorkloadInstallCommand.cs b/src/Cli/dotnet/commands/dotnet-workload/install/WorkloadInstallCommand.cs index 2e899dae537c..a03d3500e138 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/install/WorkloadInstallCommand.cs +++ b/src/Cli/dotnet/commands/dotnet-workload/install/WorkloadInstallCommand.cs @@ -153,8 +153,14 @@ public override int Execute() { return; } - InstallWorkloadsAndGarbageCollect(context, workloadIds, manifests, offlineCache, false); + InstallWorkloadsWithInstallRecord(context, _workloadInstaller, workloadIds, _sdkFeatureBand, manifests, offlineCache, false); }); + + TryRunGarbageCollection(_workloadInstaller, Reporter, Verbosity, workloadSetVersion => _workloadResolverFactory.CreateForWorkloadSet(_dotnetPath, _sdkVersion.ToString(), _userProfileDir, workloadSetVersion), offlineCache); + + Reporter.WriteLine(); + Reporter.WriteLine(string.Format(LocalizableStrings.InstallationSucceeded, string.Join(" ", workloadIds))); + Reporter.WriteLine(); } } catch (Exception e) @@ -226,14 +232,9 @@ public void InstallWorkloads(IEnumerable workloadIds, bool skipManif } } - InstallWorkloadsAndGarbageCollect(context, workloadIds, manifestsToUpdate, offlineCache, useRollback); + InstallWorkloadsWithInstallRecord(context, _workloadInstaller, workloadIds, _sdkFeatureBand, manifestsToUpdate, offlineCache, useRollback); }); - } - private void InstallWorkloadsAndGarbageCollect(ITransactionContext context, IEnumerable workloadIds, IEnumerable manifestsToUpdate, DirectoryPath? offlineCache, bool useRollback) - { - InstallWorkloadsWithInstallRecord(context, _workloadInstaller, workloadIds, _sdkFeatureBand, manifestsToUpdate, offlineCache, useRollback); - _workloadInstaller.NotifyInstallComplete(); TryRunGarbageCollection(_workloadInstaller, Reporter, Verbosity, workloadSetVersion => _workloadResolverFactory.CreateForWorkloadSet(_dotnetPath, _sdkVersion.ToString(), _userProfileDir, workloadSetVersion), offlineCache); Reporter.WriteLine(); diff --git a/src/Cli/dotnet/commands/dotnet-workload/list/WorkloadListCommand.cs b/src/Cli/dotnet/commands/dotnet-workload/list/WorkloadListCommand.cs index 71a081a028a9..3541d6729c4e 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/list/WorkloadListCommand.cs +++ b/src/Cli/dotnet/commands/dotnet-workload/list/WorkloadListCommand.cs @@ -88,7 +88,8 @@ public override int Execute() globalJsonInformation.GlobalJsonVersion, globalJsonInformation.GlobalJsonPath)); } - else + + if (globalJsonInformation?.WorkloadVersionInstalled != false) { var manifestInfoDict = _workloadListHelper.WorkloadResolver.GetInstalledManifests().ToDictionary(info => info.Id, StringComparer.OrdinalIgnoreCase); @@ -105,11 +106,14 @@ public override int Execute() table.PrintRows(installedWorkloads.AsEnumerable(), l => Reporter.WriteLine(l)); - var installState = InstallStateContents.FromPath(Path.Combine(WorkloadInstallType.GetInstallStateFolder(_workloadListHelper._currentSdkFeatureBand, _workloadListHelper.DotnetPath), "default.json")); - if (installState.UseWorkloadSets == true) + if (globalJsonInformation is null) { - Reporter.WriteLine(); - Reporter.WriteLine(string.Format(LocalizableStrings.WorkloadSetVersion, _workloadListHelper.WorkloadResolver.GetWorkloadVersion() ?? "unknown")); + var installState = InstallStateContents.FromPath(Path.Combine(WorkloadInstallType.GetInstallStateFolder(_workloadListHelper._currentSdkFeatureBand, _workloadListHelper.DotnetPath), "default.json")); + if (installState.UseWorkloadSets == true) + { + Reporter.WriteLine(); + Reporter.WriteLine(string.Format(LocalizableStrings.WorkloadSetVersion, _workloadListHelper.WorkloadResolver.GetWorkloadVersion() ?? "unknown")); + } } } diff --git a/src/Cli/dotnet/commands/dotnet-workload/update/WorkloadUpdateCommand.cs b/src/Cli/dotnet/commands/dotnet-workload/update/WorkloadUpdateCommand.cs index 66455ee3c711..7bd8614085c9 100644 --- a/src/Cli/dotnet/commands/dotnet-workload/update/WorkloadUpdateCommand.cs +++ b/src/Cli/dotnet/commands/dotnet-workload/update/WorkloadUpdateCommand.cs @@ -161,11 +161,15 @@ public void CalculateManifestUpdatesAndUpdateWorkloads(bool includePreviews = fa } UpdateWorkloads(useRollback, manifestsToUpdate, offlineCache, context); - - Reporter.WriteLine(); - Reporter.WriteLine(string.Format(LocalizableStrings.UpdateSucceeded, string.Join(" ", workloadIds))); - Reporter.WriteLine(); }); + + WorkloadInstallCommand.TryRunGarbageCollection(_workloadInstaller, Reporter, Verbosity, workloadSetVersion => _workloadResolverFactory.CreateForWorkloadSet(_dotnetPath, _sdkVersion.ToString(), _userProfileDir, workloadSetVersion), offlineCache); + + _workloadManifestUpdater.DeleteUpdatableWorkloadsFile(); + + Reporter.WriteLine(); + Reporter.WriteLine(string.Format(LocalizableStrings.UpdateSucceeded, string.Join(" ", workloadIds))); + Reporter.WriteLine(); } private void UpdateWorkloads(bool useRollback, IEnumerable manifestsToUpdate, DirectoryPath? offlineCache, ITransactionContext context) @@ -173,10 +177,6 @@ private void UpdateWorkloads(bool useRollback, IEnumerable _workloadResolverFactory.CreateForWorkloadSet(_dotnetPath, _sdkVersion.ToString(), _userProfileDir, workloadSetVersion), offlineCache); - - _workloadManifestUpdater.DeleteUpdatableWorkloadsFile(); } private void WriteSDKInstallRecordsForVSWorkloads(IEnumerable updateableWorkloads) diff --git a/src/Tests/dotnet-workload-install.Tests/MockPackWorkloadInstaller.cs b/src/Tests/dotnet-workload-install.Tests/MockPackWorkloadInstaller.cs index a753b9ecaa5a..fb4b3924dea5 100644 --- a/src/Tests/dotnet-workload-install.Tests/MockPackWorkloadInstaller.cs +++ b/src/Tests/dotnet-workload-install.Tests/MockPackWorkloadInstaller.cs @@ -75,8 +75,6 @@ public void AdjustWorkloadSetInInstallState(SdkFeatureBand sdkFeatureBand, strin } } - public void NotifyInstallComplete() { } - public void InstallWorkloads(IEnumerable workloadIds, SdkFeatureBand sdkFeatureBand, ITransactionContext transactionContext, DirectoryPath? offlineCache = null) { List packs = new List(); From 9c5514561056b32d21aadfe537866a5da57a1aaa Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Tue, 16 Apr 2024 17:32:05 +0000 Subject: [PATCH 561/577] [release/8.0.3xx] Update dependencies from dotnet/msbuild (#40202) [release/8.0.3xx] Update dependencies from dotnet/msbuild --- NuGet.config | 2 +- eng/Version.Details.xml | 12 ++++++------ eng/Versions.props | 4 ++-- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/NuGet.config b/NuGet.config index 195781574335..405da51f1bd5 100644 --- a/NuGet.config +++ b/NuGet.config @@ -14,7 +14,7 @@ - + diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index a9a7e4ddfd3d..3255e9be8899 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -51,17 +51,17 @@ https://github.com/dotnet/emsdk 2fc2ffd960930318f33fcaa690cbdbc55d72f52d - + https://github.com/dotnet/msbuild - d08d5e4155f737845380a75b3cfcb68b5a9f05c5 + fc97b2d1f7c2309d0069dfbd4ab73e4779ad6989 - + https://github.com/dotnet/msbuild - d08d5e4155f737845380a75b3cfcb68b5a9f05c5 + fc97b2d1f7c2309d0069dfbd4ab73e4779ad6989 - + https://github.com/dotnet/msbuild - d08d5e4155f737845380a75b3cfcb68b5a9f05c5 + fc97b2d1f7c2309d0069dfbd4ab73e4779ad6989 diff --git a/eng/Versions.props b/eng/Versions.props index fb95a8f2ca39..17fd1a546dac 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -120,7 +120,7 @@ - 17.10.2 + 17.10.3 $(MicrosoftBuildPackageVersion) - 7.0.0-preview.24208.1 - 7.0.0-preview.24208.1 - 7.0.0-preview.24208.1 + 7.0.0-preview.24216.4 + 7.0.0-preview.24216.4 + 7.0.0-preview.24216.4 From 07445bde54e774a3860e6eab860d0dff45c0c807 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" Date: Wed, 17 Apr 2024 12:50:51 +0000 Subject: [PATCH 563/577] Update dependencies from https://github.com/dotnet/source-build-externals build 20240416.1 Microsoft.SourceBuild.Intermediate.source-build-externals From Version 8.0.0-alpha.1.24175.3 -> To Version 8.0.0-alpha.1.24216.1 --- eng/Version.Details.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 728bf180e8f3..793b1c9c0df8 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -337,9 +337,9 @@ 02fe27cd6a9b001c8feb7938e6ef4b3799745759 - + https://github.com/dotnet/source-build-externals - 300e99190e6ae1983681694dbdd5f75f0c692081 + 908177a58a41532b3302c17f1e1a8cf1c1234545 From a4fcb48382910cbca1f9ebb772828b49b9a690a2 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Wed, 17 Apr 2024 15:57:24 +0000 Subject: [PATCH 564/577] [release/8.0.3xx] Update dependencies from dotnet/roslyn (#40243) [release/8.0.3xx] Update dependencies from dotnet/roslyn --- eng/Version.Details.xml | 28 ++++++++++++++-------------- eng/Versions.props | 14 +++++++------- 2 files changed, 21 insertions(+), 21 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 728bf180e8f3..12ca3e78aab8 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -78,34 +78,34 @@ ac0d85557969d51bca72181514ddb7d5796fbbe2 - + https://github.com/dotnet/roslyn - 0b1fefc344701f2669b2190fbfda5ca588083605 + 3af0081a6e811b78d37c62e479914f7f4cfb0d1a - + https://github.com/dotnet/roslyn - 0b1fefc344701f2669b2190fbfda5ca588083605 + 3af0081a6e811b78d37c62e479914f7f4cfb0d1a - + https://github.com/dotnet/roslyn - 0b1fefc344701f2669b2190fbfda5ca588083605 + 3af0081a6e811b78d37c62e479914f7f4cfb0d1a - + https://github.com/dotnet/roslyn - 0b1fefc344701f2669b2190fbfda5ca588083605 + 3af0081a6e811b78d37c62e479914f7f4cfb0d1a - + https://github.com/dotnet/roslyn - 0b1fefc344701f2669b2190fbfda5ca588083605 + 3af0081a6e811b78d37c62e479914f7f4cfb0d1a - + https://github.com/dotnet/roslyn - 0b1fefc344701f2669b2190fbfda5ca588083605 + 3af0081a6e811b78d37c62e479914f7f4cfb0d1a - + https://github.com/dotnet/roslyn - 0b1fefc344701f2669b2190fbfda5ca588083605 + 3af0081a6e811b78d37c62e479914f7f4cfb0d1a https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore diff --git a/eng/Versions.props b/eng/Versions.props index ae7865174a8c..034b0a29a578 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -154,13 +154,13 @@ - 4.10.0-3.24212.1 - 4.10.0-3.24212.1 - 4.10.0-3.24212.1 - 4.10.0-3.24212.1 - 4.10.0-3.24212.1 - 4.10.0-3.24212.1 - 4.10.0-3.24212.1 + 4.10.0-3.24216.12 + 4.10.0-3.24216.12 + 4.10.0-3.24216.12 + 4.10.0-3.24216.12 + 4.10.0-3.24216.12 + 4.10.0-3.24216.12 + 4.10.0-3.24216.12 $(MicrosoftNetCompilersToolsetPackageVersion) From 174bf5f61239cf9e8bfbf746e191b02338f7fdca Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" Date: Thu, 18 Apr 2024 12:45:30 +0000 Subject: [PATCH 565/577] Update dependencies from https://github.com/dotnet/msbuild build 20240418.2 Microsoft.SourceBuild.Intermediate.msbuild , Microsoft.Build , Microsoft.Build.Localization From Version 17.10.3-preview-24215-04 -> To Version 17.10.4-preview-24218-02 --- NuGet.config | 3 ++- eng/Version.Details.xml | 12 ++++++------ eng/Versions.props | 4 ++-- 3 files changed, 10 insertions(+), 9 deletions(-) diff --git a/NuGet.config b/NuGet.config index 405da51f1bd5..067d780dc0a2 100644 --- a/NuGet.config +++ b/NuGet.config @@ -7,6 +7,7 @@ + @@ -14,7 +15,7 @@ - + diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 653327cf49b9..8bef9bfb5307 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -51,17 +51,17 @@ https://github.com/dotnet/emsdk 2fc2ffd960930318f33fcaa690cbdbc55d72f52d - + https://github.com/dotnet/msbuild - fc97b2d1f7c2309d0069dfbd4ab73e4779ad6989 + 10fbfbf2eeb0597fdc1f600d87d38c7f57317bdc - + https://github.com/dotnet/msbuild - fc97b2d1f7c2309d0069dfbd4ab73e4779ad6989 + 10fbfbf2eeb0597fdc1f600d87d38c7f57317bdc - + https://github.com/dotnet/msbuild - fc97b2d1f7c2309d0069dfbd4ab73e4779ad6989 + 10fbfbf2eeb0597fdc1f600d87d38c7f57317bdc diff --git a/eng/Versions.props b/eng/Versions.props index 034b0a29a578..2c0477905428 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -120,7 +120,7 @@ - 17.10.3 + 17.10.4 $(MicrosoftBuildPackageVersion) - false + true release preview From fc905848cf9363c1f0bc09a1872c1547f352d546 Mon Sep 17 00:00:00 2001 From: DotNet Bot Date: Thu, 18 Apr 2024 20:40:22 +0000 Subject: [PATCH 570/577] Merged PR 39069: [internal/release/8.0.3xx] Update dependencies from 3 repositories This pull request updates the following dependencies [marker]: <> (Begin:Coherency Updates) ## Coherency Updates The following updates ensure that dependencies with a *CoherentParentDependency* attribute were produced in a build used as input to the parent dependency's build. See [Dependency Description Format](https://github.com/dotnet/arcade/blob/master/Documentation/DependencyDescriptionFormat.md#dependency-description-overview) [DependencyUpdate]: <> (Begin) - **Coherency Updates**: - **Microsoft.NET.Workload.Emscripten.Current.Manifest-8.0.100**: from 8.0.2 to 8.0.5 (parent: Microsoft.NETCore.App.Runtime.win-x64) [DependencyUpdate]: <> (End) [marker]: <> (End:Coherency Updates) [marker]: <> (Begin:1adb2556-0120-43d1-c468-08dc11e32ec2) ## From https://dev.azure.com/dnceng/internal/_git/dotnet-windowsdesktop - **Subscription**: 1adb2556-0120-43d1-c468-08dc11e32ec2 - **Build**: 20240417.5 - **Date Produced**: April 17, 2024 10:17:39 PM UTC - **Commit**: dda23bbe00c4a4bfdd3732783f0cce37c11a4f40 - **Branch**: refs/heads/internal/release/8.0 [DependencyUpdate]: <> (Begin) - **Updates**: - **Microsoft.WindowsDesktop.App.Ref**: [from 8.0.2 to 8.0.5][1] - **Microsoft.WindowsDesktop.App.Runtime.win-x64**: [from 8.0.2 to 8.0.5][1] - **VS.Redist.Common.WindowsDesktop.SharedFramework.x64.8.0**: [from 8.0.2-servicing.24068.6 to 8.0.5-servicing.24217.5][1] - **VS.Redist.Common.WindowsDesktop.TargetingPack.x64.8.0**: [from 8.0.2-servicing.24068.6 to 8.0.5-servicing.24217.5][1] - **Microsoft.NET.Sdk.WindowsDesktop**: [from 8.0.2-servicing.24068.6 to 8.0.5-servicing.24217.2][2] [1]: https://dev.azure.com/dnceng/internal/_git/dotnet-windowsdesktop/branches?baseVersion=GC593444ad8328a5a933c006c6564469666f45ad2e&targetVersion=GCdda23bbe00c4a4bfdd3732783f0cce37c11a4f40&_a=files [2]: https://dev.azure.com/dnceng/internal/_git/dotnet-wpf/branches?baseVersion=GC472140dd926227876848e48f41cfc9acb9275492&targetVersion=GCb5af29a8f41f880f38fd015c6bcb7aeb816fcef6&_a=files [DependencyUpdate]: <> (End) [marker]: <> (End:1adb2556-0120-43d1-c468-08dc11e32ec2) [marker]: <> (Begin:911684f3-0faa-4fc9-de45-08dc11e85c3a) ## From https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore - **Subscription**: 911684f3-0faa-4fc9-de45-08dc11e85c3a - **Build**: 20240417.6 - **Date Produced**: April 17, 2024 10:32:21 PM UTC - **Commit**: 1681d9acf750c1f1ba8f89d54796c99fbfbfb8b2 - **Branch**: refs/heads/internal/release/8.0 [DependencyUpdate]: <> (Begin) - **Updates**: - **dotnet-dev-certs**: [from 8.0.2-servicing.24068.4 to 8.0.5-servicing.24217.6][3] - **dotnet-user-jwts**: [from 8.0.2-servicing.24068.4 to 8.0.5-servicing.24217.6][3] - **dotnet-user-secrets**: [from 8.0.2-servicing.24068.4 to 8.0.5-servicing.24217.6][3] - **Microsoft.AspNetCore.Analyzers**: [from 8.0.2-servicing.24068.4 to 8.0.5-servicing.24217.6][3] - **Microsoft.AspNetCore.App.Ref**: [from 8.0.2 to 8.0.5][3] - **... --- NuGet.config | 7 +++ eng/Version.Details.xml | 136 ++++++++++++++++++++-------------------- eng/Versions.props | 34 +++++----- 3 files changed, 92 insertions(+), 85 deletions(-) diff --git a/NuGet.config b/NuGet.config index 067d780dc0a2..5d74e23641e5 100644 --- a/NuGet.config +++ b/NuGet.config @@ -4,6 +4,7 @@ + @@ -13,6 +14,7 @@ + @@ -20,10 +22,12 @@ + + @@ -50,12 +54,15 @@ + + + diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 8bef9bfb5307..7d0372ad0df2 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -10,46 +10,46 @@ https://github.com/dotnet/templating 40c69ed5c711955baf5a624ec83a12e9cd1a8484 - + https://dev.azure.com/dnceng/internal/_git/dotnet-runtime - 1381d5ebd2ab1f292848d5b19b80cf71ac332508 + 087e15321bb712ef6fe8b0ba6f8bd12facf92629 - + https://dev.azure.com/dnceng/internal/_git/dotnet-runtime - 1381d5ebd2ab1f292848d5b19b80cf71ac332508 + 087e15321bb712ef6fe8b0ba6f8bd12facf92629 - + https://dev.azure.com/dnceng/internal/_git/dotnet-runtime - 1381d5ebd2ab1f292848d5b19b80cf71ac332508 + 087e15321bb712ef6fe8b0ba6f8bd12facf92629 - + https://dev.azure.com/dnceng/internal/_git/dotnet-runtime - 1381d5ebd2ab1f292848d5b19b80cf71ac332508 + 087e15321bb712ef6fe8b0ba6f8bd12facf92629 - + https://dev.azure.com/dnceng/internal/_git/dotnet-runtime - 1381d5ebd2ab1f292848d5b19b80cf71ac332508 + 087e15321bb712ef6fe8b0ba6f8bd12facf92629 - + https://dev.azure.com/dnceng/internal/_git/dotnet-runtime - 1381d5ebd2ab1f292848d5b19b80cf71ac332508 + 087e15321bb712ef6fe8b0ba6f8bd12facf92629 - + https://dev.azure.com/dnceng/internal/_git/dotnet-runtime - 1381d5ebd2ab1f292848d5b19b80cf71ac332508 + 087e15321bb712ef6fe8b0ba6f8bd12facf92629 https://dev.azure.com/dnceng/internal/_git/dotnet-runtime 5535e31a712343a63f5d7d796cd874e563e5ac14 - + https://dev.azure.com/dnceng/internal/_git/dotnet-runtime - 1381d5ebd2ab1f292848d5b19b80cf71ac332508 + 087e15321bb712ef6fe8b0ba6f8bd12facf92629 - + https://github.com/dotnet/emsdk - 2fc2ffd960930318f33fcaa690cbdbc55d72f52d + 71359b18c2d83c01a68bf155244a65962a7e8c8e https://github.com/dotnet/msbuild @@ -107,13 +107,13 @@ https://github.com/dotnet/roslyn 3af0081a6e811b78d37c62e479914f7f4cfb0d1a - + https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore - da7e9894ce22ef8cc02e5acc56e95a6f8cf8f644 + 1681d9acf750c1f1ba8f89d54796c99fbfbfb8b2 - + https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore - da7e9894ce22ef8cc02e5acc56e95a6f8cf8f644 + 1681d9acf750c1f1ba8f89d54796c99fbfbfb8b2 https://github.com/nuget/nuget.client @@ -196,9 +196,9 @@ https://github.com/microsoft/vstest 56d28849af08dc3143d019694aa92f186b89d2ac - + https://dev.azure.com/dnceng/internal/_git/dotnet-runtime - 1381d5ebd2ab1f292848d5b19b80cf71ac332508 + 087e15321bb712ef6fe8b0ba6f8bd12facf92629 https://dev.azure.com/dnceng/internal/_git/dotnet-runtime @@ -216,70 +216,70 @@ https://dev.azure.com/dnceng/internal/_git/dotnet-runtime 5535e31a712343a63f5d7d796cd874e563e5ac14 - + https://dev.azure.com/dnceng/internal/_git/dotnet-windowsdesktop - 593444ad8328a5a933c006c6564469666f45ad2e + dda23bbe00c4a4bfdd3732783f0cce37c11a4f40 - + https://dev.azure.com/dnceng/internal/_git/dotnet-windowsdesktop - 593444ad8328a5a933c006c6564469666f45ad2e + dda23bbe00c4a4bfdd3732783f0cce37c11a4f40 - + https://dev.azure.com/dnceng/internal/_git/dotnet-windowsdesktop - 593444ad8328a5a933c006c6564469666f45ad2e + dda23bbe00c4a4bfdd3732783f0cce37c11a4f40 - + https://dev.azure.com/dnceng/internal/_git/dotnet-windowsdesktop - 593444ad8328a5a933c006c6564469666f45ad2e + dda23bbe00c4a4bfdd3732783f0cce37c11a4f40 - + https://dev.azure.com/dnceng/internal/_git/dotnet-wpf - 472140dd926227876848e48f41cfc9acb9275492 + b5af29a8f41f880f38fd015c6bcb7aeb816fcef6 - + https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore - da7e9894ce22ef8cc02e5acc56e95a6f8cf8f644 + 1681d9acf750c1f1ba8f89d54796c99fbfbfb8b2 - + https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore - da7e9894ce22ef8cc02e5acc56e95a6f8cf8f644 + 1681d9acf750c1f1ba8f89d54796c99fbfbfb8b2 - + https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore - da7e9894ce22ef8cc02e5acc56e95a6f8cf8f644 + 1681d9acf750c1f1ba8f89d54796c99fbfbfb8b2 - + https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore - da7e9894ce22ef8cc02e5acc56e95a6f8cf8f644 + 1681d9acf750c1f1ba8f89d54796c99fbfbfb8b2 - + https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore - da7e9894ce22ef8cc02e5acc56e95a6f8cf8f644 + 1681d9acf750c1f1ba8f89d54796c99fbfbfb8b2 - + https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore - da7e9894ce22ef8cc02e5acc56e95a6f8cf8f644 + 1681d9acf750c1f1ba8f89d54796c99fbfbfb8b2 - + https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore - da7e9894ce22ef8cc02e5acc56e95a6f8cf8f644 + 1681d9acf750c1f1ba8f89d54796c99fbfbfb8b2 - + https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore - da7e9894ce22ef8cc02e5acc56e95a6f8cf8f644 + 1681d9acf750c1f1ba8f89d54796c99fbfbfb8b2 - + https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore - da7e9894ce22ef8cc02e5acc56e95a6f8cf8f644 + 1681d9acf750c1f1ba8f89d54796c99fbfbfb8b2 - + https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore - da7e9894ce22ef8cc02e5acc56e95a6f8cf8f644 + 1681d9acf750c1f1ba8f89d54796c99fbfbfb8b2 - + https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore - da7e9894ce22ef8cc02e5acc56e95a6f8cf8f644 + 1681d9acf750c1f1ba8f89d54796c99fbfbfb8b2 https://github.com/dotnet/razor @@ -294,21 +294,21 @@ https://github.com/dotnet/razor bf7698527c4dc48ce1965bc8cdd9b2c35115dab6 - + https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore - da7e9894ce22ef8cc02e5acc56e95a6f8cf8f644 + 1681d9acf750c1f1ba8f89d54796c99fbfbfb8b2 - + https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore - da7e9894ce22ef8cc02e5acc56e95a6f8cf8f644 + 1681d9acf750c1f1ba8f89d54796c99fbfbfb8b2 - + https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore - da7e9894ce22ef8cc02e5acc56e95a6f8cf8f644 + 1681d9acf750c1f1ba8f89d54796c99fbfbfb8b2 - + https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore - da7e9894ce22ef8cc02e5acc56e95a6f8cf8f644 + 1681d9acf750c1f1ba8f89d54796c99fbfbfb8b2 https://github.com/dotnet/xdt @@ -425,9 +425,9 @@ https://dev.azure.com/dnceng/internal/_git/dotnet-runtime 5535e31a712343a63f5d7d796cd874e563e5ac14 - + https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore - da7e9894ce22ef8cc02e5acc56e95a6f8cf8f644 + 1681d9acf750c1f1ba8f89d54796c99fbfbfb8b2 https://dev.azure.com/dnceng/internal/_git/dotnet-runtime @@ -465,9 +465,9 @@ https://dev.azure.com/dnceng/internal/_git/dotnet-runtime 5535e31a712343a63f5d7d796cd874e563e5ac14 - + https://dev.azure.com/dnceng/internal/_git/dotnet-runtime - 5535e31a712343a63f5d7d796cd874e563e5ac14 + 087e15321bb712ef6fe8b0ba6f8bd12facf92629 https://dev.azure.com/dnceng/internal/_git/dotnet-runtime diff --git a/eng/Versions.props b/eng/Versions.props index 4e3aaf87d3b2..53100e724544 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -49,22 +49,22 @@ - 8.0.2 - 8.0.2-servicing.24067.11 - 8.0.2 + 8.0.5 + 8.0.5-servicing.24216.15 + 8.0.5 $(MicrosoftNETCoreAppRuntimewinx64PackageVersion) 8.0.0 - 8.0.2 - 8.0.2-servicing.24067.11 + 8.0.5 + 8.0.5-servicing.24216.15 8.0.0 $(MicrosoftExtensionsDependencyModelPackageVersion) 8.0.0 8.0.0 8.0.0 - 8.0.2 + 8.0.5 8.0.0 8.0.0 - 8.0.2 + 8.0.5 8.0.0 8.0.0 8.0.0 @@ -74,7 +74,7 @@ 8.0.0 8.0.2 8.0.0 - 8.0.0 + 8.0.1 8.0.0 8.0.0 8.0.2 @@ -165,13 +165,13 @@ - 8.0.2 - 8.0.2-servicing.24068.4 - 8.0.2-servicing.24068.4 - 8.0.2-servicing.24068.4 - 8.0.2-servicing.24068.4 - 8.0.2-servicing.24068.4 - 8.0.2 + 8.0.5 + 8.0.5-servicing.24217.6 + 8.0.5-servicing.24217.6 + 8.0.5-servicing.24217.6 + 8.0.5-servicing.24217.6 + 8.0.5-servicing.24217.6 + 8.0.5 @@ -181,7 +181,7 @@ - 8.0.2-servicing.24068.6 + 8.0.5-servicing.24217.2 @@ -225,7 +225,7 @@ - 8.0.2 + 8.0.5 $(MicrosoftNETWorkloadEmscriptenCurrentManifest80100PackageVersion) 8.0.100$([System.Text.RegularExpressions.Regex]::Match($(EmscriptenWorkloadManifestVersion), `-rtm|-[A-z]*\.*\d*`)) From 09d0181e244b0b624fb2581ed1cadb6decb38ef5 Mon Sep 17 00:00:00 2001 From: Forgind <12969783+Forgind@users.noreply.github.com> Date: Fri, 19 Apr 2024 14:03:06 -0700 Subject: [PATCH 571/577] Update loc branch target (#40147) --- eng/build-pr.yml | 4 ++-- eng/build.yml | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/eng/build-pr.yml b/eng/build-pr.yml index 4dac64e70bd4..23f394e6f943 100644 --- a/eng/build-pr.yml +++ b/eng/build-pr.yml @@ -15,13 +15,13 @@ parameters: timeoutInMinutes: 180 jobs: -- ${{ if and(ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest'), eq(variables['Build.SourceBranch'], 'refs/heads/release/8.0.3xx'), not(contains(parameters.agentOs, 'TemplateEngine'))) }}: +- ${{ if and(ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest'), eq(variables['Build.SourceBranch'], 'refs/heads/release/8.0.4xx'), not(contains(parameters.agentOs, 'TemplateEngine'))) }}: - template: /eng/common/templates/job/onelocbuild.yml parameters: CreatePr: true LclSource: lclFilesfromPackage LclPackageId: 'LCL-JUNO-PROD-DOTNETSDK' - MirrorBranch: release/8.0.3xx + MirrorBranch: release/8.0.4xx MirrorRepo: sdk - ${{ if not(contains(parameters.agentOs, 'TemplateEngine')) }}: diff --git a/eng/build.yml b/eng/build.yml index f8f12f3f6538..ba6ee57efb91 100644 --- a/eng/build.yml +++ b/eng/build.yml @@ -15,13 +15,13 @@ parameters: timeoutInMinutes: 180 jobs: -- ${{ if and(ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest'), eq(variables['Build.SourceBranch'], 'refs/heads/release/8.0.3xx'), not(contains(parameters.agentOs, 'TemplateEngine'))) }}: +- ${{ if and(ne(variables['System.TeamProject'], 'public'), notin(variables['Build.Reason'], 'PullRequest'), eq(variables['Build.SourceBranch'], 'refs/heads/release/8.0.4xx'), not(contains(parameters.agentOs, 'TemplateEngine'))) }}: - template: /eng/common/templates-official/job/onelocbuild.yml@self parameters: CreatePr: true LclSource: lclFilesfromPackage LclPackageId: 'LCL-JUNO-PROD-DOTNETSDK' - MirrorBranch: release/8.0.3xx + MirrorBranch: release/8.0.4xx MirrorRepo: sdk - ${{ if not(contains(parameters.agentOs, 'TemplateEngine')) }}: From fb41ef0cb16a60e50e2ea1531607e57739768fac Mon Sep 17 00:00:00 2001 From: Sean Reeser Date: Mon, 22 Apr 2024 20:36:56 +0000 Subject: [PATCH 572/577] Merged PR 39128: update runtime build dependencies to march release update runtime build dependencies to march release --- NuGet.config | 17 ++--- eng/Version.Details.xml | 148 ++++++++++++++++++++-------------------- eng/Versions.props | 40 +++++------ 3 files changed, 101 insertions(+), 104 deletions(-) diff --git a/NuGet.config b/NuGet.config index 5d74e23641e5..3ac2c397d8bf 100644 --- a/NuGet.config +++ b/NuGet.config @@ -4,17 +4,17 @@ - - - - - - + + + + + + + - @@ -27,7 +27,6 @@ - @@ -54,7 +53,6 @@ - @@ -62,7 +60,6 @@ - diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 7d0372ad0df2..8dd12a48d8dd 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -10,46 +10,46 @@ https://github.com/dotnet/templating 40c69ed5c711955baf5a624ec83a12e9cd1a8484 - + https://dev.azure.com/dnceng/internal/_git/dotnet-runtime - 087e15321bb712ef6fe8b0ba6f8bd12facf92629 + 9f4b1f5d664afdfc80e1508ab7ed099dff210fbd - + https://dev.azure.com/dnceng/internal/_git/dotnet-runtime - 087e15321bb712ef6fe8b0ba6f8bd12facf92629 + 9f4b1f5d664afdfc80e1508ab7ed099dff210fbd - + https://dev.azure.com/dnceng/internal/_git/dotnet-runtime - 087e15321bb712ef6fe8b0ba6f8bd12facf92629 + 9f4b1f5d664afdfc80e1508ab7ed099dff210fbd - + https://dev.azure.com/dnceng/internal/_git/dotnet-runtime - 087e15321bb712ef6fe8b0ba6f8bd12facf92629 + 9f4b1f5d664afdfc80e1508ab7ed099dff210fbd - + https://dev.azure.com/dnceng/internal/_git/dotnet-runtime - 087e15321bb712ef6fe8b0ba6f8bd12facf92629 + 9f4b1f5d664afdfc80e1508ab7ed099dff210fbd - + https://dev.azure.com/dnceng/internal/_git/dotnet-runtime - 087e15321bb712ef6fe8b0ba6f8bd12facf92629 + 9f4b1f5d664afdfc80e1508ab7ed099dff210fbd - + https://dev.azure.com/dnceng/internal/_git/dotnet-runtime - 087e15321bb712ef6fe8b0ba6f8bd12facf92629 + 9f4b1f5d664afdfc80e1508ab7ed099dff210fbd https://dev.azure.com/dnceng/internal/_git/dotnet-runtime 5535e31a712343a63f5d7d796cd874e563e5ac14 - + https://dev.azure.com/dnceng/internal/_git/dotnet-runtime - 087e15321bb712ef6fe8b0ba6f8bd12facf92629 + 9f4b1f5d664afdfc80e1508ab7ed099dff210fbd - + https://github.com/dotnet/emsdk - 71359b18c2d83c01a68bf155244a65962a7e8c8e + 9a29abdd764a4de0f253ed368871877a47725247 https://github.com/dotnet/msbuild @@ -73,9 +73,9 @@ 90a81d78e3a2780e8fc599fff60c7bfcc5ab4526 - + https://github.com/dotnet/format - ac0d85557969d51bca72181514ddb7d5796fbbe2 + d237e172b324021b97effa244af44d63d1a8bb7e @@ -107,13 +107,13 @@ https://github.com/dotnet/roslyn 3af0081a6e811b78d37c62e479914f7f4cfb0d1a - + https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore - 1681d9acf750c1f1ba8f89d54796c99fbfbfb8b2 + 88ec3bc3f37e76fbcc932a25f9f0c1c29fe2b343 - + https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore - 1681d9acf750c1f1ba8f89d54796c99fbfbfb8b2 + 88ec3bc3f37e76fbcc932a25f9f0c1c29fe2b343 https://github.com/nuget/nuget.client @@ -196,9 +196,9 @@ https://github.com/microsoft/vstest 56d28849af08dc3143d019694aa92f186b89d2ac - + https://dev.azure.com/dnceng/internal/_git/dotnet-runtime - 087e15321bb712ef6fe8b0ba6f8bd12facf92629 + 9f4b1f5d664afdfc80e1508ab7ed099dff210fbd https://dev.azure.com/dnceng/internal/_git/dotnet-runtime @@ -216,70 +216,70 @@ https://dev.azure.com/dnceng/internal/_git/dotnet-runtime 5535e31a712343a63f5d7d796cd874e563e5ac14 - + https://dev.azure.com/dnceng/internal/_git/dotnet-windowsdesktop - dda23bbe00c4a4bfdd3732783f0cce37c11a4f40 + baf3c0df45e13d065884f7e84260f645295f219e - + https://dev.azure.com/dnceng/internal/_git/dotnet-windowsdesktop - dda23bbe00c4a4bfdd3732783f0cce37c11a4f40 + baf3c0df45e13d065884f7e84260f645295f219e - + https://dev.azure.com/dnceng/internal/_git/dotnet-windowsdesktop - dda23bbe00c4a4bfdd3732783f0cce37c11a4f40 + baf3c0df45e13d065884f7e84260f645295f219e - + https://dev.azure.com/dnceng/internal/_git/dotnet-windowsdesktop - dda23bbe00c4a4bfdd3732783f0cce37c11a4f40 + baf3c0df45e13d065884f7e84260f645295f219e - + https://dev.azure.com/dnceng/internal/_git/dotnet-wpf - b5af29a8f41f880f38fd015c6bcb7aeb816fcef6 + 46fb08cfa8160d0885b74c7f28a7b187ab86efed - + https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore - 1681d9acf750c1f1ba8f89d54796c99fbfbfb8b2 + 88ec3bc3f37e76fbcc932a25f9f0c1c29fe2b343 - + https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore - 1681d9acf750c1f1ba8f89d54796c99fbfbfb8b2 + 88ec3bc3f37e76fbcc932a25f9f0c1c29fe2b343 - + https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore - 1681d9acf750c1f1ba8f89d54796c99fbfbfb8b2 + 88ec3bc3f37e76fbcc932a25f9f0c1c29fe2b343 - + https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore - 1681d9acf750c1f1ba8f89d54796c99fbfbfb8b2 + 88ec3bc3f37e76fbcc932a25f9f0c1c29fe2b343 - + https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore - 1681d9acf750c1f1ba8f89d54796c99fbfbfb8b2 + 88ec3bc3f37e76fbcc932a25f9f0c1c29fe2b343 - + https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore - 1681d9acf750c1f1ba8f89d54796c99fbfbfb8b2 + 88ec3bc3f37e76fbcc932a25f9f0c1c29fe2b343 - + https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore - 1681d9acf750c1f1ba8f89d54796c99fbfbfb8b2 + 88ec3bc3f37e76fbcc932a25f9f0c1c29fe2b343 - + https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore - 1681d9acf750c1f1ba8f89d54796c99fbfbfb8b2 + 88ec3bc3f37e76fbcc932a25f9f0c1c29fe2b343 - + https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore - 1681d9acf750c1f1ba8f89d54796c99fbfbfb8b2 + 88ec3bc3f37e76fbcc932a25f9f0c1c29fe2b343 - + https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore - 1681d9acf750c1f1ba8f89d54796c99fbfbfb8b2 + 88ec3bc3f37e76fbcc932a25f9f0c1c29fe2b343 - + https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore - 1681d9acf750c1f1ba8f89d54796c99fbfbfb8b2 + 88ec3bc3f37e76fbcc932a25f9f0c1c29fe2b343 https://github.com/dotnet/razor @@ -294,21 +294,21 @@ https://github.com/dotnet/razor bf7698527c4dc48ce1965bc8cdd9b2c35115dab6 - + https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore - 1681d9acf750c1f1ba8f89d54796c99fbfbfb8b2 + 88ec3bc3f37e76fbcc932a25f9f0c1c29fe2b343 - + https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore - 1681d9acf750c1f1ba8f89d54796c99fbfbfb8b2 + 88ec3bc3f37e76fbcc932a25f9f0c1c29fe2b343 - + https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore - 1681d9acf750c1f1ba8f89d54796c99fbfbfb8b2 + 88ec3bc3f37e76fbcc932a25f9f0c1c29fe2b343 - + https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore - 1681d9acf750c1f1ba8f89d54796c99fbfbfb8b2 + 88ec3bc3f37e76fbcc932a25f9f0c1c29fe2b343 https://github.com/dotnet/xdt @@ -394,9 +394,9 @@ 5535e31a712343a63f5d7d796cd874e563e5ac14 - + https://dev.azure.com/dnceng/internal/_git/dotnet-runtime - 5535e31a712343a63f5d7d796cd874e563e5ac14 + 9f4b1f5d664afdfc80e1508ab7ed099dff210fbd @@ -413,9 +413,9 @@ https://dev.azure.com/dnceng/internal/_git/dotnet-runtime 5535e31a712343a63f5d7d796cd874e563e5ac14 - + https://dev.azure.com/dnceng/internal/_git/dotnet-runtime - 1381d5ebd2ab1f292848d5b19b80cf71ac332508 + 9f4b1f5d664afdfc80e1508ab7ed099dff210fbd https://dev.azure.com/dnceng/internal/_git/dotnet-runtime @@ -425,9 +425,9 @@ https://dev.azure.com/dnceng/internal/_git/dotnet-runtime 5535e31a712343a63f5d7d796cd874e563e5ac14 - + https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore - 1681d9acf750c1f1ba8f89d54796c99fbfbfb8b2 + 88ec3bc3f37e76fbcc932a25f9f0c1c29fe2b343 https://dev.azure.com/dnceng/internal/_git/dotnet-runtime @@ -457,9 +457,9 @@ https://dev.azure.com/dnceng/internal/_git/dotnet-runtime 5535e31a712343a63f5d7d796cd874e563e5ac14 - + https://dev.azure.com/dnceng/internal/_git/dotnet-winforms - c58fa00bd16b92aab1d7fb2b93e71af6a7768139 + bd280bbb5c9699bb93097206f076ad2f330ea8e1 https://dev.azure.com/dnceng/internal/_git/dotnet-runtime diff --git a/eng/Versions.props b/eng/Versions.props index 273b431024c2..abe6eda149b4 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -50,22 +50,22 @@ - 8.0.5 - 8.0.5-servicing.24216.15 - 8.0.5 + 8.0.3 + 8.0.3-servicing.24114.23 + 8.0.3 $(MicrosoftNETCoreAppRuntimewinx64PackageVersion) 8.0.0 - 8.0.5 - 8.0.5-servicing.24216.15 + 8.0.3 + 8.0.3-servicing.24114.23 8.0.0 $(MicrosoftExtensionsDependencyModelPackageVersion) 8.0.0 - 8.0.0 + 8.0.1 8.0.0 - 8.0.5 + 8.0.3 8.0.0 8.0.0 - 8.0.5 + 8.0.3 8.0.0 8.0.0 8.0.0 @@ -73,12 +73,12 @@ 8.0.0 8.0.0 8.0.0 - 8.0.2 + 8.0.3 8.0.0 8.0.1 8.0.0 8.0.0 - 8.0.2 + 8.0.3 8.0.0 @@ -112,7 +112,7 @@ - 8.0.512703 + 8.0.511601 @@ -166,13 +166,13 @@ - 8.0.5 - 8.0.5-servicing.24217.6 - 8.0.5-servicing.24217.6 - 8.0.5-servicing.24217.6 - 8.0.5-servicing.24217.6 - 8.0.5-servicing.24217.6 - 8.0.5 + 8.0.3 + 8.0.3-servicing.24116.15 + 8.0.3-servicing.24116.15 + 8.0.3-servicing.24116.15 + 8.0.3-servicing.24116.15 + 8.0.3-servicing.24116.15 + 8.0.3 @@ -182,7 +182,7 @@ - 8.0.5-servicing.24217.2 + 8.0.3-servicing.24116.6 @@ -226,7 +226,7 @@ - 8.0.5 + 8.0.3 $(MicrosoftNETWorkloadEmscriptenCurrentManifest80100PackageVersion) 8.0.100$([System.Text.RegularExpressions.Regex]::Match($(EmscriptenWorkloadManifestVersion), `-rtm|-[A-z]*\.*\d*`)) From 3432f38d7810a4787a1e3546e01048d7eee1986f Mon Sep 17 00:00:00 2001 From: Sean Reeser Date: Mon, 22 Apr 2024 22:01:30 +0000 Subject: [PATCH 573/577] Merged PR 39130: update runtime build dependencies to april release update runtime build dependencies to april release --- eng/Version.Details.xml | 136 ++++++++++++++++++++-------------------- eng/Versions.props | 34 +++++----- 2 files changed, 85 insertions(+), 85 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 8dd12a48d8dd..6f2e00837b0b 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -10,46 +10,46 @@ https://github.com/dotnet/templating 40c69ed5c711955baf5a624ec83a12e9cd1a8484 - + https://dev.azure.com/dnceng/internal/_git/dotnet-runtime - 9f4b1f5d664afdfc80e1508ab7ed099dff210fbd + 2d7eea252964e69be94cb9c847b371b23e4dd470 - + https://dev.azure.com/dnceng/internal/_git/dotnet-runtime - 9f4b1f5d664afdfc80e1508ab7ed099dff210fbd + 2d7eea252964e69be94cb9c847b371b23e4dd470 - + https://dev.azure.com/dnceng/internal/_git/dotnet-runtime - 9f4b1f5d664afdfc80e1508ab7ed099dff210fbd + 2d7eea252964e69be94cb9c847b371b23e4dd470 - + https://dev.azure.com/dnceng/internal/_git/dotnet-runtime - 9f4b1f5d664afdfc80e1508ab7ed099dff210fbd + 2d7eea252964e69be94cb9c847b371b23e4dd470 - + https://dev.azure.com/dnceng/internal/_git/dotnet-runtime - 9f4b1f5d664afdfc80e1508ab7ed099dff210fbd + 2d7eea252964e69be94cb9c847b371b23e4dd470 - + https://dev.azure.com/dnceng/internal/_git/dotnet-runtime - 9f4b1f5d664afdfc80e1508ab7ed099dff210fbd + 2d7eea252964e69be94cb9c847b371b23e4dd470 - + https://dev.azure.com/dnceng/internal/_git/dotnet-runtime - 9f4b1f5d664afdfc80e1508ab7ed099dff210fbd + 2d7eea252964e69be94cb9c847b371b23e4dd470 https://dev.azure.com/dnceng/internal/_git/dotnet-runtime 5535e31a712343a63f5d7d796cd874e563e5ac14 - + https://dev.azure.com/dnceng/internal/_git/dotnet-runtime - 9f4b1f5d664afdfc80e1508ab7ed099dff210fbd + 2d7eea252964e69be94cb9c847b371b23e4dd470 - + https://github.com/dotnet/emsdk - 9a29abdd764a4de0f253ed368871877a47725247 + 08a90ca2c88b17f1b5d081318354a41db0882cff https://github.com/dotnet/msbuild @@ -107,13 +107,13 @@ https://github.com/dotnet/roslyn 3af0081a6e811b78d37c62e479914f7f4cfb0d1a - + https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore - 88ec3bc3f37e76fbcc932a25f9f0c1c29fe2b343 + 8486d31e24f30e3fa1809a95699a0adc16f448d7 - + https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore - 88ec3bc3f37e76fbcc932a25f9f0c1c29fe2b343 + 8486d31e24f30e3fa1809a95699a0adc16f448d7 https://github.com/nuget/nuget.client @@ -196,9 +196,9 @@ https://github.com/microsoft/vstest 56d28849af08dc3143d019694aa92f186b89d2ac - + https://dev.azure.com/dnceng/internal/_git/dotnet-runtime - 9f4b1f5d664afdfc80e1508ab7ed099dff210fbd + 2d7eea252964e69be94cb9c847b371b23e4dd470 https://dev.azure.com/dnceng/internal/_git/dotnet-runtime @@ -216,70 +216,70 @@ https://dev.azure.com/dnceng/internal/_git/dotnet-runtime 5535e31a712343a63f5d7d796cd874e563e5ac14 - + https://dev.azure.com/dnceng/internal/_git/dotnet-windowsdesktop - baf3c0df45e13d065884f7e84260f645295f219e + 04094d116496e0bd1d376fd346397ec7900141f8 - + https://dev.azure.com/dnceng/internal/_git/dotnet-windowsdesktop - baf3c0df45e13d065884f7e84260f645295f219e + 04094d116496e0bd1d376fd346397ec7900141f8 - + https://dev.azure.com/dnceng/internal/_git/dotnet-windowsdesktop - baf3c0df45e13d065884f7e84260f645295f219e + 04094d116496e0bd1d376fd346397ec7900141f8 - + https://dev.azure.com/dnceng/internal/_git/dotnet-windowsdesktop - baf3c0df45e13d065884f7e84260f645295f219e + 04094d116496e0bd1d376fd346397ec7900141f8 - + https://dev.azure.com/dnceng/internal/_git/dotnet-wpf - 46fb08cfa8160d0885b74c7f28a7b187ab86efed + ebbf01f54996755566db36e2e962ba6364da2ecc - + https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore - 88ec3bc3f37e76fbcc932a25f9f0c1c29fe2b343 + 8486d31e24f30e3fa1809a95699a0adc16f448d7 - + https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore - 88ec3bc3f37e76fbcc932a25f9f0c1c29fe2b343 + 8486d31e24f30e3fa1809a95699a0adc16f448d7 - + https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore - 88ec3bc3f37e76fbcc932a25f9f0c1c29fe2b343 + 8486d31e24f30e3fa1809a95699a0adc16f448d7 - + https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore - 88ec3bc3f37e76fbcc932a25f9f0c1c29fe2b343 + 8486d31e24f30e3fa1809a95699a0adc16f448d7 - + https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore - 88ec3bc3f37e76fbcc932a25f9f0c1c29fe2b343 + 8486d31e24f30e3fa1809a95699a0adc16f448d7 - + https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore - 88ec3bc3f37e76fbcc932a25f9f0c1c29fe2b343 + 8486d31e24f30e3fa1809a95699a0adc16f448d7 - + https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore - 88ec3bc3f37e76fbcc932a25f9f0c1c29fe2b343 + 8486d31e24f30e3fa1809a95699a0adc16f448d7 - + https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore - 88ec3bc3f37e76fbcc932a25f9f0c1c29fe2b343 + 8486d31e24f30e3fa1809a95699a0adc16f448d7 - + https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore - 88ec3bc3f37e76fbcc932a25f9f0c1c29fe2b343 + 8486d31e24f30e3fa1809a95699a0adc16f448d7 - + https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore - 88ec3bc3f37e76fbcc932a25f9f0c1c29fe2b343 + 8486d31e24f30e3fa1809a95699a0adc16f448d7 - + https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore - 88ec3bc3f37e76fbcc932a25f9f0c1c29fe2b343 + 8486d31e24f30e3fa1809a95699a0adc16f448d7 https://github.com/dotnet/razor @@ -294,21 +294,21 @@ https://github.com/dotnet/razor bf7698527c4dc48ce1965bc8cdd9b2c35115dab6 - + https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore - 88ec3bc3f37e76fbcc932a25f9f0c1c29fe2b343 + 8486d31e24f30e3fa1809a95699a0adc16f448d7 - + https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore - 88ec3bc3f37e76fbcc932a25f9f0c1c29fe2b343 + 8486d31e24f30e3fa1809a95699a0adc16f448d7 - + https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore - 88ec3bc3f37e76fbcc932a25f9f0c1c29fe2b343 + 8486d31e24f30e3fa1809a95699a0adc16f448d7 - + https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore - 88ec3bc3f37e76fbcc932a25f9f0c1c29fe2b343 + 8486d31e24f30e3fa1809a95699a0adc16f448d7 https://github.com/dotnet/xdt @@ -425,9 +425,9 @@ https://dev.azure.com/dnceng/internal/_git/dotnet-runtime 5535e31a712343a63f5d7d796cd874e563e5ac14 - + https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore - 88ec3bc3f37e76fbcc932a25f9f0c1c29fe2b343 + 8486d31e24f30e3fa1809a95699a0adc16f448d7 https://dev.azure.com/dnceng/internal/_git/dotnet-runtime @@ -457,9 +457,9 @@ https://dev.azure.com/dnceng/internal/_git/dotnet-runtime 5535e31a712343a63f5d7d796cd874e563e5ac14 - + https://dev.azure.com/dnceng/internal/_git/dotnet-winforms - bd280bbb5c9699bb93097206f076ad2f330ea8e1 + 41a4bd690229661e3ec74276ce3f93863b22435b https://dev.azure.com/dnceng/internal/_git/dotnet-runtime diff --git a/eng/Versions.props b/eng/Versions.props index abe6eda149b4..ad1cc7b16a47 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -50,22 +50,22 @@ - 8.0.3 - 8.0.3-servicing.24114.23 - 8.0.3 + 8.0.4 + 8.0.4-servicing.24169.9 + 8.0.4 $(MicrosoftNETCoreAppRuntimewinx64PackageVersion) 8.0.0 - 8.0.3 - 8.0.3-servicing.24114.23 + 8.0.4 + 8.0.4-servicing.24169.9 8.0.0 $(MicrosoftExtensionsDependencyModelPackageVersion) 8.0.0 8.0.1 8.0.0 - 8.0.3 + 8.0.4 8.0.0 8.0.0 - 8.0.3 + 8.0.4 8.0.0 8.0.0 8.0.0 @@ -73,7 +73,7 @@ 8.0.0 8.0.0 8.0.0 - 8.0.3 + 8.0.4 8.0.0 8.0.1 8.0.0 @@ -166,13 +166,13 @@ - 8.0.3 - 8.0.3-servicing.24116.15 - 8.0.3-servicing.24116.15 - 8.0.3-servicing.24116.15 - 8.0.3-servicing.24116.15 - 8.0.3-servicing.24116.15 - 8.0.3 + 8.0.4 + 8.0.4-servicing.24170.14 + 8.0.4-servicing.24170.14 + 8.0.4-servicing.24170.14 + 8.0.4-servicing.24170.14 + 8.0.4-servicing.24170.14 + 8.0.4 @@ -182,7 +182,7 @@ - 8.0.3-servicing.24116.6 + 8.0.4-servicing.24169.10 @@ -226,7 +226,7 @@ - 8.0.3 + 8.0.4 $(MicrosoftNETWorkloadEmscriptenCurrentManifest80100PackageVersion) 8.0.100$([System.Text.RegularExpressions.Regex]::Match($(EmscriptenWorkloadManifestVersion), `-rtm|-[A-z]*\.*\d*`)) From 24b24dff657fb42ae4db343aff5a369a171929f1 Mon Sep 17 00:00:00 2001 From: DotNet Bot Date: Mon, 22 Apr 2024 22:06:38 +0000 Subject: [PATCH 574/577] Merged PR 39131: [internal/release/8.0.3xx] Update dependencies from 3 repositories This pull request updates the following dependencies [marker]: <> (Begin:Coherency Updates) ## Coherency Updates The following updates ensure that dependencies with a *CoherentParentDependency* attribute were produced in a build used as input to the parent dependency's build. See [Dependency Description Format](https://github.com/dotnet/arcade/blob/master/Documentation/DependencyDescriptionFormat.md#dependency-description-overview) [DependencyUpdate]: <> (Begin) - **Coherency Updates**: - **Microsoft.NET.Workload.Emscripten.Current.Manifest-8.0.100**: from 8.0.4 to 8.0.5 (parent: Microsoft.NETCore.App.Runtime.win-x64) [DependencyUpdate]: <> (End) [marker]: <> (End:Coherency Updates) [marker]: <> (Begin:1adb2556-0120-43d1-c468-08dc11e32ec2) ## From https://dev.azure.com/dnceng/internal/_git/dotnet-windowsdesktop - **Subscription**: 1adb2556-0120-43d1-c468-08dc11e32ec2 - **Build**: 20240417.5 - **Date Produced**: April 17, 2024 10:17:39 PM UTC - **Commit**: dda23bbe00c4a4bfdd3732783f0cce37c11a4f40 - **Branch**: refs/heads/internal/release/8.0 [DependencyUpdate]: <> (Begin) - **Updates**: - **Microsoft.WindowsDesktop.App.Ref**: [from 8.0.4 to 8.0.5][1] - **Microsoft.WindowsDesktop.App.Runtime.win-x64**: [from 8.0.4 to 8.0.5][1] - **VS.Redist.Common.WindowsDesktop.SharedFramework.x64.8.0**: [from 8.0.4-servicing.24169.24 to 8.0.5-servicing.24217.5][1] - **VS.Redist.Common.WindowsDesktop.TargetingPack.x64.8.0**: [from 8.0.4-servicing.24169.24 to 8.0.5-servicing.24217.5][1] - **Microsoft.NET.Sdk.WindowsDesktop**: [from 8.0.4-servicing.24169.10 to 8.0.5-servicing.24217.2][2] [1]: https://dev.azure.com/dnceng/internal/_git/dotnet-windowsdesktop/branches?baseVersion=GC04094d116496e0bd1d376fd346397ec7900141f8&targetVersion=GCdda23bbe00c4a4bfdd3732783f0cce37c11a4f40&_a=files [2]: https://dev.azure.com/dnceng/internal/_git/dotnet-wpf/branches?baseVersion=GCebbf01f54996755566db36e2e962ba6364da2ecc&targetVersion=GCb5af29a8f41f880f38fd015c6bcb7aeb816fcef6&_a=files [DependencyUpdate]: <> (End) [marker]: <> (End:1adb2556-0120-43d1-c468-08dc11e32ec2) [marker]: <> (Begin:911684f3-0faa-4fc9-de45-08dc11e85c3a) ## From https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore - **Subscription**: 911684f3-0faa-4fc9-de45-08dc11e85c3a - **Build**: 20240417.6 - **Date Produced**: April 17, 2024 10:32:21 PM UTC - **Commit**: 1681d9acf750c1f1ba8f89d54796c99fbfbfb8b2 - **Branch**: refs/heads/internal/release/8.0 [DependencyUpdate]: <> (Begin) - **Updates**: - **dotnet-dev-certs**: [from 8.0.4-servicing.24170.14 to 8.0.5-servicing.24217.6][3] - **dotnet-user-jwts**: [from 8.0.4-servicing.24170.14 to 8.0.5-servicing.24217.6][3] - **dotnet-user-secrets**: [from 8.0.4-servicing.24170.14 to 8.0.5-servicing.24217.6][3] - **Microsoft.AspNetCore.Analyzers**: [from 8.0.4-servicing.24170.14 to 8.0.5-servicing.24217.6][3] - **Microsoft.AspNetCore.App.Ref**: [from 8.0.4 to 8.0.5][3] ... --- NuGet.config | 5 ++ eng/Version.Details.xml | 132 ++++++++++++++++++++-------------------- eng/Versions.props | 32 +++++----- 3 files changed, 87 insertions(+), 82 deletions(-) diff --git a/NuGet.config b/NuGet.config index 3ac2c397d8bf..fd5c19e788eb 100644 --- a/NuGet.config +++ b/NuGet.config @@ -4,6 +4,7 @@ + @@ -15,6 +16,7 @@ + @@ -27,6 +29,7 @@ + @@ -53,6 +56,7 @@ + @@ -60,6 +64,7 @@ + diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 6f2e00837b0b..61fb7a352af3 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -10,46 +10,46 @@ https://github.com/dotnet/templating 40c69ed5c711955baf5a624ec83a12e9cd1a8484 - + https://dev.azure.com/dnceng/internal/_git/dotnet-runtime - 2d7eea252964e69be94cb9c847b371b23e4dd470 + 087e15321bb712ef6fe8b0ba6f8bd12facf92629 - + https://dev.azure.com/dnceng/internal/_git/dotnet-runtime - 2d7eea252964e69be94cb9c847b371b23e4dd470 + 087e15321bb712ef6fe8b0ba6f8bd12facf92629 - + https://dev.azure.com/dnceng/internal/_git/dotnet-runtime - 2d7eea252964e69be94cb9c847b371b23e4dd470 + 087e15321bb712ef6fe8b0ba6f8bd12facf92629 - + https://dev.azure.com/dnceng/internal/_git/dotnet-runtime - 2d7eea252964e69be94cb9c847b371b23e4dd470 + 087e15321bb712ef6fe8b0ba6f8bd12facf92629 - + https://dev.azure.com/dnceng/internal/_git/dotnet-runtime - 2d7eea252964e69be94cb9c847b371b23e4dd470 + 087e15321bb712ef6fe8b0ba6f8bd12facf92629 - + https://dev.azure.com/dnceng/internal/_git/dotnet-runtime - 2d7eea252964e69be94cb9c847b371b23e4dd470 + 087e15321bb712ef6fe8b0ba6f8bd12facf92629 - + https://dev.azure.com/dnceng/internal/_git/dotnet-runtime - 2d7eea252964e69be94cb9c847b371b23e4dd470 + 087e15321bb712ef6fe8b0ba6f8bd12facf92629 https://dev.azure.com/dnceng/internal/_git/dotnet-runtime 5535e31a712343a63f5d7d796cd874e563e5ac14 - + https://dev.azure.com/dnceng/internal/_git/dotnet-runtime - 2d7eea252964e69be94cb9c847b371b23e4dd470 + 087e15321bb712ef6fe8b0ba6f8bd12facf92629 - + https://github.com/dotnet/emsdk - 08a90ca2c88b17f1b5d081318354a41db0882cff + 71359b18c2d83c01a68bf155244a65962a7e8c8e https://github.com/dotnet/msbuild @@ -107,13 +107,13 @@ https://github.com/dotnet/roslyn 3af0081a6e811b78d37c62e479914f7f4cfb0d1a - + https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore - 8486d31e24f30e3fa1809a95699a0adc16f448d7 + 1681d9acf750c1f1ba8f89d54796c99fbfbfb8b2 - + https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore - 8486d31e24f30e3fa1809a95699a0adc16f448d7 + 1681d9acf750c1f1ba8f89d54796c99fbfbfb8b2 https://github.com/nuget/nuget.client @@ -196,9 +196,9 @@ https://github.com/microsoft/vstest 56d28849af08dc3143d019694aa92f186b89d2ac - + https://dev.azure.com/dnceng/internal/_git/dotnet-runtime - 2d7eea252964e69be94cb9c847b371b23e4dd470 + 087e15321bb712ef6fe8b0ba6f8bd12facf92629 https://dev.azure.com/dnceng/internal/_git/dotnet-runtime @@ -216,70 +216,70 @@ https://dev.azure.com/dnceng/internal/_git/dotnet-runtime 5535e31a712343a63f5d7d796cd874e563e5ac14 - + https://dev.azure.com/dnceng/internal/_git/dotnet-windowsdesktop - 04094d116496e0bd1d376fd346397ec7900141f8 + dda23bbe00c4a4bfdd3732783f0cce37c11a4f40 - + https://dev.azure.com/dnceng/internal/_git/dotnet-windowsdesktop - 04094d116496e0bd1d376fd346397ec7900141f8 + dda23bbe00c4a4bfdd3732783f0cce37c11a4f40 - + https://dev.azure.com/dnceng/internal/_git/dotnet-windowsdesktop - 04094d116496e0bd1d376fd346397ec7900141f8 + dda23bbe00c4a4bfdd3732783f0cce37c11a4f40 - + https://dev.azure.com/dnceng/internal/_git/dotnet-windowsdesktop - 04094d116496e0bd1d376fd346397ec7900141f8 + dda23bbe00c4a4bfdd3732783f0cce37c11a4f40 - + https://dev.azure.com/dnceng/internal/_git/dotnet-wpf - ebbf01f54996755566db36e2e962ba6364da2ecc + b5af29a8f41f880f38fd015c6bcb7aeb816fcef6 - + https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore - 8486d31e24f30e3fa1809a95699a0adc16f448d7 + 1681d9acf750c1f1ba8f89d54796c99fbfbfb8b2 - + https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore - 8486d31e24f30e3fa1809a95699a0adc16f448d7 + 1681d9acf750c1f1ba8f89d54796c99fbfbfb8b2 - + https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore - 8486d31e24f30e3fa1809a95699a0adc16f448d7 + 1681d9acf750c1f1ba8f89d54796c99fbfbfb8b2 - + https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore - 8486d31e24f30e3fa1809a95699a0adc16f448d7 + 1681d9acf750c1f1ba8f89d54796c99fbfbfb8b2 - + https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore - 8486d31e24f30e3fa1809a95699a0adc16f448d7 + 1681d9acf750c1f1ba8f89d54796c99fbfbfb8b2 - + https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore - 8486d31e24f30e3fa1809a95699a0adc16f448d7 + 1681d9acf750c1f1ba8f89d54796c99fbfbfb8b2 - + https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore - 8486d31e24f30e3fa1809a95699a0adc16f448d7 + 1681d9acf750c1f1ba8f89d54796c99fbfbfb8b2 - + https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore - 8486d31e24f30e3fa1809a95699a0adc16f448d7 + 1681d9acf750c1f1ba8f89d54796c99fbfbfb8b2 - + https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore - 8486d31e24f30e3fa1809a95699a0adc16f448d7 + 1681d9acf750c1f1ba8f89d54796c99fbfbfb8b2 - + https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore - 8486d31e24f30e3fa1809a95699a0adc16f448d7 + 1681d9acf750c1f1ba8f89d54796c99fbfbfb8b2 - + https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore - 8486d31e24f30e3fa1809a95699a0adc16f448d7 + 1681d9acf750c1f1ba8f89d54796c99fbfbfb8b2 https://github.com/dotnet/razor @@ -294,21 +294,21 @@ https://github.com/dotnet/razor bf7698527c4dc48ce1965bc8cdd9b2c35115dab6 - + https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore - 8486d31e24f30e3fa1809a95699a0adc16f448d7 + 1681d9acf750c1f1ba8f89d54796c99fbfbfb8b2 - + https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore - 8486d31e24f30e3fa1809a95699a0adc16f448d7 + 1681d9acf750c1f1ba8f89d54796c99fbfbfb8b2 - + https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore - 8486d31e24f30e3fa1809a95699a0adc16f448d7 + 1681d9acf750c1f1ba8f89d54796c99fbfbfb8b2 - + https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore - 8486d31e24f30e3fa1809a95699a0adc16f448d7 + 1681d9acf750c1f1ba8f89d54796c99fbfbfb8b2 https://github.com/dotnet/xdt @@ -425,9 +425,9 @@ https://dev.azure.com/dnceng/internal/_git/dotnet-runtime 5535e31a712343a63f5d7d796cd874e563e5ac14 - + https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore - 8486d31e24f30e3fa1809a95699a0adc16f448d7 + 1681d9acf750c1f1ba8f89d54796c99fbfbfb8b2 https://dev.azure.com/dnceng/internal/_git/dotnet-runtime diff --git a/eng/Versions.props b/eng/Versions.props index ad1cc7b16a47..1985b48ab03d 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -50,22 +50,22 @@ - 8.0.4 - 8.0.4-servicing.24169.9 - 8.0.4 + 8.0.5 + 8.0.5-servicing.24216.15 + 8.0.5 $(MicrosoftNETCoreAppRuntimewinx64PackageVersion) 8.0.0 - 8.0.4 - 8.0.4-servicing.24169.9 + 8.0.5 + 8.0.5-servicing.24216.15 8.0.0 $(MicrosoftExtensionsDependencyModelPackageVersion) 8.0.0 8.0.1 8.0.0 - 8.0.4 + 8.0.5 8.0.0 8.0.0 - 8.0.4 + 8.0.5 8.0.0 8.0.0 8.0.0 @@ -166,13 +166,13 @@ - 8.0.4 - 8.0.4-servicing.24170.14 - 8.0.4-servicing.24170.14 - 8.0.4-servicing.24170.14 - 8.0.4-servicing.24170.14 - 8.0.4-servicing.24170.14 - 8.0.4 + 8.0.5 + 8.0.5-servicing.24217.6 + 8.0.5-servicing.24217.6 + 8.0.5-servicing.24217.6 + 8.0.5-servicing.24217.6 + 8.0.5-servicing.24217.6 + 8.0.5 @@ -182,7 +182,7 @@ - 8.0.4-servicing.24169.10 + 8.0.5-servicing.24217.2 @@ -226,7 +226,7 @@ - 8.0.4 + 8.0.5 $(MicrosoftNETWorkloadEmscriptenCurrentManifest80100PackageVersion) 8.0.100$([System.Text.RegularExpressions.Regex]::Match($(EmscriptenWorkloadManifestVersion), `-rtm|-[A-z]*\.*\d*`)) From 9c9c6b892bc050f14f204c11208db36a0d2513a9 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Tue, 23 Apr 2024 01:59:47 +0000 Subject: [PATCH 575/577] [release/8.0.3xx] Update dependencies from dotnet/templating (#40311) [release/8.0.3xx] Update dependencies from dotnet/templating - Update Version.Details.xml Add direct dependency on Microsoft.SourceBuild.Intermediate.templating --- NuGet.config | 2 ++ eng/Version.Details.xml | 14 +++++++++----- eng/Versions.props | 4 ++-- 3 files changed, 13 insertions(+), 7 deletions(-) diff --git a/NuGet.config b/NuGet.config index 067d780dc0a2..b066aed06ac9 100644 --- a/NuGet.config +++ b/NuGet.config @@ -7,6 +7,7 @@ + @@ -22,6 +23,7 @@ + diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 8bef9bfb5307..42815508ce08 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -1,14 +1,18 @@ - + https://github.com/dotnet/templating - 40c69ed5c711955baf5a624ec83a12e9cd1a8484 - + 7e0db003cac85364c450d0c7e916c2b1df17eb11 + + + https://github.com/dotnet/templating + 7e0db003cac85364c450d0c7e916c2b1df17eb11 - + https://github.com/dotnet/templating - 40c69ed5c711955baf5a624ec83a12e9cd1a8484 + 7e0db003cac85364c450d0c7e916c2b1df17eb11 + https://dev.azure.com/dnceng/internal/_git/dotnet-runtime diff --git a/eng/Versions.props b/eng/Versions.props index 6b07ea4f95c0..0203559c51f0 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -138,13 +138,13 @@ - 8.0.300-preview.24206.1 + 8.0.300 $(MicrosoftTemplateEngineAbstractionsPackageVersion) $(MicrosoftTemplateEngineAbstractionsPackageVersion) $(MicrosoftTemplateEngineAbstractionsPackageVersion) $(MicrosoftTemplateEngineAbstractionsPackageVersion) - 8.0.300-preview.24206.1 + 8.0.300-rtm.24218.7 $(MicrosoftTemplateEngineMocksPackageVersion) $(MicrosoftTemplateEngineAbstractionsPackageVersion) $(MicrosoftTemplateEngineMocksPackageVersion) From 41cc4535199ed7d3ceb126f3588fee7fb31fa720 Mon Sep 17 00:00:00 2001 From: Sean Reeser Date: Tue, 23 Apr 2024 23:36:03 +0000 Subject: [PATCH 576/577] Merged PR 39172: Updated NuGet.config - revert format feeds to values prior to merge from publ... Updated NuGet.config - revert format feeds to values prior to merge from public dd266941272bcc89cb144e71f1d555f2a1f0f6e2 --- NuGet.config | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/NuGet.config b/NuGet.config index e9f2994eb209..b15dd3f7c111 100644 --- a/NuGet.config +++ b/NuGet.config @@ -7,12 +7,13 @@ - - - - - - + + + + + + + From 5c2ea7348fe2457b5187dce990b10bda9bb1902b Mon Sep 17 00:00:00 2001 From: DotNet Bot Date: Wed, 24 Apr 2024 20:52:13 +0000 Subject: [PATCH 577/577] Merged PR 39211: [internal/release/8.0.3xx] Update dependencies from dnceng/internal/dotnet-aspnetcore This pull request updates the following dependencies [marker]: <> (Begin:911684f3-0faa-4fc9-de45-08dc11e85c3a) ## From https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore - **Subscription**: 911684f3-0faa-4fc9-de45-08dc11e85c3a - **Build**: 20240424.4 - **Date Produced**: April 24, 2024 8:13:40 PM UTC - **Commit**: c9e3996173cec136bc2e9f3b4ec45f2a323b1d63 - **Branch**: refs/heads/internal/release/8.0 [DependencyUpdate]: <> (Begin) - **Updates**: - **dotnet-dev-certs**: [from 8.0.5-servicing.24217.6 to 8.0.5-servicing.24224.4][1] - **dotnet-user-jwts**: [from 8.0.5-servicing.24217.6 to 8.0.5-servicing.24224.4][1] - **dotnet-user-secrets**: [from 8.0.5-servicing.24217.6 to 8.0.5-servicing.24224.4][1] - **Microsoft.AspNetCore.Analyzers**: [from 8.0.5-servicing.24217.6 to 8.0.5-servicing.24224.4][1] - **Microsoft.AspNetCore.App.Ref**: [from 8.0.5 to 8.0.5][1] - **Microsoft.AspNetCore.App.Ref.Internal**: [from 8.0.5-servicing.24217.6 to 8.0.5-servicing.24224.4][1] - **Microsoft.AspNetCore.App.Runtime.win-x64**: [from 8.0.5 to 8.0.5][1] - **Microsoft.AspNetCore.Authorization**: [from 8.0.5 to 8.0.5][1] - **Microsoft.AspNetCore.Components.SdkAnalyzers**: [from 8.0.5-servicing.24217.6 to 8.0.5-servicing.24224.4][1] - **Microsoft.AspNetCore.Components.Web**: [from 8.0.5 to 8.0.5][1] - **Microsoft.AspNetCore.DeveloperCertificates.XPlat**: [from 8.0.5-servicing.24217.6 to 8.0.5-servicing.24224.4][1] - **Microsoft.AspNetCore.Mvc.Analyzers**: [from 8.0.5-servicing.24217.6 to 8.0.5-servicing.24224.4][1] - **Microsoft.AspNetCore.Mvc.Api.Analyzers**: [from 8.0.5-servicing.24217.6 to 8.0.5-servicing.24224.4][1] - **Microsoft.AspNetCore.TestHost**: [from 8.0.5 to 8.0.5][1] - **Microsoft.Extensions.FileProviders.Embedded**: [from 8.0.5 to 8.0.5][1] - **Microsoft.Extensions.ObjectPool**: [from 8.0.5 to 8.0.5][1] - **Microsoft.JSInterop**: [from 8.0.5 to 8.0.5][1] - **VS.Redist.Common.AspNetCore.SharedFramework.x64.8.0**: [from 8.0.5-servicing.24217.6 to 8.0.5-servicing.24224.4][1] [1]: https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore/branches?baseVersion=GC1681d9acf750c1f1ba8f89d54796c99fbfbfb8b2&targetVersion=GCc9e3996173cec136bc2e9f3b4ec45f2a323b1d63&_a=files [DependencyUpdate]: <> (End) [marker]: <> (End:911684f3-0faa-4fc9-de45-08dc11e85c3a) --- NuGet.config | 4 +-- eng/Version.Details.xml | 56 ++++++++++++++++++++--------------------- eng/Versions.props | 10 ++++---- 3 files changed, 35 insertions(+), 35 deletions(-) diff --git a/NuGet.config b/NuGet.config index b15dd3f7c111..9613e4ee01d8 100644 --- a/NuGet.config +++ b/NuGet.config @@ -16,7 +16,7 @@ - + @@ -57,7 +57,7 @@ - + diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 6b47e6ce95f4..04884e8dc297 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -111,13 +111,13 @@ https://github.com/dotnet/roslyn 3af0081a6e811b78d37c62e479914f7f4cfb0d1a - + https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore - 1681d9acf750c1f1ba8f89d54796c99fbfbfb8b2 + c9e3996173cec136bc2e9f3b4ec45f2a323b1d63 https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore - 1681d9acf750c1f1ba8f89d54796c99fbfbfb8b2 + c9e3996173cec136bc2e9f3b4ec45f2a323b1d63 https://github.com/nuget/nuget.client @@ -242,48 +242,48 @@ https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore - 1681d9acf750c1f1ba8f89d54796c99fbfbfb8b2 + c9e3996173cec136bc2e9f3b4ec45f2a323b1d63 - + https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore - 1681d9acf750c1f1ba8f89d54796c99fbfbfb8b2 + c9e3996173cec136bc2e9f3b4ec45f2a323b1d63 https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore - 1681d9acf750c1f1ba8f89d54796c99fbfbfb8b2 + c9e3996173cec136bc2e9f3b4ec45f2a323b1d63 - + https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore - 1681d9acf750c1f1ba8f89d54796c99fbfbfb8b2 + c9e3996173cec136bc2e9f3b4ec45f2a323b1d63 - + https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore - 1681d9acf750c1f1ba8f89d54796c99fbfbfb8b2 + c9e3996173cec136bc2e9f3b4ec45f2a323b1d63 - + https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore - 1681d9acf750c1f1ba8f89d54796c99fbfbfb8b2 + c9e3996173cec136bc2e9f3b4ec45f2a323b1d63 - + https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore - 1681d9acf750c1f1ba8f89d54796c99fbfbfb8b2 + c9e3996173cec136bc2e9f3b4ec45f2a323b1d63 - + https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore - 1681d9acf750c1f1ba8f89d54796c99fbfbfb8b2 + c9e3996173cec136bc2e9f3b4ec45f2a323b1d63 - + https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore - 1681d9acf750c1f1ba8f89d54796c99fbfbfb8b2 + c9e3996173cec136bc2e9f3b4ec45f2a323b1d63 - + https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore - 1681d9acf750c1f1ba8f89d54796c99fbfbfb8b2 + c9e3996173cec136bc2e9f3b4ec45f2a323b1d63 - + https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore - 1681d9acf750c1f1ba8f89d54796c99fbfbfb8b2 + c9e3996173cec136bc2e9f3b4ec45f2a323b1d63 https://github.com/dotnet/razor @@ -300,19 +300,19 @@ https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore - 1681d9acf750c1f1ba8f89d54796c99fbfbfb8b2 + c9e3996173cec136bc2e9f3b4ec45f2a323b1d63 https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore - 1681d9acf750c1f1ba8f89d54796c99fbfbfb8b2 + c9e3996173cec136bc2e9f3b4ec45f2a323b1d63 https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore - 1681d9acf750c1f1ba8f89d54796c99fbfbfb8b2 + c9e3996173cec136bc2e9f3b4ec45f2a323b1d63 https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore - 1681d9acf750c1f1ba8f89d54796c99fbfbfb8b2 + c9e3996173cec136bc2e9f3b4ec45f2a323b1d63 https://github.com/dotnet/xdt @@ -431,7 +431,7 @@ https://dev.azure.com/dnceng/internal/_git/dotnet-aspnetcore - 1681d9acf750c1f1ba8f89d54796c99fbfbfb8b2 + c9e3996173cec136bc2e9f3b4ec45f2a323b1d63 https://dev.azure.com/dnceng/internal/_git/dotnet-runtime diff --git a/eng/Versions.props b/eng/Versions.props index f7b61bfcd98f..1e4c6ba34b0a 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -167,11 +167,11 @@ 8.0.5 - 8.0.5-servicing.24217.6 - 8.0.5-servicing.24217.6 - 8.0.5-servicing.24217.6 - 8.0.5-servicing.24217.6 - 8.0.5-servicing.24217.6 + 8.0.5-servicing.24224.4 + 8.0.5-servicing.24224.4 + 8.0.5-servicing.24224.4 + 8.0.5-servicing.24224.4 + 8.0.5-servicing.24224.4 8.0.5