Сложно представить современную разработку без Continuous Integration. Многие компании выпускают по нескольку релизов в день и прогоняют тысячи тестов. Со времен Jenkins и Travis CI на рынке появилось много самых разнообразных инструментов. Большинство из них работают по модели SaaS — вы платите фиксированную плату за использование сервиса, или за количество пользователей.  Но использование hosted платформ не всегда возможно, например, если нельзя передавать код приложения, или не хочется зависеть от внешних сервисов. В таком случае выручают системы, которые можно установить на своих серверах (self-hosted). Бонусом вы имеете полный контроль над ресурсами и можете масштабировать их согласно вашим потребностям используя, к примеру, amazon ec2. В этой статье представлен личный опыт использования нескольких opensource self-hosted continuous integration систем. Если вы использовали другие системы, расскажите об этом в комментариях. Основой любого CI является билд (build) — единичная сборка вашего проекта. Билд может собираться по различным триггерам — пуш в репозиторий, pull-request, по расписанию. Билд состоит из набора задач (jobs). Задачи могут выполняться как последовательно, так и параллельно. Набор задач задается перечислением всех задач или матрицей билда (build matrix) — характеристиками, по которым происходит разделение. Например, указанием версий языка программирования и переменных окружения — для каждой версии языка и каждого значения переменной будет создана своя задача. В некоторых ci системах также есть конвейер задач (pipeline) — задачи объединяются в группы (stage), все задачи в текущей группе исполняются параллельно, следующая группа выполняется только если предыдущая группа завершилась успешно. Например, конвейер test — deploy: если все задачи в test завершились успешно, то можно запускать задачи из группы deploy. Для эффективной работы ci важно наличие кэша — данных, которые используются для ускорения сборки. Это могут быть apt-пакеты, кэш npm, composer. Без кэша при запуске каждой задачи нужно будет заново скачивать и устанавливать все зависимости, что может занять времени больше, чем сам прогон тестов. Чем ближе расположен кэш к серверам, на которых выполняются задачи, тем лучше, например, если вы используете amazon ec2, то хорошим вариантом будет хранить кэш в amazon s3. При выполнении билда могут генерироваться артефакты — результаты сборки, отчеты о чистоте кода, логи. CI-система, позволяющая просматривать и скачивать эти артефакты, существенно облегчает жизнь. Если у вас большой проект с большим количеством одновременно запущенных задач, то вам не обойтись без масштабирования. Масштабирование бывает ручным и автоматическим. При ручном масштабировании вы сами запускаете и останавливаете runner-ы на свободных серверах. В случае автоматического масштабирования система сама решает, нужно ли создавать новые виртуальные машины и в каком количестве. Разные ci-системы поддерживают разных провайдеров — обычно это amazon, google compute, digital ocean и т.д. Важным является то, как система запускает команды, указанные в конфигурации билда (executors). Есть несколько способов: непосредственное выполнение (на хосте, где запущен runner), выполнение в виртуальной машине, в docker-контейнере, через ssh. У каждого способа есть особенности, которые нужно учитывать при выборе ci-системы, например, при запуске задачи в docker-контейнере отсутствует сессия и терминал, из-за чего некоторые вещи не получится протестировать. А при выполнении на хосте не забывать о очистке ресурсов после окончания выполнения — удаления данных из бд, docker-образов и т.д. Наконец, есть параметры, которые не критически важные, но делают работу с ci приятнее. Вывод лога — работает ли он в realtime режиме, или с каким-то интервалом? Можно ли прервать билд в случае проблем? Можно ли посмотреть конфигурацию билда и задачи?