On this page
GitHub Actions
GitHub Actions is GitHub’s built-in CI/CD platform. Workflows are YAML files in .github/workflows/ that run on GitHub-hosted or self-hosted runners.
Core Concepts
| Concept | Description |
|---|---|
| Workflow | Automated process defined in YAML |
| Event | Trigger (push, pull_request, schedule) |
| Job | Set of steps running on one runner |
| Step | Individual task (run command or use action) |
| Action | Reusable unit (checkout, setup-node) |
| Runner | VM that executes jobs (ubuntu-latest, etc.) |
Your First Workflow
# .github/workflows/ci.yml
name: CI
on:
push:
branches: [main]
pull_request:
branches: [main]
jobs:
test:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'npm'
- name: Install dependencies
run: npm ci
- name: Run linter
run: npm run lint
- name: Run tests
run: npm test
Push to GitHub — view runs under Actions tab.
Python CI Example
name: Python CI
on: [push, pull_request]
jobs:
test:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: ['3.11', '3.12']
steps:
- uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
- run: pip install -r requirements-dev.txt
- run: pytest --cov=src --cov-fail-under=80
- run: ruff check src/
Matrix builds test against multiple Python versions in parallel.
Docker Build and Push
name: Build Docker Image
on:
push:
branches: [main]
tags: ['v*']
env:
REGISTRY: ghcr.io
IMAGE_NAME: ${{ github.repository }}
jobs:
build:
runs-on: ubuntu-latest
permissions:
contents: read
packages: write
steps:
- uses: actions/checkout@v4
- name: Log in to GitHub Container Registry
uses: docker/login-action@v3
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Build and push
uses: docker/build-push-action@v5
with:
push: true
tags: |
${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:latest
${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ github.sha }}
Secrets
Store sensitive values in Settings → Secrets and variables → Actions:
steps:
- name: Deploy
env:
DATABASE_URL: ${{ secrets.DATABASE_URL }}
API_KEY: ${{ secrets.API_KEY }}
run: ./deploy.sh
Never log secrets. GitHub masks known secret values in output.
Environments and Approvals
jobs:
deploy-staging:
runs-on: ubuntu-latest
environment: staging
steps:
- run: ./deploy.sh staging
deploy-production:
needs: deploy-staging
runs-on: ubuntu-latest
environment:
name: production
url: https://myapp.com
steps:
- run: ./deploy.sh production
Configure required reviewers for the production environment in repo settings.
Caching Dependencies
Speed up builds with caching:
- uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'npm'
# Manual cache
- uses: actions/cache@v4
with:
path: ~/.npm
key: ${{ runner.os }}-npm-${{ hashFiles('**/package-lock.json') }}
restore-keys: |
${{ runner.os }}-npm-
Reusable Workflows
Define once, call from multiple repos:
# .github/workflows/reusable-test.yml
on:
workflow_call:
inputs:
node-version:
required: true
type: string
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: ${{ inputs.node-version }}
- run: npm ci && npm test
Call it:
jobs:
call-test:
uses: ./.github/workflows/reusable-test.yml
with:
node-version: '20'
Deploy to AWS / Azure / GCP
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v4
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
aws-region: us-east-1
- name: Deploy to ECS
run: |
aws ecs update-service \
--cluster my-cluster \
--service my-service \
--force-new-deployment
Workflow Status Badge
Add to README.md:

Debugging Failed Workflows
- Click failed job → expand failed step
- Enable debug logging: set repo secrets
ACTIONS_STEP_DEBUG=true - Re-run failed jobs without re-pushing
- Test locally with act (limited support)
What Comes Next
Compare with self-hosted Jenkins for enterprise scenarios, then apply CI/CD Best Practices across your pipelines.