Skip to content

Commit

Permalink
Add Azure.Sdk.Tools.NotificationConfiguration.Tests + improve `Noti…
Browse files Browse the repository at this point in the history
…ficationConfiguration.Program.Main` (#5247)
  • Loading branch information
Konrad Jamrozik authored Jan 27, 2023
1 parent b3668aa commit a442861
Show file tree
Hide file tree
Showing 4 changed files with 178 additions and 53 deletions.
24 changes: 24 additions & 0 deletions tools/notification-configuration/notification-configuration.sln
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,18 @@ VisualStudioVersion = 17.5.33103.201
MinimumVisualStudioVersion = 10.0.40219.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Azure.Sdk.Tools.NotificationConfiguration", "notification-creator\Azure.Sdk.Tools.NotificationConfiguration.csproj", "{5759063D-A7B3-4D36-ACF4-5595C2789D27}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Azure.Sdk.Tools.NotificationConfiguration.Tests", "notification-creator.Tests\Azure.Sdk.Tools.NotificationConfiguration.Tests.csproj", "{3097CBB4-ED3C-4273-AC67-F5D189CB94BA}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Azure.Sdk.Tools.CodeOwnersParser", "..\code-owners-parser\CodeOwnersParser\Azure.Sdk.Tools.CodeOwnersParser.csproj", "{A9826C8B-85DF-48DB-8A05-40FB04833C42}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Azure.Sdk.Tools.CodeOwnersParser.Tests", "..\code-owners-parser\Azure.Sdk.Tools.CodeOwnersParser.Tests\Azure.Sdk.Tools.CodeOwnersParser.Tests.csproj", "{2146E1FF-04D1-4B19-9767-C011A73CB40D}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "identity-resolution", "..\identity-resolution\identity-resolution.csproj", "{9805B503-5469-412C-9A0C-F09F504F0ED8}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Azure.Sdk.Tools.RetrieveCodeOwners", "..\code-owners-parser\Azure.Sdk.Tools.RetrieveCodeOwners\Azure.Sdk.Tools.RetrieveCodeOwners.csproj", "{3E5237F2-6536-4329-A9CF-92E42B040612}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Azure.Sdk.Tools.RetrieveCodeOwners.Tests", "..\code-owners-parser\Azure.Sdk.Tools.RetrieveCodeOwners.Tests\Azure.Sdk.Tools.RetrieveCodeOwners.Tests.csproj", "{8DAEC12F-8390-4122-9959-9CF3391F18CC}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{EBC153AF-0244-4DFB-8084-E6C0ACAA5CF3}"
ProjectSection(SolutionItems) = preProject
ci.yml = ci.yml
Expand All @@ -33,6 +41,22 @@ Global
{9805B503-5469-412C-9A0C-F09F504F0ED8}.Debug|Any CPU.Build.0 = Debug|Any CPU
{9805B503-5469-412C-9A0C-F09F504F0ED8}.Release|Any CPU.ActiveCfg = Release|Any CPU
{9805B503-5469-412C-9A0C-F09F504F0ED8}.Release|Any CPU.Build.0 = Release|Any CPU
{8DAEC12F-8390-4122-9959-9CF3391F18CC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{8DAEC12F-8390-4122-9959-9CF3391F18CC}.Debug|Any CPU.Build.0 = Debug|Any CPU
{8DAEC12F-8390-4122-9959-9CF3391F18CC}.Release|Any CPU.ActiveCfg = Release|Any CPU
{8DAEC12F-8390-4122-9959-9CF3391F18CC}.Release|Any CPU.Build.0 = Release|Any CPU
{2146E1FF-04D1-4B19-9767-C011A73CB40D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{2146E1FF-04D1-4B19-9767-C011A73CB40D}.Debug|Any CPU.Build.0 = Debug|Any CPU
{2146E1FF-04D1-4B19-9767-C011A73CB40D}.Release|Any CPU.ActiveCfg = Release|Any CPU
{2146E1FF-04D1-4B19-9767-C011A73CB40D}.Release|Any CPU.Build.0 = Release|Any CPU
{3E5237F2-6536-4329-A9CF-92E42B040612}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{3E5237F2-6536-4329-A9CF-92E42B040612}.Debug|Any CPU.Build.0 = Debug|Any CPU
{3E5237F2-6536-4329-A9CF-92E42B040612}.Release|Any CPU.ActiveCfg = Release|Any CPU
{3E5237F2-6536-4329-A9CF-92E42B040612}.Release|Any CPU.Build.0 = Release|Any CPU
{3097CBB4-ED3C-4273-AC67-F5D189CB94BA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{3097CBB4-ED3C-4273-AC67-F5D189CB94BA}.Debug|Any CPU.Build.0 = Debug|Any CPU
{3097CBB4-ED3C-4273-AC67-F5D189CB94BA}.Release|Any CPU.ActiveCfg = Release|Any CPU
{3097CBB4-ED3C-4273-AC67-F5D189CB94BA}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<Nullable>enable</Nullable>
<WarningsAsErrors>Nullable</WarningsAsErrors>
<IsPackable>false</IsPackable>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.1.0" />
<PackageReference Include="NUnit" Version="3.13.3" />
<PackageReference Include="NUnit3TestAdapter" Version="4.2.1" />
<PackageReference Include="NUnit.Analyzers" Version="3.3.0" />
<PackageReference Include="coverlet.collector" Version="3.1.2" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\notification-creator\Azure.Sdk.Tools.NotificationConfiguration.csproj" />
</ItemGroup>

</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
using System;
using NUnit.Framework;

namespace Azure.Sdk.Tools.NotificationConfiguration.Tests;

[TestFixture]
public class ProgramTests
{
[Test]
public void ThrowsVssUnauthorizedException()
{
Environment.SetEnvironmentVariable("aadAppIdVar", "aadAppIdVarValue");
Environment.SetEnvironmentVariable("aadAppSecretVar", "aadAppSecretVarValue");
Environment.SetEnvironmentVariable("aadTenantVar", "aadTenantVarValue");
Assert.ThrowsAsync<Microsoft.VisualStudio.Services.Common.VssUnauthorizedException>(
async () =>
// Act
await Program.Main(
organization: "fooOrg",
project: "barProj",
pathPrefix: "qux",
tokenVariableName: "token",
aadAppIdVar: "aadAppIdVar",
aadAppSecretVar: "aadAppSecretVar",
aadTenantVar: "aadTenantVar",
selectionStrategy: PipelineSelectionStrategy.Scheduled,
dryRun: true)
);
}
}
155 changes: 102 additions & 53 deletions tools/notification-configuration/notification-creator/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,64 +7,113 @@
using Azure.Sdk.Tools.NotificationConfiguration.Helpers;
using Azure.Identity;

namespace Azure.Sdk.Tools.NotificationConfiguration
namespace Azure.Sdk.Tools.NotificationConfiguration;

/// <summary>
/// A tool for creating and configuring Azure DevOps groups for sending email notifications
/// on build failures to owners of relevant build definitions. The recipients are determined
/// based on the build definition .yml file paths as given by the CODEOWNERS of given build definition
/// source repository.
/// </summary>
public static class Program
{
class Program
/// <summary>
/// Create notification groups for failures in scheduled builds
/// </summary>
/// <param name="organization">Azure DevOps Organization</param>
/// <param name="project">Name of the DevOps project</param>
/// <param name="pathPrefix">Path prefix to include pipelines (e.g. "\net")</param>
/// <param name="tokenVariableName">Environment variable token name (e.g. "SYSTEM_ACCESSTOKEN")</param>
/// <param name="aadAppIdVar">AAD App ID environment variable name (OpensourceAPI access)</param>
/// <param name="aadAppSecretVar">AAD App Secret environment variable name (OpensourceAPI access)</param>
/// <param name="aadTenantVar">AAD Tenant environment variable name (OpensourceAPI access)</param>
/// <param name="selectionStrategy">Pipeline selection strategy</param>
/// <param name="dryRun">Prints changes but does not alter any objects</param>
/// <returns></returns>
public static async Task Main(
string organization,
string project,
string pathPrefix,
string tokenVariableName,
string aadAppIdVar,
string aadAppSecretVar,
string aadTenantVar,
PipelineSelectionStrategy selectionStrategy = PipelineSelectionStrategy.Scheduled,
bool dryRun = false)
{
/// <summary>
/// Create notification groups for failures in scheduled builds
/// </summary>
/// <param name="organization">Azure DevOps Organization</param>
/// <param name="project">Name of the DevOps project</param>
/// <param name="pathPrefix">Path prefix to include pipelines (e.g. "\net")</param>
/// <param name="tokenVariableName">Environment variable token name (e.g. "SYSTEM_ACCESSTOKEN")</param>
/// <param name="aadAppIdVar">AAD App ID environment variable name (OpensourceAPI access)</param>
/// <param name="aadAppSecretVar">AAD App Secret environment variable name (OpensourceAPI access)</param>
/// <param name="aadTenantVar">AAD Tenant environment variable name (OpensourceAPI access)</param>
/// <param name="selectionStrategy">Pipeline selection strategy</param>
/// <param name="dryRun">Prints changes but does not alter any objects</param>
/// <returns></returns>
static async Task Main(
string organization,
string project,
string pathPrefix,
string tokenVariableName,
string aadAppIdVar,
string aadAppSecretVar,
string aadTenantVar,
PipelineSelectionStrategy selectionStrategy = PipelineSelectionStrategy.Scheduled,
bool dryRun = false)
var loggerFactory = LoggerFactory.Create(builder =>
{
var devOpsToken = Environment.GetEnvironmentVariable(tokenVariableName);
var devOpsCreds = new VssBasicCredential("nobody", devOpsToken);
var devOpsConnection = new VssConnection(new Uri($"https://dev.azure.com/{organization}/"), devOpsCreds);
builder.AddSimpleConsole(config => { config.IncludeScopes = true; });
});
var logger = loggerFactory.CreateLogger(nameof(Program));
logger.LogInformation(
"Executing Azure.Sdk.Tools.NotificationConfiguration.Program.Main with following arguments: "
+ "organization: '{organization}' "
+ "project: '{project}' "
+ "pathPrefix: '{pathPrefix}' "
+ "tokenVariableName: '{tokenVariableName}' "
+ "aadAppIdVar: '{aadAppIdVar}' "
+ "aadAppSecretVar: '{aadAppSecretVar}' "
+ "aadTenantVar: '{aadTenantVar}' "
+ "selectionStrategy: '{selectionStrategy}' "
+ "dryRun: '{dryRun}' "
, organization
, project
, pathPrefix
, tokenVariableName
, aadAppIdVar
, aadAppSecretVar
, aadTenantVar
, selectionStrategy
, dryRun);

var notificationConfigurator = new NotificationConfigurator(
AzureDevOpsService(organization, tokenVariableName, loggerFactory),
GitHubService(loggerFactory),
loggerFactory.CreateLogger<NotificationConfigurator>());

await notificationConfigurator.ConfigureNotifications(
project,
pathPrefix,
GitHubToAADConverter(aadTenantVar, aadAppIdVar, aadAppSecretVar, loggerFactory),
persistChanges: !dryRun,
strategy: selectionStrategy);
}

var loggerFactory = LoggerFactory.Create(builder =>
{
builder.AddSimpleConsole(config => { config.IncludeScopes = true; });
});
var devOpsServiceLogger = loggerFactory.CreateLogger<AzureDevOpsService>();
var notificationConfiguratorLogger = loggerFactory.CreateLogger<NotificationConfigurator>();
private static AzureDevOpsService AzureDevOpsService(
string organization,
string tokenVariableName,
ILoggerFactory loggerFactory)
{
var devOpsToken = Environment.GetEnvironmentVariable(tokenVariableName);
var devOpsCreds = new VssBasicCredential("nobody", devOpsToken);
var devOpsConnection = new VssConnection(
new Uri($"https://dev.azure.com/{organization}/"),
devOpsCreds);
var devOpsService = new AzureDevOpsService(
devOpsConnection,
loggerFactory.CreateLogger<AzureDevOpsService>());
return devOpsService;
}

var devOpsService = new AzureDevOpsService(devOpsConnection, devOpsServiceLogger);
var gitHubService = new GitHubService(loggerFactory.CreateLogger<GitHubService>());
var credential = new ClientSecretCredential(
Environment.GetEnvironmentVariable(aadTenantVar),
Environment.GetEnvironmentVariable(aadAppIdVar),
Environment.GetEnvironmentVariable(aadAppSecretVar));
var githubToAadResolver = new GitHubToAADConverter(
credential,
loggerFactory.CreateLogger<GitHubToAADConverter>()
);
var configurator = new NotificationConfigurator(devOpsService,
gitHubService, notificationConfiguratorLogger);
await configurator.ConfigureNotifications(
project,
pathPrefix,
githubToAadResolver,
persistChanges: !dryRun,
strategy: selectionStrategy);
private static GitHubService GitHubService(ILoggerFactory loggerFactory)
=> new GitHubService(loggerFactory.CreateLogger<GitHubService>());

private static GitHubToAADConverter GitHubToAADConverter(
string aadTenantVar,
string aadAppIdVar,
string aadAppSecretVar,
ILoggerFactory loggerFactory)
{
var credential = new ClientSecretCredential(
Environment.GetEnvironmentVariable(aadTenantVar),
Environment.GetEnvironmentVariable(aadAppIdVar),
Environment.GetEnvironmentVariable(aadAppSecretVar));

}
var githubToAadResolver = new GitHubToAADConverter(
credential,
loggerFactory.CreateLogger<GitHubToAADConverter>()
);
return githubToAadResolver;
}
}

0 comments on commit a442861

Please sign in to comment.