I want to run my Github workflow two ways:
Manually by user
Cron job
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 * * * *"
inputs are available to workflows triggered by the workflow_dispatch event only (and to any workflows that are called by dispatched workflows).
You can use the || expression operator to set the default values for input parameters. For example:
on:
schedule:
- cron: '15 0,18 * * 0-5'
workflow_dispatch:
inputs:
logLevel:
required: true
type: string
jobs:
test:
uses: ./.github/workflows/run-job-with-params.yml
secrets: inherit
with:
springProfile: 'production'
logLevel: ${{ inputs.logLevel || 'DEBUG' }}
In the above example the logLevel parameter is set to DEBUG when the workflow is triggered by cron. When the job is triggered by a dispatch event it gets set to the input value.
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
Related
We have a workflow file:
---
name: 'Deploy Test Env'
on:
pull_request:
types:
- edited
- opened
- synchronize
branches:
- develop
paths:
- '**.js'
jobs:
deploy:
# yamllint disable rule:line-length
name: '[DEV] DEPLOY'
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout#v2
- name: Deploy
run: |
echo 'Deploy Dev Env by ${{ github.event.action }} event type' >> "${GITHUB_STEP_SUMMARY}"
When new Pull Request (feature_branch → develop) is created or new commit inside feature_branch is occured, pull_request's opened (or synchronize) event is triggering Job.
Here is a paths condition: if none of JavaScript files are changed, application source code is the same and we don't need to deploy new test environment. That is correct.
But, here is third action type: edited. It is used because we have environment parameters passed inside Pull Request message. And if message is changed (edited), it means that parameters possibly changed too, and we have to re-deploy test environment even if **.js files are not changed. But because of paths condition edited event will not be triggered too.
In other words, description should be looks like:
---
name: 'Deploy Test Env'
on:
# will be triggered only if *.js files changed
pull_request:
types:
- opened
- synchronize
branches:
- develop
paths:
- '**.js'
# will be triggered anytime when PR contents are updated
pull_request:
types:
- edited
branches:
- develop
But YAML doesn't support duplicated keys and this format is wrong.
OR:
on:
pull_request:
types:
# paths are set only for `opened` and `synchronize` types
- type: edited
- type: opened
paths:
- '**.js'
- type: synchronize
paths:
- '**.js'
branches:
- develop
But types should be a list...
The question is: Is it possible to describe desired behavior? Maybe pull_request may be passed twice as array or paths may be set under the edited type (something like my second example)
You can use reusable workflows to achieve this.
Divide your workflow into three (3) workflows:
ci.yml: reusable workflow (workflow that performs stuff)
ci-pr-opened-synchronize.yml: reusable workflow caller (for PR opened/synchronize for .js files)
ci-pr-edited.yml: reusable workflow caller (for PR edited)
The above reusable workflow callers will call the ci.yml workflow.
Here's a complete working example with .md files filter and PRs to the main branch (https://github.com/iamazeem/github-actions-reusable-workflow-test):
ci.yml
name: CI
on:
workflow_call:
inputs:
message:
type: string
description: custom message
required: true
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Print message
if: ${{ inputs.message }}
env:
MESSAGE: ${{ inputs.message }}
run: |
echo "message: $MESSAGE"
ci-pr-opened-synchronize.yml
name: PR opened/synchronize
on:
pull_request:
types:
- opened
- synchronize
branches:
- main
paths:
- '**.md'
jobs:
pr-open-sync:
uses: ./.github/workflows/ci.yml
with:
message: 'PR opened/synchronized'
ci-pr-edited.yml
name: PR edited
on:
pull_request:
types:
- edited
branches:
- main
jobs:
pr-edited:
uses: ./.github/workflows/ci.yml
with:
message: 'PR edited'
You may check this PR and its respective actions for this sample:
PR: https://github.com/iamazeem/github-actions-reusable-workflow-test/pull/1
Actions: https://github.com/iamazeem/github-actions-reusable-workflow-test/actions
Here is one more example of reusable workflows:
.github/workflows/reuser_on_edited.yml
the workflow will reuse to_reuse.yml jobs when PR contents are edited
---
name: 'Reuser on Edited'
on:
pull_request:
types:
- edited
branches:
- 'develop'
jobs:
reuse:
uses: ./.github/workflows/to_reuse.yml
with:
original_github: ${{ toJSON(github) }}
other_input: 'BOOM! edited'
.github/workflows/reuser_on_pr_changed.yml
the workflow will reuse to_reuse.yml jobs when some of **.js files is changed.
---
name: 'Reuser on PR changed'
on:
pull_request:
types:
- opened
- synchronize
branches:
- 'develop'
paths:
- '**.js'
jobs:
reuse:
uses: ./.github/workflows/to_reuse.yml
with:
original_github: ${{ toJSON(github) }}
.github/workflows/to_reuse.yml
the file to reuse jobs inside it
on:
workflow_call:
inputs:
original_github:
type: string
required: true
description: "github context that passed from original workflow (JSON)"
other_input:
type: string
default: 'default'
required: false
description: "just for LOLs"
jobs:
deploy_job:
runs-on: ubuntu-latest
steps:
- name: Checkout v2
uses: actions/checkout#v2
with:
ref: ${{ fromJSON(inputs.original_github).event.pull_request.head.sha }}
- name: Deploy
run: |
{
echo 'Deploy Dev Env by `${{ fromJSON(inputs.original_github).event.action }}` event type';
echo '';
echo 'Also `${{ inputs.other_input }}` input is passed';
} >> "${GITHUB_STEP_SUMMARY}"
Original github context may be passed as JSON string and reused inside different workflow.
Also, different conditions (paths, etc.) may be set for different pull_request action types.
I've really struggled here doing this for the first time and having no background in development.
We have an action that checks the status of several services running on different envs (DEV, TEST, PROD) and sends notifications to Microsoft Teams Channel.
At the moment there is a dedicated action for each env and the goal is to combine them in one.
the action itself:
name: Services Health Check
on:
workflow_dispatch:
schedule:
- cron: '*/30 * * * *'
env:
DEV: https://app.dev.contoso.com
TEST: https://app.test.contoso.com
PROD: https://app.contoso.com
TEAMS_TOKEN_DEV: ${{ secrets.HEALTH_CHECK_TEAMS_WEB_HOOK_URL_DEV }}
TEAMS_TOKEN_TEST: ${{ secrets.HEALTH_CHECK_TEAMS_WEB_HOOK_URL_TEST }}
TEAMS_TOKEN_PROD: ${{ secrets.HEALTH_CHECK_TEAMS_WEB_HOOK_URL_PROD }}
jobs:
#here I want to create a matrix as a JSON array to look like this, but Im not sure if I do it right (I am also not sure if I correctly escape the characters and which one should I escape):
#[
# { dev : https://app.dev.contoso.com, webhook : ${{ secrets.WEB_HOOK_URL_DEV }} },
# {test : https://app.test.contoso.com, webhook : ${{ secrets.WEB_HOOK_URL_TEST }} },
# {prod : https://app.contoso.com, webhook : ${{ secrets.WEB_HOOK_URL_TEST }} }
#]
env-matrix:
name: Setup ENV Matrix
runs-on: ubuntu-latest
outputs:
matrix: ${{ steps.matrix.outputs.env }}
steps:
- id: matrix-env
run: |
echo '::set-output name=env::[\{\"env\"\:\"$DEV\", \"webhook\"\:\"$TEAMS_TOKEN_DEV\"\}, \{\"env\"\:\"$DEMO\", \"webhook\"\:\"$TEAMS_TOKEN_DEMO\"\}, \{\"env\"\:\"$TEST\", \"webhook\"\:\"$TEAMS_TOKEN_TEST\"\}, \{\"env\"\:\"$POC\", \"webhook\"\:\"$TEAMS_TOKEN_POC\"\}, \{\"env\"\:\"$PRE\", \"webhook\"\:\"$TEAMS_TOKEN_PRE\"\}, \{\"env\"\:\"$PROD\", \"webhook\"\:\"$TEAMS_TOKEN_PROD\"\}]'
#and the healthcheck job itself
healthcheck:
needs: env-matrix
name: Health Check
runs-on: ubuntu-18.04
strategy:
matrix:
value: ${{ fromJson(needs.env-matrix.outputs.matrix-env)}}
steps:
- name: service1
uses: repo/action
continue-on-error: true
with:
url: '${{ matrix.value.env }}/service1/q/health/ready'
teamsWebHookURL: '${{ matrix.value.webhook }}'
- name: service2
uses: repo/action
continue-on-error: true
with:
url: '${{ matrix.value.env }}/service2/q/health/ready'
teamsWebHookURL: '${{ matrix.value.webhook }}'
so the job must run on DEV with TEAMS_TOKEN_DEV, on TEST with TEAMS_TOKEN_TEST, but I don't know the way to access an array item, so the steps are incorrect.
Any help will be appreciated. If you know a simpler solution pls share.
Thanks for your time and help
Another way of rewriting your workflow is to define the name of the secrets in the matrix and then using Array notation to fetch the actual value of the secrets. Below is a way of doing this and it is not a clone of your workflow. But this should give you an idea.
name: Services Health Check
on:
workflow_dispatch:
jobs:
healthcheck:
name: Health Check
runs-on: ubuntu-18.04
strategy:
matrix:
environment: [dev, test, prod]
include:
- environment: dev
url: https://app.dev.contoso.com
webhook: HEALTH_CHECK_TEAMS_WEB_HOOK_URL_DEV
- environment: test
url: https://app.test.contoso.com
webhook: HEALTH_CHECK_TEAMS_WEB_HOOK_URL_TEST
- environment: prod
url: https://app.prod.contoso.com
webhook: HEALTH_CHECK_TEAMS_WEB_HOOK_URL_PROD
steps:
- name: test_1
run: |
echo ${{ format('{0}{1}', matrix.url, '/service1/q/health/ready') }}
echo ${{secrets[matrix.webhook]}}
- name: test_2
run: |
echo ${{ format('{0}{1}', matrix.url, '/service2/q/health/ready') }}
echo ${{secrets[matrix.webhook]}}
How do I create a workflow that can only be started manually, while it will need to specify a specific commit with which it will work?
You can manually run a workflow, provided it is configured to run on the workflow_dispatch event.
Add inputs to define your parameter
on:
workflow_dispatch:
inputs:
myCommit:
description: 'Commit SHA1'
required: true
default: 'undefined'
type: string
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- name: Do something
run: your_command ${{ inputs.myCommit }}
...
Here's an example how to check out the specific commit for build:
on:
workflow_dispatch:
inputs:
refToBuild:
description: 'Branch, tag or commit SHA1 to build'
required: true
type: string
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout#v3
with:
ref: ${{ inputs.refToBuild }}
- name: Build
run: <command for build>
I've been reading about expressions.
I need to create an env var that all jobs in a workflow can reference that, in English, checks for the existence of ${{ inputs.db_schema }} and if it exists, use it, otherwise set it to 'prod'.
Tried (borrows from JWLs solution on this SO post):
env:
db_schema: ${{ ${{inputs.db_schema}} :-'prod }}
This returned an error when I tried to run:
The workflow is not valid. .github/workflows/main.yaml (Line: 17, Col: 14): Unexpected symbol: '${{inputs'. Located at position 1 within expression: ${{inputs.db_schema .github/workflows/update-sk4-caller.yaml (Line: 18, Col: 16): Unexpected symbol: '${{inputs'. Located at position 1 within expression: ${{inputs.update_date
How can I create an env variable that can be used by all jobs in a workflow where the value is either what exists in ${{inputs.db_schema}} else if that input doesn't exist then 'prod'?
[EDIT]
Adding a more complete example of what I"m trying to do. Here's a piece of my workflow:
name: MyWorkflow
on:
workflow_dispatch:
inputs:
db_schema:
required: true
type: string
default: US.DATA_SCIENCE
schedule:
- cron: '10 3 * * *' # daily at ten past 3am
env:
db_schema: ${{inputs.db_schema || 'US.DATA_SCIENCE'}}
jobs:
check-env-vars:
runs-on: ubuntu-latest
steps:
- name: check env vars
run: |
echo ${{ env.db_schema }}
update-clicks:
uses: ./.github/workflows/update-clicks.yaml
secrets: inherit
with:
db_schema: ${{ env.db_schema }}
I need to pass a value to db_schema within the with statement.
You're mixing access to GitHub Actions context and shell parameter expansion. You might be able to do something like
db_schema: ${{ inputs.db_schema || 'prod' }}
or if you access db_schema in a shell script, you could use
db_schema: ${{ inputs.db_schema }}
and then access via
${db_schema:-prod}
I am trying to get default value when github action execute by cron job. but it picking empty instead of default value.
Note getting why its not picking default value. Any idea?
Here is my code
workflow_dispatch:
inputs:
typeOfTesting:
type: choice
description: Select Type of Test
default: "stage-test"
required: true
options:
- stage-test-local-All
- stage-test
- stage-test-Uptime
schedule:
- cron: "0 1 * * *"
- cron: "0 11 * * *"
jobs:
WebdriverIO-Automation:
runs-on: ubuntu-latest
steps:
- name: Selection of Testing type
run: |
echo "Branch Name: ${{ github.event.inputs.typeOfTesting }}"
Output:
inputs is not available to cron triggers. They are available to workflows triggered by the workflow_dispatch event only.
If you want to default value for corn you need to handle it in a step like:
workflow_dispatch:
inputs:
typeOfTesting:
type: choice
description: Select Type of Test
default: "stage-test"
required: true
options:
- stage-test-local-All
- stage-test
- stage-test-Uptime
schedule:
- cron: "0 1 * * *"
- cron: "0 11 * * *"
jobs:
WebdriverIO-Automation:
runs-on: ubuntu-latest
steps:
- name: Selection of Testing type
run: |
echo "Branch Name: ${{ github.event.inputs.typeOfTesting == '' && github.event.inputs.typeOfTesting || 'stage-test' }}"
Please take look here for a fake ternary expression:
steps:
- name: stuff
env:
PR_NUMBER_OR_MASTER: ${{ github.event.number == 0 && 'master' || format('pr-{0}', github.event.number) }}