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

Azure Pipeline从Bitbucket拉取代码时CI任务工作目录不一致问题问询

Azure DevOps流水线checkout任务目录异常问题

背景

我有一个Azure DevOps(ADO)流水线,包含名为option的运行时参数,可选值为ci、cd、release-test、release-build。流水线会根据option的取值调用对应模板,四个模板都会先调用同一个setup_tasks.yml模板,该模板会执行从Bitbucket Cloud拉取源代码的checkout操作。
全局仅存在一份setup_tasks.yml,供四个模板共用。

核心配置文件

  1. azure-pipelines.yml 内容如下:
# Azure Pipeline for ACM builds.
trigger:
- azure-pipelines
- parallel-builds2
parameters:
- name: option
  type: string
  default: 'release-build'
  values:
  - 'ci'
  - 'cd'
  - 'release-test'
  - 'release-build'
- name: agent
  type: string
  default: 'ACMBUILD3'
  values:
  - 'ACMBUILD3'
  - 'ACMBUILD4'
  - 'ACMBUILD5'
  - 'ACMBUILD6'
  - 'ACMBUILD32'
  - 'ACMBUILD64'
- name: bits
  type: string
  default: '64'
  values:
  - '64'
  - '32'
pool:
  name: 'Default'
variables:
  - name: buildConfiguration
    ${{ if eq(parameters.option, 'cd')}}:
      value: 'CD'
    ${{ if eq(parameters.option, 'ci')}}:
      value: 'Debug'
    ${{ if eq(parameters.option, 'release-build')}}:
      value: 'Release'
    ${{ if eq(parameters.option, 'release-test')}}:
      value: 'Test'
  - name: theAgent
    value: ${{ parameters.agent }}
  - name: buildPlatform
    ${{ if eq(parameters.bits, '32') }}:
      value: 'x86'
    ${{ if eq(parameters.bits, '64') }}:
      value: 'x64'
  - name: nativePlatform
    ${{ if eq(parameters.bits, '32') }}:
      value: 'Win32'
    ${{ if eq(parameters.bits, '64') }}:
      value: 'x64'
jobs:
- ${{ if eq(parameters.option, 'cd') }}:
  - template: pipelines/cd-build.yml
- ${{ if eq(parameters.option, 'ci') }}:
  - template: pipelines/ci-build.yml
- ${{ if eq(parameters.option, 'release-build') }}:
  - template: pipelines/release-build.yml
- ${{ if eq(parameters.option, 'release-test') }}:
  - template: pipelines/release-test.yml
  1. CI模板pipelines/ci-build.yml内容如下,另外三个模板除了作业名称和专属业务逻辑外完全一致:
# Template for CI build
jobs:
- job: ACM_CI_Build
  timeoutInMinutes: 0 # No time limit
  pool:
    name: 'Default'
    demands:
    - Agent.Name -equals $(theAgent)
  steps:
  - template: ./setup-tasks.yml
  - powershell: | 
        Copy-Item -Path "$(Pipeline.Workspace)\s\packages" -Destination "c:\users\public" -Force -Recurse 
    displayName: Save a copy of NuGet packages 
  - powershell: |
      Write-Host "CI specific stuff starts here"
    displayName: And so on
  1. 公共检出模板pipelines/setup_tasks.yml内容如下:
steps:
- checkout: self
  clean: true
  displayName: Checkout source 
- script: type c:\users\Public\dummy.txt
  displayName: 'Verify self-hosted agent'
- powershell: |
    Write-Host "This is where the problem becomes evident"
    Write-Host "... because the named files are not found their expected places."
    Write-Host "A CI job will exit with error."
    ForEach ( $file in (
      "$(Pipeline.Workspace)\s\Build\acm_components.targets",
      "$(Pipeline.Workspace)\s\Client\something\else.txt"
      )
    )
    {
      Write-Host "Doing stuff to $file"
    }
  displayName: The AAB hack
- script: |
    Write-Host "Rest of setup.yml is NuGet tasks, et cetera"
    Write-Host "By now, the damage is done"
  displayName: And so on

问题现象

四个模板中,三个执行checkout任务的行为一致且符合预期,仅ci对应的模板执行checkout时行为异常:

  • 正常任务的checkout输出示例:
Syncing repository: blabla/acm_source_821_azure_pipelines (Bitbucket)
Prepending Path environment variable with directory containing 'git.exe'.
...
##[command]git init "C:\acmbuild6\_work\1\s"
Initialized empty Git repository in C:/acmbuild6/_work/1/s/.git/
##[command]git remote add origin https://bitbucket.org/blabla/acm_source_821_azure_pipelines
  • CI任务的checkout输出示例:
Syncing repository: blabla/acm_source_821_***_pipelines (Bitbucket)
Prepending Path environment variable with directory containing 'git.exe'.
##[command]git init "C:\acmbuild4\_work\2\s\acm_source_821_***_pipelines"
Initialized empty Git repository in C:/acmbuild4/_work/2/s/acm_source_821_***_pipelines/.git/
##[command]git remote add origin https://bitbucket.org/blabla/acm_source_821_***_pipelines

待解答问题

  1. 为什么ADO checkout任务在ci选项下会使用不同的目标目录拉取代码?
  2. 相关配置存储在ADO虚拟机还是代码仓库中,要如何访问并修改这些配置?

参考信息

  • 所有代理均为运行在Azure虚拟机上的自托管代理。
  • 目前所有构建均为手动触发,手动设置option运行时变量。
  • ci选项为最早开发的功能,其余三个选项为后续新增,该异常行为可能从ci功能上线起就存在。

已完成的排查操作

手动复制原ci-build.yml的文本内容新建了pipelines\ci-build2.yml模板,同时在ADO上新建了指向同一个Bitbucket仓库的流水线。在新流水线触发ci构建时,虽然拉取的仓库名仍有差异,但目标目录已经恢复正常。无法判断是模板修改还是新建流水线修复了目录异常问题,不清楚底层相关参数或配置的变动逻辑。


问题1解答

该异常由旧流水线的UI层残留配置导致,和代码中的YAML模板无关:
CI是最早开发的功能,早期配置流水线时,大概率在ADO流水线UI中设置过自定义检出路径、或者配置过多仓库资源,即使后续YAML模板已经统一为使用checkout: self,旧流水线的UI配置不会自动同步更新,会强制将代码检出到以仓库名命名的子目录下。其余三个选项是后续新增的,没有修改过UI层面的配置,所以沿用默认的检出路径$(Pipeline.Workspace)/s。
你新建流水线后目录恢复正常,也验证了这一点:新流水线没有历史UI配置残留,会完全按照YAML内容执行检出逻辑。

问题2解答

相关配置分为两类,存储位置和修改方式如下:

  • YAML格式的流水线配置:存储在Bitbucket代码仓库中,直接修改对应文件提交即可生效。
  • 流水线UI层面的自定义配置:存储在Azure DevOps服务端,既不在代码仓库也不在代理虚拟机中。修改方式为:打开旧的目标流水线,点击「编辑」→ 右上角三个点的更多按钮→ 「触发器」,先查看「变量」页签,删除自定义的Build.SourcesDirectory、CheckoutPath等和路径相关的变量;再查看「资源」→「仓库」页签,删除多余的仓库配置,仅保留当前使用的主仓库即可。
    如果要彻底避免该类问题,可以直接在setup_tasks.yml的checkout步骤中强制指定检出路径:
- checkout: self
  clean: true
  path: s # 强制检出到$(Pipeline.Workspace)/s目录
  displayName: Checkout source 

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.25 19:36:04