What is GitHub Actions?
GitHub Actions is a CI/CD platform built directly into GitHub. It allows you to automate tasks like testing code, building applications, and deploying to production - all triggered by events in your repository.
Think of it as having a robot assistant that watches your repository. Whenever something happens (like pushing code), the robot performs tasks you've defined automatically.
Key Concepts
- Workflow: An automated process defined in a YAML file
- Event: Something that triggers a workflow (push, pull request, etc.)
- Job: A set of steps that run on the same runner
- Step: Individual task within a job
- Action: Reusable unit of code (like a function)
- Runner: Server that runs your workflows
Workflow Structure:
┌─────────────────────────────────────────┐
│ Workflow (.github/workflows/ci.yml) │
│ ├── Event: push to main │
│ ├── Job 1: test │
│ │ ├── Step 1: Checkout code │
│ │ ├── Step 2: Setup Python │
│ │ └── Step 3: Run tests │
│ └── Job 2: deploy │
│ ├── Step 1: Build │
│ └── Step 2: Deploy │
└─────────────────────────────────────────┘
Your First Workflow
Create a file at .github/workflows/ci.yml:
# .github/workflows/ci.yml
name: CI
# When to run
on:
push:
branches: [main, develop]
pull_request:
branches: [main]
# What to run
jobs:
test:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.11'
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install -r requirements.txt
- name: Run tests
run: pytest
Common Triggers (Events)
# On push to specific branches
on:
push:
branches: [main, develop]
# On pull request
on:
pull_request:
branches: [main]
# On schedule (cron)
on:
schedule:
- cron: '0 0 * * *' # Daily at midnight
# Manual trigger
on:
workflow_dispatch:
inputs:
environment:
description: 'Environment to deploy'
required: true
default: 'staging'
# Multiple triggers
on:
push:
branches: [main]
pull_request:
branches: [main]
release:
types: [published]
Complete Python CI Workflow
# .github/workflows/python-ci.yml
name: Python CI
on:
push:
branches: [main, develop]
pull_request:
branches: [main]
jobs:
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.11'
- name: Install linting tools
run: pip install flake8 black isort
- name: Run linters
run: |
flake8 .
black --check .
isort --check-only .
test:
runs-on: ubuntu-latest
needs: lint # Run after lint job
strategy:
matrix:
python-version: ['3.9', '3.10', '3.11']
steps:
- uses: actions/checkout@v4
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
- name: Cache pip dependencies
uses: actions/cache@v3
with:
path: ~/.cache/pip
key: ${{ runner.os }}-pip-${{ hashFiles('**/requirements.txt') }}
- name: Install dependencies
run: |
pip install -r requirements.txt
pip install pytest pytest-cov
- name: Run tests with coverage
run: pytest --cov=app --cov-report=xml
- name: Upload coverage to Codecov
uses: codecov/codecov-action@v3
with:
file: ./coverage.xml
build:
runs-on: ubuntu-latest
needs: test
if: github.ref == 'refs/heads/main'
steps:
- uses: actions/checkout@v4
- name: Build Docker image
run: docker build -t myapp:${{ github.sha }} .
- name: Log in to Docker Hub
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
- name: Push to Docker Hub
run: |
docker tag myapp:${{ github.sha }} myuser/myapp:latest
docker push myuser/myapp:latest
Using Secrets
Store sensitive data securely:
# 1. Add secrets in GitHub:
# Repository Settings → Secrets → Actions → New secret
# 2. Use in workflow:
env:
DATABASE_URL: ${{ secrets.DATABASE_URL }}
API_KEY: ${{ secrets.API_KEY }}
steps:
- name: Deploy
run: ./deploy.sh
env:
SSH_KEY: ${{ secrets.SSH_PRIVATE_KEY }}
SERVER_HOST: ${{ secrets.SERVER_HOST }}
Matrix Builds
Test across multiple configurations:
jobs:
test:
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ubuntu-latest, windows-latest, macos-latest]
python-version: ['3.9', '3.10', '3.11']
exclude:
- os: macos-latest
python-version: '3.9'
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
- run: pytest
Deploy to Cloud Platforms
# Deploy to AWS
- 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 S3
run: aws s3 sync ./build s3://my-bucket
# Deploy to Heroku
- name: Deploy to Heroku
uses: akhileshns/heroku-deploy@v3.12.12
with:
heroku_api_key: ${{ secrets.HEROKU_API_KEY }}
heroku_app_name: my-app
heroku_email: me@example.com
# Deploy to DigitalOcean
- name: Deploy to DigitalOcean
uses: appleboy/ssh-action@v1.0.0
with:
host: ${{ secrets.DO_HOST }}
username: ${{ secrets.DO_USERNAME }}
key: ${{ secrets.DO_SSH_KEY }}
script: |
cd /var/www/myapp
git pull
docker-compose up -d --build
Reusable Workflows
# .github/workflows/reusable-test.yml
name: Reusable Test Workflow
on:
workflow_call:
inputs:
python-version:
required: true
type: string
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: ${{ inputs.python-version }}
- run: pip install -r requirements.txt
- run: pytest
# Use in another workflow
jobs:
call-tests:
uses: ./.github/workflows/reusable-test.yml
with:
python-version: '3.11'
Best Practices
- Cache dependencies: Speed up builds by caching pip/npm packages
- Use specific versions: Pin action versions (e.g.,
@v4not@latest) - Fail fast: Run quick checks (lint) before slow ones (tests)
- Use secrets: Never hardcode credentials
- Parallel jobs: Run independent jobs concurrently
- Limit permissions: Use least privilege for tokens
- Add status badges: Show build status in README
# Add badge to README.md

Master GitHub Actions with Expert Mentorship
Our Full Stack Python program covers CI/CD with GitHub Actions. Learn to automate testing, building, and deployment with personalized guidance.
Explore Full Stack Python Program