使用两个自托管的 Azure 管道代理以并行模式发布工件

Using two self-hosted Azure pipeline agents for artifact publishing in parallel mode

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

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

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

此外,另一种类型的 st运行ge 错误开始出现。错误文本类似于下面的屏幕截图: A strange error text

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

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

有人成功地运行在同一台机器上安装两个 Azure Pipelines 代理来处理一个管道吗?

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

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

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

例如,您可以在阶段B中使用publish build artifacts task in stage A to publish the files that are needed in other stages to azure devops server. Then you can use download build artifacts task来下载其工作目录中的文件。

更新:

另一种解决方法是在 Stage A 的工作目录中添加脚本任务 define a variable and set its value。并在 Stage B 中添加对 Stage A 的依赖。

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

请查看以下示例:阶段 B 可以访问阶段 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

希望以上帮助!