Command Palette

Search for a command to run...

Hectal
PHASE 4Intermediate ~13 min· topic 1 of 4

Topic 4.1

.gitlab-ci.yml: Stages and Jobs

In one line

GitLab CI/CD is configured through exactly one file, .gitlab-ci.yml, at the repository root — stages define order, jobs define the actual work, and jobs in the same stage run in parallel by default, same as everywhere else.

0/4 · 0%

Key ideas

  1. 01

    .gitlab-ci.yml, committed at the repository ROOT, is GitLab's single, complete pipeline definition — genuinely simpler in structure than GitHub Actions' potentially-many-workflow-files-per-repository model, with everything for a project's CI/CD living in exactly one file (Phase 4.4 covers splitting large configs across multiple files via include:, once one file genuinely becomes too large).

  2. 02

    A top-level stages: list defines the ORDER stages run in (stages: [build, test, deploy]) — this is purely a declaration of sequence; the actual WORK happens in individually-defined JOBS, each explicitly assigned to one of these stages via its own stage: key.

  3. 03

    A JOB is defined simply by giving it a name at the top level of the YAML, with a script: key listing the actual shell commands to run — test-job: { stage: test, script: ["mvn test"] } is a genuinely complete, valid job definition; there's no separate nested 'steps' concept the way GitHub Actions and Jenkins both have — a job's script list IS its steps.

  4. 04

    Every job assigned to the SAME stage runs in PARALLEL by default — directly the same behavior Phase 0.2 established as the universal default, and jobs in a LATER stage automatically wait for every job in the stage(s) before it to complete successfully first, before that later stage begins at all.

  5. 05

    artifacts: lets one job's output (a compiled JAR, test reports) be passed forward to LATER stages' jobs — directly the same concept Phase 0.2 introduced generally, GitLab's own specific keyword for declaring exactly what a job produces that should persist beyond that one job's own fresh workspace.

  6. 06

    GitLab's own web UI visualizes the entire pipeline as a genuinely clear PIPELINE GRAPH — stages as columns, jobs as nodes within them, with lines showing dependencies — arguably the clearest visual representation of Phase 0.2's stage/job model of any of the three platforms this course covers.

Code & diagrams

.gitlab-ci.ymlmarkdown

A genuinely complete pipeline — three stages, with artifacts passed from build to test.

stages:
  - build
  - test
  - deploy

build-job:
  stage: build
  image: eclipse-temurin:21-jdk
  script:
    - mvn clean package
  artifacts:
    paths:
      - target/*.jar

unit-tests:
  stage: test
  image: eclipse-temurin:21-jdk
  script:
    - mvn test

lint:
  stage: test          # runs in PARALLEL with unit-tests — same stage
  image: eclipse-temurin:21-jdk
  script:
    - mvn checkstyle:check

deploy-staging:
  stage: deploy
  script:
    - echo "Deploying $(ls target/*.jar) to staging"
  # this job automatically waits for BOTH test-stage jobs to succeed first

Explain it without notes

01

Why do unit-tests and lint (both in this example's test stage) run in parallel, while deploy-staging waits for both to finish?

02

What's the practical purpose of the artifacts key on build-job in this example?

Practice

01

Write a .gitlab-ci.yml with at least three stages and confirm, either on a real GitLab project or by reasoning through the YAML, which jobs would run in parallel and which would wait for others.

02

If you have access to a real GitLab project, push a .gitlab-ci.yml and view the resulting Pipeline graph in GitLab's UI, matching what you see against your own YAML's stages and jobs.

Trade-offs

  • ↔

    GitLab's single-file, script-list job model is genuinely simpler to read for a small-to-medium pipeline than GitHub Actions' or Jenkins' equivalents — but as a pipeline grows to have genuinely many jobs and stages, one large file can become unwieldy, which is exactly the problem Phase 4.4's include: mechanism (splitting configuration across multiple files) exists to solve, mirroring GitHub Actions' own reusable-workflow motivation from Phase 2.3.

Done when you can

  • I can write a .gitlab-ci.yml with multiple stages and jobs correctly assigned to each.

  • I understand jobs in the same stage run in parallel, while later stages wait for earlier ones.

  • I can use artifacts to pass a job's output forward to a later stage.