Nerdbank.GitVersioning

repository·main·Indexed 23 days ago

https://github.com/dotnet/nerdbank.gitversioning

A toolset for generating unique, semver-compatible version numbers for assemblies and packages based on git commit history and a central version.json configuration file. It provides integration for MSBuild, Cake build scripts, Gulp tasks, and a CLI tool (nbgv) for repository setup, version translation, and stamping NPM package.json files.

Tokens
14.8K
Snippets
42
Records
83
Agent score
81%

What's inside Nerdbank.GitVersioning

  1. Overview of Nerdbank.GitVersioning

    main

    Nerdbank.GitVersioning is a package that injects precise, SemVer-compatible Git commit information into assemblies, VSIX, NuGet, and NPM packages.

    Key characteristics include:

    • Build Reproducibility: Every commit can be built to produce a unique, predictable version.
    • Tag-Independent: Does not rely on Git tags, which can be unreliable in certain CI environments or clones.
    • Branch-Independent: Does not rely on branch names, ensuring builds remain identical regardless of which branch the HEAD is attached to.
    • Version Calculation: Versions are computed using an author-defined major.minor version, an optional unstable tag, and a shortened Git commit ID.
    • CI/CD Compatibility: Works implicitly with all cloud build services and CI servers by using Git directly and integrating with MSBuild, gulp, and other build scripts.
  2. Understand 'git height' in versioning

    main

    'Git height' is a core concept used to determine the PATCH version component in Nerdbank.GitVersioning. It represents the number of commits in the longest path from HEAD to the commit that established the current major.minor version.

    Key behaviors:

    • Minimum value: The minimum git height is 1 (when HEAD is the commit that changed the version).
    • Incrementing: The height increases with each commit, ensuring that the PATCH version component is always increasing and alphanumerically sortable.
    • Resetting: The height automatically resets to 1 whenever the major or minor version numbers are incremented.
  3. Configure versioning with version.json

    main

    Versioning is controlled via a version.json file. This file allows you to define:

    • The base major.minor version number.
    • An optional unstable tag.
    • The placement for the git 'height' incrementing integer.
    • Prerelease label identifiers.

    By using this file instead of git tags or branch names, you ensure that the computed version is based on the commit history relative to your defined base version.

  4. Understand the difference between Public and Stable releases

    main

    Nerdbank.GitVersioning distinguishes between SemVer stability and Public release status:

    1. SemVer Stability: Defined by the presence of a hyphenated suffix (e.g., 1.2.0-beta). This indicates the software might be functionally unstable or have an unfinalized API.
    2. Public Release: A version intended for public consumption that participates in a linear history. A public release does not include a git commit hash suffix (e.g., -gc0ffee).

    In short: A version can be stable according to SemVer but not be a 'public release' if it is built on a topic branch (in which case it will receive a commit hash suffix).

  5. Understand the generated Assembly attributes

    main

    During the build process, Nerdbank.GitVersioning automatically injects assembly attributes into your compilation. These attributes define the versioning metadata for your .NET assemblies.

    Key attributes include:

    • System.Reflection.AssemblyVersion: Typically uses the major and minor components from your version file.
    • System.Reflection.AssemblyFileVersion: Includes the major, minor, and the git history height (e.g., 1.0.24.15136).
    • System.Reflection.AssemblyInformationalVersion: A full semantic version string that includes pre-release tags (like -alpha) and the git commit metadata (e.g., 1.0.24-alpha+g9a7eb6c819).

    Version Component Breakdown:

    • Major/Minor: Defined in your version file.
    • Height: The third integer component represents the height of your git history, ensuring it increases reliably with each release.
    • Commit ID Hash: The fourth component (if present) is the first two bytes of the git commit ID encoded as an integer. This is used to distinguish between commits that share the same major.minor.height version.
    • Pre-release Tag: Derived from the version file (e.g., -alpha).
    • Git Metadata: The -g<commit_id> suffix is the concatenation of -g and the git commit ID used for the build.
    [assembly: System.Reflection.AssemblyVersion("1.0")]
    [assembly: System.Reflection.AssemblyFileVersion("1.0.24.15136")]
    [assembly: System.Reflection.AssemblyInformationalVersion("1.0.24-alpha+g9a7eb6c819")]
  6. Understand the difference between prerelease and public release version formats

    main

    The version format changes depending on whether the build is considered a prerelease or a public release:

    • Prerelease versions: Include the git commit ID as a suffix (prefixed with g). Example: 1.0.24-alpha-g9a7eb6c819.
    • Public releases: The git commit ID is dropped to create a clean version number. Example: 1.0.24-alpha.

    For more details on how to distinguish between these states, see public-vs-stable.md.

  7. Configure version.json placement and lifecycle

    main

    The version.json file is the source of truth for version generation.

    • Scope: For packages.config clients, the file is created in the project directory. To apply the same version number to all projects in a repository, move the version.json file to the root directory of your git repo.
    • Lifecycle Requirement: After the first installation, you must commit the version.json file to your repository before building. If you build before committing, the generated version number will be 0.0.x instead of the intended version.
    • Automatic Generation: If no version.json or version.txt exists, the installation scripts attempt to parse the Major.Minor version from the AssemblyVersion attribute in your Properties\AssemblyInfo.cs to create a compatible version.json.
  8. How version calculation works in Nerdbank.GitVersioning

    main

    Nerdbank.GitVersioning calculates a version number using three primary inputs:

    1. version.json: The base version configuration.
    2. Git 'height': A counter representing the number of version-incrementing commits since the last version change.
    3. Git commit ID: The specific hash of the current commit.

    You can optionally configure the git 'height' to only increment for commits that affect specific file paths (see path-filters.md).

  9. Understand Path Filters in Monorepos

    main

    In a monorepo (a repository containing multiple projects), GitVersioning's default behavior is to bump the version of every project whenever any file in the repository changes.

    Path filters solve this by allowing you to specify which subtrees or files should trigger a version bump for a specific project. When a version.json file includes a pathFilters array, only commits affecting those paths will cause that project's version height to increase.

    If pathFilters is absent, the default behavior is [":/"], meaning the entire repository is considered for version calculations.

  10. Translate between versions and git commits

    main

    To manually translate between a version number and a git commit, use the nbgv CLI tool with the following commands:

    • To get the version for a specific commit: nbgv get-version (or similar depending on context).
    • To get the commit(s) for a specific version: nbgv get-commits.

    Alternatively, the Nerdbank.GitVersioning NuGet package includes two deprecated PowerShell scripts for this purpose:

    • tools\Get-CommitId.ps1: Takes a version and prints the matching commit.
    • tools\Get-Version.ps1: Prints the version information for the current git commit at HEAD.
  11. Use the nbgv CLI for versioning operations

    main

    Once installed, the nbgv tool supports several core workflows for managing your software versions:

    • Repository Setup: Install Nerdbank.GitVersioning into an MSBuild-based repository.
    • Version Translation: Translate between computed versions and the specific Git commits that created them.
    • Git Tagging: Automatically tag a commit with its computed version.
    • CI Integration: Set variables within a Continuous Integration (CI) build environment.
    • Release Preparation: Prepare your repository for a stable software release.

    To see all available commands and options, run the tool with the help flag.

    nbgv -?