GitLab CI/CD: Architecting, Deploying, and Optimizing Pipelines

Architecture Core Concepts

Using stage vs stages Keyword

Introduction

In GitLab CI/CD, the stages keyword defines the sequence in which jobs execute. Without an explicit order, all jobs run in parallel—leading to situations where tests or deployments start before your build finishes and ultimately fail. By declaring an ordered list of stages and assigning each job to one, you ensure a reliable, sequential pipeline: build → test → deploy.

All GitLab CI/CD YAML syntax is covered in the official GitLab docs.


Defining Stages in Your .gitlab-ci.yml

1. Basic stages Syntax

stages:
  - build
  - test
  - deploy

Each item under stages represents a phase of your pipeline. Jobs in the same stage run in parallel, while stages themselves execute one after another.

2. Assigning Jobs to Stages

stages:
  - build
  - test
  - deploy

compile_code:
  stage: build
  script:
    - echo "Compiling code..."

run_tests:
  stage: test
  script:
    - echo "Running tests..."

deploy_app:
  stage: deploy
  script:
    - echo "Deploying application..."

Here, compile_code runs first. If it succeeds, run_tests starts. Finally, deploy_app executes only after tests pass.


Example: Full Pipeline Configuration

Below is a complete pipeline that installs a gem, generates ASCII art in a file, then tests and deploys based on that file.

workflow:
  name: Generate ASCII Artwork

stages:
  - build
  - test
  - deploy

build_job:
  stage: build
  before_script:
    - gem install cowsay
    - sleep 30s
  script:
    - >
      cowsay -f dragon "Run for cover,
      I am a DRAGON....RAWR" >> dragon.txt

test_job:
  stage: test
  script:
    - sleep 10s
    - grep -i "dragon" dragon.txt

deploy_job:
  stage: deploy
  script:
    - echo "Deploying..."
StageDescription
buildInstalls dependencies and generates dragon.txt
testExecutes a search for “dragon” in the generated file
deployDeploys the application after successful tests
  • workflow.name: Gives your pipeline a friendly title.
  • build_job: Installs cowsay, waits 30s, and writes ASCII art to dragon.txt.
  • test_job: Waits 10s then searches for “dragon” inside dragon.txt.
  • deploy_job: Runs only if the test stage succeeds.

Note

Jobs must be assigned to one of the listed stages. Assigning a job to an undefined stage will trigger a pipeline editor warning.


Exploring Pipeline Visualization

Once committed, GitLab runs the pipeline in three sequential stages. Use the Visualize tab in the pipeline editor to confirm the flow before pushing changes.

The image shows a GitLab pipeline interface with three stages: build, test, and deploy. The test stage has failed due to a script failure.


Analyzing Job Output

Build Job Logs

$ gem install cowsay
Successfully installed cowsay-3.1.0
1 gem installed
$ sleep 30s
$ cowsay -f dragon "Run for cover, I am a DRAGON....RAWR" >> dragon.txt

Test Job Failure

$ sleep 10s
grep: dragon.txt: No such file or directory
ERROR: Job failed: exit code 1

Warning

Because each job runs in its own runner environment, artifacts created in build aren’t available in test by default. You must configure artifacts to pass files between stages.


Passing Data with Artifacts

To preserve files like dragon.txt across stages, add an artifacts section to your build job:

build_job:
  stage: build
  script:
    - cowsay -f dragon "..." >> dragon.txt
  artifacts:
    paths:
      - dragon.txt
    expire_in: 1 hour

This makes the file available to all downstream jobs in the same pipeline.


Monitoring Compute Minutes

GitLab’s UI shows Pipeline Duration and Minutes Used—critical metrics if you’re on a usage-limited plan. Check these under Pipeline Details for better cost management.


Watch Video

Watch video content

Previous
Pipeline with Multiple Dependent Jobs