azure-pipelines.yml 中的多个单独触发器

soc*_*pet 14 azure azure-devops azure-pipelines

我目前有一个在子目录中提供服务的 monorepo,我倾向于将其转变为带有 metarepo 的 multirepo。

我决定尝试 Azure DevOps 的原因之一是有人告诉我您可以在子目录上设置触发器,例如:

trigger:
  branches:
    include:
    - master
  paths:
    include:
    - client
Run Code Online (Sandbox Code Playgroud)

经测试,它有效。

但是,我想知道是否可以有多个独立的触发器,或者这是否需要 polyrepo 或 multiple .yml?原因是如果client服务中只有更改,它只会触发那组测试、构建和部署,而不会触发api服务运行测试、构建和部署。

例如:

trigger:
  branches:
    include:
    - master
  paths:
    include:
    - client

  stages:
    ...
    Run tests
    If tests pass, build and push to ACR
    Deploy to AKS
    ...

trigger:
  branches:
    include:
    - master
  paths:
    include:
    - api

  stages:
    ...
    Run tests
    If tests pass, build and push to ACR
    Deploy to AKS
    ...
Run Code Online (Sandbox Code Playgroud)

这样,一个更改不会导致整个应用程序被重建,只是改变了什么。

但是,这是否需要多个.yml文件(甚至不确定是否azure-pipelines.yml可以识别任何其他文件),这是否需要 polyrepo,或者这是否可以在azure-pipelines.yml我没有看到的单个文件中执行?

Lev*_*SFT 13

如果我正确理解您的要求。您可以在单个 azure-pipeline.yml 中实现此目的。请检查以下示例 yml。

trigger:
  branches:
    include:
    - master
  paths:
    include:
    - client/*
    - api/*

jobs:
- job: getchangepath
  pool:
    vmImage: 'windows-latest'
  steps: 
  - powershell: |
      $url="$(System.CollectionUri)/$(System.TeamProject)/_apis/git/repositories/$(Build.Repository.ID)/commits/$(Build.SourceVersion)/changes?api-version=5.1"
      $result = Invoke-RestMethod -Uri $url -Headers @{Authorization = "Bearer $(System.AccessToken)"} -Method GET
                       
      $changesFolder = $result.changes | Where-Object{$_.item.gitObjectType -match "tree"} | Select-Object -Property {$_.item.path}
     
      foreach($path in $changesFolder){
        if($path -match '/client'){
          echo "##vso[task.setvariable variable=Client;isOutput=true]$True"
          break
        }
      }

      foreach($path in $changesFolder){
        if($path -match '/api'){
          echo "##vso[task.setvariable variable=Api;isOutput=true]$True"
          break
        }
      }
    name: MyVariable

- job: client
  pool :
    vmImage: 'windows-latest'
  dependsOn: getchangepath
  condition: eq(dependencies.getchangepath.outputs['Myvariable.Client'], 'true')
  steps:
  - powershell: echo 'client job start'
  
- job: api
  pool :
    vmImage: 'windows-latest'
  dependsOn: getchangepath
  condition: eq(dependencies.getchangepath.outputs['Myvariable.Api'], 'true')
  steps:
  - powershell: echo 'api job start'
Run Code Online (Sandbox Code Playgroud)

在上面的yml。我有三份工作。在第一份工作中,getchangepath我在 powershell 任务中调用git get changes rest api 来获取触发构建的更改路径。和输出变量,如果路径中包含路径/client/api

工作的客户和工作API是依赖于工作getchangepath,将在作业的输出变量的条件执行getchangepath

假设我更改了文件夹客户端中的一个文件并将更改提交到 azure repo。然后工作getchangepath完成后。MyVariable.Client将被设置为 true。然后作业客户端将评估其状况并开始使用。Job Api 将无法满足其条件并被跳过。


jul*_*-ng 8

我最近遇到了这个问题。您无需在上述解决方案中硬编码和访问 DevOps API 和 PowerShell 代码。

这是一个更简单的解决方案,使用开箱即用的 YAML和官方 Azure DevOps 文档中的workingDirectory属性

设置这样的项目结构,每个存储库都有自己的 YAML 文件:

.
??? README.md
??? azure-pipelines.yml
??? service-a
|?? azure-pipelines-a.yml
?   ??? …
??? service-b
        |?? azure-pipelines-b.yml
        ??? …
Run Code Online (Sandbox Code Playgroud)

您可能不需要根管道,但如果需要,您将要忽略子项目:

.
??? README.md
??? azure-pipelines.yml
??? service-a
|?? azure-pipelines-a.yml
?   ??? …
??? service-b
        |?? azure-pipelines-b.yml
        ??? …
Run Code Online (Sandbox Code Playgroud)

而在子项目中,你希望他们关注自己:

# Excerpt from /azure-pipeline.yml 

trigger:
  paths:
    exclude: # Exclude!
      - 'service-a/*'
      - 'service-b/*'
Run Code Online (Sandbox Code Playgroud)

警告 - 工作目录!

您的子项目管道仍在以根目录作为您的工作目录运行。例如,您可以使用workingDirectory键更改此设置(使用变量来避免重复):

# Excerpt from /service-a/azure-pipeline-a.yml

trigger:
  paths:
    include: # Include!
      - 'service-a/*' # or 'service-b/*'
Run Code Online (Sandbox Code Playgroud)

如果您的项目共享步骤,您应该根据官方文档使用管道模板(在另一个存储库中)