← Назад к вопросам
Какие шаги могут входить в процесс CI?
2.0 Middle🔥 171 комментариев
#DevOps и инфраструктура
Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
Шаги в процессе CI (Continuous Integration)
CI - это практика автоматического тестирования и интеграции кода. Разберём полный процесс и лучшие практики.
1. Триггеры CI
# Процесс CI начинается когда:
# - Push в ветку (например, pull request)
# - Merge в main/develop
# - Tag создан
# - Нажата кнопка в UI (manual trigger)
# GitHub Actions пример
name: CI Pipeline
on:
push:
branches: [main, develop]
pull_request:
branches: [main, develop]
schedule:
- cron: '0 2 * * *' # Daily at 2 AM
jobs:
ci:
runs-on: ubuntu-latest
2. Обязательные шаги CI
A. Checkout и Setup
jobs:
ci:
runs-on: ubuntu-latest
steps:
# Шаг 1: Получить код
- uses: actions/checkout@v3
with:
fetch-depth: 0 # Полная история для diff
# Шаг 2: Настроить окружение
- uses: actions/setup-python@v4
with:
python-version: '3.11'
# Шаг 3: Кэшировать зависимости
- uses: actions/cache@v3
with:
path: ~/.cache/pip
key: ${{ runner.os }}-pip-${{ hashFiles('**/requirements.txt') }}
# Шаг 4: Установить зависимости
- run: pip install -r requirements.txt
B. Linting (Проверка стиля)
# Проверка PEP 8, форматирования и синтаксических ошибок
- name: Lint with ruff
run: |
ruff check .
ruff format --check .
- name: Type checking with mypy
run: mypy . --ignore-missing-imports
- name: Security check with bandit
run: bandit -r .
- name: Complexity check
run: radon cc . -a -nb
Пример конфига:
# pyproject.toml
[tool.ruff]
line-length = 100
target-version = "py311"
[tool.ruff.lint]
select = ["E", "F", "W", "I", "N", "D", "UP", "B"]
ignore = ["E501"] # Line too long (обрабатываем в formatter)
[tool.ruff.lint.isort]
known-first-party = ["myapp"]
[tool.mypy]
python_version = "3.11"
warn_return_any = true
warn_unused_configs = true
disallow_untyped_defs = true
C. Запуск тестов
# Юнит тесты
- name: Run unit tests
run: |
pytest tests/unit \
--cov=myapp \
--cov-report=xml \
--cov-report=html \
--cov-fail-under=90 \
-v
# Интеграционные тесты
- name: Run integration tests
run: pytest tests/integration -v
if: github.event_name == 'push' && github.ref == 'refs/heads/main'
# E2E тесты
- name: Run E2E tests
run: pytest tests/e2e -v
if: github.event_name == 'push' && github.ref == 'refs/heads/main'
Пример конфига pytest:
# pytest.ini
[pytest]
minversion = 7.0
addopts =
-ra
--strict-markers
--strict-config
--tb=short
--disable-warnings
testpaths = tests
python_files = test_*.py *_test.py
python_classes = Test*
python_functions = test_*
markers =
unit: Unit tests
integration: Integration tests
slow: Slow tests
db: Database tests
D. Покрытие кода (Code Coverage)
# Проверка покрытия
- name: Upload coverage reports
uses: codecov/codecov-action@v3
with:
files: ./coverage.xml
flags: unittests
fail_ci_if_error: true
verbose: true
# Коммент в PR с результатами
- name: Comment coverage
uses: py-cov-action/python-coverage-comment-action@v3
if: github.event_name == 'pull_request'
E. Сборка и запуск приложения
# Docker build
- name: Build Docker image
run: docker build -t myapp:${{ github.sha }} .
# Стартуем сервис (для интеграционных тестов)
- name: Start services
run: |
docker-compose up -d postgres redis
docker-compose exec -T postgres pg_isready -U postgres
# Проверяем что приложение запускается
- name: Check application startup
run: python -m myapp --help
F. Статический анализ
# Анализ зависимостей на уязвимости
- name: Check dependencies for vulnerabilities
run: |
pip install safety
safety check --json
# SonarQube анализ
- name: SonarCloud Scan
uses: SonarSource/sonarcloud-github-action@master
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
# SAST (Static Application Security Testing)
- name: Semgrep scan
uses: returntocorp/semgrep-action@v1
with:
config: >-
p/security-audit
p/python
G. Проверка документации
# Проверяем что все публичные функции документированы
- name: Check docstrings
run: |
interrogate -vv myapp -i -M -n
# Проверяем что документация компилируется
- name: Build documentation
run: |
cd docs
make clean html
H. Проверка миграций БД
# Убедиться что миграции работают
- name: Check database migrations
run: |
python manage.py migrate --check
# Проверяем что все миграции применяются
- name: Test migrations forward and backward
run: |
python manage.py migrate
python manage.py migrate zero
python manage.py migrate
3. Параллелизация для скорости
jobs:
# Запускаем разные проверки параллельно
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- run: ruff check .
- run: mypy . --ignore-missing-imports
test-unit:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- run: pytest tests/unit -v --cov
test-integration:
runs-on: ubuntu-latest
services:
postgres:
image: postgres:15
env:
POSTGRES_PASSWORD: postgres
steps:
- uses: actions/checkout@v3
- run: pytest tests/integration -v
security:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- run: safety check --json
- run: bandit -r .
# Ждём когда все завершатся
all-checks:
needs: [lint, test-unit, test-integration, security]
runs-on: ubuntu-latest
steps:
- run: echo "All checks passed!"
4. Матрица тестирования (для разных версий)
jobs:
test:
strategy:
matrix:
python-version: ['3.9', '3.10', '3.11', '3.12']
django-version: ['4.2', '5.0']
os: [ubuntu-latest, macos-latest, windows-latest]
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v3
- uses: actions/setup-python@v4
with:
python-version: ${{ matrix.python-version }}
- run: pip install Django==${{ matrix.django-version }}
- run: pytest tests/ -v
5. Уведомления и отчёты
# Отправить результаты в Slack
- name: Notify Slack on failure
if: failure()
uses: slackapi/slack-github-action@v1
with:
webhook-url: ${{ secrets.SLACK_WEBHOOK }}
payload: |
{
"text": "CI Pipeline Failed for ${{ github.repository }}",
"blocks": [
{
"type": "section",
"text": {
"type": "mrkdwn",
"text": "*CI Failed*\\n${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}"
}
}
]
}
# Создать issue если тесты падают
- name: Create issue on test failure
if: failure()
uses: actions/github-script@v6
with:
script: |
github.rest.issues.create({
owner: context.repo.owner,
repo: context.repo.repo,
title: `CI Pipeline Failed`,
body: `Failed run: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}`
})
6. Условные проверки (сэкономить время)
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
# Только для PR
- name: Run quick tests on PR
if: github.event_name == 'pull_request'
run: pytest tests/unit -v
# Только для main ветки
- name: Run full tests on main
if: github.ref == 'refs/heads/main'
run: pytest tests/ -v
# Если изменились файлы Python
- name: Run lint
if: |
github.event.pull_request.base.sha != '' &&
contains(github.event.pull_request.changed_files, '*.py')
run: ruff check .
7. Успешный полный pipeline
name: Complete CI/CD Pipeline
on:
push:
branches: [main, develop]
pull_request:
branches: [main, develop]
jobs:
# Stage 1: Быстрые проверки
quality:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-python@v4
with:
python-version: '3.11'
- run: pip install -r requirements-dev.txt
- run: ruff check .
- run: mypy . --ignore-missing-imports
- run: black --check .
# Stage 2: Тесты
test:
needs: quality
runs-on: ubuntu-latest
services:
postgres:
image: postgres:15
env:
POSTGRES_PASSWORD: postgres
steps:
- uses: actions/checkout@v3
- uses: actions/setup-python@v4
with:
python-version: '3.11'
- run: pip install -r requirements.txt
- run: pytest --cov=myapp --cov-report=xml
- uses: codecov/codecov-action@v3
# Stage 3: Безопасность
security:
needs: quality
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- run: pip install safety bandit
- run: safety check --json
- run: bandit -r .
# Stage 4: Сборка
build:
needs: [test, security]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- run: docker build -t myapp:${{ github.sha }} .
- run: docker save myapp:${{ github.sha }} > image.tar
- uses: actions/upload-artifact@v3
with:
name: docker-image
path: image.tar
# Stage 5: Уведомления
notify:
needs: build
if: always()
runs-on: ubuntu-latest
steps:
- name: Send Slack notification
run: |
echo "CI Pipeline completed: ${{ job.status }}"
8. Рекомендуемое минимальное покрытие
- Тесты: 90%+ покрытия кода
- Linting: 0 ошибок
- Type checking: strict mode
- Security: 0 известных уязвимостей
- Performance: не медленнее чем в main
Полный, хорошо настроенный CI pipeline обеспечивает высокое качество и скорость разработки.