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
9 changes: 7 additions & 2 deletions .github/workflows/nuget-publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,11 @@ jobs:
with:
dotnet-version: "9.0.x"

- name: Setup .NET 10
uses: actions/setup-dotnet@v4
with:
dotnet-version: "10.0.x"

- name: Restore dependencies
run: dotnet restore

Expand All @@ -41,7 +46,7 @@ jobs:
run: dotnet test --configuration Release --no-build --verbosity normal

- name: Pack
run: dotnet pack --configuration Release --no-build --output ./nupkgs -p:IncludeSymbols=true -p:SymbolPackageFormat=snupkg
run: dotnet pack --configuration Release --output ./nupkgs -p:IncludeSymbols=true -p:SymbolPackageFormat=snupkg

- name: Publish
uses: actions/upload-artifact@v4
Expand All @@ -67,7 +72,7 @@ jobs:
- name: Setup .NET
uses: actions/setup-dotnet@v4
with:
dotnet-version: "9.0.x"
dotnet-version: "10.0.x"

- name: Publish to NuGet
run: |
Expand Down
6 changes: 3 additions & 3 deletions Directory.Build.props
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
<Authors>Peter Nylander</Authors>
<PackageLicenseFile>LICENSE</PackageLicenseFile>
<PackageReadmeFile>README.md</PackageReadmeFile>
<Copyright>Copyright © 2025 Peter Nylander </Copyright>
<Copyright>Copyright © $([System.DateTime]::Now.Year) Peter Nylander </Copyright>
</PropertyGroup>

<PropertyGroup>
Expand Down Expand Up @@ -49,8 +49,8 @@

<RepositoryType>git</RepositoryType>
<PublishRepositoryUrl>true</PublishRepositoryUrl>
<PackageProjectUrl>https://github.com/penyland/infinity-tomahawk</PackageProjectUrl>
<RepositoryUrl>https://github.com/penyland/infinity-tomahawk</RepositoryUrl>
<PackageProjectUrl>https://github.com/penyland/infinity-toolkit</PackageProjectUrl>
<RepositoryUrl>https://github.com/penyland/infinity-toolkit</RepositoryUrl>

</PropertyGroup>

Expand Down
5 changes: 2 additions & 3 deletions samples/AzureSample/AzureSample.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,8 @@
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="9.0.9" />
<PackageReference Include="Microsoft.OpenApi" Version="1.6.26" />
<PackageReference Include="Scalar.AspNetCore" Version="2.8.7" />
<PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="9.0.10" />
<PackageReference Include="Scalar.AspNetCore" Version="2.9.0" />
</ItemGroup>

<ItemGroup>
Expand Down
11 changes: 9 additions & 2 deletions samples/AzureSample/Program.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
using Azure.Identity;
using Infinity.Toolkit.Azure.Configuration;
using Infinity.Toolkit.Azure;
using Infinity.Toolkit.OpenApi;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Options;
Expand All @@ -9,7 +9,13 @@

builder.ConfigureAzureAppConfiguration(configureSettings: options =>
{
options.TokenCredential = new AzureCliCredential();
//options.TokenCredential = new VisualStudioCredential(new() { TenantId = "cf4e6228-1dc7-45f6-aa1c-71e47553e4ac" });
//options.TokenCredential = new AzureCliCredential(new() { TenantId = "cf4e6228-1dc7-45f6-aa1c-71e47553e4ac" });
//options.TokenCredential = new DefaultAzureCredential();
options.TokenCredential = new ChainedTokenCredential(
new AzureCliCredential(),
new VisualStudioCredential()
);
}, refreshOptions: refreshOptions =>
{
refreshOptions.SetRefreshInterval(TimeSpan.FromSeconds(15));
Expand Down Expand Up @@ -43,6 +49,7 @@
}

app.UseHttpsRedirection();
app.UseAzureAppConfiguration();

app.MapGet("/config", ([FromServices] IConfiguration configuration) =>
{
Expand Down
2 changes: 1 addition & 1 deletion samples/AzureSample/appsettings.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
"AppConfig": {
"ApplicationName": "",
"Endpoint": "",
"GlobalKeyFilter": "Global",
"GlobalKeyFilter": "",
"UseFeatureFlags": true
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="9.0.9" />
<PackageReference Include="Microsoft.OpenApi" Version="1.6.26" />
<PackageReference Include="Microsoft.OpenApi" Version="1.6.28" />
<PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="9.0.10" />
</ItemGroup>

<ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@
</ItemGroup>

<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="9.0.9" />
<PackageReference Include="Microsoft.OpenApi" Version="1.6.26" />
<PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="9.0.10" />
<PackageReference Include="Microsoft.OpenApi" Version="1.6.28" />
</ItemGroup>

</Project>
6 changes: 3 additions & 3 deletions samples/FeatureModulesSample/FeatureModulesSample.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="9.0.9" />
<PackageReference Include="Microsoft.OpenApi" Version="1.6.26" />
<PackageReference Include="Scalar.AspNetCore" Version="2.8.7" />
<PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="9.0.10" />
<PackageReference Include="Microsoft.OpenApi" Version="1.6.28" />
<PackageReference Include="Scalar.AspNetCore" Version="2.9.0" />
</ItemGroup>

<ItemGroup>
Expand Down
2 changes: 1 addition & 1 deletion samples/MediatorSample/MediatorSample.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="9.0.9" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="9.0.10" />
</ItemGroup>

<ItemGroup>
Expand Down
4 changes: 2 additions & 2 deletions samples/MessagingSample/MessagingSample.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="9.0.9" />
<PackageReference Include="Microsoft.OpenApi" Version="1.6.26" />
<PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="9.0.10" />
<PackageReference Include="Microsoft.OpenApi" Version="1.6.28" />
</ItemGroup>

<ItemGroup>
Expand Down
2 changes: 1 addition & 1 deletion samples/PipelineSample/PipelineSample.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="9.0.9" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="9.0.10" />
</ItemGroup>

<ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net9.0</TargetFramework>
<TargetFrameworks>net10.0;net9.0</TargetFrameworks>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<RootNamespace>Infinity.Toolkit.AspNetCore</RootNamespace>
<VersionPrefix>1.0.0</VersionPrefix>
<VersionPrefix>1.1.0</VersionPrefix>
</PropertyGroup>

<ItemGroup>
Expand All @@ -17,7 +17,7 @@
</ItemGroup>

<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="9.0.9" NoWarn="NU1605" />
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="9.0.10" NoWarn="NU1605" />
</ItemGroup>

<ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
using System.Data.Common;
using System.Text.Json.Serialization;

namespace Infinity.Toolkit.Azure.Configuration;
namespace Infinity.Toolkit.Azure;

// Config section specifications
//"Infinity": {
Expand All @@ -23,7 +23,7 @@ namespace Infinity.Toolkit.Azure.Configuration;

public class AzureAppConfigSettings
{
internal const string DefaultConfigSectionName = "Infinity:Azure:AppConfig";
internal const string DefaultConfigSectionName = "AzureAppConfiguration";

public string ApplicationName { get; set; }

Expand All @@ -33,10 +33,10 @@ public class AzureAppConfigSettings

public bool UseFeatureFlags { get; set; } = true;

public bool UseKeyVault { get; set; } = true;
public bool UseKeyVault { get; set; } = false;

[JsonIgnore]
public TokenCredential? TokenCredential { get; set; } = Identity.TokenCredentialHelper.GetTokenCredential();
public TokenCredential? TokenCredential { get; set; }

internal void ParseConnectionString(string? connectionString)
{
Expand Down Expand Up @@ -84,52 +84,63 @@ configuration section.

public static class ConfigurationBuilderExtensions
{
private const string DefaultConfigSectionName = "Infinity:Azure:AppConfig";

public static IHostApplicationBuilder ConfigureAzureAppConfiguration(this IHostApplicationBuilder builder)
=> builder.ConfigureAzureAppConfiguration(DefaultConfigSectionName, null, null);
=> builder.ConfigureAzureAppConfiguration(AzureAppConfigSettings.DefaultConfigSectionName, null, null);

public static IHostApplicationBuilder ConfigureAzureAppConfiguration(this IHostApplicationBuilder app, Action<AzureAppConfigSettings>? configure = null, Action<AzureAppConfigurationRefreshOptions>? refreshOptions = null)
=> app.ConfigureAzureAppConfiguration(DefaultConfigSectionName, configure, refreshOptions);
=> app.ConfigureAzureAppConfiguration(AzureAppConfigSettings.DefaultConfigSectionName, configure, refreshOptions);

public static IHostApplicationBuilder ConfigureAzureAppConfiguration(this IHostApplicationBuilder builder, string configSectionName = DefaultConfigSectionName, Action<AzureAppConfigSettings>? configureSettings = null, Action<AzureAppConfigurationRefreshOptions>? refreshOptions = null)
public static IHostApplicationBuilder ConfigureAzureAppConfiguration(this IHostApplicationBuilder builder, string configSectionName = AzureAppConfigSettings.DefaultConfigSectionName, Action<AzureAppConfigSettings>? configureSettings = null, Action<AzureAppConfigurationRefreshOptions>? refreshOptions = null)
{
ArgumentNullException.ThrowIfNull(builder, nameof(builder));
var settings = new AzureAppConfigSettings()
{
ApplicationName = builder.Environment.ApplicationName
ApplicationName = builder.Environment.ApplicationName,
TokenCredential = Identity.TokenCredentialHelper.GetTokenCredential()
};

builder.Configuration.GetSection(configSectionName).Bind(settings);
configureSettings?.Invoke(settings);

builder.Services.AddAzureAppConfiguration();

builder.Configuration.AddAzureAppConfiguration(options =>
{
if (builder.Configuration.GetConnectionString("AzureAppConfig") is string connectionString)
{
settings.ParseConnectionString(connectionString);
options.Connect(builder.Configuration.GetConnectionString("AzureAppConfig"));
options.Connect(connectionString);
}
else
{
if (Uri.TryCreate(settings.Endpoint.ToString(), UriKind.Absolute, out var endpointUri))
// Try to use configured endpoint
if (settings.Endpoint != null && Uri.TryCreate(settings.Endpoint.ToString(), UriKind.Absolute, out var endpointUri))
{
options.Connect(endpointUri, settings.TokenCredential);
// Endpoint from settings is valid
}
else
{
throw new InvalidOperationException($"""
The 'Endpoint' key in
'{configSectionName}') isn't a valid URI.
// Try to get endpoint from environment variable
var envEndpoint = Environment.GetEnvironmentVariable("AZURE_APP_CONFIG_ENDPOINT");
if (!Uri.TryCreate(envEndpoint, UriKind.Absolute, out endpointUri))
{
throw new InvalidOperationException($"""
ConnectionString is missing.
It should be provided in 'ConnectionStrings:AzureAppConfig'
or '{configSectionName}:Endpoint' key
configuration section or 'AZURE_APP_CONFIG_ENDPOINT' environment variable.
""");
}
}

options.Connect(endpointUri, settings.TokenCredential);
}

if (!string.IsNullOrEmpty(settings.GlobalKeyFilter))
{
// Filter by global key filter
options
.Select($"{settings.GlobalKeyFilter}*")
.Select($"{settings.GlobalKeyFilter}*", LabelFilter.Null)
.Select($"{settings.GlobalKeyFilter}*", builder.Environment.EnvironmentName)
.TrimKeyPrefix($"{settings.GlobalKeyFilter}:");
}
Expand All @@ -138,7 +149,7 @@ public static IHostApplicationBuilder ConfigureAzureAppConfiguration(this IHostA
{
// Filter by application name
options
.Select($"{settings.ApplicationName}*")
.Select($"{settings.ApplicationName}*", LabelFilter.Null)
.Select($"{settings.ApplicationName}*", builder.Environment.EnvironmentName)
.TrimKeyPrefix(settings.ApplicationName + ":");
}
Expand All @@ -162,7 +173,10 @@ public static IHostApplicationBuilder ConfigureAzureAppConfiguration(this IHostA
});
}

options.ConfigureRefresh(refreshOptions);
if (refreshOptions != null)
{
options.ConfigureRefresh(refreshOptions);
}
});

return builder;
Expand Down
14 changes: 14 additions & 0 deletions src/Infinity.Toolkit.Azure/EnvironmentHelper.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
namespace Infinity.Toolkit.Azure;

internal static class EnvironmentHelper
{
public static bool IsRunningInContainer => Equals(Environment.GetEnvironmentVariable("DOTNET_RUNNING_IN_CONTAINER"), "true");

public static bool IsRunningInAzureAppService => Equals(Environment.GetEnvironmentVariable("WEBSITE_SITE_NAME"), "true");

public static bool IsRunningInAzureContainerApps => IsRunningInContainer && !string.IsNullOrEmpty(Environment.GetEnvironmentVariable("CONTAINER_APP_NAME"));

public static bool IsRunningInAzureFunctions => !string.IsNullOrEmpty(Environment.GetEnvironmentVariable("FUNCTIONS_WORKER_RUNTIME"));

public static bool IsRunningInAzure => IsRunningInAzureAppService || IsRunningInAzureContainerApps || IsRunningInAzureFunctions;
}
Loading