Чтобы выпустить готовый к использованию программный продукт, мало просто написать код. После того, как программисты завершили свою работу, требуется еще довольно много времени, чтобы представлять продукт широкой пользовательской аудитории. Сделать, казалось бы, нужно всего ничего: объединить все, что написано разными разработчиками, создать установщик, подготовить документацию. Нередко программисты даже не представляют себе, сколько времени занимают рутинные операции. Часто возникает такая ситуация: все торопятся, и тем самым только умножают количество ошибок и недочетов. На устранение недочетов тоже требуется определенное время — и релиз продукта приходится отложить на неопределенной срок.
Программный продукт должен постоянно развиваться, «обрастая» новой функциональностью и становясь более удобным в использовании. Но по мере развития проектов рутинной работы, как правило, также становится больше, а времени на то, чтобы думать об улучшении проекта, совершенно не остается.
Ситуации, о которых идет речь, знакомы нам не понаслышке. Было время, когда наши программисты собирали все пакеты вручную. Но проектов становилось все больше, и количество рутины росло. А вот времени на размышления о развитии и совершенствовании продуктов становилось все меньше и меньше. Нужно было что-то менять, и мы задумались о внедрении непрерывной интеграции.
Что такое непрерывная интеграция?
Понятие непрерывной интеграции (англ. continuous integration, сокращенно CI) было впервые употреблено в 2000 году в одноименной статье Мартина Фаулера. Согласно определению, данному в этой статье, непрерывной интеграцией называется практика разработки ПО, при которой осуществляются частые сборки проекта с целью оперативного выявления проблем и ошибок на ранних стадиях.
Непрерывная интеграция основывается на следующих принципах:
- каждое изменение должно интегрироваться: при каждом изменении, вносимом в код, запускается новая сборка. Соблюдение этого принципа всегда позволяет иметь под рукой актуальную версию продукта;
- сборка должна быть по возможности быстрой. В статьях-рекомендациях по внедрению непрерывной интеграции иногда встречаются такие цифры: стандартная сборка не должна занимать более десяти минут. Собственно, смысл непрерывной интеграции заключается в получении быстрой обратной связи;
- тестирование должно быть регулярным: это обеспечивает оперативное обнаружение и исправление всех ошибок;
- интеграция должна осуществляться на специальной машине, конфигурация которой максимально соответствует окружению, в котором проект должен быть развернут. Это обязательно должна быть выделенная машина (она может быть и виртуальной).
Что можно получить, претворив все эти принципы в жизнь?
Во-первых, раз и навсегда решить проблему изменений и правок, внесенных разными программистами: все происходит в автоматическом режиме.
Во-вторых, непрерывная интеграция дает возможность беспристрастной оценки результатов работы программистов: что-то не работает на сборочном сервере — значит, не работает вообще.
В-третьих, регулярное тестирование позволяет поддерживать качество продукта на должном уровне.
Чтобы внедрить CI в реальную практику, нужно учитывать немало различных факторов. Немаловажным моментом является выбор программного решения для CI. Мы перепробовали несколько продуктов, прежде чем нашли полностью устраивающий нас вариант.
Выбор системы CI
Первым инструментом непрерывной интеграции, который мы попытались использовать, был Atlassian Bamboo. К тому моменту мы уже активно использовали Atlassian JIRA, и главным аргументом в пользу Bamboo было единство пользовательского интерфейса и простота интеграции с другими сервисами Atlassian.
До того, как мы внедрили Bamboo, программистам приходилось собственноручно делать много вещей, совершенно далеких от программирования и отнимавших очень много времени — здесь речь идет в первую очередь о ручной сборке пакетов и тестировании. С помощью Bamboo мы рассчитывали автоматизировать сборку и сэкономить время, но, к сожалению, этого у нас не получилось. Одним из недостатков Bamboo на тот момент, когда мы пытались его использовать, была рутинность конфигурирования, которое порой забирало столько времени, что программисты сами возвращались к ручной сборке: так им было удобнее. Поэтому этот инструмент у нас не прижился.
Затем мы попытались внедрить опенсорсный инструмент Jenkins — и столкнулись с целым рядом серьезных проблем. Сразу же бросаются в глаза такие его недостатки, как неудобный интерфейс и чрезмерная сложность настройки. В ходе работы стал очевидным еще один, гораздо более существенный минус. Дело в том, что в исходной комплектации «из коробки» возможности Jenkins крайне ограничены. Набор функций расширяется при помощи разнообразных плагинов. Но эти плагины далеко не всегда отличаются хорошим качеством и очень часто конфликтуют между собой, и это тоже порождает многочисленные проблемы.
Из-за всех описанных сложностей Jenkins у наших программистов тоже, что называется «не пошел». Но в отделе облачных серверов, тем не менее, он до сих пор используется для пересборки ядер и фунционального тестирования.
Подходящий инструмент CI был найден в ходе дальнейших поисков: это TeamCity, продукт компании JetBrains. В числе его несомненных плюсов следует назвать:
- простоту настройки и администрирования;
- достаточно большой набор функций «из коробки», в базовой комплектации;
- возможность интеграции с различными средами разработки;
- возможность интеграции с используемыми нами продуктами Atlassian (JIRA и Confluence);
- наличие шаблонизатора проектов;
- достаточно гибкие условия лицензирования.
Интересно, что TeamCity базируется на том же подходе, который стал одной из причин от Jenkins: расширение набора функций так же осуществляется с помощью плагинов. Но, как уже было сказано выше, Team City обладает достаточно широкими возможностями в базовой комплектации, и поэтому не нужно устанавливать плагины на все случаи жизни; те немногочисленные плагины, с которыми нам приходилось иметь дело, работали достаточно стабильно. Еще одним важным преимуществом TeamCity является эргономичность и удобство использования.
Вместо заключения
Попробуем описать преимущества, полученные нами в результате внедрения непрерывной интеграции, на языке цифр и фактов. Приведем статистику за все время, что мы используем Team City:
- 102 проекта;
- 280 сборок;
- 320 Гб артефактов;
- каждую неделю осуществляется примерно 1000 новых сборок.
В результате автоматизации рутинных операций нам удалось сэкономить примерно 33 часа в неделю. Высвобожденное время мы посвящаем развитию и совершенствованию уже существующих сервисов, а также внедрению новых.
Тех, кто не может комментировать посты на Хабре, приглашаем к нам в блог.
Автор: AndreiYemelianov