A normal application does not need a platform pipeline. It needs a path the team trusts on a Tuesday morning. Everything I put into the first version serves that one sentence.
GitHub Actions or GitLab CI hardly matters. The difference between the two is syntax. The difference between a path you trust and a path you do not trust is not.
What I mean by normal
What I mean is one team, a handful of services, one repository, a deployment onto a server, onto ECS, or onto something of the same size. No internal portal for twelve teams, no runner fleet of your own, no catalogue of your own actions. The path here assumes the code is in Git and a command can build it.
Anyone still putting files on the server by hand is one step earlier. That step is described in When deployment still runs over FTP.
The four things in the first version
A check before the merge that can say no. Tests, and the static analysis that already exists. The check that runs before the merge stays under ten minutes. Above that, people start batching changes, and the benefit of small steps is gone. More on the term under CI/CD. Long tests belong in a second stage after the merge, not on the path every commit has to take.
One artefact per commit. A container image or a package, and the same artefact goes through staging and production. A second build per stage checks something other than what will later run: the same ingredients, a different moment. The stages differ in configuration and approval, not in content.
Staging follows the merge. Production waits for a person. Continuous delivery means every checked revision could be released. It does not mean every merge goes to production on its own. For as long as the way back is still exciting, a person approves production. That is the normal final stage, not a half-finished one.
A way back that is the previous artefact and that somebody has already walked. Back means: the same artefact as the last good revision, released again. A schema change that renames a column makes exactly that impossible, whatever the runbook says. Schema changes therefore run in two steps: add first, then the application, then clean up. The way back is walked once on a real service. A described rollback is a claim.
What the switch between two revisions looks like without Kubernetes is covered in Blue/green and canary without Kubernetes. That is the rollout form. It is not the path that builds the artefact.
Access and third-party actions belong in it
Two things look like hardening and still belong in the first version, because they are small and because their absence is the part an attacker uses.
No long-lived access keys. Where the path touches AWS, it takes permissions at runtime through OIDC: a short-lived token, exchanged for a role. It is only bound to repository, branch and environment if the role’s trust policy checks exactly that; a policy that is too open lets any repository in. A key in the secret store is valid until somebody rotates it. Nobody rotates it.
Third-party actions pinned to a commit SHA, not to a tag. In March 2025 several version tags of a widely used action were retroactively pointed at a different commit (CVE-2025-30066, tj-actions/changed-files). That commit read secrets out of the runner's memory and wrote them into the workflow logs. A tag is not a fixed point. The pin is one line per action, not a later phase.
The incidents around that, the attestations, and the question of when a self-hosted runner pays for itself, are on the page about building a deployment pipeline. The boundary here is enough: these two points are the first version. The rest of the supply chain can wait until the path is boring.
Whether one AWS account sits behind the role or several does not change the path. It changes which role is assumed. The decision before that is covered in One AWS account or several.
What waits until there is a reason
The first version is deliberately small. I leave these things out until somebody names a concrete problem.
- A runner fleet of your own. First measure where the minutes go: duplicate build steps, caches, tests without parallelism. Self-hosted runners replace a bill with operational work. That is not always the better trade.
- Canary for a service with one or two instances. Canary assumes traffic can be split and that a small slice says something. Otherwise the previous revision as an artefact is the way back, and blue/green is enough when two revisions can run side by side.
- A portal, a catalogue of your own actions, a policy engine. The second service copies the first workflow. A shared platform becomes due when the copies diverge for the same reason, not when the second service appears.
- Infrastructure and application in one workflow with one approval. A Terraform plan and a release are two risks. They get two paths. The same person may approve both. It should not be the same button.
- Production on every merge. That becomes viable once the way back has become boring. Before that, the automation only delivers faster something nobody wants to fetch back.
Four arguments that are not enough on their own
“Every commit must reach production.” That is a decision about the blast radius of a mistake, not a property of CI. Delivery means the revision could go out. Deployment means it does go out. The team makes the second decision once the way back has been walked.
“We need GitOps.” A pull request that produces an artefact, and a person who promotes it, are already the loop. A second tool that reconciles a cluster earns its place when the cluster is the problem. For a normal application the Git host is the control point of the path.
“The pipeline must fit every future service.” The second service copies the first workflow and changes the three lines that belong to it. A shared template appears from the third copy that broke at the same point. Before that, the template is a guess about services that do not exist yet.
“Security is phase two.” The keys and the unpinned actions are the part an attacker uses before phase two. Pinning and OIDC are small enough for the first day. An SBOM, an organisation policy that enforces the pinning, a runner of your own: that is phase two, and it has a reason, namely a path that is already running.
What the path does not fix
A pipeline does not make a large release small. If the change is a week of work, the path only ships that week faster. Small steps are a way of working. The pipeline makes them possible and does not force them.
A check that cannot turn red is a green lamp. An exit code other than zero must block the merge. A test that swallows the exception and ends in success needs fixing before another tool joins the path.
And the pipeline replaces nobody who knows the way back. Walked once with the team on a real service, the path then lives in the repository, not in a head. That is the point at which a deployment loses its time of day and a Tuesday morning is enough.
The decision as a table
| First version | Later, with a reason | |
|---|---|---|
| Check before the merge | yes, under ten minutes | slow tests in a second stage |
| Artefact | one, and it is promoted | the same one, no second build |
| Production | a person approves | automatic, once the way back is boring |
| Access to the cloud | OIDC, no long-lived keys | the same role, cut tighter |
| Third-party actions | commit SHA | enforced as an organisation policy |
| Way back | previous artefact, walked once | blue/green or canary, when the traffic allows it |
| Runners | the provider's | your own, when the bill says so |
| Second service | copy the workflow | a shared template, when the copies break the same way |
The question I start with
I do not ask about the CI product. I ask: Which step does a person still do because they do not trust the path?
“A person approves production” can be the intended form. Then the path is finished once the check, the artefact and a walked way back are there.
“Someone builds on a laptop and copies files” means the first version is still missing. “Nobody knows whether the way back works” means the rehearsal is missing, not another tool. “The run takes forty minutes because it builds three times” means the one artefact is missing.
The smallest path the team trusts on a Tuesday is the right one. Anyone who has it built finds the sequence on the page about building a deployment pipeline: one artefact, access without long-lived keys, a way back that has been rehearsed, and afterwards the team that changes the path without me.

