Введение
Постоянная интеграция (CI) — это практика частого создания и тестирования программной системы в процессе её разработки. Она предназначена для обеспечения того, чтобы код, написанный программистами, всегда компилировался, запускался и проходил автоматизированное тестирование. Разработчики объединяют свой код в интеграционную ветку, после чего автоматизированная система выполняет сборку и тестирование. Хотя изначально сторонники CI не настаивали на интеграции несколько раз в день, впоследствии эта возможность стала неотъемлемой частью практики.
Continuous integration (CI) is the practice of frequently building and testing a software system during its development. It is intended to ensure that code written by programmers is always buildable, runnable and passes automated testing. Developers merge to an integration branch and an automated system builds and tests. although he did not advocate integrating multiple times a day, but later, CI came to include that aspect.
История
Самой ранней известной работой в области непрерывной интеграции была среда Infuse, разработанная Г. Э. Кайзером, Д. Э. Перри и В. М. Шеллом. В 1994 году Грейди Буч использовал термин «непрерывная интеграция» в книге «Объектно-ориентированный анализ и проектирование с приложениями» (2-е издание), чтобы объяснить, что при разработке с использованием микропроцессов «внутренние релизы представляют собой своего рода непрерывную интеграцию системы и служат для завершения микропроцесса». В 1997 году Кент Бек и Рон Джеффрис изобрели экстремальное программирование (XP) во время работы над проектом Chrysler Comprehensive Compensation System, включив в него непрерывную интеграцию. Бек опубликовал работы о непрерывной интеграции в 1998 году, подчеркивая важность непосредственного общения, а не технологической поддержки. В 1999 году Бек более подробно раскрыл эту тему в своей первой полной книге по экстремальному программированию. CruiseControl, один из первых инструментов непрерывной интеграции с открытым исходным кодом, был выпущен в 2001 году. В 2010 году Тимоти Фиц опубликовал статью, в которой подробно описал, как инженерная команда IMVU создала и использовала первую практическую систему непрерывной интеграции. Несмотря на первоначальный скептицизм, его публикация быстро приобрела популярность и стала частью методологии бережливой разработки программного обеспечения (Lean), также основанной на опыте IMVU.
Цель
Заявленная цель CI — запускать автоматизированный процесс достаточно часто, чтобы не оставалось временного промежутка между коммитом и сборкой, и чтобы любые ошибки не могли возникнуть незамеченными для разработчиков, которые могли бы немедленно их исправить. Сервер также может выполнять другие процессы контроля и обеспечения качества программного обеспечения, такие как статический анализ, измерение производительности, извлечение документации из исходного кода и поддержка ручного тестирования.
Связанные практики
В этом разделе перечислены лучшие практики, рекомендованные специалистами, для применения других подходов, повышающих эффективность непрерывной интеграции.
Автоматизация строительства
Автоматизация сборки — передовая практика.
Атомные обязательства
CI требует, чтобы система контроля версий поддерживала атомарные коммиты, то есть все изменения разработчика должны быть объединены в один коммит.
Обязательные изменения
При внесении изменений в код разработчик создает ветвь, являющуюся копией текущей кодовой базы. По мере добавления других изменений в репозиторий, эта копия начинает расходиться с последней версией. Чем дольше ведется разработка в ветви без слияния с интеграционной ветвью, тем выше риск возникновения множественных конфликтов и ошибок при последующем слиянии ветви разработчика обратно. Когда разработчики отправляют код в репозиторий, они должны сначала обновить свой код, чтобы учесть изменения, внесенные в репозиторий после создания их копии. Чем больше изменений содержится в репозитории, тем больше работы требуется от разработчиков перед отправкой собственных изменений. В конечном итоге репозиторий может настолько измениться по сравнению с исходной кодовой базой разработчика, что они попадают в ситуацию, которую иногда называют "адом слияний" или "адом интеграции", когда время, затрачиваемое на интеграцию, превышает время, потраченное на внесение первоначальных изменений.
Непрерывная доставка и непрерывная развертывание
Непрерывная поставка (Continuous Delivery) гарантирует, что программное обеспечение, добавленное в интеграционную ветку, всегда находится в состоянии, пригодном для развертывания пользователям, а непрерывная интеграция и развертывание (Continuous Deployment) автоматизирует процесс развертывания. Непрерывная поставка и непрерывная интеграция и развертывание часто используются совместно с CI и вместе формируют CI/CD-пайплайн.
Контроль версий
Сторонники CI рекомендуют хранить все файлы и информацию, необходимые для сборки, в системе контроля версий (для Git — в репозитории); система должна собираться из свежей копии (checkout) и не требовать дополнительных зависимостей. Мартин Фаулер рекомендует, чтобы все разработчики коммитили изменения в одну и ту же интеграционную ветку.
Автоматизировать сборку
Инструменты автоматизации сборки автоматизируют процесс сборки. Сторонники непрерывной интеграции (CI) рекомендуют, чтобы одна команда позволяла собрать всю систему. Автоматизация часто включает в себя автоматизацию интеграции, которая, в свою очередь, часто включает в себя развертывание в среду, максимально приближенную к производственной. Во многих случаях скрипт сборки не только компилирует исполняемые файлы, но и генерирует документацию, страницы веб-сайта, статистику и установочные пакеты (например, Debian DEB, Red Hat RPM или Windows MSI).
Каждый день каждый человек стремится к своей цели.
Регулярные коммиты позволяют каждому разработчику уменьшить количество конфликтующих изменений. Загрузка работы, накопленной за неделю, повышает риск конфликтов с другими функциями и может быть очень сложной в разрешении. Небольшие конфликты, возникающие на ранних этапах работы над определенной частью системы, стимулируют общение между членами команды об изменениях, которые они вносят. Коммиты всех изменений как минимум раз в день (после реализации каждой функции) обычно рассматриваются как часть определения непрерывной интеграции. Кроме того, рекомендуется выполнять ночные сборки. Это минимальная частота; обычно ожидается значительно более высокая частота коммитов.
Каждый коммит должен быть построен
Система должна создавать коммиты к текущей рабочей версии для проверки корректности их интеграции. Распространенной практикой является использование автоматизированной непрерывной интеграции, хотя это также может выполняться вручную. Автоматизированная непрерывная интеграция использует сервер или демон непрерывной интеграции для отслеживания изменений в системе контроля версий и последующего автоматического запуска процесса сборки.
Каждый коммит по исправлению ошибок должен быть с тестовым случаем
При исправлении ошибки рекомендуется добавлять тест-кейс, который воспроизводит эту ошибку. Это позволяет избежать отката исправления и повторного возникновения ошибки, известного как регрессия.
Строй быстро.
Сборка должна завершиться быстро, чтобы любые проблемы с интеграцией были выявлены как можно скорее.
Испытание в клоне производственной среды
Наличие тестовой среды может приводить к ошибкам в тестируемых системах при развертывании в рабочей среде, поскольку рабочая среда может существенно отличаться от тестовой. Однако создание точной копии рабочей среды обходится слишком дорого. Вместо этого, тестовая среда или отдельная предпроизводственная среда ("стейджинг") должны быть построены как масштабируемая версия рабочей среды, чтобы снизить затраты, сохраняя при этом состав технологического стека и его особенности. В этих тестовых средах часто используется виртуализация сервисов для обеспечения доступа по запросу к зависимостям (например, API, сторонним приложениям, сервисам, мэйнфреймам и т.п.), которые находятся вне контроля команды, находятся в разработке или слишком сложны для настройки в виртуальной тестовой лаборатории.
Упростите получение последних результатов
Предоставление сборок заинтересованным сторонам и тестировщикам может сократить объем переделок, необходимых при доработке функциональности, не соответствующей требованиям. Кроме того, раннее тестирование снижает вероятность того, что дефекты дойдут до этапа развертывания. Обнаружение ошибок на ранних стадиях позволяет уменьшить объем работы, требуемой для их исправления. Всем программистам следует начинать день с обновления проекта из репозитория, чтобы оставаться в курсе последних изменений.
Все могут увидеть результаты последней сборки
Должно быть легко выяснить, сломана ли сборка, и, если да, кто внес соответствующее изменение и в чём заключалось это изменение.
Автоматизировать развертывание
Большинство CI-систем позволяют запускать скрипты после завершения сборки. В большинстве случаев можно написать скрипт для развертывания приложения на рабочий тестовый сервер, доступный для всеобщего ознакомления. Дальнейшим развитием этого подхода является непрерывная поставка (Continuous Delivery), которая предполагает развертывание программного обеспечения непосредственно в производственную среду, часто с дополнительной автоматизацией для предотвращения дефектов или регрессий.