Skip to content

Conversation

Copy link
Contributor

Copilot AI commented Dec 22, 2025

Co-authored-by: dkurepa <91743470+dkurepa@users.noreply.github.com>
Copilot AI changed the title [WIP] Update darc add-default-channel command for configuration repo Add configuration repository support to darc add-default-channel Dec 22, 2025
Copilot AI requested a review from dkurepa December 22, 2025 12:33
@dkurepa dkurepa marked this pull request as ready for review December 25, 2025 10:20
Copilot AI review requested due to automatic review settings December 25, 2025 10:20
Copy link
Contributor

Copilot AI left a 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-channel with 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) ?? [];
}
}
Copy link

Copilot AI Dec 25, 2025

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.

Copilot uses AI. Check for mistakes.
{
_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");
Copy link

Copilot AI Dec 25, 2025

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.

Suggested change
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");

Copilot uses AI. Check for mistakes.
$"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)
Copy link
Contributor

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.

Copy link
Contributor

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.

Copy link
Member

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

Copy link
Contributor

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

Copy link
Member

@premun premun Jan 5, 2026

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?

Copy link
Contributor

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.

Copy link
Member

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.

Copy link
Member

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}");
Copy link
Contributor

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

premun
premun previously approved these changes Jan 5, 2026
@dkurepa dkurepa merged commit 92a1274 into main Jan 5, 2026
7 of 9 checks passed
@dkurepa dkurepa deleted the copilot/update-darc-add-default-channel branch January 5, 2026 17:15
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants