将环境变量输入传递给可重用工作流程

15

我正在尝试从另一个工作流中调用可重复使用的工作流,并传递一些输入变量。在调用者工作流中,我有一些环境变量,我想将其作为输入传递给可重复使用的工作流,方法如下:

env:
  SOME_VAR: bla_bla_bla
  ANOTHER_VAR: stuff_stuff

jobs:
  print:
    runs-on: ubuntu-latest
    steps:
      - name: Print inputs passed to the reusable workflow
        run: |
          echo "some var: $SOME_VAR"
          echo "another var: $ANOTHER_VAR"
  call_reusable:
    uses: ...
    with:
      input_var: $SOME_VAR
      another_input_var: $ANOTHER_VAR

可重用的工作流程:
on:
  workflow_dispatch:
  workflow_call:
    inputs:
      input_var:
        required: true
        type: string
      another_input_var:
        required: true
        type: string

jobs:
  the_job:
    runs-on: ubuntu-latest
    steps:
      - name: Print inputs
        run: |
          echo "input_var: ${{ inputs.input_var }}"
          echo "another_input_var: ${{ inputs.another_input_var }}"

打印传递给可重用工作流的输入步骤正常运行 - 所有变量都正确打印出来。然而,在可重用工作流(被调用者)中,打印输入步骤不按预期工作 - 所有变量都为空。

我在文档中没有找到任何提示表明我的方法有问题,因此,我认为这应该是可以工作的。尽管如此,查看日志发现有些问题,因为在可重用工作流(被调用者)中,我看到:

Run echo "input_var: $SOME_VAR"
  echo "another_input_var: $ANOTHER_VAR"
  shell: /usr/bin/bash -e {0}
input_var: 
another_input_var: 

我尝试在with:块中使用$(echo)包装值,但没有成功。

有什么想法吗?

4个回答

25
在一些研究后,我发现此主题解释道:

你无法将 ENV 变量传递给可重用的工作流,因此它们在这种模式下几乎没有用。

此外,在官方文档中指出:

在调用者工作流程中定义的 env 上下文中设置的任何环境变量不会传播到被调用的工作流程中

因此,在您的情况下,您将无法直接使用 env 变量来实现您想要的目标,但有解决方法注意:如果GitHub提供更好的分配内联值或将其传递到可重用的工作流程中的方法,那将是很棒的,因为多次处理每个参数以将其传递到可重用的工作流程中很麻烦。
一种解决方法是使用第一个作业的输出,并将这些输出用作可重复使用的工作流输入。
以下是一个可以实现此方法的示例:
env:
  SOME_VAR: bla_bla_bla
  ANOTHER_VAR: stuff_stuff

jobs:
  print:
    runs-on: ubuntu-latest
    outputs:
      some_var: ${{ steps.step1.outputs.some_var }}
      another_var: ${{ steps.step1.outputs.another_var }}   
    steps:
      - name: Print inputs passed to the reusable workflow
        id: step1
        run: |
          echo "some var: $SOME_VAR"
          echo "some_var=$SOME_VAR" >> $GITHUB_OUTPUT
          echo "another var: $ANOTHER_VAR"
          echo "another_var=$ANOTHER_VAR" >> $GITHUB_OUTPUT
  
  call_reusable:
    needs:
      - print
    uses: ...
    with:
      input_var: ${{ needs.print.outputs.some_var }}
      another_input_var: ${{ needs.print.outputs.another_var }}

编辑:已删除现已弃用的 ::set-output 语法。

这样,即使不更新可重复使用的工作流实现,输入也会填充为期望的值。

以下是我用来测试的工作流:main + reusable

您可以在 此处 检查工作流运行的预期结果。


4
这种解决方法对于实现如此简单的操作来说非常复杂。而且,它无法用于传递机密信息,因为它们会自动从输出中删除。 - Peter Bašista
3
可重用工作流程中,您可以继承机密,或者您必须将它们作为机密发送到工作流程中。因此,在这种情况下,这种解决方法只对输入和环境有意义,而不适用于机密。 - GuiFalourd
有没有一种方法可以将所有的 secrets 解压到当前步骤的 env 中?结合在调用工作流中使用 secrets: inherit,似乎可以解决这个问题。 - Janosh
什么是解包?你想要实现什么目标? - GuiFalourd
1
有没有办法我可以动态地做这个?比如说,我有一个包含15-20个环境变量的列表。 - Yash Dixit
你最终可以使用一个.env文件作为可重复使用的工作流的输入。并且在可重复使用的工作流中有一个第一个任务,它会读取这个文件,并为其中设置的每个值设置输出。 - GuiFalourd

3

2
最近,GitHub引入了一个支持环境变量的功能(非常基础且期待已久的功能,我必须说)。因此,另一种解决方案可以是在GitHub中创建一个环境,在其下创建一些具有所需值的变量,并根据需要使用该环境。
调用者的工作流程:
jobs:
  Dev-Deployment:
    uses: ./.github/workflows/reusable-workflow.yml
    with:
        environment: Development

  QA-Deployment:
    uses: ./.github/workflows/reusable-workflow.yml
    with:
        environment: QA

可重复使用的工作流程:
on:
 workflow_call:
  inputs:
    environment:
      type: string
      required: true

jobs:
  deploy:
    runs-on: ubuntu-latest
    environment: ${{ inputs.environment }}
    steps:
      - name: Print variables - ${{ vars.SOME_VAR }} - ${{ vars.ANOTHER_VAR }}
        run: |
            echo ${{ vars.SOME_VAR }}
            echo ${{ vars.ANOTHER_VAR }}

GitHub环境:

在这里输入图片描述

0
一个简单的实验表明,不需要将变量echo$GITHUB_OUTPUT,只需要在outputs中定义它就足够了。
name: Test outputs

on:
  workflow_dispatch:

env:
  BRANCH: main

jobs:
  variables:
    name: Compute outputs
    runs-on: ubuntu-latest
    outputs:
      branch: ${{ env.BRANCH }}
      # branch: ${{ steps.variables.outputs.branch }}
    steps:
      - name: Echo
        if: false
        run: echo

      # - name: Set outputs variables
      #   id: variables
      #   run: echo
      #     echo "branch=${{ env.BRANCH }}" >> "$GITHUB_OUTPUT"

  show:
    name: Show outputs
    needs: variables
    runs-on: ubuntu-latest
    steps:
      - name: Echo outputs
        run: |
          echo "branch: ${{ needs.variables.outputs.branch }}"

这简化了变量传递,尤其是当我们有很多变量时。它可以用于简单的情况,当我们只需要传递变量值,而不是进行计算时。
唯一的缺点是我们在第一个任务中至少需要一步,但我们可以设置一个虚拟的步骤或禁用它。

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