持续部署环境中的 dotnet 语义版本控制

ibe*_*dev 6 csproj semantic-versioning gitlab .net-core dotnet-cli

我正在使用 GitLab 为我的 dotnet 核心应用程序和 netstandard 2.0 包配置语义版本控制。

在阅读了相当多的意见后,其中一些意见相互矛盾,这对我来说很清楚。语义版本应该类似于 M.m.P.B-abc123where

  • M 是主要版本
  • m 是次要版本
  • P 是补丁版本
  • B 是构建版本(可选)
  • -abc123是后缀(可选)以防我使用预发行版。它必须以字母开头

因此,以下软件包版本将是有效的:

  • 1.0.0
  • 1.0.1.20190301123
  • 1.0.1.20190301123-beta
  • 1.0.1-rc1

我的版本控制有以下 gitlab 脚本

#Stages
stages:
  - ci
  - pack

#Global variables
variables:
  GITLAB_RUNNER_DOTNET_CORE: mcr.microsoft.com/dotnet/core/sdk:2.2
  NUGET_REPOSITORY: $NEXUS_NUGET_REPOSITORY
  NUGET_API_KEY: $NEXUS_API_KEY
  NUGET_FOLDER_NAME: nupkgs

#Docker image
image: $GITLAB_RUNNER_DOTNET_CORE

#Jobs
ci:
  stage: ci
  script:
    - dotnet restore --no-cache --force
    - dotnet build --configuration Release
    - dotnet vstest *Tests/bin/Release/**/*Tests.dll

pack-beta-nuget:
  stage: pack
  script:
    - export VERSION_SUFFIX=beta$CI_PIPELINE_ID
    - dotnet pack *.sln --configuration Release --output $NUGET_FOLDER_NAME --version-suffix $VERSION_SUFFIX --include-symbols
    - dotnet nuget push **/*.nupkg --api-key $NUGET_API_KEY --source $NUGET_REPOSITORY
  except:
    - master

pack-nuget:
  stage: pack
  script:
    - dotnet restore
    - dotnet pack *.sln --configuration Release --output $NUGET_FOLDER_NAME
    - dotnet nuget push **/*.nupkg --api-key $NUGET_API_KEY --source $NUGET_REPOSITORY
  only:
    - master
Run Code Online (Sandbox Code Playgroud)

这会生成诸如: 1.0.0用于 master 分支(稳定或生产就绪)和1.0.0-beta1234567任何其他分支的包。

我的方法的问题是我有多个项目的 VS 解决方案,每个项目都是一个 nuget 包,每个项目都有自己的版本。有时我会修改一个项目而不是另一个,因此理论上我不需要制作我没有接触过的项目的新工件,当然也不需要新版本。

现在我的 nuget 存储库防止覆盖包,所以如果有一个XXX.YYY 1.0.0,我生成另一个XXX.YYY 1.0.0并将其推送到存储库,它将引发错误并且管道将失败。

我想也许每次运行 CI/CD 管道时生成一个新包并不是一个坏主意,所以我考虑引入内部版本号并使用类似的东西XXX.YYY 1.0.0.12345,即使我没有触及那里的任何东西,下次XXX.YYY 1.0.0.123499会生产一个新的包。

这是持续部署场景中的正确方法吗?或者,如果我的 nuget 存储库中已经有一个具有相同版本的工件,我是否应该寻找一种方法来使我的脚本更智能,而不是生成新工件?

假设可以始终使用内部版本号,我如何确保仅从管道中检索内部M.m.P版本号,但版本号仍保留在我的 csproj 中,如下所示?

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <TargetFramework>netstandard2.0</TargetFramework>
    <Description>Whatever</Description>
    <VersionPrefix>1.0.1</VersionPrefix>
  </PropertyGroup>
</Project>
Run Code Online (Sandbox Code Playgroud)

我需要类似的东西: dotnet pack *.sln --configuration Release -p:PackageVersion=$FIXED_VERSION.$CI_PIPELINE_ID --output nupkg

但我不知道如何<VersionPrefix>通过 CLI 从 csproj检索内容。

假设它是有效的,我的方法有什么建议、好的阅读或解决方案吗?

谢谢

Mad*_*lei 4

\n

我的方法的问题是我有多个项目的 VS 解决方案,每个项目都是一个 nuget 包,每个项目都有自己的版本。有时我会修改一个项目而不是另一个项目,因此理论上我不需要生成我没有接触过的项目的新工件,当然也不需要生成新版本。

\n
\n\n

由于持续集成管道无法确定您的代码应该是新的次要版本还是主要版本,因此您始终必须确定您的包应该获得哪个语义版本。这使得整个过程变得更加容易。

\n\n

来自视觉工作室团队服务的人员对此有这样的说法:

\n\n
\n

不变性和唯一版本号\n 在 NuGet 中,特定包由其名称和版本号标识。一旦您发布了特定版本的包,您就永远无法更改其内容。但是,当您\xe2\x80\x99 生成 CI 包时,\xe2\x80\x99 无法知道它是版本 1.2.3 还是只是朝着 1.2.3 迈进的一步。您不想\xe2\x80\x99 不想在仍需要一些错误修复的软件包上刻录 1.2.3 版本号。

\n\n

SemVer 来救援!除了 Major.Minor.Patch 之外,SemVer 还提供预发行标签。预发行标签是 \xe2\x80\x9c-\xe2\x80\x9d 后跟您想要的任何字母和数字。版本 1.0.0-alpha、1.0.0-beta 和 1.0.0-foo12345 都是 1.0.0 的预发行版本。更好的是,SemVer 指定当您按版本号排序时,这些预发布版本完全符合您\xe2\x80\x99d 的预期:0.99.999 < 1.0.0-alpha < 1.0.0 < 1.0.1-beta。

\n\n

Xavier\xe2\x80\x99s 博客文章描述了 \xe2\x80\x9chijacking\xe2\x80\x9d 用于 CI 的预发布标签。不过,我们不认为\xe2\x80\x99是劫持。这正是我们在 Visual Studio Team Services 上创建 CI 包时所做的事情。我们\xe2\x80\x99将通过选择一个版本号,然后生成该版本的预发行版来克服这个悖论。我们在版本号中留下预发布标签有什么关系吗?对于大多数用例来说,事实并非如此。如果您\xe2\x80\x99 固定到依赖包的特定版本号,则不会有任何影响,如果您在project.json 中使用浮动版本范围,则意味着对您指定的版本范围进行小幅更改。 \n 来源:https ://devblogs.microsoft.com/devops/versioning-nuget-packages-cd-1/

\n
\n\n

如前所述,您仍然需要自己为新软件包选择一个版本。对于实际发布最终包(在您的情况下为 master 分支)之前的过程,您可以使用预发布标签将内部版本号包含为预发布标签。

\n\n

如果不做任何聪明的事情,这将为每个运行的管道发布一个新的包。视觉工作室团队服务的人们,我不认为这是一件坏事,但这取决于每个人的个人品味

\n