Github Action - handling input default value
Tags: github, todayilearned
Published: 2022-01-06 20:45:14

Today I want to share a recently learned technique for handling input default value for automatically triggered actions.

### `workflow_dispatch` trigger
Github Action offers the way to parametrize your action when you're using `workflow_dispatch` to manually trigger the action. 

Let's say we have simple greeting action
```yaml
name: Greeting Action
on:
  workflow_dispatch:
    inputs:
      name:
        default: "Octocat"
        description: "Name to greet"
jobs:
  say-hello:
    runs-on: ubuntu-latest
    steps:
      - run: echo "Hello ${{ github.event.inputs.name }}"
```

It allows you to run action with a custom name parameter. From the Github UI perspective, it looks like this

![Workflow dispatch](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/bll2d4sj4bwt2xfwwcoz.png)

It works in a very simple way. Passed name or default value can be accessed with `${{ github.event.inputs.name }}`. But the problem is that this input will be only available for jobs triggered with `workflow_dispatch` event.

### Different types of triggers
As you probably know, a single action can have more triggers than just `workflow_dispatch`. For example, your action can be triggered with `push` event or `scheduled` with cron.

Initially, I thought that the default value of the input parameter will be used but this is not true. The action triggered with non `workflow_dispatch` event doesn't have access to inputs. This may produce subtle bugs when your action calls `${{ github.event.inputs.<key> }}`. **Watch out for this**.

### Shell Parameter Expansion to the rescue
I found parameter expansion technique particularly useful in solving this problem.

Without going much into details, you can think of parameter expansion as a way to provide a default value when a parameter is unset or null (but it's more than that - [more details](https://www.gnu.org/software/bash/manual/html_node/Shell-Parameter-Expansion.html)).

A Simple Bash example
```bash
# let's define empty VAL parameter
~$ VAL=
~$ echo ${VAL:-"default"} # we use parameter expansion here
default # since VAL is empty "default" is printed
```

### Solution
Knowing how parameter expansion works, let's see how to use it to solve the problem.
```yaml
steps:
   - run: |
     USER_INPUT=${{ github.event.inputs.name }}
     # Use user input or fall back to "Octocat"
     NAME=${USER_INPUT:-"Octocat"}
     # use $NAME in your action, value will be always provided
```

When your action is triggered with `workflow_dispatch` event `NAME` value will be equal to the value provided by the user. In other cases, it will fall back to `"Octocat"`.

If I want to use input value across different steps I usually create separate step for exporting my input value.
```yaml
steps:
      - name: Set name output
        id: name
        run: |
          USER_INPUT=${{ github.event.inputs.name }}
          echo "::set-output name=value::${USER_INPUT:-"Octocat"}"

      - name: Use output
        # Now I can access my parameter in a similar fashion to github.events.inputs.name
        run: echo "Hello ${{ steps.name.outputs.value}}"
```

This strategy allows me to create and maintain a single action with different triggers.