Я прочитал достаточно теории и вроде как понял суть CI. Необходимо оптимально настроить автоматический билд приложения чтобы побыстрее пресечь различного рода ошибки при частой интеграции. Какой еще build для PHP? Насколько я знаю никаких билдов нету. Зачем запускаются разные phploc и прочие программы которые просто возвращают размер проекта. Зачем запускать эти CI сервера? Чем они помогают (в контексте PHP)? Автоматически запускают команды просто?
Ответ
Постоянная интеграция призвана решать много проблем сразу:
Исключение человеческого фактора из повторяемых процессов, и, собственно, повторяемость и воспроизводимость этих процессов. Если разработчик может случайно вывалить на продакшен конкретную версию приложения со своими изменениями или забыть в исправленный код отдельной ветке, то постоянная интеграция не дает разработчику это сделать - она устанавливает набор правил и позволяет разработчику пропустить через эти правила свой код, чтобы дать добро на выкладку или отрицательный фидбэк в связи с ошибкой.
Предыдущий пункт выливается в то, что постоянная интеграция не способна забыть какие-либо вещи. В то время как в голове у разработчика умещаются плюс-минус последние две недели, интеграция будет сообщать о проблеме все то время, пока проблема существует.
Тестирование (с которого, как правило, она начинается). Пока код выкладывается на продакшен без тестирования, никто не может сказать, работает ли он.
Превращение кодовой базы в артефакт. Кодовая база - это просто текстовые файлы, артефакт - это готовое к работе приложение. В случае с PHP разница между двумя состояниями может быть минимальна и незаметна, но если вы, например, делаете phar-приложение, то непосредственно подготовкой этого phar-архива будет заниматься CI-сервер. Разработчик может несколько раз за день собирать этот архив, но финальную версию собирает машина, и именно она дает гарантии работоспособности архива.
Автоматизацию процесса релиза проекта до одной кнопки. Разница с предыдущем пунктом тоже может быть не очень хорошо заметна, но артефакт - это просто какая-то сборка приложения, в то время как релиз - это конкретная версия приложения с каким-то функционалом. Сборка артефакта и прогонка тестов гарантируют, что приложение работает, но такой артефакт не обязательно содержит в себе весь функционал, который можно выложить, это может быть промежуточная версия - так, если руководитель запланировал в следующей версии веб-сайта новую админку и интеграцию с какой-нибудь соцсетью, то промежуточный артефакт может содержать что-то одно, а в релиз уходит только такой артефакт, который содержит все запланированное. Кроме того (!sic), релиз может состоять и из нескольких артефактов.
Сам по себе релиз может быть и автоматическим.
Полную автоматизацию процесса от выкладки кода в репозитории до выкладки артефактов в продакшен; в отличие от предыдущего пункта, человек полностью исключается из всей цепочки, а каждая успешная сборка автоматом становится релизом.
Дополнительные артефакты, такие, как автоматическая документация (пресловутый PHPDoc), подписи артефактов (чтобы конечный получатель мог убедиться в том, что информация о сборке артефактов соотстветствует действительности).
Дополнительный анализ кода. Тесты - это хорошо, но они говорят исключительно то, работает ли тот код, который был протестирован; они ничего не говорят о том, сколько кода было протестировано и насколько хорош этот код. Поэтому интеграция может включать в себя еще и дополнительные отчеты, например:
Общее покрытие кода тестами (e.g. 65% кода покрыто)
Отчет о покрытии конкретных файлов, строк, логических ветвей и выражений. Здесь начинается самая мякотка, которая может выглядеть вот так - вы просто физически видите, какие строки и в каких тестах были покрыты. Более того, такие отчеты отлично интегрируются с IDE, что позволяет вам отслеживать подобные штуки на своей машине (оставляя CI для мониторинга общего тренда - покрытие растет или падает)
Человекочитаемые отчеты о тестах. Когда вы тестируете код, вы формализуете проблему до сравнения реального результат с желаемым, и ошибка 'Failed asserting that 42 is true' или 'Failed asserting that server returned 200' вам ничего не скажет. Однако есть специальные фреймворки, позволяющие вам сгенерировать еще более вкусную мякотку с человеческими описаниями тестами (что мы тестируем? почему появился этот тест? что происходило во время теста? какой use-case проверяется в ходе этого теста?), прикладывать к ним аттачменты, мерять скорость выполнения тестов (если какой-то из них подвисает, то хорошо знать какой, верно? этакий test-insght). Конкретно сейчас я описываю мой любимый allure, но кроме него наверняка есть еще непочатый край утилит. Не пожалейте времени, сходите по ссылке - представляете, насколько вы упростите жизнь в сложном проекте, если к каждому проваленному тесту будет прилагаться (sic!) скриншот страницы, на которой не удалось совершить ожидаемые действия, список шагов, которые должны были быдь пройдены в тесте, конкретный браузер, в котором появились проблемы, и, наконец, какая-нибудь несмешная шутка?
Отчеты о статическом анализе кода. Это очередная мякотка, которая надает вам по рукам, если вы строите слишком сложные циклы или пишете нечитаемый код. В то время как анализ реализации логики - это AI-complete задача (после решения которой программисты не очень и нужны, потому что логику может писать сама система), анализ правильно расставленных отступов, повторяемого кода и количества комментариев - это вполне разрешимая задача. Чтобы еще раз впечатлить вас, оставлю очередную ссылку, а чуть позже вернусь к этой теме.
Автоматические ченджлоги и отчеты о вкладе команды в проект. Это уже очень специфичная и сложная тема, которой я не касался.
Нагрузочное и прочее тестирование, приближенное к реальной жизни и не тестирующее код напрямую (в нетфликсе, например, не пропускают релизы, которые по показателям производительности хуже предыдущих и намеренно убивают серверы, чтобы проверить жизнеспособность системы в критических ситуациях). Если нас интересует конечный продукт, то почему бы не автоматизировать еще и проверку того, что он будет соответствовать нашим ожиданиям скорости?
Проверку возможности слияния двух источников кода до реального слияния
И, наконец, постоянная интеграция легко интегрируется (pun intended) с различными способами оповещения разработчиков. Следить за процессом билда - утомительное и ненужное дело, поэтому постоянную интеграцию можно настроить на уведомление только в тех случаях, когда изменения что-то ломают; в этом случае молчание системы автоматически означает, что либо все работает, либо интеграция тупо сдохла (это решается мониторингом, который я не буду здесь затрагивать).
Весь набор задач - создать артефакт, прогнать тесты, прогнать анализ - называется пайплайном, а однократное прохождение кодом пайплайна - билдом. Билд - это сам факт прохождения кодом постоянной интеграции, результатом которого могут быть вышеописанные артефакты и отчеты.
Как это все помогает проекту? Представим, что у нас есть некоторый виртуально-бесконечный проект с гигантским числом разработчиков, которых невозможно контролировать физически. Если у вас нет вышеописанного пайплайна, у вас нет возможности заглянуть в код и оценить состояние текущей кодовой базы, технического долга и вклада разработчиков в проект. На маленьких проектах это может настолько же виртуально-бесконечно не стрелять в ногу, но в случае с большим проектом это уже не прокатит, потому что начинают появляться следующие ситуации:
В продакшен ушел битый релиз с багами. В ходе разработки новых фич разработчики затронули старый код и все сломали. Кто виноват? Кто внес баг? Кто пропустил этот баг?
Разработчики говорят, что нужен срочный рефакторинг. Как оценить, насколько он нужен, как расставить приоритеты при рефакторинге, где находятся наиболее горячие места?
Разработчики говорят, что проект недопокрыт тестами и грозятся рисками выкатки нерабочего релиза. Как определить, правда ли это?
Разработчики говорят, что у нас в целом ухудшается кодовая база. Опять клянчат рефакторинг, или все действительно идет по наклонной?
Другие ситуации, для которых иссякла моя фантазия
Суммируя все вышенаписанное, CI дает вам возможность автоматизировать все рутинные процессы, перенести основные задачи тестирования на машину, нормализовать диалог между менеджерами / разработчиками / отделом качества продукта и проанализировать кодовую базу буквально что изнутри. Пока у вас нет этой штуки, вы не знаете, в каком состоянии текущий продукт, поэтому берете на себя все риски выпуска нерабочего продукта, внезапно открывшейся необходимости рефакторинга, траты времени на бэктрейс багов, возникающих в системах со сложной логикой. Безусловно, это не панацея, и баги, на которые не были написаны тесты, все равно уйдут в продакшен, но без всей этой штуки вы вообще не можете заглянуть внутрь и отследить техническое (и, возможно, не только) качество продукта.
Касаясь вашего конкретного примера с PHPLoc - он действительно бесполезен, если просто использовать его для подсчета веселых цифр. Но косвенно он дает вам способ проанализировать ваше приложение:
Каков объем кодовой базы? Если мы берем нового разработчика, с каким объемом кода ему придется ознакомиться, чтобы начать работать?
Сколько у нас глобальных констант? Не работают ли у нас макаки?
Что у нас с цикломатической сложностью? Корректно ли у нас разносится логика в коде?
Если в проекте участвуете только вы, и вы совершенно точно не используете глобальные константы, то он вам не нужен. Но если вы работаете в стартапе, где каждый день на счету, и зачастую вам приходится жертвовать качеством в угоду скорости, то вместо расставления todo по всему проекту вы можете мониторить те грязные участки кода, которые пришлось оставить, с помощью тех же phploc, phpcs, phpmd. Вопрос о том, насколько это нужно вашему текущему проекту - открытый, но сама возможность предоставить этот самый взгляд на код изнутри у вас есть.
Для закрепления впечатления - еще одна ссылка на CI вышеупомянутого Allure. Его разрабатывает команда автоматизации тестирования в Яндексе, и там можно посмотреть, как проходит билд - там есть и прогонка тестов, и тренды, и автоматический анализ качества через sonarqube.