Sign in
← CI/CD: hands-on
12 min · easy · Lesson 3 of 10

Stages: work order and stopping on failure

We split the pipeline into build and test, see how stages run in order, and why a failed build cancels everything after it.

We split the pipeline into build and test, see how stages run in order, and why a failed build cancels everything after it.

Why split into stages

One job is enough right up until there's more than one job to do. Build, check, deploy: these steps need to run in a specific order, and deploying only makes sense for something that passed the check.

Stages set the order. A stage is a named step of the pipeline that holds one or more jobs. The list of stages is declared once at the top of the file, and each job says which stage it belongs to.

stages:
  - build
  - test

build-site:
  stage: build
  script:
    - echo "Building the site"
    - test -f index.html

check-title:
  stage: test
  script:
    - grep "<title>" index.html

Push this to your project in place of the old config. The pipeline page will show two columns instead of one, one column per stage.

How it runs

Stages run strictly in sequence: until all of build finishes, not a single job from test starts.

Inside one stage it's the opposite: jobs run in parallel if runners are free. Two tests in the test stage will run at the same time, and won't double the total time.

A pipeline with two stages takes longer than one job with the same commands. Each job waits for its own runner and gets its own container with a fresh clone of the repo; the container is never reused. So splitting work into a dozen tiny jobs for the sake of it isn't worth it: each one adds startup time.

A failure stops the pipeline

Check this key property of stages by hand. Break a command in build:

build-site:
  stage: build
  script:
    - echo "Building"
    - test -f nonexistent.html

Result on the pipeline page:

build-site   failed
check-title  skipped

skipped, not failed. The test stage never even started: GitLab didn't bother spending a runner on checking something that didn't build.

Inside a stage, a neighbor's failure doesn't stop anything. If test has two jobs and one fails, the other still finishes. Only the next stage stops.

Hence the rule for ordering stages: the cheaper and faster a check is, the earlier it should sit. A linter that fails in five seconds saves ten minutes of integration tests.

Stage names mean nothing

build, test and deploy are just strings. GitLab doesn't know that build means building, and doesn't check what you actually do there. Only the order in the stages list matters.

If you don't declare stages at all, GitLab uses its own list: .pre, build, test, deploy, .post. The built-in .pre and .post always come first and last, no matter what you write. A job with no stage specified falls into test, which is why the pipeline from the previous lesson worked without the word stages.

Try the config without breaking main

You don't have to run experiments on the main branch. A pipeline runs on any branch:

git checkout -b pipeline-test
git push -u origin pipeline-test

The pipeline list will show the branch name next to the commit. Done experimenting? Merge into main or delete the branch.

Common mistakes

What to remember

stages at the top of the file sets the order, stage: on a job says where it sits.

Stages run in sequence, jobs inside a stage run in parallel.

A failed stage cancels every stage after it: their jobs get status skipped.

Put cheap checks before expensive ones, so the pipeline fails faster and burns fewer minutes.

Next, we'll pass built files from one stage to another.

What you'll need for the tasks

The tasks are done locally, without gitlab.com. The lab environment creates a git repo work/, and the training runner run-pipeline.sh executes the last commit: stages in order, each job in a clean alpine:3.20.3 container. At the end it prints a summary per job: passed, failed or skipped. Unlike GitLab, it runs jobs in one stage one after another, not in parallel. That doesn't affect the result.

Done reading?

Mark the lesson as read to move your track progress forward.

Go through it with an AI agent

The agent explains anything unclear in plain words, gives you 2 labs for this lesson and drills you on interview questions. $49 one-time, lifetime access.

Get access for $49

Tell the agent: use MCP izi, give me lesson cicd-practice-03-stages