Mastering GitLab CI Hidden Jobs: Reuse, Extend, and Simplify Pipelines
This guide explains how GitLab CI hidden jobs work, why they’re essential for DRY pipelines, and provides step‑by‑step examples of using the extends keyword for single and multiple inheritance, configuration merging, and visualizing job relationships.
When writing a .gitlab-ci.yml file, repetitive configuration across multiple jobs—such as the same stage, tags, or preparation scripts—can become cumbersome and error‑prone. GitLab CI solves this with hidden jobs , which act as reusable templates that never run directly in a pipeline but can be inherited by regular jobs.
What Is a Hidden Job?
A hidden job is any job whose name starts with a dot ( .). The parser recognizes it but excludes it from the execution graph, effectively treating it as a configuration blueprint.
Why Use Hidden Jobs?
Maximum reuse : Any key‑value pair—variables, scripts, tags, cache, artifacts—can be placed in a hidden job and inherited by other jobs.
Improved maintainability : Updating a shared setting (e.g., a Docker image) in one hidden job automatically propagates to all dependent jobs.
Clear structure : Group related settings into logically named templates such as .base_template, .docker_build_template, or .deploy_to_aws_template, making the .gitlab-ci.yml self‑documenting.
How to Use Hidden Jobs – The extends Keyword
Regular jobs inherit hidden jobs via the extends keyword. The child job merges the hidden job’s configuration with its own.
Basic Single Inheritance Example
.base_build_template:
stage: build
tags:
- docker-builder
before_script:
- echo "Logging into private registry..."
- docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
build_project_a:
extends: .base_build_template
script:
- echo "Building Project A..."
- docker build -t project-a .
build_project_b:
extends: .base_build_template
script:
- echo "Building Project B..."
- docker build -t project-b .Both build_project_a and build_project_b inherit the stage, tags, and before_script from .base_build_template while providing their own script sections.
Configuration Merging Rules
Hashes (e.g., variables ) : merged.
Arrays (e.g., script , tags ) : child definition completely overrides the parent.
Scalar values (e.g., stage , image ) : child overrides parent.
Advanced Multiple Inheritance
The extends keyword can accept a list of hidden jobs, allowing you to combine different configuration fragments.
.on_production_runner:
tags:
- production
.base_deploy_script:
before_script:
- ./prepare_deployment.sh
script:
- ./execute_deployment.sh
after_script:
- ./cleanup.sh
deploy_to_production:
stage: deploy
extends:
- .on_production_runner
- .base_deploy_script
variables:
DEPLOY_TARGET: "production-server-1"When multiple templates define the same key, the rightmost template wins, and the job’s own definitions have the highest priority.
Visualizing Inheritance
UML‑style diagrams can illustrate how jobs inherit from multiple hidden jobs, similar to class inheritance in software design.
Conclusion
GitLab CI hidden jobs, combined with extends, provide a powerful design pattern for DRY, modular, and maintainable pipeline configurations. Whenever you find yourself copying and pasting CI/CD snippets, consider extracting them into a hidden job to improve clarity and robustness.
Ops Development & AI Practice
DevSecOps engineer sharing experiences and insights on AI, Web3, and Claude code development. Aims to help solve technical challenges, improve development efficiency, and grow through community interaction. Feel free to comment and discuss.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
