Azure DevOps Pipelines调用共享仓库Shell脚本失败的问题排查
问题描述
为实现Pipeline模板复用,创建了名为DevOps.Shared的共享仓库,存放模板文件与Shell脚本。在另一仓库的Test.yaml中,通过resources引用该共享仓库,并调用其Build.yaml模板执行构建任务,但执行时提示找不到Templates/Build/scripts/validate_build_type.sh脚本——代理工作目录中未检出共享仓库。尽管Build.yaml中包含checkout:self步骤,问题仍未解决。
补充信息:
- 两个仓库同属一个ADO组织,调用方Pipeline拥有共享仓库的访问权限
- 共享仓库结构:[图片链接]
Build.yaml内容:
# Build.yaml file on DevOps.Shared pipeline parameters: buildType: ~ #dotnet, flutter projectName: ~ #Project name gitRepoUrl: ~ #Git repo URL to checkout buildTarget: ~ #file or directory jobs: - job: BuildTargetStep displayName: Build ${{ parameters.buildType }} component steps: - checkout: self - task: Bash@3 inputs: targetType: 'inline' script: | ls -l - task: Bash@3 displayName: Validate Build Type inputs: targetType: 'filePath' filePath: Templates/Build/scripts/validate_build_type.sh arguments: > -t ${{ parameters.buildType }}
- 调用方
Test.yaml内容:
# Test.yaml (pipeline file on another repo) resources: repositories: - repository: DevOps_Shared type: git name: DevOps.Shared/DevOps.Shared ref: task/ground-work stages: - stage: BuildAndAnalyse displayName: Build and Analyse jobs: - template: Templates/Build/Build.yaml@DevOps_Shared parameters: buildType: 'dotnet' projectName: 'test'
原因分析
问题出在checkout:self的上下文理解上:在Azure DevOps中,当从共享仓库引用模板时,模板里的checkout:self指向的是运行当前流水线的仓库(也就是Test.yaml所在的调用方仓库),而非模板本身所在的DevOps.Shared共享仓库。因此原步骤只检出了调用方仓库,共享仓库并未被拉取到代理工作目录,自然找不到存放在共享仓库里的脚本文件。
解决方案
1. 明确检出共享仓库
在Build.yaml的步骤中,添加对共享仓库的检出操作,使用你在Test.yaml中定义的共享仓库别名DevOps_Shared:
- checkout: DevOps_Shared
如果需要同时保留调用方仓库的检出(比如构建时需要调用方的代码),可以同时保留checkout:self和checkout: DevOps_Shared,Azure DevOps会将两个仓库分别检出到$(Build.SourcesDirectory)下的对应目录(默认目录名就是仓库别名)。
2. 调整脚本路径
因为共享仓库会被检出到$(Build.SourcesDirectory)/DevOps_Shared目录下,所以需要修改脚本的filePath指向该路径:
filePath: DevOps_Shared/Templates/Build/scripts/validate_build_type.sh
修改后的完整Build.yaml示例
# Build.yaml file on DevOps.Shared pipeline parameters: buildType: ~ #dotnet, flutter projectName: ~ #Project name gitRepoUrl: ~ #Git repo URL to checkout buildTarget: ~ #file or directory jobs: - job: BuildTargetStep displayName: Build ${{ parameters.buildType }} component steps: # 检出调用方仓库(如果构建需要调用方代码则保留,否则可移除) - checkout: self # 检出共享仓库DevOps_Shared - checkout: DevOps_Shared - task: Bash@3 inputs: targetType: 'inline' script: | ls -l $(Build.SourcesDirectory) # 可查看当前目录结构,验证仓库是否检出 - task: Bash@3 displayName: Validate Build Type inputs: targetType: 'filePath' filePath: DevOps_Shared/Templates/Build/scripts/validate_build_type.sh arguments: > -t ${{ parameters.buildType }}
可选:自定义共享仓库检出路径
如果你想指定共享仓库的检出路径,避免默认目录名冲突,可以在checkout步骤中添加path参数:
- checkout: DevOps_Shared path: 'SharedRepo' # 自定义检出目录名
此时脚本路径需要对应修改为:
filePath: SharedRepo/Templates/Build/scripts/validate_build_type.sh
内容的提问来源于stack exchange,提问作者Selim Balci

