Setting Up Pipeline Configuration
1. Creating .gitlab-ci.yml File
Example: Basic .gitlab-ci.yml Structure
image: node:18
services:
- postgres:13
variables:
POSTGRES_DB: test_db
POSTGRES_USER: test_user
POSTGRES_PASSWORD: test_password
before_script:
- npm install
- npm run build
test:
script:
- npm test
artifacts:
reports:
junit: junit.xml
deploy:
script:
- echo "Deploying..."
only:
- main
| Property | Description | Values |
|---|---|---|
| image | Specifies the Docker image to use for the job | node:18, python:3.9 |
| services | List of services to use in the job | postgres:13, redis:latest |
| variables | Environment variables available to all jobs | POSTGRES_DB: test_db |
| before_script | Script to run before each job's script | - npm install |
| script | Command or list of commands to execute in the job | - npm test |
| artifacts | Files to save and pass between jobs | reports: junit: junit.xml |
| only | Branches or tags to run the job on | - main, - /^v\d+\.\d+/ |
Note: The
.gitlab-ci.yml file must be in the root of your repository.
2. Understanding YAML Syntax
| Feature | Description | Example |
|---|---|---|
| Indentation | YAML uses indentation to define structure. Spaces are preferred over tabs. | |
| Keys and Values | Keys and values are separated by a colon and space. | image: alpine:latest |
| Lists | Lists are defined using a dash and space. | |
| Comments | Comments start with # and go to the end of the line. | # This is a comment |
Example: Basic YAML Structure
image: alpine:latest
before_script:
- echo "Running before script"
script:
- echo "Running main script"
after_script:
- echo "Running after script"
3. Defining Pipeline Stages
| Stage | Description | Usage |
|---|---|---|
| build | Compiles source code into binaries or packages | Used for compiling and packaging applications |
| test | Runs unit, integration, and functional tests | Ensures code quality and functionality before deployment |
| deploy | Deploys artifacts to production or staging environments | Automates deployment processes to target systems |
| cleanup | Performs post-deployment tasks like cleanup or notifications | Handles final steps after deployment completion |
Example: Defining Stages in .gitlab-ci.yml
stages:
- build
- test
- deploy
build_job:
stage: build
script:
- echo "Building the application..."
test_job:
stage: test
script:
- echo "Running tests..."
deploy_job:
stage: deploy
script:
- echo "Deploying to production..."
4. Setting Default Configuration
Example: Default configuration with .gitlab-ci.yml
image: node:18
services:
- postgres:13
variables:
POSTGRES_DB: test_db
POSTGRES_USER: test_user
POSTGRES_PASSWORD: test_password
before_script:
- npm install
- npm run build
test:
script:
- npm test
artifacts:
reports:
junit: junit.xml
deploy:
script:
- echo "Deploying..."
only:
- main
| Property | Description | Default Value |
|---|---|---|
| image | Container image to use for the job | ruby:latest |
| services | List of services to use for the job | None |
| variables | Environment variables to set for all jobs | None |
| before_script | Script to run before each job's script | None |
| after_script | Script to run after each job's script | None |
Note: The
image and services properties are inherited by all jobs in the pipeline if not overridden.Warning: The
before_script and after_script are executed in the context of each job, not once per pipeline.5. Setting Global Variables
| Variable | Value | Description |
|---|---|---|
| CI_PROJECT_NAME | my-project |
Name of the project |
| CI_COMMIT_REF_NAME | main |
Branch or tag name |
| CI_REGISTRY_USER | gitlab-ci-token |
Registry user for Docker image push |
Example: Using Global Variables in a Job
job_name:
script:
- echo "Project: $CI_PROJECT_NAME"
- echo "Branch: $CI_COMMIT_REF_NAME"
Note: Global variables are automatically available in all jobs and can be overridden by local job or stage variables.
6. Configuring Workflow Rules
| Rule | Description | Example |
|---|---|---|
| only | Defines when a job runs based on the branch or tag name | only: ['main', 'develop'] |
| except | Defines when a job does NOT run based on the branch or tag name | except: ['feature/*'] |
| changes | Triggers job only if files matching a pattern have changed | changes: ['src/**/*'] |
| rules | Advanced conditional logic for job execution | rules: [{if: '$CI_PIPELINE_SOURCE == "merge_request"', when: "never"}] |
Example: Using rules for conditional execution
deploy:
stage: deploy
rules:
- if: '$CI_COMMIT_BRANCH == "main"'
when: on_success
- if: '$CI_PIPELINE_SOURCE == "merge_request"'
when: never
- when: manual
Note: Rules are evaluated in order, and the first matching rule is applied.
7. Using YAML Anchors and Aliases (&, *)
| Feature | Description | Usage |
|---|---|---|
| YAML Anchors | Define a value once and reuse it elsewhere using & |
|
| YAML Aliases | Reference previously defined anchors using * |
|
Note: Anchors and aliases are supported in GitLab CI YAML files, but they must be used carefully to avoid complex merge conflicts or unclear configuration structure.
8. Using YAML Merge Keys (<<: *)
Note: YAML merge keys are a feature of the YAML 1.1 specification and are supported in GitLab CI/CD configuration files.
| Feature | Description | Usage |
|---|---|---|
| <<: * | Merge keys allow reusing and merging parts of YAML configuration. | Used to include predefined configuration blocks in a pipeline. |
Example: Reusing Configuration with Merge Keys
variables:
<<: *default_variables
stages:
- build
- test
- deploy
build_job:
<<: *default_job
stage: build
script:
- echo "Building..."
test_job:
<<: *default_job
stage: test
script:
- echo "Testing..."
deploy_job:
<<: *default_job
stage: deploy
script:
- echo "Deploying..."
Example: Defining Merge Key Templates
default_variables: &default_variables
NODE_VERSION: "18"
NPM_REGISTRY: "https://registry.npmjs.org"
default_job: &default_job
image: node:${NODE_VERSION}
before_script:
- npm config set registry ${NPM_REGISTRY}
- npm ci
9. Validating Pipeline Syntax
Example: Basic .gitlab-ci.yml syntax validation
image: alpine:latest
services:
- postgres:13
variables:
POSTGRES_DB: test_db
POSTGRES_USER: test_user
POSTGRES_PASSWORD: test_password
before_script:
- apk add --no-cache git
test:
script:
- echo "Running tests"
- git status
| Validation Method | Description | Command | Notes |
|---|---|---|---|
| gitlab-ci-lint | Official linter for GitLab CI configuration | gitlab-ci-lint |
Available as a CLI tool or via GitLab UI |
| .gitlab-ci.yml | File to validate in project root | gitlab-ci-lint .gitlab-ci.yml |
Checks syntax and basic structure |
| GitLab UI | Validate via GitLab web interface | Go to Project → Settings → CI/CD → Validate | Real-time validation with error messages |
Note: GitLab CI uses YAML syntax, so ensure all indentation is consistent and no tabs are used.
Warning: Invalid syntax will cause pipeline jobs to fail with "Could not parse" errors.
10. Using Include for External Configuration
The include keyword in GitLab CI/CD allows you to reference external configuration files or templates, promoting reusability and modularity in your pipeline definitions.
| Property | Description | Values |
|---|---|---|
| include | Specifies the external configuration to be included in the pipeline. | Can be a local file path, a remote URL, or a template from GitLab's built-in templates. |
Example: Including a Remote Template
include:
- remote: "https://gitlab.example.com/group/template/-/raw/main/ci-template.yml"
Note: When using
include, the included configuration is merged with the main pipeline configuration. Variables and jobs defined in the included file will be available in the context of the main pipeline.
Warning: Be cautious when including remote configurations, as they can introduce security risks if not from trusted sources.