在 GitHub 操作中的新作业中使用先前作业的输出

jjm*_*elo 44 perl github-actions

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

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"
Run Code Online (Sandbox Code Playgroud)

我需要两个不同的作业,因为它们使用不同的上下文(操作系统),但是我需要将第一个作业中的步骤输出到第二个作业。我正在尝试使用此处jobs找到的几种上下文组合,但似乎没有任何方法可以做到这一点。显然,只是一个 YAML 变量的名称,它实际上没有上下文,上下文只包含成功或失败。任何的想法?jobsjob

Von*_*onC 83

检查2020 年 4 月的“ GitHub 操作:新工作流功能”,这对您的情况可能有所帮助(参考以前作业的步骤输出)

工作产出

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

请参阅文档

jobs.<jobs_id>.outputs
Run Code Online (Sandbox Code Playgroud)

作业的输出图

作业输出可用于依赖此作业的所有下游作业。
有关定义作业依赖项的更多信息,请参阅jobs.<job_id>.needs

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

要在依赖作业中使用作业输出,您可以使用needs上下文。
有关更多信息,请参阅“ GitHub 操作的上下文和表达式语法。

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

例子

jobs:
  job1:
    runs-on: ubuntu-latest
    # Map a step output to a job output
    outputs:
      output1: ${{ steps.step1.outputs.test }}
      output2: ${{ steps.step2.outputs.test }}
    steps:
    - id: step1
      run: echo "::set-output name=test::hello"
    - id: step2
      run: echo "::set-output name=test::world"
  job2:
    runs-on: ubuntu-latest
    needs: job1
    steps:
    - run: echo ${{needs.job1.outputs.output1}} ${{needs.job1.outputs.output2}}
Run Code Online (Sandbox Code Playgroud)

  • 对于其他想知道为什么没有生成输出的人;检查您的步骤是否使用“id”而不是“name” (3认同)
  • @JesseAdelman 好问题:我不确定。您应该提出一个单独的问题,并带有返回此答案的链接,以获得更准确的答案。 (2认同)
  • 或者,您可以对输出进行 Base64 编码,然后在下一个作业中对其进行解码 (2认同)

pet*_*ans 14

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

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

  1. 将数据写入文件并使用actions/upload-artifactactions/download-artifact。有点尴尬,但它有效。
  2. 创建存储库调度事件并将数据发送到第二个工作流。我个人更喜欢这种方法,但缺点是它需要一个repo作用域PAT

这是第二种方式如何工作的示例。它使用存储库调度操作。

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.output.GREET }}"}'
Run Code Online (Sandbox Code Playgroud)

这会触发同一存储库中的存储库分派工作流。

name: Repository Dispatch
on:
  repository_dispatch:
    types: [my-event]
jobs:
  myEvent:
    runs-on: ubuntu-latest
    steps:
      - run: echo ${{ github.event.client_payload.greet }}
Run Code Online (Sandbox Code Playgroud)


Dr-*_*ket 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
Run Code Online (Sandbox Code Playgroud)


Eva*_*anK 6

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

就我而言,我需要调用脚本并捕获其完整的标准输出以供后续步骤使用,并保留其结果以进行错误检查:

# 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)
Run Code Online (Sandbox Code Playgroud)

由于 Github 的作业输出似乎只能捕获一行文本,因此我必须转义输出的任何换行符:

echo "::set-output name=stdout::${SCRIPT_OUTPUT//$'\n'/\\n}"
Run Code Online (Sandbox Code Playgroud)

此外,我最终需要返回脚本的退出代码以正确指示它是否失败。整个 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
      })
Run Code Online (Sandbox Code Playgroud)

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