在 GitHub Action 中的新作业中使用上一作业的输出

问题描述 投票:0回答:6

出于(主要)教学原因,我尝试在 GitHub actions 中运行此工作流程:

name: "We 🎔 Perl"
on:
  issues:
    types: [opened, edited, milestoned]

jobs:
  seasonal_greetings:
    runs-on: windows-latest
    steps:
      - name: Maybe greet
        id: maybe-greet
        env:
          HEY: "Hey you!"
          GREETING: "Merry Xmas to you too!"
          BODY: ${{ github.event.issue.body }}
        run: |
          $output=(perl -e 'print ($ENV{BODY} =~ /Merry/)?$ENV{GREETING}:$ENV{HEY};')
          Write-Output "::set-output name=GREET::$output"
  produce_comment:
    name: Respond to issue
    runs-on: ubuntu-latest
    steps:
      - name: Dump job context
        env:
          JOB_CONTEXT: ${{ jobs.maybe-greet.steps.id }}
        run: echo "$JOB_CONTEXT"

我需要两个不同的作业,因为它们使用不同的上下文(操作系统),但我需要将第一个作业中的步骤的输出获取到第二个作业。我正在尝试使用

jobs
上下文的几种组合,如here所示,但似乎没有任何方法可以做到这一点。显然,
jobs
只是一个 YAML 变量的名称,并没有真正的上下文,而上下文
job
只包含成功或失败。有什么想法吗?

perl github-actions
6个回答
217
投票

查看 2020 年 4 月的“GitHub Actions:新工作流程功能”,这可能对您的案例有所帮助(参考之前作业的步骤输出)

工作输出

您可以指定一组要传递给后续作业的输出,然后从您的需求上下文中访问这些值。

参见文档

jobs.<jobs_id>.outputs

工作产出图

作业输出可用于依赖于该作业的所有下游作业。
有关定义作业依赖性的更多信息,请参阅

jobs.<job_id>.needs

作业输出是字符串,并且包含表达式的作业输出在每个作业结束时在运行器上进行评估。包含机密的输出会在运行器上进行编辑,不会发送到 GitHub Actions。

要在依赖作业中使用作业输出,您可以使用

needs
上下文。
有关更多信息,请参阅“GitHub Actions 的上下文和表达式语法。

要在依赖作业中使用作业输出,您可以使用需求上下文。

示例

jobs:
  job1:
    runs-on: ubuntu-latest
    # Expose step outputs as job outputs
    outputs:
      output1: ${{ steps.step1.outputs.test }}
      output2: ${{ steps.step2.outputs.test }}
    steps:
    - id: step1
      run: echo "test=hello" >> "$GITHUB_OUTPUT"
    - id: step2
      run: echo "test=world" >> "$GITHUB_OUTPUT"
  job2:
    runs-on: ubuntu-latest
    needs: job1
    steps:
    - run: echo ${{needs.job1.outputs.output1}} ${{needs.job1.outputs.output2}}

请注意使用

$GITHUB_OUTPUT
,而不是现在(2022 年 10 月)已弃用的 旧版
::set-output

为了避免不受信任的记录数据在工作流作者无意的情况下使用

set-state

set-output
 工作流命令,我们引入了一组 
新的环境文件集 来管理状态和输出。


杰西阿德尔曼添加评论

这似乎不适用于静态字符串之外的任何内容。

例如,我如何获取步骤的多行文本输出(例如,我正在运行
pytest

 或类似的)并在另一个作业中使用该输出?

    将多行文本写入文件(
  • jschmitter评论
  • 或多行文字发送至
  • >> $GITHUB_OUTPUT
    maxisamanswer
  • 或对输出进行base64编码,然后在下一个作业中对其进行解码(
  • Nate Karasch评论

19
投票

更新:现在可以设置可用于将字符串值传输到下游作业的作业输出。请参阅此答案

以下是原答案。这些技术对于某些用例可能仍然有用。

    将数据写入文件并使用
  1. actions/upload-artifact
    actions/download-artifact
    。虽然有点尴尬,但确实有效。
  2. 创建存储库调度事件并将数据发送到第二个工作流程。我个人更喜欢这种方法,但缺点是它需要一个
  3. repo
    范围的
    PAT
这是第二种方式如何工作的示例。它使用

repository-dispatch 操作。

name: "We 🎔 Perl" on: issues: types: [opened, edited, milestoned] jobs: seasonal_greetings: runs-on: windows-latest steps: - name: Maybe greet id: maybe-greet env: HEY: "Hey you!" GREETING: "Merry Xmas to you too!" BODY: ${{ github.event.issue.body }} run: | $output=(perl -e 'print ($ENV{BODY} =~ /Merry/)?$ENV{GREETING}:$ENV{HEY};') Write-Output "::set-output name=GREET::$output" - name: Repository Dispatch uses: peter-evans/repository-dispatch@v1 with: token: ${{ secrets.REPO_ACCESS_TOKEN }} event-type: my-event client-payload: '{"greet": "${{ steps.maybe-greet.outputs.GREET }}"}'
这会触发同一存储库中的存储库调度工作流程。

name: Repository Dispatch on: repository_dispatch: types: [my-event] jobs: myEvent: runs-on: ubuntu-latest steps: - run: echo ${{ github.event.client_payload.greet }}
    

6
投票

可以在run

步骤中捕获命令的整个输出(和返回代码),我在这里写下它是为了希望避免其他人的头痛。 
公平警告,它需要大量的 shell 技巧和多行 run
 来确保一切都发生在单个 shell 实例中。

就我而言,我需要调用脚本并捕获其标准输出的

整个以供后续步骤使用,并保留其结果以进行错误检查:

# capture stdout from script SCRIPT_OUTPUT=$(./do-something.sh) # capture exit code as well SCRIPT_RC=$? # FYI, this would get stdout AND stderr SCRIPT_ALL_OUTPUT=$(./do-something.sh 2>&1)
由于 Github 的作业输出似乎只能捕获一行文本,因此我

必须转义输出的任何换行符:

echo "::set-output name=stdout::${SCRIPT_OUTPUT//$'\n'/\\n}"
此外,我需要最终返回脚本的

退出代码以正确指示它是否失败。整个 shebang 最终看起来像这样:

- name: A run step with stdout as a captured output id: myscript run: | # run in subshell, capturiing stdout to var SCRIPT_OUTPUT=$(./do-something.sh) # capture exit code too SCRIPT_RC=$? # print a single line output for github echo "::set-output name=stdout::${SCRIPT_OUTPUT//$'\n'/\\n}" # exit with the script status exit $SCRIPT_RC continue-on-error: true - name: Add above outcome and output as an issue comment uses: actions/github-script@v5 env: STEP_OUTPUT: ${{ steps.myscript.outputs.stdout }} with: github-token: ${{ secrets.GITHUB_TOKEN }} script: | // indicates whather script succeeded or not let comment = `Script finished with \`${{ steps.myscript.outcome }}\`\n`; // adds stdout, unescaping newlines again to make it readable comment += `<details><summary>Show Output</summary> \`\`\` ${process.env.STEP_OUTPUT.replace(/\\n/g, '\n')} \`\`\` </details>`; // add the whole damn thing as an issue comment github.rest.issues.createComment({ issue_number: context.issue.number, owner: context.repo.owner, repo: context.repo.repo, body: comment })

编辑:还有一个行动可以用更少的引导来完成此任务,这是我刚刚发现的。


6
投票
就我而言,我想传递整个构建/工件,而不仅仅是一个字符串:

name: Build something on Ubuntu then use it on MacOS on: workflow_dispatch: # Allows for manual build trigger jobs: buildUbuntuProject: name: Builds the project on Ubuntu (Put your stuff here) runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - uses: some/compile-action@v99 - uses: actions/upload-artifact@v2 # Upload the artifact so the MacOS runner do something with it with: name: CompiledProject path: pathToCompiledProject doSomethingOnMacOS: name: Runs the program on MacOS or something runs-on: macos-latest needs: buildUbuntuProject # Needed so the job waits for the Ubuntu job to finish steps: - uses: actions/download-artifact@master with: name: CompiledProject path: somewhereToPutItOnMacOSRunner - run: ls somewhereToPutItOnMacOSRunner # See the artifact on the MacOS runner
    

4
投票

2022 年 10 月更新: GitHub 正在弃用 set-output

,建议使用 
GITHUB_OUTPUT 代替。用于定义输出并在其他步骤、作业中引用它们的语法。

文档中的示例:

- name: Set color id: random-color-generator run: echo "SELECTED_COLOR=green" >> $GITHUB_OUTPUT - name: Get color run: echo "The selected color is ${{ steps.random-color-generator.outputs.SELECTED_COLOR }}"
    

4
投票
要更新 @vonc

https://stackoverflow.com/a/61236803/667767 多行输出。

方法如下

echo 'RESULT<<EOF' >> $GITHUB_OUTPUT echo $multiLine >> $GITHUB_OUTPUT echo 'EOF' >> $GITHUB_OUTPUT
    
© www.soinside.com 2019 - 2024. All rights reserved.