Most software organisations have a CI/CD pipeline. Jenkins, GitHub Actions, GitLab CI, CircleCI: the tool is there. Yet releases remain rare, risky and stressful. Branches live for weeks, merges spark conflicts, tests run for hours and fail unpredictably. Nobody releases on a Friday.
The problem isn't the tool. The problem is that having a pipeline doesn't mean you're doing continuous integration, let alone continuous delivery. Many organisations have simply automated the show: the pipeline exists, but releasing is still largely manual, slow and fragile.
CI/CD isn't a tool you install; it's a practice you adopt. The gap between a team that actually practises it and one that merely owns the tool is the gap between releasing confidently every day and dreading a monthly release.
What continuous integration really is
Continuous integration has a precise definition, set out by Martin Fowler and Matthew Foemmel in 2000 and still valid today: every developer integrates their code into the trunk (the main branch) at least once a day, and every integration is verified by an automated build with tests. Fowler later revised and expanded the article in 2006, but the core principle dates back to the original.
Three phrases matter here:
- Trunk: a single shared branch. Not a feature branch that lives for weeks; the trunk, where everyone integrates
- At least once a day: small, frequent integrations. Each commit is small enough to be understood, reviewed and verified in minutes
- Automated build with tests: every integration triggers a pipeline that compiles, tests and verifies the code. If it fails, the team stops and fixes it before moving on
If branches last more than a day, it isn't continuous integration. If the tests don't run on every commit, it isn't continuous integration. If the build fails and nobody fixes it within the hour, it isn't continuous integration. It's something else: useful, perhaps, but not CI.
CI/CD theatre
This is the pattern we see most often in growing organisations:
- Every developer works on a separate branch for days or weeks
- The merge happens at the end, generates conflicts and takes hours to resolve
- The pipeline runs on the branch and passes, but once the code lands in the trunk the tests fail
- End-to-end tests are slow (30–60 minutes), fragile and often ignored when they fail
- Releasing requires a "release manager" who coordinates, tests manually and decides when it's safe
- Deployment happens on Thursday morning, never on a Friday, never after 4pm
The pipeline exists; the process is manual. Automation covers the easy steps (compiling, running tests) but doesn't tackle the real problems: long-lived branches, unreliable tests, a lack of confidence in releasing.
The clearest sign that your CI/CD is theatre: the team is afraid to release. If releasing causes anxiety, the process isn't working, no matter how sophisticated the pipeline is.
Why the tool isn't the problem
Jenkins, GitHub Actions, GitLab CI: they're all capable tools. The difference between an organisation that releases with confidence every day and one that releases in terror once a month isn't the tool; it comes down to three factors.
First: branching strategy. Trunk-based development, where everyone works on the same branch with frequent integrations, is the prerequisite for real CI. Long-lived feature branches are the most common and most damaging anti-pattern: they delay integration, amplify conflicts and turn every merge into a risky event.
Second: test strategy. A pipeline with slow, fragile tests is worse than a pipeline with no tests at all, because it breeds false confidence. Tests need to be fast (under 10 minutes for the full suite), reliable and meaningful (testing behaviour, not implementation). High-maturity teams aim for zero flaky tests: every unstable test gets investigated and fixed rather than excluded or ignored. If the test suite takes more than 15 minutes, nobody will wait for the result before moving on.
Third: release culture. Releasing often reduces the risk of each individual release. A release that contains one change is easy to understand, verify and, if needed, revert. A release that contains three weeks of work from five teams is a ticking time bomb. A culture of frequent releases is built through practice: you start by releasing twice a week, then daily, then several times a day.
How to go from a pipeline to continuous delivery
The transition isn't a project: it's a series of small steps. Each step reduces the risk of the next.
Step 1: shorten branch lifespans. From weeks to days, from days to hours. Feature flags let you integrate incomplete code into the trunk without exposing it to users: the code is in production, but the feature is switched off until it's ready. This solves the problem at the root: there are no branches to merge because everything is already in the trunk.
Step 2: make tests fast and reliable. Eliminate flaky tests (the ones that fail at random): every flaky test you tolerate erodes trust in the pipeline. Shift the weight from end-to-end tests (slow and fragile) towards unit and integration tests (fast and reliable). The goal is a suite that runs in under 10 minutes and, when it fails, points to a genuine problem.
Step 3: automate the release. If the tests pass and the build is green, releasing should be a single click, not a ceremony. Remove manual steps one at a time: first the staging deployment becomes automatic, then the production deployment becomes a click, then that too becomes automatic. Every manual step you remove is one less point of friction.
Step 4: release small and often. Release frequency is the single most important metric. Small, frequent releases reduce risk, speed up feedback and make rollback trivial. If something goes wrong with a release that contains one change, the cause is obvious. If it goes wrong with a release that contains 47 changes, good luck finding the problem.
The impact on the business
Real CI/CD isn't a technical improvement: it's a competitive advantage. Organisations that release with confidence every day can react to the market in hours, not months; they can experiment with feature flags and measure the impact before committing further investment; they can fix production problems in minutes rather than days.
The DORA metrics (deployment frequency, lead time for changes, change failure rate, time to restore) are the most direct way to measure how effective your CI/CD is. The "elite" organisations in the DORA report release multiple times a day with a change failure rate of between 5 and 15%. That isn't an unrealistic target: it's the natural result of the practices described in this article.
What to do in practice
Three things to do this week.
When we join a team through our Embedded Teams service, we almost always find the same situation: a pipeline is configured, but tests get skipped because "they don't pass in CI", or branches live for weeks because "we're waiting to integrate everything together". CI/CD theatre doesn't come from laziness — it comes from the absence of a shared agreement on what counts as a green build. The first thing we do is establish that contract: no skipped tests, a red build means stop, no exceptions. It sounds obvious. It isn't: it requires the team to stop treating the pipeline as an obstacle to work around and start treating it as a barometer of the system's health.
- Measure your current release frequency: how often does the team release to production? If the answer is "less than once a week", there's room to improve. The Consistency Impact Calculator helps you estimate how much each day of release delay costs
- Identify your oldest branch: how long has the longest-lived branch been open? Every extra day is accumulated risk. The goal is for no branch to live longer than 24 hours
- Time your pipeline: how long does it take from commit to test feedback? If it exceeds 15 minutes, developers will stop waiting for the result. Under 10 minutes is the target; under 5 is ideal
If the pipeline is slow, the tests unreliable and releases rare, the problem isn't solved by switching tools. It's solved by changing the process, the culture and, often, the architecture that constrains them. This is exactly the kind of work we do through an Embedded Teams engagement: we join the team, work alongside it and transfer the practices that make continuous delivery an everyday reality.
