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

时间:2020-01-30 14:15:32

标签: azure azure-devops azure-pipelines-build-task

是否可以使用基于文件的触发器来构建构建管道?

假设我具有以下目录结构。

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)创建不同的版本。 是否可以检查哪个目录/文件启动了触发器并相应地设置了变量?

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

谢谢 KR

2 个答案:

答案 0 :(得分:2)

是否可以检查哪个目录/文件启动了触发器并 相应地设置变量?

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

#1:

虽然没有变量可以直接存储消息,例如修改了哪个文件夹和哪个文件,但是您可以通过commit message通过跟踪api Build.SourceVersion来获取消息。

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

从其响应主体中,您可以直接知道其路径和文件:

enter image description here

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

然后使用powershell脚本来set these value as pipeline variable,下一个代理作业/任务可以使用它们。

此外,在您的情况下,所有这些都应在所有下一个作业开始之前完成。因此,您可以考虑使用管道decorator创建一个简单的扩展。在decorator中定义上述所有步骤,以便可以在每个管道的工作前完成。


#2

您应该认为上述方法有点复杂。因此,我建议您可以使用提交消息。例如,在提交消息中指定project namefile name,并使用变量Build.SourceVersionMessage获取它们。

然后使用powershell脚本(如上所述)将它们设置为变量。

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

希望其中之一可以提供帮助。

答案 1 :(得分:0)

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

我使用“筛选”创建“ git log”,以进行目录微服务的最后一次提交。 有了一些awk(不是很令人满意的解决方案),我得到了Project&Stage,并将它们写到管道变量中。 当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脚本如下:

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

WORKING_DIRECTORY=${1}
cd ${WORKING_DIRECTORY}

CHANGEPATH="$(git log -1 --name-only --pretty='format:' -- Microservices/)"
Project=$(echo $CHANGEPATH | awk -F[/] '{print $2}')
CHANGEFILE=$(echo $CHANGEPATH | awk -F[/] '{print $4}')
Stage=$(echo $CHANGEFILE | awk -F[-] '{print $1}')
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命令请告诉我。 非常感谢。 KR