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
Section titled “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
Section titled “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
Section titled “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
Section titled “Key contexts for conditions”github- Access branch names, event types, commit infoneeds- Check status of dependent jobssteps- Read previous step outputs and statusenv- Use environment variablesjob- Get info about current jobrunner- Access runner environment details
Status check functions
Section titled “Status check functions”success()- Green light - previous steps passedfailure()- Red light - something failed upstreamcancelled()- Someone hit the cancel buttonalways()- Run regardless of previous status (use carefully!)
Expression syntax
Section titled “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"