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

Быстрые ссылки
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 в боковой панели проекта — это означает, что пайплайны включены.

Чтобы включить CI, откройте Settings → Visibility, project features, permissions и включите Pipelines. При использовании Merge Requests рекомендовано включить требование успешного пайплайна перед слиянием — это настраивается в разделе 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.json) со страницы пайплайна, чтобы изучить детали.
Использование в Merge Requests
GitLab автоматически отображает данные code quality в Merge Request, если job отдаёт артфакт в ожидаемом формате.

В MR откроется секция Code quality с числом найденных проблем и разворачиваемым списком. Исправьте ошибки, запушьте изменения — пайплайн перезапустится и статус обновится.
Типичный рабочий процесс (мини-методология)
- Разработчик создаёт ветку и локально запускает PHPStan.
- Пуш в ветку запускает пайплайн с PHPStan.
- Если PHPStan нашёл ошибки — MR блокируется до исправления.
- После исправления и прохождения пайплайна MR становится доступен для слияния.
Эта методология минимальна и легко масштабируется для команд любого размера.
Чек-листы по ролям
Разработчик:
- запустил PHPStan локально;
- поправил предупреждения уровня ошибки;
- обновил phpstan.neon при необходимости (и добавил объяснение в MR);
- написал тесты для новых функций.
Код-ревьюер:
- проверил, что новый код не вводит снижения качества по результатам PHPStan;
- подтвердил, что изменения в конфигурации phpstan.neon обоснованы;
- прогнал быстрый локальный анализ при сомнениях.
CI/DevOps:
- проверил Runner и Docker executor;
- настроил кеширование и квоты на артефакты;
- настроил уведомления о падениях критичных пайплайнов.
Стандартный playbook при падении PHPStan в MR
- Откройте MR и секцию Code quality.
- Просмотрите список ошибок и примеры кода.
- Локально исправьте проблемы или добавьте исключения в конфиг (только при обосновании).
- Запушьте изменения и дождитесь повторного успешного выполнения пайплайна.
- В случае сомнений — обсудите изменения в комментариях 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 при провале пайплайна и проводите постепенную жёсткую настройку уровней проверки.
Похожие материалы
Обновить Cube WP10 до Anniversary Update
Как проверить, запущен ли Docker daemon
Как запланировать твит в Twitter
docker cp — копирование файлов между хостом и контейнером
Копирование файлов по SSH без пароля