CI/CD with GitHub Actions
Build CI/CD pipelines with GitHub Actions — workflows, jobs, steps, matrix builds, secrets, caching, and deploying to production.
What you'll learn
- ✓How GitHub Actions workflows, jobs, and steps work
- ✓Triggering workflows on push, PR, schedule, and manual dispatch
- ✓Matrix builds, secrets, caching, and artifacts
- ✓A complete CI/CD pipeline from test to deploy
Prerequisites
- •Basic Git and GitHub knowledge
- •Understanding of CI/CD concepts
GitHub Actions gives you CI/CD built into your repository. No separate service to configure. Define workflows in YAML, and GitHub runs them on every push, PR, or schedule.
Your first workflow
Create .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
- run: npm ci
- run: npm test
Workflow anatomy
- Triggers (
on): what events start the workflow - Jobs: independent units of work that run in parallel by default
- Steps: sequential commands within a job
- Actions: reusable steps from the marketplace
Triggers
on:
push:
branches: [main, develop]
paths: ['src/**', 'tests/**']
pull_request:
types: [opened, synchronize]
schedule:
- cron: '0 6 * * 1' # every Monday at 6 AM
workflow_dispatch: # manual trigger
inputs:
environment:
description: 'Deploy environment'
required: true
default: 'staging'
Matrix builds
Test across multiple versions and OS combinations.
jobs:
test:
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ubuntu-latest, macos-latest]
node-version: [18, 20, 22]
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node-version }}
- run: npm ci
- run: npm test
This creates 6 jobs (2 OS × 3 Node versions) that run in parallel.
Secrets
Store sensitive values in Settings → Secrets → Actions.
steps:
- name: Deploy
env:
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
run: aws s3 sync ./dist s3://my-bucket
Caching dependencies
- uses: actions/setup-node@v4
with:
node-version: 20
cache: 'npm'
- run: npm ci
For custom caching:
- uses: actions/cache@v4
with:
path: ~/.cache/pip
key: pip-${{ runner.os }}-${{ hashFiles('requirements.txt') }}
restore-keys: |
pip-${{ runner.os }}-
Job dependencies
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: npm ci
- run: npm test
build:
needs: test
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: npm ci
- run: npm run build
- uses: actions/upload-artifact@v4
with:
name: dist
path: dist/
deploy:
needs: build
if: github.ref == 'refs/heads/main'
runs-on: ubuntu-latest
steps:
- uses: actions/download-artifact@v4
with:
name: dist
- run: echo "Deploying..."
Environment protection rules
deploy:
needs: build
runs-on: ubuntu-latest
environment:
name: production
url: https://myapp.com
steps:
- run: echo "Deploying to production"
Configure required reviewers, wait timers, and branch restrictions in the GitHub UI.
Docker build and push
jobs:
docker:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- uses: docker/build-push-action@v5
with:
context: .
push: true
tags: ghcr.io/${{ github.repository }}:${{ github.sha }}
Reusable workflows
Define a workflow that other workflows can call.
# .github/workflows/deploy.yml
name: Deploy
on:
workflow_call:
inputs:
environment:
required: true
type: string
secrets:
deploy_key:
required: true
jobs:
deploy:
runs-on: ubuntu-latest
environment: ${{ inputs.environment }}
steps:
- run: echo "Deploying to ${{ inputs.environment }}"
Call it:
jobs:
deploy-staging:
uses: ./.github/workflows/deploy.yml
with:
environment: staging
secrets:
deploy_key: ${{ secrets.DEPLOY_KEY }}
Summary
GitHub Actions gives you CI/CD as YAML files in your repo. Use matrix builds for broad coverage, cache dependencies for speed, artifacts for passing data between jobs, and environments for deployment protection. Start with a simple test workflow and layer on deploy steps as your project matures.
Related articles
- CI/CD Deploy to Production with GitHub Actions
A practical guide to production deploys with GitHub Actions — environments, secrets, OIDC, deploy-on-tag vs deploy-on-main, and pushing images to AWS, Vercel, or Fly.
- CI/CD GitHub Actions vs Jenkins: CI/CD Compared
Compare GitHub Actions and Jenkins for CI/CD pipelines. Covers setup, configuration, plugins, pricing, and when to choose each tool for your team.
- CI/CD CI/CD Artifact Management: Build, Store, and Promote
Learn how to manage build artifacts in CI/CD pipelines including versioning, storage, promotion strategies, and cleanup policies.
- CI/CD Optimize Docker Builds in CI/CD Pipelines
Speed up Docker builds in CI/CD — multi-stage builds, layer caching, BuildKit, registry caching, and slim base images for faster deployments.