无法在 Azure Pipelines 中有条件地下载安全文件

问题描述

问题 我正在使用 DownloadSecureFile@1 任务下载安全文件。 在 Azure DevOps 中,在库的安全文件部分中,仅存在 file_A.txt 时会出现此问题。 当两个文件都存在时,脚本工作正常。

在我的例子中,用户 A 只需要 file_A.txt,用户 B 只需要 file_B.txt。 这是预期的行为吗?任何可能的解决方法来满足用例?

错误信息: 存在资源授权问题:“管道无效。作业作业:步骤 fileB 输入 secureFile 引用了无法找到的安全文件 file_B.txt。安全文件不存在或未被授权使用。有关授权详细信息,参考https://aka.ms/yamlauthz."

代码

parameters:
- name: file_name
  type: string
  default: ''
  values:
    - file_A.txt
    - file_B.txt


pool:
  vmImage: ubuntu-latest
steps:
    - task: DownloadSecureFile@1
      displayName: Download File A
      condition: eq('${{ parameters.file_name }}','file_A.txt')
      name: fileA
      inputs:
        secureFile: 'file_A.txt'        

    - task: DownloadSecureFile@1
      displayName: Download file B
      condition: eq('${{ parameters.file_name }}','file_B.txt')
      name: fileB
      inputs:
        secureFile: 'file_B.txt'    

解决方法

这是预期的行为吗?

是的,这是预期的行为。要将管道转换为运行,Azure Pipelines 按以下顺序执行以下几个步骤:

  1. 首先,展开模板并评估模板表达式。
  2. 接下来,在阶段级别评估依赖项以选择第一个 要运行的阶段。
  3. 对于选择运行的每个阶段,会发生两件事:
    • 收集所有作业中使用的所有资源并进行验证
      运行授权。
    • 评估工作级别的依赖关系以选择第一个工作 运行。
  4. 对于选择运行的每个作业,展开多配置(策略:矩阵 或策略:在 YAML 中并行)到多个运行时作业中。
  5. 对于每个运行时作业,评估条件以确定该作业是否 有资格运行。
  6. 为每个符合条件的运行时作业请求一个代理。

因此,您的安全文件将在评估条件之前下载。请参阅有关 Pipeline run sequence 的文档。作为解决方法,您可以参考@danielorn 分享的示例。

,

您可以使用 if 语句包围该步骤,而不是在任务上使用条件,如 use parameters to determine what steps run

中所述
parameters:
- name: file_name
  type: string
  default: ''
  values:
    - file_A.txt
    - file_B.txt

pool:
  vmImage: ubuntu-latest
steps:
- ${{ if eq(parameters.file_name,'file_A.txt') }}:
  - task: DownloadSecureFile@1
    displayName: Download File A
    name: fileA
    inputs:
      secureFile: 'file_A.txt'        
- ${{ if eq(parameters.file_name,'file_B.txt') }}:
  - task: DownloadSecureFile@1
    displayName: Download file B
    name: fileB
    inputs:
      secureFile: 'file_B.txt'   

然而,如果每个用户只需要一个文件,一个常见的(更干净的)选项是提供所需文件的名称作为参数。如果不需要安全文件(即参数默认为空),可以使用 if 语句排除该步骤

parameters:
- name: file_name
  type: string
  default: ''
  values:
    - file_A.txt
    - file_B.txt

pool:
  vmImage: ubuntu-latest
steps:
- ${{ if ne(parameters.file_name,'') }}:
  - task: DownloadSecureFile@1
    displayName: Download Secure File 
    name: secureFileDownload
    inputs:
      secureFile: '${{ parameters.file_name }}'