A production-ready FastAPI template with robust CI/CD pipeline, semantic versioning, and best practices.
- FastAPI-based RESTful API with:
- QR code generation
- User registration with email validation
- Secure password hashing using bcrypt
- SQLite database (configurable for production)
- Poetry for dependency management
- Comprehensive CI/CD pipeline with GitHub Actions
- Optimized caching strategy for dependencies
- In-project Poetry virtual environments
- Poetry package cache
- Pip cache for Poetry installation
- Matrix testing with Python 3.11
- Automated dependency updates
- Optimized caching strategy for dependencies
- Robust code quality checks
- Black for code formatting
- Flake8 with advanced plugins:
- flake8-docstrings for docstring validation
- flake8-bugbear for bug detection
- flake8-comprehensions for optimization
- flake8-simplify for code simplification
- MyPy for static type checking
- Commitlint for commit message validation
- Pre-commit hooks for automated validation
- Semantic versioning with automated releases
- Automated changelog generation on main branch
- Structured logging with structlog
- Prometheus metrics integration
- Conventional Commits standard
- Pull Request based workflow
- Release automation on main branch
-
Create a Feature Branch
git checkout -b feature/your-feature # or fix/your-fix
-
Make Changes and Commit
# Stage changes git add . # Commit with conventional commit message git commit -m "feat(scope): add amazing feature" # or git commit -m "fix(scope): resolve specific issue"
-
Create Pull Request
git push origin feature/your-feature # Create PR to main branch via GitHub UI
-
Release Process
- Merging to main branch automatically:
- Updates CHANGELOG.md
- Creates a new release
- Updates version numbers
- Creates GitHub release with assets
- Merging to main branch automatically:
Follow the Angular Commit Message Convention:
<type>(<scope>): <description>
[optional body]
[optional footer]
Types:
- feat: A new feature (MINOR version bump)
- fix: A bug fix (PATCH version bump)
- docs: Documentation only changes
- style: Changes that do not affect the meaning of the code
- refactor: A code change that neither fixes a bug nor adds a feature
- perf: A code change that improves performance
- test: Adding missing tests or correcting existing tests
- build: Changes that affect the build system or external dependencies
- ci: Changes to our CI configuration files and scripts
- chore: Other changes that don't modify src or test files
Breaking Changes:
- Add
BREAKING CHANGE:
in the footer - Or append
!
after type/scope (e.g.,feat!:
orfeat(api)!:
) - Triggers a MAJOR version bump
Examples:
# Feature with scope
feat(auth): add OAuth2 authentication
# Bug fix with breaking change
fix!: remove deprecated API endpoints
BREAKING CHANGE: The /v1/api/* endpoints have been removed.
# Documentation update
docs(readme): update installation instructions
# Multiple-line description with scope
feat(api): improve error handling for REST endpoints
Implement better error messages and status codes
for all REST API endpoints.
Closes #123
Scope:
- Optional parentheses-enclosed identifier
- Indicates section of codebase (e.g., api, auth, core)
- Should be noun describing the section
Description:
- Imperative, present tense: "change" not "changed" nor "changes"
- Don't capitalize first letter
- No period (.) at the end
Body:
- Free-form
- Provide context and motivation for changes
- Use imperative, present tense
Footer:
- Reference issues being closed
- Note breaking changes
- Multiple footers allowed
- Format:
token: value
orBREAKING CHANGE: description
-
Install Dependencies
# Install Poetry curl -sSL https://install.python-poetry.org | python3 - # Install project dependencies poetry install # Install commitlint npm install -g @commitlint/cli @commitlint/config-conventional
-
Set up Pre-commit Hooks
poetry run pre-commit install poetry run pre-commit install --hook-type commit-msg
-
Configure GitHub Token
# Add to your environment export GH_TOKEN=your_github_pat_token
# Development server
poetry run uvicorn app.main:app --reload --log-level debug
# Production server
poetry run uvicorn app.main:app --host 0.0.0.0 --port 8000 --workers 4
curl -X POST "http://localhost:8000/api/v1/users/register" \
-H "Content-Type: application/json" \
-d '{
"email": "[email protected]",
"password": "StrongPass123!",
"full_name": "John Doe"
}'
Password requirements:
- Minimum 8 characters
- At least one uppercase letter
- At least one lowercase letter
- At least one number
- At least one special character
Response (201 Created):
{
"id": 1,
"email": "[email protected]",
"full_name": "John Doe"
}
curl -X POST "http://localhost:8000/api/v1/qr-code/generate" \
-H "Content-Type: application/json" \
-d '{
"url": "https://example.com",
"fill_color": "#000000",
"background_color": "#FFFFFF",
"box_size": 10,
"border": 4
}'
Required environment variables:
GH_TOKEN
: GitHub token for releasesLOG_LEVEL
: Logging level (debug/info/warning/error)PORT
: Application port (default: 8000)WORKERS
: Number of worker processes (default: 1)METRICS_ENABLED
: Enable/disable Prometheus metrics
- Fork the repository
- Create your feature branch
- Make changes following our commit conventions
- Create a Pull Request to main branch
- Ensure CI checks pass
- Wait for review and merge
For more detailed documentation, see:
- CHANGELOG.md for version history
- API Documentation when running locally
- GitHub Actions Workflows for CI/CD details
-
Create New Repository
- Click "Use this template" on GitHub
- Or clone and reinitialize:
git clone https://github.com/gsinghjay/fast-api-ci-cd cd fast-api-ci-cd rm -rf .git git init
-
Configure GitHub Repository
- Go to repository Settings β Branches β Add rule
- Protect
main
branch - Require pull request reviews
- Require status checks to pass
- Note: The workflows use
GITHUB_TOKEN
which is automatically provided by GitHub Actions
-
Update Configuration Files
- Update
pyproject.toml
:[tool.poetry] name = "your-project-name" version = "1.0.0" authors = ["Your Name <[email protected]>"]
- Update GitHub workflow files in
.github/workflows/
- Update repository URLs in documentation
- Update
# List recent workflow runs
gh run list --limit 5
# Watch a specific workflow run
gh run watch
# View workflow run details
gh run view --log
# List failed workflow runs
gh run list --status failed
# Download workflow artifacts
gh run download <run-id>
# View workflow in browser
gh run view --web
-
Release Creation Fails
- Check workflow permissions in repository settings
- Ensure commit messages follow convention
- Verify branch protection settings
- Check git configuration:
git config --list gh auth status
-
Changelog Not Updating
- Only updates on main branch merges
- Verify commit message format
- Check workflow logs for errors
- Ensure workflow has write permissions
-
Pre-commit Hooks Failing
- Update hooks:
pre-commit clean pre-commit autoupdate
- Check commit message format
- Run black manually:
poetry run black .
- Update hooks:
-
Workflow Permission Issues
- Repository Settings β Actions β General
- Enable "Allow GitHub Actions to create and approve pull requests"
- Check workflow permissions in yml files
- Ensure proper permissions are set in workflow files
This project follows Semantic Versioning 2.0.0 principles. Version numbers are structured as MAJOR.MINOR.PATCH:
- MAJOR version - Incremented for incompatible API changes
- MINOR version - Incremented for backward-compatible new functionality
- PATCH version - Incremented for backward-compatible bug fixes
Additional labels for pre-release and build metadata are available as extensions to the MAJOR.MINOR.PATCH format.
- Breaking changes (MAJOR):
BREAKING CHANGE:
in commit footer or!
after type/scope - New features (MINOR):
feat:
commit type - Bug fixes (PATCH):
fix:
commit type - No version bump:
chore:
,docs:
,style:
,refactor:
,perf:
,test:
We use Python Semantic Release for automated versioning and changelog generation. Key features:
- Automatic version bumping based on commit messages
- Changelog generation following Keep a Changelog format
- GitHub release creation and asset publishing
- Support for pre-releases and build metadata
Configuration in pyproject.toml
integrates our versioning and changelog standards:
[tool.python_semantic_release]
# Version Management
version_variables = ["app/__init__.py:__version__"] # Update version in code
version_toml = ["pyproject.toml:tool.poetry.version"] # Update version in pyproject.toml
version_source = ["tag", "commit"] # Determine version from tags and commits
major_on_zero = false # Follow SemVer for 0.x versions
tag_format = "v{version}" # Git tag format (e.g., v1.0.0)
# Commit Parsing
commit_parser = "conventional_commits" # Use Conventional Commits standard
commit_author = "github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>"
# Changelog Management
changelog_file = "CHANGELOG.md" # Keep a Changelog file
changelog_sections = [ # Keep a Changelog categories
"feature", # Maps to Added
"fix", # Maps to Fixed
"breaking", # Maps to Changed with breaking changes
"documentation",
"performance",
"refactor"
]
# Release Settings
upload_to_repository = false
build_command = "poetry build"
tag_type = "annotated" # Use annotated tags for better documentation
-
Semantic Versioning:
- Analyzes commit messages using Conventional Commits
- Automatically determines version bumps:
BREAKING CHANGE
β MAJORfeat:
β MINORfix:
β PATCH
- Creates appropriate Git tags
-
Keep a Changelog:
- Maintains CHANGELOG.md in the standard format
- Groups changes by type (Added, Changed, Fixed, etc.)
- Includes release dates and version links
- Keeps an Unreleased section for upcoming changes
- Links to Git comparisons between versions
# Check what the next version would be
poetry run semantic-release version --noop
# Create a new version (local only)
poetry run semantic-release version
# Create and publish a new release
poetry run semantic-release publish
Required environment variables:
GH_TOKEN
: GitHub Personal Access Token withrepo
scope- For fine-grained tokens:
contents
permission required
We follow the Keep a Changelog principles for maintaining our CHANGELOG.md. This ensures our changelog is:
- Written for humans, not machines
- Easy to link to any section
- One sub-section per version
- List releases in reverse-chronological order
- Include release date for each version
- Group changes by type
- Mention whether we follow Semantic Versioning
Added
- New featuresChanged
- Changes in existing functionalityDeprecated
- Soon-to-be removed featuresRemoved
- Now removed featuresFixed
- Any bug fixesSecurity
- In case of vulnerabilities
- Keep an
Unreleased
section at the top for tracking upcoming changes - Never use commit log diffs as changelog entries
- Always write clear, human-friendly descriptions
- Use ISO 8601 format for dates (YYYY-MM-DD)
- Make it clear when breaking changes occur
- Keep entries consistent and well-organized
- Link to issues, PRs, and other relevant information
## [1.0.0] - 2024-01-02
### Added
- New API endpoint for QR code generation
- Support for custom QR code colors
### Changed
- Improved error handling in API responses
- Updated dependencies to latest versions
### Fixed
- Issue with QR code size calculation
- Memory leak in image processing
[1.0.0]: https://github.com/username/project/compare/v0.9.0...v1.0.0
flowchart TD
subgraph "CI/CD Pipeline"
A[Push/PR] --> B{Event Type?}
B --> |PR/Push| C[Setup Python]
C --> D[Install Dependencies]
D --> E[Cache Environment]
E --> F[Lint Check]
E --> G[Test]
F & G --> H{All Checks Pass?}
H -->|No| I[Report Failure]
H -->|Yes & PR| J[Ready for Review]
H -->|Yes & Push to Main| K[Semantic Release]
K --> L[Generate Changelog]
L --> M[Create Release]
M --> N[Publish Assets]
subgraph "Skip Release Conditions"
S1[Skip if]
S2[Commit by github-actions]
S3["Message contains 'skip ci'"]
S4["Message has 'chore(release)'"]
S1 --> S2 & S3 & S4
end
end
classDef trigger fill:#90EE90
classDef setup fill:#FFE4B5
classDef check fill:#FFB6C1
classDef release fill:#ADD8E6
classDef skip fill:#D3D3D3
class A trigger
class C,D,E setup
class F,G,H check
class K,L,M,N release
class S1,S2,S3,S4 skip
-
CI Workflow (.github/workflows/ci.yml)
- Main orchestrator workflow
- Triggers on push to main and pull requests
- Controls the release process
- Uses reusable workflows for setup, lint, and test
-
Setup Workflow (.github/workflows/setup-python.yml)
- Sets up Python environment
- Installs and configures Poetry
- Creates and caches virtual environment
- Shares environment via artifacts
-
Lint Workflow (.github/workflows/lint.yml)
- Runs Black code formatter
- Validates commit messages with Commitlint
- Uses shared virtual environment
-
Test Workflow (.github/workflows/test.yml)
- Runs pytest with coverage
- Uses shared virtual environment
- Reports test results
-
Setup Phase:
- Initializes Python 3.11 environment
- Installs Poetry and dependencies
- Creates virtual environment
- Caches dependencies for speed
- Shares environment via artifacts
-
Parallel Checks:
- Lint and Test jobs run concurrently
- Both use the shared virtual environment
- All checks must pass to proceed
-
Release Phase (Main Branch Only):
- Triggered on push to main
- Uses python-semantic-release
- Updates CHANGELOG.md
- Creates GitHub release
- Publishes release assets
Workflow skips release when:
- Commit is from github-actions[bot]
- Commit message contains:
- [skip ci]
- chore(release)
- Event is a pull request
- Uses built-in GITHUB_TOKEN
- Minimal required permissions per job:
- Lint: read (contents, pull-requests)
- Test: read (contents), write (checks)
- Release: write (contents, id-token)
- Shared virtual environment via artifacts
- Poetry for dependency management
- Cached dependencies:
- Poetry virtual environment
- Pip cache
- Poetry package cache
- Preserved environment across jobs