【问题标题】:Exposing TFS buildnumber via an endpoint of .NET Core WebAPI通过 .NET Core WebAPI 的端点公开 TFS 内部版本号
【发布时间】:2019-06-18 15:16:16
【问题描述】:

在一个解决方案中,我有一个 .NET Core 2.2 WebAPI 项目(以及其他项目)。 该解决方案在 TFS 中设置了相应的构建管道。每个 TFS 版本都有一个版本号,例如“20190615.15”。我想做的是通过 Web-API 端点公开这个内部版本号,以实现维护和跟踪目的。

作为一个预解决方案,我设法从构建管道中设置了AssemblyInformationalVersion 属性,并且使用以下控制器,我可以轻松检索所需的内部版本号:

[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; }
    }
}

我所做的很简单: 首先,我在 Web-API 的 Dockerfile 中引入了一个名为“VERSION_NUMBER”的新ARG,并在最后一个发布步骤中设置了InformationalVersion

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

然后在 docker-compose.yml 文件中我设置相同的arg:

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

最后在 TFS 构建的 Docker-Compose 任务中,我设置了上述参数:

它就像魅力一样,如果我访问我的端点https://somedomain.com/api/version,那么我会得到一个带有所需内部版本号的 json。

问题在于,在我的解决方案中,我重用/利用了 AssemblyInformationalVersion 属性,但我希望将此属性设置为正确的版本号(例如:1.0.1)。所以最终https://somdomain.com/api/version 端点会返回一个 .json 像:

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

通过 Web-API 端点公开内部版本号(来自 TFS 内部版本)的最佳方式是什么?是否可以在 .csproj 文件中设置自定义属性(xml 标记),因此我可以将 AssemblyInformationalVersion 用于预期目的?感谢您的帮助!

【问题讨论】:

    标签: c# docker asp.net-core tfs asp.net-core-webapi


    【解决方案1】:

    我已经成功地想出了如何解决我的问题。有两种很好的方法来做到这一点:

    第一种方法: 引入一个可以在运行时访问的自定义 .csproj 属性。首先创建一个属性类:

    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; }
        }
    }
    

    将以下项目组添加到 .csproj 文件以使属性可访问:

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

    最后在dockerfile中,传递build参数

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

    请注意,在 TFS 构建管道的 docker-compose 任务中,VERSION_NUMBER 设置为 $(Build.BuildNumber)

    要访问这个新添加的属性,请执行以下操作:

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

    第二种方法: 在 TFS 构建管道中使用“替换令牌”任务。这样就可以在appsettings.json中设置模板,模板可以替换为task。详情请查看this stackoverflow question

    【讨论】:

      猜你喜欢
      • 2010-12-04
      • 2016-03-25
      • 2012-06-08
      • 2017-02-15
      • 1970-01-01
      • 2011-09-20
      • 2016-05-23
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多