GitHub Actions
GitHub Actions automates testing, building, and deploying on every push. Here's a practical CI/CD setup.
Basic CI Pipeline
# .github/workflows/ci.yml
name: CI
on:
push:
branches: [main, master]
pull_request:
branches: [main, master]
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"
cache: "pip"
- name: Install dependencies
run: pip install -r requirements.txt
- name: Run tests
run: python manage.py test
- name: Check migrations
run: python manage.py makemigrations --check --dry-run
Deploy on Push to Main
# .github/workflows/deploy.yml
name: Deploy
on:
push:
branches: [main]
jobs:
deploy:
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_PRIVATE_KEY }}
script: |
cd /var/www/myproject
git pull origin main
source venv/bin/activate
pip install -r requirements.txt
python manage.py migrate
python manage.py seed_content
python manage.py collectstatic --noinput
sudo systemctl restart gunicorn
Key Patterns
Cache dependencies to speed up builds:
- uses: actions/setup-python@v5
with:
python-version: "3.12"
cache: "pip" # Caches ~/.cache/pip
Use secrets for sensitive values — never commit credentials:
env:
DATABASE_URL: ${{ secrets.DATABASE_URL }}
SECRET_KEY: ${{ secrets.DJANGO_SECRET_KEY }}
Matrix testing across Python versions:
strategy:
matrix:
python-version: ["3.10", "3.11", "3.12"]
Branch protection — require CI to pass before merging: - Settings → Branches → Add rule → Require status checks