Azure DevOps构建提示目录为空无法添加到drop工件
问题根因
报错是多个配置问题叠加导致最终工件目录为空:
- Job隔离机制问题:Azure DevOps流水线中每个独立Job默认运行在全新的独立代理实例上,不同Job之间的工作目录、生成文件完全隔离,不会自动共享。配置中的
Buildproj1、BuildProj2、CreateOutput是三个独立Job,前两个Job写入$(Build.ArtifactStagingDirectory)的构建产物,第三个Job完全访问不到。 - 代理环境不匹配:前两个Job显式指定使用
windows-2019镜像池,但CreateOutputJob未配置pool参数,系统默认分配了Linux代理(报错路径/home/vsts/work/1/a就是Linux代理下的工件暂存目录默认路径),该代理启动时自身的工件目录本身就是空状态。 - 任务顺序与路径配置错误:
CreateOutput中先执行PublishBuildArtifacts发布工件,后执行ArchiveFiles打zip包,发布动作执行时压缩包还未生成;且ArchiveFiles配置的源路径是$(Build.BinariesDirectory),整个流程没有任何步骤往这个目录写入构建产物,根本打不出有效压缩包。 - YAML语法与逻辑错误:
- Proj2的项目路径末尾多写了一个单引号,会导致VSBuild任务参数解析失败
- Proj2的CopyFiles任务过滤规则写为
!*.dll,会排除所有dll文件,编译生成的核心程序集根本不会被复制 - 触发器配置使用运行时变量
$(Build.SourceBranchName),该配置无法被触发器识别,会导致分支触发逻辑异常 - 前两个Job的CopyFiles直接全量复制整个源码目录到工件目录,会把大量无关源码文件带入产物,没有实际必要
修复方案
针对这个简单构建场景,直接把三个独立Job合并为单个Job即可解决跨Job文件隔离问题,同时修正所有配置错误,具体调整点如下:
- 合并所有构建、打包、发布步骤到同一个Job,统一指定代理池为
windows-2019 - 修正YAML语法错误:删除Proj2路径多余的单引号,将触发器分支配置为明确的分支名(如
main、release/*) - 调整任务顺序:先完成两个项目的构建、文件复制,再执行压缩打包,最后执行工件发布
- 修正打包路径:将
ArchiveFiles的源目录改为$(Build.ArtifactStagingDirectory),指向实际存放构建产物的路径 - 修正文件复制过滤规则:去掉
!*.dll的错误排除配置,如需复制额外文件明确指定匹配规则,不需要全量复制源码目录
修正后的参考配置如下:
trigger: - main - release/* stages: - stage: BuildProject displayName: buildProj jobs: - job: BuildAll pool: vmImage: 'windows-2019' steps: # 构建Proj1 - task: VSBuild@1 inputs: solution: 'Proj1Folder/Proj1/Proj1.csproj' msbuildArgs: '/p:DeployOnBuild=true /p:WebPublishMethod=Package /p:PackageAsSingleFile=true /p:SkipInvalidConfigurations=true /p:PackageLocation="$(build.artifactStagingDirectory)/Proj1"' platform: 'Any CPU' configuration: 'Release' # 构建Proj2 - task: VSBuild@1 inputs: solution: 'Proj2Folder/Proj2/Proj2.csproj' msbuildArgs: '/p:DeployOnBuild=true /p:WebPublishMethod=Package /p:PackageAsSingleFile=true /p:SkipInvalidConfigurations=true /p:PackageLocation="$(build.artifactStagingDirectory)/Proj2"' platform: 'Any CPU' configuration: 'Release' # 如需复制额外非编译文件可在此配置,不需要全量复制源码 - task: CopyFiles@2 inputs: sourceFolder: $(System.SourcesDirectory) contents: '**/*.config' targetFolder: '$(Build.artifactStagingDirectory)/configs' # 打zip包 - task: ArchiveFiles@2 inputs: rootFolderOrFile: '$(Build.ArtifactStagingDirectory)' includeRootFolder: false archiveType: 'zip' archiveFile: '$(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip' replaceExistingArchive: true # 发布工件 - task: PublishBuildArtifacts@1 inputs: PathtoPublish: '$(Build.ArtifactStagingDirectory)' ArtifactName: 'drop_$(Build.SourceBranchName)' publishLocation: 'Container'
如果确实需要拆分多个Job(比如并行构建缩短时间),则需要在
Buildproj1和BuildProj2的末尾分别添加PublishBuildArtifacts任务把当前Job的产物发布为中间工件,在CreateOutput开头添加DownloadBuildArtifacts任务把两个项目的产物下载到当前代理的暂存目录后,再执行打包和最终发布,这种方式配置更复杂,对当前场景没有必要。
内容的提问来源于stack exchange,提问作者subho
相关产品推荐
相关产品推荐

