Cloud Tech by Victor
DevOpsIntermediate

CI/CD Pipelines

What continuous integration and continuous delivery actually automate, how a pipeline stage graph is structured, and why fast feedback loops matter more than pipeline complexity.

Updated 2026-07-223 min read

Overview

A CI/CD pipeline is the automated sequence that takes a code change from a pull request to a running deployment, build, test, package, and release, without a human manually repeating those steps for every change. The value isn't automation for its own sake; it's making the feedback loop between "I made a change" and "I know whether it broke something" as short and reliable as possible, and making every release a repeatable, auditable process instead of a bespoke manual ritual. Most pipeline design problems come from treating the pipeline as a checklist to satisfy rather than a feedback tool to optimize, a pipeline that's thorough but takes 45 minutes trains developers to stop watching it.

Quick Reference

StagePurposeTypical trigger
BuildCompile/bundle the artifactEvery push
TestUnit, integration, and/or e2e checksEvery push
PackageProduce a deployable artifact (container image, binary)On merge to main
Deploy (staging)Automated release to a pre-production environmentOn merge to main
Deploy (production)Release to production, often behind a gateManual approval or automatic on green staging

Syntax

yaml
# .github/workflows/ci.yml
name: CI
on: [push, pull_request]
jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with: { node-version: 20, cache: 'npm' }
      - run: npm ci
      - run: npm run lint && npm run typecheck && npm test
      - run: npm run build

Examples

yaml
# Deploy job that only runs after CI passes on main, gated behind
# a required environment approval configured in repo settings.
deploy:
  needs: test
  if: github.ref == 'refs/heads/main'
  runs-on: ubuntu-latest
  environment: production
  steps:
    - uses: actions/checkout@v4
    - run: ./scripts/deploy.sh

Fail fast, in order of cost

Order pipeline steps from cheapest/fastest to most expensive, lint before typecheck before unit tests before integration tests before build. A typo shouldn't wait behind a 10-minute integration suite to get flagged.

Visual Diagram

Common Mistakes

  • Running the full test suite serially when most of it is independent, parallelizing test shards is usually the single biggest pipeline-speed win available.
  • Treating a green pipeline as proof the deployment will succeed, CI validates the code, not the deployment process itself; deploy failures need their own checks (health checks, smoke tests post-deploy).
  • No caching of dependencies between runs, so every pipeline run pays a full npm install/pip install cost that adds minutes for no new information.
  • Putting a slow, flaky end-to-end suite directly in the required path for every commit, flaky required checks train developers to ignore failures and re-run blindly.

Performance

  • Dependency and build-cache reuse between runs is usually the highest-leverage speed improvement, cold installs dominate pipeline time on most projects.
  • Parallelizing independent stages (lint, typecheck, and unit tests can usually run concurrently, not sequentially) directly cuts wall-clock time even though total compute cost stays the same.
  • Running only the checks relevant to what changed (path-based triggers, affected-package detection in a monorepo) avoids paying full-pipeline cost for a one-line documentation fix.

Best Practices

  • Keep the required-to-merge pipeline fast (minutes, not tens of minutes), move slow, lower-signal checks (full e2e suites, load tests) to a separate, non-blocking or scheduled pipeline.
  • Make pipeline configuration live in the same repository as the code it builds, versioned and reviewed the same way.
  • Use environment-scoped deployment gates for production, not personal judgment about "is now a good time", codify the constraint (approval required, freeze windows) so it's enforced consistently.
  • Fail on the first meaningful problem (lint/typecheck) before spending time on expensive stages (integration tests, build), order stages by cost, not by convention.

Interview questions

What is the difference between continuous integration, continuous delivery, and continuous deployment?

Continuous integration means every code change is automatically built and tested against the main branch frequently; the goal is catching integration problems within minutes, not weeks. Continuous delivery extends that so every change that passes CI is automatically packaged into a release-ready artifact, though a human still decides when to actually deploy it. Continuous deployment goes one step further and removes that human gate, every change that passes all automated checks is deployed to production automatically. The three form a spectrum of increasing automation, and most teams stop at continuous delivery rather than full continuous deployment for anything customer-facing.

Why is pipeline speed treated as a first-class metric, not just a convenience?

A slow pipeline directly increases the cost of every mistake, if tests take 40 minutes to run, a developer either waits 40 minutes for feedback or, more likely, starts the next task and context-switches back later, making the eventual failure much more expensive to fix. Fast pipelines keep the feedback loop close to the moment the mistake was introduced, which is when it is cheapest to fix. This is why teams invest in parallelizing test suites, caching dependencies, and running only the checks relevant to what changed, rather than accepting pipeline slowness as a fixed cost.

What is a deployment gate, and why put one between CI and production?

A deployment gate is a checkpoint, automated (a canary health check, a manual approval, a change-freeze window), that must pass before a build progresses to the next environment. It exists because passing CI only proves the code works in isolation; it doesn't prove the deployment itself will succeed, or that now is a safe time to deploy (e.g., not during a change freeze, not without on-call coverage). Gates let teams keep deployments frequent and automated while still retaining a control point for the decisions that genuinely need human or environmental judgment.

References

ShareXLinkedInReddit
Was this page helpful?
Suggest an improvement