CI/CD Pipeline for Beginners: Automate Before You Regret It
A CI/CD pipeline catches bugs before they hit production and deploys automatically. Here's how to set one up without the DevOps complexity.
What CI/CD Actually Means (Without the Buzzwords)
Continuous Integration (CI) means that every code change automatically runs your tests and checks — catching bugs before they get to production. Continuous Deployment (CD) means that every change that passes CI is automatically deployed to production. Together, they create a pipeline that turns 'git push' into 'your code is live and tested.' The alternative — manually testing and deploying — doesn't scale. It's also less reliable: manual processes are inconsistent, get skipped when things are busy, and create a disconnect between 'it works on my machine' and 'it works in production.'
Your First GitHub Actions Workflow in 20 Lines
GitHub Actions is the easiest entry point for CI/CD. Every GitHub repository can run automated workflows. A basic CI workflow runs your tests on every pull request — before you merge, you know whether the tests pass.
# .github/workflows/ci.yml
name: CI
on:
push:
branches: [main]
pull_request:
branches: [main]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'npm'
- run: npm ci # Clean install (faster than npm install)
- run: npm run lint # Check code style
- run: npm test # Run your tests
- run: npm run build # Ensure it builds
# This file alone saves you from merging broken code.
# It runs on every PR and shows a green/red check next to the commit.Adding a Database to Your CI Pipeline
Many CI pipelines fail because developers don't know how to add a database for integration tests. GitHub Actions supports service containers — you can run a real PostgreSQL database for the duration of your test run.
# .github/workflows/ci.yml (with database)
jobs:
test:
runs-on: ubuntu-latest
services:
postgres:
image: postgres:16
env:
POSTGRES_DB: testdb
POSTGRES_USER: testuser
POSTGRES_PASSWORD: testpass
options: >-
--health-cmd pg_isready
--health-interval 10s
--health-timeout 5s
--health-retries 5
ports:
- 5432:5432
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with: { node-version: '20' }
- run: npm ci
- run: npm run db:migrate # Run migrations against test DB
env:
DATABASE_URL: postgresql://testuser:testpass@localhost:5432/testdb
- run: npm test
env:
DATABASE_URL: postgresql://testuser:testpass@localhost:5432/testdbContinuous Deployment: Deploying Automatically
Once CI is green, CD automatically deploys your application. The simplest setup: Vercel and Railway both integrate with GitHub and deploy automatically on push to main. The GitHub Actions approach gives you more control — deploy only if CI passes, deploy to staging first and promote to production, run smoke tests after deployment before declaring success. The CD pipeline that runs in production: on merge to main, CI runs → if green, deploy to staging → run smoke tests → if green, deploy to production.
# Deployment job that runs after tests pass:
deploy:
needs: test # Only run if test job passes
runs-on: ubuntu-latest
if: github.ref == 'refs/heads/main' # Only on main branch
steps:
- uses: actions/checkout@v4
- name: Deploy to Railway
run: railway up --detach
env:
RAILWAY_TOKEN: ${{ secrets.RAILWAY_TOKEN }}
- name: Run smoke tests
run: npm run test:smoke
env:
APP_URL: https://your-production-url.railway.appSecrets and Environment Variables in CI
Production credentials should never be in your code. GitHub Actions has a Secrets feature — encrypted variables stored in your repository settings that are injected into workflows as environment variables. API keys, database URLs, deployment tokens — all go in Secrets. Access them in your workflow as `${{ secrets.SECRET_NAME }}`. The discipline: if a value changes between environments (local vs. production) or contains sensitive data, it's a secret, not a hardcoded value. Setting up this discipline in your CI pipeline enforces it project-wide. The deployment and DevOps module at Beyond Vibe Code walks through setting up a complete CI/CD pipeline for a production-grade application.