Проверки перед выкладкой - синтаксис, стандарт, тесты, миграции
Ставим автоматические проверки перед выкладкой: синтаксис, стандарт кода, тесты на копии базы, сборка и прогон миграций.
Механика
Проверки окупаются там, где выкладок много и людей больше одного. На проекте с одной правкой в месяц они лишние; на проекте с ежедневными выкладками они экономят больше времени, чем стоят.
Проверки различаются по цене, и выстраивают их по возрастанию. Синтаксис проверяется за секунды, стандарт кода - за десятки секунд, тесты - за минуты, а проверка интерфейса браузером измеряется уже десятками минут.
Проверяют только свой код проекта. Каталог платформы и чужие решения из каталога не ваши, их правила оформления другие, и их проверка превращает быструю задачу в многочасовую с сотнями бесполезных замечаний.
Тестам нужна база, и это главная сложность. Своя логика на платформе почти всегда обращается к инфоблокам, заказам и пользователям, поэтому под тесты поднимают копию базы, а не боевую.
Сборка фронтенда - это тоже проверка, ничем не хуже прогона тестов. Бандл должен собираться из чистого клона репозитория; сборка, которая получается только на машине одного разработчика, однажды не соберётся вовсе.
Миграции проверяют на копии, а применяют на выкладке. Прогон на свежей копии базы отвечает на вопрос, доедет ли выкладка до конца, до того как её начнут делать на боевом сайте.
Проверка обязана блокировать выкладку. Красный результат, который никого не останавливает, за месяц перестают читать, и дальше он показывает не состояние кода, а привычку его игнорировать.
Проверка интерфейса браузером - это крайний и самый дорогой уровень проверок. Она дорога в поддержке, поэтому её берут только на денежные сценарии: добавление в корзину, оформление заказа, вход в личный кабинет.
Шаги
- Проверять синтаксис изменённых файлов на каждом отправленном изменении.
- Прогонять стандарт кода только по каталогу проекта, без платформы.
- Поднимать копию базы и запускать на ней тесты своей логики.
- Собирать фронтенд из чистого клона репозитория, а не из рабочей копии.
- Прогонять миграции на копии базы до выкладки на боевой сайт.
- Останавливать выкладку при первом же красном результате проверки.
Код
Проверяем синтаксис изменённых файлов:
git diff --name-only origin/main...HEAD -- '*.php' | xargs -r -n1 php -l# проверка занимает секунды и ловит самую обидную ошибку - опечатку в скобках# на каждой отправке изменений её гоняют целиком, без всяких условийСинтаксис проверяют по изменённым файлам, а не по всему проекту. Разница принципиальная: первый вариант укладывается в секунды и работает на каждой отправке, второй - в минуты, и его начинают пропускать.
Держим в проверке только свой код:
vendor/bin/phpcs --standard=PSR12 --extensions=php \ local/php_interface local/modules local/templates# каталог платформы и чужие решения в проверку не берут никогда# правила фиксируют файлом настроек в репозитории, а не ключами в командеПравила оформления - предмет договорённости команды, а не спора о вкусах. Их фиксируют файлом настроек в репозитории, чтобы проверка на машине разработчика и проверка на сервере давали один результат.
Поднимаем копию базы для тестов:
mysql -e "DROP DATABASE IF EXISTS bitrix_ci; CREATE DATABASE bitrix_ci"gunzip < backup/nightly.sql.gz | mysql bitrix_ci# копия ночной резервной копии: свежая структура и обезличенные данныеmysql bitrix_ci -e "UPDATE b_user SET EMAIL = CONCAT('u', ID, '@example.org')"Тесты работают на копии, и это не перестраховка. Тест, создающий заказ или элемент инфоблока, на боевой базе оставляет мусор, а иногда и письмо покупателю с тестовым заказом.
Запускаем тесты своей логики:
BITRIX_DB=bitrix_ci vendor/bin/phpunit --testsuite local# набор тестов ограничен своим кодом: ядро платформы не тестируют# подъём ядра занимает секунды на каждый запуск: тесты гоняют наборомТесты пишут не на всё подряд, а на то, что ломается. Расчёт цены, разбор чужого формата, правила скидок и любой код с ветвлениями окупают тест первым же найденным расхождением, а вывод разметки - почти никогда.
Собираем фронтенд из чистого клона:
npm ci # именно ci: ставит ровно то, что записано в блокировкеnpx bitrix build# сборка, которая получается только у одного разработчика, однажды не соберётсяtest -s local/js/vendor/catalog/dist/catalog.bundle.js # результат обязан появитьсяУстановка по файлу блокировки версий - половина смысла этого шага. Она делает сборку повторяемой: на машине разработчика и на сервере проверки получается один и тот же результат, а не два похожих.
Прогоняем миграции на копии:
php local/tools/migrate.php up# журнал применённых миграций на копии свой: прогон идёт с нуля# упавшая здесь миграция не доедет до боевого сайта# после прогона копию базы удаляют: она нужна ровно на одну проверкуПрогон на копии ловит ровно ту ошибку, которую иначе находят в момент выкладки. Миграция, написанная под структуру стенда, падает на копии боевой базы, и лучше узнать об этом за день до релиза.
Собираем всё в один скрипт с кодом возврата:
#!/bin/shset -e # первая же неуспешная проверка останавливает остальныеsh ci/syntax.shsh ci/style.shsh ci/migrate.shsh ci/test.shecho "проверки пройдены"# скрипт выкладки запускают только после нулевого кода возврата этого файла# тот же файл запускают локально перед отправкой изменений в общую веткуКод возврата - это то, что связывает проверку с выкладкой. Скрипт выкладки запускается только после успешного завершения, и никакого другого способа заставить проверку работать не существует.
Ограничения
Автоматическая проверка не заменяет прохода по деньгам. Добавление в корзину, оформление и оплату проверяют руками перед крупными выкладками, потому что ошибка здесь стоит дороже всех остальных вместе взятых.
Тесты на платформе редко бывают по-настоящему быстрыми, и это стоит принять. Подъём ядра занимает секунды на каждый запуск, поэтому тесты пишут порциями по смыслу и запускают набором, а не по одному файлу.
На дешёвом хостинге автоматических проверок не будет вовсе, и это нормально. Пакетного менеджера и узловых пакетов там обычно нет, поэтому проверки гоняют на своей машине или на отдельном сервере, а на площадку приезжает готовый результат.
Проверка длиннее десяти минут перестаёт работать: её начинают обходить срочными выкладками. Её начинают обходить срочными выкладками, и через месяц она превращается в декорацию; медленные проверки уносят в ночной прогон.
Копия базы для проверок со временем неизбежно стареет и теряет актуальность. Проверка на копии полугодовой давности пропускает ошибки, связанные с реальными данными, поэтому копию обновляют по расписанию, а не когда вспомнят.
Проверка не даёт права выкладывать в пятницу вечером. Она уменьшает число ошибок, но не отменяет ни резервной копии, ни человека, который знает порядок отката.
Типичные проблемы
Проверка красная неделями, и все привыкли.
Результат проверки ничего не блокирует и не влияет на выкладку. Скрипт выкладки запускают только после успешного завершения проверок.
Проверка стандарта кода идёт часами.
В неё попал каталог платформы или чужие решения из каталога. Проверяют только каталог проекта со своим кодом, без платформы и чужих решений.
После тестов на боевом сайте появились тестовые заказы.
Тесты запускались на боевой базе. Под них поднимают копию из ночной резервной копии и работают только с ней.
Бандл собирается у одного разработчика и больше нигде.
Сборка зависит от локального состояния каталога пакетов. Проверка собирает фронтенд из чистого клона с установкой по блокировке версий.
Миграция упала прямо во время выкладки.
Её прогоняли только на стенде, где структура базы другая. Прогон на копии боевой базы делают до выкладки.
Проверка проходит, а сайт после выкладки не работает.
Проверки покрывают код, но не денежные сценарии целиком. Корзину, оформление и вход проходят руками перед крупными релизами.
Частые вопросы
С чего начать, если проверок нет вовсе?
С проверки синтаксиса изменённых файлов: она ставится за полчаса, работает секунды и сразу ловит опечатки. Всё остальное добавляют потом, по одной проверке за раз.
Где взять базу для тестов?
Из ночной резервной копии, развёрнутой в отдельную базу с обезличенными данными. Боевую базу под тесты не берут никогда: тестовые заказы и письма покупателям обходятся дороже любых тестов.
Нужно ли проверять код платформы?
Нет: он не ваш, его правила оформления другие, и замечания по нему бесполезны. В проверку берут каталог проекта, а если платформу всё-таки правили, это отдельная находка для разбора.
Что делать, если проверка идёт слишком долго?
Разделить её: быстрые проверки на каждую отправку, медленные - в ночной прогон. Проверка длиннее десяти минут перестаёт останавливать людей и превращается в декорацию.
Заменяют ли тесты ручную проверку перед релизом?
Нет. Они закрывают повторяющиеся ошибки в своём коде, но проход по корзине, оформлению и оплате руками перед крупной выкладкой остаётся обязательным.
Смежное
- Git и выкладка - оглавление подтемы
- Проверка кода перед релизом: чек-лист безопасности проекта - что смотрят глазами помимо автопроверок
- После выкладки сайт сломался: разбор причин - разбор, если проверки не помогли
- Выкладка на боевой: порядок, структура, откат - что происходит после зелёной проверки
- Миграции структуры: перенос инфоблоков и настроек между стендами - что прогоняют на копии базы
- Тесты для своего кода: что покрывать и как запускать - как устроены сами тесты
- Сборка фронтенда рядом с шаблоном: исходники, бандл, приложение - сборка как часть проверки
- Стандарты кода - что именно проверяет стандарт