Гид по технологиям

PHPStan в GitLab CI — запуск статического анализа

6 min read CI/CD Обновлено 28 Nov 2025
PHPStan в GitLab CI — запуск статического анализа
PHPStan в GitLab CI — запуск статического анализа

TL;DR

PHPStan позволяет находить ошибки в PHP-коде до запуска тестов и деплоя. Интегрируйте PHPStan в GitLab CI, чтобы блокировать слияния с ошибками и автоматически показывать отчёты в Merge Request. В статье — настройка, пример .gitlab-ci.yml, чек-листы и план внедрения.

Логотипы GitLab и PHPStan

Быстрые ссылки

  • Getting Setup with PHPStan

  • Configuring GitLab for CI

  • Creating a GitLab CI Pipeline

  • Using the Pipeline

  • Using with Merge Requests

  • Conclusion

Введение

Статический анализ кода экономит время, выявляя скрытые ошибки до выполнения. PHPStan — инструмент статического анализа для PHP, который повышает качество кода. Интеграция PHPStan в пайплайны GitLab CI гарантирует, что код с критическими ошибками не попадёт в основную ветку.

Запускать PHPStan полезно локально, но локальная дисциплина команды не всегда достаточна. CI-интеграция обеспечивает единый, автоматический контроль для всех MRs.

Установка и базовая конфигурация PHPStan

Сначала добавьте PHPStan в проект. Здесь кратко — для полной инструкции используйте официальную документацию PHPStan.

Установите через Composer:

composer require --dev phpstan/phpstan

Создайте простой файл конфигурации phpstan.neon в корне проекта. Пример базовой конфигурации:

parameters:
  level: max
  paths:
    - src
    - tests
  tmpDir: .tmp

Пояснения: level — уровень строгости (max означает максимальную проверку), paths — пути для анализа, tmpDir — временная директория. tmpDir переопределён для удобного кеширования в GitLab CI.

Проверьте работу локально:

vendor/bin/phpstan analyse

На этом этапе прохождение тестов не обязательно — важно убедиться, что конфигурация и запуск работают.

Подготовка GitLab для CI

Убедитесь, что код запушен в проект на GitLab. Проверьте, видна ли опция CI / CD в боковой панели проекта — это означает, что пайплайны включены.

Пункт меню Pipelines в GitLab

Чтобы включить CI, откройте Settings → Visibility, project features, permissions и включите Pipelines. При использовании Merge Requests рекомендовано включить требование успешного пайплайна перед слиянием — это настраивается в разделе Merge requests.

Включение Pipelines в настройках проекта

Включение обязательных пайплайнов для Merge Requests

GitLab Runner должен быть зарегистрирован на уровне инстанса, группы или проекта. Для запуска PHPStan в контейнере нам нужен Runner с Docker executor. В примере ниже мы используем официальный образ PHPStan из GitHub Container Registry.

Пример .gitlab-ci.yml

Разместите файл .gitlab-ci.yml в корне репозитория. Для простоты — один этап и одна job, которая запускает PHPStan и сохраняет результат в формате, совместимом с GitLab Code Quality.

stages:
  - phpstan

cache:
  key: "$CI_COMMIT_REF_SLUG"
  paths:
    - .tmp/
    - vendor/

phpstan:
  stage: phpstan
  image: ghcr.io/phpstan/phpstan
  script:
    - analyse --no-progress --error-format gitlab > phpstan.json
  artifacts:
    when: always
    reports:
      codequality: phpstan.json

Пояснения:

  • cache.key: используем slug ветки, чтобы кеш релевантно восстанавливался для отдельной ветки;
  • кешируем .tmp и vendor для ускорения последующих запусков;
  • официальный образ PHPStan сам установит зависимости, поэтому дополнительный composer install обычно не нужен;
  • опция –error-format gitlab генерирует JSON в формате, который GitLab распознаёт как отчёт о качестве кода; этот файл загружается как артефакт.

Использование пайплайна

Закоммитьте .gitlab-ci.yml и запушьте в репозиторий. Пайплайн должен запуститься автоматически. Страница CI / CD показывает прогресс.

Список пайплайнов с результатом PHPStan

Зелёная галочка означает, что PHPStan не нашёл проблем. Красный крест — найдены ошибки. Скачайте артефакт PHPStan (phpstan.json) со страницы пайплайна, чтобы изучить детали.

Использование в Merge Requests

GitLab автоматически отображает данные code quality в Merge Request, если job отдаёт артфакт в ожидаемом формате.

Виджет качества кода в Merge Request

В MR откроется секция Code quality с числом найденных проблем и разворачиваемым списком. Исправьте ошибки, запушьте изменения — пайплайн перезапустится и статус обновится.

Типичный рабочий процесс (мини-методология)

  1. Разработчик создаёт ветку и локально запускает PHPStan.
  2. Пуш в ветку запускает пайплайн с PHPStan.
  3. Если PHPStan нашёл ошибки — MR блокируется до исправления.
  4. После исправления и прохождения пайплайна MR становится доступен для слияния.

Эта методология минимальна и легко масштабируется для команд любого размера.

Чек-листы по ролям

Разработчик:

  • запустил PHPStan локально;
  • поправил предупреждения уровня ошибки;
  • обновил phpstan.neon при необходимости (и добавил объяснение в MR);
  • написал тесты для новых функций.

Код-ревьюер:

  • проверил, что новый код не вводит снижения качества по результатам PHPStan;
  • подтвердил, что изменения в конфигурации phpstan.neon обоснованы;
  • прогнал быстрый локальный анализ при сомнениях.

CI/DevOps:

  • проверил Runner и Docker executor;
  • настроил кеширование и квоты на артефакты;
  • настроил уведомления о падениях критичных пайплайнов.

Стандартный playbook при падении PHPStan в MR

  1. Откройте MR и секцию Code quality.
  2. Просмотрите список ошибок и примеры кода.
  3. Локально исправьте проблемы или добавьте исключения в конфиг (только при обосновании).
  4. Запушьте изменения и дождитесь повторного успешного выполнения пайплайна.
  5. В случае сомнений — обсудите изменения в комментариях MR.

Важно: избегайте массовых исключений уровней без review. Это снижает ценность анализа.

Частые ошибки и способы устранения

  • Ошибка: job зависает при запуске образа.
    • Проверьте доступ Runner к github container registry; если инстанс самоуправляемый, возможно нужен логин в registry.
  • Ошибка: отсутствуют зависимости vendor.
    • Официальный образ обычно устанавливает зависимости. Если ваш проект использует приватные пакеты, настройте auth для Composer (переменные CI/CD).
  • Ошибка: неподходящий tmpDir.
    • Убедитесь, что tmpDir в phpstan.neon совпадает с кешируемой директорией в .gitlab-ci.yml.

Когда PHPStan не даёт ожидаемой пользы (контрпримеры)

  • Очень динамичный код с интенсивным использованием магии (eval, динамические свойства) затрудняет статический анализ.
  • Если проект содержит много устаревшего кода, мгновенное возвышение уровня проверки на max породит лавину ошибок. Начинайте с более низкого уровня и постепенно повышайте.

Стратегии адаптации для разных зрелостей кода

  • Начальный уровень: включите PHPStan в CI, используйте уровень 0–4, исправляйте критические ошибки.
  • Средний уровень: повышайте уровень до 6–8, добавляйте проверки custom rules.
  • Высокий уровень: уровень max, строгие правила и автоматический blocking для MR.

Критерии приёмки

  • В CI настроен job phpstan, который создаёт артефакт codequality.
  • Merge Requests блокируются при провале пайплайна.
  • Ветка main содержит конфиг phpstan.neon и базовый уровень проверки, утверждённый командой.
  • Документация внутри репозитория описывает процесс локальной проверки и обходные пути.

Примеры шаблонов и сниппетов

Пример расширенного phpstan.neon для больших проектов:

parameters:
  level: 7
  paths:
    - src
    - tests
  excludes_analyse:
    - src/legacy/*
  tmpDir: .tmp
  checkMissingIterableValueType: true
  checkUnionTypes: true

Дополнительные сниппеты для .gitlab-ci.yml при приватных пакетах:

variables:
  COMPOSER_AUTH: '{"github-oauth":{"github.com":"$GITHUB_TOKEN"}}'

before_script:
  - composer config --global --auth github-oauth.github.com "$GITHUB_TOKEN"

Безопасность и приватность

PHPStan анализирует исходный код проекта. Он не собирает внешние пользовательские данные. Если пайплайн использует приватные токены (напр., для приватных пакетов), храните их в защищённых CI/CD переменных GitLab и не печатайте в логах.

Decision flowchart (упрощённый)

flowchart TD
  A[Push в ветку] --> B{Запуск пайплайна}
  B --> C[PHPStan job]
  C --> D{Ошибки найдены?}
  D -- Да --> E[Блокировка MR, показать ошибки]
  D -- Нет --> F[Разрешено слияние]
  E --> G[Разработчик исправляет]
  G --> B

Тесты и приёмка

Критерии приёмки для функции интеграции PHPStan в CI:

  • Отчёт phpstan.json появляется в артефактах job всегда.
  • GitLab корректно отображает Code quality в MR для тестового MR.
  • Для тестовых ошибок MR остаётся заблокированным до исправления.

Пример тест-кейса:

  • Создать MR, в котором добавлена функция с очевидной типовой ошибкой (напр., возвращаемый тип не соответствует аннотации).
  • Ожидаемый результат: PHPStan на пайплайне должен указать на ошибку, MR — быть заблокированным.

Миграция и совместимость

  • При миграции с другого CI учитывайте формат code quality отчётов. GitLab ожидает конкретную структуру JSON; используйте –error-format gitlab в PHPStan.
  • Для старых проектов постепенный подход (фиксирование на ветках, постепенное исправление) обычно эффективнее, чем резкое повышение уровня анализа.

Заключение

PHPStan в GitLab CI помогает убедиться, что в main не попадают скрытые ошибки. Правильно настроенный пайплайн и политика блокировки MR при провале повышают качество и надёжность кода. Начните с базовой интеграции и постепенно усиливайте правила по мере улучшения качества кода.

Важно: обсуждайте изменения конфигурации команды и документируйте оправдания для исключений.

Резюме

  • Интеграция PHPStan в GitLab CI делает статический анализ обязательным шагом в процессе разработки.
  • Используйте кеширование .tmp и vendor для ускорения пайплайнов.
  • Настройте блокировку MR при провале пайплайна и проводите постепенную жёсткую настройку уровней проверки.
Поделиться: X/Twitter Facebook LinkedIn Telegram
Автор
Редакция

Похожие материалы

Обновить Cube WP10 до Anniversary Update
Мобильные устройства

Обновить Cube WP10 до Anniversary Update

Как проверить, запущен ли Docker daemon
DevOps

Как проверить, запущен ли Docker daemon

Как запланировать твит в Twitter
соцсети

Как запланировать твит в Twitter

docker cp — копирование файлов между хостом и контейнером
Docker

docker cp — копирование файлов между хостом и контейнером

Копирование файлов по SSH без пароля
Сеть

Копирование файлов по SSH без пароля

Создайте собственные обои: от съёмки до готового фона
Фото

Создайте собственные обои: от съёмки до готового фона