Jobs
Job schema, DAG dependencies (needs), conditional execution (if), side-car services
jobs is the set of tasks to execute in a Workflow. Each Job runs in parallel by default, and you use needs to control execution order.
Job Schema
jobs:
# Job ID: unique identifier (letters, numbers, _, - allowed)
build:
# Dependent Job — build runs after test completes
needs: [test]
# Conditional execution — run only if the previous Job succeeded
if: "success()"
# Metadata — used to distinguish phases in the dashboard
phase: build
# Job-level environment variables
env:
NODE_ENV: production
# Auxiliary services (e.g., Docker)
services:
- docker
# List of steps (at least 1 required)
steps:
- name: compile
run: npm run build
image: node:18Job Fields
| Field | Required | Type | Description |
|---|---|---|---|
steps | YES | list | List of steps (can be omitted when using include) |
include | NO | string | Workspace template reference (workspace/repo/name format) |
needs | NO | list[string] | List of dependent Job IDs |
if | NO | string | Conditional execution expression |
phase | NO | string | Metadata. One of source, deps, build, test, security, deploy |
env | NO | object | Job-level environment variables |
services | NO | list | List of auxiliary services |
timeout-minutes | NO | int | Job timeout in minutes (must be positive) |
Job ID Rules
Allowed characters: [a-zA-Z0-9_-]
Maximum 255 characters
Case-insensitive (Build and build are the same ID)
Spaces and special characters are not allowed
Must be unique within the Workflow
needs (DAG Dependencies)
needs defines the execution order between Jobs. Jobs without needs run in parallel.
Sequential Execution
jobs:
# Phase 1: lint (no dependencies → runs immediately)
lint:
steps:
- name: eslint
run: npm run lint
image: node:18
# Phase 2: test (runs after lint completes)
test:
needs: [lint]
steps:
- name: unit-test
run: npm test
image: node:18
# Phase 3: deploy (runs after test completes)
deploy:
needs: [test]
steps:
- name: deploy
run: ./deploy.shParallel + Join (Fan-out / Fan-in)
jobs:
# Phase 1: checkout (common)
checkout:
steps:
- name: checkout
uses: "collabops/checkout@v2"
with:
repo-url: "https://<collabops-host>/<workspace>/<repository>.git"
# Phase 2: lint and test run in parallel
lint:
needs: [checkout]
steps:
- name: eslint
run: npm run lint
image: node:18
test:
needs: [checkout]
steps:
- name: unit-test
run: npm test
image: node:18
# Phase 3: deploy after both lint and test complete
deploy:
needs: [lint, test]
steps:
- name: deploy
run: ./deploy.shExample Pipeline DAG
DAG Rules
Circular dependencies (cycles) are not allowed — a → b → a is invalid
Self-references are not allowed — needs: [self] is invalid
Referencing non-existent Job IDs is not allowed
All Jobs specified in needs must succeed for the next Job to run
Conditional Execution (if)
if is supported only at the Job level. It cannot be used at the Step level.
Status Functions
jobs:
deploy:
needs: [build]
# Run only if the previous Job (build) succeeded (default behavior)
if: "success()"
steps: [...]
cleanup:
needs: [build]
# Always run regardless of success or failure
if: "always()"
steps: [...]
rollback:
needs: [deploy]
# Run only when the deploy Job has failed
if: "failure()"
steps: [...]| Function | Description |
|---|---|
success() | When all previous Jobs succeeded (default behavior) |
failure() | When a previous Job (specified in needs) has failed |
always() | Always runs regardless of previous Job success or failure |
failure() requires needs to specify which Jobs to monitor. The Job will run only when at least one of the dependent Jobs has failed.
cancelled() is not currently supported.
Comparison Operators
jobs:
deploy:
# Deploy only on push to main branch
if: "collabops.ref == 'refs/heads/main'"
steps: [...]
skip-cr:
# Run only when the event is not a change_request
if: "collabops.event_name != 'change_request'"
steps: [...]Supported operators: ==, !=
String Functions
| Function | Description | Example |
|---|---|---|
contains(string, substring) | Checks if a substring is present | contains(collabops.ref, 'release') |
startsWith(string, prefix) | Checks for prefix match | startsWith(collabops.ref_name, 'feature/') |
endsWith(string, suffix) | Checks for suffix match | endsWith(collabops.ref_name, '-hotfix') |
jobs:
release:
# Run only if the branch name contains 'release'
if: "contains(collabops.ref, 'release')"
steps: [...]
feature-test:
# Run additional tests only on feature/ branches
if: "startsWith(collabops.ref_name, 'feature/')"
steps: [...]Logical Operators
Supports && (AND), || (OR), ! (NOT), and parenthetical grouping.
jobs:
deploy-prod:
# Deploy only on push to main branch and when previous Jobs succeeded
if: "success() && collabops.ref == 'refs/heads/main' && collabops.event_name == 'push'"
steps: [...]
deploy-staging:
# Deploy to staging on push to main or develop branch
if: "(collabops.ref == 'refs/heads/main' || collabops.ref == 'refs/heads/develop') && collabops.event_name == 'push'"
steps: [...]Unsupported Features
cancelled() — planned for future support
Step-level if — use Job-level if or shell conditionals inside run instead
services
Declares auxiliary services that run alongside a Job. Currently supports the Docker service.
Sugar Syntax
jobs:
build:
# Declare Docker service with shorthand
services:
- docker
steps:
- name: build-image
run: docker build -t my-app .Declaring docker in services automatically enables the Docker service. The docker-build-push template configures this automatically behind the scenes.
phase
phase is metadata used to visually distinguish Job stages in the dashboard.
phase is purely metadata and does not affect execution behavior. It is used solely for visual distinction in the dashboard.
| Phase | Purpose |
|---|---|
source | Source code checkout |
deps | Dependency installation |
build | Build |
test | Testing, linting |
security | Security scanning |
deploy | Deployment |
jobs:
lint:
phase: test # Displayed as the "test" phase in the dashboard
steps: [...]
build:
phase: build # Displayed as the "build" phase in the dashboard
steps: [...]
deploy:
phase: deploy # Displayed as the "deploy" phase in the dashboard
steps: [...]