Skip to content

Conditions for GitHub Actions jobs and steps

GitHub Actions workflows don’t have to be simple linear sequences of jobs or steps. Using conditions, you can make your workflows smarter by controlling exactly when jobs and steps should run. This article will show you how to add logic and decision-making to your workflows.

Job-level conditions

Only want to deploy when code hits the main branch? Use GitHub’s ref context:

jobs:
deploy:
if: github.ref == 'refs/heads/main'
runs-on: ubuntu-latest
steps:
- run: echo "Deploying to production"

Smart job dependencies

Sometimes you want jobs to run even when their dependencies are skipped. Here’s how to handle a deployment that should run when tests are skipped (but not when they fail):

jobs:
test:
if: github.event_name != 'workflow_dispatch' # Skip tests on manual trigger
runs-on: ubuntu-latest
steps:
- run: echo "Running tests"
deploy:
needs: test
if: ${{ !failure() && !cancelled() }}
runs-on: ubuntu-latest
steps:
- run: echo "Deploying since tests passed or were skipped"

Step-level conditions

Control step execution based on previous outputs - useful for multi-stage deployments:

steps:
- id: check_env
run: |
echo "status=ready" >> $GITHUB_OUTPUT
- if: ${{ steps.check_env.outputs.status == 'ready' }}
run: echo "Environment is ready for deployment"

Key contexts for conditions

  • github - Access branch names, event types, commit info
  • needs - Check status of dependent jobs
  • steps - Read previous step outputs and status
  • env - Use environment variables
  • job - Get info about current job
  • runner - Access runner environment details

Status check functions

  • success() - Green light - previous steps passed
  • failure() - Red light - something failed upstream
  • cancelled() - Someone hit the cancel button
  • always() - Run regardless of previous status (use carefully!)

Expression syntax

Expressions use ${{ <expression> }} syntax (optional in if conditions). Chain conditions with && (AND) and || (OR):

steps:
- if: |
github.ref == 'refs/heads/main' &&
github.event_name == 'push' &&
success()
run: echo "Running production deploy on main branch push"

Resources