Automated code quality checks before commits. Use before committing code, when finishing a feature, or when user mentions "ready to commit" or "quality check".
Content & Writing
73 Stars
14 Forks
Updated Jan 8, 2026, 03:16 PM
Why Use This
This skill provides specialized capabilities for Afaneor's codebase.
Use Cases
Developing new features in the Afaneor repository
Refactoring existing code to follow Afaneor standards
Understanding and working with Afaneor's codebase structure
---
name: code-quality-gate
description: Automated code quality checks before commits. Use before committing code, when finishing a feature, or when user mentions "ready to commit" or "quality check".
allowed-tools: Bash(poetry:*, ruff:*, pytest:*)
hooks:
Stop:
- matcher: ""
hooks:
- type: command
command: "poetry run ruff format . && poetry run ruff check . && poetry run pytest tests/ -v"
---
# Code Quality Gate
## 5-Stage Quality Pipeline
Before ANY commit, code must pass ALL stages. No exceptions.
### Stage 1: Code Formatting (Ruff Format)
```bash
poetry run ruff format .
```
**What it checks:**
- Consistent code style (PEP 8 compliant)
- Line length (88 characters by default)
- Imports formatting
- Trailing whitespace
**Action:** Auto-fixes issues. Re-run if changes were made.
### Stage 2: Linting (Ruff Check)
```bash
poetry run ruff check . --fix
```
**What it checks:**
- Unused imports and variables
- Code smells and anti-patterns
- Security issues (hardcoded secrets, SQL injection)
- Complexity issues
- Missing docstrings
**Action:** Auto-fixes when possible. Manual fixes required for some issues.
### Stage 3: Type Checking (MyPy) - Optional
```bash
poetry run mypy app/ --ignore-missing-imports || true
```
**What it checks:**
- Type hint correctness
- Return type mismatches
- Argument type errors
- None-safety violations
**Action:** Fix type errors. Use `# type: ignore` only as last resort with comment explaining why.
### Stage 4: Tests (Pytest)
```bash
poetry run pytest tests/ -v --maxfail=1
```
**What it checks:**
- All tests pass
- No test failures
- No test errors
**Action:** Fix failing tests. Never skip tests.
### Stage 5: Import Sorting
```bash
poetry run ruff check . --select I --fix
```
**What it checks:**
- Import order (stdlib → third-party → local)
- Import grouping
- Unused imports
**Action:** Auto-fixes import order.
## Full Quality Gate Command
Run all stages in sequence:
```bash
poetry run ruff format . && \
poetry run ruff check . --fix && \
poetry run pytest tests/ -v && \
echo "✅ All quality checks passed!"
```
## When to Run Quality Gates
### 1. Before Every Commit
```bash
# Before git commit
./run_quality_gate.sh
git add .
git commit -m "feat: add user endpoint"
```
### 2. After Major Refactoring
```bash
# After large code changes
poetry run pytest tests/ -v --cov=app --cov-report=html
```
### 3. Before Pull Request
```bash
# Full comprehensive check
poetry run ruff check . --statistics
poetry run pytest tests/ -v --cov=app --cov-report=term-missing
```
## What to Do When Checks Fail
### Ruff Format Failures
If `ruff format` makes changes:
```bash
poetry run ruff format .
git add . # Stage formatted files
```
### Ruff Check Failures
Read error messages carefully:
```
app/api/users.py:45:5: F401 'User' imported but unused
```
Fix the issue:
```python
# Remove unused import
# from models import User ← Remove this
```
### Pytest Failures
```
FAILED tests/test_users.py::test_get_user - AssertionError: ...
```
Debug and fix:
```bash
# Run specific test with output
poetry run pytest tests/test_users.py::test_get_user -v -s
```
### Type Check Failures (MyPy)
```
app/api/users.py:45: error: Incompatible return value type
```
Fix type annotations:
```python
# Before (wrong)
def get_user(id) -> User:
return None # Error: None is not User!
# After (correct)
def get_user(id: int) -> User | None:
return None # OK: None is allowed
```
## Coverage Requirements
Maintain minimum test coverage:
- **Overall coverage:** 80%+
- **New code coverage:** 90%+
- **Critical paths:** 100% (auth, payments, etc.)
Check coverage:
```bash
poetry run pytest tests/ --cov=app --cov-report=term-missing
```
## Emergency Bypass (Use Sparingly!)
In rare cases when quality gate blocks urgent fixes:
```bash
# Skip only specific check
poetry run ruff check . --ignore E501 # Ignore line length
# Or commit with --no-verify (DOCUMENT WHY!)
git commit -m "hotfix: critical bug" --no-verify
```
**Rules for bypass:**
1. Document reason in commit message
2. Create follow-up issue to fix properly
3. Never bypass tests
4. Get team approval for production
## Quality Gate Success Criteria
All of these must be true:
- ✅ `ruff format .` makes zero changes
- ✅ `ruff check .` returns zero errors
- ✅ `mypy app/` returns zero errors (if enabled)
- ✅ `pytest tests/` all tests pass
- ✅ Test coverage ≥ 80%
## Troubleshooting
### "Command not found: ruff"
```bash
poetry install # Install dependencies first
```
### "No tests collected"
```bash
# Check test file naming
# Must be: test_*.py or *_test.py
ls tests/
```
### "Import errors in tests"
```bash
# Set PYTHONPATH
export PYTHONPATH="${PYTHONPATH}:$(pwd)"
poetry run pytest tests/
```
### Slow tests
```bash
# Run in parallel
poetry run pytest tests/ -n auto
# Run only fast tests
poetry run pytest tests/ -m "not slow"
```
## Pre-commit Hook Setup (Optional)
Create `.git/hooks/pre-commit`:
```bash
#!/bin/bash
echo "Running quality gate..."
poetry run ruff format .
poetry run ruff check . --fix
poetry run pytest tests/ -v --maxfail=1
if [ $? -ne 0 ]; then
echo "❌ Quality gate failed. Commit blocked."
exit 1
fi
echo "✅ Quality gate passed!"
```
Make it executable:
```bash
chmod +x .git/hooks/pre-commit
```
## Integration with CI/CD
Quality gate should also run in CI:
```yaml
# .github/workflows/quality.yml
name: Quality Gate
on: [push, pull_request]
jobs:
quality:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- run: poetry install
- run: poetry run ruff format . --check
- run: poetry run ruff check .
- run: poetry run pytest tests/ --cov=app
```
## Remember
**Quality gate is not optional.** It's the foundation of production-ready code.
No shortcuts. No bypasses. No "I'll fix it later."
✅ Write code → Run quality gate → Fix issues → Commit → Repeat