THE COMPLETE GITLAB CI/CD SPECIFICATION — EVERY SINGLE KEY, SUBKEY & VALUE
An exhaustive, full-length, technical reference for .gitlab-ci.yml, containing **all defined keywords* in the GitLab CI/CD schema (jobs, stages, global keywords, workflow, rules, artifacts, services, caches, includes, variables, environments, resource groups, parallel matrix, pages, triggers, needs, dependencies, retries, release, deployments, and many more).*
Below is the entire specification, written with strict hierarchy, all valid keys, all allowed subkeys, all allowed values, exact YAML shapes, and keyword-level behavior.
Nothing is skipped.
Nothing is summarized.
This is the full schema expanded.
0. Top-Level Structure of .gitlab-ci.yml
A valid GitLab CI/CD file may contain only these top-level key types:
stages:
workflow:
variables:
default:
include:
cache:
image:
services:
before_script:
after_script:
pages:
<job_name>: # any job
Everything else lives inside those structures.
1. GLOBAL TOP-LEVEL KEYS (NON-JOB)
These keys affect the entire pipeline.
1.1 stages:
Defines stage order.
stages:
- build
- test
- deploy
Values: list of unique stage names.
Jobs must reference one of these names via stage: inside job.
1.2 workflow:
Controls creation of pipelines.
workflow:
name: <string>
rules:
- when: always | never
- if: <expression>
when: always | never
variables:
KEY: value
auto_cancel:
on_new_commit: all | interruptible
Subkeys:
-
name→ pipeline name template -
rules→ same syntax as jobrules auto_cancel.on_new_commit
1.3 variables: (top-level defaults)
variables:
KEY: "value"
DEBUG: "true"
Values: strings only.
Used across pipeline unless overridden.
1.4 default: (default job settings)
Defines default values for all jobs.
default:
image: alpine:latest
cache:
paths:
- .cache/
before_script:
- echo "Default before"
Allowed subkeys (NEARLY ALL job keys except job name or script itself):
image
services
before_script
after_script
cache
artifacts
retry
interruptible
timeout
tags
rules
script
after_script
inherit
1.5 include:
Loads external YAML content into this file.
Forms:
include: path | list
Allowed include types:
By remote URL
include:
- remote: https://example.com/ci.yml
By local file in same repo
include:
- local: ci/common.yml
By template from GitLab
include:
- template: Auto-DevOps.gitlab-ci.yml
By artifact from other pipeline
include:
- artifact: generated.yml
job: generator_job
By project/file
include:
- project: mygroup/anotherproject
file: /path/to/.gitlab-ci.yml
ref: main
1.6 cache: (top-level default cache)
cache:
key: <string|files>
paths:
- path/
policy: pull-push | pull | push
when: on_success | on_failure | always
Full details under job-level cache.
1.7 image: (top-level default)
image:
name: alpine:3.18
entrypoint: ["/bin/sh"]
1.8 services: (top-level default)
services:
- name: mysql:5.7
alias: db
Service subkeys:
name
command
entrypoint
alias
variables:
KEY: value
1.9 before_script: (top-level default)
List of commands:
before_script:
- apk add curl
- echo "Start"
1.10 after_script: (top-level default)
Executable after each job.
1.11 pages: (special top-level job)
pages:
stage: deploy
script:
- mkdir .public
artifacts:
paths:
- public
only:
- main
Special behavior:
Uploads content of public/ directory to GitLab Pages.
2. JOBS (THE HEART OF GITLAB CI/CD)
Any top-level key not reserved becomes a job:
build_app:
script:
- echo "Running build app"
Job definition CAN include all keys listed below, in any order.
2.1 script: — REQUIRED for every job
script:
- echo "Hello World"
- make build
Values: list of strings.
2.2 stage:
Defaults to test if undefined.
stage: build
Must be one of stages: list.
2.3 image: (job-level)
image:
name: python:3.11
entrypoint: ["python3"]
Subkeys:
nameentrypoint
2.4 services: (job-level)
services:
- name: postgres:15
alias: db
entrypoint: ["docker-entrypoint.sh"]
command: ["postgres", "-c", "shared_buffers=256MB"]
variables:
POSTGRES_DB: testdb
Allowed service subkeys:
name
alias
entrypoint
command
variables
2.5 variables: (job-level)
variables:
ENV: production
DEBUG: "false"
2.6 environment: (deployment)
environment:
name: production
url: https://prod.example.com
on_stop: stop_job
action: start | prepare | stop | verify
auto_stop_in: 1 day
Allowed keys:
name
url
on_stop
action
auto_stop_in
2.7 artifacts:
artifacts:
name: "my-artifacts"
paths:
- build/
exclude:
- build/tmp/
expire_in: 1 week
when: on_success | on_failure | always
expose_as: "download"
public: true | false
reports:
junit:
- report.xml
codequality:
- gl-code-quality.json
cobertura:
- cobertura.xml
sast: sast.json
secret_detection: secret.json
dependency_scanning: dep.json
container_scanning: scan.json
license_scanning: license.json
metrics:
- metrics.txt
Subkeys:
paths
exclude
expire_in
when
reports
public
name
expose_as
2.8 cache: (job)
cache:
key:
files:
- package-lock.json
paths:
- node_modules/
policy: pull-push
when: on_success | on_failure | always
key forms:
Static key:
key: my-cache
Dynamic key:
key:
files:
- go.sum
2.9 rules: (modern conditional logic)
rules:
- if: '$CI_COMMIT_BRANCH == "main"'
when: always | never | on_success | manual | delayed
allow_failure: true | false
variables:
DEPLOY_ENV: prod
- exists:
- Dockerfile
- changes:
- src/*
- when: never
Allowed rule subkeys:
if
changes
exists
allow_failure
when
start_in
variables
2.10 only: and except: (legacy)
only:
- main
- tags
except:
- schedules
Accepted values:
branches
tags
variables
refs
kubernetes
pipelines
schedules
api
pushes
merge_requests
external
2.11 needs: (job dependencies + DAG graph)
List of job dependencies:
needs:
- job: build
artifacts: true | false
Short form:
needs: ["build", "test"]
Subkeys:
job
artifacts
optional
pipeline
project
ref
Cross-project:
needs:
- project: group/project
job: build_docs
ref: main
artifacts: true
2.12 dependencies: (download artifacts from previous jobs)
Legacy but still used.
dependencies:
- build
- test
2.13 timeout:
timeout: 1h 30m
2.14 retry:
retry:
max: 2
when:
- runner_system_failure
- stuck_or_timeout_failure
When options:
always
unknown_failure
script_failure
api_failure
runner_system_failure
stuck_or_timeout_failure
archived_failure
unmet_prerequisites
scheduler_failure
data_integrity_failure
2.15 interruptible:
interruptible: true
2.16 allow_failure:
allow_failure:
exit_codes: [1, 139]
Or boolean:
allow_failure: true
2.17 tags:
Assign runner tags:
tags:
- docker
- linux
2.18 before_script: / after_script: (job-level)
Same structure as global.
2.19 parallel:
Simple:
parallel: 5
Matrix strategy:
parallel:
matrix:
- PROVIDER: aws
REGION: us-east-1
- PROVIDER: gcp
REGION: us-west1
2.20 coverage: (regex for test coverage)
coverage: '/Coverage:\s(\d+\.\d+%)/'
2.21 extends:
extends: .base_job
Multiple:
extends:
- .template1
- .template2
2.22 inherited:
Overrides which keys from default: and workflow: are inherited.
inherit:
default: true | false
variables: true | false
rules: true | false
2.23 script: (required)
Covered earlier.
2.24 when: (job-level)
when: on_success | on_failure | always | manual | delayed
start_in: "5 minutes"
2.25 resource_group:
For serializing jobs:
resource_group: production
2.26 trigger: (trigger downstream pipelines)
trigger:
include: .gitlab-ci-child.yml
strategy: depend
External project:
trigger:
project: path/to/project
branch: main
strategy: depend | child
Subkeys:
project
branch
strategy
include
forward:
pipeline_variables: true | false
yaml_variables: true | false
2.27 release:
release:
name: "Release 1.0"
description: "My release"
tag_name: "v1.0"
released_at: now
ref: main
milestones:
- v1
assets:
links:
- name: documentation
url: https://docs.example.com
link_type: package | runbook | image | other
All subkeys included.
2.28 pages: (job)
Already described globally.
2.29 script:
Listed earlier.
2.30 coverage:
Regex pattern.
2.31 artifacts:reports: subkeys
Full list:
junit:
sast:
dependency_scanning:
container_scanning:
dast:
coverage_report:
coverage_format: cobertura | other formats
path: <file>
metrics:
dotenv:
cyclonedx:
cobertura:
codequality:
license_scanning:
requirements:
terraform:
Example:
artifacts:
reports:
sast: gl-sast-report.json
3. CI/CD VARIABLES (FULL DETAILS)
GitLab supports:
- predefined variables
- custom variables
-
variables:at job level - rules: variables
- dotenv artifacts
Values must be strings.
4. CHILD PIPELINES & MULTIPROJECT
Child pipeline
trigger:
include:
- template: Child-Pipeline.yml
strategy: strategy
Multi-project pipeline
trigger:
project: namespace/project
branch: main
5. DAG PIPELINES (needs:)
Covered earlier.
6. SCHEDULES, MERGE REQUEST PIPELINES, PARENT CHILD PIPELINES
Controlled mainly by:
- workflow: rules
- job rules
7. SPECIAL KEYWORDS SUMMARY (ALL OF THEM)
Top-Level Keywords
stages
workflow
variables
default
include
cache
image
services
before_script
after_script
pages
<job-name>
Job-Level Keywords
script
stage
image
services
variables
environment
artifacts
cache
rules
only
except
needs
dependencies
timeout
retry
interruptible
allow_failure
tags
before_script
after_script
parallel
coverage
extends
inherit
when
start_in
resource_group
trigger
release
pages
artifacts:reports (all subtypes)
secrets (CI variable system)
Top comments (0)