Skip to content

Commit 396a181

Browse files
authored
[Rollout] Production rollout 2026-01-30 (#5878)
#5877 ## Checklist - [ ] Verify this PR contains the expected changes - [ ] Follow the rollout process in issue #5877 - [ ] ⚠️ **DO NOT SQUASH** when merging - use merge commit
2 parents 3e3209e + 932e7c1 commit 396a181

53 files changed

Lines changed: 663 additions & 4237 deletions

File tree

Some content is hidden

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

eng/Version.Details.props

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ This file should be imported by eng/Versions.props
2929
<MicrosoftDncEngConfigurationBootstrapPackageVersion>1.1.0-beta.26065.2</MicrosoftDncEngConfigurationBootstrapPackageVersion>
3030
<MicrosoftDncEngSecretManagerPackageVersion>1.1.0-beta.26065.2</MicrosoftDncEngSecretManagerPackageVersion>
3131
<!-- _git/maestro-configuration dependencies -->
32-
<MicrosoftDotNetMaestroConfigurationClientPackageVersion>1.1.0-beta.26071.1</MicrosoftDotNetMaestroConfigurationClientPackageVersion>
32+
<MicrosoftDotNetMaestroConfigurationClientPackageVersion>1.1.0-beta.26079.6</MicrosoftDotNetMaestroConfigurationClientPackageVersion>
3333
</PropertyGroup>
3434
<!--Property group for alternate package version names-->
3535
<PropertyGroup>

eng/Version.Details.xml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -83,9 +83,9 @@
8383
<Uri>https://github.com/dotnet/dnceng</Uri>
8484
<Sha>cd39caadfdc198bfc3cb138675d6a031f2fef74b</Sha>
8585
</Dependency>
86-
<Dependency Name="Microsoft.DotNet.MaestroConfiguration.Client" Version="1.1.0-beta.26071.1">
86+
<Dependency Name="Microsoft.DotNet.MaestroConfiguration.Client" Version="1.1.0-beta.26079.6">
8787
<Uri>https://dev.azure.com/dnceng/internal/_git/maestro-configuration</Uri>
88-
<Sha>2202396405c0b4b7516c8883bf34a244d3e1afd8</Sha>
88+
<Sha>594b3c83e560d14fa5a641ef254292072d7342b0</Sha>
8989
</Dependency>
9090
</ToolsetDependencies>
9191
</Dependencies>

src/Maestro/Maestro.DataProviders/Maestro.DataProviders.csproj

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,10 @@
55
<IsPackable>true</IsPackable>
66
</PropertyGroup>
77

8+
<ItemGroup>
9+
<InternalsVisibleTo Include="ProductConstructionService.Api.Tests" />
10+
</ItemGroup>
11+
812
<ItemGroup>
913
<PackageReference Include="Microsoft.DotNet.GitHub.Authentication" />
1014
<PackageReference Include="Microsoft.DotNet.Kusto" />
@@ -16,4 +20,5 @@
1620
<ProjectReference Include="..\Maestro.Data\Maestro.Data.csproj" />
1721
</ItemGroup>
1822

23+
1924
</Project>

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

Lines changed: 14 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,13 @@
33

44
using System;
55
using System.Linq;
6-
using System.Net;
76
using System.Threading.Tasks;
87
using Microsoft.DotNet.Darc.Options;
98
using Microsoft.DotNet.DarcLib;
109
using Microsoft.DotNet.MaestroConfiguration.Client;
1110
using Microsoft.DotNet.MaestroConfiguration.Client.Models;
1211
using Microsoft.DotNet.ProductConstructionService.Client;
13-
using Microsoft.DotNet.ProductConstructionService.Client.Models;
1412
using Microsoft.Extensions.Logging;
15-
using Newtonsoft.Json;
1613

1714
namespace Microsoft.DotNet.Darc.Operations;
1815

@@ -51,55 +48,17 @@ public override async Task<int> ExecuteAsync()
5148
return Constants.ErrorCode;
5249
}
5350

54-
if (_options.ShouldUseConfigurationRepository)
51+
var channelYaml = new ChannelYaml
5552
{
56-
var channelYaml = new ChannelYaml
57-
{
58-
Name = _options.Name,
59-
Classification = _options.Classification
60-
};
53+
Name = _options.Name,
54+
Classification = _options.Classification
55+
};
6156

62-
await ValidateNoEquivalentChannel(channelYaml);
57+
await ValidateNoEquivalentChannel(channelYaml);
6358

64-
try
65-
{
66-
await _configurationRepositoryManager.AddChannelAsync(
67-
_options.ToConfigurationRepositoryOperationParameters(),
68-
channelYaml);
69-
}
70-
// TODO https://github.com/dotnet/arcade-services/issues/5693 drop to the "global try-catch" when configuration repo is the only behavior
71-
catch (DuplicateConfigurationObjectException e)
72-
{
73-
_logger.LogError("Channel with name '{name}' already exists in '{filePath}' in repo {repo} on branch {branch}.",
74-
channelYaml.Name,
75-
e.FilePath,
76-
e.Repository,
77-
e.Branch);
78-
return Constants.ErrorCode;
79-
}
80-
}
81-
else
82-
{
83-
Channel newChannelInfo = await _barClient.CreateChannelAsync(_options.Name, _options.Classification);
84-
switch (_options.OutputFormat)
85-
{
86-
case DarcOutputType.json:
87-
Console.WriteLine(JsonConvert.SerializeObject(
88-
new
89-
{
90-
id = newChannelInfo.Id,
91-
name = newChannelInfo.Name,
92-
classification = newChannelInfo.Classification
93-
},
94-
Formatting.Indented));
95-
break;
96-
case DarcOutputType.text:
97-
Console.WriteLine($"Successfully created new channel with name '{_options.Name}' and id {newChannelInfo.Id}.");
98-
break;
99-
default:
100-
throw new NotImplementedException($"Output type {_options.OutputFormat} not supported by add-channel");
101-
}
102-
}
59+
await _configurationRepositoryManager.AddChannelAsync(
60+
_options.ToConfigurationRepositoryOperationParameters(),
61+
channelYaml);
10362

10463
return Constants.SuccessCode;
10564
}
@@ -108,9 +67,13 @@ await _configurationRepositoryManager.AddChannelAsync(
10867
Console.WriteLine(e.Message);
10968
return Constants.ErrorCode;
11069
}
111-
catch (RestApiException e) when (e.Response.Status == (int) HttpStatusCode.Conflict)
70+
catch (DuplicateConfigurationObjectException e)
11271
{
113-
_logger.LogError($"An existing channel with name '{_options.Name}' already exists");
72+
_logger.LogError("Channel with name '{name}' already exists in '{filePath}' in repo {repo} on branch {branch}.",
73+
_options.Name,
74+
e.FilePath,
75+
e.Repository,
76+
e.Branch);
11477
return Constants.ErrorCode;
11578
}
11679
catch (Exception e)

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

Lines changed: 21 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -55,41 +55,19 @@ public override async Task<int> ExecuteAsync()
5555
return Constants.ErrorCode;
5656
}
5757

58-
if (_options.ShouldUseConfigurationRepository)
58+
DefaultChannelYaml defaultChannelYaml = new()
5959
{
60-
DefaultChannelYaml defaultChannelYaml = new()
61-
{
62-
Repository = _options.Repository,
63-
Branch = _options.Branch,
64-
Channel = _options.Channel,
65-
Enabled = true
66-
};
60+
Repository = _options.Repository,
61+
Branch = _options.Branch,
62+
Channel = _options.Channel,
63+
Enabled = true
64+
};
6765

68-
await ValidateNoEquivalentDefaultChannel(defaultChannelYaml);
66+
await ValidateNoEquivalentDefaultChannel(defaultChannelYaml);
6967

70-
try
71-
{
72-
await _configurationRepositoryManager.AddDefaultChannelAsync(
73-
_options.ToConfigurationRepositoryOperationParameters(),
74-
defaultChannelYaml);
75-
}
76-
// TODO https://github.com/dotnet/arcade-services/issues/5693 drop to the "global try-catch" when configuration repo is the only behavior
77-
catch (MaestroConfiguration.Client.DuplicateConfigurationObjectException e)
78-
{
79-
_logger.LogError("Default channel with repository '{repo}', branch '{branch}', and channel '{channel}' already exists in '{filePath}' in repo {repo} on branch {branch}.",
80-
defaultChannelYaml.Repository,
81-
defaultChannelYaml.Branch,
82-
defaultChannelYaml.Channel,
83-
e.FilePath,
84-
e.Repository,
85-
e.Branch);
86-
return Constants.ErrorCode;
87-
}
88-
}
89-
else
90-
{
91-
await _barClient.AddDefaultChannelAsync(_options.Repository, _options.Branch, _options.Channel);
92-
}
68+
await _configurationRepositoryManager.AddDefaultChannelAsync(
69+
_options.ToConfigurationRepositoryOperationParameters(),
70+
defaultChannelYaml);
9371

9472
return Constants.SuccessCode;
9573
}
@@ -98,6 +76,17 @@ await _configurationRepositoryManager.AddDefaultChannelAsync(
9876
Console.WriteLine(e.Message);
9977
return Constants.ErrorCode;
10078
}
79+
catch (MaestroConfiguration.Client.DuplicateConfigurationObjectException e)
80+
{
81+
_logger.LogError("Default channel with repository '{repo}', branch '{branch}', and channel '{channel}' already exists in '{filePath}' in repo {configRepo} on branch {configBranch}.",
82+
_options.Repository,
83+
_options.Branch,
84+
_options.Channel,
85+
e.FilePath,
86+
e.Repository,
87+
e.Branch);
88+
return Constants.ErrorCode;
89+
}
10190
catch (Exception e)
10291
{
10392
_logger.LogError(e, "Error: Failed to add a new default channel association.");

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

Lines changed: 26 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -336,8 +336,6 @@ public override async Task<int> ExecuteAsync()
336336
excludedAssets = [..addSubscriptionPopup.ExcludedAssets];
337337
}
338338

339-
340-
341339
try
342340
{
343341
// If we are about to add a batchable subscription and the merge policies are empty for the
@@ -401,84 +399,42 @@ await ValidateCodeflowSubscriptionConflicts(
401399
}
402400
}
403401

404-
if (_options.ShouldUseConfigurationRepository)
402+
SubscriptionYamlParameters subscriptionYamlParameters = new()
405403
{
406-
SubscriptionYamlParameters subscriptionYaml = new()
407-
{
408-
Enabled = enabled,
409-
Channel = channel,
410-
SourceRepository = sourceRepository,
411-
TargetRepository = targetRepository,
412-
TargetBranch = targetBranch,
413-
UpdateFrequency = (UpdateFrequency)Enum.Parse(typeof(UpdateFrequency), updateFrequency, ignoreCase: true),
414-
Batchable = batchable,
415-
MergePolicies = MergePolicyYaml.FromClientModels(mergePolicies),
416-
FailureNotificationTags = failureNotificationTags,
417-
SourceEnabled = sourceEnabled,
418-
SourceDirectory = sourceDirectory,
419-
TargetDirectory = targetDirectory,
420-
ExcludedAssets = excludedAssets
421-
};
422-
423-
await ValidateNoEquivalentSubscription(subscriptionYaml);
404+
Enabled = enabled,
405+
Channel = channel,
406+
SourceRepository = sourceRepository,
407+
TargetRepository = targetRepository,
408+
TargetBranch = targetBranch,
409+
UpdateFrequency = (UpdateFrequency)Enum.Parse(typeof(UpdateFrequency), updateFrequency, ignoreCase: true),
410+
Batchable = batchable,
411+
MergePolicies = MergePolicyYaml.FromClientModels(mergePolicies),
412+
FailureNotificationTags = failureNotificationTags,
413+
SourceEnabled = sourceEnabled,
414+
SourceDirectory = sourceDirectory,
415+
TargetDirectory = targetDirectory,
416+
ExcludedAssets = excludedAssets
417+
};
418+
419+
await ValidateNoEquivalentSubscription(subscriptionYamlParameters);
420+
421+
await _configurationRepositoryManager.AddSubscriptionAsync(
422+
_options.ToConfigurationRepositoryOperationParameters(),
423+
subscriptionYamlParameters);
424424

425-
try
426-
{
427-
await _configurationRepositoryManager.AddSubscriptionAsync(
428-
_options.ToConfigurationRepositoryOperationParameters(),
429-
subscriptionYaml);
430-
}
431-
// TODO https://github.com/dotnet/arcade-services/issues/5693 drop to the "global try-catch" when configuration repo is the only behavior
432-
catch (MaestroConfiguration.Client.DuplicateConfigurationObjectException ex)
433-
{
434-
_logger.LogError("Subscription with equivalent parameters already exists in '{filePath}' in repo {repo} on branch {branch}.",
435-
ex.FilePath,
436-
ex.Repository,
437-
ex.Branch);
438-
return Constants.ErrorCode;
439-
}
440-
}
441-
else
442-
{
443-
Subscription newSubscription = await _barClient.CreateSubscriptionAsync(
444-
enabled,
445-
channel,
446-
sourceRepository,
447-
targetRepository,
448-
targetBranch,
449-
updateFrequency,
450-
batchable,
451-
mergePolicies,
452-
failureNotificationTags,
453-
sourceEnabled,
454-
sourceDirectory,
455-
targetDirectory,
456-
excludedAssets);
457-
458-
Console.WriteLine($"Successfully created new subscription with id '{newSubscription.Id}'.");
459-
460-
// Prompt the user to trigger the subscription unless they have explicitly disallowed it
461-
if (!_options.NoTriggerOnCreate)
462-
{
463-
bool triggerAutomatically = _options.TriggerOnCreate || UxHelpers.PromptForYesNo("Trigger this subscription immediately?");
464-
if (triggerAutomatically)
465-
{
466-
await _barClient.TriggerSubscriptionAsync(newSubscription.Id);
467-
Console.WriteLine($"Subscription '{newSubscription.Id}' triggered.");
468-
}
469-
}
470-
}
471425
return Constants.SuccessCode;
472426
}
473427
catch (AuthenticationException e)
474428
{
475429
Console.WriteLine(e.Message);
476430
return Constants.ErrorCode;
477431
}
478-
catch (RestApiException e) when (e.Response.Status == (int) System.Net.HttpStatusCode.BadRequest)
432+
catch (MaestroConfiguration.Client.DuplicateConfigurationObjectException ex)
479433
{
480-
// Could have been some kind of validation error (e.g. channel doesn't exist)
481-
_logger.LogError($"Failed to create subscription: {e.Response.Content}");
434+
_logger.LogError("Subscription with equivalent parameters already exists in '{filePath}' in repo {repo} on branch {branch}.",
435+
ex.FilePath,
436+
ex.Repository,
437+
ex.Branch);
482438
return Constants.ErrorCode;
483439
}
484440
catch (Exception e)

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

Lines changed: 18 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -72,39 +72,15 @@ public override async Task<int> ExecuteAsync()
7272
enabled = false;
7373
}
7474

75-
if (_options.ShouldUseConfigurationRepository)
75+
// Create an updated YAML default channel with the new enabled status
76+
DefaultChannelYaml updatedDefaultChannelYaml = DefaultChannelYaml.FromClientModel(resolvedChannel) with
7677
{
77-
// Create an updated YAML default channel with the new enabled status
78-
DefaultChannelYaml updatedDefaultChannelYaml = DefaultChannelYaml.FromClientModel(resolvedChannel) with
79-
{
80-
Enabled = enabled
81-
};
82-
83-
try
84-
{
85-
await _configurationRepositoryManager.UpdateDefaultChannelAsync(
86-
_options.ToConfigurationRepositoryOperationParameters(),
87-
updatedDefaultChannelYaml);
88-
}
89-
// TODO drop to the "global try-catch" when configuration repo is the only behavior
90-
catch (MaestroConfiguration.Client.ConfigurationObjectNotFoundException ex)
91-
{
92-
_logger.LogError("No existing default channel with repository '{repository}', branch '{branch}', and channel '{channel}' found in file {filePath} of repo {repositoryUri} on branch {branchName}",
93-
updatedDefaultChannelYaml.Repository,
94-
updatedDefaultChannelYaml.Branch,
95-
updatedDefaultChannelYaml.Channel,
96-
ex.FilePath,
97-
ex.RepositoryUri,
98-
ex.BranchName);
99-
return Constants.ErrorCode;
100-
}
101-
}
102-
else
103-
{
104-
await _barClient.UpdateDefaultChannelAsync(resolvedChannel.Id, enabled: enabled);
78+
Enabled = enabled
79+
};
10580

106-
Console.WriteLine($"Default channel association has been {(enabled ? "enabled" : "disabled")}.");
107-
}
81+
await _configurationRepositoryManager.UpdateDefaultChannelAsync(
82+
_options.ToConfigurationRepositoryOperationParameters(),
83+
updatedDefaultChannelYaml);
10884

10985
return Constants.SuccessCode;
11086
}
@@ -113,6 +89,17 @@ await _configurationRepositoryManager.UpdateDefaultChannelAsync(
11389
Console.WriteLine(e.Message);
11490
return Constants.ErrorCode;
11591
}
92+
catch (MaestroConfiguration.Client.ConfigurationObjectNotFoundException ex)
93+
{
94+
_logger.LogError("No existing default channel with repository '{repository}', branch '{branch}', and channel '{channel}' found in file {filePath} of repo {repositoryUri} on branch {branchName}",
95+
_options.Repository,
96+
_options.Branch,
97+
_options.Channel,
98+
ex.FilePath,
99+
ex.RepositoryUri,
100+
ex.BranchName);
101+
return Constants.ErrorCode;
102+
}
116103
catch (Exception e)
117104
{
118105
_logger.LogError(e, "Error: Failed enable/disable default channel association.");

0 commit comments

Comments
 (0)