Can someone explain how concurrency works on GitHub Actions at the job level and workflow level?
As its name does not suggest, at the job level (jobs.<job_id>.concurrency) is there for the opposite:
You can use
jobs.<job_id>.concurrencyto ensure that only a single job or workflow using the same concurrency group will run at a time.
A concurrency group can be any string or expression. The expression can use any context, except for the "secrets" context.
You can see many examples on GitHub workflows:
This one from ankush56 helpfully explains:
#########################################################
# Concurrency allows to run 1 cycle at a time
# If worflow is running, 2nd one will automatically go in pending state
# if concurrency is enabled
# If 1st running, 2nd in pending and 3rd is triggered then 2nd which was
# in pending will be cancelled and only 3rd (latest) will run
#
# If this is enabled it will cancel current running and start latest
# cancel-in-progress: true
#
# When a concurrent job or workflow is queued,
# if another job or workflow using the same concurrency group in the repository
# is in progress, the queued job or workflow will be pending.
#
# Any previously pending job or workflow in the concurrency group will be canceled.
# To also cancel any currently running job or workflow in the same concurrency group,
# specify cancel-in-progress: true.
############################################################
name: Concurrency Test
on:
#Triggers the workflow on push or pull request events but only for the master branch
# push:
# branches: [ master ]
# pull_request:
# branches: [ master ]
# Allows you to run this workflow manually from the Actions tab
workflow_dispatch:
# Concurrency can be used at workflow level or job leve
concurrency:
group: build-and-test
# If this is enabled it will cancel current running and start latest
cancel-in-progress: true
jobs:
build-and-test-on-pr:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v2
# Adding sleep time to keep one running and trigger 2nd to check concurrency
- name: Build and code sim
run: |
echo "Starting the code build"
sleep 3m
echo "Finish the code build"
At the workflow level, here is an example from Constantine Kim 김현진:
concurrency:
group: ${{ github.repository }}-concurrency-for-workflow
cancel-in-progress: false
on:
push:
branches:
- playground/concurrency-for-job
jobs:
concurrency-3:
concurrency:
group: ${{ github.repository }}-concurrency-for-job
cancel-in-progress: false
runs-on: ubuntu-latest
steps:
- run: |
sleep 100
echo "concurrency-for-job-test ${{github.job}}"
If you push multiple commits quickly (say 3 commits in a row), GitHub will start a workflow run for each commit. This can lead to wasted resources because sometimes you only care about the latest run (e.g., latest push to a branch).
Concurrency solves this by creating "groups" of runs, and only allowing one run in a group at a time.
You declare a concurrency block in your workflow YAML:
concurrency:
group: my-workflow-group
cancel-in-progress: true
Every time the workflow with group: my-workflow-group runs, it belongs to the group. You can think a group as a labeled bucket where all the workflow with that "my-workflow-group" goes there.
cancel-in-progress → If true, GitHub will cancel any in-progress run in that group when a new run starts.
For example, if you push 3 commits in a row, the latest will be run and the other cancelled.
Workflow-level vs Job-level concurrency
Workflow level (at the top of the file, like in my examples): controls concurrency for the entire workflow run.
Job level (inside a job): controls concurrency only for that job.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With