CI/CD Concepts - What Is Continuous Integration and Why It Matters

Status: Active
Last Updated: 2026-08-14
Category: CI/CD - Phase 1: CI/CD Fundamentals
Prerequisites: None
Time: 1 hour
Tags: ci-cd, continuous-integration, continuous-deployment, fundamentals, concepts

Summary

Continuous Integration and Continuous Deployment are the practices that turn "software we hope works" into "software we know works." This article explains what CI/CD actually means, how the build โ†’ test โ†’ deploy pipeline replaced manual release rituals, and what benefits and tradeoffs you accept when you automate your delivery workflow.

๐ŸŽฏ What You'll Learn

By the end of this article, you'll be able to:


The Problem CI/CD Solves

Imagine the classic software release from the early 2000s:

Weeks of development on a branch
    โ†“
"Integration day": merge everything at once
    โ†“
Conflicts everywhere, nothing compiles
    โ†“
Days of debugging the merge
    โ†“
Manual testing checklist (partially skipped under deadline)
    โ†“
Deploy by copying files to a server via FTP
    โ†“
Something breaks. Roll back by... restoring from memory?
    โ†“
Repeat next quarter

This is late integration: combining everyone's work rarely and painfully. Every problem surfaces at once, months after the code was written, when context is gone.

CI/CD inverts this:

Every developer merges small changes daily
    โ†“
An automated system builds the project on every merge
    โ†“
Automated tests run within minutes
    โ†“
Failures surface while the code is fresh in someone's head
    โ†“
Working builds flow automatically toward production

What Happens conceptually: instead of one giant risky event per quarter, you perform hundreds of tiny low-risk events. Risk is amortized. Feedback is immediate.

Continuous Integration Explained

Continuous Integration (CI) is the practice of merging every developer's working copy to a shared mainline several times a day, with each merge verified by an automated build and test run.

The three rules of CI:

  1. Everyone commits to main frequently. Long-lived branches are where integration pain lives.
  2. Every commit triggers an automated build + test. A machine, not a person, verifies the merge.
  3. A broken build is the top priority. You do not build new features on a red pipeline.

A minimal CI loop looks like this:

# Conceptual โ€” what a CI system does on every push:
on: push
steps:
  - install dependencies      # npm install / bun install / pip install
  - compile or lint           # tsc --noEmit / ruff check
  - run unit tests            # pytest / vitest / go test
  - report pass/fail          # badge, email, chat notification

What Happens when a commit lands: the CI server checks out your exact commit into a clean environment, runs the steps deterministically, and publishes the result. If step 2 fails, steps 3โ€“4 don't run. You get a red X and a log link within minutes.

What CI Is NOT

CD: Delivery vs Deployment

The two CDs get confused constantly. The difference is one decision:

                    โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
   Commit โ”€โ”€โ–บ CI โ”€โ”€โ–บโ”‚ Automated tests pass         โ”‚
                    โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
                                   โ–ผ
                     Artifact built & versioned
                                   โ”‚
              โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
              โ–ผ                                       โ–ผ
   CONTINUOUS DELIVERY                  CONTINUOUS DEPLOYMENT
   Staging deploy is automatic;         Production deploy is also
   production needs a human             automatic. Green build on
   "Approve" button.                    main == live in production.
Practice Deploy to staging Deploy to production Typical for
Continuous Integration manual manual teams just starting automation
Continuous Delivery automatic manual approval regulated products, cautious orgs
Continuous Deployment automatic automatic high-trust pipelines, SaaS, homelabs

Rule of thumb: you earn continuous deployment by starting with delivery. If your pipeline has never deployed something broken to staging, you can consider removing the human gate to production.

Build โ†’ Test โ†’ Deploy

Nearly every pipeline, regardless of tool, decomposes into three stages:

Stage 1: Build

Transform source code into a runnable artifact.

# Examples of "build" steps
npm run build          # JS/TS bundle
go build ./...         # compiled binary
docker build -t app .  # container image

Key property: the artifact is immutable. You build once, then promote that same artifact through staging โ†’ production. Rebuilding per environment reintroduces "works on my machine."

Stage 2: Test

Verify the artifact before anyone depends on it, ordered fastest-and-cheapest first:

Lint/typecheck   (seconds)     fail fast โ€” no point compiling further
Unit tests       (minutes)     pure logic, no network
Integration tests(minutes+)    needs a DB/Redis โ€” spin up services
E2E/smoke tests  (tens of min) full running app, few critical paths

What Happens if you order it wrong: a typo fails a 40-minute E2E suite instead of a 10-second linter. Fast checks gate slow checks.

Stage 3: Deploy

Move the artifact to running infrastructure:

# Common deploy mechanisms (covered later in this course)
ssh server 'docker compose pull && docker compose up -d'   # compose host
kubectl set image deployment/app app=registry/app:v1.2.3   # k8s/k0s
git push production                                        # GitOps trigger

Traditional vs Modern Workflows

Dimension Traditional Modern (CI/CD)
Merge frequency Rarely; feature branches live for weeks Daily; branches live hours
When bugs found Weeks later, in QA or prod Minutes later, in the pipeline
Who tests Dedicated QA at the end Automated suite + humans on behavior
Release size Big-bang quarterly Small, continuous, reversible
Rollback Restore backups, improvise Redeploy previous artifact/tag
Release anxiety High โ€” ceremonies, war rooms Low โ€” releases are boring

The deep shift isn't tooling โ€” it's that releases stop being events. In a mature pipeline, deploying is as unremarkable as saving a file.

Benefits and Tradeoffs

Benefits (real, measured)

  1. Faster feedback loops. Bugs are cheapest minutes after they're written; CI finds them then.
  2. Smaller blast radius. A diff of 50 lines is easy to reason about and revert; 5,000 lines is archaeology.
  3. Reproducible builds. Pipelines run in clean containers, so "works on my machine" stops being an excuse.
  4. Safer change culture. When rollback is one command, people ship improvements instead of hoarding them.
  5. Institutional knowledge encoded as code. The deploy process lives in the repo, not in one admin's shell history.

Tradeoffs (honest ones)

  1. Up-front investment. Pipelines, test suites, and environments take days-to-weeks to stand up before they pay off.
  2. Tests become mandatory debt repayment. CI amplifies whatever test coverage exists โ€” including zero. Automating deploys without tests automates breaking production.
  3. New failure domain. Flaky tests, runner outages, and YAML bugs now block shipping. You must treat pipeline failures as first-class incidents.
  4. Discipline requirement. Broken main must be fixed immediately; skipping that discipline makes the pipeline theater.
  5. Self-hosted operational load. Running your own Forgejo/Woodpecker (this course's stack) means you patch, back up, and monitor it.

Which Parts Belong in a Pipeline?

Automate anything deterministic, repeatable, and boring:

Keep human judgment calls outside (or as explicit gates):

Mental Model for the Rest of This Course

You are here
     โ”‚
     โ–ผ
[concepts] โ†’ [Forgejo: your own GitHub] โ†’ [Woodpecker: your own Actions]
                                                       โ”‚
                              [build images] [run tests] [cache]
                                                       โ”‚
                                            [deploy: ssh/compose/k0s]
                                                       โ”‚
                                          [GitOps: ArgoCD reconciles]

Everything ahead is these concepts made concrete with self-hosted tools you own end to end.

๐Ÿ› ๏ธ Troubleshooting & Common Issues

Even conceptual-stage CI adopters hit predictable walls:

Symptom Root cause Fix
Pipeline green but code still broken Tests assert nothing meaningful Write failing test first, watch it fail, make it pass
Team ignores red builds No ownership rule Adopt "broken main = drop everything"; assign fixer automatically
"Works locally, fails in CI" Environment drift Pin versions, replicate local setup with containers
Pipeline slower than manual deploy Wrong stage ordering, no caching Fail fast ordering + caching (see caching-strategies)
Fear of enabling auto-deploy No confidence in tests Stay at continuous delivery until pipeline earns trust

๐Ÿ”— Related

Change Log

Choose Theme

Your selection is saved locally.

Neural Cacophony
Aperture v2
Flux v1
Mosaic Chaos
Nexus v1
Nexus Zest
Prism v2
Synapse