.depllo-ci.yml reference
Depllo reads a GitLab-CI-compatible subset. This page documents every
key it supports. Anything not listed here is either ignored or, in the
case of include:, rejected with a clear error.
A config is a YAML map. Reserved top-level keys (stages, default,
variables, workflow) configure the pipeline; every other top-level
map is a job.
Top-level keys
stages
The ordered list of stages. Jobs run stage by stage. Defaults to
[build, test, deploy] if omitted.
stages:
- test
- build
- deploy
default
Defaults applied to every job unless the job overrides them. Supported
sub-keys: image, before_script, after_script, retry, timeout,
cache, tags.
default:
image: node:24-bookworm
before_script:
- npm ci
retry: 1
timeout: 30m
variables
Pipeline-wide variables, available to every job as environment
variables. Job-level variables override these.
variables:
NODE_ENV: test
API_BASE: https://staging.example.com
workflow
Controls whether a pipeline is created at all. Only rules is supported
(same grammar as job rules). The first matching rule decides;
when: never blocks the pipeline.
workflow:
rules:
- if: '$CI_PIPELINE_SOURCE == "push"'
- if: '$CI_COMMIT_REF_NAME == "main"'
- when: never
include (not supported)
include: is rejected with an explicit config error — Depllo has no
remote-config resolution in v1. Keep everything in one file (or use
extends and YAML anchors to share
blocks).
Job keys
A job is any top-level map that isn't a reserved key. script is
required unless an extends target provides it.
script, before_script, after_script
The commands to run. Each is a list of shell lines, executed with
bash -e. before_script runs first, then script, then
after_script (which runs even if script fails).
test:
before_script:
- npm ci
script:
- npm run lint
- npm test
after_script:
- echo "done"
stage
The stage this job belongs to. Must be one of stages. Defaults to
test.
image
The Docker image to run in. Defaults to default.image, or
node:24-bookworm if unset.
build:
image: golang:1.23
script: [go build ./...]
needs
A list of job names this job depends on. needs can cross stages — a
job becomes ready as soon as all its needs reach terminal-success. An
empty needs (or no needs) means the job waits on the stage
barrier: all jobs of earlier stages must be terminal first.
deploy:
stage: deploy
needs: [build, test]
script: [./deploy.sh]
An allow_failure: true job counts as success for readiness even when it
fails.
rules
A list of { if, when, allow_failure, variables } entries. The first
matching rule wins; if no rule matches, the job is excluded from the
pipeline. See the expression grammar below.
deploy:
script: [./deploy.sh]
rules:
- if: '$CI_COMMIT_REF_NAME == "main"'
when: on_success
- if: '$CI_PIPELINE_SOURCE == "schedule"'
when: on_success
variables:
DEPLOY_ENV: nightly
- when: never
only / except (legacy)
Branch/tag name lists, and the refs: form, for compatibility with older
GitLab configs. Prefer rules for new work.
publish:
script: [./publish.sh]
only:
- main
- tags
artifacts
Files to collect after the job. paths is required; expire_in sets a
retention window (e.g. 1 week, 30 days, null = keep); when
controls when to upload (on_success — default, on_failure, always).
build:
script: [npm run build]
artifacts:
paths:
- dist
- coverage/lcov.info
expire_in: 1 week
when: on_success
Downstream jobs receive artifacts from their needs/dependencies
automatically.
cache
A keyed cache reused across runs. key names the cache; paths are the
directories to cache; policy is pull-push (default), pull, or
push.
default:
cache:
key: node-$CI_COMMIT_REF_NAME
paths:
- node_modules
policy: pull-push
variables
Job-level environment variables. Highest precedence after predefined variables (see merge order).
when
When the job runs: on_success (default), on_failure, always, or
manual. A manual job starts in the manual state and only runs when
you press play in the dashboard (or call the play API).
allow_failure
true lets the pipeline succeed even if this job fails (the job still
shows as failed).
retry
How many times to auto-retry a failed job — an int, or { max: N }.
Range 0..2.
flaky:
script: [./e2e.sh]
retry: 2
timeout
Per-job wall-clock limit, e.g. 1h, 30m, 90s. Enforced server-side —
a job exceeding it fails with stuck_timeout. Defaults to 1 hour.
tags
Runner tag selectors. A job only runs on a runner whose tags are a superset of the job's tags. Use tags to route jobs to specific runners.
gpu-build:
tags: [gpu, linux]
script: [./train.sh]
dependencies
Restricts which jobs' artifacts this job downloads (by default it gets
all artifacts from its needs). An empty list downloads nothing.
deploy:
needs: [build, test]
dependencies: [build] # only build's artifacts
script: [./deploy.sh]
YAML anchors & extends
YAML anchors
Standard YAML anchors/aliases work for sharing blocks.
.node-defaults: &node
image: node:24-bookworm
before_script: [npm ci]
test:
<<: *node
script: [npm test]
extends
Inherit from one or more hidden jobs (names starting with .). Supports
a single parent or a list, deep-merges the maps, and allows nesting up to
depth 10.
.base:
image: node:24-bookworm
before_script: [npm ci]
.with-cache:
cache:
key: node
paths: [node_modules]
test:
extends: [.base, .with-cache]
script: [npm test]
rules.if expression grammar
rules.if (and workflow.rules.if) expressions are evaluated against the
pipeline's variable set. Supported:
- Variable references:
$VAR - String literals:
'x'or"x" - Comparison:
==,!= - Regex match:
=~ /pattern/,!~ /pattern/ - Boolean logic:
&&,||, and parentheses null
rules:
- if: '$CI_COMMIT_BRANCH == "main" && $CI_PIPELINE_SOURCE != "schedule"'
- if: '$CI_COMMIT_TAG =~ /^v\d+\./'
- when: never
Variable precedence
At dispatch, variables merge in this order (later wins):
- Predefined
CI_*variables — see Predefined variables. - Project variables (Settings → Variables); protected ones only on default-branch pipelines.
- Pipeline-level
variables:(plus any from a schedule or manual run). - Job-level
variables:andrulesvariables.
Config errors
Invalid YAML or an unsupported construct produces a config error. When a
webhook-triggered pipeline has a broken config, Depllo still creates the
pipeline with a single failed config_error job so the failure is
visible in the UI and as a red commit status — rather than silently doing
nothing.