GitHub/Workflow
Starter Workflows
Quickstart for GitHub Actions - GitHub Docs https://docs.github.com/en/actions/quickstart
actions/starter-workflows: Accelerating new GitHub Actions workflows https://github.com/actions/starter-workflows
GitHub Marketplace - Actions https://github.com/marketplace?category=&query=&type=actions&verification=
Manual Run
manual.yaml:
name: Manual Run
run-name: Test
on:
workflow_dispatch:
inputs:
LABEL:
required: true
type: string
description: label
jobs:
run:
runs-on: ${{ inputs.LABEL }}
steps:
- run: hostname
On Pull Request
name: On Pull Request
on:
pull_request:
types: [opened, reopened]
jobs:
test:
runs-on: [ubuntu-latest]
steps:
- name: do something
shell: bash
run: |
echo "hi"
On Label Change
Note: Must have event in
name: On Label
on:
pull_request:
types:
- labeled
jobs:
label-job:
if: "github.event.label.name == 'run-mylabel'"
uses: myorg/myrepo/.github/workflows/dolabel.yaml@v2
with:
VAR1: VAR1
secrets: inherit
Basic Workflow
name: GitHub Actions Demo
run-name: ${{ github.actor }} is testing out GitHub Actions 🚀
on: [push]
jobs:
Explore-GitHub-Actions:
runs-on: ubuntu-latest
steps:
- run: echo "🎉 The job was automatically triggered by a ${{ github.event_name }} event."
- run: echo "🐧 This job is now running on a ${{ runner.os }} server hosted by GitHub!"
- run: echo "🔎 The name of your branch is ${{ github.ref }} and your repository is ${{ github.repository }}."
- name: Check out repository code
uses: actions/checkout@v3
- run: echo "💡 The ${{ github.repository }} repository has been cloned to the runner."
- run: echo "🖥️ The workflow is now ready to test your code on the runner."
- name: List files in the repository
run: |
ls ${{ github.workspace }}
- run: echo "🍏 This job's status is ${{ job.status }}."
ref: https://docs.github.com/en/actions/quickstart
Using Job Output
jobs:
job1:
runs-on: ubuntu-latest
# Map a step output to a job output
outputs:
output1: ${{ steps.step1.outputs.test }}
output2: ${{ steps.step2.outputs.test }}
steps:
- id: step1
run: echo "test=hello" >> "$GITHUB_OUTPUT"
- id: step2
run: echo "test=world" >> "$GITHUB_OUTPUT"
job2:
runs-on: ubuntu-latest
needs: job1
steps:
- env:
OUTPUT1: ${{needs.job1.outputs.output1}}
OUTPUT2: ${{needs.job1.outputs.output2}}
run: echo "$OUTPUT1 $OUTPUT2"
ref: Defining outputs for jobs - GitHub Enterprise Cloud Docs - https://docs.github.com/en/enterprise-cloud@latest/actions/using-jobs/defining-outputs-for-jobs
Dynamic Runs-on
Dynamic from Input:
name: Dynamic Labels
run-name: Dynamic Labels
on:
workflow_dispatch:
inputs:
LABELS:
required: false
type: string
jobs:
run:
# runs-on: ${{ fromJSON( '["CI"]' ) }} # This works
# runs-on: ${{ fromJSON( '["CI", "MORE"]' ) }} # This works
runs-on: ${{ fromJSON( inputs.LABELS ) }} # This works if formatted like: ["CI", "MORE"]
# runs-on: ${{ inputs.LABELS }} # this works for single label
# runs-on: [ CI, MORE ] # this works
steps:
- run: hostname
Dynamic from script:
name: Dynamic Script
run-name: Test
on:
workflow_dispatch:
inputs:
Go:
required: false
type: string
jobs:
job1:
runs-on: ubuntu-latest
outputs:
RUNS: ${{ steps.set-RUNS.outputs.RUNS }}
steps:
- id: set-RUNS
run: echo "RUNS=[\"CI\",\"MORE\"]" >> $GITHUB_OUTPUT
job2:
needs: job1
runs-on: ${{fromJSON(needs.job1.outputs.RUNS)}}
steps:
- run: hostname
ref:
- How to Dynamically assign the runs-on value in the github actions - Stack Overflow - https://stackoverflow.com/questions/73241812/how-to-dynamically-assign-the-runs-on-value-in-the-github-actions
- Github Actions: How use strategy/matrix with script - Stack Overflow - https://stackoverflow.com/questions/59977364/github-actions-how-use-strategy-matrix-with-script
Dynamic Jobs
{ "include": [
{"runson": ["CI", "MORE"],
"task": "joe"},
{"runson": ["CI", "LESS"],
"task": "bob"}
]
}
name: Dynamic Jobs
run-name: Test
on:
workflow_dispatch:
inputs:
Go:
required: false
type: string
jobs:
generate:
runs-on: ubuntu-latest
outputs:
MATRIX: ${{ steps.set-MATRIX.outputs.MATRIX }}
steps:
- id: set-MATRIX
run: echo "MATRIX={\"include\":[{\"runson\":[\"CI\",\"MORE\"],\"task\":\"joe\"},{\"runson\":[\"CI\",\"LESS\"],\"task\":\"bob\"}]}" >> $GITHUB_OUTPUT
jober:
needs: generate
runs-on: ${{ matrix.runson }}
strategy:
matrix: ${{fromJson(needs.generate.outputs.matrix)}}
steps:
- run: hostname
- run: echo ${{ matrix.runson }}
- run: echo ${{ matrix.task }}
Remotely Trigger Workflow - repository_dispatch
on: repository_dispatch:
---
on:
repository_dispatch:
types: [some_event_type]
curl -X POST https://api.github.com/repos/OWNER/REPO/dispatches -H "Authorization: Bearer ${GH_TOKEN}" -d '{"event_type":"some_event_type"}'
---
curl -X POST https://api.github.com/repos/ORG/REPO/dispatches -d '{"event_type":"some_event_type"}' # -d or --data, -X or --request # -H "Accept: application/vnd.github.v3+json" # -H "Accept: application/vnd.github+json" # You will most likely need to also pass along auth: (unless you are silly and on a publicly executable workflow?) # -H "Authorization: Bearer $GITHUB_TOKEN"
curl -L \ -X POST \ -H "Accept: application/vnd.github+json" \ -H "Authorization: Bearer <YOUR-TOKEN>" \ -H "X-GitHub-Api-Version: 2022-11-28" \ https://api.github.com/repos/OWNER/REPO/dispatches \ -d '{"event_type":"on-demand-test","client_payload":{"unit":false,"integration":true}}'
---
if you want to trigger from some other branch:
{...,'ref':'other_branch_or_ref'},...}
---
repository_dispatch - Events that trigger workflows - GitHub Docs https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#repository_dispatch
repository_dispatch - Repositories - GitHub Docs https://docs.github.com/rest/repos/repos#create-a-repository-dispatch-event
---
If you pass this payload through, you can limit the workflow, and access it in the workflow:
{
"event_type": "test_result",
"client_payload": {
"passed": false,
"message": "Error: timeout"
}
}
workflow:
on:
repository_dispatch:
types: [test_result]
jobs:
run_if_failure:
if: ${{ !github.event.client_payload.passed }}
runs-on: ubuntu-latest
steps:
- env:
MESSAGE: ${{ github.event.client_payload.message }}
run: echo $MESSAGE
Job Timeout
Workflow syntax - jobs - timeout-minutes https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idtimeout-minutes
my-job: runs-on: ubuntu-latest timeout-minutes: 30
jobs.<job_id>.timeout-minutes The maximum number of minutes to let a job run before GitHub automatically cancels it. Default: 360
If the timeout exceeds the job execution time limit for the runner, the job will be canceled when the execution time limit is met instead. For more information about job execution time limits, see "Usage limits, billing, and administration" for GitHub-hosted runners and "About self-hosted runners" for self-hosted runner usage limits.
Usage Limits:
There are some limits on GitHub Actions usage when using GitHub-hosted runners. These limits are subject to change. [1]
- Job execution time - Each job in a workflow can run for up to 6 hours of execution time. If a job reaches this limit, the job is terminated and fails to complete.
There are some limits on GitHub Actions usage when using self-hosted runners. These limits are subject to change. [2]
- Job execution time - Each job in a workflow can run for up to 5 days of execution time. If a job reaches this limit, the job is terminated and fails to complete.
Step Timeout
jobs.<job_id>.steps[*].timeout-minutes The maximum number of minutes to run the step before killing the process.
Status Check Functions
Expressions - GitHub Docs https://docs.github.com/en/actions/learn-github-actions/expressions#status-check-functions
success
steps:
...
- name: The job has succeeded
if: ${{ success() }}
failure
Returns true when any previous step of a job fails.
steps:
...
- name: The job has failed
if: ${{ failure() }}
with step conclusion check:
steps:
...
- name: Failing step
id: demo
run: exit 1
- name: The demo step has failed
if: ${{ failure() && steps.demo.conclusion == 'failure' }}
always
Causes the step to always execute, and returns true, even when canceled. The always expression is best used at the step level or on tasks that you expect to run even when a job is canceled.
if: ${{ always() }}
cancelled
Returns true if the workflow was canceled.
if: ${{ cancelled() }}
Pass Status to Step
Use:
steps.<id>.outcome != 'success'
- name: Check status step
id: check-step
if: success()
shell: bash
run: |
echo "Workflow successful"
- name: The step to call the action
if: always()
uses: ./path/to/action
with:
some-token: ${{ inputs.some-token }}
some-value: ${{ inputs.some-value }}
workflow-status: ${{ steps.check-step.outcome }}