Most pipeline advice starts in the middle — here is a clever job snippet — and never explains what holds the cleverness up. The order below starts at the foundations and ends with evidence. It follows the sequence The Ops Atlas recommends in its GitLabOps playbooks, condensed for a team putting its first serious pipeline onto GitLab. Follow the steps in order; several later steps depend on earlier ones being true.
What You Need Before Starting
Four things, none exotic:
- a repository whose build can actually run;
- administrator access to the project, not just developer access;
- at least one machine that can be registered as a runner;
- an afternoon with no deployment scheduled, so mistakes stay cheap.
If the build cannot be triggered by hand from a workstation, fix that first — pipelines amplify whatever they are given, including brokenness.
The GitLabOps Steps, in the Order That Works
Step 1: Inventory what already runs
List every pipeline that exists today, every registered runner, and every credential stored in CI variables. The Atlas’s adoption arc begins here for a reason: you cannot govern what nobody has written down, and the inventory almost always turns up one forgotten job that runs nightly for reasons lost to staff turnover. Date-stamp the list while you make it; a quarter from now it becomes the before picture for every improvement claim you want to make.
Step 2: Write the smallest honest skeleton
Replace any inherited mega-file with a minimal pipeline: one build job, one test job, nothing speculative. Add workflow rules that decide when pipelines exist at all, so a branch does not produce two identical runs — once for the branch and once for its merge request. Duplicate pipelines are the most common configuration-loop failure, and rules are the fix. While you are in the file, pull repeated blocks into shared components where the platform supports them; a skeleton that references maintained pieces stays maintainable long after a copy-pasted one has forked into five dialects.
Step 3: Draw the graph on purpose
Declare dependencies between jobs so the graph is explicit, and turn on cancellation for superseded runs so that five rapid pushes do not leave five racing pipelines behind. Evidence from the field is blunt about this: teams that skip the explicit graph pay for it in every later debugging session.
Step 4: Register and tag the runners
Give each runner a truthful tag describing what it offers, then make jobs state what they require. Mismatched tags are why work parks itself in pending; the match is by declaration, not luck. Choose the executor deliberately — containers for isolation, disposable virtual machines where code from outside the team will run. If any project accepts contributions from strangers, register a separate, protected runner for the sensitive repositories rather than letting one pool serve everyone; trust segmentation is a property you decide at registration time, not afterward.
Step 5: Pin versions
Reference pipeline components and container images at fixed versions rather than latest. A pinned pipeline reproduces; a floating one surprises. This is a ten-minute step that prevents a category of “nothing changed” incidents. Record the pins in your runbook too, so the next upgrade is a decision rather than an accident.
Step 6: Gate production
Mark the production environment protected so only chosen branches and chosen people can deploy to it, and add a resource group so two competing deployments queue instead of interleaving. If releases push a container image, lock the production tag so maintainers alone can move it. Add the setting that keeps an outdated deployment job from executing once a newer one has started — without it, a slow pipeline can happily overwrite the work of a faster successor.
Step 7: Shorten the secrets
Find the oldest credential in the variables list and plan its retirement. Where the cloud provider supports it, issue an OIDC identity token per job instead of storing a long-lived key, and set the job-token allowlist so only intended projects may authenticate. Identity that expires cannot leak last year’s access. Expect this step to take longer than the others; it touches other teams’ systems, and the allowlist conversation is political as often as technical.
Proving the GitLabOps Setup Works
Analytical work demands a baseline, so record two figures the week you finish: the 95th percentile of merge request feedback and the 95th percentile of job queue time. Targets worth adopting are fifteen minutes and two minutes respectively. Note also what the platform’s duration figure ignores — queue time — so nobody celebrates a fast pipeline that sits in a slow queue. A third figure belongs on the same sheet: the proportion of pipelines finishing green. Read all three against their thresholds monthly; the trend is the finding, not any single reading.
Where Teams Stumble After Step Seven
Two habit relapses account for most regressions. The first is convenience creep: an emergency pushes someone to deploy from an unprotected branch, the guardrail gets bypassed once, and the bypass becomes folklore. The second is blanket retries added to silence a flaky suite, which trades honesty for green ticks. Both are worth naming in a retrospective early. Our piece on adoption mistakes companies should avoid collects more of these patterns, and the security-minded reader should pair this walkthrough with our guide to pipeline security and early safety checks. For the deeper material this summary draws on — fleet design, signing, upgrade stops — the Atlas maintains a full GitLabOps playbook library. One last habit seals the work: whenever an incident does slip through, trace it back to its loop, then ask which of the seven steps would have caught it. Work the sequence once, honestly, and the second pipeline will take an afternoon instead of a quarter.
