Azure Pipeline 基于文件的触发器和标记

Azure Pipeline File-based Trigger and Tags

是否可以使用基于文件的触发器创建构建流水线?

假设我有以下目录结构。

Microservices/
    |_Service A
        |_Test_Stage
            |_Testing_Config
        |_QA_Stage
            |_QA_Config
        |_Prod_stage
            |_Prod_Config
    |_Service B
        |_Test_Stage
            |_Testing_Config
        |_QA_Stage
            |_QA_Config
        |_Prod_stage
            |_Prod_Config

我只想拥有一个 YAML 构建管道文件。 基于变量 $(Project) & $(Stage) 创建不同的构建。 是否可以检查是什么 directory/file 启动了触发器并相应地设置变量?

此外,如果可以在 运行 之后使用这些变量为工件设置标签,那就太好了。

谢谢 韩国

Is it possible to check what directory/file initiated the Trigger and set the variables accordingly?

当然可以。但是没有直接的方法,因为我们没有提供任何预定义的变量来存储此类消息,因此您需要额外的复杂工作来获得它。

#1:

虽然没有变量可以直接存储哪个文件夹、哪个文件被修改等信息,但是可以通过跟踪commit message Build.SourceVersion via api.

得到
GET https://dev.azure.com/{organization}/{project}/_apis/git/repositories/{repositoryId}/commits/{commitId}/changes?api-version=5.1

从它的响应体中,可以直接知道它的路径和文件:

由于响应主体是JSON格式,您可以使用一些JSON函数来解析这个路径值。请参阅此 脚本作为参考。

然后使用 powershell 脚本 下一个代理 jobs/tasks 可以使用它们。

此外,在您的场景中,所有这些都应该在所有下一个作业开始之前完成。因此,您可以考虑使用管道 decorator 创建一个简单的扩展。在decorator中定义以上所有步骤,以便在每个流水线的pre-job中完成。


#2

想你应该觉得上面的方法有点复杂。所以我宁愿建议你可以使用 commit messge。例如,在提交消息中指定 project namefile name,使用变量 Build.SourceVersionMessage 获取它们。

然后使用powershell 脚本(我在上面提到过)将它们设置为变量。

这比使用 api 解析提交主体更方便。

希望其中一位能有所帮助。

感谢您的回复。 我用 Bash 脚本尝试了不同的方法。 因为我只使用 ubuntu 图片。

我对目录微服务的最后一次提交进行了过滤 "git log"。 通过一些 awk(不是一个令人满意的解决方案),我得到了项目和阶段并将它们写入管道变量。 当 Microservices/* 路径发生变化时,管道就会被触发。

trigger:
  batch: true
  branches:
    include:
    - master
  paths:
    include: 
    - Microservices/*

触发器激活时的第一个作业是 Dynamic_variables 作业。 这个作业我只用来设置变量 $(Project) & $(Stage)。此外,构建标签是使用这些变量设置的,因此我能够区分发布中的工件。

jobs:
  - job: Dynamic_Variables
    pool:
      vmImage: 'ubuntu-latest'
    steps:
      - checkout: self
      - task: Bash@3
        name: Dynamic_Var
        inputs:
          filePath: './scripts/multi-usage.sh'
          arguments: '$(Build.SourcesDirectory)'
        displayName: "Set Dynamic Variables Project"
      - task: Bash@3
        inputs:
          targetType: 'inline'
          script: |
            set +e
            if [ -z $(Dynamic_Var.Dynamic_Project) ]; then
            echo "target Project not specified";
            exit 1;
            fi
            echo "Project is:" $(Dynamic_Var.Dynamic_Project)
        displayName: 'Verify that the Project parameter has been supplied to pipeline'
      - task: Bash@3
        inputs:
          targetType: 'inline'
          script: |
            set +e
            if [ -z $(Dynamic_Var.Dynamic_Stage) ]; then
            echo "target Stage not specified";
            exit 1;
            fi
            echo "Stage is:" $(Dynamic_Var.Dynamic_Stage)
        displayName: 'Verify that the Stage parameter has been supplied to pipeline'

此作业中的 Bash 脚本 I 运行 如下所示:

#!/usr/bin/env bash
set -euo pipefail

WORKING_DIRECTORY=
cd ${WORKING_DIRECTORY}

CHANGEPATH="$(git log -1 --name-only --pretty='format:' -- Microservices/)"
Project=$(echo $CHANGEPATH | awk -F[/] '{print }')
CHANGEFILE=$(echo $CHANGEPATH | awk -F[/] '{print }')
Stage=$(echo $CHANGEFILE | awk -F[-] '{print }')
echo "##vso[task.setvariable variable=Dynamic_Project;isOutput=true]${Project}"
echo "##vso[task.setvariable variable=Dynamic_Stage;isOutput=true]${Stage}"
echo "##vso[build.addbuildtag]${Project}"
echo "##vso[build.addbuildtag]${Stage}"

如果有人有更好的解决方案,请告诉我 awk 命令。 非常感谢。 韩国