Continuous Integration and Continuous Deployment

CI/CD automates the build, test, and deployment pipeline — enabling rapid, reliable software delivery.
Continuous Integration (CI)
Developers integrate code frequently (at least daily). Each integration is verified by automated builds and tests.
CI Pipeline
Developer pushes code
↓
[Build] → Compile, resolve dependencies
↓
[Lint] → Code style, static analysis
↓
[Unit Tests] → Fast tests (~seconds)
↓
[Integration Tests] → Component interaction tests (~minutes)
↓
[Security Scan] → Dependency vulnerabilities, SAST
↓
[Artifact] → Build deployable artifact (binary, container image)
↓
Report: ✅ All checks passed / ❌ Failure (block merge)
CI Best Practices
- Keep the build fast (< 10 minutes). Parallelize tests.
- Fix broken builds immediately. A broken main branch blocks everyone.
- Run on every push/PR. No exceptions.
- Automate everything. No manual build steps.
- Make build results visible. Dashboard, Slack notifications.
CI Systems
| System | Type | Key Feature | |---|---|---| | GitHub Actions | Cloud-hosted | Integrated with GitHub. YAML workflows | | GitLab CI | Self-hosted/Cloud | Built into GitLab. Auto DevOps | | Jenkins | Self-hosted | Most flexible. Plugin ecosystem. Groovy DSL | | CircleCI | Cloud-hosted | Docker-first. Orbs (reusable configs) | | Buildkite | Hybrid | Cloud orchestration, self-hosted agents |
GitHub Actions Example
name: CI
on: [push, pull_request]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install Rust
uses: dtolnay/rust-toolchain@stable
- name: Build
run: cargo build --release
- name: Test
run: cargo test
- name: Lint
run: cargo clippy -- -D warnings
- name: Format check
run: cargo fmt -- --check
Continuous Delivery
Code is always in a deployable state. Deployment to production requires manual approval.
CI Pipeline → [Staging Deploy] → [Manual Approval] → [Production Deploy]
Continuous Deployment
Every change that passes CI is automatically deployed to production. No manual approval.
CI Pipeline → [Staging Deploy] → [Automated Tests] → [Production Deploy]
Requires: High confidence in automated tests. Feature flags. Fast rollback capability.
Pipeline Design
Stages
[Build] → [Test] → [Security] → [Staging] → [Approval] → [Production]
Fast feedback: Run fast checks first (lint, compile, unit tests). Slow checks later (integration, E2E, security).
Fail fast: Stop the pipeline on first failure. Don't waste time running later stages.
Artifact Management
Build once, deploy many times. Don't rebuild for each environment.
Build → artifact (container image, binary) → store in registry
↓ deploy to staging (same artifact)
↓ deploy to production (same artifact)
Artifact registries: Docker Hub, GitHub Container Registry, AWS ECR, Nexus, Artifactory.
Environment Promotion
Development → Staging → Production
Each environment:
- Same artifact (different config)
- Environment-specific secrets (injected at deploy time)
- Increasing rigor (manual testing in staging, canary in production)
Deployment Strategies
Blue-Green Deployment
Run two identical environments. One serves traffic (blue), the other is idle (green).
1. Green environment running v1 (serving traffic)
2. Deploy v2 to Blue environment
3. Test v2 on Blue
4. Switch router to Blue (now serving traffic)
5. Green becomes idle (rollback target)
Rollback: Switch back to Green (instant).
Cost: Two full environments. But rollback is instant and reliable.
Canary Deployment
Gradually route traffic to the new version. Monitor for errors.
1. Deploy v2 to a subset (1% of traffic → canary)
2. Monitor: error rate, latency, business metrics
3. If OK: increase to 10%, then 50%, then 100%
4. If problems: roll back canary to v1
Advantages: Low risk. Real user traffic validates the new version. Can catch issues that tests miss.
Rolling Deployment
Update instances one at a time (or in small batches).
[v1][v1][v1][v1] → [v2][v1][v1][v1] → [v2][v2][v1][v1] → [v2][v2][v2][v2]
Kubernetes default: Rolling update with configurable maxSurge and maxUnavailable.
Rollback: Deploy v1 again (another rolling update). Slower than blue-green rollback.
Feature Flags
Decouple deployment from release. Deploy code with features hidden behind flags. Enable features gradually.
IF FEATURE_FLAGS.IS_ENABLED("new_search", user)
NEW_SEARCH_ALGORITHM(query)
ELSE
OLD_SEARCH_ALGORITHM(query)
Use cases: Canary releases (enable for 1% of users), A/B testing, kill switches (disable broken feature without deploy), trunk-based development.
Tools: LaunchDarkly, Unleash, Flagsmith, environment variables (simplest).
Infrastructure as Code (IaC)
Define infrastructure (servers, networks, databases) in code. Version controlled. Reproducible.
Terraform
resource "aws_instance" "web" {
ami = "ami-0c55b159cbfafe1f0"
instance_type = "t3.micro"
tags = { Name = "web-server" }
}
resource "aws_db_instance" "db" {
engine = "postgres"
instance_class = "db.t3.micro"
allocated_storage = 20
}
Declarative: Describe desired state. Terraform computes and applies the diff.
State: Terraform tracks current infrastructure state. terraform plan shows what will change. terraform apply makes changes.
Pulumi
IaC using general-purpose languages (TypeScript, Python, Go, Rust).
const server = new aws.ec2.Instance("web", {
ami: "ami-0c55b159cbfafe1f0",
instanceType: "t3.micro",
});
GitOps
Use Git as the single source of truth for infrastructure and application state.
Git repo (desired state) → GitOps controller → Kubernetes cluster (actual state)
↕ reconcile
(ArgoCD / Flux)
ArgoCD: Monitors a Git repo. Automatically syncs Kubernetes resources to match the repo. Detects drift.
Flux: Similar to ArgoCD. Pull-based. Lightweight.
Benefits: Audit trail (git log). Rollback (git revert). Review (PRs for infra changes). Reproducible.
Pipeline Security
Static Analysis Security Testing (SAST)
Analyze source code for vulnerabilities without executing it.
Tools: Semgrep, SonarQube, CodeQL (GitHub), Clippy (Rust — catches some security issues).
Software Composition Analysis (SCA)
Scan dependencies for known vulnerabilities.
cargo audit # Rust: check for known vulnerabilities in dependencies
npm audit # Node.js
Tools: Dependabot (GitHub), Snyk, Trivy, cargo-audit.
Container Scanning
Scan container images for vulnerabilities in base images and installed packages.
Tools: Trivy, Grype, Docker Scout, Snyk Container.
Secrets Scanning
Detect accidentally committed secrets (API keys, passwords, tokens).
Tools: git-secrets, Gitleaks, TruffleHog, GitHub secret scanning.
Monitoring and Feedback
Deployment Metrics
- Deployment frequency: How often you deploy. (Elite: multiple per day.)
- Lead time for changes: Time from commit to production. (Elite: < 1 hour.)
- Change failure rate: Percentage of deployments causing incidents. (Elite: < 5%.)
- Mean time to recovery (MTTR): Time to recover from a failure. (Elite: < 1 hour.)
These four metrics (from DORA research) measure DevOps performance.
Applications in CS
- Every software project: CI/CD is table stakes for professional software development.
- Microservices: Independent CI/CD pipelines per service. Deployment autonomy.
- Mobile: CI builds for iOS/Android. Beta distribution (TestFlight, Firebase App Distribution).
- Infrastructure: IaC tested in CI. GitOps for deployment. Immutable infrastructure.
- Data pipelines: CI for data transformation code. CD for pipeline deployment.