Github и Travis CI для командной разработки
Представьте что вы пишите свою PHP библиотеку. Вы подготовили github репозиторий, сделали первый коммит с пометкой Initial и начали разработку. Со временем, вокруг вашего кода появилось комьюнити. Люди начинают активно использовать вашу библиотеку в своих проектах. А еще к вам присоединился коллега разработчик, и теперь вы вместе продолжаете развивать свой продукт. На этом этапе все идет хорошо.
Проблемы появляются, когда с выходом каждой новой версии все больше людей начинают жаловаться на баги в библиотеке. Тщательно анализируя историю коммитов, вы приходите к понимаю, что вы с коллегой работаете в одной главной ветке (master) и все новые фичи и доработки пушите именно туда. При этом ваш код никак не тестируется с изменениями вашего коллеги. Единственный тестировщик вашего кода - вы и браузер. Именно эту проблему мы попытаемся сегодня решить. Сразу скажу, что данная статья не является каноном того, как нужно делать. Она лишь показывает один из простых способов решения проблем при совместной работе над проектом.
Подготовка проекта
Я рекомендую использовать подготовленный мной репозиторий https://github.com/kirillbdev/php-simple-travis-config для лучшего понимания статьи. В дальнейшем вы можете откорректировать проект под свои нужды. Структура проекта будет иметь следующий вид:
Основной код проекта будет храниться в папке src (я уже подготовил класс Kernel как основной класс нашей библиотеки). Мы будем разрабатывать проект по методологии TDD, т.е. сначала покроем новый функционал тестами, затем напишем его и отправим изменения. Для тестирования установим PHPUnit, как зависимость для composer, а также установим пакет PHP Code Sniffer для проверки соответствия нового кода стандарту PSR-2. Сам файл composer.json должен выглядеть примерно так:
А так будет выглядеть наш базовый конфигурационный файл для PHPUnit:
Ну и на последок, нам нужен конфигурационный файл для Travis CI, который будет все это дело собирать и тестировать. В проекте он выглядит так:
Начало работы
Поскольку мы не хотим чтобы соавторы вносили изменения в код без предварительного code review, нам необходимо защитить нашу основную ветку. Причем защитить таким образом, чтобы code review должен был делать именно владелец кода (то есть мы).
Переходим в наш репозиторий и открываем пункт Settings -> Branches.
Нажимаем кнопку Add rule. Откроется страница настройки правила. Заполняем её, как показано на скриншоте.
Внизу страницы кликаем кнопку Create. Теперь наша ветка master защищена по таким правилам:
- Require pull request reviews before merging - указываем, что перед слиянием, другая ветка обязана пройти code review.
- Dismiss stale pull request approvals when new commits are pushed - отклонять утвержденные запросы на слияние веток при поступлении новых коммитов.
- Require review from Code Owners - code review должен выполнить пользователь с правами owner.
- Require status checks to pass before merging - в данной группе указываем, что перед слиянием ветка также должна получить зеленый статус от Travis.
- Include administrators - применить все включенные правила защиты для администрации.
После данных манипуляций пробуем запушить изменения в master ветку от имени колаборатора и получаем ожидаемый ответ.
Теперь мы не можем напрямую работать с мастер веткой. Переходим к следующему этапу.
Разработка новой фичи
Весь новый код теперь должен быть написан в отдельной ветке, а слияние с основной происходит с помощью pull request и проверки кода владельцем репозитория. Давайте создадим новую ветку и напишем туда немного php кода (работаем от имени колаборатора).
Теперь перейдем в папку tests/Unit, создадим класс KernelFeatureTest и напишем туда код для тестирования нашей будущей фичи.
namespace kirillbdev\PHPSimpleTravis\Tests\Unit;
use kirillbdev\PHPSimpleTravis\Core\Kernel;
use PHPUnit\Framework\TestCase;
class KernelFeatureTest extends TestCase
{
public function testNewFeature()
{
$kernel = new Kernel();
$this->assertEquals(10, $kernel->newFeature());
}
}
Теперь откроем файл src/Core/Kernel.php и реализуем нашу фичу.
namespace kirillbdev\PHPSimpleTravis\Core;
class Kernel
{
public function init()
{
// something
}
/**
* @return int
*/
public function newFeature()
{
return 10;
}
}
Пушим нашу ветку в удаленный репозиторий. После успешного выполнения открываем репозиторий github (от имени соавтора) и создаем pull request нашей фичи.
Обратите внимание, вам необходимо указать ревьювера в блоке Reviewers. После создания пулл реквеста этот пользователь получит оповещение о необходимости проверки кода. Теперь откройте наш свежесозданный пулл-реквест. Можно заметить, что кнопка слияния с мастер веткой нам недоступна. На данном этапе Travis CI должен собрать и протестировать свежий код, а ревьювер должен дать свой апрув.
После того, как все тесты будут успешно пройдены и ревьювер подтвердит разрешение на слияние - кнопка станет активна и мы, как соавтор можем слить свой код с основной веткой.
Вместо заключения
Мы с вами подготовили простую основу для безопасной работы над проектом github в команде. Конечно, это далеко не идеальная структура, она обладает достаточно базовыми и простыми принципами и её можно развивать. Например, можно создать несколько веток v1, v2 и т.д., таким образом, вы можете безопасно развивать несколько версий вашего проекта.
Каждый новый коммит теперь будет проходить базовую проверку на соблюдение стандарта PSR-2, автоматически тестироваться и оптравлятся владельцу на code review. Таким образом вы максимально снижаете вероятность появления критических ошибок при написании нового кода, а процесс разработки станет более прозрачным, что также влияет на конечное качество проекта.