Sign in
← CI/CD
11 min · easy · Lesson 2 of 7

Continuous Integration

What runs on every push, fail fast, a green main, and why you need to merge often.

What runs on every push, why a pipeline should fail early, why you keep main green, and why you merge changes often.

The idea of CI in one sentence

Every developer merges their changes into a shared branch often and in small batches, and automation checks that nothing broke on every change.

"Continuous" here is about frequency: not once a week in one big chunk, but many times a day in small ones. Martin Fowler's article on CI names the lower bound: merge your changes into the shared branch at least once a day. The smaller the batch, the easier it is to find what broke the build.

What CI usually runs

A typical CI run on every push to a merge request:

checkout the code
  -> install dependencies
  -> linter / formatter   (style, obvious mistakes)
  -> build / compile      (does it even build?)
  -> unit tests           (is the logic broken?)
  -> other checks         (types, security scan, bundle size)

Each step (GitLab calls it a job) is a command or a script. The CI system looks at its exit code: 0 means success, anything else means failure. If a job fails, the later stages usually don't run, the pipeline turns red, and the merge request can't be merged. This is the automated quality gate at the door.

A simple consequence follows. A script that swallows an error and returns 0 looks green to CI, even if everything inside broke. A check is only as good as how honestly it reports failure.

Fail fast

A good pipeline fails as early and as cheaply as possible. Fast checks go first: a linter finishes in seconds. Expensive ones go later: integration tests take minutes. There's no point running 10-minute tests if the code doesn't even compile.

The goal is for the developer to learn about the breakage within minutes after the push, while the context is still fresh, not a day later in code review.

Green main as a rule

The main branch (main/master) must always be in a working state that passes its tests. A release can be built from it at any moment.

So:

This is the same branch protection from the lesson on branches in the Git track. CI is its mandatory half: the rule "main is always green" holds only because the checks are automatic and can't be bypassed.

In GitLab these are two settings. Branch protection sets who can push and merge into main; the default branch in a new project is already protected. Blocking merges on a red pipeline is a separate setting: Settings → Merge requests → Merge checks, the "Pipelines must succeed" checkbox. In GitHub the same thing is done by the branch protection rule "Require status checks to pass before merging".

Why merging often is safer

Counterintuitive: the more often you merge, the lower the risk. A big branch that lives for two weeks drifts further and further from main. At merge time you get a pile of conflicts and surprises. This is called merge hell.

The approach where everyone stays close to main and merges in small pieces is called trunk-based development. Small MRs are easier to review, pass CI faster, and conflict less often.

What the code needs for CI to work

CI isn't magic. It only runs what you wrote. For that to mean anything:

That last point is worth unpacking. A flaky test passes and fails on the same code from run to run. The cause is almost always that the result depends on something other than the code: the current time, random data, the network, test run order, or an element order the language doesn't promise. The team quickly gets used to hitting "rerun", starts ignoring a red CI, and it becomes useless.

A flaky test isn't fixed by rerunning it or disabling it. You need to find what the result depends on and remove that dependency from the code or the test.

Common mistakes

What to remember

CI: merge often and in small batches, and automatically check every change.

A typical run: dependencies → linter → build → tests. If it fails, the MR doesn't merge. CI learns about failure from a nonzero exit code.

Fail fast: cheap checks before expensive ones, so breakage surfaces within minutes.

main always green: push only through an MR, can't merge while CI is red.

Frequent small merges (trunk-based) are safer than rare big ones: no merge hell.

What you'll need for the tasks

The next lesson covers the second letter: how Continuous Delivery differs from Continuous Deployment.

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 3 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-basics-02-continuous-integration