If there’s one capability that separates high-performing engineering organisations from struggling ones, it’s software delivery. Not talent, not tooling, not architecture — delivery.

Continuous integration and continuous delivery (CI/CD) is the engineering practice that makes frequent, safe delivery possible. This post builds the CI/CD blueprint for cloud-native systems.

Why Frequent Small Releases Win

The research in Accelerate (Forsgren, Humble, Kim) is unambiguous: high-performing teams deploy more frequently and have lower change failure rates than low-performing teams. These aren’t trade-offs — more frequent deployment is correlated with better stability.

The intuition: a deployment of 10 small changes is less risky than a deployment of 100 changes. Each small change is easier to understand, easier to review, easier to roll back if something goes wrong.

Big bang releases are a risk accumulation strategy. Avoid them.

Cloud-Native in Eight Elements

Before getting into the pipeline, it’s worth stating what “cloud-native” means from a delivery perspective. Four central ideas:

  1. Containerisation — every workload is a container
  2. Orchestration — Kubernetes manages the containers
  3. DevOps — shared ownership of the full SDLC
  4. Continuous delivery — software is always in a deployable state

And eight elements that make it real:

  1. Immutable infrastructure
  2. Declarative configuration
  3. Microservices
  4. Dynamic scheduling
  5. Automated delivery pipelines
  6. Observability
  7. Self-healing
  8. Policy-as-code

SCM as SDLC Tempo Driver

Source control management (Git) is the heartbeat of the SDLC. Every significant step — feature start, code review, quality gate, deployment — should be triggered by a Git event.

We use GitHub Flow as the branching strategy:

  • main is always deployable
  • Feature work happens on short-lived branches (hours to days, not weeks)
  • PRs are the unit of review and the trigger for quality gates
  • Merge to main triggers deployment to dev; tagged releases trigger staging/production

GitHub Flow is simple and it forces small, frequent merges. Long-lived feature branches are a smell — they mean large, risky merges.

The Containerisation Pipeline

Every service gets built into a container image in CI:

git push → CI trigger → build container image → tag with git SHA → push to registry

Key principles:

  • Build once — the same image that passes tests gets deployed to every environment
  • Tag with git SHA — gives you exact traceability from production back to the commit
  • Never use latest — in production, always pin to a specific image SHA or version tag

Dev Environment Per Branch

One of the most powerful patterns in cloud-native CI/CD: a full development environment per branch.

With Kubernetes, it’s feasible to spin up a complete stack for every feature branch:

feature-branch → CI → build image → deploy to dev/feature-xyz namespace → accessible at feature-xyz.dev.yourdomain.com

This gives developers and reviewers a live, isolated environment to test against before merging. It eliminates the “works on my machine” problem and makes PR review much more effective.

The namespace is torn down when the branch is deleted.

Quality Gates on PRs

Before any code can merge to main, it must pass a set of automated quality gates:

1. Unit Tests

Fast, isolated tests of individual components. Must pass with high coverage. Target: under 5 minutes.

2. Integration Tests

Tests that exercise the service against real (or realistic) dependencies. Slower, but catch integration bugs that unit tests can’t.

3. Static Security Scan (SAST)

Automated scanning for security vulnerabilities in code and dependencies. Fail the build on critical findings.

4. Code Quality Scan

Linting, static analysis, code smell detection. Sonarqube, CodeClimate, or similar.

5. Peer Review

At minimum one human review of every change. Security-sensitive changes require a security-aware reviewer.

All five gates are required. A merge that skips any of them is a risk that will eventually manifest as a production incident.

Build Once, Promote Everywhere

The golden rule of CI/CD: the same artifact that was tested is the artifact that runs in production.

Do not rebuild images between environments. Rebuilding introduces the possibility of differences — different dependency versions, different build environment state, different code if something was wrong with the first build.

The promotion pipeline looks like:

commit → build image (tag: git SHA) → push to registry
                                              ↓
                                    deploy to dev (automatic on merge)
                                              ↓
                                    automated test suite in dev
                                              ↓
                                    promote same image to staging (manual or automatic)
                                              ↓
                                    acceptance tests in staging
                                              ↓
                                    promote same image to production (manual approval)

The image SHA is what gets promoted. The environments are different; the artifact is not.

ChatOps

ChatOps brings your deployment pipeline into your team’s communication tool (Slack, Teams, etc.).

Instead of logging into a CI dashboard to trigger or check deployments, you interact via chat commands:

/deploy sensor-api v1.4.2 to staging
/rollback sensor-api in production
/status sensor-api

The bot executes the commands, reports back, and logs everything in the channel. This gives the whole team visibility into what’s being deployed and when, without anyone needing to context-switch to a separate tool.

ChatOps also serves as an audit log: every deployment, every rollback, is recorded in the chat channel with a timestamp and the person who triggered it.

Infrastructure as Code

The Kubernetes manifests, Helm charts, Terraform configurations — all of this is code, and it lives in Git.

Changes to infrastructure go through the same review and quality gate process as application code. Separate repositories for app code and infrastructure config (GitOps pattern) is common and works well.

Use ArgoCD or Flux to apply infrastructure changes from Git automatically (GitOps). The cluster state is always reconciled with what’s in Git.

Summary

A complete cloud-native CI/CD pipeline:

  1. Developer pushes to feature branch
  2. CI builds image, runs unit tests
  3. Dev environment deployed from branch
  4. PR raised → quality gates run (unit, integration, security scan, code quality)
  5. PR reviewed and approved
  6. Merge to main → automatic deploy to dev
  7. Automated tests run in dev
  8. Manual promotion to staging → acceptance tests
  9. Manual approval → promote to production
  10. ChatOps notification to team

The goal is a pipeline where deploying to production is boring. Boring is good.