1

我在 Azure Pipelines 中有一个构建管道,其中包含几个阶段。语言——C#、.Net Core 3.1/.Net Framework 4.7 在管道的第一阶段,构建了整个解决方案,并运行了单元和集成测试。在接下来的阶段,不同的微服务和 API 的单独部分将作为单独的工件发布并下载到 Azure。所有这些东西都在自托管的构建代理上运行。

我试图在测试后并行化这些阶段。逻辑是在这些阶段没有完成构建,只完成了简单的文件复制和归档。为此,我在一台计算机上从同一个池中运行了两个不同的构建代理。代理使用与他们的工作文件夹相同的本地文件夹。但是当我尝试运行构建管道时,代理开始争夺资源。构建工件的文件夹问题已解决,但不是唯一的问题。例如,两个代理都试图在 _temp 文件夹中创建/删除相同的临时文件。在这种情况下,一项任务因以下错误而失败:

[error]Unhandled: ENOENT: no such file or directory, open 'e:\_build\_temp\.taskkey'

此外,另一种奇怪的错误开始发生。错误的文本类似于下面的屏幕截图: 一个奇怪的错误文本

我想,两个代理之间的冲突导致了这些错误。

为代理使用两个不同的工作文件夹似乎不是最好的解决方案,因为在这种情况下,一个代理将无法访问在第一阶段构建的文件。

有没有人在同一台机器上运行两个 Azure Pipelines 代理来处理一个管道的成功经验?

4

2 回答 2

0

正如 Daniel 上面提到的,您不应该为本地代理使用与工作文件夹相同的本地文件夹

有一些解决方法可以在本地机器代理的不同阶段之间共享文件。

例如,您可以使用阶段 A 中的发布构建工件任务将其他阶段所需的文件发布到 azure devops 服务器。然后,您可以使用Stage B 中的下载构建工件任务来下载其工作目录中的文件。

更新:

另一种解决方法是添加一个脚本任务来定义一个变量并将其值设置为Stage A的工作目录。并在Stage B中添加对Stage A的依赖。

然后可以使用表达式dependencies.<Previous stage name>.outputs['<name of the job which execute the task.setvariable >.TaskName.VariableName']来获取Stage A中定义的变量的值,也就是Stage A的工作目录。

请查看以下示例: Stage B 可以访问 Stage A 的工作目录并将其文件复制到c:\test\copyfromoriginalfolder

stages: 
- stage: A
  jobs:
  - job: a
    pool: Default
    steps:
    - task: PowerShell@2
      inputs:
        targetType: inline
        script: |
          echo "##vso[task.setvariable variable=PathA]$(system.defaultworkingdirectory)"
      name: power1

- stage: B
  dependsOn: A
  variables:
    PathInA: $[dependencies.A.outputs['a.power1.PathA']]
  jobs:
  - job: b
    pool: Default
    steps:
    - powershell: |
        cd $(PathInA)
        ls
    - task: CopyFiles@2
      inputs:
        SourceFolder: $(PathInA)
        contents: '**'
        TargetFolder: 'c:\test\copyfromoriginalfolder'
        CleanTargetFolder: true

希望以上帮助!

于 2020-03-25T06:40:21.280 回答
0

你不能也不应该做你想做的事。代理有意在隔离的、独立的工作文件夹中运行作业。尝试针对同一个工作文件夹运行多个代理将导致与您所看到的完全一样的竞争条件和错误。

于 2020-03-24T13:00:39.993 回答