You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Azure DevOps YAML中PowerShell更新变量失败求助

解决方案:将Azure DevOps流水线运行号转换为合规的FileVersion

核心问题分析

Windows系统要求FileVersion的四个分段均为uint16类型(0-65535),流水线运行号的yyyyMMdd格式(如20230506)数值远大于该限制,必须拆分后重新组合。另外,Azure DevOps中脚本设置流水线变量需使用特定命令,否则变量无法在后续任务中生效。

步骤1:拆分流水线运行号并设置全局变量

在ci.yml中添加PowerShell任务,拆分Build.BuildNumber并输出可被后续任务读取的变量:

- task: PowerShell@2
  displayName: '拆分流水线运行号并设置FileVersion变量'
  inputs:
    targetType: 'inline'
    script: |
      # 获取流水线运行号,格式示例:20230506.1
      $buildNumber = "$(Build.BuildNumber)"
      
      # 拆分日期部分和流水号
      $datePart = $buildNumber.Split('.')[0]
      $revision = $buildNumber.Split('.')[1]
      
      # 拆分日期为合规分段:年份取后两位+月份,日期+流水号,确保每段≤65535
      $versionPart1 = [int]$datePart.Substring(2,2) * 100 + [int]$datePart.Substring(4,2) # 23*100+5=2305
      $versionPart2 = [int]$datePart.Substring(6,2) * 100 + [int]$revision # 6*100+1=601
      
      # 输出全局变量,供后续任务使用
      Write-Host "##vso[task.setvariable variable=FileVersionPart1;]$versionPart1"
      Write-Host "##vso[task.setvariable variable=FileVersionPart2;]$versionPart2"
      
      # 组合成最终FileVersion格式:主版本.次版本.分段1.分段2
      $finalFileVersion = "1.0.$versionPart1.$versionPart2"
      Write-Host "##vso[task.setvariable variable=FinalFileVersion;]$finalFileVersion"

可选拆分逻辑

如果偏好保留完整年份,可将日期拆分为完整年份和月日+流水号(2023和5061,均≤65535),替换脚本中对应行:

$versionPart1 = $datePart.Substring(0,4) # 2023
$versionPart2 = [int]$datePart.Substring(4,4) * 10 + [int]$revision # 0506*10+1=5061

步骤2:使用Assembly-Info-NetCore@3任务设置FileVersion

在PowerShell任务之后添加该任务,直接引用已设置的全局变量:

- task: Assembly-Info-NetCore@3
  displayName: '设置项目FileVersion'
  inputs:
    fileNames: '**/*.csproj'
    fileVersion: '$(FinalFileVersion)'
    assemblyVersion: '$(FinalFileVersion)' # 可选,同步AssemblyVersion
    informationalVersion: '$(Build.BuildNumber)' # 可选,保留原始流水线号作为信息版本

步骤3:直接修改.csproj文件的备选方案

如果Assembly-Info-NetCore任务不生效,可直接用PowerShell修改.csproj中的FileVersion节点:

- task: PowerShell@2
  displayName: '直接修改csproj的FileVersion'
  inputs:
    targetType: 'inline'
    script: |
      $csprojFiles = Get-ChildItem -Path "$(Build.SourcesDirectory)" -Filter *.csproj -Recurse
      $finalFileVersion = "$(FinalFileVersion)"
      
      foreach ($file in $csprojFiles) {
          $xml = [xml](Get-Content $file.FullName)
          $namespace = $xml.DocumentElement.NamespaceURI
          
          # 查找或创建FileVersion节点
          $fileVersionNode = $xml.SelectSingleNode("//*[local-name()='FileVersion']", $namespace)
          if ($fileVersionNode -eq $null) {
              $propertyGroup = $xml.SelectSingleNode("//*[local-name()='PropertyGroup']", $namespace)
              $fileVersionNode = $xml.CreateElement("FileVersion", $namespace)
              $propertyGroup.AppendChild($fileVersionNode) | Out-Null
          }
          
          $fileVersionNode.InnerText = $finalFileVersion
          $xml.Save($file.FullName)
          Write-Host "已更新 $($file.FullName) 的FileVersion为 $finalFileVersion"
      }

关键注意事项

  • 设置流水线变量必须使用Write-Host "##vso[task.setvariable variable=VAR;]VALUE"格式,否则变量仅在当前脚本内部有效。
  • 拆分后的每段数值必须确保≤65535,可根据需求调整拆分逻辑。
  • 使用Assembly-Info-NetCore任务时,需确保fileNames路径覆盖所有需要更新的.csproj文件。

内容的提问来源于stack exchange,提问作者kryman27

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.19 17:08:15