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

Azure Pipelines中.NET发布第二次运行覆盖首次发布问题

问题描述

我在azure-pipelines.yml中编写了如下代码,用于发布两个项目:

trigger:
  branches:
    include:
      - main

pool:
  vmImage: 'windows-latest'

steps:
- task: UseDotNet@2
  displayName: 'Use .NET'
  inputs:
    packageType: 'sdk'
    version: '8.0.x'

- task: NuGetToolInstaller@1
  displayName: 'NuGet Installer'


- task: VSBuild@1
  displayName: 'Restore WinUI3Project'
  inputs:
    solution: 'src/WinUI3Project/WinUI3Project.csproj'
    msbuildArgs: '/restore /p:Configuration=Release /p:Platform="x64"'

- task: VSBuild@1
  displayName: 'Restore BlazorServerProject'
  inputs:
    solution: 'src/BlazorServerProject/BlazorServerProject.csproj'
    msbuildArgs: '/restore /p:Configuration=Release /p:Platform="x64"'


- task: DotNetCoreCLI@2
  displayName: 'Publish WinUI3Project'
  inputs:
    command: 'publish'
    arguments: '--configuration Release --output $(Build.BinariesDirectory)\WinUI3Project'
    projects: 'src/WinUI3Project/WinUI3Project.csproj'

- task: CopyFiles@2
  displayName: 'Copy WinUI3Project Files to Staging Directory'
  inputs:
    SourceFolder: '$(Build.BinariesDirectory)\WinUI3Project'
    Contents: '**'
    TargetFolder: '$(Build.ArtifactStagingDirectory)\WinUI3Project'


- task: DotNetCoreCLI@2
  displayName: 'Publish BlazorServerProject'
  inputs:
    command: 'publish'
    arguments: '--configuration Release --output $(Build.BinariesDirectory)\BlazorServerProject'
    projects: 'src/BlazorServerProject/BlazorServerProject.csproj'

- task: CopyFiles@2
  displayName: 'Copy BlazorServerProjectFiles to Staging Directory'
  inputs:
    SourceFolder: '$(Build.BinariesDirectory)\BlazorServerProject'
    Contents: '**'
    TargetFolder: '$(Build.ArtifactStagingDirectory)\BlazorServerProject'


- task: PublishBuildArtifacts@1
  displayName: 'Publish Build Artifacts'
  inputs:
    pathToPublish: '$(Build.ArtifactStagingDirectory)'
    artifactName: 'drop'
    publishLocation: 'Container'

但查看发布后的制品时,得到如下结构:

drop
├─ WinUI3Project
|   └─ BlazorServerProject.zip
└─ BlazorServerProject
   └─ BlazorServerProject.zip

两个压缩包内容完全一致,均为第二个项目的文件。调整yaml中项目的构建、发布及复制顺序后,结果仍相同:两次都是后执行的项目内容。我尝试过用同一个DotNetCoreCLI@2步骤发布两个项目,但未找到可行的语法;传入**/*.csproj不符合需求,因为仓库中还有其他不应构建的项目。我不需要变通方案(比如创建仅包含目标项目的新.sln文件),想了解流水线出现此行为的原因,以及如何针对性地将两个.csproj文件发布到构建制品中。

问题原因
  1. WinUI3项目发布适配问题:WinUI3是桌面项目,DotNetCoreCLI@2的publish命令对其支持有限,无法正确生成完整的发布输出,导致其指定的输出目录为空或不完整。
  2. Web项目自动打包的潜在冲突:Blazor Server作为Web项目,DotNetCoreCLI@2的publish任务默认启用zipAfterPublish参数,会自动将输出打包为与项目同名的zip包。如果WinUI3的输出目录为空,后续任务的上下文可能导致Blazor的zip包被误复制到WinUI3的制品目录;更关键的是,若两个项目的.csproj文件中配置了全局PublishDir属性,会覆盖命令行的--output参数,导致两个项目都发布到同一目录,后发布的项目直接覆盖前一个的内容,最终两个制品目录复制的都是后发布的项目文件。
解决方案

针对WinUI3项目改用VSBuild@1完成发布(适配WinUI3的MSBuild依赖),同时明确隔离两个项目的发布目录,手动控制zip包生成,避免自动打包的冲突:

trigger:
  branches:
    include:
      - main

pool:
  vmImage: 'windows-latest'

steps:
- task: UseDotNet@2
  displayName: 'Use .NET 8 SDK'
  inputs:
    packageType: 'sdk'
    version: '8.0.x'

- task: NuGetToolInstaller@1
  displayName: 'Install NuGet Tool'

# 合并Restore步骤,同时处理两个项目的依赖还原
- task: VSBuild@1
  displayName: 'Restore All Target Projects'
  inputs:
    solution: 'src/{WinUI3Project,BlazorServerProject}/*.csproj'
    msbuildArgs: '/restore /p:Configuration=Release /p:Platform="x64"'

# 使用VSBuild发布WinUI3项目,适配Windows App SDK的发布需求
- task: VSBuild@1
  displayName: 'Publish WinUI3Project'
  inputs:
    solution: 'src/WinUI3Project/WinUI3Project.csproj'
    msbuildArgs: '/p:Configuration=Release /p:Platform="x64" /p:PublishDir="$(Build.BinariesDirectory)\WinUI3Project" /p:SelfContained=true /p:WindowsAppSDKSelfContained=true'
    platform: 'x64'
    configuration: 'Release'

- task: CopyFiles@2
  displayName: 'Copy WinUI3Project Files to Staging'
  inputs:
    SourceFolder: '$(Build.BinariesDirectory)\WinUI3Project'
    Contents: '**'
    TargetFolder: '$(Build.ArtifactStagingDirectory)\WinUI3Project'

# 发布Blazor Server项目,禁用自动打包,手动控制输出
- task: DotNetCoreCLI@2
  displayName: 'Publish BlazorServerProject'
  inputs:
    command: 'publish'
    arguments: '--configuration Release --output $(Build.BinariesDirectory)\BlazorServerProject'
    projects: 'src/BlazorServerProject/BlazorServerProject.csproj'
    zipAfterPublish: false # 关闭自动打包,避免默认zip名冲突

- task: CopyFiles@2
  displayName: 'Copy BlazorServerProject Files to Staging'
  inputs:
    SourceFolder: '$(Build.BinariesDirectory)\BlazorServerProject'
    Contents: '**'
    TargetFolder: '$(Build.ArtifactStagingDirectory)\BlazorServerProject'

# 手动为每个项目生成独立的zip包
- task: ArchiveFiles@2
  displayName: 'Zip WinUI3Project'
  inputs:
    rootFolderOrFile: '$(Build.ArtifactStagingDirectory)\WinUI3Project'
    includeRootFolder: false
    archiveType: 'zip'
    archiveFile: '$(Build.ArtifactStagingDirectory)\WinUI3Project\WinUI3Project.zip'

- task: ArchiveFiles@2
  displayName: 'Zip BlazorServerProject'
  inputs:
    rootFolderOrFile: '$(Build.ArtifactStagingDirectory)\BlazorServerProject'
    includeRootFolder: false
    archiveType: 'zip'
    archiveFile: '$(Build.ArtifactStagingDirectory)\BlazorServerProject\BlazorServerProject.zip'

- task: PublishBuildArtifacts@1
  displayName: 'Publish Build Artifacts'
  inputs:
    pathToPublish: '$(Build.ArtifactStagingDirectory)'
    artifactName: 'drop'
    publishLocation: 'Container'

关键修改说明

  1. WinUI3改用VSBuild发布:WinUI3依赖MSBuild的Windows App SDK特定目标,VSBuild@1能正确处理自包含发布、平台适配等配置,确保生成完整的可发布文件。
  2. 禁用Blazor自动打包:通过zipAfterPublish: false关闭默认的自动打包,避免因默认zip文件名相同导致的覆盖或误复制问题,改用ArchiveFiles@2手动生成指定名称的zip包。
  3. 隔离发布目录:每个项目的发布输出目录完全独立,同时通过明确的CopyFiles步骤确保仅复制对应项目的内容到制品目录。
  4. 前置排查:检查两个项目的.csproj文件,若存在PublishDir属性,删除或改为项目相对路径,避免覆盖命令行指定的输出目录。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.23 10:20:53