Git SHA in informational assembly version
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.