0Pricing
DevOps Bootcamp · Lesson

Conditional Execution and Job Dependencies

Control when steps and jobs run using if conditions, the needs keyword, expressions, and status check functions in GitHub Actions workflows.

Conditional Execution and Job Dependencies is a free DevOps Bootcamp lesson on CoddyKit — lesson 4 of 4. You can read the complete lesson below for free — then practise it hands-on in the browser with a built-in code editor and a 24/7 AI tutor. It is part of the DevOps Bootcamp learning path, one of 4 lessons in the course, and your progress syncs across the web and the CoddyKit app.

Why Conditions Matter

Not every step should run every time. You might want a deploy step to run only on the main branch, or a notification step to run only when something failed.

GitHub Actions lets you attach an if condition to any step or job to control whether it executes.

The if Key

Add an if: key to a step. The step only runs when the expression evaluates to true.

Expressions inside if do not need the ${{ }} wrapper, though it is allowed.

steps:
  - name: Deploy
    if: github.ref == 'refs/heads/main'
    run: ./deploy.sh

Context Objects

Conditions read from context objects that describe the run:

  • github — event, ref, actor, sha
  • env — environment variables
  • job and steps — status of prior work
  • runner — OS and architecture

For example, github.event_name tells you whether a push or pull_request triggered the run.

Status Check Functions

By default, a step is skipped if a previous step failed. To override this, use the status functions:

  • success() — true if no prior step failed (the default)
  • failure() — true if any prior step failed
  • always() — runs no matter what
  • cancelled() — true if the run was cancelled
  - name: Notify on failure
    if: failure()
    run: echo 'Build failed, sending alert'

Always Run Cleanup

A common pattern is a cleanup step that must run even if earlier steps failed. Use if: always().

This guarantees temporary resources, containers, or test reports are handled regardless of the outcome.

  - name: Upload logs
    if: always()
    uses: actions/upload-artifact@v4
    with:
      name: logs
      path: ./logs

Job Dependencies with needs

The needs keyword makes one job wait for others. Without it, jobs run in parallel.

A job listed in needs must finish successfully before the dependent job starts.

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - run: npm test
  deploy:
    needs: test
    runs-on: ubuntu-latest
    steps:
      - run: ./deploy.sh

Multiple Dependencies

A job can depend on several jobs by passing a list to needs. It waits for all of them.

This is how you build fan-in patterns, where a final job runs only after parallel jobs all succeed.

  release:
    needs: [lint, test, build]
    runs-on: ubuntu-latest
    steps:
      - run: echo 'all checks passed'

Conditional Jobs

The if key works on jobs too, not just steps. A job-level condition decides whether the entire job runs.

Here the deploy job runs only for pushes to main, while still depending on tests.

  deploy:
    needs: test
    if: github.ref == 'refs/heads/main'
    runs-on: ubuntu-latest
    steps:
      - run: ./deploy.sh

Using Job Outputs

Jobs can pass data downstream via outputs. A dependent job reads them through the needs context.

This lets a condition depend on a value computed earlier, such as whether a version changed.

  check:
    runs-on: ubuntu-latest
    outputs:
      changed: ${{ steps.diff.outputs.changed }}
    steps:
      - id: diff
        run: echo 'changed=true' >> $GITHUB_OUTPUT

Combining Conditions

You can combine expressions with && (and), || (or), and ! (not).

This example runs only on a successful push to main that is not a fork.

    if: success() && github.ref == 'refs/heads/main' && github.event_name == 'push'

if Always With needs

Careful: a job with needs is skipped if a dependency fails. To run a final reporting job regardless, combine needs with if: always().

Inside it you can inspect needs.<job>.result to decide what to report.

  report:
    needs: [test, build]
    if: always()
    runs-on: ubuntu-latest
    steps:
      - run: echo ${{ needs.test.result }}

Quick Check

Test your understanding of conditional execution.

Recap

You learned to control workflow flow with conditions and dependencies.

  • if gates steps and jobs on expressions
  • Status functions like failure() and always() override skip-on-failure
  • needs creates ordering and fan-in patterns
  • Job outputs feed values into later conditions

These primitives let you build precise, efficient pipelines.

Frequently asked questions

Is the “Conditional Execution and Job Dependencies” lesson free?

Yes — the full text of “Conditional Execution and Job Dependencies” is free to read here on the web, and the DevOps Bootcamp course includes 4 lessons in total. To practise it interactively (a built-in code editor and a 24/7 AI tutor) and unlock the rest of the DevOps Bootcamp course, upgrade to CoddyKit PRO.

What will I learn in “Conditional Execution and Job Dependencies”?

Control when steps and jobs run using if conditions, the needs keyword, expressions, and status check functions in GitHub Actions workflows. You practise DevOps Bootcamp with hands-on code you run directly in the browser, and a 24/7 AI tutor answers your questions as you work through the lesson.

Do I need any experience to start DevOps Bootcamp?

No prior experience is required. DevOps Bootcamp on CoddyKit is structured for beginners through advanced learners; this is — lesson 4 of 4, so you can start here or from the beginning and move at your own pace.

How long does the “Conditional Execution and Job Dependencies” lesson take?

Most CoddyKit lessons take about 5–10 minutes. Each one is bite-sized and interactive, so you make steady progress and pick up exactly where you left off across the web and the app.

Can I write and run code in this DevOps Bootcamp lesson?

Yes. Every DevOps Bootcamp lesson includes a built-in code editor, so you write and run real code right in your browser and get instant AI feedback — no local setup required.

All lessons in this course

  1. Matrix Builds for Multiple Environments
  2. Caching Dependencies for Speed
  3. Reusable Workflows and Actions
  4. Conditional Execution and Job Dependencies
← Back to DevOps Bootcamp