include, extends, !reference and components

GitLab CI/CD · Advanced · 14 min

Large projects and organisations need one maintained pipeline definition instead of copy-paste.

include merges other YAML files into your configuration:

  • include: local: ci/test.yml from the same repository.
  • include: project: my-group/ci-templates, ref: v2, file: node.yml from another project.
  • include: remote: from a URL, and include: template: for GitLab's bundled templates.
  • include: component: for CI/CD components.

Components are versioned, reusable pipeline pieces published to the CI/CD Catalog. A component declares typed inputs in a spec: header and is used as component: $CI_SERVER_FQDN/my-group/components/python-test@1.2.0 with inputs:. Inputs are substituted with $[[ inputs.name ]] when the file is included, so they are checked before the pipeline runs.

Hidden jobs start with a dot (.test-base) and never run; they serve as templates. extends inherits from one or more of them, deep-merging hashes. Lists like script are replaced, not concatenated.

When you need just one piece of another job, !reference pulls a specific value: script: [!reference [.setup, script], make test] combines lists that extends would overwrite.

Pin includes to tags or SHAs like any dependency, and use the pipeline editor's Full configuration view to see the merged result.

Example

include:
  - local: ci/lint.yml
  - project: acme/ci-templates
    ref: v2.3.0
    file: /templates/python.yml
  - component: $CI_SERVER_FQDN/acme/components/sast@1.4.0
    inputs:
      stage: test

.python-base:                     # hidden job: never runs on its own
  image: python:3.13
  before_script: [pip install -r requirements.txt]
  script: [echo base]

unit:
  extends: .python-base
  script: [pytest tests/unit]     # replaces the base script list

integration:
  extends: .python-base
  script:
    - !reference [.python-base, before_script]
    - pytest tests/integration

Remember

  • include pulls in local, project, remote, template and component files
  • Hidden .jobs plus extends give job templates; lists are replaced
  • Components are versioned with typed inputs from the CI/CD Catalog

Watch out for

  • Expecting extends to append to script; it overwrites the list. Use !reference to combine.

Check yourself

  1. A job extends .base, which has script: [a]. The job defines script: [b]. What runs?

Sign in to answer, see the explanations, and get this lesson back as a quick review later.

Official docs: docs.gitlab.com/ci/yaml/includes/