Streamlining Development with Make, CI/CD, and GitHub Actions

A comprehensive guide to setting up automated workflows for Python projects using Make, CI/CD, and GitHub Actions
devops
python
automation
Published

April 9, 2024

Streamlining Development with Make, CI/CD, and GitHub Actions

Automation is key to maintaining code quality and ensuring consistent deployment processes. Here we explores how to set up a robust development workflow using Make, CI/CD pipelines, and GitHub Actions for Python projects.

Why Automate?

Before diving into the implementation, let’s understand why automation is crucial:

  • Consistency: Automated processes ensure that every team member follows the same steps
  • Quality: Automated testing and linting catch issues early
  • Speed: Reduce manual work and speed up development cycles
  • Reliability: Minimize human error in deployment processes

The Makefile: Your Development Swiss Army Knife

A Makefile serves as the central command hub for your project. Here’s a basic structure for a Python project:

.PHONY: install test lint format clean

# Install dependencies
install:
    pip install -r requirements.txt
    pip install -r requirements-dev.txt

# Run tests
test:
    pytest tests/

# Run linting
lint:
    black --check .
    isort --check-only .
    ruff check .

# Format code
format:
    black .
    isort .
    ruff check --fix .

# Clean up
clean:
    find . -type d -name "__pycache__" -exec rm -r {} +
    find . -type f -name "*.pyc" -delete
    rm -rf .pytest_cache/
    rm -rf .ruff_cache/

Setting Up GitHub Actions for CI/CD

GitHub Actions provides a powerful platform for automating your workflows. Let’s create a workflow that handles:

  1. Code formatting and linting
  2. Testing
  3. Documentation building
  4. Deployment

Here’s a sample workflow file:

name: CI/CD Pipeline

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

jobs:
  quality:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      
      - name: Set up Python
        uses: actions/setup-python@v4
        with:
          python-version: '3.10'
          
      - name: Install dependencies
        run: |
          python -m pip install --upgrade pip
          pip install -r requirements.txt
          pip install -r requirements-dev.txt
          
      - name: Run linting
        run: make lint
        
      - name: Run tests
        run: make test
        
      - name: Build documentation
        run: |
          pip install quarto
          quarto render
          
      - name: Deploy to GitHub Pages
        if: github.ref == 'refs/heads/main'
        uses: peaceiris/actions-gh-pages@v3
        with:
          github_token: ${{ secrets.GITHUB_TOKEN }}
          publish_dir: ./docs

Key Components of the CI/CD Pipeline

1. Code Quality Checks

  • Black: Python code formatter
  • isort: Import sorter
  • Ruff: Fast Python linter
  • mypy: Static type checker

2. Testing

  • pytest: Test framework
  • coverage: Test coverage reporting
  • tox: Test automation

3. Documentation

  • Quarto: Documentation generator
  • GitHub Pages: Documentation hosting

Best Practices

  1. Keep Makefiles Simple: Each target should do one thing well
  2. Use Matrix Testing: Test across multiple Python versions
  3. Cache Dependencies: Speed up CI/CD runs
  4. Fail Fast: Run quick checks first
  5. Security First: Never expose secrets in logs

Example Project Structure

project/
├── .github/
│   └── workflows/
│       └── ci-cd.yml
├── Makefile
├── requirements.txt
├── requirements-dev.txt
├── src/
│   └── project/
│       └── __init__.py
├── tests/
│   └── test_project.py
└── docs/
    └── index.qmd

Conclusion

Setting up a robust CI/CD pipeline with Make and GitHub Actions can significantly improve your development workflow. By automating repetitive tasks, you can focus on writing code while maintaining high quality standards.

Remember to: - Start small and iterate - Document your processes - Monitor pipeline performance - Keep security in mind - Regularly update dependencies

Further Reading