-
Notifications
You must be signed in to change notification settings - Fork 78
Add configuration repository support to darc add-default-channel
#5684
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Co-authored-by: dkurepa <91743470+dkurepa@users.noreply.github.com>
darc add-default-channel
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
This PR extends the darc add-default-channel command to support writing default channel configurations directly to the maestro-configuration repository, enabling a dual-mode operation during the transition from API-based to file-based configuration management. The implementation follows the established pattern from add-subscription and is controlled by the DARC_USE_CONFIGURATION_REPOSITORY environment variable.
Key Changes
- Added configuration repository support to
darc add-default-channelwith dual-mode operation (API vs. config repo) - Implemented BAR validation before writing to config repo to prevent duplicates across both systems
- Comprehensive test suite covering file creation, appending, and duplicate detection scenarios
Reviewed changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated 6 comments.
Show a summary per file
| File | Description |
|---|---|
src/Microsoft.DotNet.Darc/Darc/Options/AddDefaultChannelCommandLineOptions.cs |
Changed base class to ConfigurationManagementCommandLineOptions to inherit configuration repository flags |
src/Microsoft.DotNet.Darc/Darc/Operations/AddDefaultChannelOperation.cs |
Added dual-mode operation routing, BAR validation, and config repo integration for default channel management |
src/MaestroConfiguration/src/Microsoft.DotNet.MaestroConfiguration.Client/IConfigurationRepositoryManager.cs |
Added AddDefaultChannelAsync method signature to the interface |
src/MaestroConfiguration/src/Microsoft.DotNet.MaestroConfiguration.Client/ConfigurationRepositoryManager.cs |
Implemented AddDefaultChannelAsync with duplicate detection and proper file path resolution |
test/Microsoft.DotNet.Darc.Tests/Operations/AddDefaultChannelOperationConfigRepoTests.cs |
Added comprehensive test suite covering file creation, appending to existing files, and duplicate detection in YAML files |
| var content = await File.ReadAllTextAsync(filePath); | ||
| return YamlDeserializer.Deserialize<List<DefaultChannelYaml>>(content) ?? []; | ||
| } | ||
| } |
Copilot
AI
Dec 25, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The test suite is missing a test case for when ValidateNoEquivalentDefaultChannel fails because a default channel already exists in BAR. This is an important scenario to test since it validates the BAR-level duplicate detection logic. Consider adding a test that mocks _barClient.GetDefaultChannelsAsync to return an existing default channel, then verifies that ExecuteAsync returns Constants.ErrorCode and logs the appropriate error message.
test/Microsoft.DotNet.Darc.Tests/Operations/AddDefaultChannelOperationConfigRepoTests.cs
Show resolved
Hide resolved
| { | ||
| _logger.LogError("A default channel with the same repository, branch, and channel already exists (ID: {id})", | ||
| existingDefaultChannel.Id); | ||
| throw new ArgumentException($"A default channel with the repository {existingDefaultChannel.Repository}, branch {existingDefaultChannel.Branch} and channel {existingDefaultChannel.Channel} already exists"); |
Copilot
AI
Dec 25, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Default 'ToString()': Channel inherits 'ToString()' from 'Object', and so is not suitable for printing.
| throw new ArgumentException($"A default channel with the repository {existingDefaultChannel.Repository}, branch {existingDefaultChannel.Branch} and channel {existingDefaultChannel.Channel} already exists"); | |
| throw new ArgumentException($"A default channel with the repository {existingDefaultChannel.Repository}, branch {existingDefaultChannel.Branch} and channel {existingDefaultChannel.Channel.Name} already exists"); |
| $"Add new default channel ({dc.Channel}) {dc.Repository} ({dc.Branch})"), | ||
| $"Successfully added default channel on branch '{parameters.ConfigurationBranch}' of the configuration repository {parameters.RepositoryUri}"); | ||
| } | ||
| catch (DuplicateConfigurationObjectException ex) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These ones look like they should just be caught at the base operation - or even better, I think we already have a global catcher at the darc operation base which prints the exception message without the stack trace - so we don't need to catch it anywhere.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There should probably be no logging at all in this class, since it's actually a library. We don't know where this code will run.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we want these to do the logging because they're a library
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we want these to do the logging because they're a library
Doing a catch and rethrow just for logging is redundant, I don't see the point. The exception goes through to the caller of the library anyway, so the caller will either catch it himself anyway, or let it make his process quit unsuccessfully
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is it though? If we have 5 places we use the library from, do all 5 now need to catch+log so that they explain what the exception means to the user?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think catching and rethrowing just for a log should be done anywhere, not in the library and not by the caller.
Notice that in our darc operations we already have a catcher on the base operation level that hides the stack trace but shows the error message to the user - that's perfect usage of it IMO. There was no need to catch and rethrow just for logging anywhere inbetween.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If the exception has a similar message inside then I agree it's not worth catching+logging+rethrowing.
If this logging in the catch explains some important detail of the exception that only the client library understands then I can see it staying. Alternatively, we could catch here and rethrow with a different exception message that is more explanatory - e.g. instead of throwing "entity like this already exists in a file on branch", we'd set it to "this channel already exists" or "channel with the same name already exists" which is more user-friendly.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I made the logging only happen in the darc operations, and improved the messaging on the exceptions themselves for whoever catches it while using the library.
Let me know if you think it's good so I can update other PRs with it
| && string.Equals(existing.Channel, newDc.Channel, StringComparison.OrdinalIgnoreCase), | ||
| new DefaultChannelYamlComparer(), | ||
| $"Add new default channel ({dc.Channel}) {dc.Repository} ({dc.Branch})"), | ||
| $"Successfully added default channel on branch '{parameters.ConfigurationBranch}' of the configuration repository {parameters.RepositoryUri}"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The success message seems like a darc operation concern, not something that should be in the config repo client library
#5501