首页 > 解决方案 > 在 azure 管道作业中使用 for 循环

问题描述

我将使用一个 for 循环来扫描文件夹中的文件(value-f1.yaml、values-f2.yaml、...),并且每次使用文件名作为变量并在 Azure 管道作业中运行作业根据该值文件部署 helmchart。该文件夹位于 GitHub 存储库中。所以我在想这样的事情:

管道.yaml

 stages:
  - stage: Deploy
    variables:
      azureResourceGroup: ''
      kubernetesCluster: ''
      subdomain: ''
    jobs:
    ${{ each filename in /myfolder/*.yaml}}:
       valueFile: $filename 
       - template: Templates/deploy-helmchart.yaml@pipelinetemplates    

部署 helmchart.yaml

 jobs:
    - job: Deploy
      pool:
        vmImage: 'ubuntu-latest'
      steps:
      - task: HelmInstaller@1
        displayName: 'Installing Helm'
        inputs:
          helmVersionToInstall: '2.15.1'
        condition: and(succeeded(), startsWith(variables['build.sourceBranch'], 'refs/tags/v'))  

      - task: HelmDeploy@0
        displayName: 'Initializing Helm'
        inputs:
          connectionType: 'Azure Resource Manager'
          azureSubscription: $(azureSubscription)
          azureResourceGroup: $(azureResourceGroup)
          kubernetesCluster: $(kubernetesCluster)
          command: 'init'
        condition: and(succeeded(), startsWith(variables['build.sourceBranch'], 'refs/tags/v'))  

      - task: PowerShell@2
        displayName: 'Fetching GitTag'
        inputs:
          targetType: 'inline'
          script: |
            # Write your PowerShell commands here.
            Write-Host "Fetching the latest GitTag"
            $gt = git describe --abbrev=0
            Write-Host "##vso[task.setvariable variable=gittag]$gt"
        condition: and(succeeded(), startsWith(variables['build.sourceBranch'], 'refs/tags/v'))    


      - task: Bash@3
        displayName: 'Fetching repo-tag'
        inputs:
          targetType: 'inline'
          script: |
            echo GitTag=$(gittag)
            echo BuildID=$(Build.BuildId)
            echo SourceBranchName=$(Build.SourceBranchName)
            echo ClusterName= $(kubernetesCluster)

      - task: HelmDeploy@0
        displayName: 'Upgrading helmchart'
        inputs:
          connectionType: 'Azure Resource Manager'
          azureSubscription: $(azureSubscription)
          azureResourceGroup: $(azureResourceGroup)
          kubernetesCluster: $(kubernetesCluster)
          command: 'upgrade'
          chartType: 'FilePath'
          chartPath: $(chartPath)
          install: true
          releaseName: $(releaseName)
          valueFile: $(valueFile)
          arguments: '--set image.tag=$(gittag) --set subdomain=$(subdomain)'
        condition: and(succeeded(), startsWith(variables['build.sourceBranch'], 'refs/tags/v'))  

另一件事是,如果作业可以默认访问 GitHub 存储库,还是我需要在作业级别做一些事情?

此外,在这种情况下,我如何在工作中使用 for-loop?

任何帮助,将不胜感激。

在收到@Leo 的评论后更新

这是我在 deploy-helmchart.yaml 中添加的 PowerShell 任务,用于从 GitHub 的文件夹中获取文件。

 - task: PowerShell@2
   displayName: 'Fetching Files'
   inputs:
     targetType: 'inline'
     script: |
       Write-Host "Fetching values files"
       cd myfolder
       $a=git ls-files
       foreach ($i in $a) {
          Write-Host "##vso[task.setvariable variable=filename]$i"
          Write-Host "printing"$i
       }

现在的问题是如何使用参数运行任务:HelmDeploy@0 为每个文件?

标签: for-loopazure-devopsazure-pipelines

解决方案


如果作业可以默认访问 GitHub 存储库,还是我需要在作业级别做一些事情?

答案是肯定的。

我们可以在作业中添加一个命令行任务,例如job1通过 Github PAT 克隆 GitHub 存储库,然后我们可以在以下位置访问这些文件(value-f1.yaml、、values-f2.yaml...)$(Build.SourcesDirectory)

git clone https://<GithubPAT>@github.com/XXXXX/TestProject.git

此外,在这种情况下,我如何在工作中使用 for-loop?

您可以创建一个包含一组操作的模板,并在构建过程中传递参数,例如:

部署 helmchart.yaml:

parameters:
  param : []

steps:
  - ${{each filename in parameters.param}}:
    - scripts: 'echo ${{ filename  }}'

管道.yaml:

steps:
 - template: deploy-helmchart.yaml
   parameters:
     param: ["filaname1","filaname2","filaname3"]

查看文档解决 Azure DevOps Pipelines 中的循环问题以获取更多详细信息。

命令行获取文件夹中的最新文件名:

   FOR /F "delims=|" %%I IN ('DIR "$(Build.SourcesDirectory)\*.txt*" /B /O:D') DO SET NewestFile=%%I
    
   echo "##vso[task.setvariable variable=NewFileName]NewestFile"

更新:

现在的问题是如何使用参数运行任务:HelmDeploy@0 为每个文件?

HelmDeploys depends on whether your 任务具有接受文件名参数的选项。

正如我之前所说,我们可以使用以下 yaml 来调用带有参数的模板 yaml:

 - template: deploy-helmchart.yaml
   parameters:
     param: ["filaname1","filaname2","filaname3"]

但是,如果任务HelmDeploy没有接受参数的选项,我们就不能HelmDeploy@0使用参数为每个文件运行任务。

然后我查了一下HelmDeploy@0,发现只有一个选项可以接受Helm 命令参数:

在此处输入图像描述

因此,这个问题的答案取决于您的文件名是否可以用作 Helm 命令,如果不能,则无法HelmDeploy@0使用参数为每个文件运行任务。如果是,你可以做到。

请查看官方文档模板了解更多详细信息。

希望这可以帮助。


推荐阅读