CI/CD Documentation
October 21, 2025 · View on GitHub
This document describes the Continuous Integration and Continuous Deployment (CI/CD) pipelines for the docbt project.
Overview
The project uses GitHub Actions for CI/CD with two main workflows:
- CI Workflow (
ci.yml) - Runs on every pull request and push - Release Workflow (
release.yml) - Manual workflow for releasing to PyPI and Docker registries
CI Workflow
The CI workflow runs automatically on pull requests and pushes to main and develop branches.
Jobs
1. Lint with Ruff
- Purpose: Check code quality and formatting
- Steps:
- Check code formatting with
ruff format --check - Run linter with
ruff check
- Check code formatting with
- Python Version: 3.10
2. Test with pytest
- Purpose: Run unit and integration tests
- Matrix: Tests run on Python 3.10, 3.11, and 3.12
- Steps:
- Install package with all optional dependencies
- Run pytest with coverage
- Upload coverage report to Codecov (Python 3.10 only)
- Coverage: Generates XML and terminal coverage reports
3. Build Python Package
- Purpose: Ensure the package can be built successfully
- Steps:
- Build source distribution and wheel using
uv build - Validate package with
twine check - Upload artifacts for inspection
- Build source distribution and wheel using
- Artifacts: Available for 7 days
4. Build Docker Images
- Purpose: Ensure Docker images can be built successfully
- Targets Built:
base- Minimal image with core dependenciesproduction- Full image with all provider dependenciesdevelopment- Development image with dev tools
- Features:
- Uses BuildKit for efficient caching
- GitHub Actions cache for faster builds
- Multi-stage builds
Status Check
All jobs must pass for the PR to be mergeable. The all-checks-passed job provides a single status check.
Release Workflow
The release workflow is manually triggered from the GitHub Actions tab and should only be run from the main branch.
Inputs
| Input | Description | Required | Default |
|---|---|---|---|
version | Version to release (semver format, e.g., 0.1.0) | Yes | - |
release_pypi | Whether to release to PyPI | Yes | true |
release_docker | Whether to release Docker images | Yes | true |
docker_registry | Docker registry to use | No | ghcr.io |
Jobs
1. Validate Release
- Ensures release is from
mainbranch - Validates version format (semver)
2. Release to PyPI
- Updates version in
pyproject.toml - Builds the package
- Publishes to PyPI using trusted publishing
- Environment:
pypi(requires approval) - Requires: PyPI trusted publisher configured
3. Release Docker Images
- Builds and pushes Docker images to registry
- Creates multi-platform images (amd64, arm64)
- Tags images with:
- Specific version (e.g.,
0.1.0) - Major.minor version (e.g.,
0.1) - Major version (e.g.,
0) latest
- Specific version (e.g.,
- Environment:
docker-registry(requires approval) - Registries Supported:
- GitHub Container Registry (
ghcr.io) - usesGITHUB_TOKEN - Docker Hub (
docker.io) - requiresDOCKERHUB_USERNAMEandDOCKERHUB_TOKENsecrets
- GitHub Container Registry (
4. Create GitHub Release
- Creates a Git tag
- Creates a GitHub release with release notes
- Links to PyPI and Docker Hub
Setup Requirements
PyPI Publishing
For trusted publishing on PyPI:
- Go to your PyPI project settings
- Add a new "trusted publisher"
- Configure:
- Owner:
aleenprd - Repository:
docbt - Workflow:
release.yml - Environment:
pypi
- Owner:
Docker Hub Publishing
If using Docker Hub, add these secrets to your repository:
DOCKERHUB_USERNAME: Your Docker Hub usernameDOCKERHUB_TOKEN: Docker Hub access token
GitHub Environments
Create these environments in your repository settings:
-
pypi
- Add protection rules (recommended: require reviewers)
- No secrets needed (uses trusted publishing)
-
docker-registry
- Add protection rules (recommended: require reviewers)
- Add
DOCKERHUB_USERNAMEandDOCKERHUB_TOKENif using Docker Hub
Usage
Running CI
CI runs automatically. To test locally:
# Lint
ruff format --check .
ruff check .
# Test
pytest --cov=src/docbt --cov-report=term
# Build package
uv build
# Build Docker images
docker build --target base -t docbt:base .
docker build --target production -t docbt:production .
docker build --target development -t docbt:development .
Creating a Release
- Ensure all changes are merged to
main - Go to Actions → Release → Run workflow
- Enter the version number (e.g.,
0.1.0) - Choose whether to release to PyPI and/or Docker
- Select the Docker registry if applicable
- Click "Run workflow"
- Approve the release in the environments (if configured)
Post-Release
After a successful release:
- Update
CHANGELOG.mdwith release notes - Create a PR to bump the version in
pyproject.tomlfor the next development cycle - Announce the release
Troubleshooting
CI Failures
- Ruff failures: Run
ruff format .to auto-fix formatting - Test failures: Run
pytest -vlocally to debug - Build failures: Check
pyproject.tomldependencies
Release Failures
- PyPI upload fails: Check trusted publisher configuration
- Docker push fails: Verify registry credentials and permissions
- Version conflict: Ensure version doesn't already exist
Best Practices
- Always run tests locally before pushing
- Keep the main branch stable - only merge tested code
- Use semantic versioning for releases
- Document breaking changes in release notes
- Test Docker images locally before releasing
- Review dependency updates carefully