Working with Conditional Execution
1. Using If Conditions
GitHub Actions allows you to run jobs or steps conditionally using the if expression. The if condition is evaluated at runtime and determines whether a step or job should execute.
| Expression | Description | Example |
|---|---|---|
| if | Condition to evaluate before running a step or job | if: github.event_name == 'push' |
Example: Conditional Step Based on Event
steps:
- name: Run on Push
if: github.event_name == 'push'
run: echo "This runs only on push events"
Example: Conditional Step Based on Branch
steps:
- name: Run on Main Branch
if: github.ref == 'refs/heads/main'
run: echo "Running on main branch"
Note: The
if condition supports JavaScript-like syntax and can use context variables, functions, and operators.
Common If Conditions
github.event_name == 'push'— Runs on push eventsgithub.ref == 'refs/heads/main'— Runs only on the main branchgithub.actor == 'octocat'— Runs only if the actor is octocatgithub.event.pull_request.merged == true— Runs only if the PR is merged
2. Checking Job Status
| Expression | Description | Usage |
|---|---|---|
| success() | Runs if the job succeeded | if: success() |
| failure() | Runs if the job failed | if: failure() |
| cancelled() | Runs if the job was cancelled | if: cancelled() |
| always() | Runs regardless of job status | if: always() |
Example: Using success() and failure()
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
deploy:
needs: build
if: success()
runs-on: ubuntu-latest
steps:
- name: Deploy to production
run: echo "Deploying..."
cleanup:
needs: build
if: failure()
runs-on: ubuntu-latest
steps:
- name: Cleanup resources
run: echo "Cleaning up..."
3. Checking Step Status
| Property | Description | Usage |
|---|---|---|
| steps.<step-id>.outcome | Indicates the outcome of a step, either success, failure, cancelled, or skipped. |
${{ steps.my-step.outcome }} |
| steps.<step-id>.conclusion | Provides a more granular status, including success, failure, cancelled, skipped, or failure for a step that was skipped due to a condition. |
${{ steps.my-step.conclusion }} |
Example: Using step outcome in a conditional
name: Check Step Outcome
on: [push]
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Run a step that might fail
id: my-step
run: |
echo "Running some command"
exit 1
- name: Check if previous step failed
if: steps.my-step.outcome == 'failure'
run: |
echo "The previous step failed"
4. Using Always Condition
| Condition | Description | Usage |
|---|---|---|
| always() | Executes the job or step regardless of the outcome of previous steps | if: always() |
Example: Using always() condition
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Run tests
run: npm test
continue-on-error: true
- name: Always run cleanup
if: always()
run: echo "Cleaning up resources..."
5. Using Cancelled Condition
The cancelled condition in GitHub Actions is used to run a job or step when the workflow has been cancelled. This can be useful for cleanup operations or sending notifications.
| Condition | Description | Usage Example |
|---|---|---|
| cancelled() | Triggers when the workflow run is cancelled | if: ${{ job.status == 'cancelled' }} |
Example: Cancelled Condition in a Job
jobs:
cleanup:
if: ${{ job.status == 'cancelled' }}
runs-on: ubuntu-latest
steps:
- name: Notify on cancellation
run: echo "Workflow was cancelled"
6. Combining Conditions
GitHub Actions allows you to combine multiple conditions using logical operators in the if context of a job or step. These conditions can be used to control when jobs or steps run based on complex criteria.
| Operator | Description | Example |
|---|---|---|
| and | Logical AND operator. All conditions must be true. | if: ${{ github.event_name == 'push' && github.ref == 'refs/heads/main' }} |
| or | Logical OR operator. At least one condition must be true. | if: ${{ github.event_name == 'push' || github.event_name == 'pull_request' }} |
| not | Logical NOT operator. Negates the condition. | if: ${{ !(github.event_name == 'push') }} |
| () | Grouping operator to control precedence. | if: ${{ (github.event_name == 'push') && (github.ref == 'refs/heads/main' || github.ref == 'refs/heads/develop') }} |
Example: Combining Conditions in a Job
jobs:
deploy:
if: ${{ github.event_name == 'push' && (github.ref == 'refs/heads/main' || github.ref == 'refs/heads/staging') }}
runs-on: ubuntu-latest
steps:
- name: Deploy to Production
run: echo "Deploying..."
Example: Combining Conditions in a Step
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Run on Main or Staging
if: ${{ github.event_name == 'push' && (github.ref == 'refs/heads/main' || github.ref == 'refs/heads/staging') }}
run: echo "Running build on main or staging branch"
7. Checking Event Type
| Event Type | Description | Usage |
|---|---|---|
| pull_request | Triggered when a pull request is opened, synchronized, or closed. | on: pull_request |
| push | Triggered when a commit is pushed to a branch. | on: push |
| workflow_dispatch | Allows manual triggering of a workflow. | on: workflow_dispatch |
| schedule | Triggers a workflow based on a cron schedule. | on: schedule |
| issue_comment | Triggered when a comment is added to an issue or pull request. | on: issue_comment |
Example: Using event type in conditions
on:
push:
branches: [ main ]
pull_request:
branches: [ main ]
jobs:
build:
if: github.event_name == 'push'
runs-on: ubuntu-latest
steps:
- run: echo "Push event detected"
8. Checking Branch
| Condition | Description | Example |
|---|---|---|
| github.ref | Current branch or tag ref | refs/heads/main |
| github.ref_name | Name of the branch or tag | main |
| github.ref_type | Type of ref: branch or tag |
branch |
Example: Check if on main branch
on:
push:
branches: [ main ]
jobs:
build:
runs-on: ubuntu-latest
if: ${{ github.ref_name == 'main' }}
steps:
- name: Run build
run: echo "Building on main branch"
Example: Check if on feature branch
on:
push:
branches: [ '*' ]
jobs:
build:
runs-on: ubuntu-latest
if: ${{ startsWith(github.ref_name, 'feature/') }}
steps:
- name: Run feature build
run: echo "Building on feature branch"
9. Checking Actor
| Property | Description | Values |
|---|---|---|
| github.actor | The username of the person or app that initiated the workflow run | octocat |
| github.event_name | The name of the event that triggered the workflow | push, pull_request, schedule |
| github.event | Full event payload for the triggering event | Object containing event data |
Example: Using github.actor in a condition
on:
push:
branches: [ main ]
jobs:
build:
runs-on: ubuntu-latest
if: github.actor == 'octocat'
steps:
- run: echo "Running build for octocat"
10. Using Ternary Expressions
| Expression | Description | Usage |
|---|---|---|
| condition ? valueIfTrue : valueIfFalse | Conditional operator that evaluates a condition and returns one of two values | github.event_name === 'push' ? 'deploy' : 'test' |
Example: Setting Job Matrix Based on Event
jobs:
build:
strategy:
matrix:
os: [ubuntu-latest, windows-latest]
node-version: [14, 16, 18]
steps:
- name: Set test matrix
run: echo "OS: ${{ matrix.os }}"
Example: Conditional Environment Variable
env:
ENVIRONMENT: ${{ github.event_name === 'push' ? 'production' : 'staging' }}
11. Handling Default Values
| Property | Description | Default Value | Example |
|---|---|---|---|
| env | Environment variables available to all jobs | Empty object | {"NODE_VERSION": "18"} |
| if | Conditional expression to determine job execution | Always true | success() |
| continue-on-error | Whether to continue workflow on job failure | false | true |
Example: Setting Default Values in Workflow
name: Default Values Example
on:
push:
branches: [ main ]
jobs:
build:
runs-on: ubuntu-latest
env:
NODE_VERSION: "18"
steps:
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}
12. Using Environment Conditions
| Condition | Description | Example |
|---|---|---|
| github.event_name | Event that triggered the workflow | push, pull_request |
| github.ref | Branch or tag ref that triggered the workflow | refs/heads/main, refs/tags/v1.0 |
| github.actor | User who triggered the workflow | octocat |
| github.repository | Full name of the repository | octocat/Hello-World |
| github.workflow | Name of the workflow | CI |
| github.run_number | Unique number for each run of a workflow | 12345 |
| github.sha | Commit SHA that triggered the workflow | a1b2c3d4e5f6... |