A good pipeline makes shipping boring. A poor one becomes a second product the team must maintain. Small platform teams, which often support many services with few people, benefit most from keeping the design simple, consistent and easy to reason about. This article describes a staged approach you can adapt to nearly any toolchain.
Define What the Pipeline Is For
Before choosing tools, agree on the pipeline’s purpose. Continuous integration means every change is merged frequently and verified automatically. Continuous delivery means every verified change is always in a releasable state. Continuous deployment goes one step further and releases automatically. Many teams practice integration and delivery with a manual approval before production, and that is a perfectly respectable place to be.
The practical goals are fast feedback for developers, repeatable releases and a clear audit trail of what shipped, when and why.
Stage One: Fast Feedback on Every Commit
The first stage runs on every push or pull request and should finish quickly, because slow feedback trains people to ignore it. Typical contents:
- Formatting and static analysis checks.
- Unit tests.
- Dependency and secret scanning.
- A build of the artifact, such as a container image, without publishing it.
If this stage is slow, split it into parallel jobs and cache dependencies before cutting any checks.
Stage Two: Build Once, Promote Everywhere
A core principle is to build an artifact once and promote that same artifact through environments. Rebuilding for each environment means the thing you tested is not the thing you ship. Tag artifacts with an immutable identifier, such as the commit hash, and store them in a registry. Configuration that differs between environments should be injected at deploy time, not baked into the artifact.
Stage Three: Test in a Realistic Environment
After the artifact exists, deploy it to a staging environment that resembles production in the ways that matter: similar topology, the same deployment mechanism and realistic configuration. Run integration and smoke tests here. Slower end-to-end suites can run on a schedule or only for risky changes, as long as the team agrees on which failures block a release.
Stage Four: Deploy With a Safety Net
Production deployment should be the same automation used in staging, with extra guardrails. Common patterns include:
- Rolling updates, replacing instances gradually.
- Blue-green deployments, switching traffic between two full environments.
- Canary releases, sending a small share of traffic to the new version first.
Whichever you choose, pair it with automated health checks and a rehearsed rollback path. A pipeline that can deploy but cannot reliably roll back is only half finished.
Pipeline Stage Summary
| Stage | Trigger | Purpose | Blocks Release? |
|---|---|---|---|
| Commit checks | Every push | Fast feedback on quality | Yes |
| Build and publish | Merge to main | Create the immutable artifact | Yes |
| Staging verification | After build | Integration and smoke tests | Yes |
| Production deploy | Approval or automatic | Release with guardrails | Not applicable |
| Post-deploy checks | After deploy | Confirm health, trigger rollback | Triggers rollback |
Handling Secrets and Permissions
Pipelines are privileged systems, so treat them accordingly. Keep secrets in a dedicated secrets manager or the CI platform’s protected store, never in repository files. Prefer short-lived credentials issued per job over long-lived keys where your platform supports it. Give each pipeline only the permissions it needs, and separate the permission to build from the permission to deploy to production. Review who can edit pipeline definitions, since changing the pipeline can mean changing what runs with production access.
Keep Pipelines as Code and Share Them
Define pipelines in version-controlled files alongside the application so changes are reviewed like any other change. For a small team supporting many services, create shared templates or reusable workflows for common steps. A new service should inherit sensible defaults rather than copy and paste a pipeline from a neighbor and drift away from it.
A Realistic Example
Imagine a three-person platform team supporting eight internal services. Each service had its own hand-written pipeline, and builds behaved differently everywhere. The team defines one reusable template covering commit checks, image build, staging deploy and a manually approved production deploy. Services adopt it one at a time, overriding only what they genuinely need to. Over a few weeks, onboarding a new service drops from a day of copying and debugging to a short configuration file, and a fix to the template reaches every service at once. The team did not buy anything new; they removed variation.
Common Pitfalls
- Letting the main branch stay red for days, which teaches everyone to ignore failures.
- Rebuilding artifacts per environment.
- Treating flaky tests as acceptable background noise.
- Granting broad production credentials to every pipeline job.
- Measuring only deployment frequency while ignoring how often changes fail or need rollback.
Frequently Asked Questions
Do we need continuous deployment to practice CI/CD? No. Continuous integration with a reliable, automated path to production and a human approval step is a strong setup for many teams.
How fast should the commit stage be? Fast enough that developers wait for it rather than context-switching. Many teams aim for a handful of minutes; the right number depends on your team’s habits.
Should we use one pipeline tool for everything? Fewer tools means less to maintain, but pick based on where your code lives and what your team can support. Consistency matters more than the brand.
How do we handle database changes? Version schema migrations alongside code, make them backward compatible where possible and apply them as a deliberate pipeline step rather than ad hoc.
What should we measure? Lead time for changes, deployment frequency, change failure rate and time to restore service are commonly used indicators. Track trends rather than chasing targets.
Next Step
Draw your current path from commit to production on a single page and mark every manual step and every place an artifact is rebuilt. Pick the one that causes the most pain and automate that first.
By SkyStackHub Editorial · Updated November 4, 2026
- CI/CD pipeline
- continuous delivery
- DevOps
- deployment automation