Sign in
← CI/CD: patterns
12 min · medium · Lesson 1 of 5

The ideal pipeline: stages and principles

What a well-built CI/CD pipeline looks like: stage order, fail-fast, fast feedback, and where deploy starts.

Why the order of stages matters

You can slap a pipeline together any old way and it will work. But a bad order of stages costs time and money: heavy tests run before the linter has caught a typo, the image gets built before the unit tests have had a chance to fail. A good pipeline is set up so cheap checks catch the problem before the expensive ones do.

The order of stages usually looks like this:

lint → build → test → package → deploy

Each next stage costs more than the one before it, so it pays to break earlier.

Concepts

Stages in order

Cheap goes first. The linter catches a typo in two seconds, so you don't have to wait for five-minute tests to find out about it.

Where to put security checks

People often draw "scan" as a single stage somewhere in the middle or at the end. That's a mistake: the word scan hides several different checks, and they need different moments in the pipeline.

Dependency scanning and secret detection work on the source. They need neither a built binary nor an image, so their place is next to the linter, before the build. If a private key slipped into a commit, you need to find out in twenty seconds, not after five minutes of tests. Same with a dependency that has a critical CVE: there's no point building an image on top of it.

Image scanning checks what isn't in the source: the base layer, system packages, user configuration. Until the image exists there's nothing to scan, so the check runs after the image is built and before the push to the registry. Otherwise a vulnerable image already sits in the registry, and someone has time to roll it out.

GitLab's built-in Container Scanning pulls the image from the registry (the CS_IMAGE variable). With it, the image is first pushed under a temporary tag, like the commit SHA, and the release tag is set only after a clean scan. The point is the same: only a checked image makes it to the rollout.

Put together, the order looks like this:

lint + scan:deps + scan:secrets   ← on the source, before the build
        ↓
build → test
        ↓
package: build the image → scan:image → push
        ↓
deploy

Fail-fast

Fail-fast means stopping at the very first error instead of running the pipeline to the end. If build fails, there's no point running tests: there's nothing to test. GitLab CI works this way by default: if a job fails, the pipeline is marked failed, and jobs in the stages after it don't start.

Inside a single stage it's the opposite. Jobs in the same stage run in parallel, and a failed job doesn't stop its neighbors: they run to completion. That's useful. A linter, a type check and a dependency audit in the same stage show you every failure at once, instead of fixing them one per run.

Hence the practical rule: put checks that don't depend on each other in one stage, and put whatever makes going further pointless without it in an earlier stage.

Fast feedback

The main value of CI is how fast a developer learns about a problem. A 40-minute pipeline that reports a typo right at the end is almost useless: the context is already gone. That's why pipeline time gets watched and cut down.

What speeds it up:

Rule of thumb: the main push pipeline should fit into a few minutes. Anything longer gets moved into separate schedules.

Where the deploy boundary is

lint → build → test → package usually runs automatically on every push. deploy is kept separate, though. You roll out to prod either by tag, or by manual confirmation (a job with when: manual), or automatically but only from a protected branch. The next lesson, on rollout strategies, covers this boundary.

Common mistakes

What you'll need for the tasks

What to remember

Cheap checks come first: the linter before the build, the build before the tests, the tests before packaging. That way the problem gets caught earlier and cheaper.

Fail-fast stops the pipeline at the first failed stage. Inside a stage, checks run in parallel and show every failure at once.

Security checks get spread across the pipeline. Dependencies and secrets are scanned on the source before the build, the image after the image is built and before the push to the registry.

The next lesson covers rollout strategies: blue-green, canary and rolling.

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-advanced-01-ideal-pipeline