Skip to content

Commit 2703b3f

Browse files
authored
[Rollout] Production rollout 2025-04-30 (#4775)
#4774
2 parents 7c58df2 + 1eb0c2d commit 2703b3f

File tree

21 files changed

+367
-542
lines changed

21 files changed

+367
-542
lines changed

src/Maestro/Maestro.DataProviders/RemoteFactory.cs

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7,24 +7,23 @@
77
using Maestro.Data;
88
using Microsoft.DotNet.DarcLib;
99
using Microsoft.DotNet.DarcLib.Helpers;
10-
using Microsoft.DotNet.DarcLib.VirtualMonoRepo;
1110
using Microsoft.DotNet.GitHub.Authentication;
1211
using Microsoft.DotNet.Internal.Logging;
12+
using Microsoft.Extensions.DependencyInjection;
1313
using Microsoft.Extensions.Logging;
1414

1515
namespace Maestro.DataProviders;
1616

1717
public class RemoteFactory : IRemoteFactory
1818
{
19-
private readonly IVersionDetailsParser _versionDetailsParser;
2019
private readonly OperationManager _operations;
2120
private readonly IProcessManager _processManager;
2221
private readonly ILoggerFactory _loggerFactory;
2322
private readonly BuildAssetRegistryContext _context;
2423
private readonly DarcRemoteMemoryCache _cache;
2524
private readonly IGitHubTokenProvider _gitHubTokenProvider;
2625
private readonly IAzureDevOpsTokenProvider _azdoTokenProvider;
27-
private readonly ISourceMappingParser _sourceMappingParser;
26+
private readonly IServiceProvider _serviceProvider;
2827

2928
public RemoteFactory(
3029
BuildAssetRegistryContext context,
@@ -35,25 +34,24 @@ public RemoteFactory(
3534
OperationManager operations,
3635
IProcessManager processManager,
3736
ILoggerFactory loggerFactory,
38-
ISourceMappingParser sourceMappingParser)
37+
IServiceProvider serviceProvider)
3938
{
4039
_operations = operations;
4140
_processManager = processManager;
4241
_loggerFactory = loggerFactory;
43-
_versionDetailsParser = versionDetailsParser;
4442
_context = context;
4543
_gitHubTokenProvider = gitHubTokenProvider;
4644
_azdoTokenProvider = azdoTokenProvider;
4745
_cache = memoryCache;
48-
_sourceMappingParser = sourceMappingParser;
46+
_serviceProvider = serviceProvider;
4947
}
5048

5149
public async Task<IRemote> CreateRemoteAsync(string repoUrl)
5250
{
5351
using (_operations.BeginOperation($"Getting remote for repo {repoUrl}."))
5452
{
5553
IRemoteGitRepo remoteGitClient = await GetRemoteGitClient(repoUrl);
56-
return new Remote(remoteGitClient, _versionDetailsParser, _sourceMappingParser, _loggerFactory.CreateLogger<IRemote>());
54+
return ActivatorUtilities.CreateInstance<Remote>(_serviceProvider, remoteGitClient);
5755
}
5856
}
5957

@@ -62,7 +60,7 @@ public async Task<IDependencyFileManager> CreateDependencyFileManagerAsync(strin
6260
using (_operations.BeginOperation($"Getting remote file manager for repo {repoUrl}."))
6361
{
6462
IRemoteGitRepo remoteGitClient = await GetRemoteGitClient(repoUrl);
65-
return new DependencyFileManager(remoteGitClient, _versionDetailsParser, _loggerFactory.CreateLogger<IRemote>());
63+
return ActivatorUtilities.CreateInstance<DependencyFileManager>(_serviceProvider, remoteGitClient);
6664
}
6765
}
6866

src/Microsoft.DotNet.Darc/Darc/Helpers/RemoteFactory.cs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
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;
45
using System.IO;
56
using System.Threading.Tasks;
67
using Microsoft.DotNet.Darc.Options;
78
using Microsoft.DotNet.DarcLib;
89
using Microsoft.DotNet.DarcLib.Helpers;
9-
using Microsoft.DotNet.DarcLib.VirtualMonoRepo;
10+
using Microsoft.Extensions.DependencyInjection;
1011
using Microsoft.Extensions.Logging;
1112

1213
namespace Microsoft.DotNet.Darc.Helpers;
@@ -15,29 +16,28 @@ internal class RemoteFactory : IRemoteFactory
1516
{
1617
private readonly ILoggerFactory _loggerFactory;
1718
private readonly ICommandLineOptions _options;
18-
private readonly ISourceMappingParser _sourceMappingParser;
19+
private readonly IServiceProvider _serviceProvider;
1920

2021
public RemoteFactory(
2122
ILoggerFactory loggerFactory,
2223
ICommandLineOptions options,
23-
ISourceMappingParser sourceMappingParser)
24+
IServiceProvider serviceProvider)
2425
{
2526
_loggerFactory = loggerFactory;
2627
_options = options;
27-
_sourceMappingParser = sourceMappingParser;
28+
_serviceProvider = serviceProvider;
2829
}
2930

3031
public Task<IRemote> CreateRemoteAsync(string repoUrl)
3132
{
3233
IRemoteGitRepo gitClient = CreateRemoteGitClient(_options, repoUrl);
33-
return Task.FromResult<IRemote>(new Remote(gitClient, new VersionDetailsParser(), _sourceMappingParser, _loggerFactory.CreateLogger<IRemote>()));
34+
return Task.FromResult<IRemote>(ActivatorUtilities.CreateInstance<Remote>(_serviceProvider, gitClient));
3435
}
3536

3637
public Task<IDependencyFileManager> CreateDependencyFileManagerAsync(string repoUrl)
3738
{
3839
IRemoteGitRepo gitClient = CreateRemoteGitClient(_options, repoUrl);
39-
var dfm = new DependencyFileManager(gitClient, new VersionDetailsParser(), _loggerFactory.CreateLogger<IDependencyFileManager>());
40-
return Task.FromResult<IDependencyFileManager>(dfm);
40+
return Task.FromResult<IDependencyFileManager>(ActivatorUtilities.CreateInstance<DependencyFileManager>(_serviceProvider, gitClient));
4141
}
4242

4343
private IRemoteGitRepo CreateRemoteGitClient(ICommandLineOptions options, string repoUrl)

src/Microsoft.DotNet.Darc/Darc/Operations/UpdateDependenciesOperation.cs

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -26,19 +26,22 @@ internal class UpdateDependenciesOperation : Operation
2626
private readonly IBarApiClient _barClient;
2727
private readonly IRemoteFactory _remoteFactory;
2828
private readonly IGitRepoFactory _gitRepoFactory;
29+
private readonly ICoherencyUpdateResolver _coherencyUpdateResolver;
2930

3031
public UpdateDependenciesOperation(
3132
UpdateDependenciesCommandLineOptions options,
3233
IBarApiClient barClient,
3334
IRemoteFactory remoteFactory,
3435
IGitRepoFactory gitRepoFactory,
36+
ICoherencyUpdateResolver coherencyUpdateResolver,
3537
ILogger<UpdateDependenciesOperation> logger)
3638
{
3739
_options = options;
3840
_logger = logger;
3941
_barClient = barClient;
4042
_remoteFactory = remoteFactory;
4143
_gitRepoFactory = gitRepoFactory;
44+
_coherencyUpdateResolver = coherencyUpdateResolver;
4245
}
4346

4447
/// <summary>
@@ -50,8 +53,6 @@ public override async Task<int> ExecuteAsync()
5053
{
5154
try
5255
{
53-
var coherencyUpdateResolver = new CoherencyUpdateResolver(_barClient, _logger);
54-
5556
var local = new Local(_options.GetRemoteTokenProvider(), _logger);
5657
List<DependencyDetail> dependenciesToUpdate = [];
5758
bool someUpToDate = false;
@@ -113,7 +114,7 @@ public override async Task<int> ExecuteAsync()
113114
Console.WriteLine($"Looking up build with BAR id {_options.BARBuildId}");
114115
var specificBuild = await _barClient.GetBuildAsync(_options.BARBuildId);
115116

116-
int nonCoherencyResult = NonCoherencyUpdatesForBuild(specificBuild, coherencyUpdateResolver, currentDependencies, candidateDependenciesForUpdate, dependenciesToUpdate);
117+
int nonCoherencyResult = NonCoherencyUpdatesForBuild(specificBuild, currentDependencies, candidateDependenciesForUpdate, dependenciesToUpdate);
117118
if (nonCoherencyResult != Constants.SuccessCode)
118119
{
119120
_logger.LogError("Failed to update non-coherent parent tied dependencies.");
@@ -187,7 +188,7 @@ public override async Task<int> ExecuteAsync()
187188
continue;
188189
}
189190

190-
int nonCoherencyResult = NonCoherencyUpdatesForBuild(build, coherencyUpdateResolver, currentDependencies, candidateDependenciesForUpdate, dependenciesToUpdate);
191+
int nonCoherencyResult = NonCoherencyUpdatesForBuild(build, currentDependencies, candidateDependenciesForUpdate, dependenciesToUpdate);
191192
if (nonCoherencyResult != Constants.SuccessCode)
192193
{
193194
_logger.LogError("Failed to update non-coherent parent tied dependencies.");
@@ -196,7 +197,7 @@ public override async Task<int> ExecuteAsync()
196197
}
197198
}
198199

199-
int coherencyResult = await CoherencyUpdatesAsync(coherencyUpdateResolver, _remoteFactory, currentDependencies, dependenciesToUpdate)
200+
int coherencyResult = await CoherencyUpdatesAsync(currentDependencies, dependenciesToUpdate)
200201
.ConfigureAwait(false);
201202
if (coherencyResult != Constants.SuccessCode)
202203
{
@@ -250,9 +251,8 @@ public override async Task<int> ExecuteAsync()
250251
}
251252
}
252253

253-
private static int NonCoherencyUpdatesForBuild(
254+
private int NonCoherencyUpdatesForBuild(
254255
Build build,
255-
ICoherencyUpdateResolver updateResolver,
256256
List<DependencyDetail> currentDependencies,
257257
List<DependencyDetail> candidateDependenciesForUpdate,
258258
List<DependencyDetail> dependenciesToUpdate)
@@ -265,7 +265,7 @@ private static int NonCoherencyUpdatesForBuild(
265265
});
266266

267267
// Now determine what needs to be updated.
268-
List<DependencyUpdate> updates = updateResolver.GetRequiredNonCoherencyUpdates(
268+
List<DependencyUpdate> updates = _coherencyUpdateResolver.GetRequiredNonCoherencyUpdates(
269269
build.GetRepository(),
270270
build.Commit,
271271
assetData,
@@ -292,8 +292,6 @@ private static int NonCoherencyUpdatesForBuild(
292292
}
293293

294294
private async Task<int> CoherencyUpdatesAsync(
295-
ICoherencyUpdateResolver updateResolver,
296-
IRemoteFactory remoteFactory,
297295
List<DependencyDetail> currentDependencies,
298296
List<DependencyDetail> dependenciesToUpdate)
299297
{
@@ -303,7 +301,7 @@ private async Task<int> CoherencyUpdatesAsync(
303301
try
304302
{
305303
// Now run a coherency update based on the current set of dependencies updated from the previous pass.
306-
coherencyUpdates = await updateResolver.GetRequiredCoherencyUpdatesAsync(currentDependencies, remoteFactory);
304+
coherencyUpdates = await _coherencyUpdateResolver.GetRequiredCoherencyUpdatesAsync(currentDependencies);
307305
}
308306
catch (DarcCoherencyException e)
309307
{

src/Microsoft.DotNet.Darc/Darc/Options/CommandLineOptions.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,7 @@ public virtual IServiceCollection RegisterServices(IServiceCollection services)
150150
disableInteractiveAuth: IsCi,
151151
BuildAssetRegistryBaseUri));
152152
services.TryAddSingleton<IBasicBarClient>(sp => sp.GetRequiredService<IBarApiClient>());
153+
services.TryAddTransient<ICoherencyUpdateResolver, CoherencyUpdateResolver>();
153154
services.TryAddTransient<ILogger>(sp => sp.GetRequiredService<ILogger<Operation>>());
154155
services.TryAddTransient<ITelemetryRecorder, NoTelemetryRecorder>();
155156
services.TryAddTransient<IGitRepoFactory>(sp => ActivatorUtilities.CreateInstance<GitRepoFactory>(sp, Path.GetTempPath()));

src/Microsoft.DotNet.Darc/DarcLib/AzureDevOpsClient.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -541,7 +541,7 @@ private string DisplayPolicy(MergePolicyEvaluationResult result)
541541
return $"- ❓ **{result.Title}** - {result.Message}";
542542
}
543543

544-
if (result.Status == MergePolicyEvaluationStatus.DecisiveSuccess)
544+
if (result.Status == MergePolicyEvaluationStatus.DecisiveSuccess || result.Status == MergePolicyEvaluationStatus.TransientSuccess)
545545
{
546546
return $"- ✔️ **{result.MergePolicyDisplayName}** Succeeded"
547547
+ (result.Title == null ? string.Empty: $" - {result.Title}");

src/Microsoft.DotNet.Darc/DarcLib/CoherencyUpdateResolver.cs

Lines changed: 30 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -14,20 +14,21 @@ namespace Microsoft.DotNet.DarcLib;
1414
public class CoherencyUpdateResolver : ICoherencyUpdateResolver
1515
{
1616
private readonly IBasicBarClient _barClient;
17+
private readonly IRemoteFactory _remoteFactory;
1718
private readonly ILogger _logger;
1819

1920
public CoherencyUpdateResolver(
2021
IBasicBarClient barClient,
22+
IRemoteFactory remoteFactory,
2123
ILogger logger)
2224
{
2325
_barClient = barClient;
26+
_remoteFactory = remoteFactory;
2427
_logger = logger;
2528
}
2629

27-
public async Task<List<DependencyUpdate>> GetRequiredCoherencyUpdatesAsync(
28-
IEnumerable<DependencyDetail> dependencies,
29-
IRemoteFactory remoteFactory)
30-
=> await GetRequiredStrictCoherencyUpdatesAsync(dependencies, remoteFactory);
30+
public async Task<List<DependencyUpdate>> GetRequiredCoherencyUpdatesAsync(IEnumerable<DependencyDetail> dependencies)
31+
=> await GetRequiredStrictCoherencyUpdatesAsync(dependencies);
3132

3233
public List<DependencyUpdate> GetRequiredNonCoherencyUpdates(
3334
string sourceRepoUri,
@@ -38,18 +39,32 @@ public List<DependencyUpdate> GetRequiredNonCoherencyUpdates(
3839
Dictionary<DependencyDetail, DependencyDetail> toUpdate = [];
3940

4041
// Walk the assets, finding the dependencies that don't have coherency markers.
42+
// And are not a part of the same build.
4143
// those must be updated in a second pass.
4244
foreach (AssetData asset in assets)
4345
{
4446
DependencyDetail matchingDependencyByName =
45-
dependencies.FirstOrDefault(d => d.Name.Equals(asset.Name, StringComparison.OrdinalIgnoreCase) &&
46-
string.IsNullOrEmpty(d.CoherentParentDependencyName));
47+
dependencies.FirstOrDefault(d => d.Name.Equals(asset.Name, StringComparison.OrdinalIgnoreCase));
4748

4849
if (matchingDependencyByName == null)
4950
{
5051
continue;
5152
}
5253

54+
// If the dependency has a coherent parent, and the parent is among the build assets (in case of VMR builds)
55+
// we still want to update the dependency.
56+
if (!string.IsNullOrEmpty(matchingDependencyByName.CoherentParentDependencyName))
57+
{
58+
if (!assets.Any(a => a.Name == matchingDependencyByName.CoherentParentDependencyName))
59+
{
60+
continue;
61+
}
62+
if (dependencies.FirstOrDefault(d => d.Name == matchingDependencyByName.CoherentParentDependencyName)?.Pinned ?? false)
63+
{
64+
continue;
65+
}
66+
}
67+
5368
// If the dependency is pinned, don't touch it.
5469
if (matchingDependencyByName.Pinned)
5570
{
@@ -97,7 +112,6 @@ public List<DependencyUpdate> GetRequiredNonCoherencyUpdates(
97112
/// Get updates required by coherency constraints using the "strict" algorithm
98113
/// </summary>
99114
/// <param name="dependencies">Current set of dependencies.</param>
100-
/// <param name="remoteFactory">Remote factory for remote queries.</param>
101115
/// <returns>Dependencies with updates.</returns>
102116
/// <remarks>
103117
/// 'Strict' coherency is a version of coherency that does not **require** any build information,
@@ -119,9 +133,7 @@ public List<DependencyUpdate> GetRequiredNonCoherencyUpdates(
119133
/// but this is fairly minimal and generally covered by the need to have dependencies explicit in the
120134
/// version details files anyway.
121135
/// </remarks>
122-
private async Task<List<DependencyUpdate>> GetRequiredStrictCoherencyUpdatesAsync(
123-
IEnumerable<DependencyDetail> dependencies,
124-
IRemoteFactory remoteFactory)
136+
private async Task<List<DependencyUpdate>> GetRequiredStrictCoherencyUpdatesAsync(IEnumerable<DependencyDetail> dependencies)
125137
{
126138
List<DependencyUpdate> toUpdate = [];
127139
IEnumerable<DependencyDetail> leavesOfCoherencyTrees = CalculateLeavesOfCoherencyTrees(dependencies);
@@ -189,7 +201,7 @@ private async Task<List<DependencyUpdate>> GetRequiredStrictCoherencyUpdatesAsyn
189201
if (!dependenciesCache.TryGetValue(parentCoherentDependencyCacheKey,
190202
out IEnumerable<DependencyDetail> coherentParentsDependencies))
191203
{
192-
IRemote remoteClient = await remoteFactory.CreateRemoteAsync(parentCoherentDependency.RepoUri);
204+
IRemote remoteClient = await _remoteFactory.CreateRemoteAsync(parentCoherentDependency.RepoUri);
193205
coherentParentsDependencies = await remoteClient.GetDependenciesAsync(
194206
parentCoherentDependency.RepoUri,
195207
parentCoherentDependency.Commit);
@@ -235,7 +247,7 @@ private async Task<List<DependencyUpdate>> GetRequiredStrictCoherencyUpdatesAsyn
235247
_logger.LogInformation($"Dependency {dependencyToUpdate.Name} will be updated to " +
236248
$"{cpdDependency.Version} from {cpdDependency.RepoUri}@{cpdDependency.Commit}.");
237249

238-
Asset coherentAsset = await DisambiguateAssetsAsync(remoteFactory, buildCache, nugetConfigCache,
250+
Asset coherentAsset = await DisambiguateAssetsAsync(buildCache, nugetConfigCache,
239251
parentCoherentDependency, cpdDependency);
240252

241253
var updatedDependency = new DependencyDetail(dependencyToUpdate)
@@ -314,15 +326,16 @@ private static IEnumerable<DependencyDetail> CalculateLeavesOfCoherencyTrees(IEn
314326
/// Disambiguate a set of potential assets based the nuget config
315327
/// file in a repo. The asset's locations are returned if a match is found.
316328
/// </summary>
317-
/// <param name="remoteFactory">Remote factory for looking up the nuget config.</param>
318329
/// <param name="buildCache">Cache of builds</param>
319330
/// <param name="nugetConfigCache">Cache of nuget config files</param>
320331
/// <param name="parentCoherentDependency">Parent dependency of <paramref name="cpdDependency"/></param>
321332
/// <param name="cpdDependency">Dependency to disambiguate on.</param>
322333
/// <returns>Asset if a match to nuget.config is found. Asset from newest build is returned </returns>
323-
private async Task<Asset> DisambiguateAssetsAsync(IRemoteFactory remoteFactory,
324-
Dictionary<string, List<Build>> buildCache, Dictionary<string, IEnumerable<string>> nugetConfigCache,
325-
DependencyDetail parentCoherentDependency, DependencyDetail cpdDependency)
334+
private async Task<Asset> DisambiguateAssetsAsync(
335+
Dictionary<string, List<Build>> buildCache,
336+
Dictionary<string, IEnumerable<string>> nugetConfigCache,
337+
DependencyDetail parentCoherentDependency,
338+
DependencyDetail cpdDependency)
326339
{
327340
var parentCoherentDependencyCacheKey = $"{parentCoherentDependency.RepoUri}@{parentCoherentDependency.Commit}";
328341

@@ -389,7 +402,7 @@ private async Task<Asset> DisambiguateAssetsAsync(IRemoteFactory remoteFactory,
389402
// coherent asset itself.
390403
if (!nugetConfigCache.TryGetValue(parentCoherentDependencyCacheKey, out IEnumerable<string> nugetFeeds))
391404
{
392-
IRemote remoteClient = await remoteFactory.CreateRemoteAsync(parentCoherentDependency.RepoUri);
405+
IRemote remoteClient = await _remoteFactory.CreateRemoteAsync(parentCoherentDependency.RepoUri);
393406
nugetFeeds = await remoteClient.GetPackageSourcesAsync(parentCoherentDependency.RepoUri, parentCoherentDependency.Commit);
394407
}
395408

src/Microsoft.DotNet.Darc/DarcLib/GitHubClient.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -560,7 +560,7 @@ private static void UpdateCheckRun(NewCheckRun newCheckRun, MergePolicyEvaluatio
560560
{
561561
newCheckRun.Status = CheckStatus.InProgress;
562562
}
563-
else if (result.Status == MergePolicyEvaluationStatus.DecisiveSuccess)
563+
else if (result.Status == MergePolicyEvaluationStatus.DecisiveSuccess || result.Status == MergePolicyEvaluationStatus.TransientSuccess)
564564
{
565565
newCheckRun.Conclusion = "success";
566566
newCheckRun.CompletedAt = DateTime.Now;

src/Microsoft.DotNet.Darc/DarcLib/ICoherencyUpdateResolver.cs

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,8 @@ public interface ICoherencyUpdateResolver
1414
/// Get updates required by coherency constraints.
1515
/// </summary>
1616
/// <param name="dependencies">Current set of dependencies.</param>
17-
/// <param name="remoteFactory">Remote factory for remote queries.</param>
1817
/// <returns>List of dependency updates.</returns>
19-
Task<List<DependencyUpdate>> GetRequiredCoherencyUpdatesAsync(
20-
IEnumerable<DependencyDetail> dependencies,
21-
IRemoteFactory remoteFactory);
18+
Task<List<DependencyUpdate>> GetRequiredCoherencyUpdatesAsync(IEnumerable<DependencyDetail> dependencies);
2219

2320
/// <summary>
2421
/// Given a current set of dependencies, determine what non-coherency updates

0 commit comments

Comments
 (0)