Skip to content

CI/CD Integration

CI/CD runs your tests and checks automatically on every code change.


What Is CI/CD?

Term Meaning
CI (Continuous Integration) Automatically build and test code on every push
CD (Continuous Delivery) Automatically prepare code for release
CD (Continuous Deployment) Automatically deploy to production

Basic CI Pipeline

Every CI pipeline should include these steps:

1. Install dependencies
2. Run linters (ruff, mypy)
3. Run tests (pytest)
4. Check coverage
5. Generate reports

GitHub Actions Example

# .github/workflows/ci.yml
name: CI

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

jobs:
  test:
    runs-on: ubuntu-latest

    steps:
      - uses: actions/checkout@v4

      - name: Install uv
        uses: astral-sh/setup-uv@v4

      - name: Set up Python
        run: uv python install 3.12

      - name: Install dependencies
        run: uv sync

      - name: Run linter
        run: uv run ruff check .

      - name: Run type checker
        run: uv run mypy src/

      - name: Run tests
        run: uv run pytest --cov=src --cov-report=xml

      - name: Check coverage
        run: uv run pytest --cov=src --cov-fail-under=100

GitLab CI Example

# .gitlab-ci.yml
stages:
  - lint
  - test

variables:
  UV_SYSTEM_PYTHON: "true"

lint:
  stage: lint
  image: python:3.12
  script:
    - pip install uv
    - uv sync
    - uv run ruff check .
    - uv run mypy src/

test:
  stage: test
  image: python:3.12
  script:
    - pip install uv
    - uv sync
    - uv run pytest --cov=src --junitxml=report.xml
  artifacts:
    reports:
      junit: report.xml

Test Reporting

JUnit XML (Standard Format)

uv run pytest --junitxml=report.xml

Most CI systems can read JUnit XML and show test results in the UI.

Allure Reports

uv add --dev allure-pytest
uv run pytest --alluredir=allure-results

Allure creates rich HTML reports with:

  • Test history
  • Screenshots
  • Step-by-step logs
  • Trends

HTML Coverage Report

uv run pytest --cov=src --cov-report=html

This creates an htmlcov/ folder with a visual coverage report.


Pipeline Best Practices

Fail Fast

Put the fastest checks first:

1. Ruff (seconds)      → catches syntax and style issues
2. mypy (seconds)      → catches type errors
3. Unit tests (seconds) → catches logic bugs
4. Integration tests (minutes) → catches integration issues
5. E2E tests (minutes)  → catches user flow issues

Cache Dependencies

# GitHub Actions
- uses: actions/cache@v4
  with:
    path: ~/.cache/uv
    key: uv-${{ hashFiles('uv.lock') }}

Run on Every PR

  • Run all checks on every pull request
  • Block merge if any check fails
  • Keep pipeline under 10 minutes

Quality Gates

Set rules that must pass before code can be merged:

Gate Rule
Linting Zero ruff errors
Type checking Zero mypy errors
Tests All tests pass
Coverage >= 100% line coverage
No secrets No API keys in code

Best Practices

  • Run all checks on every pull request
  • Fail fast — put quick checks first
  • Cache dependencies to speed up pipelines
  • Keep pipelines under 10 minutes
  • Generate test reports (JUnit XML, Allure)
  • Set quality gates and enforce them
  • Use branch protection — require passing CI before merge
  • Run the same checks locally and in CI