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文件发布到构建制品中。
问题原因
- WinUI3项目发布适配问题:WinUI3是桌面项目,
DotNetCoreCLI@2的publish命令对其支持有限,无法正确生成完整的发布输出,导致其指定的输出目录为空或不完整。 - 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'
关键修改说明
- WinUI3改用VSBuild发布:WinUI3依赖MSBuild的Windows App SDK特定目标,
VSBuild@1能正确处理自包含发布、平台适配等配置,确保生成完整的可发布文件。 - 禁用Blazor自动打包:通过
zipAfterPublish: false关闭默认的自动打包,避免因默认zip文件名相同导致的覆盖或误复制问题,改用ArchiveFiles@2手动生成指定名称的zip包。 - 隔离发布目录:每个项目的发布输出目录完全独立,同时通过明确的CopyFiles步骤确保仅复制对应项目的内容到制品目录。
- 前置排查:检查两个项目的
.csproj文件,若存在PublishDir属性,删除或改为项目相对路径,避免覆盖命令行指定的输出目录。
内容的提问来源于stack exchange,提问作者Josh Brunton
相关产品推荐
相关产品推荐

