Azure Pipeline 从Bitbucket 云端拉取代码时,为什么本地工作目录不一致?

When Azure Pipeline pulls code from Bitbucket cloud, why is the local working directory inconsistent?

我有一个 Azure DevOps (ADO) 管道,其中包含一个名为 option 的运行时变量或参数。 option 的值可以是 buildtestcicd。管道立即根据 option 的值调用模板。然后,这些模板中的每一个都会立即调用另一个模板 setup_tasks.ymlsetup_tasks.yml 模板立即从 Bitbucket 云中检出源代码。

只有一个 setup_tasks.yml。所有四个模板都使用它。

`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

模板内容pipelines/ci-build.yml。其他三个模板是相同的,除了作业名称,直到“CI specific stuff starts here”这一点。因此这里只展示一个模板:

# 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

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 的)执行方式不同。

这是三个正确方法的相关输出。

Syncing repository: blabla/acm_source_821_azure_pipelines (Bitbucket)
Prepending Path environment variable with directory containing 'git.exe'.
...
##[command]git init "C:\acmbuild6\_work\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 任务的执行方式。

Syncing repository: blabla/acm_source_821_***_pipelines (Bitbucket)
Prepending Path environment variable with directory containing 'git.exe'.
##[command]git init "C:\acmbuild4\_work\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

为什么 ADO checkout 任务对我的选项 ci 使用与其他选项不同的存储库和目标目录?

此配置信息存储在我的 ADO VM 上的什么位置(或者可能在存储库中),我如何访问它来编辑信息?

作业流程的屏幕截图,以及由此产生的错误。

可能有帮助的其他信息

故障排除工作

我创建了一个重复的模板,名为 pipelines\ci-build2.yml。我从原始 ci-build.yml 模板复制文本并将其粘贴到 ci-build2.yml,而不是像 cp ci-build.yml ci-build2.yml 这样的命令 运行。这样我就确保我只得到了文本。

然后我在 ADO 上创建了一个新的管道。此管道使用与原始管道相同的 BBCloud 存储库 -- 因此其操作与原始管道相同。

当我 select 在这个新管道上构建 ci 时,它仍然使用不同的存储库,但这次它使用了正确的目标目录。

我不知道这两个更改中的哪一个(不同的 ci-build.yml 模板,不同的管道)解决了这个问题,因为我看不到引擎盖下发生了什么。我不知道更改了哪些参数或配置设置。谁能给我一些提示?

问题出在 `pipelines/ci-build.yml' 的一部分,我没有将其放入原始问题陈述的代码清单中,因为我认为它不相关。原来是关键的一块。

完成上面清单中显示的步骤后,pipelines/ci-build.yml 的下一步是再次检出源。 checkout 任务在 pipelines/setup-tasks.ymlpipelines/ci-build.yml 中是相同的。

- checkout: self
  clean: true

根据 Checkout path 文档,管道可以签出单个存储库或多个存储库。

  • 如果是单个存储库,它会进入 c:\acmbuild6\_work\s。 (遵循原始问题陈述中的路径名)
  • 如果有多个存储库,则每个存储库都位于其自己的子目录中。所以他们进入 c:\acmbuild6\_work\s\FirstRepoNamec:\acmbuild6\_work\s\SecondRepoName.

当我编写管道文件时,我假设因为两个文件中引用了同一个存储库,所以它被算作“单个存储库”。但是,Azure Pipelines 似乎将多个 checkout 任务视为“多个存储库”;因此,它将我的代码检出到 c:\acmbuild6\_work\s\acm_source_821_azure_pipelines。两次。

问题的简单解决方法是在checkout任务中cify目标路径explicitly:

steps:
- checkout: self
  clean: true
  path: s

路径是相对于管道工作空间定义的,在我的例子中是 c:\acmbuild6\_work,或者在一般情况下是 c:\<agent>\_work\<n>。此解决方案已经过测试,有效。

更好的解决方案是重写管道或项目源代码,这样 ci-build.yml 中的第二个 checkout 就不需要了。