使用两个自托管的 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
希望以上帮助!
我在 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
希望以上帮助!