Bennewitz.Ninja.AutoVersioning by Brian Bennewitz
NuGet / site data
Details
Info
Name: Bennewitz.Ninja.AutoVersioning
Assembly info incremental source generator.
Author: Brian Bennewitz
NuGet: https://www.nuget.org/packages/Bennewitz.Ninja.AutoVersioning/
You can find more details at https://github.com/JanusMael/Bennewitz.Ninja.AutoVersioning
Source: https://github.com/JanusMael/Bennewitz.Ninja.AutoVersioning
Author
Brian Bennewitz

Original Readme
Bennewitz.Ninja.AutoVersioning
A Roslyn incremental source generator that injects assembly metadata attributes and build-time constants into .NET projects at compile time — no AssemblyInfo.cs, no disk writes, full IDE caching.
Requirements
.NET SDK 6.0 or later (requires Roslyn 4.0+ for IIncrementalGenerator support). The consuming project may target any framework — .NET Framework 4.x, .NET Standard, .NET 6+, etc.
Quick Start
1. Add the package:
<PackageReference Include="Bennewitz.Ninja.AutoVersioning" Version="x.x.x" />
2. Enable the generator in your root Directory.Build.props (or any .props / .csproj imported by your build):
<PropertyGroup>
<GenerateAutoVersionedAssemblyInfo>true</GenerateAutoVersionedAssemblyInfo>
<AssemblyCompany>YourCompany</AssemblyCompany>
<AssemblyProduct>YourProduct</AssemblyProduct>
<!-- Optional: map your CI provider's variables -->
<CommitSha Condition="'$(CommitSha)' == ''">$(GITHUB_SHA)</CommitSha>
<IsContinuousIntegration>$(GITHUB_ACTIONS)</IsContinuousIntegration>
<PublicVersion Condition="'$(PublicVersion)' == ''">$(MY_VERSION_VAR)</PublicVersion>
</PropertyGroup>
Note: The package's auto-imported
Build.propsautomatically suppresses the 8 SDK-generated attributes that conflict with this generator (e.g.AssemblyVersion,AssemblyCopyright). It uses granular per-attribute suppressions rather than<GenerateAssemblyInfo>false</GenerateAssemblyInfo>, which meansInternalsVisibleToand all other SDK-generated attributes continue to work normally. Do not add<GenerateAssemblyInfo>false</GenerateAssemblyInfo>yourself — it will breakInternalsVisibleTo.
A ready-to-use template is available at Directory.Build.props.template.
3. Build. The generator runs automatically — no further setup needed.
Tip: View the generated files in your IDE under
Dependencies → Analyzers → *SourceGenerators.
Generated Output
Given a build on 2026-04-29 at 14:35 UTC for company Acme Corp, product Acme App, commit abc1234def, and public version 3.1.0:
######### AutoVersionedAssemblyInfo.g.cs
using System.Reflection;
using System.Runtime.CompilerServices;
[assembly: AssemblyDescription("Assembly Version: 2026.2.429.1435")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyCompany("Acme Corp")]
[assembly: AssemblyProduct("Acme App v2026.2.429.1435")]
[assembly: AssemblyCopyright("Copyright 2026 [Release]")]
[assembly: AssemblyVersion("2026.2.429.1435")]
[assembly: AssemblyFileVersion("2026.2.429.1435")]
[assembly: AssemblyInformationalVersion("Commit♥: abc1234def")]
[assembly: AssemblyMetadata("CommitSha", "abc1234def")]
[assembly: AssemblyMetadata("GITHUB_SHA", "abc1234def")]
[assembly: AssemblyMetadata("PublicVersion", "3.1.0")]
######### DirectoryBuildInfo.g.cs
// <auto-generated/>
namespace Bennewitz.Ninja.AutoVersioning
{
/// <summary>Build-time constants generated by the source generator.</summary>
public static class DirectoryBuildInfo
{
public const string BuildRelease = "Version 2026.2.429.1435 [built 4/29/2026 2:35:00 PM (UTC)]";
}
}
Use DirectoryBuildInfo.BuildRelease wherever you need the build version at runtime — error trackers, log enrichment, health endpoints — without reading environment variables.
Configuration Reference
| MSBuild Property | Description | Required |
|---|---|---|
GenerateAutoVersionedAssemblyInfo | Set to true to enable the generator | Yes |
AssemblyCompany | Value for [assembly: AssemblyCompany(...)] | Yes |
AssemblyProduct | Value for [assembly: AssemblyProduct(...)] | Yes |
CopyrightHolder | Name shown in the copyright attribute — defaults to AssemblyCompany if omitted | No |
CommitSha | Git commit SHA | No |
IsContinuousIntegration | true on CI runs | No |
PublicVersion | Your app's public-facing version string | No |
Configuration | Debug / Release — set automatically by MSBuild | Auto |
BuildTimestamp | Build start time in yyyyMMddHHmmss format — captured automatically at MSBuild evaluation time (before any project compiles), ensuring a consistent version across all projects in a multi-project solution build. Override on CI for an exact guarantee: dotnet build -p:BuildTimestamp=$(date +%Y%m%d%H%M%S) | Auto |
######### CI Provider Mappings
| Provider | Commit SHA | CI flag |
|---|---|---|
| GitHub Actions | $(GITHUB_SHA) | $(GITHUB_ACTIONS) |
| GitLab CI | $(CI_COMMIT_SHA) | $(GITLAB_CI) |
| Bitbucket Pipelines | $(BITBUCKET_COMMIT) | $(CI) |
######### Version Format
The generator uses CalVer: YEAR.QUARTER.MMDD.HHmm
| Part | Example | Meaning |
|---|---|---|
| Major | 2026 | Calendar year |
| Minor | 2 | Quarter (1–4) |
| Build | 429 | Month + day (MMdd as integer) |
| Revision | 1435 | Hour + minute (HHmm as integer) |
How It Works
This is a modern C# IIncrementalGenerator. Compared to legacy ISourceGenerator approaches it:
- Runs entirely in-memory — zero files written to disk
- Uses the Roslyn caching pipeline — the IDE (Rider, Visual Studio) only re-runs the generator when its inputs change, eliminating background compilation loops
- Reads MSBuild properties via
AnalyzerConfigOptionsProvider— safe, no direct environment variable reads
The package auto-imports Build.props via NuGet, which declares CompilerVisibleProperty items and suppresses the SDK's default AssemblyInfo generation (preventing CS0579 duplicate attribute errors when the generator is enabled).
######### Timestamp Consistency in Multi-Project Builds
BuildTimestamp keeps the version consistent across every project in a solution build. See docs/MultiProjectBuildTimestamps.md for how it works and what alternative approaches were considered.
TL;DR: For CI, or any local build where an exact guarantee matters more than convenience, use
-p:BuildTimestamp=...to fix the value explicitly instead of relying on evaluation-time capture. Ready-to-use wrappers are available atBuild.ps1.template(Windows/PowerShell 7+) andBuild.sh.template(Linux/macOS/bash).
######### Diagnostics
| ID | Severity | Description |
|---|---|---|
BAUTOVERSIONING00 | Warning | Generator is installed but GenerateAutoVersionedAssemblyInfo is not set to true (single-line signal) |
BAUTOVERSIONING01 | Warning | Generator threw an unexpected exception |
BAUTOVERSIONING02 | Error | AssemblyCompany is not configured |
BAUTOVERSIONING03 | Error | AssemblyProduct is not configured |
BAUTOVERSIONING04 | Warning | Multi-line setup snippet emitted alongside BAUTOVERSIONING00 — shows the required Directory.Build.props configuration |
Building Locally
Requires PowerShell 7+ and the .NET SDK.
./Pack.ps1
The script prompts for a version (defaults to CalVer YYYY.Q.MMDD) and produces .nupkg files in packages/Debug/ and packages/Release/.
License
MIT © 2026 Brian Bennewitz
About
Generating build version numbers for .NET projects
How to use
Example (source csproj, source files)
- CSharp Project
- Program.cs
This is the CSharp Project that references Bennewitz.Ninja.AutoVersioning
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net10.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Bennewitz.Ninja.AutoVersioning" Version="2026.3.701">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
</ItemGroup>
<PropertyGroup>
<GenerateAutoVersionedAssemblyInfo>true</GenerateAutoVersionedAssemblyInfo>
<!-- Prevents CS0579 duplicate attribute errors by suppressing only the 8 SDK-generated
attributes that this generator also emits. Using granular suppressions (rather than
GenerateAssemblyInfo=false) preserves other SDK-generated attributes such as
InternalsVisibleTo from MSBuild item groups.
NOTE: The NuGet package's auto-imported Build.props sets these automatically when
GenerateAutoVersionedAssemblyInfo=true. You only need these here if your build does
not pick up the auto-imported Build.props for some reason. -->
<GenerateAssemblyVersionAttribute>false</GenerateAssemblyVersionAttribute>
<GenerateAssemblyFileVersionAttribute>false</GenerateAssemblyFileVersionAttribute>
<GenerateAssemblyInformationalVersionAttribute>false</GenerateAssemblyInformationalVersionAttribute>
<GenerateAssemblyCompanyAttribute>false</GenerateAssemblyCompanyAttribute>
<GenerateAssemblyProductAttribute>false</GenerateAssemblyProductAttribute>
<GenerateAssemblyConfigurationAttribute>false</GenerateAssemblyConfigurationAttribute>
<GenerateAssemblyDescriptionAttribute>false</GenerateAssemblyDescriptionAttribute>
<GenerateAssemblyCopyrightAttribute>false</GenerateAssemblyCopyrightAttribute>
<AssemblyCompany>AOM Company</AssemblyCompany>
<AssemblyProduct>Andrei Ignat Product</AssemblyProduct>
<CommitSha Condition="'$(CommitSha)' == ''">$(GITHUB_SHA)</CommitSha>
<IsContinuousIntegration>$(GITHUB_ACTIONS)</IsContinuousIntegration>
<PublicVersion Condition="'$(PublicVersion)' == ''">$(MY_VERSION_VAR)</PublicVersion>
</PropertyGroup>
<PropertyGroup>
<EmitCompilerGeneratedFiles>true</EmitCompilerGeneratedFiles>
<CompilerGeneratedFilesOutputPath>$(BaseIntermediateOutputPath)\GX</CompilerGeneratedFilesOutputPath>
</PropertyGroup>
</Project>
This is the use of Bennewitz.Ninja.AutoVersioning in Program.cs
using Bennewitz.Ninja.AutoVersioning;
Console.WriteLine("Hello, World!");
Console.WriteLine(DirectoryBuildInfo.BuildRelease);
Generated Files
Those are taken from $(BaseIntermediateOutputPath)\GX
- AutoVersionedAssemblyInfo.g.cs
- DirectoryBuildInfo.g.cs
//------------------------------------------------------------------------------
// <auto-generated>
// This code was automatically generated by Andrei Ignat Product version 2026.3.716.1852;
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
using System.CodeDom.Compiler;
using System.Reflection;
using System.Runtime.CompilerServices;
[assembly: AssemblyDescription("Assembly Version: 2026.3.716.1852")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyCompany("AOM Company")]
[assembly: AssemblyProduct("Andrei Ignat Product v2026.3.716.1852")]
[assembly: AssemblyCopyright("Copyright 2026 [Debug]")]
[assembly: AssemblyVersion("2026.3.716.1852")]
[assembly: AssemblyFileVersion("2026.3.716.1852")]
[assembly: AssemblyInformationalVersion("Built with ♥")]
// <auto-generated/>
namespace Bennewitz.Ninja.AutoVersioning
{
/// <summary>
/// Build-time constants generated by the source generator.
/// </summary>
public static class DirectoryBuildInfo
{
/// <summary>The build version string calculated at compile time.</summary>
public const string BuildRelease = "Version 2026.3.716.1852 [built 7/16/2026 6:52:32 PM (GST)]";
}
}
Useful
Download Example (.NET C#)
Share Bennewitz.Ninja.AutoVersioning
https://ignatandrei.github.io/RSCG_Examples/v2/docs/Bennewitz.Ninja.AutoVersioning
Category "EnhancementProject" has the following generators:
1 AssemblyMetadata
2026-04-02
2 AssemblyMetadata.Generators
2026-05-15
3 AssemblyVersionInfo
2025-07-28
4 AutoInvoke.Generator
2024-03-03
5 AutoSpectre
2024-02-24
6 Bennewitz.Ninja.AutoVersioning
2026-07-04
7 BuildInfo
2024-01-20
8 Credfeto.Version.Information.Generator
2024-11-05
9 Larcanum.GitInfo
2025-01-17
10 LinqGen.Generator
2024-03-04
11 Pekspro.BuildInformationGenerator
2024-07-19
12 PlantUmlClassDiagramGenerator
2024-02-20
13 RSCG_AMS
2023-04-16
14 RSCG_ExportDiagram
2024-08-01
15 RSCG_FunctionsWithDI
2023-04-16
16 RSCG_NameGenerator
2024-08-25
17 RSCG_TimeBombComment
2023-04-16
18 RSCG_Wait
2024-02-21
19 ShadowWriterProjectInfo
2025-07-27
20 ThisAssembly
2023-04-16
21 ThisAssembly.Constants
2024-07-18
22 ThisAssembly.Metadata
2024-07-20