# How to Define Conditional Execution for Jobs and Steps in Probe

> Learn how to define conditional execution for jobs and steps in Probe using the skipif field and Go-template expressions. Control your workflows precisely.

- Repository: [Tomohisa Oda/probe](https://github.com/linyows/probe)
- Tags: how-to-guide
- Published: 2026-03-06

---

**Probe enables conditional execution through the `skipif` field, which accepts Go-template expressions that evaluate to boolean values—when `true`, the job or step is skipped entirely.**

The linyows/probe workflow engine provides flexible pipeline control through conditional logic. By leveraging the `skipif` field in your workflow definitions, you can dynamically skip entire jobs or individual steps based on runtime variables and previous outputs, creating adaptable CI/CD pipelines that respond to environment states.

## Understanding the skipif Field

The `skipif` field accepts a Go-template expression string that Probe evaluates at runtime. According to the linyows/probe source code, this expression must resolve to a boolean value. When the evaluation returns `true`, Probe marks the component as skipped and omits execution.

If the expression returns a non-boolean value or encounters an error, Probe logs the error and proceeds with normal execution rather than skipping.

## Job-Level Conditional Execution

### How Job Skipping Works

Job-level conditional execution is implemented in `func (j *Job) shouldSkip` within **[job.go](https://github.com/linyows/probe/blob/main/job.go)**. This method evaluates the job's `SkipIf` string using a `StepContext` containing workflow variables and current outputs.

The evaluation utilizes the `Expr.Eval` mechanism to process the template expression. If the result is not a boolean, Probe logs an error and the job runs normally rather than being skipped.

### Variable Availability for Jobs

Job skip conditions are evaluated **before** any steps execute. Consequently, the context only contains workflow variables (`vars`). Outputs from steps are unavailable at this stage because no steps have run yet.

## Step-Level Conditional Execution

### How Step Skipping Works

Step-level skipping is handled by `func (st *Step) shouldSkip` in **[step.go](https://github.com/linyows/probe/blob/main/step.go)**. Each step's `SkipIf` expression evaluates against the step's own context (`st.ctx`), using the same `Expr.Eval` mechanism as job-level skipping.

When a step is skipped, the `handleSkip` method creates a `StepResult` with status `StatusSkipped`, and the UI renders a gray "SKIPPED" icon to indicate the omission.

### Variable Availability for Steps

Step skip conditions evaluate after the step's context is fully built, providing access to:

- Workflow variables (`vars`)
- Outputs from earlier steps (`outputs`)
- The current step's iteration index (`repeat.index`) when operating in repeat mode

## Configuration Examples

The repository includes practical examples demonstrating conditional execution patterns. The **[examples/skipif-literal.yml](https://github.com/linyows/probe/blob/main/examples/skipif-literal.yml)** file and **[testdata/e2e-test.yml](https://github.com/linyows/probe/blob/main/testdata/e2e-test.yml)** demonstrate various `skipif` scenarios.

Basic job skipping based on environment variables:

```yaml
jobs:
  - id: build
    name: Build job
    skipif: vars.ci == ""
    steps:
      - uses: actions/checkout@v3

```

Step-level conditions referencing previous outputs:

```yaml
jobs:
  - id: test
    name: Test job
    steps:
      - uses: docker/run@v1
        skipif: vars.build_skipped == true
      - uses: ./custom-action
        skipif: vars.environment != "production"

```

The [`skipif-literal.yml`](https://github.com/linyows/probe/blob/main/skipif-literal.yml) example shows literal boolean and conditional expressions:

```yaml
description: skipif functionality with gray colored icons
jobs:
  - id: demo
    skipif: vars.skip
    steps:
      - name: skipif is true (Should skip)
        skipif: true
        uses: ./noop
      - name: skipif is false (Should not skip)
        skipif: false
        uses: ./noop
      - name: conditional based on env
        skipif: vars.environment != "production"
        uses: ./noop

```

## Critical Behavior and Edge Cases

Understanding Probe's error handling ensures reliable pipeline execution:

- **Boolean requirement**: The expression must return a boolean. Non-boolean results trigger error logging and normal execution.
- **Empty strings**: Empty or malformed `skipif` strings are ignored, treated as "do not skip".
- **Repeat mode handling**: In repeat mode, a skipped step counts as a successful execution, not a failure.
- **Result propagation**: The `handleSkip` methods in both job and step contexts properly update `JobResult` or create `StepResult` instances with `StatusSkipped` status.

## Summary

- Use the `skipif` field in job or step definitions to enable conditional execution in Probe workflows.
- Job-level conditions evaluate in `func (j *Job) shouldSkip` within [`job.go`](https://github.com/linyows/probe/blob/main/job.go) before any steps run, accessing only workflow variables.
- Step-level conditions evaluate in `func (st *Step) shouldSkip` within [`step.go`](https://github.com/linyows/probe/blob/main/step.go) with access to variables, previous outputs, and repeat indices.
- Expressions must evaluate to boolean `true` to trigger skipping; non-boolean results or errors cause normal execution with logged warnings.
- Skipped components display gray "SKIPPED" indicators in the UI and maintain successful execution status for pipeline continuity.

## Frequently Asked Questions

### What happens if my skipif expression returns a non-boolean value?

Probe logs an error message and proceeds with normal execution of the job or step. The expression must explicitly evaluate to a boolean `true` to trigger skipping; any other return type is treated as an error condition that fails safe by running the component.

### Can I reference step outputs in a job-level skipif condition?

No. Job-level `skipif` expressions evaluate before any steps execute, so the context only contains workflow variables (`vars`). Step outputs are only available in step-level `skipif` conditions, which evaluate after the step context is built and previous steps have produced results.

### How does Probe handle empty or invalid skipif expressions?

Empty or malformed `skipif` strings are treated as "do not skip" and the job or step executes normally. This default behavior ensures that configuration errors or missing fields do not inadvertently prevent critical pipeline stages from running.

### Does a skipped step count as a failure in Probe pipelines?

No. According to the implementation in [`step.go`](https://github.com/linyows/probe/blob/main/step.go), skipped steps are marked with `StatusSkipped` and count as successful executions. This design ensures that conditional omissions do not trigger pipeline failure states, maintaining flow continuity when steps are intentionally bypassed based on runtime conditions.