diff --git a/tools/notification-configuration/notification-creator/Contacts.cs b/tools/notification-configuration/notification-creator/Contacts.cs
index 4fe2427bfcb0..9e6404f137a0 100644
--- a/tools/notification-configuration/notification-creator/Contacts.cs
+++ b/tools/notification-configuration/notification-creator/Contacts.cs
@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
+using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
@@ -12,18 +13,21 @@ namespace Azure.Sdk.Tools.NotificationConfiguration;
///
/// This class represents a set of contacts obtained from CODEOWNERS file
-/// located in repository attached to given build definition.
+/// located in repository attached to given build definition [1].
///
/// The contacts are the CODEOWNERS path owners of path that matches the build definition file path.
///
/// To obtain the contacts, construct this class and then call GetFromBuildDefinitionRepoCodeowners(buildDefinition).
+///
+/// [1] https://learn.microsoft.com/en-us/rest/api/azure/devops/build/definitions/get?view=azure-devops-rest-7.0#builddefinition
///
internal class Contacts
{
private readonly ILogger log;
private readonly GitHubService gitHubService;
- // Type 2 maps to a build definition YAML file in the repository
+ // Type 2 maps to a build definition YAML file in the repository.
+ // You can confirm it by decompiling Microsoft.TeamFoundation.Build.WebApi.YamlProcess..ctor.
private const int BuildDefinitionYamlProcessType = 2;
internal Contacts(GitHubService gitHubService, ILogger log)
@@ -40,14 +44,15 @@ public async Task> GetFromBuildDefinitionRepoCodeowners(BuildDefini
if (buildDefinition.Process.Type != BuildDefinitionYamlProcessType)
{
this.log.LogDebug(
- "buildDefinition.Process.Type '{buildDefinitionProcessType}' " +
- "for buildDefinition.Name '{buildDefinitionName}' " +
+ "buildDefinition.Process.Type: '{buildDefinitionProcessType}' " +
+ "for buildDefinition.Name: '{buildDefinitionName}' " +
"must be '{BuildDefinitionYamlProcessType}'.",
buildDefinition.Process.Type,
buildDefinition.Name,
BuildDefinitionYamlProcessType);
return null;
}
+ YamlProcess yamlProcess = (YamlProcess)buildDefinition.Process;
Uri repoUrl = GetCodeownersRepoUrl(buildDefinition);
@@ -65,23 +70,15 @@ public async Task> GetFromBuildDefinitionRepoCodeowners(BuildDefini
return null;
}
- if (buildDefinition.Process is not YamlProcess process)
- {
- this.log.LogError(
- "buildDefinition.Process as YamlProcess is null. buildDefinition.Name: '{buildDefinitionName}'",
- buildDefinition.Name);
- return null;
- }
-
- // process.YamlFilename is misleading here. It is actually a file path, not file name.
+ // yamlProcess.YamlFilename is misleading here. It is actually a file path, not file name.
// E.g. it is "sdk/foo_service/ci.yml".
- string buildDefinitionFilePath = process.YamlFilename;
+ string buildDefinitionFilePath = yamlProcess.YamlFilename;
this.log.LogInformation(
"Searching CODEOWNERS for matching path for '{buildDefinitionFilePath}'",
buildDefinitionFilePath);
- CodeownersEntry matchingCodeownersEntry = GetMatchingCodeownersEntry(process, codeownersEntries);
+ CodeownersEntry matchingCodeownersEntry = GetMatchingCodeownersEntry(yamlProcess, codeownersEntries);
List contacts = matchingCodeownersEntry.Owners;
this.log.LogInformation(
@@ -98,7 +95,7 @@ private Uri GetCodeownersRepoUrl(BuildDefinition buildDefinition)
Uri repoUrl = buildDefinition.Repository.Url;
this.log.LogInformation("Fetching CODEOWNERS file from repoUrl: '{repoUrl}'", repoUrl);
- if (String.IsNullOrEmpty(repoUrl))
+ if (!string.IsNullOrEmpty(repoUrl?.ToString()))
{
repoUrl = new Uri(Regex.Replace(repoUrl.ToString(), @"\.git$", String.Empty));
}