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
14 changes: 12 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -38,17 +38,27 @@ jobs:
dotnet-quality: preview

- name: Restore
run: dotnet restore src/ConfigWay.Tests/ConfigWay.Tests.csproj
run: |
dotnet restore src/ConfigWay.Tests/ConfigWay.Tests.csproj
dotnet restore src/ConfigWay.FeatureManagement.Tests/ConfigWay.FeatureManagement.Tests.csproj

- name: Build
run: dotnet build src/ConfigWay.Tests/ConfigWay.Tests.csproj --no-restore --configuration Release
run: |
dotnet build src/ConfigWay.Tests/ConfigWay.Tests.csproj --no-restore --configuration Release
dotnet build src/ConfigWay.FeatureManagement.Tests/ConfigWay.FeatureManagement.Tests.csproj --no-restore --configuration Release

- name: Test
run: >
dotnet test src/ConfigWay.Tests/ConfigWay.Tests.csproj
--no-build --configuration Release
--logger "trx;LogFilePrefix=unit-results"

- name: Test feature flags
run: >
dotnet test src/ConfigWay.FeatureManagement.Tests/ConfigWay.FeatureManagement.Tests.csproj
--no-build --configuration Release
--logger "trx;LogFilePrefix=feature-flags-results"

- name: Upload test results
uses: actions/upload-artifact@v4
if: always()
Expand Down
14 changes: 12 additions & 2 deletions .github/workflows/deploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -39,17 +39,27 @@ jobs:
dotnet-quality: preview

- name: Restore
run: dotnet restore src/ConfigWay.Tests/ConfigWay.Tests.csproj
run: |
dotnet restore src/ConfigWay.Tests/ConfigWay.Tests.csproj
dotnet restore src/ConfigWay.FeatureManagement.Tests/ConfigWay.FeatureManagement.Tests.csproj

- name: Build
run: dotnet build src/ConfigWay.Tests/ConfigWay.Tests.csproj --no-restore --configuration Release
run: |
dotnet build src/ConfigWay.Tests/ConfigWay.Tests.csproj --no-restore --configuration Release
dotnet build src/ConfigWay.FeatureManagement.Tests/ConfigWay.FeatureManagement.Tests.csproj --no-restore --configuration Release

- name: Test
run: >
dotnet test src/ConfigWay.Tests/ConfigWay.Tests.csproj
--no-build --configuration Release
--logger "trx;LogFileName=unit-results.trx"

- name: Test feature flags
run: >
dotnet test src/ConfigWay.FeatureManagement.Tests/ConfigWay.FeatureManagement.Tests.csproj
--no-build --configuration Release
--logger "trx;LogFileName=feature-flags-results.trx"

test-postgres:
name: PostgreSQL Tests
runs-on: ubuntu-latest
Expand Down
7 changes: 7 additions & 0 deletions .github/workflows/publish-nuget.yml
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,9 @@ jobs:
dotnet build src/ConfigWay.SqlServer/ConfigWay.SqlServer.csproj \
--configuration Release \
-p:Version=${{ steps.version.outputs.VERSION }}
dotnet build src/ConfigWay.FeatureManagement/ConfigWay.FeatureManagement.csproj \
--configuration Release \
-p:Version=${{ steps.version.outputs.VERSION }}

- name: Pack
run: |
Expand All @@ -76,6 +79,10 @@ jobs:
--configuration Release --no-build \
-p:Version=${{ steps.version.outputs.VERSION }} \
--output ./nupkgs
dotnet pack src/ConfigWay.FeatureManagement/ConfigWay.FeatureManagement.csproj \
--configuration Release --no-build \
-p:Version=${{ steps.version.outputs.VERSION }} \
--output ./nupkgs

- name: Push to NuGet
run: |
Expand Down
61 changes: 59 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
[![CI](https://github.com/kododo-dev/ConfigWay/actions/workflows/ci.yml/badge.svg)](https://github.com/kododo-dev/ConfigWay/actions/workflows/ci.yml)
[![Demo](https://img.shields.io/badge/demo-live-brightgreen)](https://kododo.dev/configway/demo)

Runtime configuration editor for ASP.NET Core. View and modify `IOptions<T>` values at runtime through a built-in web UI without restarting the application.
Runtime configuration editor for ASP.NET Core. View and modify `IOptions<T>` values at runtime through a built-in web UI without restarting the application, and manage [feature flags](#feature-flags) the same way.

A live demo is available at [kododo.dev/configway/demo](https://kododo.dev/configway/demo).

Expand All @@ -15,6 +15,10 @@ A live demo is available at [kododo.dev/configway/demo](https://kododo.dev/confi

![Array editor](docs/screenshots/03-array-editor.png)

![Feature flags](docs/screenshots/04-feature-flags.png)

![Flag editor](docs/screenshots/05-flag-editor.png)

## Packages

| Package | NuGet | Description |
Expand All @@ -24,6 +28,7 @@ A live demo is available at [kododo.dev/configway/demo](https://kododo.dev/confi
| `Kododo.ConfigWay.UI` | [![NuGet](https://img.shields.io/nuget/v/Kododo.ConfigWay.UI)](https://www.nuget.org/packages/Kododo.ConfigWay.UI) | Embedded web UI |
| `Kododo.ConfigWay.PostgreSQL` | [![NuGet](https://img.shields.io/nuget/v/Kododo.ConfigWay.PostgreSQL)](https://www.nuget.org/packages/Kododo.ConfigWay.PostgreSQL) | PostgreSQL persistence store |
| `Kododo.ConfigWay.SqlServer` | [![NuGet](https://img.shields.io/nuget/v/Kododo.ConfigWay.SqlServer)](https://www.nuget.org/packages/Kododo.ConfigWay.SqlServer) | SQL Server persistence store |
| `Kododo.ConfigWay.FeatureManagement` | [![NuGet](https://img.shields.io/nuget/v/Kododo.ConfigWay.FeatureManagement)](https://www.nuget.org/packages/Kododo.ConfigWay.FeatureManagement) | Feature flags of Microsoft.FeatureManagement in the editor |

## Quick start

Expand Down Expand Up @@ -194,6 +199,44 @@ builder.Services.AddSingleton<IValidateOptions<EmailOptions>, EmailOptionsValida

Errors are shown in the UI and saving is blocked until they are resolved.

## Feature flags

`Kododo.ConfigWay.FeatureManagement` adds a Feature flags view to the editor. You can turn [Microsoft.FeatureManagement](https://learn.microsoft.com/azure/azure-app-configuration/feature-management-dotnet-reference) flags on and off, roll them out to users and groups, or limit them to a time window without redeploying. Your code keeps using `IFeatureManager`, `[FeatureGate]` and the other feature management APIs.

```bash
dotnet add package Kododo.ConfigWay.FeatureManagement
```

```csharp
builder.AddConfigWay(x =>
{
x.UsePostgreSql(connectionString);
x.AddUiEditor();
x.AddFeatureFlags();
});

builder.Services.AddFeatureManagement();
```

The view lists the flags from your configuration (the `feature_management` section of appsettings, environment variables and so on), including flags in the older `FeatureManagement` schema. You can also add flags that exist only in ConfigWay.

A flag saved in the editor is stored by ConfigWay and replaces the flag with the same id from your configuration. Resetting it brings the configured flag back. A flag that exists only in ConfigWay is deleted on reset.

| Filter | Editor |
|---|---|
| `Microsoft.Percentage` | Slider |
| `Microsoft.TimeWindow` | Start and end in your time zone, stored in UTC |
| `Microsoft.Targeting` | Users, groups with a percentage, default percentage, exclusions |
| Other filters | JSON parameters |

A filter that your application has not registered can't be saved, because checking the flag would throw.

Variants, allocation, telemetry and recurring time windows are kept when you save a flag, but you can't edit them yet.

To see how a flag evaluates for a user, enter the user and groups under "Check for a user". The check uses your application's feature manager.

The flag endpoints are part of the editor's API (`{path}/api`) and use the same authorization. If the app runs as several replicas, set [`ReloadInterval`](#several-replicas) so that a changed flag reaches all of them.

## Security

Outside the Development environment the editor and its API answer `403` until you decide who may use them:
Expand Down Expand Up @@ -226,9 +269,23 @@ app.UseWayShell("/admin").RequireAuthorization(); // every Way the user may op

> Use `IOptionsSnapshot<T>` or `IOptionsMonitor<T>` in your code to always get the latest values after a reload.

## Several replicas

A save reloads the configuration in the instance that handled it. When the app runs as several replicas sharing one store, let each of them check the store for changes:

```csharp
builder.AddConfigWay(x =>
{
x.UsePostgreSql(connectionString);
x.ReloadInterval = TimeSpan.FromSeconds(30);
});
```

Every 30 seconds each replica reads the store and reloads only when a setting was added, changed or removed, so the other replicas get a change within one interval. Without `ReloadInterval` they keep their values until a restart.

## Limitations

- Changes are reloaded only in the instance that saved them. When the app runs as several replicas, the other replicas pick up the new values after a restart.
- Without `ReloadInterval`, changes are reloaded only in the instance that saved them (see [Several replicas](#several-replicas)).
- Saves do not check for concurrent edits. If two people edit the same section at the same time, the last save wins.

## Custom store
Expand Down
Loading
Loading