GitLab CI/CD & Where AI Fits
Before you can automate a pipeline with an LLM, you need the pipeline. This chapter is the foundation of the track: how GitLab CI/CD actually works — .gitlab-ci.yml, stages, jobs, runners, merge-request pipelines — and the three distinct places an AI model plugs in. Everything after this builds on these pieces.
Learning objectives
- Explain the GitLab CI/CD model: pipelines, stages, jobs, and runners.
- Read and write a basic
.gitlab-ci.yml. - Understand merge-request pipelines — where AI review and automation hook in.
- Name the three places an LLM fits into a pipeline, with either Claude or OpenAI.
1 · The GitLab CI/CD model essential
Strip away the jargon and CI/CD is one idea: every time you push code, a machine runs a checklist for you. Does it build? Do the tests pass? Is it safe to merge? GitLab CI/CD automates that checklist so a human doesn't run it by hand (and doesn't forget). The whole system is driven by a single file in your repo root — .gitlab-ci.yml — which GitLab reads on every push to decide what to run.
Four nouns carry the whole model. A pipeline is one full run of your checklist, triggered by a push or a merge request. It's divided into stages that run in order (typically build → test → deploy). Each stage holds one or more jobs — the actual commands — and jobs in the same stage run in parallel, while stages run sequentially. Jobs execute on a runner: a machine (GitLab-hosted or your own) that checks out your code and runs the job's script in a container. That's the entire mental model; everything else is detail on top of it.
The common mistake coming in is imagining CI as "a script that runs somewhere." It's more structured than that: the stage/job split is what gives you parallelism and ordering, and the runner-in-a-container model is why a job starts from a clean checkout every time (no leftover state from the last run). Hold the pipeline → stages → jobs → runner picture and GitLab CI stops being a wall of YAML.
- The three big boxes are stages — they run strictly left to right: build, then test, then deploy.
- The small green boxes inside are jobs; those in the same stage run in parallel (unit + lint together).
- The amber box is the point of this whole track: an AI review job is just another job in the test stage — nothing special structurally.
- Everything runs on a runner — a fresh container that checks out your code per job.
In short: stages order the work, jobs parallelize it, runners execute it — and an LLM call is just a job's script.
2 · Reading a .gitlab-ci.yml essential
The config is YAML. Each top-level key (that isn't a reserved word) is a job; stages declares the order; each job names its stage and a script of shell commands. Here's a minimal, complete pipeline.
.gitlab-ci.ymlstages:
- build
- test
build-app:
stage: build
script:
- echo "Compiling..."
- make build
run-tests:
stage: test
script:
- pip install -r requirements.txt
- pytest -q
stages:lists the order —buildruns fully beforeteststarts.build-appandrun-testsare jobs (the top-level names); each declares whichstageit belongs to.- Each job's
scriptis just shell commands run on a fresh runner — sopytestruns against a clean checkout of your code.
Try this: add a third stage deploy with a job that only runs on the default branch (you'll add the rules: for that in gl3) — the skeleton is always stages + jobs + scripts.
script is ordinary shell on a container. That's the key that unlocks this whole track: if you can call an LLM from a Python script on your laptop, you can call it from a CI job — same code, now triggered by a push instead of by you.3 · Merge-request pipelines intermediate
The merge request is where AI automation earns its keep, so it's worth understanding precisely. A merge request (MR) is GitLab's proposal to merge one branch into another — the equivalent of a GitHub pull request. GitLab can run a special merge-request pipeline that fires when an MR is opened or updated, and crucially these pipelines have access to the diff — exactly what changed — plus the MR's metadata (title, description, author).
That diff is the raw material for AI review (gl2): a job can grab the changes, hand them to a model, and post the model's feedback back onto the MR as a comment. You scope a job to MR pipelines with the rules: keyword and the predefined $CI_PIPELINE_SOURCE variable, so the AI review runs only on merge requests, not on every push.
.gitlab-ci.ymlai-review:
stage: test
rules:
- if: '$CI_PIPELINE_SOURCE == "merge_request_event"' # MRs only
script:
- git fetch origin $CI_MERGE_REQUEST_TARGET_BRANCH_NAME
- git diff origin/$CI_MERGE_REQUEST_TARGET_BRANCH_NAME > changes.diff
- python review.py changes.diff # calls the model — gl2
rules:with$CI_PIPELINE_SOURCE == "merge_request_event"makes this job run only in MR pipelines — not on branch pushes.- The script captures the diff against the target branch into
changes.diffusing GitLab's predefined MR variables. python review.py changes.diffis where the LLM comes in — that script (built in gl2) sends the diff to Claude or OpenAI and posts the review back.
Try this: GitLab exposes many predefined variables ($CI_MERGE_REQUEST_IID, $CI_PROJECT_ID, $CI_COMMIT_SHA). They're how a job knows which MR it's reviewing — you'll use them to post comments back in gl2.
4 · The three places AI fits advanced
Across this whole track, an LLM plugs into GitLab in exactly three ways — worth naming now so the later chapters slot into place. (1) Review: a job reads the MR diff and posts feedback (gl2). (2) Generation / action: a job calls a model to produce something — a changelog, release notes, a test, a summary — and commits it or attaches it (gl3). (3) Routing: when you use more than one model, a job decides which model handles a given task, with fallback if one fails (gl4). All three are "a job whose script calls an LLM API" — the structure you already know.
And a fourth option that isn't your code at all: GitLab Duo, GitLab's built-in AI features (code suggestions, chat, MR summaries) that run as a managed product rather than jobs you write. The track's framing (expanded in gl3): reach for Duo when its built-in features fit, and write your own API-calling jobs when you need control, a specific model, or logic Duo doesn't offer.
5 · Tech-lead — CI as the enforcement point tech-lead
The reason to put AI in the pipeline rather than in each developer's editor is consistency: a CI job runs the same way for everyone, every time, and can be made a required check before merge. That makes the pipeline the natural enforcement point for AI-assisted quality — an AI review that every MR gets, a generated changelog that's never forgotten, a security scan that can't be skipped. The lead-level principle: editor AI assists the individual; pipeline AI enforces the standard. This track builds the pipeline kind.
🪜 Practice ladder beginner → industry
- Beginner: write a two-stage
.gitlab-ci.yml(build, test) with one job each. - Easy: add a job scoped to MRs only with
rules: $CI_PIPELINE_SOURCE. - Core: capture the MR diff to a file in a job script.
- Stretch: list which predefined CI variables you'd need to post a comment back to an MR.
- Hard: sketch the three AI insertion points for a repo you know (review / generate / route).
- Industry: decide which AI checks should be required before merge vs advisory, and why.
✓ Checkpoint — you can move on when you can…
- Explain pipelines, stages, jobs, and runners.
- Read and write a basic
.gitlab-ci.yml. - Scope a job to merge-request pipelines and grab the diff.
- Name the three places an LLM fits into a pipeline.
Knowledge check check yourself
In GitLab CI, what's the relationship between pipelines, stages, jobs, and runners?
Show answer
.gitlab-ci.yml.How do you make a job run only on merge requests, and why does that matter for AI review?
Show answer
rules: with if: '$CI_PIPELINE_SOURCE == "merge_request_event"' so the job runs only in merge-request pipelines, not on every branch push. It matters because MR pipelines have access to the diff and MR metadata — exactly what an AI review job needs to read the changes and post feedback back onto the specific merge request.