Skip to content
LinkedInX

Getting Started with CI/CD Using GitHub Actions

Target audience: People who know GitHub basics and want to start automating tests and deployments
Prerequisites: Reading GitHub Features Overview

After writing code, do you find yourself manually running tests, building the project, and uploading files to a server — every single time? With CI/CD, GitHub handles all of that automatically.

This article walks through the basics of CI/CD using GitHub Actions, starting from scratch.

What Is CI/CD?

CI/CD stands for Continuous Integration and Continuous Delivery/Deployment.

TermMeaning
CI (Continuous Integration)Automatically run tests and builds on every push to catch problems early
CD (Continuous Delivery)Automatically deliver code that passes CI to staging or production environments
This table scrolls horizontally. Keyboard users can focus the table and use the left and right arrow keys.

Why CI/CD Matters

Manual testing and deployment carries these risks:

  • Human error — “I forgot to run the tests” or “I uploaded the wrong file”
  • Slow feedback — Bugs go unnoticed for days
  • Knowledge silos — Only one person knows the deployment steps

Automation through CI/CD eliminates these risks at the process level.


What Is GitHub Actions?

GitHub Actions is a CI/CD tool built directly into GitHub. By adding a single YAML file to a repository, I can automate testing, building, and deploying.

Key Terms

TermDescription
WorkflowThe complete automation definition. One YAML file in .github/workflows/ = one workflow
TriggerWhat starts the workflow (push, PR creation, schedule, etc.)
JobA unit of execution inside a workflow. Multiple jobs can run in parallel
StepAn individual task inside a job (running a command or calling an action)
ActionA reusable processing component. Many are published on the GitHub Marketplace
RunnerThe virtual machine that runs a job (e.g., ubuntu-latest)
This table scrolls horizontally. Keyboard users can focus the table and use the left and right arrow keys.

Creating My First Workflow

Step 1: Create the File

Create a .github/workflows/ directory at the repository root and place a YAML file inside it.

.github/
  workflows/
    ci.yml   ← write the workflow here

Step 2: A Basic CI Workflow

Here’s a simple example that runs tests on every push for a Node.js project.

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

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

jobs:
  test:
    runs-on: ubuntu-latest

    steps:
      - name: Check out the repository
        uses: actions/checkout@v4

      - name: Set up Node.js
        uses: actions/setup-node@v4
        with:
          node-version: '20'

      - name: Install dependencies
        run: npm ci

      - name: Run tests
        run: npm test

What Each Section Means

name: CI                        # Workflow name (shown in the GitHub UI)

on:                             # Trigger configuration
  push:
    branches: [main]            # Run on push to main
  pull_request:
    branches: [main]            # Run on PR creation/update targeting main

jobs:
  test:                         # Job name (freely chosen)
    runs-on: ubuntu-latest      # Runtime environment (latest Ubuntu)

    steps:
      - uses: actions/checkout@v4   # Fetch the repo code onto the runner
      - run: npm test               # Execute a shell command

Common Triggers

on:
  push:                          # When code is pushed
    branches: [main, develop]
  pull_request:                  # When a PR is created or updated
    branches: [main]
  schedule:                      # Recurring execution (cron format)
    - cron: '0 9 * * 1'         # Every Monday at 9:00 UTC
  workflow_dispatch:             # Manual trigger from the GitHub UI

Practical Examples

Example 1: Testing a Python Project

name: Python CI

on: [push, pull_request]

jobs:
  test:
    runs-on: ubuntu-latest

    steps:
      - uses: actions/checkout@v4

      - name: Set up Python
        uses: actions/setup-python@v5
        with:
          python-version: '3.12'

      - name: Install dependencies
        run: pip install -r requirements.txt

      - name: Run tests
        run: pytest

Example 2: Run a Linter on Every PR

name: Lint

on:
  pull_request:

jobs:
  lint:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: '20'
      - run: npm ci
      - run: npm run lint

Example 3: Auto-Deploy After Merging to Main (CD)

name: Deploy

on:
  push:
    branches: [main]

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Build
        run: npm run build

      - name: Deploy to Vercel
        uses: amondnet/vercel-action@v25
        with:
          vercel-token: ${{ secrets.VERCEL_TOKEN }}
          vercel-org-id: ${{ secrets.VERCEL_ORG_ID }}
          vercel-project-id: ${{ secrets.VERCEL_PROJECT_ID }}
          vercel-args: '--prod'

About secrets: Never write API keys or tokens directly in a YAML file. Store sensitive values in the repository’s Settings → Secrets and variables → Actions, then reference them with ${{ secrets.VARIABLE_NAME }}.


Checking Workflow Status

After pushing a workflow, I can monitor execution status from the Actions tab of the repository.

  1. Click the “Actions” tab on the repository page
  2. A list of running and completed workflows appears
  3. Click any entry to see per-step logs
  4. Failed steps are shown in red with detailed error output

Common Errors and Fixes

npm ci fails

This usually means package-lock.json is missing or out of sync with package.json. Run npm install locally, commit the updated package-lock.json, and push again.

Permission denied

The script may not have execute permission. Add chmod +x script.sh as a step, or run it with bash script.sh instead.

Secret shows as undefined

The most common causes are a typo in the secret name or the restriction that prevents forked PRs from accessing secrets. Check the exact name in the repository Settings.


GitHub Actions Pricing

EnvironmentFree Tier
Public repositoriesUnlimited (completely free)
Private repositoriesUp to 2,000 minutes/month free (GitHub Free)
This table scrolls horizontally. Keyboard users can focus the table and use the left and right arrow keys.

For personal learning or open-source projects, Actions is essentially free.


Next Steps

Once I’m comfortable with the basics, here are good next challenges:

  • Matrix builds — Run tests in parallel across multiple OS and language versions
  • Caching — Use actions/cache to cache dependencies and speed up runs
  • Reusable workflows — Share a common workflow across multiple repositories
  • Environments and deployment gates — Set up an approval flow between staging and production

See the references for the external specifications and background sources used on this page.[1][2]

References

  1. GitHub, GitHub Actions Documentation
  2. GitHub, GitHub Actions Marketplace
Quiz