Azure DevOps 管道 – 仅在另一个管道触发时,而不是提交时触发。

huangapple go评论70阅读模式
英文:

Azure devops pipeline - trigger only on another pipeline, NOT commit

问题

要求

在Azure DevOps中有一些新功能,允许管道触发其他管道,并在此处记录:https://learn.microsoft.com/en-us/azure/devops/pipelines/build/triggers?view=azure-devops&tabs=yaml#pipeline-triggers-1 这听起来很棒,除了我无法获得所需的行为。我希望在同一个存储库中有2个管道:

  • 管道A:仅由其自己存储库之外的多个其他管道触发,但在同一项目中。作为被触发的结果,它对其自己的存储库进行更改,因此触发了管道B。
  • 管道B:仅在其自己的存储库发生更改时触发,并在触发时执行所需的任何操作。

管道A语法

资源:
    管道:
    - 管道:数据库
      来源:数据库
      触发器:
        分支:
        - develop
        - release/*
        # 根据以下链接,阶段过滤器应该工作:https://learn.microsoft.com/en-us/azure/devops/pipelines/build/triggers?view=azure-devops&tabs=yaml
        # 但是,当指定以下内容时会出现错误:/azure-pipelines.yml(第8行,第15列):管道资源数据库中不支持阶段过滤器。
        #stages:
        #- 构建
    - 管道:身份验证
      来源:身份验证
      触发器:
        分支:
        - develop
        - release/*
    - 管道:API
      来源:API
      触发器:
        分支:
        - develop
        - release/*
    - 管道:Web
      来源:Web
      触发器:
        分支:
        - develop
        - release/*
  ... 多个触发器 - 共9个
阶段:
  ...

当前行为

管道A不会被任何其他管道触发,只有在其自己的存储库发生更改时才会触发。由于它自己的存储库已经发生更改,因此它会陷入无限循环。

问题/评论

  • 管道A的语法是否正确?
  • 从文档中了解到:“但是,如果这两个管道使用不同的存储库,则触发的管道将使用其默认分支的最新代码。” 我假设这意味着yaml管道将在默认分支中被激活。我们真的没有那么少的控制吗?最好在管道声明中指定目标分支。
  • 是否可能以某种方式获取触发管道的源分支?
  • 为什么阶段过滤器不按照文档工作?
  • 在管道A中,为了阻止循环,我尝试使用$(Build.TriggeredBy.DefinitionId)来检查是否与$(System.DefinitionId)相同,如果是,则跳过构建步骤,但$(Build.TriggeredBy.DefinitionId)没有值。
  • 如果我无法使其工作,我倾向于让其他管道触发管道A。

发现

  • 在管道A的顶部添加trigger: none可以防止在提交到其存储库时运行它,目前它根本不运行!
  • 在单独的帐户中的简化管道场景中,我设法让触发的构建工作,在同一个存储库中有2个管道,并发现:
    • 执行的yaml管道文件与触发管道上的提交所在的分支相同
    • 检出的代码也来自于触发管道上的提交所在的分支
    • 从GUI手动运行管道不会触发依赖管道
    • 依赖管道在第一个开始后立即触发并排队
    • 我无法让分支排除起作用:不管排除子句如何,管道都会触发
  • 在单独的帐户中运行简化的管道场景,在存储库C中有管道A,而在存储库D中有依赖的管道B(同一个项目),到目前为止我无法让管道A触发管道B(我的原始情景)
  • 哦,太棒了 Azure DevOps 管道 – 仅在另一个管道触发时,而不是提交时触发。 有一个Azure DevOps命令行扩展,支持管道,并允许您触发管道:
    • 安装:https://learn.microsoft.com/en-us/azure/devops/cli/?view=azure-devops
    • 管道运行文档:https://learn.microsoft.com/en-us/cli/azure/ext/azure-devops/pipelines?view=azure-cli-latest#ext-azure-devops-az-pipelines-run
    • 示例管道触发命令:az pipelines run --branch master --name "<PipelineName>" --org "https://dev.azure.com/<OrganisationName>" -p "<ProjectName>"
    • 示例Azure DevOps集成:https://learn.microsoft.com/en-us/azure/devops/cli/azure-devops-cli-in-yaml?view=azure-devops
英文:

Requirement

So, there is some newish functionality in Azure DevOps which allows pipelines to trigger other pipelines and is documented here: https://learn.microsoft.com/en-us/azure/devops/pipelines/build/triggers?view=azure-devops&tabs=yaml#pipeline-triggers-1 It sounds great, apart from the fact I can't get the behaviour I need. I want 2 pipelines in the same repository:

  • Pipeline A: is only triggered by multiple other pipelines outside of its own repo, but in the same project. As a result of being triggered it makes a change to its own repo and therefore triggers pipeline B.
  • Pipleline B: is only triggered by changes to its own repo and when triggered goes ahead and does whatever it needs to do

Pipeline A Syntax

resources:
    pipelines:
    - pipeline: database
      source: database
      trigger:
        branches:
        - develop
        - release/*
        # The stages filter should work, according to: https://learn.microsoft.com/en-us/azure/devops/pipelines/build/triggers?view=azure-devops&tabs=yaml
        # However, this error occurs when specifying: /azure-pipelines.yml (Line: 8, Col: 15): Stage filters in pipeline resource database is not supported.
        #stages:
        #- Build
    - pipeline: auth
      source: auth
      trigger:
        branches:
        - develop
        - release/*
    - pipeline: api
      source: api
      trigger:
        branches:
        - develop
        - release/*
    - pipeline: web
      source: web
      trigger:
        branches:
        - develop
        - release/*
  ... multiple triggers - 9 in total
stages:
  ...

Current Behaviour

Pipeline A is not triggered by any of the other pipelines, but only on changes to its own repo. Since it makes changes to its own repo anyway, it triggers itself in an endless loop.

Questions / Comments

  • Is the syntax for Pipeline A correct?
  • From the documentation: "However, if the two pipelines use different repositories, then the triggered pipeline will use the latest version of the code from its default branch." I'm assuming this means the yaml pipeline from the default branch will be activated. And do we really have that little control? It'd be far better to specify the target branch in the pipeline declarations.
  • Is it possible to somehow get the source branch which triggered the pipeline?
  • Why don't stage filters work as documented?
  • In Pipeline A, to stop the looping, I tried using $(Build.TriggeredBy.DefinitionId) to check if that was the same as $(System.DefinitionId) and skip the build steps if so, but $(Build.TriggeredBy.DefinitionId) didn't have a value
  • I'm leaning towards getting the other pipelines to trigger Pipeline A if I can't get it to work.

Discovery

  • Adding trigger: none to the top of the pipeline A prevented it from running when commits were made to its repo, it just doesn't run at all currently!
  • In a simplified pipeline scenario in a separate account, I managed to get triggered builds working, with 2 pipelines in the same repo and found:
    • The yaml pipeline file executed is on the same branch as the commit on the triggering pipeline
    • The code checked out is also from the same branch as the commit on the triggering pipeline
    • Manual pipeline execution from the GUI does not trigger dependent pipelines
    • The dependent pipeline is triggered and queued immediately the first starts
    • I couldn't get branch exclusion to work: the pipeline triggered regardless of the exclusion clause
  • Running a simplified pipeline scenario in a separate account, with pipeline A in repo C and dependant pipeline B in repo D (same project), I am unable to get pipeline A to trigger pipeline B so far (my original scenario)
  • Oh great joy Azure DevOps 管道 – 仅在另一个管道触发时,而不是提交时触发。 there's an az azure devops command line extension which has got pipeline support and lets you trigger a pipeline:

答案1

得分: 12

工作解决方案

因为我所有的构建都集中在一个管道模板中,我将此模板更改为在成功发布工件时触发我的管道 A。以下是管道触发代码,基本上与 (https://learn.microsoft.com/en-us/azure/devops/cli/azure-devops-cli-in-yaml?view=azure-devops) 中的代码一致,除了最后几个步骤:

# 更新 Linux 代理上可用的 Python 版本
- task: UsePythonVersion@0
  displayName: 升级构建代理 Python 版本
  inputs:
    versionSpec: '3.x'
    architecture: 'x64'

# 更新 pip 到最新版本
- script: python -m pip install --upgrade pip
  displayName: '升级 pip'

# 更新到最新的 Azure CLI 版本。
- script: pip install --pre azure-cli --extra-index-url https://azurecliprod.blob.core.windows.net/edge
  displayName: '升级 Azure CLI'

- script: az --version
  displayName: '显示 Azure CLI 版本'

- script: az extension add -n azure-devops
  displayName: '安装 Azure DevOps 扩展'

- script: echo ${AZURE_DEVOPS_CLI_PAT} | az devops login
  env:
    AZURE_DEVOPS_CLI_PAT: $(System.AccessToken)
  displayName: '登录 Azure DevOps 扩展'

- script: az devops configure --defaults organization=$(System.TeamFoundationCollectionUri) project="$(System.TeamProject)" --use-git-aliases true
  displayName: '设置默认的 Azure DevOps 组织和项目'

- script: |
    set -euo pipefail
    if [[ "$(Build.SourceBranch)" == *"/release/"* ]]; then
      branchName="master"
    else
      branchName="develop"
    fi
    commandLine="--branch $branchName --name <YourPipelineName>"
    echo "触发发布创建:az pipelines run $commandLine"
    az pipelines run $commandLine    
  displayName: 为内部 (develop) 和外部 (release) 构建触发发布构建

注意事项

  • 根据需要更改 <YourPipelineName>,并且你的分支名称处理方式可能与我的不同。
  • Azure CLI 升级需要 1.5 分钟,如果要显著加快速度,只需删除前三个步骤。
  • 我宁愿触发的管道声明其自己的触发器,因为如果你能看到触发的原因,维护起来会更容易,但是无论如何。
英文:

Working Solution

Because all of my builds are centralised in one pipeline template, I changed this template to trigger my pipeline A on successful publishing of an artifact. Here's the pipeline trigger code which is pretty much verbatim from (https://learn.microsoft.com/en-us/azure/devops/cli/azure-devops-cli-in-yaml?view=azure-devops), apart from the last couple of steps:

# Updating the python version available on the linux agent
    - task: UsePythonVersion@0
      displayName: Upgrade build agent Python version
      inputs:
        versionSpec: &#39;3.x&#39;
        architecture: &#39;x64&#39;

    # Updating pip to latest
    - script: python -m pip install --upgrade pip
      displayName: &#39;Upgrade pip&#39;

    # Updating to latest Azure CLI version.
    - script: pip install --pre azure-cli --extra-index-url https://azurecliprod.blob.core.windows.net/edge
      displayName: &#39;Upgrade azure cli&#39;

    - script: az --version
      displayName: &#39;Show Azure CLI version&#39;

    - script: az extension add -n azure-devops
      displayName: &#39;Install Azure DevOps Extension&#39;

    - script: echo ${AZURE_DEVOPS_CLI_PAT} | az devops login
      env:
        AZURE_DEVOPS_CLI_PAT: $(System.AccessToken)
      displayName: &#39;Login Azure DevOps Extension&#39;

    - script: az devops configure --defaults organization=$(System.TeamFoundationCollectionUri) project=&quot;$(System.TeamProject)&quot; --use-git-aliases true
      displayName: &#39;Set default Azure DevOps organization and project&#39;

    - script: |
        set -euo pipefail
        if [[ &quot;$(Build.SourceBranch)&quot; == *&quot;/release/&quot;* ]]; then
          branchName=&quot;master&quot;
        else
          branchName=&quot;develop&quot;
        fi
        commandLine=&quot;--branch $branchName --name &lt;YourPipelineName&gt;&quot;
        echo &quot;Triggering release creation with: az pipelines run $commandLine&quot;
        az pipelines run $commandLine
      displayName: Trigger release build for internal (develop) and external (release) builds

Caveats

  • Change &lt;YourPipelineName&gt; as appropriate, and your branch name handling is going to be different to mine
  • The Azure CLI upgrade takes 1.5 minutes, so just delete the first 3 steps if you want to significantly speed it up
  • I'd rather the triggered pipeline declared its own triggers, as it's easier to maintain if you can see what's causing it to trigger, but hey-ho

答案2

得分: 2

我遇到了相同的问题。
我在这里找到了解决方案:
https://developercommunity.visualstudio.com/content/problem/864701/pipeline-trigger-not-working-as-expressed-in-docum.html?childToView=897210#comment-897210

简而言之,当我将依赖管道中的defaultBranch更改为我的工作分支时,触发开始起作用:
您需要前往:

编辑 -&gt; 触发器(右上角的3个点) -&gt; YAML -&gt; 获取源 -&gt; 手动和计划构建的默认分支

在那里放入您的YAML管道存在的分支。
Azure DevOps 管道 – 仅在另一个管道触发时,而不是提交时触发。

英文:

I was running into the same issue.
I found solution over here:
https://developercommunity.visualstudio.com/content/problem/864701/pipeline-trigger-not-working-as-expressed-in-docum.html?childToView=897210#comment-897210

In shortcut, when I've changed defaultBranch in my dependent pipeline to my working branch
triggering start working.:
You need to go:

Edit -&gt; Triggers (3 dots in right upper corner) -&gt; YAML -&gt; Get sources -&gt; Default branch for manual and scheduled builds

Over there put a branch in which your yaml pipeline exists.
Azure DevOps 管道 – 仅在另一个管道触发时,而不是提交时触发。

答案3

得分: 0

如果您没有从触发管道发布工件,它将不会触发被触发的管道。我已经创建了一个最小可行产品,其中这个功能是有效的,并且我已经在这个 答案 中解释了这个过程。

英文:

If you're not publishing an artifact from the triggering pipeline, it won't trigger the triggered pipeline. I have created a minimum viable product where this is working, and I have explained the process in this answer.

huangapple
  • 本文由 发表于 2020年1月4日 01:50:34
  • 转载请务必保留本文链接:https://go.coder-hub.com/59583099.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定