.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):

  1. Predefined CI_* variables — see Predefined variables.
  2. Project variables (Settings → Variables); protected ones only on default-branch pipelines.
  3. Pipeline-level variables: (plus any from a schedule or manual run).
  4. Job-level variables: and rules variables.

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.