Module 7: CI Integration with GitHub Actions
Module Project: A Working CI Pipeline
Module Project: A Working CI Pipeline
Project overview
You have tests that run locally. Now you're going to automate them. You'll configure a complete CI pipeline with GitHub Actions that runs your whole test suite on every push and PR, generates coverage reports, uses matrix testing for multiple Python versions, and blocks unsafe merges.
This project takes an existing repository (you can use any project from the previous modules) and adds professional CI to it. Claude Code helps you generate the workflow YAML based on your project's context.
Project Objective
Configure a working CI pipeline with GitHub Actions for a repository with tests.
By completing this project:
- ✅ Your repository will have a working
.github/workflows/tests.yml - ✅ The tests will run automatically on push and PR
- ✅ Matrix testing will validate on Python 3.10, 3.11, 3.12
- ✅ A coverage report will be published as an artifact
- ✅ pip caching will reduce build times
- ✅ Branch protection will block merges if the tests fail
Technical Specifications
Prerequisites
- A GitHub account
- A repository with at least 10 tests (you can use the project from any previous module)
- A
requirements.txtwith the dependencies
The Target Structure
your-project/
├── .github/
│ └── workflows/
│ └── tests.yml ← The pipeline (you create it)
├── src/ or module/ ← Your code
├── tests/ ← Your existing test suite
├── requirements.txt
├── pyproject.toml ← pytest and coverage configuration
└── README.md ← The CI badge
The Pipeline Step by Step
Step 1: A basic workflow
Create .github/workflows/tests.yml:
name: Tests
on:
push:
branches: [main]
pull_request:
branches: [main]
jobs:
test:
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 dependencies
run: |
python -m pip install --upgrade pip
pip install -r requirements.txt
- name: Run tests
run: pytest tests/ -v
Commit, push, and verify that it runs on GitHub.
Step 2: Add matrix testing
jobs:
test:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: ["3.10", "3.11", "3.12"]
steps:
- uses: actions/checkout@v4
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install -r requirements.txt
- name: Run tests
run: pytest tests/ -v
Step 3: Add caching
- name: Cache pip packages
uses: actions/cache@v4
with:
path: ~/.cache/pip
key: ${{ runner.os }}-pip-${{ hashFiles('requirements.txt') }}
restore-keys: |
${{ runner.os }}-pip-
Step 4: Add coverage
- name: Run tests with coverage
run: pytest tests/ -v --cov=src --cov-report=term-missing --cov-report=html
- name: Upload coverage report
uses: actions/upload-artifact@v4
with:
name: coverage-report-${{ matrix.python-version }}
path: htmlcov/
Step 5: pyproject.toml
[tool.pytest.ini_options]
testpaths = ["tests"]
addopts = "-v --tb=short"
[tool.coverage.run]
source = ["src"]
omit = ["tests/*"]
[tool.coverage.report]
fail_under = 85
show_missing = true
Step 6: A badge in the README

Step 7: Branch protection (manual on GitHub)
- Settings → Branches → Add rule
- Branch name pattern:
main - ✅ Require status checks to pass before merging
- ✅ Select the "test" job
- Save changes
Generating it with Claude Code
A prompt to generate the complete workflow:
Generate a GitHub Actions workflow (.github/workflows/tests.yml)
for my Python project.
Context:
- Tests in tests/ (unit, integration)
- Dependencies in requirements.txt
- Coverage with pytest-cov, target: ≥85%
- Python versions: 3.10, 3.11, 3.12
Include: matrix testing, pip caching, a coverage report as an artifact.
Success Criteria
Your project is complete when:
- ✅
git pushtriggers the workflow automatically - ✅ The tests run on 3 Python versions (matrix)
- ✅ The pipeline uses caching (verifiable in the logs: "Cache restored")
- ✅ A coverage report is generated as a downloadable artifact
- ✅ A push with a failing test → the pipeline fails (verifiable)
- ✅ The README has the CI badge
Evaluation Rubric (100 points)
A Working Workflow (35 points)
- (15 pts) The workflow runs pytest successfully in CI
- (10 pts) The triggers are configured (push and pull_request)
- (10 pts) Valid workflow YAML with no errors
Matrix and Caching (25 points)
- (15 pts) Matrix testing with at least 2 Python versions
- (10 pts) pip caching implemented
Coverage (20 points)
- (10 pts) A coverage report generated in CI
- (10 pts) The coverage report published as an artifact
Protection (10 points)
- (5 pts) The pipeline fails if the tests fail (verifiable with an intentional push)
- (5 pts) A CI badge in the README
Documentation (10 points)
- (5 pts) pyproject.toml with the pytest and coverage configuration
- (5 pts) The README explains how to run the tests locally and in CI
Extra Credit (up to +10 points)
- (+5 pts) Branch protection configured on GitHub
- (+5 pts) Separate jobs for unit, integration, and e2e tests
Common Mistakes
Mistake 1: The workflow doesn't run
Cause: The file isn't in .github/workflows/ exactly, or the YAML has indentation errors.
Solution: Verify the exact path and use a YAML validator. Check the "Actions" tab on GitHub to see the errors.
Mistake 2: The tests fail in CI but pass locally
Cause: Missing dependencies in requirements.txt, hardcoded paths, or missing environment variables.
Solution: Review the CI logs. Make sure requirements.txt has ALL the dependencies (including pytest, pytest-cov).
Mistake 3: The cache doesn't work
Cause: The cache key doesn't match (requirements.txt changed or isn't hashed correctly).
Solution: Verify that hashFiles('requirements.txt') points to the correct file. Check the logs: "Cache hit" vs "Cache miss".
Mistake 4: The coverage report isn't generated
Cause: pytest-cov isn't in requirements.txt or the --cov flag doesn't point to the correct module.
Solution: Add pytest-cov to requirements.txt and verify that --cov=src points to your source code.
Resources for the Project
- GitHub Actions Quickstart - A quick start
- actions/setup-python - Setting up Python in CI
- actions/cache - Caching dependencies
- actions/upload-artifact - Publishing artifacts
- GitHub Branch Protection - Branch protection
Connection with the Next Module
The CI you configured today is part of the final project:
- Module 8 (Capstone Project): The final application includes CI as part of the delivery
- The pipeline you built here gets reused directly for the final project
- You'll only need to adjust the paths and dependencies for the new application
You have professional CI. Every push, every PR, every merge is protected by your test suite. This is the industry standard.
Module 7, Capsule 06 — Testing with Claude Code Guide Your first professional CI pipeline