Skip to content

Instantly share code, notes, and snippets.

@PadreSVK
Last active January 6, 2021 16:37
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save PadreSVK/59b7918fd3005f398c94a8b75e33b21d to your computer and use it in GitHub Desktop.
Save PadreSVK/59b7918fd3005f398c94a8b75e33b21d to your computer and use it in GitHub Desktop.
Infrastructure for append git metadata

Combo of files that add git metadata to your dlls and nugets

  1. Put Directory.Build.props and Directory.Build.targets to root of your repository (or to where exist .sln file). These files are automatically added by msbuild to all projects (csprojs) that are in file system in folders under .targets and .props files.
  2. On your CI set required GitBranch msbuild property. This is required because most of CI do not checkout to branch, but to commit so you need explicitly add this to msbuild (dotnet cli). It is added to nuget metadata.
    1. [optional] (but recommended) - BuildNumber is used for build number for prerelease packages (it is used . instead of + because nuget do not support it). If is not filled, is used git SHA (with this is not working proper prerelease sorting in git) (i.e. 20201222.12 will be `1.0.0-prereleasefield..20201222.12)
    2. [optional] - PreReleaseField is used for specifying prerelease field. If is not filled it is created from git branch name without "/"

Git metadata in nugets (repository url, git branch, git commit)

  • examples of nuget versions
    • stable branch 1.0.0
    • feature branch 1.0.0-featurenewitem.20201222.11
    • stable dirty branch 1.0.0-dirty
    • feature dirty branch 1.0.7-featurenewitem.dirty.20201222.11
  • Add Git metadata to nugets (repository url, git branch, git commit)
<?xml version="1.0" encoding="utf-8"?>
<package xmlns="http://schemas.microsoft.com/packaging/2012/06/nuspec.xsd">
  <metadata>
    <id>TestClassLib</id>
    <version>1.0.0-featurenewitem.20201222.11</version>
    <authors>Paradajka Paprika</authors>
    <requireLicenseAcceptance>false</requireLicenseAcceptance>
    <description>Package Description</description>
    <repository type="git" url="https://dev.azure.com/mysuperorganization/GitMetadataInfrastructure/_git/GitMetadataInfrastructure" branch="feature/newitem" commit="4d21db7d9389f9d94d03b820ae4f5a9970390249" />
    <dependencies>
      <group targetFramework=".NETStandard2.0" />
    </dependencies>
  </metadata>
</package>

Git metadata in dlls

  • Add git metadata to all created dlls (via set InformationalVersion)
  • If is dll/nuget created with some nonstandard way (from dirty repo) add dirty field to dll InformationalVersion and nuget version.
  • Examples of InformationaVersion ("Product version") values
    • stable branch 1.0.7-sha+4d21db7d9389f9d94d03b820ae4f5a9970390249
    • feature branch 1.0.7-gitmetadatainfrastructure-sha+1552f2a0b01f42f73943e9b532c6fa175e21351c
    • stable dirty branch 1.0.7.dirty-sha+f2a475b3c352cb87368979bc25fa0db81b2c37c1
    • feature dirty branch 1.0.7-gitmetadatainfrastructure.dirty-sha+1552f2a0b01f42f73943e9b532c6fa175e21351c

Usage

  1. Add Directory.Build.props and Directory.Build.targets to root of you project (beside .sln)
  2. Set props in Directory.Build.props
  3. On you CI specify build props like
variables:
  projectToNuget: './GitMetadataInfrastructure/GitMetadataInfrastructure.csproj'
  # this just normalize branch name - i.e. from `refs/heads/master` do just `master`
  gitBranch:  ${{ replace(variables['Build.SourceBranch'],'refs/heads/','') }}
  buildConfiguration: Release

steps:
#restore step
#build step

# by cli this could be 
# dotnet pack ./GitMetadataInfrastructure/GitMetadataInfrastructure.csproj -c Release -p:BuildNumber=123 -p:GitBranch="mysuperfeature"

- task: DotNetCoreCLI@2
  displayName: "Pack ${{ parameters.projectToNuget}}"
  inputs:
    command: 'pack'
    packagesToPack: $(projectToNuget)
    versioningScheme: 'off'
    buildProperties: 'BuildNumber=$(Build.BuildNumber);GitBranch=$(gitBranch)'
    arguments: '--configuration $(buildConfiguration)'
<Project>
<PropertyGroup>
<Copyright>© 2021 Paradajka Paprika</Copyright>
<Authors>Paradajka Paprika</Authors>
<Company>Paradajka Paprika</Company>
<StableVersionBranch>master</StableVersionBranch>
<RepositoryUrl>https://dev.azure.com/mysuperorganization/GitMetadataInfrastructure/_git/GitMetadataInfrastructure</RepositoryUrl>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="GitInfo" Version="2.1.2" PrivateAssets ="All">
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
</PackageReference>
</ItemGroup>
</Project>
<Project>
<!-- https://github.com/kzu/GitInfo/blob/main/src/GitInfo/build/GitInfo.targets#L544 -->
<Target Name="AddGitMetadata" AfterTargets="GitVersion">
<PropertyGroup>
<!--https://docs.microsoft.com/en-us/dotnet/core/tools/csproj-->
<RepositoryCommit>$(GitSha)</RepositoryCommit>
<!-- most CI do checkout to bare commit not branch, in this case set p:GitBranch while inkoking msbuild/dotnet cli -->
<RepositoryBranch>$(GitBranch)</RepositoryBranch>
<BuildNumber Condition="$(BuildNumber) == ''">$(GitCommit)</BuildNumber>
<InformationalVersion>$(Version)</InformationalVersion>
</PropertyGroup>
<!-- pre-release versions of nugets-->
<PropertyGroup Condition="'$(GitBranch)' != '$(StableVersionBranch)'">
<!-- create prerelease field from git brachn if is not specified -->
<PreReleaseField Condition="'$(PreReleaseField)' == ''">$(GitBranch.Replace("/", ""))</PreReleaseField>
<PackageVersion>$(Version)-$(PreReleaseField)</PackageVersion>
<!-- if is package/dll builded from dirty repo add reprerelease field dirty -->
<PackageVersion Condition="'$(GitIsDirty)' == '1'">$(PackageVersion).dirty</PackageVersion>
<InformationalVersion>$(PackageVersion)</InformationalVersion>
<!-- nuget do not support semversion 2 build "+" suffix, add "." instead -->
<PackageVersion>$(PackageVersion).$(BuildNumber)</PackageVersion>
</PropertyGroup>
<!-- Add suffix prerelease "dirty" field if is builded frogom dirty StableVersionBranch -->
<PropertyGroup Condition="'$(GitIsDirty)' == '1' AND '$(GitBranch)' == '$(StableVersionBranch)'">
<PackageVersion>$(PackageVersion)-dirty</PackageVersion>
<InformationalVersion>$(InformationalVersion).dirty</InformationalVersion>
</PropertyGroup>
<!-- append +gitSHA to every dll-->
<PropertyGroup>
<InformationalVersion>$(InformationalVersion)-sha+$(RepositoryCommit)</InformationalVersion>
</PropertyGroup>
</Target>
</Project>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment