Need the #1 custom application developer in Brisbane?Click here →

Infrastructure

CI/CD Pipelines

11 min readLast reviewed: March 2026

CI/CD automates testing and deployment. Every code change is tested automatically. Good changes are deployed automatically. Broken changes are caught immediately. This is how professional teams ship quality software reliably.

What Is CI/CD?

Continuous Integration (CI) means that code changes are integrated into a shared repository multiple times per day. Each integration is tested automatically to catch bugs early.

Continuous Deployment (CD) means code changes that pass tests are automatically deployed to production. There's a distinction between Continuous Deployment (automatic to production) and Continuous Delivery (ready for production, deployed manually).

Together, CI/CD enables teams to ship features and fixes rapidly with confidence. Instead of pushing to production every month and praying, teams push daily and know immediately if something broke.

The Value of CI/CD

Without CI/CD, deployment is manual and error-prone. Developer A writes code, commits it, hopes it doesn't conflict with Developer B's changes, hopes it works in production. If it breaks, everyone stops working until it's fixed.

With CI/CD, every commit triggers automated tests. If tests fail, the developer sees it immediately and fixes it. If tests pass, the code is deployed automatically. Broken deployments are caught within minutes, not discovered by users.

The business benefit is clear: ship faster, with fewer bugs. The team sleeps better knowing deployments are tested before they touch production.

A Typical CI/CD Pipeline

A typical pipeline looks like:

  1. Push code to GitHub
  2. Lint check — code style validation, catch obvious errors
  3. Unit tests — run automated tests to catch logic errors
  4. Integration tests — test how components work together
  5. Build — compile/bundle the application
  6. Security scan — check for known vulnerabilities
  7. Deploy to staging — test in production-like environment
  8. Deploy to production — push to live servers

If any step fails, the pipeline stops. The developer gets notified. They fix the issue and push again. This fast feedback loop is crucial—if a developer waits hours to find out their code is broken, they've moved on to something else and debugging is harder.

Popular CI/CD Tools

GitHub Actions is built into GitHub. Create `.yml` files in `.github/workflows/` directory and GitHub runs them automatically. Simple for most teams.

GitLab CI is similar but built into GitLab. If you use GitLab, it's the natural choice.

CircleCI is a dedicated CI/CD platform with powerful features. Popular in larger teams.

Bitbucket Pipelines is Atlassian's offering, built into Bitbucket.

For most small-to-medium projects, GitHub Actions is sufficient and free.

GitHub Actions Basics

GitHub Actions uses YAML workflow files. Create `.github/workflows/test-and-deploy.yml`:

name: Test & Deploy

on:
  push:
    branches:
      - main
  pull_request:
    branches:
      - main

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - uses: actions/setup-node@v3
        with:
          node-version: '18'
      - run: npm install
      - run: npm run lint
      - run: npm run test
      - run: npm run build

Key components:

  • on: When to run the workflow (push to main, pull requests)
  • jobs: Steps to execute
  • runs-on: What machine to run on (ubuntu-latest is standard)
  • steps: Individual commands
  • uses: Pre-built actions (checkout code, setup node)
  • run: Shell commands to execute

This workflow runs on every push to main and every pull request. It checks out the code, installs Node, runs linting, runs tests, and tries to build. If any step fails, the whole workflow fails and GitHub notifies the developer.

Deployment Strategies

Rolling deployment: Gradually replace old servers with new ones. If you have 10 servers running v1, replace them with v2 one by one. If v2 is bad, you catch it early and can rollback. This keeps your application available throughout deployment.

Blue/Green deployment: Maintain two identical production environments: "blue" (current) and "green" (new). Test the new version in green, then switch all traffic to green. If problems occur, switch back to blue instantly. This enables fast rollbacks.

Canary deployment: Send 5% of traffic to the new version, 95% to the old. Monitor for errors. If the new version looks good, gradually increase to 100%. If errors spike, automatically rollback. This is the safest approach for catching problems before they affect all users.

Most modern platforms support these strategies automatically.

Note
Canary deployments are standard in professional teams. Deploying a new version to 5% of users is safer and smarter than deploying to 100% immediately. If there's a problem, you've impacted 5% of users instead of everyone.

Preview Deployments for Pull Requests

Modern CI/CD systems deploy pull requests to temporary environments so reviewers can test changes before merging. Push a PR → deployment automatically creates a live URL → reviewer tests the changes → deployment is cleaned up when PR closes.

This eliminates the "but it works on my machine" excuse. Reviewers test in the actual deployment environment.

Secrets Management in Pipelines

Pipelines need to deploy to production, so they need access tokens, API keys, database passwords. These are secrets that should never be stored in code.

GitHub Actions has built-in secrets management. Go to Settings → Secrets and add them:

secrets:
  DEPLOY_KEY: (hidden)
  DATABASE_PASSWORD: (hidden)

Reference them in workflows:

- run: npm run deploy
  env:
    DEPLOY_KEY: ${{ secrets.DEPLOY_KEY }}

Secrets are never logged or exposed. GitHub hides them even in logs.

Warning
Never commit secrets to version control. If you accidentally commit an API key, assume it's compromised. Rotate the key immediately. GitHub will warn you if you try to push secrets, but don't rely on that.

Failing Fast vs Failing Safe

Fail fast: Deploy to production immediately after tests pass. If there's a problem, detect it immediately. Good if you have good monitoring and fast rollback.

Fail safe: Take a conservative approach. Wait for manual approval. Deploy during business hours. Have a human review everything. Good for critical systems where downtime is expensive.

Most modern teams prefer fail fast with good monitoring. Detect problems quickly and fix them. Better than deploying slowly and missing problems that users discover first.

The Cost of Not Having CI/CD

Without CI/CD, teams resort to manual testing. "Let's test this in QA before production." This creates bottlenecks. QA becomes a bottleneck, releases happen less frequently, features take longer to ship.

Without automated testing, bugs slip through to production. Users find them. You're in damage control mode. This is stressful and expensive.

Organizations without CI/CD ship less frequently and with lower quality. They lose competitive advantage to teams that ship weekly or daily.

Rollback Strategies

Things go wrong in production. You deployed a new version and something is broken. How do you get back to the last good state?

Code rollback: Deploy the previous version. This is fast but loses any data created since the bad deploy.

Database migrations: Some deployments include database changes. Rolling back code doesn't roll back the database. You need a rollback plan for migrations.

Feature flags: Instead of deploying/rolling back code, disable the broken feature with a feature flag. This is instant and zero-downtime.

Best practice: always have a rollback plan before deploying. Know exactly what you'll do if the new version is broken. For critical deployments, have a runbook written and tested before deploying.

Common CI/CD Mistakes

Tests that are too slow. If tests take 30 minutes, developers won't wait. They'll skip running tests locally. Make tests fast. Slow tests are broken tests.

Tests that are flaky. Tests that pass sometimes and fail sometimes are useless. You can't trust the pipeline. Fix flaky tests or remove them.

No monitoring after deployment. Deploy without monitoring and you won't know if something is broken. Always have monitoring in place before deploying.

Complex deployments without documentation. If only one person understands how to deploy, you're in trouble. Document the process. Write runbooks. Enable others to help in emergencies.

CI/CD Best Practices

Keep deployments boring. If a deployment feels risky or exciting, something is wrong. Deployments should feel routine and safe.

Deploy frequently. Teams that deploy daily have fewer problems than teams that deploy monthly. Smaller changes are easier to reason about and safer to deploy.

Automate everything you can. If you're doing something manually twice, automate it. This includes builds, tests, deployments, rollbacks, notifications.

Make rollback easy. You should be able to rollback in seconds, not hours. If rollback is hard, you won't do it when you need to.

Continuous Integration vs Continuous Deployment

NameDescriptionBenefitRequirement
Continuous Integration (CI)Automatically test code on every pushCatch bugs early in developmentGood test suite, fast tests
Continuous DeliveryCode ready for production, deployed manuallyFast deployment, but with human controlReliable automated tests, documented process
Continuous Deployment (CD)Automatically deploy to production if tests passShip fast, detect problems immediatelyExcellent monitoring, fast rollback, feature flags

The Reality

CI/CD is non-negotiable in professional software development. Every serious team has it. It's not a nice-to-have, it's a baseline. Without CI/CD, you're at a competitive disadvantage.

Start simple. Get tests running automatically. Get deployments automated. Gradually add more sophisticated deployment strategies as your team matures.

The goal is to ship quality software fast. CI/CD is how you get there.