Continuous integration and continuous deployment are the foundational habits that separate teams shipping 50 times a day from teams dreading their monthly release. Getting CI/CD right doesn't require a platform team or a six-figure tooling budget — it requires understanding what each stage must do and why speed and reliability are non-negotiable.
What changed in 2026
- GitHub Actions and GitLab CI matured into full platforms. Most teams no longer need a self-hosted Jenkins instance; hosted runners cover the majority of workloads at competitive cost.
- Runner caches became smarter. Layer caching for Docker and dependency caching for npm/pip/go modules cut median pipeline times by 40–60% compared to 2023.
- Security scanning became default. SAST, dependency auditing (SBOM generation), and secret detection are now expected in every CI config, not optional add-ons.
- Deployment frequency is measurable. DORA metrics are baked into most CI platforms, so you can benchmark your team against industry data.
The five core stages
Every production-grade pipeline needs these five stages in order:
| Stage |
What it does |
Typical duration |
| Lint & static analysis |
Catch syntax errors, style issues, SAST findings |
<2 min |
| Unit tests |
Fast, isolated, no external services |
2–5 min |
| Build artifact |
Compile, bundle, produce an immutable image |
2–6 min |
| Integration tests |
Spin up dependencies (DB, cache), run contract tests |
4–10 min |
| Deploy |
Push to target environment, run smoke tests |
2–5 min |
Keep the total under 15 minutes. Every minute over that threshold increases skip-the-pipeline pressure.
A minimal GitHub Actions example
# .github/workflows/ci.yml
name: CI
on: [push, pull_request]
jobs:
ci:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up Node
uses: actions/setup-node@v4
with:
node-version: 22
cache: npm
- run: npm ci
- run: npm run lint
- run: npm test -- --coverage
- name: Build image
run: docker build -t myapp:${{ github.sha }} .
- name: Security scan
uses: aquasecurity/trivy-action@master
with:
image-ref: myapp:${{ github.sha }}
exit-code: 1
severity: CRITICAL,HIGH
The cache: npm in setup-node alone cuts install time from ~90 seconds to ~5 seconds on warm runners.
How to start
- Start with lint and tests only. A two-minute pipeline that blocks merges on failing tests beats a perfect future pipeline that doesn't exist yet.
- Add artifact builds once tests are green. Build the same artifact that goes to production — no "build again on release" antipattern.
- Add environments progressively. CI → staging auto-deploy → production with a manual gate is a safe starting pattern.
- Enforce branch protection. Require CI to pass before merging to main. No exceptions, no bypass for "quick hotfixes."
- Measure. Track pipeline duration, flaky test rate, and deployment frequency weekly.
Common mistakes
Flaky tests that get muted. A flaky test suite trains engineers to ignore red builds. Fix or delete flaky tests — don't mark them as allowed to fail and forget them.
Building in CI but not using the artifact. The staging deploy rebuilds from source and the production deploy rebuilds again. Build once, promote the artifact.
Secrets in the repo. Use secret scanning (GitHub has it built-in) and store credentials in your CI secrets store, never in .env files committed to the repo.
No rollback story. A deploy stage with no way to roll back is incomplete. Blue-green, canary, or a simple previous-image tag are all valid — pick one before you need it.
Mega-pipelines. One 45-minute pipeline that does everything serially. Parallelize stages; fail fast on lint before waiting for a 20-minute test suite.
What to skip
- Self-hosted Jenkins if a hosted solution covers your security requirements — the operational overhead is real.
- Manual deploy steps in what you call a "CD" pipeline. Manual is fine as a gate; manual as the actual deploy mechanism is not CD.
- Skipping integration tests to keep pipelines fast. Speed up the tests instead — use testcontainers, parallel workers, or mock only at the network boundary.
FAQ
How often should we deploy to production?
At minimum, daily deployments to staging. Production cadence depends on your risk tolerance, but anything less than weekly usually indicates a pipeline or confidence problem worth fixing.
What is the difference between CD (delivery) and CD (deployment)?
Continuous delivery means every green build could go to production with a manual gate. Continuous deployment means every green build does go to production automatically. Most teams start with delivery; deployment comes after test confidence is high.
Should pipelines run on every push or only on PRs?
Both. Run fast checks (lint, unit tests) on every push for immediate feedback. Run the full pipeline on PRs before merging, and on merges to main.
How do we handle database migrations in CI/CD?
Run migrations as a separate deploy step before the new application version starts. Use idempotent, backward-compatible migrations (add columns before removing old ones) so rollbacks don't break the DB.
Where to go next
Infrastructure as code in 2026, Observability vs monitoring in 2026, and Feature flags guide in 2026.