我们如何从 javascript GitHub 操作中获取“输入”上下文?

bri*_*ist 4 node.js github-api github-actions

我正在使用该github-script操作来使用一些 javascript 来完成工作流程中的某些任务。

workflow_dispatch例如,如果我使用带有触发器的工作流程,我可以通过 获取其输入context.payload.inputs

我正在利用可重用的工作流程,因此我有一个带有workflow_call触发器的工作流程,然后是另一个通过 调用该工作流程的工作流程jobs.<job>.uses

在工作流文件中使用模板时,workflow_dispatch输入的引用方式与 a 类似${{ github.event.inputs.<input_name> }},但要将输入引用到 a workflow_call,我们只需使用${{ inputs.<input_name> }}. 在对值进行模板化时一切都很好,没有问题,但我想知道如何inputs从 JS 中直接获取该上下文。我似乎找不到它,也找不到任何例子。

以下是一些要演示的片段:

一个workflow_dispatch例子

---
name: scripty
on:
  workflow_dispatch:
    inputs:
      dummy:
        required: false
        description: dummy
jobs:
  scripty:
    runs-on: ubuntu-latest
    steps:
      - name: script
        id: script
        uses: actions/github-script@v5
        with:
          script: |
            var dummy = context.payload.inputs.dummy
            return {
                context: context,
                github: github,
                env: process.env,
                test1: dummy
            }

      - run: |
          echo <<EOF
          ${{ toJSON(fromJSON(steps.script.outputs.result)) }}
          EOF
Run Code Online (Sandbox Code Playgroud)

这太棒了!

工作流程workflow_call(重复使用的工作流程)

---
name: scripty-called
on:
  workflow_call:
    inputs:
      dummy:
        required: false
        description: dummy
jobs:
  scripty-called:
    runs-on: ubuntu-latest
    steps:
      - name: script
        id: script
        uses: actions/github-script@v5
        with:
          script: |
            //var dummy = context.payload.inputs.dummy
            // ^ this will fail
            return {
                context: context,
                github: github,
                env: process.env
            }

      - run: |
          echo <<EOF
          ${{ toJSON(fromJSON(steps.script.outputs.result)) }}
          EOF
Run Code Online (Sandbox Code Playgroud)

调用工作流程

---
name: scripty-caller
on:
  pull_request:
jobs:
  scripty-caller:
    name: Call scripty
    uses: <my-repo>/.github/workflows/scripty-shared.yml@thisref
    with:
      dummy: '@DUMMY_VALUE@'
Run Code Online (Sandbox Code Playgroud)

现在,我知道在这个示例中,我将脚本嵌入到工作流程中,因此我可以对其进行模板化:

      - name: script
        id: script
        uses: actions/github-script@v5
        with:
          script: |
            var dummy = '${{ inputs.dummy }}'
            return {
                context: context,
                github: github,
                env: process.env
            }
Run Code Online (Sandbox Code Playgroud)

但这感觉不对……如果我想将脚本放入存储库中的单独文件中,或者如果我想将此代码片段升级为真正的基于 JS 的操作,那么它不会很好地工作。

所以我想知道如何访问该值?而且,我怎么能在不发帖的情况下找到答案呢?我花了几个小时挖掘代码、文档和网络帖子,是否有更好的地方可以查看?

bri*_*ist 5

我发布答案来描述我所做的事情,尽管我从未找到我实际问题的答案。不过,我不会将此标记为答案,也许有一天它会直接回答。

最后,我不得不求助于模板。

我选择做的不是单独模板化每个输入,而是模板inputs一次,这样我就可以将所有输入作为映射获取,保留类型信息。

var inputs = ${{ toJSON(inputs) }}
var dummy = inputs['dummy']
Run Code Online (Sandbox Code Playgroud)

最初让我感到困惑的是,我试图将序列化的 JSON 放入字符串中,然后在代码中对其进行反序列化,如下所示:

// don't do this
var inputsJson = '${{ toJSON(inputs) }}'
var inputs = JSON.parse(inputsJson)
Run Code Online (Sandbox Code Playgroud)

由于 JSON 是多行等,这一直失败,我花了很长时间才意识到JS ON 是有效的 JS;我们可以直接嵌入并使用它/分配它。感觉很奇怪,但效果很好。