我在 CI/CD 管道中遇到 NuGet 包的预发布版本控制问题。标准 NuGet 包版本工作正常,但在拉取请求 (PR) 期间创建预发布版本时存在问题,即使在提交消息中使用 +semver: Major 也是如此。
背景:
最近变化:
这个问题是在我们从 gitversion/setup@0 升级到 gitversion/setup@1 后开始出现的。之前的 GitVersion 配置是:
更新后的配置为:
变更原因: Azure DevOps 管道错误:找不到版本大于 2.220.0 的代理
问题:
当我们创建 PR 时,构建系统会生成预发布的 NuGet 包版本,例如 5.1.2-pullrequestxxxxx,而不是预期的 6.0.0-pullrequestxxxxx,尽管在提交消息中使用了 +semver: Major。但是,PR 获得批准并合并后,发布的版本正确更新为 6.0.0。
问题:
如何确保预发布的 NuGet 包版本正确反映 PR 过程中的主要版本更改,尤其是在提交消息中使用 +semver: Major 时? CI/CD 管道中是否有我可能缺少或需要调整的特定配置或步骤?
任何有关如何解决此问题的见解或建议将不胜感激。谢谢!
gitversion.yml
# Add steps that build, run tests, deploy, and more:
# https://aka.ms/yaml
parameters:
- name: tagSources
displayName: Tag Sources
type: boolean
default: false
- name: configFilePath
type: string
displayName: 'GitVersion Configuration Path.'
default: '$(Build.Repository.LocalPath)\GitVersion.yml'
steps:
- powershell: |
Write-Host "Original Build Number: $env:Build_BuildNumber"
name: LogOriginalBuildNumber
displayName: Log Original Build Number
- powershell: |
$env:GitVersionConfigExists = Test-Path $env:GitVersionConfigurationPath
Write-Host "##vso[task.setvariable variable=GitVersionConfigExists]$env:GitVersionConfigExists"
Write-Host "##vso[task.setvariable variable=GitVersionConfigExists;isOutput=true]$env:GitVersionConfigExists"
name: DetectGitVersionConfig
displayName: Detect '${{ parameters.configFilePath }}'
env:
GitVersionConfigurationPath: ${{ parameters.configFilePath }}
- checkout: self
fetchDepth: 0
- task: gitversion/setup@1
displayName: 'Install GitVersion'
inputs:
versionSpec: '5.x'
preferLatestVersion: true
- task: gitversion/execute@1
name: Execute
inputs:
useConfigFile: $(DetectGitVersionConfig.GitVersionConfigExists)
configFilePath: ${{ parameters.configFilePath }}
displayName: Execute GitVersion
- ${{ if parameters.tagSources }}:
- powershell: |
#region Text Utils
function ConvertTo-PowershellLiteral {
[CmdletBinding(DefaultParameterSetName = 'WithoutBuilder')]
Param(
[Parameter(ParameterSetName = 'WithBuilder', Mandatory, ValueFromPipeline)]
[System.Text.StringBuilder]$Builder,
[Parameter(ParameterSetName = 'WithBuilder', Position = 0,ValueFromRemainingArguments)]
[Parameter(ParameterSetName = 'WithoutBuilder', ValueFromPipeline, Position = 0,ValueFromRemainingArguments)]
[object[]]$Value
)
Begin {
$ExternalBuilder = $PSCmdlet.ParameterSetName -eq 'WithBuilder'
if (-not $ExternalBuilder) {
$Builder = [System.Text.StringBuilder]::new()
}
function ConvertTo-DoubleLiteral([Parameter(Position = 0)][double]$Value) { if ([double]::IsNaN($Value)) { '[double]::NaN' } elseif([double]::IsPositiveInfinity($Value)) { '[double]::PositiveInfinity' } elseif([double]::IsNegativeInfinity(($Value))) { '[double]::NegativeInfinity' } elseif($Value -eq [double]::Epsilon) { '[double]::Epsilon' } elseif($Value -eq [double]::MaxValue) { '[double]::MaxValue' } elseif($Value -eq [double]::MinValue) { '[double]::MinValue' } else { $Value.ToString('G17', [System.Globalization.CultureInfo]::InvariantCulture) } }
function ConvertTo-SingleLiteral([Parameter(Position = 0)][float]$Value) { if ([float]::IsNaN($Value)) { '[float]::NaN' } elseif([float]::IsPositiveInfinity($Value)) { '[float]::PositiveInfinity' } elseif([float]::IsNegativeInfinity(($Value))) { '[float]::NegativeInfinity' } elseif($Value -eq [float]::Epsilon) { '[float]::Epsilon' } elseif($Value -eq [float]::MaxValue) { '[float]::MaxValue' } elseif($Value -eq [float]::MinValue) { '[float]::MinValue' } else { $Value.ToString('G17', [System.Globalization.CultureInfo]::InvariantCulture) } }
function ProcessItem([Parameter(Position = 0, Mandatory, ValueFromPipeline)][System.Text.StringBuilder]$Builder, [Parameter(Position = 0)]$Value, [switch]$ForceQuotes = $false) {
if ($Value -isnot [string] -and $Value -is [System.Collections.IEnumerable]) {
$AppendedValueItem = $false
$Builder.Append('@(') | Out-Null
foreach ($ValueItem in $Value) {
if ($AppendedValueItem) { $Builder.Append(', ') | Out-Null}
ProcessItem -Builder $Builder -Value $ValueItem
$AppendedValueItem = $true
}
$Builder.Append(')')
}
else {
switch ($Value) {
$null { $Builder.Append('$null');break }
{ $_ -is [string] } {
if ($ForceQuotes -or $_ -match '[\s''"]') {
$Start = $Builder.Append([char]'''').Length
$Builder.Append($_).Replace('''', '''''', $Start, $Builder.Length - $Start).Append([char]'''')
}
else {
$Builder.Append($_)
}
break
}
{ $_ -is [System.IO.DirectoryInfo] } { ($Builder.Append('[System.IO.DirectoryInfo]::new(') | ProcessItem -Value $_.FullName -ForceQuotes).Append(')');break }
{ $_ -is [System.IO.FileInfo] } { ($Builder.Append('[System.IO.FileInfo]::new(') | ProcessItem -Value $_.FullName -ForceQuotes).Append(')');break }
{ $_ -is [double] } { $Builder.Append((ConvertTo-DoubleLiteral $_));break }
{ $_ -is [float] } { $Builder.Append((ConvertTo-SingleLiteral $_));break }
{ $_ -is [byte] -or $_ -is [sbyte] -or $_ -is [uint16] -or $_ -is [int16] -or $_ -is [uint32] -or $_ -is [int] -or $_ -is [uint64] -or $_ -is [long] } { $Builder.Append($_.ToString([System.Globalization.CultureInfo]::InvariantCulture));break }
Default { throw "Unexpected value type: $($_.GetType().FullName)"
}
}
}
}
}
Process {
if ($Value) {
$AppendedAny = $false
foreach ($Item in $Value) {
if ($AppendedAny) {
$Builder.Append([char]' ') | Out-Null
}
ProcessItem -Builder $Builder -Value $Item | Out-Null
$AppendedAny = $true
}
}
if ($ExternalBuilder) {
$Builder
}
else {
$Builder.ToString()
$Builder.Clear() | Out-Null
}
}
}
#endregion
#region Logging Comands
function Write-PipelineCommand([Parameter(Position = 0, ValueFromRemainingArguments)][string[]]$Command) {
Process {
Write-Host -Object (([System.Text.StringBuilder]::new('##[command]') | ConvertTo-PowershellLiteral -Value $Command).ToString())
}
}
#endregion
Write-PipelineCommand git tag --force "v$($env:GitVersion_FullSemVer)" $env:GitVersion_Sha
git tag --force "v$($env:GitVersion_FullSemVer)" $env:GitVersion_Sha
Write-PipelineCommand git '-c' http.extraheader="AUTHORIZATION: bearer ***" push --force origin refs/tags/v$($env:GitVersion_FullSemVer)
git -c http.extraheader="AUTHORIZATION`: bearer $env:System_AccessToken" push --force origin refs/tags/v$($env:GitVersion_FullSemVer)
name: TagSources
displayName: Tag Sources
condition: eq(variables['GitVersion.PreReleaseTagWithDash'], '') # Cannot use `PreReleaseTag` as it is the `UncommittedChanges` when there isn't a pre-release tag.
env:
System_AccessToken: $(System.AccessToken)
$(Build.Repository.LocalPath)\GitVersion.yml
assembly-versioning-scheme: MajorMinorPatch
mode: Mainline
branches: {}
ignore:
sha: []
merge-message-formats: {}
注意: 预发布版本在更改为使用 setup@1 之前与这些 yml 配合得很好
我如下配置
GitVersion.yml
文件,当我将“major
”添加到提交消息中时,它可以按预期增加 +semver: major
版本。
# GitVersion.yml
mode: mainline
tag-prefix: '[vV]?'
assembly-informational-format: '{Major}.{Minor}.{Patch}'
major-version-bump-message: '\+semver:\s?(breaking|major)'
minor-version-bump-message: '\+semver:\s?(feature|minor)'
patch-version-bump-message: '\+semver:\s?(fix|patch)'
no-bump-message: '\+semver:\s?(none|skip)'
commit-message-incrementing: Enabled
update-build-number: true
# azure-pipelines.yml
jobs:
- job: build
steps:
- checkout: self
fetchDepth: 0
- task: gitversion/setup@1
displayName: 'Install GitVersion'
inputs:
versionSpec: '5.x'
preferLatestVersion: true
- task: gitversion/execute@1
displayName: 'Generate Version'
- bash: |
echo "GitVersion.FullSemVer = $(GitVersion.FullSemVer)"
echo "GitVersion.SemVer = $(GitVersion.SemVer)"
displayName: 'View Version'