Docs / Cloud & DevOps / CI/CD with GitHub Actions: A Practical Guide

CI/CD with GitHub Actions: A Practical Guide

By Admin · Feb 25, 2026 · Updated Apr 23, 2026 · 42 views · 2 min read

What Is GitHub Actions?

GitHub Actions is a CI/CD platform built into GitHub. It runs automated workflows triggered by events like pushes, pull requests, or schedules.

Basic Workflow

Create .github/workflows/deploy.yml:

name: Deploy to Production

on:
  push:
    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

  deploy:
    needs: test
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: Deploy to server
        uses: appleboy/ssh-action@v1
        with:
          host: ${{ secrets.SERVER_HOST }}
          username: ${{ secrets.SERVER_USER }}
          key: ${{ secrets.SSH_KEY }}
          script: |
            cd /var/www/myapp
            git pull origin main
            npm ci --production
            pm2 reload all

Key Concepts

  • Workflow — the YAML file defining the automation
  • Job — a set of steps that run on the same runner
  • Step — individual task (action or shell command)
  • Action — reusable unit from the marketplace
  • Secret — encrypted environment variables

Common Triggers

on:
  push:
    branches: [main]
  pull_request:
    branches: [main]
  schedule:
    - cron: "0 3 * * *"  # Daily at 3 AM
  workflow_dispatch:  # Manual trigger

Docker Build and Push

jobs:
  build:
    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:
          push: true
          tags: ghcr.io/${{ github.repository }}:latest

Caching Dependencies

- uses: actions/cache@v4
  with:
    path: ~/.npm
    key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}

Was this article helpful?