GitHub Actions CI/CD Pipeline for a Python Project

In modern software development, manually running test suites, checking code formatting, and deploying releases is inefficient and error-prone. **Continuous Integration and Continuous Deployment (CI/CD)** automate these repetitive steps, ensuring that every git commit is tested, verified, and safely pushed to production.

With **GitHub Actions** built directly into GitHub repositories, setting up powerful CI/CD workflows no longer requires third-party platforms like Jenkins or Travis CI. This comprehensive guide walks you through building a robust GitHub Actions workflow for a Python project that runs lint checks, executes pytest test suites, and automates package publishing.

1. Understanding GitHub Actions Architecture

GitHub Actions workflows are defined in YAML files located inside `.github/workflows/`. Key components include:

  • Workflows: Automated procedures defined by `.yml` files that run one or more jobs.
  • Events: Specific triggers that initiate workflow execution (e.g., `push` to `main`, pull requests, or scheduled cron triggers).
  • Jobs: Sets of steps executed on the same virtual runner machine (e.g., `ubuntu-latest`).
  • Steps: Individual tasks or shell commands executed within a job, such as checking out code or running test scripts.

2. Writing the CI/CD Pipeline Configuration

Create a file named `ci-cd.yml` inside your repository's `.github/workflows/` directory to orchestrate linting, testing, and building.

C
name: Python CI/CD Pipeline

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

jobs:
  test:
    runs-on: ubuntu-latest
    strategy:
      matrix:
        python-version: ["3.9", "3.10", "3.11", "3.12"]

    steps:
    - name: Checkout Repository
      uses: actions/checkout@v4

    - name: Set up Python ${ { matrix.python-version } }
      uses: actions/setup-python@v5
      with:
        python-version: '${ { matrix.python-version } }'
        cache: 'pip'

    - name: Install Dependencies
      run: |
        python -m pip install --upgrade pip
        pip install flake8 pytest
        if [ -f requirements.txt ]; then pip install -r requirements.txt; fi

    - name: Lint with Flake8
      run: |
        # Stop the build if there are Python syntax errors or undefined names
        flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics
        # Exit-zero treats all errors as warnings
        flake8 . --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics

    - name: Test with Pytest
      run: |
        pytest

Conclusion

Automating Python testing and code quality checks with GitHub Actions gives engineering teams instant feedback on pull requests and guarantees that only verified code reaches production. By leveraging matrix builds across multiple Python versions, developers can ensure complete cross-version compatibility effortlessly.