APEX Educational Institute

CI/CD Pipeline with GitHub Actions: A Beginner's Step-by-Step Guide

Learn what CI/CD means and build a GitHub Actions pipeline that installs dependencies, runs tests on every pull request, builds a Docker image and deploys on merge, with secrets handled safely.

Intermediate | 3 min read | Updated

CI/CD automates the path from a code change to production.

  • Continuous Integration (CI): every push or pull request is automatically built and tested, so broken code is caught in minutes.
  • Continuous Delivery / Deployment (CD): code that passes CI is automatically packaged and released to staging or production.

GitHub Actions is CI/CD built into GitHub. Pipelines are YAML files stored in your repository under .github/workflows/.

Key terms

TermMeaning
WorkflowOne YAML file describing an automated process
Event (trigger)What starts it: push, pull_request, a schedule, a manual run
JobA group of steps that runs on one machine (runner)
StepA single command or a reusable action
ActionA reusable building block, e.g. actions/checkout
SecretAn encrypted value such as an API key, never printed in logs

Step 1: A CI workflow for a Node.js project

Create .github/workflows/ci.yml:

yaml
name: CI

on:
  pull_request:
  push:
    branches: [main]

jobs:
  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 test

Push this file. Every pull request now shows a green tick or a red cross, and you can make the check required in branch protection so failing code cannot be merged.

Use npm ci instead of npm install in pipelines. It installs exactly what is in package-lock.json and fails if the lock file is out of date, which keeps builds reproducible.

Step 2: Test on several versions with a matrix

yaml
jobs:
  test:
    runs-on: ubuntu-latest
    strategy:
      matrix:
        node: [20, 22]
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: ${{ matrix.node }}
          cache: npm
      - run: npm ci
      - run: npm test

Step 3: Build and push a Docker image after tests pass

yaml
  docker:
    needs: test
    if: github.ref == 'refs/heads/main'
    runs-on: ubuntu-latest
    permissions:
      contents: read
      packages: write
    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@v6
        with:
          push: true
          tags: ghcr.io/${{ github.repository }}:${{ github.sha }}
  • needs: test means this job runs only if tests passed.
  • The if condition limits it to the main branch, so pull requests are tested but not published.
  • Tagging with the commit SHA makes every image traceable to the exact code.

Step 4: Deploy

Deployment depends on your platform (a cloud VM, Kubernetes, or a platform like Railway, Render or AWS). A common pattern is calling the platform's CLI with a token stored as a secret:

yaml
  deploy:
    needs: docker
    runs-on: ubuntu-latest
    environment: production
    steps:
      - run: ./scripts/deploy.sh ${{ github.sha }}
        env:
          DEPLOY_TOKEN: ${{ secrets.DEPLOY_TOKEN }}

Using a GitHub environment named production lets you require a manual approval before the deploy job runs.

Secrets and security

  • Add secrets in Settings > Secrets and variables > Actions. Reference them as ${{ secrets.NAME }}.
  • Never echo secrets; GitHub masks known secrets in logs, but derived values may leak.
  • Give workflows the minimum permissions they need.
  • Pin third-party actions to a version tag or commit SHA.

Pipeline best practices

  1. Keep CI fast (under 10 minutes): cache dependencies and run slow end-to-end tests in parallel.
  2. Fail early: run lint and unit tests before longer jobs.
  3. Build once, deploy the same artifact to staging and then production.
  4. Make deployments easy to roll back (redeploy the previous image tag).

Interview questions

  • Continuous Delivery vs Continuous Deployment? Delivery keeps every change ready to release with a manual approval; Deployment releases automatically to production.
  • What is a runner? The machine that executes jobs: GitHub-hosted or self-hosted.
  • How do you share data between jobs? Upload and download artifacts, or pass outputs; each job runs on a fresh machine.

Next steps

Add this CI workflow to one of your repositories today, then add Playwright tests to it. Learn Kubernetes deployments, monitoring and AIOps in the DevOps + AI course.

Master it hands-on

Cloud + AI

DevOps + AI (AIOps)

Linux, Git, CI/CD, Docker, Kubernetes, Terraform, cloud and AIOps.

16 weeks Beginner to Advanced
Online LiveRecorded Course

More Cloud + AI tutorials