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
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
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).
A Simple Bash example
# 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.
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.
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.
Top comments (1)
Thanks for this post, that helped!
By the way: set-output is depricated and will be disabled in the near future (see here). I changed your example to this and it works: