如何在Github Actions的if条件语句中检查秘密变量是否为空

23

背景

在执行工作之前,我希望在我的工作流程中检查是否存在一个秘密。

就像这样:

publish:
    runs-on: ubuntu-latest
    if: secrets.AWS_ACCESS_KEY_ID != ''
    steps:
      [ ... ]

然而,当我使用这个表达式时,我遇到了这样的错误:

The workflow is not valid. .github/workflows/release.yml (Line: 11, Col: 9): Unrecognized named-value: 'secrets'...

我的尝试

我试图以另一种方式编写表达式:

if: ${{ secrets.AWS_ACCESS_KEY_ID != '' }}
if: ${{ secrets.AWS_ACCESS_KEY_ID }} != ''

问题

如何在Github Actions工作流程中实现我想要的功能?

1个回答

31

Github Action解释器当前在使用if条件表达式时无法识别secrets关键字。因此,您不能在那里使用secrets.VARIABLE语法。

相反,使用环境来传递秘密检查的结果,然后在非秘密结果上使用if条件。

job.step示例:

job:
  runs-on: ubuntu-latest
  steps:
    - name: Check for Secret availability
      id: secret-check
      # perform secret check & put boolean result as an output
      shell: bash
      run: |
        if [ "${{ secrets.MY_KEY }}" != '' ]; then
          echo "available=true" >> $GITHUB_OUTPUT;
        else
          echo "available=false" >> $GITHUB_OUTPUT;
        fi

    - name: Check Inadequate Permissions
      if: ${{ steps.secret-check.outputs.available != 'true' }}
      # provide feedback for likely problem, note dependabot cannot access
      # secrets by default. Secondly, this step forces job failure due to
      # missing secret via `exit 1`
      shell: bash
      run: |
        if [ "${{ github.actor }}" == "dependabot[bot]" ]; then
          echo >&2 "Unable to access secrets as unprivileged dependabot.";
        else
          echo >&2 "Inadequate Permissions or missing secret value";
        fi
        exit 1

    - name: Execute Step requiring secret
      # If you didn't abort step above, then use this conditional
      # if: ${{ steps.secret-check.outputs.available == 'true' }}
      shell: bash
      # Key will be blocked out in log output but will be not empty
      run: |
        echo "This command is executed with non-empty key: \
          ${{ secrets.MY_KEY }}"

如果您需要在工作级别执行此操作,请创建一个单独的check-secret作业来验证密码,然后将结果作为已定义的输出共享。
工作流上下文级别示例:
jobs:

  check-secret:
    runs-on: ubuntu-latest
    outputs:
      my-key-exists: ${{ steps.my-key-check.outputs.defined }}
    steps:
      - name: Check for Secret availability
        id: my-key-check
        # perform secret check & put boolean result as an output
        shell: bash
        run: |
          if [ "${{ secrets.AWS_ACCESS_KEY_ID }}" != '' ]; then
            echo "defined=true" >> $GITHUB_OUTPUT;
          else
            echo "defined=false" >> $GITHUB_OUTPUT;
          fi

  job1:
    runs-on: ubuntu-latest
    needs: [check-secret]
    if: needs.check-secret.outputs.my-key-exists == 'true'
    steps:
      - run: echo "This command is executed if AWS_ACCESS_KEY_ID secret IS NOT empty"

  job2:
    runs-on: ubuntu-latest
    needs: [check-secret]
    if: needs.check-secret.outputs.my-key-exists != 'true'
    steps:
      - run: echo "This command is executed if AWS_ACCESS_KEY_ID secret IS empty"

为什么你要用双引号将它包起来?我不得不自己删除它们,以免在我的工作流程中出现语法错误。 - knocte
它可能已经发生了变化,因为答案发布后我会进行一些测试。 - GuiFalourd
1
问题是,在我的工作流程中,我已经有了一些 if: foo && bar,所以如果我将其更改为 if: "${{ env.MY_KEY != '' }}" && foo && bar,它会给出语法错误,因此我必须删除双引号,使其变为 if: ${{ env.MY_KEY != '' }} && foo && bar,然而,我刚刚意识到后者在语法上可以工作,但无法检测密钥是否为空。 - knocte
不要将秘密添加到环境变量中。这样会破坏秘密上下文的整个目的。环境变量在作业的所有步骤中都会被传递。只使用“check-secret”示例。另外,我认为作业级别过高,应该在步骤级别上完成。 - codejedi365
1
创建了一个编辑以说明仅传递秘密检查的布尔结果,该结果可用于 GitHub Actions jobs.<job_id>.if(或 jobs.<job_id>.steps[*].if)条件表达式中。这将保持所需的秘密上下文。 - codejedi365

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接