πŸš€ CI/CD Complete Guide

Continuous Integration, Deployment Strategies & Feature Flags

πŸ”„ What is CI/CD?

CI/CD stands for Continuous Integration / Continuous Delivery (or Deployment) - a set of practices that automate the software delivery process.

πŸ“ Code
β†’
πŸ”¨ Build
β†’
πŸ§ͺ Test
β†’
πŸ“¦ Release
β†’
πŸš€ Deploy

Benefits of CI/CD

⚑ Speed

Deploy in minutes instead of days. Faster feedback on code changes. Reduce time to market.

πŸ›‘οΈ Quality

Catch bugs early (before production). Consistent testing on every change. Reduce human error.

πŸ”„ Consistency

Same process every time. Reproducible builds. No "works on my machine" issues.

πŸ“Š Visibility

See build/test status at a glance. Track deployment history. Easy rollbacks.

πŸ”§ Continuous Integration (CI)

Automatically build and test code every time someone pushes changes.

Developer A ──┐
              β”‚     β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
Developer B ──┼────▢│  Shared Repository (main branch)    β”‚
              β”‚     β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
Developer C β”€β”€β”˜                    β”‚
                                   β–Ό
                       β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
                       β”‚      CI Server      β”‚
                       β”‚   (GitHub Actions)  β”‚
                       β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                                   β”‚
                  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
                  β–Ό                β–Ό                β–Ό
            β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”     β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
            β”‚  Build  β”‚     β”‚   Test    β”‚    β”‚   Lint    β”‚
            β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜     β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                                   β”‚
                                   β–Ό
                            βœ… Pass / ❌ Fail

CI Key Practices

PracticeDescription
Frequent commitsIntegrate small changes often (daily or more)
Automated buildsEvery push triggers a build
Automated testsUnit, integration tests run automatically
Fast feedbackKnow within minutes if something broke
Fix immediatelyBroken build = top priority to fix

πŸš€ Continuous Delivery vs Deployment

There are TWO meanings of "CD":

πŸ“¦ Continuous Delivery

Code is ALWAYS ready to deploy, but human MANUALLY approves and triggers production deploy.

Build β†’ Test β†’ Staging β†’ [πŸ‘€ Approval] β†’ Production
                              β”‚
                         Manual click

πŸ€– Continuous Deployment

Every change that passes tests goes to production AUTOMATICALLY. No human intervention needed.

Build β†’ Test β†’ Staging β†’ Production
                  β”‚           β”‚
                  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                   Automatic!

Comparison

AspectContinuous DeliveryContinuous Deployment
Production deployManual triggerAutomatic
Human approvalRequiredNot required
RiskLower (human review)Higher (need great tests)
SpeedFastFastest
Best forRegulated industries, banksSaaS, web apps

πŸ“¦ Pipeline Stages

A typical CI/CD pipeline has these stages:

1️⃣ Source

  • Code pushed to repository
  • Pull request opened
  • Triggers the pipeline

2️⃣ Build

  • Compile code
  • Install dependencies
  • Create build artifacts
  • Run linters

3️⃣ Test

  • Unit tests
  • Integration tests
  • E2E tests
  • Security scans

4️⃣ Deploy

  • Deploy to staging
  • Run smoke tests
  • Deploy to production
  • Monitor for issues

πŸ› οΈ Popular CI/CD Tools

Cloud-Based (Hosted)

ToolDescription
GitHub ActionsBuilt into GitHub, YAML config
GitLab CI/CDBuilt into GitLab, .gitlab-ci.yml
CircleCIFast, Docker-first
Azure DevOpsMicrosoft ecosystem

Self-Hosted

ToolDescription
JenkinsMost flexible, plugin ecosystem
TeamCityJetBrains, great for Java
BambooAtlassian, integrates with Jira

GitHub Actions Example

# .github/workflows/ci.yml
name: CI/CD Pipeline

on:
  push:
    branches: [main]
  pull_request:
    branches: [main]

jobs:
  build:
    runs-on: ubuntu-latest
    
    steps:
      - uses: actions/checkout@v4
      
      - name: Setup Node.js
        uses: actions/setup-node@v4
        with:
          node-version: '20'
      
      - name: Install dependencies
        run: npm ci
      
      - name: Test
        run: npm test
      
      - name: Build
        run: npm run build

🎯 Deployment Strategies

Modern deployment is about controlling traffic flow across multiple servers, not just replacing files.

πŸ’‘ Key Insight: Your app runs on MULTIPLE servers. A load balancer controls which servers receive traffic. Deployment strategies control HOW we update these servers.
πŸ”„

Rolling Deployment

Update servers one by one while keeping the service running.

  • βœ… Zero downtime
  • βœ… Low infrastructure cost
  • ❌ Slow rollback
πŸ”΅πŸŸ’

Blue-Green

Maintain two complete environments. Switch traffic instantly.

  • βœ… Instant rollback
  • βœ… Full testing before switch
  • ❌ 2x infrastructure cost
🐀

Canary

Send small % of traffic to new version first. Gradually increase.

  • βœ… Test with real traffic
  • βœ… Gradual rollout
  • ❌ More complex
🚩

Feature Flags

Deploy code, hide behind flags. Toggle at runtime.

  • βœ… Instant enable/disable
  • βœ… No deployment to toggle
  • ❌ Code complexity

Rolling Deployment

STEP 1: All servers on v1.0
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  v1.0 βœ“  β”‚  β”‚  v1.0 βœ“  β”‚  β”‚  v1.0 βœ“  β”‚  β”‚  v1.0 βœ“  β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

STEP 2: Update Server 1 (others still serving)
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ UPDATING β”‚  β”‚  v1.0 βœ“  β”‚  β”‚  v1.0 βœ“  β”‚  β”‚  v1.0 βœ“  β”‚
β”‚  ↓ v2.0  β”‚  β”‚  serving β”‚  β”‚  serving β”‚  β”‚  serving β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

STEP 3-4: Continue until all updated
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  v2.0 βœ“  β”‚  β”‚  v2.0 βœ“  β”‚  β”‚  v2.0 βœ“  β”‚  β”‚  v2.0 βœ“  β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Blue-Green Deployment

                    USERS
                      β”‚
                      β–Ό
              β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
              β”‚ Load Balancer β”‚
              β”‚   (Switch)    β”‚
              β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                      β”‚
         β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
         β–Ό                         β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”   β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚   BLUE ENVIRONMENT  β”‚   β”‚  GREEN ENVIRONMENT  β”‚
β”‚       (v1.0)        β”‚   β”‚       (v2.0)        β”‚
β”‚                     β”‚   β”‚                     β”‚
β”‚     [LIVE] ◄────────│   β”‚     [STANDBY]       β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜   β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

SWITCH: Change load balancer config
        Blue becomes standby, Green becomes live
        INSTANT rollback: just switch back!

Canary Deployment

                    USERS (100%)
                      β”‚
                      β–Ό
              β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
              β”‚ Load Balancer β”‚
              β”‚ (% routing)   β”‚
              β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                      β”‚
         β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
         β”‚                         β”‚
    95% traffic               5% traffic
         β–Ό                         β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”   β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚   STABLE (v1.0)     β”‚   β”‚   CANARY (v2.0)     β”‚
β”‚   8 servers         β”‚   β”‚   1 server          β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜   β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

GRADUAL ROLLOUT:
Step 1:  5%  ← Test with small % of real users
Step 2: 25%  ← Looking good...
Step 3: 50%  ← Half and half
Step 4: 100% ← Full rollout!

🚩 Feature Flags

Deploy the same code to all servers, but hide new features behind runtime flags stored externally.

YOUR APP (deployed code)          FLAG SERVICE (external)
─────────────────────────         ─────────────────────────

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”          β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                     β”‚   HTTP   β”‚                     β”‚
β”‚  if (flags.newUI)   β”‚ ◄──────► β”‚  Flag Dashboard     β”‚
β”‚    <NewUI />        β”‚  fetch   β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”‚
β”‚  else               β”‚          β”‚  β”‚ newUI: true   β”‚  β”‚
β”‚    <OldUI />        β”‚          β”‚  β”‚ darkMode: 50% β”‚  β”‚
β”‚                     β”‚          β”‚  β”‚ betaAPI: off  β”‚  β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜          β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β”‚
                                 β”‚                     β”‚
Same deployed code!              β”‚  Changed via UI     β”‚
No redeployment needed!          β”‚  (no deploy!)       β”‚
                                 β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
⚠️ Key Point: Feature flags are stored externally (not in code) and fetched at runtime. This is how you can toggle features without redeploying!

How It Works

1️⃣ App Startup

App fetches all flag values from Flag Service. Caches them locally.

2️⃣ Runtime Check

Code checks flag value from cache. Shows feature based on flag.

3️⃣ Real-time Updates

WebSocket or polling for updates. Flag changed? App updates immediately!

4️⃣ Toggle via Dashboard

Product manager toggles flag in UI. NO deployment needed!

Code Example

// Initialize flag service (external)
const flags = new FlagService({
  apiUrl: 'https://flags.mycompany.com/api',
  apiKey: 'your-api-key',
});

await flags.initialize();

// Use in component
function CheckoutPage() {
  // Value comes from EXTERNAL service, not code
  const showNewCheckout = flags.isEnabled('new-checkout');
  
  if (showNewCheckout) {
    return <NewCheckout />;
  }
  return <OldCheckout />;
}

Popular Feature Flag Services

ServiceDescription
LaunchDarklyIndustry leader, enterprise
Split.ioExperimentation focused
FlagsmithOpen source option
ConfigCatSimple, affordable
UnleashOpen source, self-host

πŸ“Š Choosing the Right Strategy

Aspect Rolling Blue-Green Canary Feature Flags
Rollback Speed Slow Instant βœ… Fast Instant βœ…
Infrastructure Cost Low βœ… High (2x) Medium Low βœ…
Complexity Low βœ… Medium High Medium
Real User Testing Yes No Yes βœ… Yes βœ…

When to Use What

πŸ”„ Rolling

Best for: Simple apps, internal tools, cost-conscious, stateless services

Avoid: Breaking changes, need instant rollback

πŸ”΅πŸŸ’ Blue-Green

Best for: Critical systems, instant rollback needs, compliance

Avoid: Very large infra, frequent deploys

🐀 Canary

Best for: Large user base, real traffic testing, gradual rollout

Avoid: Small user base, simple internal tools

🚩 Feature Flags

Best for: A/B testing, trunk-based dev, beta programs

Avoid: Simple features, short-lived changes

Who Uses What

CompanyStrategyNotes
NetflixCanary + Feature FlagsAutomated canary analysis
FacebookFeature Flags (Gatekeeper)Everything behind flags
AmazonCanary + One-boxDeploy to ONE server first
GoogleCanary + Feature FlagsMultiple canarying levels
BanksBlue-GreenGuaranteed rollback

βœ… Best Practices

⚑ Pipeline

  • Keep builds fast (< 10 min)
  • Run tests in parallel
  • Fail fast (quick checks first)
  • Use caching
  • Environment parity

πŸš€ Deployment

  • Automate everything
  • Monitor deployments
  • Easy rollbacks (one click)
  • Security scanning
  • Notify on failure

🚩 Feature Flags

  • Clean up old flags
  • Use naming conventions
  • Document flags
  • Set expiration dates
  • Test both states

πŸ“Œ Summary

ComponentDescription
CIMerge frequently, automated build & test
CD (Delivery)Always deployable, manual production trigger
CD (Deployment)Fully automated to production
RollingUpdate servers one by one
Blue-GreenTwo environments, instant switch
CanaryGradual % rollout
Feature FlagsRuntime toggle, no deploy needed
🎯 Key Takeaway: Modern deployment is about controlling traffic flow, not just replacing files. Choose the strategy that matches your team's needs and risk tolerance.