Add current Git commit to web.config on each build [.NET Core/ASP.NET Core]

*Docker service might eliminate the following technique's usability.

In this post, I am going to demonstrate a way to actually write the current commit of your version control module (I am using Git) into a location, let's say in your web.config.

One of the issue I have faced when managing multiple console apps., or even web projects is that it is not easy to keep track of the commit which the applications belong to. However, there is a simple technique to actually write the current commit of a specific branch into a location inside your project. The technique is the same regardless of the project type.

*I am talking about .NET based projects. Although I only tested this in .NET Core based projects, I am pretty sure it works almost the same in .NET Framework/ASP.NET MVC based projects.

The main idea is the utilize the build engine, MSBuild, to do something after building your application. The command execute a task could be derived in your .csproj file. You can define a task inside the Target element. A Target element will contain one or more tasks which will be executed in sequence. You could read more about this here, https://docs.microsoft.com/en-us/visualstudio/msbuild/target-element-msbuild?view=vs-2019.

The definition of task(s) is built on XML format, and you could imagine Target as the root element. The following represents the root of our task which will execute post-build.

<Target Name="PostBuild" AfterTargets="PostBuildEvent">

Next, we would like to define a variable which represents the string. In this case, we could use the PropertyGroup element.

 







<PropertyGroup>
  <Head>abc</Head>
</PropertyGroup>

Subsequently, we could refer the Head tag as the variable using the dollar sign, $, which would then gives us the value 'abc'. However, we would like to have Head to give us the current commit ID. For that, we could use property function to tap into .NET library to access the method to read a file. For simplicity, I would read a file in the local .git folder which has the information about the commit information where my current head is pointing to. Since my .git  folder resides in the folder which is the parent of my .csproj folder, I would need to navigate to the parent folder, and access file which contains the commit ID of my develop branch.

<PropertyGroup>
  <Head>$([System.IO.File]::ReadAllText("..\.git\refs\heads\develop").Trim())</Head>
</PropertyGroup>

The final step involves defining the task to change the web.config. Since web.config is XML-formatted file, we could use something called XmlPoke  to perform the operation. Basically, this is just a task to find the correct tag to override in a XML schema. Let's say we have a tag called ID that we would like to override after every build event.

<configuration>
  <configSections>
    <section name="Commit" type="System.Configuration.SingleTagSectionHandler" />
  </configSections>
  <Commit>
    <ID>abca0db5de924808fd2aa5e02dd1ddadb2025817</ID>
  </Commit>
</configuration>

We need to define the Commit tag in configSections, or else you will have problem launching your ASP.NET application because the application cannot recognize Commit tag. The XmlPoke task is shown below. We are using the Query attribute to find the tag which the value we will override.

<XmlPoke
  XmlInputPath="Web.config"
  Value="$(Head)"
  Query="/configuration/Commit/ID"
  />


So, this is a simple way to write a commit ID into your web.config on every build, the full XML task in the .csproj file is as follow.


<Target Name="PostBuild" AfterTargets="PostBuildEvent">
    <PropertyGroup>
      <Head>$([System.IO.File]::ReadAllText("..\.git\refs\heads\develop").Trim())</Head>
    </PropertyGroup>

    <XmlPoke
      XmlInputPath="Web.config"
      Value="$(Head)"
      Query="/configuration/Commit/ID"
      />
</Target>

Comments

Popular posts from this blog

ASP.NET Core service locator pattern

Ways to perform eager loading via NHibernate

Caching and generic query using NHibernate [.NET Core]