在连续部署环境中使用dotnet语义版本控制

问题描述 投票:2回答:1

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

在阅读了相当多的意见后,其中一些是矛盾的,这对我来说是清楚的。语义版本应该像M.m.P.B-abc123那样

  • 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

这将生成包,例如:1.0.0用于主分支(稳定或生产就绪)和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>

我需要像:dotnet pack *.sln --configuration Release -p:PackageVersion=$FIXED_VERSION.$CI_PIPELINE_ID --output nupkg

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

假设它有效,我的方法的任何建议,良好的阅读或解决方案?

谢谢

.net-core gitlab csproj semantic-versioning dotnet-cli
1个回答
1
投票

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

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

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

不可变性和唯一版本号在NuGet中,特定包由其名称和版本号标识。在特定版本上发布包后,您永远不能更改其内容。但是当你制作一个CI软件包时,你无法知道它是1.2.3版还是只是向1.2.3迈出的一步。您不希望在仍需要修复一些错误的程序包上刻录1.2.3版本号。

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

Xavier的博客文章描述了“劫持”用于CI的预发布标记。不过,我们认为它不会被劫持。这正是我们在Visual Studio Team Services上创建CI包的过程。我们将通过选择版本号来克服这个悖论,然后生成该版本的预发行版。我们在版本号中留下预发布标记是否重要?对于大多数用例,不是真的。如果您固定到依赖包的特定版本号,则不会产生任何影响,如果您使用project.json的浮动版本范围,则意味着对您指定的版本范围进行小的更改。资料来源:https://devblogs.microsoft.com/devops/versioning-nuget-packages-cd-1/

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

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

© www.soinside.com 2019 - 2024. All rights reserved.