GitVersion

June 30, 2026 · View on GitHub

This file provides repo-specific guidance for AI coding agents (e.g. Claude Code, Codex, Copilot Workspace).

Project overview

GitVersion is a multi-project .NET repository that calculates semantic versions from Git history. Primary source code lives under src/. CLI examples and documentation live under docs/.

Key files

  • README.md — project overview and links to documentation
  • global.json — SDK version pin (.NET 10) and solution roots (build, new-cli, src)
  • build.ps1 — primary build entry point (Cake-based); day-to-day work uses dotnet CLI directly
  • src/Directory.Packages.props — central NuGet package versioning (edit here, not in individual csproj files)
  • src/GitVersion.slnx — main solution file
  • docs/ — CLI usage examples and I/O patterns (JSON stdout, environment outputs)
  • src/GitVersion.Configuration/ConfigurationFileLocator.cs — config file lookup logic

Architecture

The repo has two parallel solution trees:

src/ — legacy/stable CLI

ProjectRole
GitVersion.CoreCore version calculation logic
GitVersion.ConfigurationConfiguration loading and validation
GitVersion.AppCLI entry point
GitVersion.BuildAgentsPlatform-specific build agent adapters
GitVersion.LibGit2SharpGit repository access
*Tests projectsUnit and integration tests

Build-agent adapters live in src/GitVersion.BuildAgents/Agents/. They write GitVersion_-prefixed environment variables — preserve that prefix when reading or writing outputs.

new-cli/ — new CLI (actively developed, new-cli/GitVersion.slnx)

ProjectRole
GitVersion.CliNew CLI entry point
GitVersion.CoreCore version calculation (new-cli variant)
GitVersion.CalculationVersion calculation plugin
GitVersion.ConfigurationConfiguration plugin
GitVersion.NormalizationNormalization plugin
GitVersion.OutputOutput plugin
GitVersion.CommonShared utilities
GitVersion.Core.Libgit2SharpGit repository access
GitVersion.Cli.GeneratorSource generator for CLI commands
GitVersion.Cli.Generator.TestsGenerator tests

The new-cli/ tree has its own Directory.Packages.props for centralized package versions.

Developer commands

# --- src/ (legacy CLI) ---

# Build the solution
dotnet build ./src/GitVersion.slnx

# Run all tests
dotnet test ./src/GitVersion.slnx

# Run tests for a single project
dotnet test --project ./src/GitVersion.Core.Tests/GitVersion.Core.Tests.csproj

# Run the legacy CLI locally
dotnet run --project src/GitVersion.App

# Format code
dotnet format ./src/GitVersion.slnx

# Verify formatting (CI-friendly, non-zero exit if changes needed)
dotnet format --verify-no-changes ./src/GitVersion.slnx

# --- new-cli/ (new CLI) ---

# Build the new CLI solution
dotnet build ./new-cli/GitVersion.slnx

# Run tests for the new CLI
dotnet test ./new-cli/GitVersion.slnx

# Run the new CLI locally
dotnet run --project new-cli/GitVersion.Cli

Conventions

  • SDK / TFM: .NET 10 (global.json); most projects target net10.0.
  • C# version: LangVersion=latest (C# 14). Prefer new syntax where it improves clarity:
    • field keyword — access auto-property backing field inside the property body instead of a manual backing field
    • Extension members — use the new extension(Type t) { } block syntax for extension methods/properties
    • Null-conditional assignment — x?.Property = value
    • params collections — params now works with any collection type, not just arrays
    • Partial properties — analogous to partial methods for source generators
  • Package versions: update src/Directory.Packages.props, not individual csproj files. Add packages via dotnet add package <Package> --version <Version>.
  • Config file names: GitVersion.yml, GitVersion.yaml, .GitVersion.yml, .GitVersion.yaml — use these names or pass --configfile.
  • Code style: .editorconfig defines style; run dotnet format to apply.
  • Commit style: prefer atomic commits; rebase onto main rather than merging.
  • Tests: integration tests live in src/GitVersion.Core.Tests/IntegrationTests/. Use EmptyRepositoryFixture / BaseGitFlowRepositoryFixture and builder patterns (GitFlowConfigurationBuilder, GitHubFlowConfigurationBuilder).

Release process

Cutting a release (milestone setup, label validation, creating the GitHub release, monitoring downstream publish PRs for Homebrew/winget/GitTools Actions, and verifying published artifacts on NuGet/Docker/Chocolatey) is documented step-by-step in .agents/skills/release/SKILL.md — read that file in full before doing any release work, and follow its phases in order rather than improvising. It's also symlinked at .claude/skills/release for tool discovery, and summarized for humans in CONTRIBUTING.md. It requires the gh CLI authenticated (gh auth login).

Tips

  • For gh commands, set GH_PAGER=cat GH_FORCE_TTY=0 to avoid pager/TTY issues in non-interactive terminals.

What to check when changing behavior

  • CLI output shape changed → update docs/ examples and build-agent adapters that parse JSON or env vars.

  • New dependency added → update src/Directory.Packages.props and verify with dotnet build.

  • Configuration schema changed → regenerate schemas:

    ./build.ps1 -Stage build -Target BuildPrepare
    ./build.ps1 -Stage docs -Target GenerateSchemas
    

Testing guidance

Most relevant tests are in src/GitVersion.Core.Tests/IntegrationTests/. There is a scenario class per branch type (e.g. MainScenarios, FeatureBranchScenarios). Use fixture.AssertFullSemver("x.y.z-label.n", configuration) to assert calculated versions.

using var fixture = new EmptyRepositoryFixture();
fixture.Repository.MakeATaggedCommit("1.0.0");
fixture.Repository.CreateBranch("feature/my-feature");
fixture.Checkout("feature/my-feature");  // use fixture.Checkout(), not fixture.Repository.Checkout()
fixture.Repository.MakeACommit();

var configuration = GitFlowConfigurationBuilder.New.Build();
fixture.AssertFullSemver("1.0.1-my-feature.1", configuration);