Reputation: 281
I want to run my Github workflow two ways:
Now, everything was running fine until I added input parameters. After that, the cron job is running but not picking default value.
Here is my yaml:
name: WebDriverIO Automation
on:
workflow_dispatch:
inputs:
typeOfTesting:
type: choice
description: Select Type of Test
default: 'stage-test-local-All'
required: true
options:
- stage-test-local-All
- stage-test
- stage-test-local-Sanity
- prod-test
branches:
- workingBranch
- JSNew
schedule:
- cron: "*/5 * * * *"
Upvotes: 26
Views: 24895
Reputation: 4739
I had same situation where the workflow was supposed to be executed on schedule basis, but also with an option to run manually for adhoc testing.
So below is working code to achieve same.
name: Scheduled Patrol Tests
on:
schedule:
- cron: 0 18 * * 1-5
workflow_dispatch:
inputs:
env:
required: false
type: string
default: "non-prod"
testing_devices:
required: false
default: "Google Pixel 8"
type: string
locales:
required: false
default: "['en','fr']"
type: string
description: "List of locales for testing"
jobs:
android-tests:
name: Android Tests for {{matrix.language}}
strategy:
matrix:
language: ${{ fromJSON(format('[{0}]', inputs.locales || "['en','it','fr','nl']")) }}
uses: ./.github/workflows/_android_integration_tests_with_browserstack.yml
with:
env: {{inputs.env || 'test'}}
testing_devices: {{inputs.testing_devices || 'Google Pixel 8' }}
language: {{matrix.language}}
secrets: inherit
So when its run manually, and no parameters provided, it will default to the values defined at top while defining inputs.
But when its executed in scheduled mode, the fallback will happen due to use of ||
operator
for e.g. env
will be test
because of env: {{inputs.env || 'test'}}
References format function fromJson function
Other options can also be explored
Upvotes: 0
Reputation: 2850
inputs
are available to workflows triggered by the workflow_dispatch event only (and to any workflows that are called by dispatched workflows).
When a workflow with inputs is triggered on a schedule (or on push/pull) all the input values are null. Any defaults that are set in the inputs section have no effect.
Therefore you need to set the defaults at the point where they are needed in the workflow. A convenient method for doing this uses Github expressions.
For string and choice inputs you can use the ||
expression operator to set the default value.
For boolean inputs that default to false
you can use ||
expression to set the default value.
For boolean inputs that default to true
you can use the contains()
function to set the default value.
For example:
on:
schedule:
- cron: '15 0,18 * * 0-5'
workflow_dispatch:
inputs:
springProfile:
required: true
type: choice
options:
- staging
- production
logLevel:
required: true
type: string
isFalseWhenScheduled:
required: true
type: boolean
isTrueWhenScheduled:
required: true
type: boolean
jobs:
test:
uses: ./.github/workflows/run-job-with-params.yml
secrets: inherit
with:
springProfile: ${{ inputs.springProfile || 'staging' }}
logLevel: ${{ inputs.logLevel || 'DEBUG' }}
isFalseWhenScheduled: ${{ inputs.isFalseWhenScheduled || false }}
isTrueWhenScheduled: ${{ !contains(inputs.isTrueWhenScheduled, 'false') }}
In the above example, if the workflow is triggered on schedule:
springProfile
parameter is set to 'staging'.logLevel
parameter is set to 'DEBUG'.isFalseWhenScheduled
parameter is set to falseisTrueWhenScheduled
parameter is set to trueIf the job is triggered on workflow_dispatch:
then the above parameters are set to the inputs:
values.
The contains
function casts its first parameter to a string, and null
is cast to the empty string ''
. As mentioned, when triggered on schedule, inputs parameters are all set to null.
So:
Trigger method | isTrueWhenScheduled value | input value resolves to |
---|---|---|
workflow_dispatch | true | !contains('true', 'false') = true |
workflow_dispatch | false | !contains('false', 'false') = false (*) |
schedule | null | !contains('', 'false') = true |
(*) This combination is what necessitates the use of contains
. If contains is not used and you do ${{ inputs.isTrueWhenScheduled || true }}
this will force this value to true
even if it is set false
in the workflow dispatch event.
And:
Trigger method | isFalseWhenScheduled value | input value resolves to |
---|---|---|
workflow_dispatch | true | true || false = true |
workflow_dispatch | false | false || false = false |
schedule | null | null || false = false |
Upvotes: 38
Reputation: 199
Use an expression like this: ${{ toJSON(inputs) == '{}' && <defaultValue> || inputs.<inputName> }}
.
WARNING: the <defaultValue>
must be truthy, For boolean and number, use the string value, eg: 'true'
, 'false'
, '0'
, '1'
.
If the default value cannot be truthy, eg: ''
for an input of type string
, reverse the expression, eg: ${{ toJSON(inputs) != '{}' && inputs.<inputName> || '' }}
.
Upvotes: 0
Reputation: 1828
You can set an env variable with a default value:
env:
typeOfTesting: ${{ github.event_name == 'schedule' && 'stage-test-local-All' || github.event.inputs.typeOfTesting }}
then use env.typeOfTesting
instead of inputs.typeOfTesting
.
Upvotes: 6
Reputation: 21
Here's another version that works with boolean inputs, and also supports setting the default to true:
name: Conditionally run a job
on:
workflow_dispatch:
inputs:
should_run:
description: "Whether the job should run"
type: boolean
default: true
schedule:
- cron: '0 * * * *'
jobs:
my-job:
name: This job runs on schedule or if inputs.should_run is true
runs-on: ubuntu-22.04
if: ${{ !contains(inputs.should_run, 'false') }}
steps:
run: echo ok
This works as expected: the job always runs on schedule and when triggered manually it only runs if inputs.should_run
is checked. That's because:
inputs.should_run
is null
.contains
function converts its argument to a string: null
is converted to ''
.Upvotes: 2
Reputation: 29
Several comments have mentioned that other answers don't work for boolean inputs, so here's one that does.
name: Read a boolean input in a scheduled job
on:
schedule:
- cron: '0 * * * *'
workflow_dispatch:
inputs:
human:
description: Did a human start this workflow?
type: boolean
default: true
jobs:
report-boolean:
name: Report boolean state
runs-on: ubuntu-latest
env:
BOOLEAN_STATE: ${{ !!(inputs.human) }}
steps:
- name: Output boolean
run: echo "'${BOOLEAN_STATE}'"
Results:
If you want the variable to be true for the scheduled job, use one exclamation mark instead of two (${{ !inputs.whatever }}
).
Upvotes: -2
Reputation: 23
Another option is to set a separate workflow that uses a curl POST to trigger the desired workflow via dispatch. That way you could set up a payload with whatever variables/context you need. It's less than ideal to have two workflows for one job, but it gives you access to the full set of inputs.
Upvotes: 0
Reputation: 281
Below code worked
name: WebDriverIO Automation
on:
workflow_dispatch:
inputs:
typeOfTesting:
type: choice
description: Select Type of Test
default: 'stage-test-local-All'
required: true
options:
- stage-test-local-All
- stage-test
- stage-test-local-Sanity
- prod-test
branches:
- workingBranch
schedule:
- cron: "*/5 * * * *"
...
..
..
- name: Test
run: |
if [ ${{ github.event.inputs.typeOfTesting }} != "" ]; then
npm run ${{ github.event.inputs.typeOfTesting }}
else
npm run stage-test-local-All
fi
Upvotes: 0