Skip to content

Commit 2a21ea7

Browse files
authored
[automated] Merge branch 'release/9.0.2xx' => 'main' (#43673)
2 parents 081a52f + 044d09f commit 2a21ea7

File tree

146 files changed

+3544
-428
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

146 files changed

+3544
-428
lines changed

.vsts-ci.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ trigger:
55
branches:
66
include:
77
- main
8-
- release/9.0.1xx
8+
- release/9.0.2xx
99
- internal/release/*
1010
- exp/*
1111

NuGet.config

+2
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
<clear />
55
<!--Begin: Package sources managed by Dependency Flow automation. Do not edit the sources below.-->
66
<!-- Begin: Package sources from dotnet-aspire -->
7+
<add key="darc-pub-dotnet-aspire-137e8dc" value="https://pkgs.dev.azure.com/dnceng/public/_packaging/darc-pub-dotnet-aspire-137e8dca/nuget/v3/index.json" />
8+
<add key="darc-pub-dotnet-aspire-137e8dc-1" value="https://pkgs.dev.azure.com/dnceng/public/_packaging/darc-pub-dotnet-aspire-137e8dca-1/nuget/v3/index.json" />
79
<!-- End: Package sources from dotnet-aspire -->
810
<!-- Begin: Package sources from dotnet-aspnetcore -->
911
<!-- End: Package sources from dotnet-aspnetcore -->

eng/Version.Details.xml

+4-4
Original file line numberDiff line numberDiff line change
@@ -660,14 +660,14 @@
660660
aren't shipping, or those extensions packages depend on aspnetcore packages that won't ship. However, given the cost
661661
of maintaining this coherency path is high. This being toolset means that aspire is responsible for its own coherency.
662662
-->
663-
<Dependency Name="Microsoft.NET.Sdk.Aspire.Manifest-8.0.100" Version="9.0.0-preview.4.24456.4">
663+
<Dependency Name="Microsoft.NET.Sdk.Aspire.Manifest-8.0.100" Version="8.2.1">
664664
<Uri>https://github.com/dotnet/aspire</Uri>
665-
<Sha>b88ce9e7cb0430fb0b4e2d018f13694a4c733289</Sha>
665+
<Sha>137e8dcae0a7b22c05f48c4e7a5d36fe3f00a8d7</Sha>
666666
</Dependency>
667667
<!-- Intermediate is necessary for source build. -->
668-
<Dependency Name="Microsoft.SourceBuild.Intermediate.aspire" Version="9.0.0-preview.4.24456.4">
668+
<Dependency Name="Microsoft.SourceBuild.Intermediate.aspire" Version="8.2.1-preview.1.24473.4">
669669
<Uri>https://github.com/dotnet/aspire</Uri>
670-
<Sha>b88ce9e7cb0430fb0b4e2d018f13694a4c733289</Sha>
670+
<Sha>137e8dcae0a7b22c05f48c4e7a5d36fe3f00a8d7</Sha>
671671
<SourceBuild RepoName="aspire" ManagedOnly="true" />
672672
</Dependency>
673673
<Dependency Name="Microsoft.IO.Redist" Version="6.0.1">

eng/Versions.props

+1-1
Original file line numberDiff line numberDiff line change
@@ -362,7 +362,7 @@
362362
</PropertyGroup>
363363
<PropertyGroup Label="Workload manifest package versions">
364364
<AspireFeatureBand>8.0.100</AspireFeatureBand>
365-
<MicrosoftNETSdkAspireManifest80100PackageVersion>9.0.0-preview.4.24456.4</MicrosoftNETSdkAspireManifest80100PackageVersion>
365+
<MicrosoftNETSdkAspireManifest80100PackageVersion>8.2.1</MicrosoftNETSdkAspireManifest80100PackageVersion>
366366
<MauiFeatureBand>9.0.100-preview.6</MauiFeatureBand>
367367
<MauiWorkloadManifestVersion>9.0.0-preview.6.24327.7</MauiWorkloadManifestVersion>
368368
<XamarinAndroidWorkloadManifestVersion>34.99.0-preview.6.340</XamarinAndroidWorkloadManifestVersion>

sdk.sln

+8
Original file line numberDiff line numberDiff line change
@@ -510,6 +510,8 @@ Project("{D954291E-2A0B-460D-934E-DC6B0785DB48}") = "Microsoft.WebTools.AspireSe
510510
EndProject
511511
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Net.Sdk.Compilers.Toolset", "src\Microsoft.Net.Sdk.Compilers.Toolset\Microsoft.Net.Sdk.Compilers.Toolset.csproj", "{FA579C03-2EB4-4D47-88EE-BFF339E96FAF}"
512512
EndProject
513+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.WebTools.AspireService.Tests", "test\Microsoft.WebTools.AspireService.Tests\Microsoft.WebTools.AspireService.Tests.csproj", "{1F0B4B3C-DC88-4740-B04F-1707102E9930}"
514+
EndProject
513515
Global
514516
GlobalSection(SolutionConfigurationPlatforms) = preSolution
515517
Debug|Any CPU = Debug|Any CPU
@@ -968,6 +970,10 @@ Global
968970
{FA579C03-2EB4-4D47-88EE-BFF339E96FAF}.Debug|Any CPU.Build.0 = Debug|Any CPU
969971
{FA579C03-2EB4-4D47-88EE-BFF339E96FAF}.Release|Any CPU.ActiveCfg = Release|Any CPU
970972
{FA579C03-2EB4-4D47-88EE-BFF339E96FAF}.Release|Any CPU.Build.0 = Release|Any CPU
973+
{1F0B4B3C-DC88-4740-B04F-1707102E9930}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
974+
{1F0B4B3C-DC88-4740-B04F-1707102E9930}.Debug|Any CPU.Build.0 = Debug|Any CPU
975+
{1F0B4B3C-DC88-4740-B04F-1707102E9930}.Release|Any CPU.ActiveCfg = Release|Any CPU
976+
{1F0B4B3C-DC88-4740-B04F-1707102E9930}.Release|Any CPU.Build.0 = Release|Any CPU
971977
EndGlobalSection
972978
GlobalSection(SolutionProperties) = preSolution
973979
HideSolutionNode = FALSE
@@ -1146,13 +1152,15 @@ Global
11461152
{19014C60-F87C-4CC7-AC0F-C41B6126EBCE} = {71A9F549-0EB6-41F9-BC16-4A6C5007FC91}
11471153
{94C8526E-DCC2-442F-9868-3DD0BA2688BE} = {71A9F549-0EB6-41F9-BC16-4A6C5007FC91}
11481154
{FA579C03-2EB4-4D47-88EE-BFF339E96FAF} = {22AB674F-ED91-4FBC-BFEE-8A1E82F9F05E}
1155+
{1F0B4B3C-DC88-4740-B04F-1707102E9930} = {580D1AE7-AA8F-4912-8B76-105594E00B3B}
11491156
EndGlobalSection
11501157
GlobalSection(ExtensibilityGlobals) = postSolution
11511158
SolutionGuid = {FB8F26CE-4DE6-433F-B32A-79183020BBD6}
11521159
EndGlobalSection
11531160
GlobalSection(SharedMSBuildProjectFiles) = preSolution
11541161
src\Compatibility\ApiCompat\Microsoft.DotNet.ApiCompat.Shared\Microsoft.DotNet.ApiCompat.Shared.projitems*{03c5a84a-982b-4f38-ac73-ab832c645c4a}*SharedItemsImports = 5
11551162
src\Compatibility\ApiCompat\Microsoft.DotNet.ApiCompat.Shared\Microsoft.DotNet.ApiCompat.Shared.projitems*{0a3c9afd-f6e6-4a5d-83fb-93bf66732696}*SharedItemsImports = 5
1163+
src\BuiltInTools\AspireService\Microsoft.WebTools.AspireService.projitems*{1f0b4b3c-dc88-4740-b04f-1707102e9930}*SharedItemsImports = 5
11561164
src\BuiltInTools\AspireService\Microsoft.WebTools.AspireService.projitems*{94c8526e-dcc2-442f-9868-3dd0ba2688be}*SharedItemsImports = 13
11571165
src\Compatibility\ApiCompat\Microsoft.DotNet.ApiCompat.Shared\Microsoft.DotNet.ApiCompat.Shared.projitems*{9d36039f-d0a1-462f-85b4-81763c6b02cb}*SharedItemsImports = 13
11581166
src\Compatibility\ApiCompat\Microsoft.DotNet.ApiCompat.Shared\Microsoft.DotNet.ApiCompat.Shared.projitems*{a9103b98-d888-4260-8a05-fa36f640698a}*SharedItemsImports = 5

src/BuiltInTools/AspireService/AspireServerService.cs

-6
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,12 @@
11
// Licensed to the .NET Foundation under one or more agreements.
22
// The .NET Foundation licenses this file to you under the MIT license.
33

4-
using System;
5-
using System.Collections.Generic;
6-
using System.Diagnostics;
74
using System.Net;
85
using System.Net.WebSockets;
96
using System.Security.Cryptography;
107
using System.Security.Cryptography.X509Certificates;
11-
using System.Text;
128
using System.Text.Json;
139
using System.Text.Json.Serialization;
14-
using System.Threading;
15-
using System.Threading.Tasks;
1610
using Microsoft.AspNetCore.Builder;
1711
using Microsoft.AspNetCore.Hosting;
1812
using Microsoft.AspNetCore.Http;

src/BuiltInTools/AspireService/Helpers/CertGenerator.cs

+4-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
// Licensed to the .NET Foundation under one or more agreements.
22
// The .NET Foundation licenses this file to you under the MIT license.
33

4-
using System;
54
using System.Security.Cryptography;
65
using System.Security.Cryptography.X509Certificates;
76

@@ -35,7 +34,11 @@ public static X509Certificate2 GenerateCert()
3534
// The file will be automatically generated by the following call and disposed when the returned cert is disposed.
3635
using (cert)
3736
{
37+
#if NET9_0_OR_GREATER
38+
return X509CertificateLoader.LoadPkcs12(cert.Export(X509ContentType.Pfx), password: null, X509KeyStorageFlags.UserKeySet);
39+
#else
3840
return new X509Certificate2(cert.Export(X509ContentType.Pfx), "", X509KeyStorageFlags.UserKeySet);
41+
#endif
3942
}
4043
}
4144
else

src/BuiltInTools/DotNetDeltaApplier/HotReloadAgent.cs

+20-1
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ private UpdateHandlerActions GetMetadataUpdateHandlerActions()
8282
var handlerActions = new UpdateHandlerActions();
8383
foreach (var assembly in sortedAssemblies)
8484
{
85-
foreach (var attr in assembly.GetCustomAttributesData())
85+
foreach (var attr in TryGetCustomAttributesData(assembly))
8686
{
8787
// Look up the attribute by name rather than by type. This would allow netstandard targeting libraries to
8888
// define their own copy without having to cross-compile.
@@ -106,6 +106,25 @@ private UpdateHandlerActions GetMetadataUpdateHandlerActions()
106106
return handlerActions;
107107
}
108108

109+
private IList<CustomAttributeData> TryGetCustomAttributesData(Assembly assembly)
110+
{
111+
try
112+
{
113+
return assembly.GetCustomAttributesData();
114+
}
115+
catch (Exception e)
116+
{
117+
// In cross-platform scenarios, such as debugging in VS through WSL, Roslyn
118+
// runs on Windows, and the agent runs on Linux. Assemblies accessible to Windows
119+
// may not be available or loaded on linux (such as WPF's assemblies).
120+
// In such case, we can ignore the assemblies and continue enumerating handlers for
121+
// the rest of the assemblies of current domain.
122+
_log($"'{assembly.FullName}' is not loaded ({e.Message})");
123+
124+
return new List<CustomAttributeData>();
125+
}
126+
}
127+
109128
internal void GetHandlerActions(UpdateHandlerActions handlerActions, Type handlerType)
110129
{
111130
bool methodFound = false;

src/BuiltInTools/DotNetDeltaApplier/StartupHook.cs

+4-2
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,11 @@ public static void Initialize()
2626
// When launching the application process dotnet-watch sets Hot Reload environment variables via CLI environment directives (dotnet [env:X=Y] run).
2727
// Currently, the CLI parser sets the env variables to the dotnet.exe process itself, rather then to the target process.
2828
// This may cause the dotnet.exe process to connect to the named pipe and break it for the target process.
29-
if (Path.ChangeExtension(processPath, ".exe") != Path.ChangeExtension(s_targetProcessPath, ".exe"))
29+
var processExe = Path.ChangeExtension(processPath, ".exe");
30+
var expectedExe = Path.ChangeExtension(s_targetProcessPath, ".exe");
31+
if (!string.Equals(processExe, expectedExe, Path.DirectorySeparatorChar == '\\' ? StringComparison.OrdinalIgnoreCase : StringComparison.Ordinal))
3032
{
31-
Log($"Ignoring process '{processPath}', expecting '{s_targetProcessPath}'");
33+
Log($"Ignoring process '{processExe}', expecting '{expectedExe}'");
3234
return;
3335
}
3436

src/BuiltInTools/dotnet-watch/DotNetWatcher.cs

+5-5
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ public override async Task WatchAsync(CancellationToken cancellationToken)
2727

2828
var environmentBuilder = EnvironmentVariablesBuilder.FromCurrentEnvironment();
2929

30-
FileItem? changedFile = null;
30+
ChangedFile? changedFile = null;
3131
var buildEvaluator = new BuildEvaluator(Context, RootFileSetFactory);
3232
await using var browserConnector = new BrowserConnector(Context);
3333

@@ -86,17 +86,17 @@ public override async Task WatchAsync(CancellationToken cancellationToken)
8686

8787
var processTask = ProcessRunner.RunAsync(processSpec, Context.Reporter, isUserApplication: true, processExitedSource: null, combinedCancellationSource.Token);
8888

89-
Task<FileItem?> fileSetTask;
89+
Task<ChangedFile?> fileSetTask;
9090
Task finishedTask;
9191

9292
while (true)
9393
{
9494
fileSetTask = fileSetWatcher.GetChangedFileAsync(startedWatching: null, combinedCancellationSource.Token);
9595
finishedTask = await Task.WhenAny(processTask, fileSetTask, cancelledTaskSource.Task);
9696

97-
if (staticFileHandler != null && finishedTask == fileSetTask && fileSetTask.Result is FileItem fileItem)
97+
if (staticFileHandler != null && finishedTask == fileSetTask && fileSetTask.Result.HasValue)
9898
{
99-
if (await staticFileHandler.HandleFileChangesAsync([fileItem], combinedCancellationSource.Token))
99+
if (await staticFileHandler.HandleFileChangesAsync([fileSetTask.Result.Value], combinedCancellationSource.Token))
100100
{
101101
// We're able to handle the file change event without doing a full-rebuild.
102102
continue;
@@ -131,7 +131,7 @@ public override async Task WatchAsync(CancellationToken cancellationToken)
131131
Debug.Assert(finishedTask == fileSetTask);
132132
changedFile = fileSetTask.Result;
133133
Debug.Assert(changedFile != null, "ChangedFile should only be null when cancelled");
134-
Context.Reporter.Output($"File changed: {changedFile.Value.FilePath}");
134+
Context.Reporter.Output($"File changed: {changedFile.Value.Item.FilePath}");
135135
}
136136
}
137137
}

src/BuiltInTools/dotnet-watch/FileItem.cs

+4-2
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
// Licensed to the .NET Foundation under one or more agreements.
22
// The .NET Foundation licenses this file to you under the MIT license.
33

4+
using Microsoft.DotNet.Watcher.Internal;
5+
46
namespace Microsoft.DotNet.Watcher
57
{
6-
internal readonly struct FileItem
8+
internal readonly record struct FileItem
79
{
810
public string FilePath { get; init; }
911

@@ -14,7 +16,7 @@ internal readonly struct FileItem
1416

1517
public string? StaticWebAssetPath { get; init; }
1618

17-
public bool IsNewFile { get; init; }
19+
public ChangeKind Change { get; init; }
1820

1921
public bool IsStaticFile => StaticWebAssetPath != null;
2022
}

src/BuiltInTools/dotnet-watch/Filters/BuildEvaluator.cs

+2-2
Original file line numberDiff line numberDiff line change
@@ -46,15 +46,15 @@ public IReadOnlyList<string> GetProcessArguments(int iteration)
4646
return [context.RootProjectOptions.Command, .. context.RootProjectOptions.CommandArguments];
4747
}
4848

49-
public async ValueTask<EvaluationResult> EvaluateAsync(FileItem? changedFile, CancellationToken cancellationToken)
49+
public async ValueTask<EvaluationResult> EvaluateAsync(ChangedFile? changedFile, CancellationToken cancellationToken)
5050
{
5151
if (context.EnvironmentOptions.SuppressMSBuildIncrementalism)
5252
{
5353
RequiresRevaluation = true;
5454
return _evaluationResult = await CreateEvaluationResult(cancellationToken);
5555
}
5656

57-
if (_evaluationResult == null || RequiresMSBuildRevaluation(changedFile))
57+
if (_evaluationResult == null || RequiresMSBuildRevaluation(changedFile?.Item))
5858
{
5959
RequiresRevaluation = true;
6060
}

src/BuiltInTools/dotnet-watch/HotReload/IncrementalMSBuildWorkspace.cs

+25-11
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,15 @@
11
// Licensed to the .NET Foundation under one or more agreements.
22
// The .NET Foundation licenses this file to you under the MIT license.
33

4-
using System;
5-
using System.Collections.Generic;
4+
using System.Collections.Immutable;
65
using System.Diagnostics;
7-
using System.Linq;
8-
using System.Text;
9-
using System.Threading.Tasks;
106
using Microsoft.CodeAnalysis;
11-
using Microsoft.CodeAnalysis.Host;
7+
using Microsoft.CodeAnalysis.ExternalAccess.Watch.Api;
128
using Microsoft.CodeAnalysis.Host.Mef;
139
using Microsoft.CodeAnalysis.MSBuild;
14-
using Microsoft.Extensions.Tools.Internal;
15-
using Microsoft.CodeAnalysis.ExternalAccess.Watch.Api;
16-
using System.Collections.Immutable;
1710
using Microsoft.CodeAnalysis.Text;
11+
using Microsoft.DotNet.Watcher.Internal;
12+
using Microsoft.Extensions.Tools.Internal;
1813

1914
namespace Microsoft.DotNet.Watcher.Tools;
2015

@@ -106,13 +101,24 @@ ImmutableArray<DocumentInfo> MapDocuments(ProjectId mappedProjectId, IReadOnlyLi
106101
}).ToImmutableArray();
107102
}
108103

109-
public async ValueTask UpdateFileContentAsync(IEnumerable<FileItem> changedFiles, CancellationToken cancellationToken)
104+
public async ValueTask UpdateFileContentAsync(IEnumerable<ChangedFile> changedFiles, CancellationToken cancellationToken)
110105
{
111106
var updatedSolution = CurrentSolution;
112107

113-
foreach (var changedFile in changedFiles)
108+
var documentsToRemove = new List<DocumentId>();
109+
110+
foreach (var (changedFile, change) in changedFiles)
114111
{
112+
// when a file is added we reevaluate the project:
113+
Debug.Assert(change != ChangeKind.Add);
114+
115115
var documentIds = updatedSolution.GetDocumentIdsWithFilePath(changedFile.FilePath);
116+
if (change == ChangeKind.Delete)
117+
{
118+
documentsToRemove.AddRange(documentIds);
119+
continue;
120+
}
121+
116122
foreach (var documentId in documentIds)
117123
{
118124
var textDocument = updatedSolution.GetDocument(documentId)
@@ -140,9 +146,17 @@ public async ValueTask UpdateFileContentAsync(IEnumerable<FileItem> changedFiles
140146
}
141147
}
142148

149+
updatedSolution = RemoveDocuments(updatedSolution, documentsToRemove);
150+
143151
await ReportSolutionFilesAsync(SetCurrentSolution(updatedSolution), cancellationToken);
144152
}
145153

154+
private static Solution RemoveDocuments(Solution solution, IEnumerable<DocumentId> ids)
155+
=> solution
156+
.RemoveDocuments(ids.Where(id => solution.GetDocument(id) != null).ToImmutableArray())
157+
.RemoveAdditionalDocuments(ids.Where(id => solution.GetAdditionalDocument(id) != null).ToImmutableArray())
158+
.RemoveAnalyzerConfigDocuments(ids.Where(id => solution.GetAnalyzerConfigDocument(id) != null).ToImmutableArray());
159+
146160
private static async ValueTask<SourceText> GetSourceTextAsync(string filePath, CancellationToken cancellationToken)
147161
{
148162
var zeroLengthRetryPerformed = false;

src/BuiltInTools/dotnet-watch/HotReload/ScopedCssFileHandler.cs

+3-2
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
using System.Collections;
66
using System.Diagnostics;
77
using Microsoft.Build.Graph;
8+
using Microsoft.DotNet.Watcher.Internal;
89
using Microsoft.Extensions.Tools.Internal;
910

1011
namespace Microsoft.DotNet.Watcher.Tools
@@ -13,14 +14,14 @@ internal sealed class ScopedCssFileHandler(IReporter reporter, ProjectNodeMap pr
1314
{
1415
private const string BuildTargetName = "GenerateComputedBuildStaticWebAssets";
1516

16-
public async ValueTask HandleFileChangesAsync(IReadOnlyList<FileItem> files, CancellationToken cancellationToken)
17+
public async ValueTask HandleFileChangesAsync(IReadOnlyList<ChangedFile> files, CancellationToken cancellationToken)
1718
{
1819
var projectsToRefresh = new HashSet<ProjectGraphNode>();
1920
var hasApplicableFiles = false;
2021

2122
for (int i = 0; i < files.Count; i++)
2223
{
23-
var file = files[i];
24+
var file = files[i].Item;
2425

2526
if (!file.FilePath.EndsWith(".razor.css", StringComparison.Ordinal) &&
2627
!file.FilePath.EndsWith(".cshtml.css", StringComparison.Ordinal))

src/BuiltInTools/dotnet-watch/HotReload/StaticFileHandler.cs

+3-2
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
using System.Text.Json;
88
using System.Text.Json.Serialization;
99
using Microsoft.CodeAnalysis.StackTraceExplorer;
10+
using Microsoft.DotNet.Watcher.Internal;
1011
using Microsoft.Extensions.Tools.Internal;
1112

1213
namespace Microsoft.DotNet.Watcher.Tools
@@ -18,13 +19,13 @@ internal sealed class StaticFileHandler(IReporter reporter, ProjectNodeMap proje
1819
DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull
1920
};
2021

21-
public async ValueTask<bool> HandleFileChangesAsync(IReadOnlyList<FileItem> files, CancellationToken cancellationToken)
22+
public async ValueTask<bool> HandleFileChangesAsync(IReadOnlyList<ChangedFile> files, CancellationToken cancellationToken)
2223
{
2324
var allFilesHandled = true;
2425
var refreshRequests = new Dictionary<BrowserRefreshServer, List<string>>();
2526
for (int i = 0; i < files.Count; i++)
2627
{
27-
var file = files[i];
28+
var file = files[i].Item;
2829

2930
if (file.StaticWebAssetPath is null)
3031
{

0 commit comments

Comments
 (0)