perl 在GitHub操作的新作业中使用上一个作业的输出

plicqrtu  于 2022-11-15  发布在  Perl
关注(0)|答案(5)|浏览(182)

出于(主要)教学原因,我尝试在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"

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

pieyvz9o

pieyvz9o1#

检查2020年4月的“GitHub Actions: New workflow features“,这可能对您的情况有所帮助(参考之前作业的步骤输出)

作业输出

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

jobs.<jobs_id>.outputs

作业的输出Map

作业输出可用于依赖于此作业的所有下游作业。
有关定义作业依存关系的详细信息,请参阅jobs.<job_id>.needs
作业输出是字符串,包含表达式的作业输出会在每个作业结束时在runner上进行计算。包含机密的输出会在runner上进行编辑,而不会发送到GitHub Actions。
若要在相依工作中使用工作输出,您可以使用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 "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,而不是older ::set-output now (Oct. 2022) deprecated
为了避免不受信任的记录数据在没有工作流作者意图的情况下使用set-stateset-output工作流命令,我们引入了一组新的环境文件来管理状态和输出。
Jesse Adelman在注解中添加:
这似乎不适用于静态字符串以外的任何对象。
例如,我如何获取step的多行文本输出(比如,我正在运行pytest或类似程序),并在另一个作业中使用该输出?

  • 将多行文本写入文件(jschmitter的注解)
  • 或base64-编码输出,然后在下一个作业中解码(Nate Karasch的注解)
wfveoks0

wfveoks02#

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

下面是最初的答案。这些技术可能对某些用例仍然有用。
1.将数据写入文件,并使用actions/upload-artifactactions/download-artifact。有点笨拙,但它工作。
1.创建一个存储库调度事件,并将数据发送到第二个工作流。我个人更喜欢这种方法,但缺点是它需要一个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 }}
ovfsdjhp

ovfsdjhp3#

run步骤中捕获一个命令的整个输出(和返回代码)* 是 * 可能的,我在这里写这个步骤是希望能让其他人省去这个麻烦。公平的警告,这需要很多shell技巧和多行run来确保所有事情都发生在单个shell示例中。
在我的例子中,我需要调用一个脚本并捕获其stdout的全部,以便在后面的步骤中使用,同时保留其结果以进行错误检查:

# 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}"

此外,我还需要最终返回脚本的 *exit代码 *,以正确指示它是否失败。

- 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
      })

**编辑:**还有an action可以用更少的自举来实现这一点,这是我刚刚发现的。

t9aqgxwy

t9aqgxwy4#

在我的例子中,我希望传递一个完整的build/工件,而不仅仅是一个字符串:

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
xzabzqsa

xzabzqsa5#

**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 }}"

相关问题