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.

Lesson 4 of 413 steps

Conditional Execution and Job Dependencies is a free DevOps Bootcamp lesson on CoddyKit. This is lesson 4 of 4. Any 3 lessons of this learning path are free to read in full — after that, CoddyKit PRO unlocks every lesson, plus hands-on practice with a built-in code editor and a 24/7 AI tutor. It is part of the DevOps Bootcamp learning path, and your progress syncs across the web and the CoddyKit app. The DevOps Bootcamp course includes 4 lessons in total.

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.

Free to start

Learn DevOps Bootcamp with an AI tutor — free

Write and run real code in your browser, get instant help from a 24/7 AI tutor, and pick up where you left off on the web or in the app.

Courses
142
Lessons
568

Frequently Asked Questions

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

Yes — any 3 lessons of the DevOps Bootcamp learning path, including “Conditional Execution and Job Dependencies”, are free to read in full here on the web. After that, CoddyKit PRO unlocks every lesson, plus interactive practice with a built-in code editor and a 24/7 AI tutor. The DevOps Bootcamp course includes 4 lessons in total.

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, so you can start here or from the beginning and move at your own pace. This is lesson 4 of 4.

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