How can we get the "inputs" context from within a javascript GitHub action?

Viewed 914

I'm using the github-script action to use some javascript for some tasks in my workflow.

If I use a workflow with the workflow_dispatch trigger for example, I can get its inputs via context.payload.inputs.

I'm making use of reusable workflows, so I have a workflow with the workflow_call trigger, and then another workflow that calls that one, via jobs.<job>.uses.

When using templating in workflow files, a workflow_dispatch input is referenced like ${{ github.event.inputs.<input_name> }} but to reference the inputs to a workflow_call, we just use ${{ inputs.<input_name> }}. That's all fine when templating the values, there's no issue there, but what I'm wondering is how I can directly get at that inputs context from within JS. I can't seem to find it and I haven't been able to find any examples.

Here's some snippets to demonstrate:

A workflow_dispatch example

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

This works great!

A workflow_call workflow (the one that's reused)

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

The calling workflow

---
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@'

Now, I know in this example, I'm embedding the script in the workflow, so I could just template it:

      - name: script
        id: script
        uses: actions/github-script@v5
        with:
          script: |
            var dummy = '${{ inputs.dummy }}'
            return {
                context: context,
                github: github,
                env: process.env
            }

But that feels wrong... and it will not work well if I want to put the script into a separate file in the repo, or if I want to graduate this snippet into a real JS-based action.

So I'm wondering, how can that value be accessed? And also, how could I have found the answer without posting? I've spent hours digging through code and docs and web posts, was there a better place to look?

1 Answers

I'm posting as answer to describe what I did, even though I never found an answer to my actual question. I won't mark this as an answer though, maybe it will be directly answerable someday.

In the end, I did have to just resort to templating.

What I opted to do instead of individually templating each input, is template inputs once so that I can get at all the inputs as a map, preserve type info.

var inputs = ${{ toJSON(inputs) }}
var dummy = inputs['dummy']

What threw me off initially was that I was trying to put the serialized JSON into a string, and then deserialize it in the code, something like:

// don't do this
var inputsJson = '${{ toJSON(inputs) }}'
var inputs = JSON.parse(inputsJson)

And this kept failing, due to the JSON being multi-line and such, and it took way too long for it to dawn on me that JSON is valid JS; we could emded it and use it/assign it directly. It feels weird, but works very well.

Related