Непрерывная интеграция для PHP-проектов с помощью PHP Censor

В настоящий момент получила широкое распространение практика Continuous integration (CI) (а так же практики Continuous Deployment и Continuous Delivery, которые ей сопутствуют), которая позволяет запускать различные проверки кода и тесты автоматически. Тем самым гарантируется непрерывный контроль качества и работоспособности кода, в отличии от избирательных ручных запусков тестов и проверок.

Сервер непрерывной интеграции представляет собой приложение, которое воплощает в себе практическую реализацию этой практики и позволяет запускать проверки кода и тесты по предопределенным правилам: периодически или при попадании измененного кода в репозиторий.

Существует множество различных Continuous integration решений на разных языках, каждое из которых обладает собственными особенностями, а так же областью применения. К ним относятся такие решения, как: Travis CI, Jenkins, TeamCity, PHPCI и другие.

В данной статье я бы хотел рассказать про еще один CI-сервер, — PHP Censor. Это приложение является форком PHPCI, который уже довольно давно активно не развивается.

PHP Censor, так же как и его прародитель, является CI-сервером с открытым исходным кодом написанным на PHP для максимального облегчения сборки PHP-проектов. В частности, можно собрать проект, который вообще не имеет конфигурационного файла, в таком случае будет использован базовый набор плагинов, которые можно запустить с базовой конфигурацией (проверки на дубликаты в коде, проверки стиля кода, тесты и т.д.).

PHP Censor является self-hosted решением, то есть должно быть установлено самостоятельно на свой собственный сервер.

403bd5e01f0c8ab0beb5d5c47c25.png

Системные требования

2718ee0669e47313c11b00d6279d.png

Для того, чтобы развернуть свой инстанс PHP Censor необходим сервер (виртуальная машина или контейнер), соответствующий следущим требованиям:

  • Unix-подобная операционная система (Windows не поддерживается);
  • Доступен PHP 5.6+ (С поддержкой OpenSSL и включенными функциями: exec(), shell_exec() and proc_open());
  • Доступен веб-сервер (Nginx, Apache или любой другой);
  • Доступна база данных MySQL или PostgreSQL;
  • Доступна очередь Beanstalkd (Очередь необходима только, если вы запускаете сервер в режиме демона, запуск по крону не требует очереди);

Возможности

eb70b3d77d7af1d2d37a5d5d8bde.png

Ниже приведен краткий список возможностей PHP Censor-а:

  • Может получать исходные коды проектов из: Github, Bitbucket, Gitlab, Git, Mercurial, SVN или локальной директории;
  • Может запускать сборки по push-у/commit-у в репозиторий;
  • Может устанавливать и очищать тестовые БД для PostgreSQL, MySQL и SQLite;
  • Может устанавливать зависимости для проекта c помощью Composer-а;
  • Может запускать тесты для PHPUnit, Atoum, Behat, Codeception и PHPSpec;
  • Может проверять ваши исходные коды с помощью Lint, PHPParallelLint, Pdepend, PHPCodeSniffer, PHPCpd, PHPCsFixer, PHPDocblockChecker, PHPLoc, PHPMessDetect, PHPTalLint и TechnicalDept;
  • Может запускать другие доступные плагины, включая: Campfire, CleanBuild, CopyBuild, Deployer, Env, Git, Grunt, Gulp, PackageBuild, Phar, Phing, Shell и Wipe;
  • Может отправлять оповещения о сборке по различным каналам связи, включая: Email, XMPP, Slack, IRC, Flowdock, HipChat and Telegram;
  • Может авторизовывать пользователей через внешний LDAP-сервер;

Установка

Самый простой способ установить приложение, — это развернуть его в docker-контейнерах, используя репозиторий ket4yii/docker-php-censor.

Чтобы установить PHP Censor у себя на сервере вручную нужно выполнить следующую последовательность действий:

  • Получить последнюю версию дистрибутива PHP Censor можно несколькими способами. Проще всего загрузить приложение через Composer:
    
    cd /var/www
    composer create-project corpsee/php-censor php-censor.local --keep-vcs
    

    После выполнения этой команды в директории /var/www/php-censor.local появится последняя версия дистрибутива со всеми необходимыми зависимостями. Дистрибутив так же можно скачать вручную с релизной страницы на GitHub-е проекта, но тогда придется установить зависимости проекта самостоятельно с помощью Composer-а (Обычно команда для установки зависимостей выглядит примерно так: composer install).

  • Необходимо создать пустую БД (MySQL или PostgreSQL) и пользователя для работы с ней.
  • Необходимо запустить команду установки приложения, попутно отвечая на вопросы о подключении к БД, очереди и прочих конфигурационных данных:
    
    cd /var/www/php-censor.local
    ./bin/console php-censor:install
    
  • Далее необходимо настроить виртуальный хост приложения на сервере. Например, примерно так будет выглядеть конфигурация виртуального хоста php-censor.local для Nginx:
    
    server {
        listen *:80;
        server_name php-censor.local www.php-censor.local;
        root /home/corpsee/Projects/php-censor.local/public;
        access_log /home/corpsee/Projects/php-censor.local/runtime/nginx_access.log;
        error_log  /home/corpsee/Projects/php-censor.local/runtime/nginx_errors.log warn;
        location ~* \.(htm|html|xhtml|jpg|jpeg|gif|png|css|zip|tar|tgz|gz|rar|bz2|doc|xls|exe|pdf|ppt|wav|bmp|rtf|swf|ico|flv|txt|docx|xlsx)$ {
            error_page 404 405 502 504 500 = @fpm;
            expires    30d;
        }
        location / {
            try_files $uri @fpm;
        }
        location @fpm {
            fastcgi_pass  unix:/var/run/php/php7.0-fpm.sock;
            include fastcgi_params;
            fastcgi_index index.php;
            fastcgi_param SCRIPT_FILENAME $document_root/index.php;
            fastcgi_param SCRIPT_NAME index.php;
        }
    }
    
  • В завершение установки необходимо настроить запуск агента. У PHP Censor-а есть 2 типа агентов, — команда, которая запускается по расписанию и демон, который запущен постоянно. Crontab задание для запуска сборщика по расписанию будет выглядеть примерно так:
    
    SHELL=/bin/bash
    PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
    * * * * * flock -n /tmp/run-builds.lock --command '/path/to/php-censor/bin/console php-censor:run-builds'
    

Настройка проекта

3af68cef302979bdf1e7206fd88b.png

PHP Censor имеет декларативный стиль описания конфигурации проектов (используется формат YAML).

Файл конфигурации .php-censor.yml берется из корня репозитория проекта (или просто рабочей директории проекта, если речь идет о локальном источнике), так же есть возможность задать конфигурацию непосредственно в проекте при его создании (Конфигурация сборки, определенная через GUI имеет более высокий приоритет, чем конфигурация находящаяся в репозитории проекта. Это позволяет перекрывать конфигурацию из репозитория и использовать конфиденциальные данные в конфигурации).

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

Ниже небольшой пример файла конфигурации .php-censor.yml:


build_settings:
  ignore:
    - "vendor"
    - "tests"
setup:
  composer:
    action: "install"
test:
  php_unit:
    config:
      - "phpunit.xml"
  php_mess_detector:
    allow_failures: true
  php_cpd:
    allow_failures: true
  php_loc:
    allow_failures: true
  php_parallel_lint:
    allow_failures: true
branch-dev:
  run-option: replace
    test:
      php_unit:
        config:
          - "phpunit.dev.xml"

Файл конфигурации имеет несколько корневых раздела:

  • build_settings — настройки сборки проекта (игнорирование директорий, настройки подключения к базам данных);
  • setup — раздел инициализации сборки проекта (установка зависимостей, выполнение запросов к базам данных, миграции для баз данных);
  • test — раздел тестирования готовой сборки проекта (над сборкой проекта запускаются различные плагины, которые возвращают успешный или нет результат, провал, как правило, приводит к провалу сборки, хотя для отдельных плагинов это не так и можно установить количество ошибок, приводящих к провалу всей сборки);
  • complete — раздел, вызываемый системой после тестирования независимо от его результата;
  • success — раздел, вызываемый системой после тестирования только в случае успешной сборки и тестирования проекта;
  • failure — раздел, вызываемый системой после тестирования только в случае провала сборки или тестирования проекта;

Директива branch-name позволяет переопределять или дополнять основную конфигурацию сборки для отдельных веток. Параметр run-option может принимать следующие значения:

  • replace — позволяет перекрывать некоторые настройки для отдельных веток;
  • before — позволяет дополнить конфигурацию для конкретной ветки настройками, которые будут запущены до основной конфигурации;
  • after — позволяет дополнить конфигурацию для конкретной ветки настройками, которые будут запущены после основной конфигурации;

a4e6e6ba15a36af186b46407a158.png