禁止在VSTS(Azure DevOps)中同时构建同一流水线

7
我在VSTS(也称为Azure DevOps)上有一个构建管道,运行在一个拥有2个构建代理(代理A和B)的代理池上,并设置了持续集成。我想禁用此构建管道在不同代理上同时执行,即如果代理A正在运行构建,则不希望在代理B上启动构建,直到代理A上的构建完成。
我可以通过更改需求来淘汰除一个以外的所有构建代理(例如,只有代理A满足需求)来实现这一点。但是,由于构建代理与其他项目共享,有时所选代理会非常繁忙,因此我不想将构建代理限制在任何特定机器上。
在VSTS中是否有简单的方法来实现这一点?

为什么你不想要并发构建? - James Reed
因为管道需要通过VSTS API更新构建变量,该变量在整个管道中都被使用。我可能可以用其他方法绕过它,但如果我可以在一个设置中禁用并发构建,那将是最简单的方法。 - scharnyw
你解决了吗? - Ian Yates
@IanYates 不,没有。我最终配置了一个专门的构建代理来完成这项工作。 - scharnyw
1
可能的解决方案:https://dev59.com/jqnka4cB1Zd3GeqPJirA#49055425/ - axmrnv
2个回答

2

0

我没有找到任何干净的解决方案,在这个线程(https://developercommunity.visualstudio.com/idea/365730/prevent-parallel-execution-of-the-same-build-defin.html)中有一个使用PowerShell作业的解决方案。

因为我的代理在Linux上,所以我用Python实现了它,使用构建代理上的环境变量(我认为变量在Windows平台上将是相同的,或者如果不是这种情况,您可以使用任务的“env”部分进行适应)。 连接到API的用户令牌隐藏在一个秘密变量中。

jobs:
-   job: ParallelRunPrevention
    timeoutInMinutes: 240
    displayName: 'prevent parallel execution of the pipeline'
    steps:
        - task: UsePythonVersion@0
          inputs:
            versionSpec: '3.x'
            addToPath: true
            architecture: 'x64'
        - script: |
            pip install azure-devops
          displayName: 'install dependency'
        - task: PythonScript@0
          displayName: 'wait for execution'
          env:
            TASK_TOKEN_USER: $(user_token)
          inputs:
            scriptSource: 'inline'
            script: |

              from azure.devops.connection import Connection
              from msrest.authentication import BasicAuthentication
              from azure.devops.v6_0.pipelines.pipelines_client import PipelinesClient
              import time
              import os


              token = os.environ["TASK_TOKEN_USER"]
              my_definition_id = int(os.environ["SYSTEM_DEFINITIONID"])
              my_build_id = int(os.environ["BUILD_BUILDID"])
              my_project = os.environ["SYSTEM_TEAMPROJECT"]
              my_organization_url = os.environ["SYSTEM_TASKDEFINITIONSURI"]
              credentials = BasicAuthentication('', token)
              connection = Connection(base_url=my_organization_url, creds=credentials)
              pipeline_c: PipelinesClient = connection.clients_v6_0.get_pipelines_client()
              while not len([run for run in pipeline_c.list_runs(project=my_project, pipeline_id=my_definition_id) if
                            run.state == "inProgress" and run.id <= my_build_id]) == 1:
                  print("not free, build stack:")
                  print([run.id for run in pipeline_c.list_runs(project=my_project, pipeline_id=my_definition_id) if
                        run.state == "inProgress" and run.id <= my_build_id])
                  time.sleep(20)
              print("lets go")

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接