简体   繁体   中英

Exposing TFS buildnumber via an endpoint of .NET Core WebAPI

In a solution I have a .NET Core 2.2 WebAPI project (among other projects). The solution has a corresponding build pipeline set up in TFS. Every TFS build has a build number, for example "20190615.15". What I would like to do is to expose this build number via an Web-API endpoint in order to fulfill maintaining and tracing purposes.

As a pre-solution I have managed to set the AssemblyInformationalVersion attribute from the build pipeline, and with the following controller I can easily retrieve the desired build-number:

[Route("api/[controller]")]
[ApiController]
public class VersionController : ControllerBase
{
    [HttpPut(Name = "version")]
    public Task<ApplicationVersion> Version()
    {
        return Task.FromResult(new ApplicationVersion
        {
            Version = ReadVersionFromAssemblyInfo()
        });
    }

    private string ReadVersionFromAssemblyInfo()
    {
        return Assembly.GetEntryAssembly()
            .GetCustomAttribute<AssemblyInformationalVersionAttribute>()
            .InformationalVersion;
    }

    public class ApplicationVersion
    {
        public string Version { get; set; }
    }
}

What I have done is pretty easy: First I introduced a new ARG called "VERSION_NUMBER" in the Dockerfile of the Web-API and set the InformationalVersion at the last publish step:

FROM microsoft/dotnet:2.2-sdk AS build
ARG VERSION_NUMBER
WORKDIR /src
COPY SomeAPI/SomeAPI.csproj SomeAPI/
RUN dotnet restore SomeAPI/SomeAPI.csproj
COPY . .
WORKDIR /src/SomeAPI
RUN dotnet publish SomeAPI.csproj -c Release -o /app -p:InformationalVersion=$VERSION_NUMBER

Then in the docker-compose.yml file I set the same arg :

services:
  someapi:
    image: someApi:${TAG:-latest}
    build:
      context: .
      dockerfile: SomeAPI/Dockerfile
      args:
        VERSION_NUMBER: ${VERSION_NUMBER}

And finally in the Docker-Compose task of TFS build I set the above-mentioned argument: TFS构建的Docker-Compose任务

It works like charm, and if I access my endpoint https://somedomain.com/api/version then I get a json back with the desired build-number.

The issue is that in my solution I reuse/leverage the AssemblyInformationalVersion attribute, but I would like to have this attribute set with the proper version number (fe: 1.0.1). So eventually the https://somdomain.com/api/version endpoint would return the a .json like:

{
    "Version": "1.0.1",
    "BuildNumber": "20190615.15"
}

What is the best way to expose the build-number (coming from TFS build) via a Web-API endpoint? Is it possible to set a custom property (xml tag) in the .csproj file, therefore I can use the AssemblyInformationalVersion for the intended purpose? Thanks for help!

I have successfully figured how to solve my issue. There are two good approaches to do it:

First approach: Introduce a custom .csproj property which can be accessed in run-time. First create a property class:

namespace MyNamespace
{
    /// <summary>
    /// A run-time-accessible property specified in .csproj file in order to store the build-number of the CI build-pipeline.
    /// </summary>
    [AttributeUsage(AttributeTargets.Assembly)]
    public sealed class BuildNumberAttribute : Attribute
    {
        public BuildNumberAttribute(string buildNumber)
        {
            BuildNumber = buildNumber;
        }

        public string BuildNumber { get; }
    }
}

Add the following item-group to .csproj file in order to make the property accessible:

  <ItemGroup>
    <AssemblyAttribute Include="MyNamespace.BuildNumberAttribute">
      <_Parameter1>"$(BuildNumber)"</_Parameter1>
    </AssemblyAttribute>
  </ItemGroup>

Finally in the dockerfile, pass the build argument

RUN dotnet publish SomeAPI.csproj -c Release -o /app -p:BuildNumber=$VERSION_NUMBER

Note that VERSION_NUMBER is set to $(Build.BuildNumber) in docker-compose task of TFS build pipeline.

To access this newly added property, do the following:

private string ReadBuildNumber()
{
    return Assembly.GetEntryAssembly()
        .GetCustomAttribute<BuildNumberAttribute>()
        .BuildNumber.Trim('"');
}

The second approach : Using "Replaced tokens" task in TFS build pipeline. With this you can set a template in appsettings.json, and the template can be replaced by task. For detailed info, check this stackoverflow question

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM