BellaBaxter.SourceGenerator
0.1.1-preview.21
See the version list below for details.
dotnet add package BellaBaxter.SourceGenerator --version 0.1.1-preview.21
NuGet\Install-Package BellaBaxter.SourceGenerator -Version 0.1.1-preview.21
<PackageReference Include="BellaBaxter.SourceGenerator" Version="0.1.1-preview.21" />
<PackageVersion Include="BellaBaxter.SourceGenerator" Version="0.1.1-preview.21" />
<PackageReference Include="BellaBaxter.SourceGenerator" />
paket add BellaBaxter.SourceGenerator --version 0.1.1-preview.21
#r "nuget: BellaBaxter.SourceGenerator, 0.1.1-preview.21"
#:package BellaBaxter.SourceGenerator@0.1.1-preview.21
#addin nuget:?package=BellaBaxter.SourceGenerator&version=0.1.1-preview.21&prerelease
#tool nuget:?package=BellaBaxter.SourceGenerator&version=0.1.1-preview.21&prerelease
BellaBaxter.SourceGenerator
A Roslyn source generator + MSBuild task that gives your .NET project typed, compile-time access to your Bella secrets — with zero values stored in the binary.
How it works
BeforeBuild (MSBuild)
└── BellaSecretsManifestTask
→ GET /api/v1/projects/{slug}/environments/{slug}/secrets?keys-only=true
→ writes bella-secrets.manifest.json ← commit this for offline builds
Compile (Roslyn)
└── BellaSecretsSourceGenerator
→ reads bella-secrets.manifest.json (AdditionalFiles)
→ emits AppSecrets.g.cs ← auto-generated, never edited
Secret values are never stored anywhere. At runtime each property reads from Environment.GetEnvironmentVariable(). The generator only needs the key names and their types at build time.
Installation
<PackageReference Include="BellaBaxter.SourceGenerator" Version="0.1.0">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
Configuration
Add to your .csproj:
<PropertyGroup>
<BellaProject>my-project</BellaProject>
<BellaEnvironment>dev</BellaEnvironment>
<BellaApiUrl>https://bella.example.com</BellaApiUrl>
<BellaApiKey>$(BELLA_API_KEY)</BellaApiKey>
<BellaSecretsClassName>AppSecrets</BellaSecretsClassName>
<BellaSecretsNamespace>$(RootNamespace)</BellaSecretsNamespace>
<BellaManifestPath>$(ProjectDir)bella-secrets.manifest.json</BellaManifestPath>
<BellaSkipFetch>false</BellaSkipFetch>
</PropertyGroup>
Generated code
Given a project with secrets:
| Key | Type |
|---|---|
DATABASE_URL |
ConnectionString |
MAX_RETRIES |
Integer |
FEATURE_ENABLED |
Boolean |
SERVICE_URL |
Url |
The generator emits:
// <auto-generated>
// This file was generated by BellaBaxter.SourceGenerator.
// Project: my-project Environment: dev
// Do not edit this file manually.
// </auto-generated>
#nullable enable
namespace MyApp.Config
{
public sealed partial class AppSecrets
{
private static string _env(string key) =>
System.Environment.GetEnvironmentVariable(key)
?? throw new System.InvalidOperationException(
$"Required secret '{key}' is not set in the environment.");
public string DatabaseUrl => _env("DATABASE_URL");
public int MaxRetries => int.Parse(_env("MAX_RETRIES"));
public bool FeatureEnabled => string.Equals(_env("FEATURE_ENABLED"), "true", System.StringComparison.OrdinalIgnoreCase);
public System.Uri ServiceUrl => new System.Uri(_env("SERVICE_URL"));
}
}
Using the generated class
var secrets = new AppSecrets();
string connStr = secrets.DatabaseUrl; // string
int retries = secrets.MaxRetries; // int — already parsed
bool flag = secrets.FeatureEnabled; // bool — already parsed
Uri svcUrl = secrets.ServiceUrl; // Uri — already parsed
If a required environment variable is missing at runtime, InvalidOperationException is thrown with a clear message.
Offline / CI builds
Commit bella-secrets.manifest.json to your repository:
# Generate or update the manifest locally
BELLA_API_KEY=... dotnet build /p:BellaSkipFetch=false
git add bella-secrets.manifest.json
git commit -m "chore: update bella secrets manifest"
CI can then build without Bella credentials:
# No BELLA_API_KEY needed — uses committed manifest
- run: dotnet build /p:BellaSkipFetch=true
If BellaApiKey is absent the manifest fetch is skipped automatically.
If the API is unreachable but a cached manifest exists, a build warning is emitted and the cached copy is used.
If neither a key nor a manifest is available, the build fails with a diagnostic error.
Manifest format
{
"version": "1",
"project": "my-project",
"environment": "dev",
"fetchedAt": "2026-03-01T12:00:00Z",
"secrets": [
{ "key": "DATABASE_URL", "type": "ConnectionString", "description": "Postgres connection" },
{ "key": "MAX_RETRIES", "type": "Integer" },
{ "key": "FEATURE_ENABLED","type": "Boolean" }
]
}
Type mappings
| Bella type | C# type | Getter expression |
|---|---|---|
String |
string |
direct |
Integer |
int |
int.Parse(...) |
Float |
double |
double.Parse(..., InvariantCulture) |
Boolean |
bool |
string.Equals(..., "true", OrdinalIgnoreCase) |
Guid |
System.Guid |
Guid.Parse(...) |
Url |
System.Uri |
new Uri(...) |
Base64 |
byte[] |
Convert.FromBase64String(...) |
Json |
string |
direct |
ConnectionString |
string |
direct |
CertificatePem |
string |
direct |
Diagnostic codes
| Code | Severity | Meaning |
|---|---|---|
BELLA001 |
Error | bella-secrets.manifest.json could not be parsed |
BELLA002 |
Warning | Manifest is present but contains no secrets |
BELLA003 |
Warning | API unreachable — using cached manifest |
BELLA004 |
Error | API unreachable and no manifest exists |
Project layout
apps/sdk/dotnet/
├── BellaBaxter.SourceGenerator/ # netstandard2.0 — Roslyn IIncrementalGenerator
│ ├── BellaSecretsSourceGenerator.cs
│ ├── ManifestParser.cs
│ ├── SecretsManifest.cs
│ ├── TypeMapper.cs
│ ├── CodeEmitter.cs
│ └── DiagnosticDescriptors.cs
├── BellaBaxter.SourceGenerator.MSBuild/ # net8.0 — MSBuild Task + .targets file
│ ├── BellaSecretsManifestTask.cs
│ └── BellaBaxter.SourceGenerator.targets
└── BellaBaxter.SourceGenerator.Tests/ # xUnit tests
├── ManifestParserTests.cs
├── TypeMapperTests.cs
└── CodeEmitterTests.cs
Learn more about Target Frameworks and .NET Standard.
-
.NETStandard 2.0
- No dependencies.
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 0.1.1-preview.36 | 34 | 3/30/2026 |
| 0.1.1-preview.35 | 32 | 3/30/2026 |
| 0.1.1-preview.34 | 33 | 3/30/2026 |
| 0.1.1-preview.33 | 29 | 3/30/2026 |
| 0.1.1-preview.32 | 38 | 3/30/2026 |
| 0.1.1-preview.31 | 35 | 3/30/2026 |
| 0.1.1-preview.30 | 44 | 3/27/2026 |
| 0.1.1-preview.29 | 38 | 3/27/2026 |
| 0.1.1-preview.28 | 28 | 3/27/2026 |
| 0.1.1-preview.27 | 36 | 3/27/2026 |
| 0.1.1-preview.26 | 35 | 3/26/2026 |
| 0.1.1-preview.23 | 40 | 3/26/2026 |
| 0.1.1-preview.22 | 29 | 3/26/2026 |
| 0.1.1-preview.21 | 37 | 3/26/2026 |
| 0.1.1-preview.20 | 33 | 3/26/2026 |
| 0.1.1-preview.19 | 36 | 3/26/2026 |
| 0.1.1-preview.18 | 34 | 3/26/2026 |
| 0.1.1-preview.17 | 36 | 3/25/2026 |
| 0.1.1-preview.16 | 34 | 3/25/2026 |
| 0.1.1-preview.15 | 30 | 3/25/2026 |