Most engineering organisations assemble their delivery toolchain from separate products: one for source control, another for pipelines, others for issues, artefacts, security scanning and deployment. Each is good at its job, and the seams between them are where the friction lives — six integrations to maintain, six access models, and no single place where a change can be traced from an idea to a running deployment.
GitLab's proposition is that one integrated platform covering the whole path is worth more than the best individual tool at each stage. This guide explains how it actually works — pipelines, environments, security scanning, review apps — what the integration genuinely buys, and where the trade-offs are real.
What you will learn
- What "one platform" means concretely, and what it replaces
- How pipelines are structured, and the features that matter at scale
- Environments, review apps and deployment strategies
- The security scanning suite and how to make it useful rather than noisy
- Runners, caching and the practical work of making pipelines fast
- Where the integrated approach costs you, and how to decide
- What the platform covers
- The value of integration
- Pipelines: the mental model
- Structuring a pipeline
- Reuse across projects
- Runners and executors
- Making pipelines fast
- Environments and deployments
- Review apps
- Security scanning
- The registries
- Merge requests and code review
- Permissions and compliance
- Self-managed or software as a service
- Where the integrated approach costs you
- Twelve mistakes
- A worked example: one service, one pipeline
- Frequently asked questions
1. What the platform covers
| Stage | Capability | Commonly replaces |
|---|---|---|
| Plan | Issues, boards, milestones, epics | A separate tracker |
| Create | Git hosting, merge requests, review | A separate hosting service |
| Verify | Pipelines, test reports, coverage | A separate CI server |
| Package | Container, package and artefact registries | A separate registry |
| Secure | Static, dependency, container, secret and dynamic scanning | Several separate scanners |
| Release | Environments, deployments, feature flags | A separate deployment tool |
| Govern | Approval rules, audit events, compliance frameworks | Manual evidence gathering |
Not every capability is best in class, and that is the honest framing. The question is not whether each individual feature beats the specialised alternative — several do not — but whether the removal of six integrations and the presence of a single traceable thread is worth more than the difference.
2. The value of integration
Four concrete benefits, distinct from marketing claims about "one platform".
Traceability without integration work. An issue links to the merge request that resolves it, which links to the pipeline that verified it, which links to the deployment that shipped it. Reconstructing that chain across separate tools requires integrations that break; here it is intrinsic.
One permission model. Access is granted once at the group or project level and applies to code, pipelines, registries and deployments. Multi-tool estates routinely drift into inconsistent access, and the drift is usually discovered during an audit.
Security findings where the change is. Scan results appear in the merge request, comparing against the target branch so only newly introduced issues are highlighted. That single behaviour — gating on new findings rather than on the historical backlog — is the difference between security scanning that gets used and security scanning that gets disabled.
Compliance evidence as a by-product. Who approved what, which pipeline ran, what was deployed and when, all recorded automatically. In regulated environments this is frequently easier to defend than manually assembled evidence, because it is generated rather than compiled.
3. Pipelines: the mental model
A pipeline is defined by a file in the repository, which means it is versioned, reviewed and branch-specific like any other code. That property matters more than any individual feature: a pipeline change goes through review, and a branch can test a pipeline change safely.
The structural concepts are few:
Stages run in sequence. Jobs within a stage run in parallel. A stage begins only when the previous one has completed successfully — unless a job is explicitly allowed to fail or configured to run regardless.
Jobs are the unit of work: a container image, a script, and rules determining whether the job runs at all. Each starts from a clean environment, which is what makes pipelines reproducible and also what makes caching necessary.
Artefacts pass files between jobs and expire on a schedule. Caches speed up repeated work such as dependency installation and are explicitly not guaranteed to exist — a pipeline that fails without a cache is misconfigured.
Rules decide whether a job runs, based on branch, changed files, variables or pipeline source. Getting rules right is most of the skill in pipeline authoring, because a pipeline that runs everything on every change is slow, and one that skips too much is untrustworthy.
Needs declares dependencies between jobs directly, allowing a job to start as soon as its own dependencies finish rather than waiting for its whole stage. On a pipeline of any size this is the single largest source of wall-clock improvement.
4. Structuring a pipeline
A pipeline that serves a team well has a recognisable shape, and the ordering is deliberate — cheap checks first, so expensive ones are not wasted on a change that fails a linter.
- Validate. Linting, formatting, secret scanning, specification linting. Seconds, and catches the most common problems.
- Build. Compile and produce the artefact exactly once. Everything downstream promotes this same artefact rather than rebuilding.
- Test. Unit tests in parallel shards, integration tests against real dependencies as services, with coverage and test reports published so results appear in the merge request.
- Scan. Static analysis, dependency scanning, container scanning, licence checking. Run in parallel with tests where they do not depend on the build.
- Package. Push the artefact to the registry, tagged immutably.
- Deploy to review. An ephemeral environment per merge request.
- Deploy to staging automatically on the default branch.
- Deploy to production, gated by a manual approval or fully automatic depending on your maturity.
Two rules keep this honest. Build once, promote the same artefact — the moment you rebuild for production, your tested artefact and your shipped artefact are different things. And fail fast: order jobs so the cheapest checks run first, and let a failing linter stop the pipeline before a twenty-minute test suite starts.
5. Reuse across projects
Twenty repositories each with a hand-maintained pipeline file means twenty places to update when a practice changes. Three mechanisms address this.
Includes pull configuration from another file, another project, or a remote location. A central pipeline library defining standard jobs, included by every project, means an improvement is made once.
Extends lets a job inherit from a template and override specifics, which is how you keep a shared definition while allowing per-project variation.
Components package reusable pipeline units with declared inputs, versioned like any dependency. This is the most maintainable option for organisations with many projects, because consumers pin a version and upgrade deliberately rather than being affected by every change to a shared file.
The governance benefit is substantial: security scanning, compliance jobs and deployment patterns can be defined centrally and enforced, rather than depending on every team remembering to add them. The associated risk is a shared template that becomes so general it is difficult to understand — versioned components with explicit inputs age considerably better than a growing shared file with conditionals.
6. Runners and executors
Runners execute jobs, and the choice affects cost, speed and security posture.
Shared hosted runners require no operation and are billed by minute. Appropriate for most projects, and the right default until a specific reason emerges.
Self-managed runners run on your own infrastructure. Justified by cost at high volume, by needing access to private networks, by specific hardware requirements, or by data handling constraints.
The executor determines how a job runs. Container-based execution is the common default, giving each job a clean, defined environment. Cluster-based execution creates a pod per job and scales naturally. Virtual machine execution provides the strongest isolation and is the appropriate choice when running untrusted code, such as pipelines from external contributions.
The security consideration that matters most: a runner has access to whatever the pipeline can reach, including deployment credentials. Runners executing untrusted code must be isolated from those handling production deployments — sharing them is a straightforward path to a serious incident.
7. Making pipelines fast
A pipeline slower than about twenty minutes stops being feedback and becomes an interruption. The levers, in order of typical impact:
- Declare job dependencies explicitly so jobs start when their inputs are ready rather than when their stage begins. This alone often halves wall-clock time.
- Shard tests across parallel jobs. A twenty-minute suite split eight ways is under three minutes, at the cost of more concurrent runners.
- Cache dependencies properly, with a key derived from the lock file so it invalidates only when dependencies change.
- Use purpose-built images containing your toolchain rather than installing it at the start of every job. Installation time repeated across every job in every pipeline is a large hidden cost.
- Skip work that cannot be affected. Rules based on changed paths prevent running the whole suite for a documentation edit.
- Split large repositories into child pipelines so each component's pipeline runs independently rather than as one enormous graph.
- Optimise container builds with layer caching and multi-stage builds; image building is frequently the slowest single job.
Measure before optimising. Pipeline analytics show where the time actually goes, and it is routinely somewhere other than where the team assumed.
8. Environments and deployments
An environment is a named deployment target, and registering deployments against it gives you a history of what is running where, who deployed it, and a one-click path to redeploy a previous version.
The deployment strategies worth knowing:
| Strategy | How it works | Suits |
|---|---|---|
| Rolling | Replace instances gradually | Stateless services; the common default |
| Blue-green | Deploy alongside, switch traffic, keep the old version ready | Fast rollback; doubles infrastructure briefly |
| Canary | Small traffic share first, expand on healthy signals | High-risk changes; needs good metrics |
| Feature flags | Deploy dark, enable separately | Separating deployment from release entirely |
The capability with the largest effect on delivery culture is the last one. When shipping code and exposing behaviour are independent decisions, deployment becomes routine and launch becomes a deliberate business choice rather than an evening event.
Protect production properly: restrict who can deploy, require approval where your risk profile demands it, and ensure the rollback path has actually been exercised rather than merely documented.
9. Review apps
A review app is a temporary deployment of a merge request's code, created when the merge request opens and destroyed when it closes. The link appears directly in the merge request.
The value is that review stops being a reading exercise. A designer can look at the change. A product manager can click through it. A tester can exercise the actual behaviour rather than inferring it from a diff. For anything user-facing, this catches a category of problem that code review structurally cannot.
Practical requirements: the environment must be genuinely ephemeral with a defined stop action, or you accumulate abandoned deployments and cost. Seeded data must be realistic enough to be useful and must never be production data. And the environments must be quick to create, because a review app that takes fifteen minutes to appear will be ignored.
10. Security scanning
The scanning suite covers several distinct concerns, and knowing what each does prevents the assumption that enabling everything means being secure.
- Static analysis examines source code for insecure patterns. Good at injection risks and unsafe functions; noisy without tuning.
- Dependency scanning identifies known vulnerabilities in libraries. The highest-value scanner for most teams, because vulnerable dependencies are among the most common real attack paths.
- Container scanning checks image layers, including the base image, which frequently contributes more vulnerabilities than your own code.
- Secret detection finds credentials committed to the repository, including in history. Cheap, and it closes one of the most common breach paths permanently.
- Licence compliance flags dependencies whose terms conflict with your policy — a legal concern rather than a security one, and frequently the more immediately consequential.
- Dynamic analysis exercises a running application. Slower and better suited to a scheduled run than to every merge request.
Two configuration decisions determine whether this is useful. Gate on newly introduced findings, comparing against the target branch, so the existing backlog does not block every change — otherwise the checks get disabled within a month. And tune aggressively: a scanner producing a hundred low-value findings trains people to dismiss the list, which costs you the ten that mattered.
11. The registries
Integrated registries for container images, language packages, generic artefacts and infrastructure modules remove a separate system with its own access model.
The practical benefits are authentication that already works from within pipelines, images scanned automatically, and cleanup policies that prevent unbounded storage growth. That last point matters more than it appears — a container registry with no cleanup policy grows indefinitely, and the cost is discovered late.
The discipline worth applying: tag images immutably with the commit reference rather than relying on a moving tag, so that what ran in staging is provably what runs in production. Moving tags are convenient and make it impossible to answer the question "what exactly is deployed" with certainty.
12. Merge requests and code review
The merge request is where the platform's integration is most visible: the diff, the pipeline result, test and coverage reports, security findings, the review app link, and approval state all in one place.
The features that change review quality:
- Approval rules requiring specific reviewers for specific paths — the team owning a module reviews changes to it, automatically.
- Code owners defined in a file, so ownership is versioned rather than configured in a settings page nobody reads.
- Merge trains, which verify each change against the result of merging those ahead of it. This prevents the failure where two individually passing changes break when combined.
- Suggested changes that a reviewer can propose and an author can apply directly, which removes a round trip for small corrections.
The practice that matters most is unchanged by tooling: keep changes small. A four-hundred-line change gets a genuine review; a four-thousand-line change gets an approval.
13. Permissions and compliance
Access is granted at group or project level through defined roles, and inheritance means an organisation's structure can be expressed as a group hierarchy rather than as per-project configuration.
For regulated environments, the mechanisms that matter are protected branches preventing direct pushes, required approvals with a rule that the author cannot approve their own change, protected environments restricting who may deploy, and audit events recording who did what. Compliance frameworks can enforce that specific pipeline configuration is applied to designated projects and cannot be removed by the project's own team.
The general principle worth stating: separation of duties is achieved through review requirements and protected environments rather than through organisational silos. Auditors are frequently more comfortable with automatically generated evidence than with manually assembled records, once the mechanism is explained.
14. Self-managed or software as a service
| Software as a service | Self-managed | |
|---|---|---|
| Operations | None | Upgrades, backups, scaling, availability |
| Data location | Provider's regions | Wherever you require |
| Network access | Runners must reach your systems | Natural access to internal networks |
| Upgrades | Continuous | Your schedule, your effort |
| Cost shape | Per user plus compute minutes | Licence plus infrastructure plus staff |
| Suits | Most organisations | Strict data residency, air-gapped, or very large scale |
The honest default is the hosted service, with self-managed runners where jobs need access to private infrastructure. That combination covers most of the reasons organisations self-host without taking on operation of the platform itself. Full self-management is justified by genuine regulatory or network constraints rather than by preference, because the operational commitment is ongoing and frequently underestimated.
15. Where the integrated approach costs you
Being clear about the trade-offs prevents disappointment.
- Individual capabilities may be weaker than the best specialised tool. Security scanning, in particular, is convenient and integrated rather than best in class.
- Migration is a real project. Moving from a separate tracker or a separate pipeline system takes months and is frequently underestimated.
- Concentration risk. An outage or an account problem affects everything at once, rather than one part of your toolchain.
- Pipeline configuration in one file can become unwieldy for large repositories, which is why includes, components and child pipelines matter as an organisation grows.
- Some workflows fit better elsewhere. Teams with heavy dependence on a particular ecosystem's tooling may find the equivalent here adequate rather than excellent.
The decision usually turns on whether your organisation values consistency and traceability across many teams more than best-of-breed capability in each stage. Both answers are defensible; assembling a toolchain deliberately is better than drifting into one.
16. Twelve mistakes
- Rebuilding the artefact per environment. What you tested is not what you shipped.
- No job dependency declarations. Wall-clock time dominated by unnecessary waiting.
- Pipelines that fail without a cache. Caches are an optimisation, not a dependency.
- Installing the toolchain in every job. Minutes wasted on every pipeline, forever.
- Running everything on every change. Slow pipelines get bypassed.
- Security gating on the whole backlog. Blocks every build; gets disabled within a month.
- Untuned scanners. Noise trains people to dismiss real findings.
- Shared runners for untrusted code and production deployments. A direct path to compromise.
- Review apps without a stop action. Accumulating environments and cost.
- Moving image tags. Nobody can say with certainty what is deployed.
- No registry cleanup policy. Storage grows without bound.
- Copying pipeline files between projects. Twenty places to update; nineteen get missed.
17. A worked example: one service, one pipeline
Consider a team adopting the platform for a single service, coming from separate hosting and a separate build server. The sequence that works is deliberately incremental.
Week one is source control and merge requests only. No pipeline yet. The team establishes protected branches, code owners, and approval rules. This alone changes review quality, because ownership becomes automatic rather than a matter of remembering who to ask.
Week two builds the minimum pipeline: lint, build once, unit tests, publish the artefact. It runs in under six minutes because the toolchain lives in a purpose-built image rather than being installed per job, and because tests are sharded across four parallel jobs. Nothing deploys yet; the goal is a trustworthy signal on every merge request.
Week three adds scanning, configured from the start to gate only on newly introduced findings. The first run surfaces a long backlog, as it always does — but because the gate compares against the target branch, that backlog informs a separate remediation plan rather than blocking every change. Secret detection over the full history finds two credentials committed eighteen months earlier; both are rotated the same day.
Week four introduces environments. Staging deploys automatically on the default branch; production is a manual step with restricted permissions. Deployments are registered, so the environment page becomes the answer to "what is running" — a question that previously required asking someone.
Week five adds review apps. Each merge request gets an ephemeral deployment with a stop action, seeded with realistic but synthetic data. The first week of use catches two user-facing problems that had passed code review cleanly, which is the argument for the feature made concretely.
Week six extracts the shared parts. With the pipeline stable, the standard jobs — lint, scan, build, publish — move into a versioned component that other projects can include with their own inputs. The second service onboarded takes two days rather than six weeks, which is where the investment repays itself.
The pattern generalises: establish trustworthy signal first, add gates second, add deployment third, extract reuse last. Teams that begin by building an elaborate shared pipeline framework before any single project uses it consistently produce something that fits nobody.
18. Frequently asked questions
Is it worth migrating from a working toolchain?
Only with a specific reason: the cost of maintaining integrations, inconsistent access control across tools, or the inability to trace a change end to end. Migration is a real project measured in months. If your current toolchain works and nobody is complaining about the seams, the case is weak — the benefit is in removing friction that must actually exist.
How do we keep pipeline configuration manageable at scale?
Versioned components with declared inputs, included by each project. Avoid the growing shared file with conditionals for every consumer, which becomes impossible to change safely. Child pipelines help for large repositories where several components have independent build and test needs.
Should we use the built-in security scanning or a specialist tool?
Start with the built-in scanning, because integration into the merge request is what makes findings get acted on. Add a specialist tool where you have a specific need the built-in scanner does not meet, and integrate its results into the same place. The most common failure is not weak scanning but findings that live somewhere developers never look.
Hosted runners or our own?
Hosted by default. Move to self-managed runners when cost at volume justifies it, when jobs need to reach private networks, or when data handling requires it. Many organisations end up with both: hosted for most work, self-managed for jobs touching internal systems. Keep the two populations separate when untrusted code is involved.
How do we make review apps affordable?
Ephemeral by construction, with a stop action on merge request close and an automatic expiry as a backstop. Use a shared cluster with per-request namespaces rather than separate infrastructure. Limit them to changes that touch user-facing code, using path rules, so a documentation edit does not deploy an environment.
Can this satisfy regulatory requirements?
In most cases, yes, and frequently more convincingly than a manual process. Protected branches, mandatory approvals with author exclusion, protected environments, audit events and enforced compliance pipelines cover the common requirements. The evidence is generated automatically rather than assembled, which auditors generally prefer once the mechanism is explained to them.
What is the most common cause of slow pipelines?
Jobs waiting for their stage rather than for their actual dependencies, and toolchain installation repeated in every job. Both are configuration problems with straightforward fixes, and together they frequently account for more than half the wall-clock time. Look at the pipeline analytics before optimising anything, because the bottleneck is rarely where the team assumes.
Where should a team start?
Source control and merge requests with protected branches and code owners, then a minimal fast pipeline that produces a trustworthy signal. Add scanning, then environments, then review apps, then shared components. Attempting the full platform at once produces a configuration nobody understands and a team that resents it.
A pipeline health checklist
These questions establish whether a pipeline is an asset or an obstacle. Each has an objective answer, and the pattern across them is usually more informative than any single one.
| Question | Healthy answer |
|---|---|
| How long does the pipeline take on a typical change? | Under twenty minutes end to end |
| Is the artefact built once and promoted? | Yes — the same image reaches every environment |
| Do jobs wait on their dependencies or on their stage? | On dependencies, declared explicitly |
| Does the pipeline still pass with an empty cache? | Yes — caches are an optimisation only |
| Does a red pipeline mean something is broken? | Yes — no tolerated flaky jobs |
| Do security findings gate on new issues or the backlog? | New issues, compared against the target branch |
| Can anyone say what version is in production? | Yes — immutable tags and registered deployments |
| Has the rollback path been exercised? | Yes, deliberately, not only during an incident |
| Are review apps ephemeral with a stop action? | Yes, with an expiry as a backstop |
| Do runners for untrusted code touch production credentials? | No — separate runner populations |
| Is pipeline configuration shared or copied between projects? | Shared, as versioned components with inputs |
| Does the registry have a cleanup policy? | Yes — otherwise storage grows without bound |
The rows that most reliably predict trouble are pipeline duration and flakiness. A slow pipeline gets bypassed, and a flaky one teaches the team that failures can be ignored — and once either is true, every other control in the list is weaker than it appears on paper.
Key takeaways
- Integration buys traceability, one permission model and automatic compliance evidence, not best-in-class at every stage.
- Build once, promote the same artefact. Rebuilding per environment breaks the guarantee testing provides.
- Declare job dependencies explicitly. Usually the single largest pipeline speedup available.
- Gate security on new findings only. Gating on the backlog gets the checks disabled.
- Review apps change what review can catch. Ephemeral by construction, or they accumulate.
- Extract shared pipeline components last, once one project's pipeline has proven itself.
The strongest argument for an integrated platform is not any feature. It is that a change can be traced from the issue that motivated it to the deployment that shipped it without anyone maintaining an integration to make that possible — and that everything a team needs to do to ship safely happens in one place, which is what makes it actually happen.
Enjoyed this article?
Get more engineering insights from ELIVTECH — or talk to us about your project.
Get in touch