$ ls index/

engineering / devops-infra

CI/CD Basics

$cat engineering/devops-infra/ci-cd-basics.md

What Is CI/CD

Continuous Integration (CI): Every code push automatically triggers a build + test run. Goal: catch integration problems early, before they reach production.

Continuous Delivery (CD): Every passing build is automatically deployable (one click or auto). The pipeline carries changes safely from code to production.

Push → Lint → Test → Build → Deploy to staging → Deploy to prod

Pipeline Stages

StageWhat it doesFails on
Lint / Type-checkStatic analysis, formattingType errors, lint violations
Unit testsFast isolated testsLogic regressions
Integration testsTests across services/DBAPI contract breaks
BuildCompiles/bundles the appBuild errors, missing env vars
Deploy (staging)Ships to pre-prod environmentDeploy errors, smoke test failures
Deploy (prod)Ships to productionGated by staging passing

Fail fast: put cheap checks (lint, types) first, expensive ones (e2e, build) later.


GitHub Actions

Workflow anatomy

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

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

jobs:
  lint-and-test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - uses: actions/setup-node@v4
        with:
          node-version: 22
          cache: npm

      - run: npm ci
      - run: npm run lint
      - run: npm run type-check
      - run: npm run test

Key concepts

ConceptWhat it is
onTrigger — push, PR, schedule, manual (workflow_dispatch)
jobsParallel units of work; each runs on a fresh runner
stepsSequential commands within a job
usesReference a pre-built action from the marketplace
runRun a shell command
envEnvironment variables scoped to a job or step
secretsEncrypted repo/org secrets accessed via ${{ secrets.NAME }}

Common patterns

PR check (block merge until CI passes):

on:
  pull_request:
    branches: [main]

Set this as a required status check in branch protection rules.

Deploy on merge to main:

on:
  push:
    branches: [main]

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - run: npm ci && npm run build
      - run: npx vercel --prod --token=${{ secrets.VERCEL_TOKEN }}

Environment-specific secrets:

jobs:
  deploy:
    environment: production   # maps to a GitHub Environment with its own secrets

Matrix builds (test across multiple Node versions):

strategy:
  matrix:
    node: [22, 24]   # Node 22 (Maintenance LTS) + Node 24 (Active LTS) as of mid-2026
steps:
  - uses: actions/setup-node@v4
    with:
      node-version: ${{ matrix.node }}

Secrets Management

  • Store secrets in Settings → Secrets and variables → Actions (repo or org level)
  • Never log secrets — mask them: echo "::add-mask::$MY_SECRET"
  • Use GitHub Environments for prod-specific secrets + required reviewers
  • Rotate secrets if a repo ever becomes public or a contributor leaves

GitHub Actions vs Alternatives

GitHub ActionsGitLab CICircleCI
Config file.github/workflows/*.yml.gitlab-ci.yml.circleci/config.yml
Free tier2,000 min/month (public: unlimited)400 min/month6,000 credits/month
Hosted runnersubuntu/windows/macLinux only (free)Linux/mac
MarketplaceLarge action ecosystemLimitedOrbs ecosystem
Best forGitHub reposGitLab self-hostedComplex pipelines

GitHub Actions is the default choice if your code is already on GitHub.

Let's build something impactful together.

ertughaskan@gmail.com Find me online
Availability
WorkAvailable
RelocationOpen
FreelanceClosed
© 2026 Ertugrul Alex Haskan /cookiesVancouver, BC 🇨🇦

This site uses one optional Google Analytics cookie to see which pages get read. Nothing is set until you choose — cookie details.