Git SHA in informational assembly version

August 9th 2024 .NET Git

I recently had a requirement for a Web API project I'm working on to be able to determine the exact commit used for a given build. Including a Git SHA in the build was the obvious choice. As I was looking for an easy way to do that, I learned that .NET 8 SDK already does it automatically: the AssemblyInformationalVersion has the SourceRevisionId property value appended which contains the Git SHA when building from a valid Git repository.

You can read the AssemblyInformationalVersion attribute value at runtime to expose the informational version in a version endpoint, for example:

[ApiController]
[Route("[controller]")]
public class VersionController : ControllerBase
{
    [HttpGet]
    public IActionResult Get()
    {
        var informationalVersion = Assembly
            .GetExecutingAssembly()
            .GetCustomAttribute<AssemblyInformationalVersionAttribute>()
            ?.InformationalVersion;

        return Ok(new { informationalVersion });
    }
}

The response will contain the Git SHA appended to the assembly version:

{
  "informationalVersion": "1.0.0+dde2ae22b2474848f2398906f844afd635a92675"
}

Since this feature is a part of the .NET 8 SDK, it will work the same even for projects that still target an older .NET version if you're using .NET 8 SDK to build them.

The only exception will be projects for which you're building Docker images using a Dockerfile because you'll still be building them with .NET 6 SDK even if you have .NET 8 SDK installed on your build machine:

FROM mcr.microsoft.com/dotnet/sdk:6.0 AS build
ARG BUILD_CONFIGURATION=Release
WORKDIR /src
COPY ["WebApp6/WebApp6.csproj", "WebApp6/"]
RUN dotnet restore "./WebApp6/WebApp6.csproj"
COPY . .
WORKDIR "/src/WebApp6"
RUN dotnet build "./WebApp6.csproj" -c $BUILD_CONFIGURATION -o /app/build

FROM build AS publish
ARG BUILD_CONFIGURATION=Release
RUN dotnet publish "./WebApp6.csproj" -c $BUILD_CONFIGURATION -o /app/publish /p:UseAppHost=false

If you want to include the Git SHA in the AssemblyInformationalVersion for such projects as well, you will have to pass the Git SHA value as an MSBuild property to the dotnet publish command via a Docker build argument:

FROM mcr.microsoft.com/dotnet/sdk:6.0 AS build
ARG BUILD_CONFIGURATION=Release
ARG GIT_SHA
WORKDIR /src
COPY ["WebApp6/WebApp6.csproj", "WebApp6/"]
RUN dotnet restore "./WebApp6/WebApp6.csproj"
COPY . .
WORKDIR "/src/WebApp6"
RUN dotnet build "./WebApp6.csproj" -c $BUILD_CONFIGURATION -o /app/build

FROM build AS publish
ARG BUILD_CONFIGURATION=Release
RUN dotnet publish "./WebApp6.csproj" -c $BUILD_CONFIGURATION -p:SourceRevisionId=$GIT_SHA -o /app/publish /p:UseAppHost=false

When building the Docker image, you must of course set the new GIT_SHA argument to the actual Git SHA value. The following Git command will emit it:

git rev-parse HEAD

If you're using PowerShell, you can embed it in your build command using the subexpression operator:

docker build -f ./WebApp6/Dockerfile -t webapp6 --build-arg="GIT_SHA=$(git rev-parse HEAD)" .

On the build server, the way you can get the Git SHA of the commit in use will depend on the product you're using. In Jenkins, for example, the value is returned from the checkout step:

def scmVars = checkout([$class: 'GitSCM'])
sh "docker build -f ./WebApp6/Dockerfile -t webapp6 --build-arg=\"GIT_SHA=${scmVars.GIT_COMMIT}\" ."

You can run the code from my GitHub repository to check the AssemblyInformationalVersion value returned by .NET 6 and .NET 8 Web API projects. For the .NET 6 project, I have modified the Dockerfile as suggested in this post to include the Git SHA in the informational version. The second to last commit contains unmodified Dockerfile which results in the informational version without the SHA. I also included a simple docker-compose.yml which you can use to run the .NET 6 and .NET 8 Web API from the Docker container image after you build it.

If you don't have full confidence in your release management process, having the ability to check the exact commit from which the currently deployed Web API application was built can be a useful tool. Fortunately, most of the work is done for you by the .NET 8 SDK. You only need to expose the informational assembly version in a way that suits you best. Only if you haven't upgraded all your .NET 6 projects to .NET 8 yet and you're using a Dockerfile to build them, then you'll have to modify your build pipeline to pass the Git SHA value to the publish command.

Get notified when a new blog post is published (usually every Friday):

Copyright
Creative Commons License