Study guide
4.4 Concurrency Controls & Status Check Functions
GitHub Actions Certification GH-200
Track your progress as you read
Finished sections get a check mark.
1 Chapter 1: Introduction & Exam Overview
1.1 Exam Structure, Format & Scoring 1.2 GitHub Actions Architecture & Core Mental Model 1.3 Hands-On Preparation & Exam Day Strategy
2 Chapter 2: Workflow Triggers & Event Architecture
2.1 Webhook & Code Events: push, pull_request, and pull_request_target 2.2 Scheduled & Manual Triggers: schedule, workflow_dispatch, and repository_dispatch 2.3 Release, Issue, and Dynamic Lifecycle Events 2.4 Branch, Tag, and Path Filtering Patterns
3 Chapter 3: Jobs, Matrix Strategies & Execution Control
3.1 Job Anatomy, Step Execution & Job Dependencies (needs) 3.2 Contexts, Expressions & Functions 3.3 Environment Variables & Workflow Commands 3.4 Matrix Strategies & Multi-Platform Builds 3.5 YAML Anchors, Aliases & Merge Keys
4 Chapter 4: Reusable Workflows & Troubleshooting
4.1 Authoring & Calling Reusable Workflows (workflow_call) 4.2 Comparing Reusable Workflows, Composite Actions & Starter Workflows 4.3 Troubleshooting Workflow Runs & Debug Logging 4.4 Concurrency Controls & Status Check Functions
5 Chapter 5: Authoring Custom Actions
5.1 Action Architecture & action.yml Specification 5.2 Authoring Composite Actions 5.3 Building JavaScript Actions 5.4 Building Docker Container Actions
6 Chapter 6: Action Distribution, Marketplace & Advanced Action Types
6.1 Action Versioning, Semantic Releases & Tagging 6.2 Publishing Actions to GitHub Marketplace 6.3 Service Containers & Network Topology 6.4 actions/github-script & Workflow Tooling
7 Chapter 7: Runner Infrastructure & Self-Hosted Runners
7.1 GitHub-Hosted Runners & Larger Runners 7.2 Self-Hosted Runner Setup, Architecture & Communication 7.3 Self-Hosted Runner Security & Ephemeral Runners 7.4 Runner Groups, Labels & Organization Routing
8 Chapter 8: Enterprise Governance, Policies & Environments
8.1 Enterprise & Organization Action Policies 8.2 Environments, Protection Rules & Deployment Approvals 8.3 Repository Rulesets, Required Status Checks & Governance 8.4 Usage Limits, Billing Multipliers & Usage Metrics
9 Chapter 9: Secrets, Permissions & OIDC Cloud Authentication
9.1 Encrypted Secrets Architecture & Scopes 9.2 GITHUB_TOKEN & Least Privilege Configuration 9.3 OpenID Connect (OIDC) & Workload Identity Federation 9.4 Script Injection Prevention & Secure Workflow Patterns
10 Chapter 10: Supply Chain Hardening & Performance Optimization
10.1 Supply Chain Hardening: SHA Pinning, Dependabot & Artifact Attestations 10.2 Caching Dependencies with `actions/cache` 10.3 Artifacts Management & Job Handoff 10.4 Workflow Performance, Cost Optimization & Architecture Review
4.4 Concurrency Controls & Status Check Functions
Key Takeaways Explain This Topic AI
Concurrency groups (concurrency:) enforce execution mutual exclusion, ensuring only a single workflow run or job executes within a specified group key at any given time.
The cancel-in-progress: true setting automatically cancels any currently executing run in the same concurrency group when a newer commit or run is queued.
Status check functions (always(), success(), failure(), cancelled()) override the default implicit if: success() condition on jobs and steps.
Cleanup and resource teardown steps must use if: always() to ensure that ephemeral cloud environments, test databases, or containers are destroyed even after test failures or cancellations.
Setting strict job-level timeouts via timeout-minutes: is an essential operational best practice to prevent hung processes from consuming the default 360-minute execution window and exhausting runner budgets.
Last updated: August 2026
Concurrency Controls & Status Check Functions
In modern automated software delivery, managing simultaneous pipeline runs and controlling conditional execution based on runtime status are vital for stability, resource optimization, and cost governance. Without concurrency controls, rapid Git pushes can trigger redundant, wasteful builds that race against each other or deploy out-of-order changes to cloud infrastructure. Similarly, without status check functions, pipelines cannot reliably clean up ephemeral test resources when earlier steps fail.
1. Concurrency Controls ( concurrency: )
The concurrency keyword controls the simultaneous execution of workflows or jobs that share the same concurrency group name. It can be declared at either the workflow level (affecting the entire workflow run) or at the job level (affecting only that specific job). concurrency:
- group: ${{ github.workflow }}-${{ github.ref }}
- cancel-in-progress: true
Key Parameters:
group (required): A string identifying the concurrency group. Expressions can dynamically construct group names using contexts like github.workflow , github.ref , github.head_ref , or job parameters.
cancel-in-progress (optional, default false ): When set to true , GitHub Actions automatically cancels any currently executing job or workflow in that group whenever a new run is queued for the same group.
Loading diagram... Concurrency Management: cancel-in-progress: true vs cancel-in-progress: false
- 2. Common Enterprise Concurrency Patterns
- Pattern A: Cancel Redundant Pull Request Builds
When developers rapidly push multiple commits to an open pull request, running CI tests on older, superseded commits wastes compute capacity. Use github.head_ref (available on pull_request events) falling back to github.ref : name: Pull Request CI
on:
pull_request:
branches: [main]
concurrency:
- group: pr-${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
- cancel-in-progress: true
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: npm test
- Pattern B: Serialized Production Deployments (No Cancellation)
For production deployments or database migrations, cancelling an in-progress deployment halfway through can leave cloud infrastructure in an inconsistent, corrupted state. Configure cancel-in-progress: false to ensure incoming releases wait in queue and execute sequentially: name: Deploy Production
on:
push:
branches: [main]
concurrency:
- group: production-environment-lock
- cancel-in-progress: false # Default behavior: Queues sequentially
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Terraform Apply
- run: terraform apply -auto-approve
Important
Concurrency Queue Depth Limit: GitHub Actions maintains a maximum queue depth of 1 active run and 1 pending run per concurrency group. If multiple new runs are queued while one is currently running, GitHub retains the latest pending run and automatically cancels any intermediate pending runs.
3. Status Check Functions in Conditional Expressions
By default, every step and job in GitHub Actions has an implicit condition: if: success() . If any preceding step fails or if the workflow is cancelled, subsequent steps are skipped automatically. To override this default behavior, GitHub Actions provides four built-in status check functions :
Status Function Evaluates to true When: Primary CI/CD Use Case
success() All previous steps/jobs have succeeded (no failures, no cancellations). Standard sequential tasks (default behavior).
always() Always returns true , even if previous steps failed or the run was cancelled. Teardown tasks, resource cleanup, log uploading.
failure() At least one previous step/job in the execution sequence has failed . Incident alerts, Slack failure notifications, diagnostics.
cancelled() The workflow run was explicitly cancelled by a user or concurrency group. Abort handlers, rolling back partial locks.
Status Check Truth Table Across Step Execution States
- Previous Step State if: success() if: failure() if: always() if: cancelled()
- All Preceding Steps Succeeded true (Runs) false (Skipped) true (Runs) false (Skipped)
- A Preceding Step Failed false (Skipped) true (Runs) true (Runs) false (Skipped)
- Workflow Cancelled by User false (Skipped) false (Skipped) true (Runs) true (Runs)
- Preceding Step Skipped true (Runs) false (Skipped) true (Runs) false (Skipped)
- 4. Teardown, Cleanup & Notification Patterns
In robust CI/CD engineering, provisioning temporary cloud testbeds, databases, or preview environments requires guaranteed teardown logic. name: Integration Test with Cloud Teardown
on: [push]
jobs:
integration-suite:
runs-on: ubuntu-latest
steps:
- name: Checkout Code
- uses: actions/checkout@v4
- name: Provision Ephemeral Test Database
- id: provision
- run: ./scripts/cloud-db-create.sh --id "test-${{ github.run_id }}"
- name: Run End-to-End Test Suite
- run: npm run test:e2e
- name: Send Failure Alert to Incident Channel
- if: failure() # Executes ONLY if provisioning or tests failed
- run: |
- curl -X POST -H 'Content-type: application/json' \
- -data '{"text":"CI Failure on branch ${{ github.ref }}"}' \
- ${{ secrets.ALERT_WEBHOOK }}
- name: Teardown Ephemeral Test Database
- if: always() # Executes ALWAYS, guaranteeing no orphaned cloud resources
- run: ./scripts/cloud-db-destroy.sh --id "test-${{ github.run_id }}"
Caution
Evaluating Steps After if: always() : If a cleanup step using if: always() fails, subsequent steps without explicit conditions will be skipped because the job status transitions to failed . Ensure all critical cleanup tasks either specify if: always() or use continue-on-error: true .
5. Job Execution Timeouts ( timeout-minutes: )
Every job in GitHub Actions should declare a reasonable timeout using timeout-minutes . jobs:
build-and-test:
- runs-on: ubuntu-latest
- timeout-minutes: 15 # Terminates job if execution exceeds 15 minutes
steps:
- uses: actions/checkout@v4
- run: make test
Key Rules & Operational Best Practices:
Default Timeout: If timeout-minutes is not specified, GitHub Actions enforces a default timeout of 360 minutes (6 hours) per job.
Billing Protection: A hanging network call, unresponsive container, or deadlocked test process left unconstrained can consume up to 6 hours of runner capacity, exhausting organization concurrency limits and incurring massive billing charges.
Step vs. Job Timeouts: timeout-minutes can also be declared on individual steps . Setting timeout-minutes: 5 on a deployment step ensures long-running network operations fail fast before consuming the entire job allocation.