Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 6 additions & 2 deletions .editorconfig
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ dotnet_style_prefer_simplified_boolean_expressions = true:suggestion
### Visual Studio ###

# IDE0005: Using directive is unnecessary.
dotnet_diagnostic.IDE0005.severity = warning
dotnet_diagnostic.IDE0005.severity = none

# IDE0130: Namespace does not match folder structure
dotnet_diagnostic.IDE0130.severity = none
Expand All @@ -108,4 +108,8 @@ indent_size = unset
indent_style = unset
insert_final_newline = false
tab_width = unset
trim_trailing_whitespace = false
trim_trailing_whitespace = false

[*.{received,verified}.{html}]
indent_size = 2
indent_style = space
12 changes: 8 additions & 4 deletions .github/workflows/github-actions-ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,10 @@ jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v7

- name: Setup .NET
uses: actions/setup-dotnet@v4
uses: actions/setup-dotnet@v5
with:
dotnet-version: 9.x

Expand All @@ -25,10 +25,14 @@ jobs:

- name: Run tests
run: |
dotnet test PosInformatique.Azure.Identity.AppRegistrationSecretWatcher.slnx \
dotnet test \
--solution PosInformatique.Azure.Identity.AppRegistrationSecretWatcher.slnx \
--configuration Release \
--no-build \
--logger "trx;LogFileName=test_results.trx" \
--coverage \
--coverage-output-format cobertura \
--coverage-settings CodeCoverage.runsettings \
--report-trx \
--results-directory ./TestResults

- name: Publish Test Results
Expand Down
14 changes: 7 additions & 7 deletions .github/workflows/github-actions-release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ on:
type: string
description: The version of the application
required: true
default: 1.1.0
default: 1.2.0
VersionSuffix:
type: string
description: The version suffix of the application (for example rc.1)
Expand All @@ -18,12 +18,12 @@ jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v7

- name: Setup .NET 9.x
uses: actions/setup-dotnet@v4
- name: Setup .NET 10.x
uses: actions/setup-dotnet@v5
with:
dotnet-version: '9.x'
dotnet-version: '10.x'

- name: Build AppRegistrationSecretWatcher Azure Functions
run: dotnet publish
Expand All @@ -34,13 +34,13 @@ jobs:
"src/Functions/Functions.csproj"

- name: Package the AppRegistrationSecretWatcher Azure Functions
run: cd ./publish && zip -r ../PosInformatique.Azure.Identity.AppRegistrationSecretWatcher.Functions.net9.0.zip .
run: cd ./publish && zip -r ../PosInformatique.Azure.Identity.AppRegistrationSecretWatcher.Functions.net10.0.zip .

- name: Upload to release
uses: softprops/action-gh-release@v2
with:
tag_name: v${{ github.event.inputs.VersionPrefix }}${{ github.event.inputs.VersionSuffix && format('-{0}', github.event.inputs.VersionSuffix) || '' }}
files: ./PosInformatique.Azure.Identity.AppRegistrationSecretWatcher.Functions.net9.0.zip
files: ./PosInformatique.Azure.Identity.AppRegistrationSecretWatcher.Functions.net10.0.zip
overwrite_files: true
draft: ${{ github.event.inputs.VersionSuffix == '' }}
prerelease: ${{ github.event.inputs.VersionSuffix != '' }}
Expand Down
51 changes: 51 additions & 0 deletions CodeCoverage.runsettings
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- File name extension must be .runsettings -->
<RunSettings>
<DataCollectionRunSettings>
<DataCollectors>
<DataCollector friendlyName="Code Coverage" uri="datacollector://Microsoft/CodeCoverage/2.0" assemblyQualifiedName="Microsoft.VisualStudio.Coverage.DynamicCoverageDataCollector, Microsoft.VisualStudio.TraceCollector, Version=11.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<Configuration>
<CodeCoverage>

<!-- Match assembly file paths: -->
<ModulePaths>
<Include>
<ModulePath>.*\.dll$</ModulePath>
</Include>
<Exclude>
<ModulePath>.*xunit.*</ModulePath>
<ModulePath>.*webjobs.*</ModulePath>
<ModulePath>moq.*</ModulePath>
<ModulePath>.*durabletask.*</ModulePath>
<ModulePath>microsoft.*</ModulePath>
<ModulePath>bouncycastle.*</ModulePath>
<ModulePath>.*tests\.dll$</ModulePath>
</Exclude>
</ModulePaths>

<Attributes>
<Exclude>
<!-- Exclude generated code from code coverage -->
<Attribute>^System\.CodeDom\.Compiler\.GeneratedCodeAttribute$</Attribute>
<Attribute>^System\.Diagnostics\.CodeAnalysis\.ExcludeFromCodeCoverageAttribute$</Attribute>
</Exclude>
</Attributes>

<CompanyNames>
<Include>
<CompanyName>.*PosInformatique.*</CompanyName>
</Include>
</CompanyNames>

<!-- We recommend you do not change the following values: -->
<UseVerifiableInstrumentation>True</UseVerifiableInstrumentation>
<AllowLowIntegrityProcesses>True</AllowLowIntegrityProcesses>
<CollectFromChildProcesses>True</CollectFromChildProcesses>
<CollectAspDotNet>False</CollectAspDotNet>

</CodeCoverage>
</Configuration>
</DataCollector>
</DataCollectors>
</DataCollectionRunSettings>
</RunSettings>
29 changes: 14 additions & 15 deletions Directory.Packages.props
Original file line number Diff line number Diff line change
Expand Up @@ -2,30 +2,29 @@
<PropertyGroup>
<ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>
<!-- Versions of the packages -->
<PosInformationFoundationsVersion>1.0.0</PosInformationFoundationsVersion>
<PosInformationFoundationsVersion>1.1.0</PosInformationFoundationsVersion>
</PropertyGroup>
<ItemGroup>
<PackageVersion Include="Azure.Identity" Version="1.17.0" />
<PackageVersion Include="coverlet.collector" Version="6.0.4" />
<PackageVersion Include="FluentAssertions" Version="7.2.0" />
<PackageVersion Include="Microsoft.ApplicationInsights.WorkerService" Version="2.23.0" />
<PackageVersion Include="Microsoft.Azure.Functions.Worker" Version="2.51.0" />
<PackageVersion Include="Microsoft.Azure.Functions.Worker.ApplicationInsights" Version="2.50.0" />
<PackageVersion Include="Azure.Identity" Version="1.21.0" />
<PackageVersion Include="Azure.Monitor.OpenTelemetry.AspNetCore" Version="1.5.0" />
<PackageVersion Include="FluentAssertions" Version="8.10.0" />
<PackageVersion Include="Microsoft.Azure.Functions.Worker" Version="2.52.0" />
<PackageVersion Include="Microsoft.Azure.Functions.Worker.Extensions.Http.AspNetCore" Version="2.1.0" />
<PackageVersion Include="Microsoft.Azure.Functions.Worker.OpenTelemetry" Version="1.2.0" />
<PackageVersion Include="Microsoft.Azure.Functions.Worker.Extensions.Timer" Version="4.3.1" />
<PackageVersion Include="Microsoft.Azure.Functions.Worker.Sdk" Version="2.0.7" />
<PackageVersion Include="Microsoft.Extensions.Options" Version="9.0.11" />
<PackageVersion Include="Microsoft.Graph" Version="5.96.0" />
<PackageVersion Include="Microsoft.NET.Test.Sdk" Version="18.0.1" />
<PackageVersion Include="Microsoft.Extensions.Options" Version="10.0.9" />
<PackageVersion Include="Microsoft.Graph" Version="6.2.0" />
<PackageVersion Include="Microsoft.Testing.Extensions.CodeCoverage" Version="18.8.0" />
<PackageVersion Include="Microsoft.Testing.Extensions.TrxReport" Version="2.2.3" />
<PackageVersion Include="Moq" Version="4.20.72" />
<PackageVersion Include="PosInformatique.Foundations.EmailAddresses" Version="$(PosInformationFoundationsVersion)" />
<PackageVersion Include="PosInformatique.Foundations.Emailing.Graph" Version="$(PosInformationFoundationsVersion)" />
<PackageVersion Include="PosInformatique.Foundations.Emailing.Templates.Razor" Version="$(PosInformationFoundationsVersion)" />
<PackageVersion Include="PosInformatique.Moq.Analyzers" Version="2.0.1" />
<PackageVersion Include="SonarAnalyzer.CSharp" Version="10.15.0.120848" />
<PackageVersion Include="PosInformatique.Moq.Analyzers" Version="2.1.0" />
<PackageVersion Include="SonarAnalyzer.CSharp" Version="10.27.0.140913" />
<PackageVersion Include="StyleCop.Analyzers" Version="1.2.0-beta.556" />
<PackageVersion Include="Verify.XunitV3" Version="31.7.1" />
<PackageVersion Include="xunit.v3" Version="3.2.0" />
<PackageVersion Include="xunit.runner.visualstudio" Version="3.1.5" />
<PackageVersion Include="Verify.XunitV3" Version="31.20.0" />
<PackageVersion Include="xunit.v3.mtp-v2" Version="3.2.2" />
</ItemGroup>
</Project>
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
<File Path=".editorconfig" />
<File Path=".gitattributes" />
<File Path=".gitignore" />
<File Path="CodeCoverage.runsettings" />
<File Path="Directory.Build.props" />
<File Path="Directory.Packages.props" />
<File Path="global.json" />
Expand Down
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,8 @@ To send the e-mail using Graph API:

### Configuration

- `APPLICATIONINSIGHTS_CONNECTION_STRING`:
Application Insights connection string to enable telemetry.
- `APP_SECRET_WATCHER_CLIENT_ID`:
Client ID of the App Registration used to query secrets across tenants. If omitted, the Function managed identity is used (single-tenant only).
- `APP_SECRET_WATCHER_CLIENT_SECRET`:
Expand Down Expand Up @@ -115,5 +117,5 @@ to send mail via Graph withb the `Mail.Send` application permission.
- Ensure recipients are a monitored distribution list or shared mailbox to avoid missed alerts.

## Compatibility
- .NET: 9.0
- .NET: 10.0
- Azure Functions: Isolated v4
5 changes: 4 additions & 1 deletion global.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
{
"sdk": {
"version": "9.0.305",
"version": "10.0.301",
"rollForward": "latestFeature"
},
"test": {
"runner": "Microsoft.Testing.Platform"
}
}
2 changes: 1 addition & 1 deletion src/Core/EntraId/GraphServiceClientFactory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ public GraphServiceClient Create(string tenantId)

if (this.options.ClientId is null)
{
credential = new ManagedIdentityCredential();
credential = new ManagedIdentityCredential(new ManagedIdentityCredentialOptions());
}
else
{
Expand Down
2 changes: 1 addition & 1 deletion src/Directory.Build.props
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<Import Project="$([MSBuild]::GetPathOfFileAbove('Directory.Build.props', '$(MSBuildThisFileDirectory)../'))" />

<PropertyGroup>
<TargetFramework>net9.0</TargetFramework>
<TargetFramework>net10.0</TargetFramework>
<Nullable>enable</Nullable>
</PropertyGroup>

Expand Down
7 changes: 5 additions & 2 deletions src/Functions/AppRegistrationSecretWatcherApplication.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,10 @@ namespace PosInformatique.Azure.Identity.AppRegistrationSecretWatcher.Functions
{
using System.Globalization;
using global::Azure.Identity;
using global::Azure.Monitor.OpenTelemetry.Exporter;
using Microsoft.Azure.Functions.Worker;
using Microsoft.Azure.Functions.Worker.Builder;
using Microsoft.Azure.Functions.Worker.OpenTelemetry;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using PosInformatique.Azure.Identity.AppRegistrationSecretWatcher.Emailing;
Expand Down Expand Up @@ -105,8 +107,9 @@ public static async Task Main(string[] args)

// Add Application Insights
builder.Services
.AddApplicationInsightsTelemetryWorkerService()
.ConfigureFunctionsApplicationInsights();
.AddOpenTelemetry()
.UseFunctionsWorkerDefaults()
.UseAzureMonitorExporter();

// Emailing
builder.Services.AddEmailing(opt =>
Expand Down
4 changes: 2 additions & 2 deletions src/Functions/Functions.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,11 @@

<ItemGroup>
<FrameworkReference Include="Microsoft.AspNetCore.App" />
<PackageReference Include="Microsoft.ApplicationInsights.WorkerService" />
<PackageReference Include="Azure.Monitor.OpenTelemetry.AspNetCore" />
<PackageReference Include="Microsoft.Azure.Functions.Worker" />
<PackageReference Include="Microsoft.Azure.Functions.Worker.ApplicationInsights" />
<PackageReference Include="Microsoft.Azure.Functions.Worker.Extensions.Http.AspNetCore" />
<PackageReference Include="Microsoft.Azure.Functions.Worker.Extensions.Timer" />
<PackageReference Include="Microsoft.Azure.Functions.Worker.OpenTelemetry" />
<PackageReference Include="Microsoft.Azure.Functions.Worker.Sdk" />
<PackageReference Include="PosInformatique.Foundations.Emailing.Graph" />
</ItemGroup>
Expand Down
6 changes: 3 additions & 3 deletions tests/Core.Tests/Emailing/RazorTemplateTools.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ namespace PosInformatique

public static class RazorTemplateTools
{
/*public static void DisplayHtmlPage(string content, string testName)
public static void DisplayHtmlPage(string content, string testName)
{
if (!Debugger.IsAttached)
{
Expand All @@ -37,7 +37,7 @@ public static class RazorTemplateTools
FileName = temporaryFile,
UseShellExecute = true,
});
}*/
}

public static async Task<string> RenderAsync<TComponent>(object model, IServiceCollection services)
where TComponent : ComponentBase
Expand Down Expand Up @@ -67,4 +67,4 @@ public static async Task<string> RenderAsync<TComponent>(object model, IServiceC
return output.ToString();
}
}
}
}
38 changes: 38 additions & 0 deletions tests/Core.Tests/UnitTestsFolders.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
//-----------------------------------------------------------------------
// <copyright file="UnitTestsFolders.cs" company="P.O.S Informatique">
// Copyright (c) P.O.S Informatique. All rights reserved.
// </copyright>
//-----------------------------------------------------------------------

namespace PosInformatique
{
internal static class UnitTestsFolders
{
static UnitTestsFolders()
{
SolutionRoot = GetSolutionRootPath();
TemporaryRoot = Path.Combine(SolutionRoot, "tmp");
}

public static string TemporaryRoot { get; }

private static string SolutionRoot { get; }

private static string GetSolutionRootPath()
{
var directory = new DirectoryInfo("./");

while (directory is not null && !directory.EnumerateFiles("PosInformatique.Azure.Identity.AppRegistrationSecretWatcher.slnx").Any())
{
directory = directory.Parent;
}

if (directory is null)
{
throw new DirectoryNotFoundException("Unable to find the PosInformatique.Azure.Identity.AppRegistrationSecretWatcher solution root path.");
}

return directory.FullName;
}
}
}
22 changes: 10 additions & 12 deletions tests/Directory.Build.props
Original file line number Diff line number Diff line change
Expand Up @@ -5,27 +5,25 @@

<!-- Common NuGet packages -->
<ItemGroup>
<PackageReference Include="coverlet.collector">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="FluentAssertions" />
<PackageReference Include="Microsoft.NET.Test.Sdk" />
<PackageReference Include="Microsoft.Testing.Extensions.CodeCoverage"/>
<PackageReference Include="Microsoft.Testing.Extensions.TrxReport"/>
<PackageReference Include="Moq"/>
<PackageReference Include="PosInformatique.Moq.Analyzers">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
</PackageReference>
<PackageReference Include="xunit.runner.visualstudio">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="xunit.v3" />
<PackageReference Include="xunit.v3.mtp-v2" />
</ItemGroup>

<PropertyGroup>
<TargetFramework>net9.0</TargetFramework>

<TargetFramework>net10.0</TargetFramework>

<!-- Required by XUnit v3 -->
<OutputType>Exe</OutputType>
<UseMicrosoftTestingPlatformRunner>true</UseMicrosoftTestingPlatformRunner>
<EnableVSTestRunner>false</EnableVSTestRunner>

<!-- Disable the StyleCop 'XML comment analysis is disabled due to project configuration' warning. -->
<NoWarn>$(NoWarn);SA0001</NoWarn>
</PropertyGroup>
Expand Down
Loading