Skip to content

Commit f5b319e

Browse files
Merge release/10.0.1xx into darc-release/10.0.1xx-42e4be27-1453-413b-801b-af106d081ec2
Auto-resolved conflicts: - src/Cli/dotnet/Commands/MSBuild/MSBuildLogger.cs
2 parents cf6f17c + 404ff4a commit f5b319e

File tree

83 files changed

+1334
-665
lines changed

Some content is hidden

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

83 files changed

+1334
-665
lines changed

NuGet.config

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
<packageSources>
44
<clear />
55
<!--Begin: Package sources managed by Dependency Flow automation. Do not edit the sources below.-->
6+
<!-- Begin: Package sources from microsoft-testfx -->
7+
<!-- End: Package sources from microsoft-testfx -->
68
<!-- Begin: Package sources from dotnet-aspire -->
79
<!-- End: Package sources from dotnet-aspire -->
810
<!-- Begin: Package sources from dotnet-runtime -->

eng/Version.Details.props

Lines changed: 132 additions & 132 deletions
Large diffs are not rendered by default.

eng/Version.Details.xml

Lines changed: 265 additions & 265 deletions
Large diffs are not rendered by default.

eng/Versions.props

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,8 +38,8 @@
3838
<VersionFeature60>36</VersionFeature60>
3939
<VersionFeature70>20</VersionFeature70>
4040
<!-- This version should be N-1 (ie the currently released version) in the preview branch but N-2 in main so that workloads stay behind the unreleased version -->
41-
<VersionFeature80>18</VersionFeature80>
42-
<VersionFeature90>7</VersionFeature90>
41+
<VersionFeature80>19</VersionFeature80>
42+
<VersionFeature90>8</VersionFeature90>
4343
<!-- Should be kept in sync with VersionFeature70. It should match the version of Microsoft.NET.ILLink.Tasks
4444
referenced by the same 7.0 SDK that references the 7.0.VersionFeature70 runtime pack. -->
4545
<_NET70ILLinkPackVersion>7.0.100-1.23211.1</_NET70ILLinkPackVersion>

eng/common/core-templates/job/publish-build-assets.yml

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,8 @@ parameters:
4040

4141
repositoryAlias: self
4242

43+
officialBuildId: ''
44+
4345
jobs:
4446
- job: Asset_Registry_Publish
4547

@@ -62,6 +64,11 @@ jobs:
6264
value: false
6365
# unconditional - needed for logs publishing (redactor tool version)
6466
- template: /eng/common/core-templates/post-build/common-variables.yml
67+
- name: OfficialBuildId
68+
${{ if ne(parameters.officialBuildId, '') }}:
69+
value: ${{ parameters.officialBuildId }}
70+
${{ else }}:
71+
value: $(Build.BuildNumber)
6572

6673
pool:
6774
# We don't use the collection uri here because it might vary (.visualstudio.com vs. dev.azure.com)
@@ -124,7 +131,7 @@ jobs:
124131
/p:ManifestsPath='$(Build.StagingDirectory)/AssetManifests'
125132
/p:IsAssetlessBuild=${{ parameters.isAssetlessBuild }}
126133
/p:MaestroApiEndpoint=https://maestro.dot.net
127-
/p:OfficialBuildId=$(Build.BuildNumber)
134+
/p:OfficialBuildId=$(OfficialBuildId)
128135
condition: ${{ parameters.condition }}
129136
continueOnError: ${{ parameters.continueOnError }}
130137

eng/common/core-templates/jobs/jobs.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ parameters:
4444
artifacts: {}
4545
is1ESPipeline: ''
4646
repositoryAlias: self
47+
officialBuildId: ''
4748

4849
# Internal resources (telemetry, microbuild) can only be accessed from non-public projects,
4950
# and some (Microbuild) should only be applied to non-PR cases for internal builds.
@@ -116,3 +117,4 @@ jobs:
116117
artifactsPublishingAdditionalParameters: ${{ parameters.artifactsPublishingAdditionalParameters }}
117118
signingValidationAdditionalParameters: ${{ parameters.signingValidationAdditionalParameters }}
118119
repositoryAlias: ${{ parameters.repositoryAlias }}
120+
officialBuildId: ${{ parameters.officialBuildId }}

eng/common/post-build/nuget-verification.ps1

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@
3030
[CmdletBinding(PositionalBinding = $false)]
3131
param(
3232
[string]$NuGetExePath,
33-
[string]$PackageSource = "https://api.nuget.org/v3/index.json",
33+
[string]$PackageSource = "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public/nuget/v3/index.json",
3434
[string]$DownloadPath,
3535
[Parameter(ValueFromRemainingArguments = $true)]
3636
[string[]]$args

global.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,8 @@
2121
}
2222
},
2323
"msbuild-sdks": {
24-
"Microsoft.DotNet.Arcade.Sdk": "10.0.0-beta.25467.107",
25-
"Microsoft.DotNet.Helix.Sdk": "10.0.0-beta.25467.107",
24+
"Microsoft.DotNet.Arcade.Sdk": "10.0.0-beta.25507.103",
25+
"Microsoft.DotNet.Helix.Sdk": "10.0.0-beta.25507.103",
2626
"Microsoft.Build.NoTargets": "3.7.0",
2727
"Microsoft.Build.Traversal": "3.4.0",
2828
"Microsoft.WixToolset.Sdk": "5.0.2-dotnet.2737382"

src/BuiltInTools/DotNetDeltaApplier/PipeListener.cs

Lines changed: 56 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
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.Diagnostics;
45
using System.IO.Pipes;
56
using System.Reflection;
67
using System.Runtime.Loader;
@@ -9,6 +10,17 @@ namespace Microsoft.DotNet.HotReload;
910

1011
internal sealed class PipeListener(string pipeName, IHotReloadAgent agent, Action<string> log, int connectionTimeoutMS = 5000)
1112
{
13+
/// <summary>
14+
/// Messages to the client sent after the initial <see cref="ClientInitializationResponse"/> is sent
15+
/// need to be sent while holding this lock in order to synchronize
16+
/// 1) responses to requests received from the client (e.g. <see cref="UpdateResponse"/>) or
17+
/// 2) notifications sent to the client that may be triggered at arbitrary times (e.g. <see cref="HotReloadExceptionCreatedNotification"/>).
18+
/// </summary>
19+
private readonly SemaphoreSlim _messageToClientLock = new(initialCount: 1);
20+
21+
// Not-null once initialized:
22+
private NamedPipeClientStream? _pipeClient;
23+
1224
public Task Listen(CancellationToken cancellationToken)
1325
{
1426
// Connect to the pipe synchronously.
@@ -21,23 +33,23 @@ public Task Listen(CancellationToken cancellationToken)
2133

2234
log($"Connecting to hot-reload server via pipe {pipeName}");
2335

24-
var pipeClient = new NamedPipeClientStream(serverName: ".", pipeName, PipeDirection.InOut, PipeOptions.CurrentUserOnly | PipeOptions.Asynchronous);
36+
_pipeClient = new NamedPipeClientStream(serverName: ".", pipeName, PipeDirection.InOut, PipeOptions.CurrentUserOnly | PipeOptions.Asynchronous);
2537
try
2638
{
27-
pipeClient.Connect(connectionTimeoutMS);
39+
_pipeClient.Connect(connectionTimeoutMS);
2840
log("Connected.");
2941
}
3042
catch (TimeoutException)
3143
{
3244
log($"Failed to connect in {connectionTimeoutMS}ms.");
33-
pipeClient.Dispose();
45+
_pipeClient.Dispose();
3446
return Task.CompletedTask;
3547
}
3648

3749
try
3850
{
3951
// block execution of the app until initial updates are applied:
40-
InitializeAsync(pipeClient, cancellationToken).GetAwaiter().GetResult();
52+
InitializeAsync(cancellationToken).GetAwaiter().GetResult();
4153
}
4254
catch (Exception e)
4355
{
@@ -46,7 +58,7 @@ public Task Listen(CancellationToken cancellationToken)
4658
log(e.Message);
4759
}
4860

49-
pipeClient.Dispose();
61+
_pipeClient.Dispose();
5062
agent.Dispose();
5163

5264
return Task.CompletedTask;
@@ -56,48 +68,52 @@ public Task Listen(CancellationToken cancellationToken)
5668
{
5769
try
5870
{
59-
await ReceiveAndApplyUpdatesAsync(pipeClient, initialUpdates: false, cancellationToken);
71+
await ReceiveAndApplyUpdatesAsync(initialUpdates: false, cancellationToken);
6072
}
6173
catch (Exception e) when (e is not OperationCanceledException)
6274
{
6375
log(e.Message);
6476
}
6577
finally
6678
{
67-
pipeClient.Dispose();
79+
_pipeClient.Dispose();
6880
agent.Dispose();
6981
}
7082
}, cancellationToken);
7183
}
7284

73-
private async Task InitializeAsync(NamedPipeClientStream pipeClient, CancellationToken cancellationToken)
85+
private async Task InitializeAsync(CancellationToken cancellationToken)
7486
{
87+
Debug.Assert(_pipeClient != null);
88+
7589
agent.Reporter.Report("Writing capabilities: " + agent.Capabilities, AgentMessageSeverity.Verbose);
7690

7791
var initPayload = new ClientInitializationResponse(agent.Capabilities);
78-
await initPayload.WriteAsync(pipeClient, cancellationToken);
92+
await initPayload.WriteAsync(_pipeClient, cancellationToken);
7993

8094
// Apply updates made before this process was launched to avoid executing unupdated versions of the affected modules.
8195

8296
// We should only receive ManagedCodeUpdate when when the debugger isn't attached,
8397
// otherwise the initialization should send InitialUpdatesCompleted immediately.
8498
// The debugger itself applies these updates when launching process with the debugger attached.
85-
await ReceiveAndApplyUpdatesAsync(pipeClient, initialUpdates: true, cancellationToken);
99+
await ReceiveAndApplyUpdatesAsync(initialUpdates: true, cancellationToken);
86100
}
87101

88-
private async Task ReceiveAndApplyUpdatesAsync(NamedPipeClientStream pipeClient, bool initialUpdates, CancellationToken cancellationToken)
102+
private async Task ReceiveAndApplyUpdatesAsync(bool initialUpdates, CancellationToken cancellationToken)
89103
{
90-
while (pipeClient.IsConnected)
104+
Debug.Assert(_pipeClient != null);
105+
106+
while (_pipeClient.IsConnected)
91107
{
92-
var payloadType = (RequestType)await pipeClient.ReadByteAsync(cancellationToken);
108+
var payloadType = (RequestType)await _pipeClient.ReadByteAsync(cancellationToken);
93109
switch (payloadType)
94110
{
95111
case RequestType.ManagedCodeUpdate:
96-
await ReadAndApplyManagedCodeUpdateAsync(pipeClient, cancellationToken);
112+
await ReadAndApplyManagedCodeUpdateAsync(cancellationToken);
97113
break;
98114

99115
case RequestType.StaticAssetUpdate:
100-
await ReadAndApplyStaticAssetUpdateAsync(pipeClient, cancellationToken);
116+
await ReadAndApplyStaticAssetUpdateAsync(cancellationToken);
101117
break;
102118

103119
case RequestType.InitialUpdatesCompleted when initialUpdates:
@@ -110,11 +126,11 @@ private async Task ReceiveAndApplyUpdatesAsync(NamedPipeClientStream pipeClient,
110126
}
111127
}
112128

113-
private async ValueTask ReadAndApplyManagedCodeUpdateAsync(
114-
NamedPipeClientStream pipeClient,
115-
CancellationToken cancellationToken)
129+
private async ValueTask ReadAndApplyManagedCodeUpdateAsync(CancellationToken cancellationToken)
116130
{
117-
var request = await ManagedCodeUpdateRequest.ReadAsync(pipeClient, cancellationToken);
131+
Debug.Assert(_pipeClient != null);
132+
133+
var request = await ManagedCodeUpdateRequest.ReadAsync(_pipeClient, cancellationToken);
118134

119135
bool success;
120136
try
@@ -131,15 +147,14 @@ private async ValueTask ReadAndApplyManagedCodeUpdateAsync(
131147

132148
var logEntries = agent.Reporter.GetAndClearLogEntries(request.ResponseLoggingLevel);
133149

134-
var response = new UpdateResponse(logEntries, success);
135-
await response.WriteAsync(pipeClient, cancellationToken);
150+
await SendResponseAsync(new UpdateResponse(logEntries, success), cancellationToken);
136151
}
137152

138-
private async ValueTask ReadAndApplyStaticAssetUpdateAsync(
139-
NamedPipeClientStream pipeClient,
140-
CancellationToken cancellationToken)
153+
private async ValueTask ReadAndApplyStaticAssetUpdateAsync(CancellationToken cancellationToken)
141154
{
142-
var request = await StaticAssetUpdateRequest.ReadAsync(pipeClient, cancellationToken);
155+
Debug.Assert(_pipeClient != null);
156+
157+
var request = await StaticAssetUpdateRequest.ReadAsync(_pipeClient, cancellationToken);
143158

144159
try
145160
{
@@ -155,8 +170,22 @@ private async ValueTask ReadAndApplyStaticAssetUpdateAsync(
155170
// Updating static asset only invokes ContentUpdate metadata update handlers.
156171
// Failures of these handlers are reported to the log and ignored.
157172
// Therefore, this request always succeeds.
158-
var response = new UpdateResponse(logEntries, success: true);
173+
await SendResponseAsync(new UpdateResponse(logEntries, success: true), cancellationToken);
174+
}
159175

160-
await response.WriteAsync(pipeClient, cancellationToken);
176+
internal async ValueTask SendResponseAsync<T>(T response, CancellationToken cancellationToken)
177+
where T : IResponse
178+
{
179+
Debug.Assert(_pipeClient != null);
180+
try
181+
{
182+
await _messageToClientLock.WaitAsync(cancellationToken);
183+
await _pipeClient.WriteAsync((byte)response.Type, cancellationToken);
184+
await response.WriteAsync(_pipeClient, cancellationToken);
185+
}
186+
finally
187+
{
188+
_messageToClientLock.Release();
189+
}
161190
}
162191
}

src/BuiltInTools/DotNetDeltaApplier/StartupHook.cs

Lines changed: 42 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -40,14 +40,49 @@ public static void Initialize()
4040

4141
RegisterSignalHandlers();
4242

43-
var agent = new HotReloadAgent(assemblyResolvingHandler: (_, args) =>
44-
{
45-
Log($"Resolving '{args.Name}, Version={args.Version}'");
46-
var path = Path.Combine(processDir, args.Name + ".dll");
47-
return File.Exists(path) ? AssemblyLoadContext.Default.LoadFromAssemblyPath(path) : null;
48-
});
43+
PipeListener? listener = null;
44+
45+
var agent = new HotReloadAgent(
46+
assemblyResolvingHandler: (_, args) =>
47+
{
48+
Log($"Resolving '{args.Name}, Version={args.Version}'");
49+
var path = Path.Combine(processDir, args.Name + ".dll");
50+
return File.Exists(path) ? AssemblyLoadContext.Default.LoadFromAssemblyPath(path) : null;
51+
},
52+
hotReloadExceptionCreateHandler: (code, message) =>
53+
{
54+
// Continue executing the code if the debugger is attached.
55+
// It will throw the exception and the debugger will handle it.
56+
if (Debugger.IsAttached)
57+
{
58+
return;
59+
}
60+
61+
Debug.Assert(listener != null);
62+
Log($"Runtime rude edit detected: '{message}'");
63+
64+
SendAndForgetAsync().Wait();
65+
66+
// Handle Ctrl+C to terminate gracefully:
67+
Console.CancelKeyPress += (_, _) => Environment.Exit(0);
68+
69+
// wait for the process to be terminated by the Hot Reload client (other threads might still execute):
70+
Thread.Sleep(Timeout.Infinite);
71+
72+
async Task SendAndForgetAsync()
73+
{
74+
try
75+
{
76+
await listener.SendResponseAsync(new HotReloadExceptionCreatedNotification(code, message), CancellationToken.None);
77+
}
78+
catch
79+
{
80+
// do not crash the app
81+
}
82+
}
83+
});
4984

50-
var listener = new PipeListener(s_namedPipeName, agent, Log);
85+
listener = new PipeListener(s_namedPipeName, agent, Log);
5186

5287
// fire and forget:
5388
_ = listener.Listen(CancellationToken.None);

0 commit comments

Comments
 (0)