← Назад к вопросам

Какие шаги могут входить в процесс 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 обеспечивает высокое качество и скорость разработки.

Какие шаги могут входить в процесс CI? | PrepBro