What Is CI/CD? Automated Deployment Explained for AI Coders

Right now you probably deploy by SSHing into a server or clicking a button. CI/CD replaces that with automation: push code to GitHub, and everything else happens automatically — testing, building, deploying. Here's how it works and how to set it up.

TL;DR

CI/CD (Continuous Integration / Continuous Deployment) automates the process of testing and deploying your code. You push to GitHub → tests run automatically → if tests pass → your app deploys to production. No manual SSH. No "did I forget a step?" GitHub Actions is the most common tool — free, built into GitHub, and works with any hosting provider.

Why AI Coders Need CI/CD

Manual deployment is a trap. You write code, you SSH into your server, you run a list of commands you half-remember, something fails, you troubleshoot, your site is down for 20 minutes. This gets worse every time you add a teammate or increase deployment frequency.

CI/CD solves this by making deployment a single action: git push. Everything else is automated. Understanding CI/CD lets you:

  • Ship faster with less anxiety about breaking things
  • Catch bugs before they reach production (the "CI" part)
  • Never forget a deployment step (the "CD" part)
  • Work on teams without deployment conflicts
  • Read job descriptions and client requirements that mention CI/CD without confusion

Real Scenario: Deploy on Every Push

Your AI Prompt

"Set up GitHub Actions so that every time I push to the main branch, my Node.js app is automatically deployed to my VPS. Run npm test first and only deploy if tests pass."

What AI Generated

# .github/workflows/deploy.yml
# Place this file in your repo at: .github/workflows/deploy.yml

name: Deploy to Production

# Trigger: run this workflow when code is pushed to 'main'
on:
  push:
    branches: [main]

jobs:
  test-and-deploy:
    runs-on: ubuntu-latest  # GitHub runs this on a fresh Ubuntu VM

    steps:
      # Step 1: Download your code onto the runner
      - name: Checkout code
        uses: actions/checkout@v4

      # Step 2: Install Node.js
      - name: Set up Node.js
        uses: actions/setup-node@v4
        with:
          node-version: '22'
          cache: 'npm'

      # Step 3: Install dependencies
      - name: Install dependencies
        run: npm ci  # 'ci' is like 'install' but stricter (uses package-lock.json)

      # Step 4: Run tests — workflow stops here if tests fail
      - name: Run tests
        run: npm test

      # Step 5: Deploy to VPS via SSH (only runs if tests passed)
      - name: Deploy to VPS
        uses: appleboy/ssh-action@v1
        with:
          host: ${{ secrets.VPS_HOST }}       # Stored in GitHub Secrets
          username: ${{ secrets.VPS_USER }}   # Never hardcode these!
          key: ${{ secrets.VPS_SSH_KEY }}     # The private SSH key
          script: |
            cd /var/www/myapp
            git pull origin main
            npm ci --production
            pm2 restart myapp  # Restart the Node.js process

For Vercel (Even Simpler)

# No workflow file needed!
# Connect your GitHub repo to Vercel:
# 1. Go to vercel.com → New Project
# 2. Import your GitHub repository
# 3. Done — Vercel automatically deploys on every push to main

# Vercel handles: build → test → deploy → HTTPS → CDN
# This is what most AI coders should start with

Understanding the Pipeline

The Three Stages

Developer pushes code to GitHub
         ↓
┌─────────────────────────────────┐
│  CONTINUOUS INTEGRATION (CI)    │
│  • Checkout fresh copy of code  │
│  • Install dependencies         │
│  • Run automated tests          │
│  • Run linter / type checks     │
│  • Build the app                │
│  → If anything fails: STOP.     │
│    Send error notification.     │
└─────────────────────────────────┘
         ↓ (only if CI passed)
┌─────────────────────────────────┐
│  CONTINUOUS DEPLOYMENT (CD)     │
│  • Upload built app to server   │
│  • Restart the app process      │
│  • Run health check             │
│  • Send success notification    │
└─────────────────────────────────┘
         ↓
App is live in production

GitHub Actions: How It Works

GitHub Actions runs your workflow on runners — fresh virtual machines GitHub provides. Each time a workflow triggers, GitHub spins up a clean Ubuntu/Windows/macOS VM, runs your steps, and discards it. You pay nothing for the compute on public repos; private repos get 2,000 free minutes/month.

The workflow file lives in your repository at .github/workflows/anything.yml. YAML format. AI generates these well — but watch out for the secrets issue below.

Secrets: The Critical Part AI Gets Wrong

Your deployment workflow needs credentials: server IP, SSH keys, API tokens. These must never be in the YAML file. They go in GitHub Secrets:

# In your GitHub repo: Settings → Secrets and variables → Actions → New secret

# Add:
# VPS_HOST     = 203.0.113.42
# VPS_USER     = deploy
# VPS_SSH_KEY  = (paste your private key)
# DATABASE_URL = postgresql://...

# Reference in workflow:
${{ secrets.VPS_HOST }}     # GitHub substitutes the real value at runtime
${{ secrets.DATABASE_URL }}  # Never appears in logs

# ✅ Safe — secret is encrypted at rest and masked in logs
# ❌ NEVER do this:
# host: 203.0.113.42          # Hardcoded — visible to everyone with repo access

CI/CD for Different Hosting Setups

Vercel / Netlify: Zero Config

Connect your repo. Done. Every push to main deploys automatically. Preview deployments on pull requests. This is the easiest CI/CD for most vibe coders and covers 90% of use cases.

Railway / Render: Also Automatic

Connect repo, configure your build command and start command. Automatic deployments on push. Slightly more control than Vercel for backend/database apps.

VPS: GitHub Actions Required

Manual hosting requires a workflow file. The pattern: test → SSH into server → git pull → restart process. See the workflow above.

Docker + Any Host

name: Build and Deploy Docker Image

on:
  push:
    branches: [main]

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Build Docker image
        run: docker build -t myapp:${{ github.sha }} .

      - name: Push to registry
        run: |
          echo ${{ secrets.REGISTRY_TOKEN }} | docker login ghcr.io -u ${{ github.actor }} --password-stdin
          docker push ghcr.io/${{ github.repository }}/myapp:${{ github.sha }}

      - name: Deploy on VPS
        uses: appleboy/ssh-action@v1
        with:
          host: ${{ secrets.VPS_HOST }}
          username: ${{ secrets.VPS_USER }}
          key: ${{ secrets.VPS_SSH_KEY }}
          script: |
            docker pull ghcr.io/${{ github.repository }}/myapp:${{ github.sha }}
            docker stop myapp || true
            docker run -d --name myapp -p 3000:3000 ghcr.io/${{ github.repository }}/myapp:${{ github.sha }}

What AI Gets Wrong About CI/CD

1. Hardcoding Secrets

Critical. AI sometimes generates workflow files with actual values instead of secret references. Never commit passwords, API keys, or SSH keys to a repository file — even private repos.

2. Missing Health Checks

AI deploys the app but doesn't verify it started correctly. Add a health check after deployment:

- name: Health check
  run: |
    sleep 10  # Wait for app to start
    curl --fail https://yourdomain.com/api/health || exit 1
    # If /api/health returns non-200, the workflow fails and you get notified

3. Deploying on Every Push (Including Feature Branches)

AI sometimes generates workflows that trigger on pushes to any branch. Usually you only want to deploy when pushing to main:

on:
  push:
    branches: [main]  # Only deploy from main — not feature branches

What to Learn Next

Frequently Asked Questions

What does CI/CD stand for?

CI/CD stands for Continuous Integration / Continuous Deployment (or Continuous Delivery). CI = code changes are automatically tested. CD = tested code is automatically deployed. Together: push code → tests run → if pass → app deploys automatically. No manual steps, no forgotten commands.

Do I need CI/CD for my project?

If you're deploying manually (SSHing into servers, running commands by memory), CI/CD replaces that with reliable automation. For solo projects on Vercel or Netlify, you already have it — they auto-deploy on push. For VPS deployments, even a simple GitHub Actions workflow saves hours of repetitive work and prevents human error.

What is GitHub Actions?

GitHub Actions is GitHub's built-in CI/CD system. You define workflows in YAML files inside .github/workflows/. When you push code, GitHub runs those workflows on its servers — installing dependencies, running tests, building your app, and deploying it. Free for public repos, 2,000 free minutes/month for private repos.

What is the difference between Continuous Delivery and Continuous Deployment?

Continuous Delivery: code is automatically built and tested, but deployment requires a manual approval step. Continuous Deployment: deployment is also automatic — every successful test run ships to production. Most small teams use full Continuous Deployment (push → live) for speed, with branch protection rules as the safety gate.

What does AI get wrong about CI/CD pipelines?

The critical mistake: AI sometimes hardcodes secrets (server IPs, passwords, API keys) directly in workflow YAML files. These must always be stored in GitHub Secrets and referenced as ${{ secrets.MY_SECRET }}. AI also generates overly complex pipelines when simple platform integrations (Vercel/Railway auto-deploy) cover most use cases.