Хотите дальше читать devby? 📝
Support us

Непрерывная интеграция (Continuous Integration) с точки зрения менеджера проекта

Оставить комментарий
Непрерывная интеграция (Continuous Integration) с точки зрения менеджера проекта
Я пришел работать в крупную компанию студентом, в силу специфики прошлого опыта попал в отдел поддержки (NOC, Software Maintenance), в котором как раз в этот момент образовалась новая команда Build Engineering Team. Поначалу нас было всего трое, но в течение почти четырех лет команда выросла в целый отдел. Было накоплено огромное количество опыта, разработаны документы, практики и стандарты построения CI сред, а так же множество специфических решений для крупных заказчиков. Уже позже, пройдя несколько других компаний и став сначала программистом, потом лидером команды, и, наконец, проектным менеджером, я стал смотреть на процесс построения CI с несколько иной позиции.

Стандартное представление о Continuous Integration

Верхи и низы

В каждом проекте есть верхи и низы, руководство и исполнители. Все работают вместе, как одна команда, но претензии к процессу CI у всех разные. Часто случается так, что проектный менеджер считает процесс CI чем-то вроде украшения: «Ну, там, сделайте, чтобы сборка запускалась, когда новый код попал в репозиторий, и чтобы обязательно запускались тесты». Как это ни печально, многие менеджеры имеют слабое представление о преимуществах правильной и осмысленной непрерывной интеграции. Менеджер просто хочет отчитаться перед своим начальством и заказчиками, что «вот на моем проекте» все соответствует новомодным практикам Agile, Scrum, и так далее, нужное подчеркнуть. Это ласкает эго, успокаивает совесть (ну заказчику то обещали, что у нас все на высшем уровне) С другой стороны, программисты и тестеры воспринимают это как дополнительную, ненужную работу. Среду интеграции нужно настроить, а результаты автоматических тестов нужно разобрать и исправить ошибки. Менеджер ведь не сядет сам всем этим заниматься? Итого, верхи не могут, а низы не хотят. Как чаще всего решается эта проблема? Менеджер на одном из проектных митингов указывает пальцем на одного из членов команды и говорит: «Так ты, да-да ты, не прячься, я все равно достану тебя из-под стола, ты будешь билд инженером, ну ты знаешь, как это все должно быть. В общем, я хочу, чтобы картинка ожила». Знакомая ситуация? К чему это приводит, я расскажу чуть позже.

Непрерывная интеграция

Если попробовать поискать в открытых источниках формулировку что же такое непрерывная интеграция, то большинство говорит, что это процесс, который позволяет автоматически собрать, протестировать и установить приложение. Основные компоненты подобной среды сборки:
  • Scheduler – это может быть Cruisecontrol (.Net), Hudson, Team City и так далее. Приложение, которое позволяет в автоматическом режиме по расписанию или по определенному событию запустить сборку, затем агрегировать результаты, разослать сообщения заинтересованным лицам
  • Builder – Ant, Nant, make, maven и так далее. Собственно средство, которое умеет в правильном порядке запустить последовательность действий, чтобы в итоге получить собранное приложение
  • 3rd party tools – сторонние приложения, которые автоматически тестируют, готовят численные характеристики вроде процента покрытия исходного кода юнит тестами, автоматически проверяют код на соответствие лицензиям (BlackDuck) и еще множество вещей

Непрерывная интеграция в оффшорной модели разработки

Жестокая реальность

Все непрерывно говорят об увеличении качества исходного кода, золотых стандартах, получаемых потрясающих результатах, но почти никто не говорит о реальных цифрах, затратах и прочем. Лично для себя я вывел два основных параметра непрерывной интеграции, которые имеют значение при оффшорной модели разработки.
  • Осмысленность – покрывает ли полученная прибыль затраты на создание и поддержку CI
  • Правильность – в общем случае это баланс между проблемами, решаемыми с помощью CI и проблемами которые создает CI (правильная CI решает больше проблем, чем создает)
Более детальное и численное описание каждого из критериев будет приведено ниже. Реальность оффшорной разработки в том, что непрерывная интеграция крайне редко воспринимается, как способ повысить качество кода. Если клиент желает супер качество, пусть наймет себе локальную команду программистов и тестеров, поставит им задачу, численные характеристики качества, и потом радостно наблюдает, как тает его банковский счет. Оффшорная разработка позволяет снизить затраты при средне-высоком качестве полученного продукта. Менеджер оффшорной команды в лучшем случае заботится о балансе качества и стоимости разработки, в худшем – только о стоимости. Как в этом разрезе видится роль непрерывной интеграции? Я лично считаю, что CI здесь способ программно автоматизировать все что возможно, экономя время программистов и тестеров на боевые свершения.

Стоимость

Попробуем разобраться в ситуации. Возьмем, для примера, случай описанный выше (небольшой проект, отсутствие серьезного опыта в вопросах CI). Я на сто процентов уверен, что в контракте четко не прописано время, которое будет потрачено билд инженером на разработку и поддержку среды. Как максимум, заложено часа два-три на изначальную подготовку (установка необходимого ПО, настройка серверов приложений на локальных компьютерах программистов и тд). Итого бюджет составляет примерно ноль. В данном примере возьмем стоимость человеко-часа равной 50 долларам. Давайте составим так называемый «profit and lost report». Lost (затраты):
  • Аренда выделенного сервера (аппаратного или виртуального) составляет от 50 до 200 долларов в месяц (это включает амортизацию, затраты на обслуживание, электричество, включая питание кондиционеров, аренду офисного помещения предназначенного для серверной комнаты). Поверьте, эти цифры взяты не с потолка, а весьма детально рассчитаны в масштабах достаточно большой компании, обладающей собственным офисом, штатом IT support, специально оборудованными комнатами для размещения серверов. Итого 1-4 человеко-часа
  • Первоначальная настройка среды – для человека немного знакомого с CI около 4 человеко-часов
  • • Поддержка среды – оптимистическая оценка равна 1 человеко-час в месяц
В сумме набирается примерно 6-10 человеко-часов в первый месяц и 2-5 в каждый последующий Profit (прибыль):
  • Если CI создан больше для галочки (по моим подсчетам это треть проектов), прибыль составляет круглый ноль
  • В проектах для мобильных платформ, где установка приложения не предполагается, а автоматические средства проверки кода либо отсутствуют, либо это только юнит тесты и подсчет покрытия, прибыль тоже в районе нуля
  • Если CI среда умеет хотя бы устанавливать приложение на сервер, то возможно тестеры сэкономят время необходимое на ручную установку приложения. Этот случай сильно зависит от специфики самого проекта
  • Если менеджер все-таки заботится о качестве кода и включает исправление ошибок найденных всевозможными Checkstyle, PMD в планы на следующую итерацию, то прибыль составит минус несколько человеко-часов (обсуждение возможной прибыли от исправления этих ошибок оставим за скобками). Ой, как же так, наверное, это стоило перенести в предыдущий список?
Итоговая прибыль для небольшого, несложного проекта составила примерно от нуля до минус нескольких человеко-часов. То есть, желание выглядеть в глазах начальства и заказчиков продвинутым менеджером, работающим по признанным мировым практикам, стоит бюджету проекта от 100 до 300 долларов ежемесячно (а ведь можно было команде каждый день покупать мороженое или печенья к чаю). Меня не раз спрашивали про вопросы мотивации (помните, что низы не хотят?). Как быть если команда считает затею глупой? Получается, что есть еще и нематериальные затраты на правильную мотивацию людей. Вот здесь численно показан один из моих параметров CI, осмысленность – если среда непрерывной интеграции приносит вам одни убытки, то неважно, что говорит умная книга про Scrum в красивой обложке. В такой ситуации от нее лучше отказаться, потому что делать что-то себе во вред бессмысленно.

Мотивация

У каждого человека присутствует толика здоровой лени. А у программиста со стажем работы в 5-7 лет этой толикой можно железнодорожный вагон забить под завязку. Он уверен в себе, знает, что он делает, имеет набор укоренившихся практик, стиль написания и прочее. Просто взять и настроить на сервере кучу софта, которое проверит его код и скажет, что он в куче мест неправ, вызовет бурю негодования в стиле: «Да кто они такие!?». Ниже несколько способов, позволяющих решить часть проблем.

Старая добрая диктатура

Натолкнулся на этот способ на одном интересном ирландском проекте. Большинство систем контроля версии имеют такую вещь, как pre-commit и post-commit hooks. То есть перед тем, как код реально попадает в репозиторий, над ним можно совершить какое-либо действие. Дальше проще, берем тот же PMD (Java/C++/Perl/etc source code checker) и натравливаем его на свежий код. Если он выдал хотя бы одну ошибку, завершить коммит нельзя. Интеграция сторонних приложений с серверной частью систем контроля версий реализуется достаточно примитивно. Негатив от такого решения можно смягчить, переложив ответственность на дядю, то есть, сказав, что это договоренность с заказчиком, и ничего не поделаешь. Тренируйте навык «глаза как у кота из Шрэка» перед зеркалом.

Ground rules

Схож с предыдущим методом, но предполагает исключения. В самом начале проекта определяются правила, которым должны следовать все программисты при разработке, сулятся кары небесные на голову тех, кто не следует правилам. Обычно работает чуть хуже, чем диктатура, но вызывает меньше негатива.

Положительная мотивация

Можно попробовать устроить соревнование внутри команды, между несколькими командами за право называться иконой качества. Победителям можно выделить бонус из бюджета. Плохо только то, что подобный метод работает для настоящей команды, а не толпы людей, собранных для работы над проектом (иначе будет не соревнование, а конфликт). И желательно, чтобы команда была высокопрофессиональной.

Осмысленность и правильность непрерывной интеграции

Осмысленность

Как было показано выше, осмысленность присутствует, если менеджер и команда (да-да командиры, мы не одни на проекте работаем) видят смысл, реальную отдачу, полезность и прибыль от организации непрерывной интеграции. Как этого добиться? Перед началом проекта сесть и посчитать:
  • Каков размер нашего проекта, какое количество кода планируется написать?
  • Насколько сложен процесс установки и тестирования полученного продукта, занимает ли он от силы пару минут, либо это сложный процесс, для которого отдельный документ впору писать?
  • Есть ли у нас инженер, который способен правильно разработать среду?
  • Какой бюджет нам доступен на разработку непрерывной интеграции? Стоит ли при нашем бюджете вообще начинать это, или полученный шедевр доктора Франкенштейна нам только все испортит?
Некоторые параметры легко поддаются подсчету, возьмите билд инженера, сядьте вместе с ним, оцените задачу, просчитайте время, состыкуйте его с бюджетом. Запланируйте все необходимые активности, внесите это в проектный план. Непрерывная интеграция не в красивых словах и терминах, а в четких, осмысленных планах. Значит, когда эти баритоны кричат: «CI неотъемлемая часть Scrum!», - я смеюсь. Клянусь вам, мне смешно. Это означает, что каждый из них должен прекратить надувать щеки, а сесть и посчитать приносит ли им CI хоть цент реальной прибыли (перефразирование М. Булгакова, Собачье сердце).

Правильность

Чтобы вы лучше понимали мой критерий правильности, я обращусь к нескольким примерам из жизни. Оба проекта большие, проектная команда обоих больше 30 человек, и разработка идет не один год. Естественно, что такой срок вырабатывается набор правил, техник и процедур, используемых на проекте. Я хочу рассказать вам о той части этих процедур, которая связана с непрерывной интеграцией. Не хочу называть имен, названий – это неважно. Важен результат, который получился в одном и втором случае.

Проект номер один

У меня закончился проект, и команду распределили по другим проектам. Один парень попал на большой долгострой, Java, несколько UI приложений, back-end, база данных, тысячи исходных файлов, тонны статических ресурсов. Поскольку мой клиент периодически находил мелкие проблемы в нашем приложении, я обращался к этому парню за помощью и между делом общался с ним. Через несколько дней он мне признался, что уже два дня мучается с Ant билдом и не может его завести. Я был свободен и решил тряхнуть стариной, подошел к его рабочему месту и попытался вникнуть в суть проблемы. И тут же испытал культурный шок. Конфигурационный файл Ant-а составлял больше шести тысяч строк. Если отбросить строк пятьсот на переменные (properties), пути (path-like structures), заголовки и пустые блоки, останется примерно пять с половиной тысяч строк XML. Примерный подсчет показывает, что в среднем одна функция (target) занимает 50-100 строк, то есть 50-100 различных функций. С учетом взаимных зависимостей между ними, Ant скрипт напоминал кастрюлю со свежесваренными спагетти. Дальше стало еще более интересно, Java машина жаловалась на недостаток памяти при запуске установки приложения. Увеличение размера кучи вплоть до максимума делу не помогло. Мы пригласили человека, который этот скрипт «дорабатывал», он пришел и посоветовал сначала запустить одну процедуру, в результате ничего не поменялось. Java машина продолжала ругаться на один специфический плагин. Поиск в Google показал, что у этого плагина проблемы со стабильностью, и есть зарегистрированные баги, связанные с ошибкой недостатка памяти. Ответственный за скрипт человек развел руками и ушел. «Помощь зала» (те опрос проектной команды) тоже не дала ничего, кто-то просто отмахивался, кто-то кивал на «ответственного». Вот к чему часто приводит техника «Эй ты, будешь ответственным за Continuous Integration»

Проект номер два

Я участвовал в этом проекте более трех лет. Проект представлял собой целую платформу для бизнеса путешествий. Платформа включала в себя приложения для продажи билетов, бронирования отелей и автомобилей конечным пользователям; приложения для работы туристических агентств, call center, административную оболочку, приложение мониторинга лог файлов, несколько backend-ов, огромную базу данных. Для этой платформы был разработан специфический Ant-based framework, который позволял собирать приложения из маленьких обособленных кусочков, каждый из которых мог иметь зависимости на остальные модули. Так, например, к динамическому приложению продажи билетов (Tomcat war file) можно было подключить специализированный статический сайт, разработанный под конкретного заказчика; разные приложения могли быть собраны на разных версиях библиотек и так далее. В какой-то момент возникла проблема установки платформы на множество различных серверов. У каждой подкоманды было свое приложение (QA, Development, Staging-Demo). Приложение устанавливалось на разные сервера, при каждой установке требовалось на лету менять параметры в конфигурационных файлах. Содержать десятки небольших, пусть даже хорошо структурированных и документированных Ant скриптов, было попросту неудобно. К тому же, программисты не могли воспользоваться этими скриптами локально, они работали только на сервере. Я решил сделать на базе Ant-а несколько специфичных функций (tasks), которые бы позволили производить установку всей платформы, опирались на простой в написании и понятный конфигурационный файл, были достаточно умны, чтобы отслеживать зависимости между отдельными приложениями платформы и производить установку на локальные или удаленные сервера приложений. К сожалению, имплементация является проприетарной, но конфигурационный XML файл содержал простейшие тэги и был понятен абсолютно всем. Сервера приложений и пакеты установки: <appserver name="tomcat" type="tomcat"> <deploymentpackage name="static" dedicateddeployment="true" appserver="apache"> <deploymentpackage name="backend" dedicateddeployment="false" appserver="jboss"> Возможность налету менять файлы внутри пакета: <deploymentpackage name="ui" dedicateddeployment="true" appserver="tomcat" depends="static,backend"> <item name="tomcat/webapps/site.war" type="war" relativedeploymentpath="webapps/site.war"> <subitem name="WEB-INF/classes/Default.xml" type="plain"> <replace token="@@@webservicehostaddress@@@" value="server"/> </subitem> </item> </deploymentpackage> Программистам не всегда нужно устанавливать всю платформу сразу, но ненужные части можно просто закомментировать. В Ant скрипте вызов специфической функции (task), которая проводила всю установку, занимал одну строчку, подобных конфигурационных файлов могло быть до десятка, и они передавались в Ant динамически. Это решение легко было использовать как мне на основном сервере CI, так и программистам локально, и иногда даже тестерам. Причем знание Ant было необязательным, достаточно было правильно оформить конфигурационный файл. Второй пример более сложный. При таком числе UI приложений количество регрессионного тестирования просто зашкаливало. Целая бригада тестеров целыми днями нажимала одни и те же кнопки, пристально вглядывалась в те же самые формы на экране. «Федор, уже нужно что-то делать», - высказалось начальство. Примерно день мы потратили на разработку концепции автоматического тестирования, собрали информацию о необходимых сторонних приложениях, их возможностях и так далее. Выбрали JMeter в качестве средства автоматизированного тестирования, нашли пути обхода его ограничений. Перед каждым тестом необходимо было выполнить предварительные действия (как-то: создать профиль пользователя перед входом в систему), а после теста выполнить чистку (удалить тестовый профиль). JMeter не умел выполнять связанные зависимостями группы тестов; поддерживал файл конфигурации для тестов (чтобы, например, на лету подставить URL приложения или данные формы), но был не в состоянии автоматически поддерживать несколько разных конфигураций; производил отдельные, слабо читаемые HTML файлы отчетов на каждый отдельный тест. Framework:
  • Позволяет делать многоуровневую группировку тестов (Pre-Test / Post Test / Main Test -->Test --> Use Case --> UI Application)
  • Позволяет подключать конфигурационные файлы динамически на разных уровнях группировки
  • Агрегирует полученные результаты в единый HTML файл (древовидное представление результатов плюс общая статистика). Дополнительно в отчет включаются лог файлы серверов приложений
  • Интеграция с общей средой сборки проекта
На разработку было потрачено примерно полторы человеко-недели. Создание всех JMeter тестов потребовало еще около человеко-месяца. Точных цифр экономии ресурсов я привести не могу, но знаю, что эти затраты достаточно быстро (в течение нескольких месяцев) окупились и стали приносить прибыль. Как вы думаете, на каком из проектов непрерывная интеграция была правильной? Там где был случайно выбран человек ни за что не отвечающий, или там где выделенный человек с многолетним опытом занимался разработкой, поддержкой среды непрерывной интеграции и нес за это ответственность? Разница заключается лишь в том, что правильная непрерывная интеграция помогла решить большой спектр проблем и принесла прибыль, а неправильная решила некоторые проблемы, но создала новые.

Стоимость внедрения непрерывной интеграции

В этом разделе я попробую в человеко-часах описать стоимость внедрения правильной непрерывной интеграции и расскажу что для этого необходимо.

Команда

Для любого дела необходима стабильная, профессиональная команда. Когда люди приходят и уходят, не приобретая значимого опыта, процесс становится слабоуправляемым и непредсказуемым. В состоянии ли инженер воплотить сложную, многофункциональную среду, если он до этого написал пару простейших билд файлов? Я сильно сомневаюсь. Скорее всего, в результате мы получим неказистого монстра, слабо шевелящего уродливыми конечностями. Первое необходимое вложение – это один или несколько человек, которые готовы стать ядром команды билд инженеров. Наилучшими в этом случае являются инженеры NOC, которые обладают знаниями из многих областей, как-то программирование, администрирование операционных систем, тестирование. Но это не является строго необходимым, скорее решает мотивация и желание достичь результатов. Необходимо освободить этих людей насколько это возможно от их текущих обязанностей и поставить им задачу.

Задача

Первая задача и цель – это построение абстрактной среды непрерывной интеграции. Для Java и Android проектов она может быть полностью унифицирована. В принципе скриптовые языки (PHP, Python, Perl) тоже могут использовать схожую структуру среды (структура каталогов в системе контроля версий, базовые алгоритмы сборки проекта). Например:
  • lib – директория с любыми сторонними библиотеками, необходимыми во время сборки
  • resources – директория с ресурсами, конфигурационными файлами
  • tools – набор подключаемых библиотек функций (например, ant скрипты с динамическими функциями macrodef)
  • vcs – репозиторий исходного кода
  • build.xml – корневой Ant скипт с набором стандартных процедур (targets)
Если базироваться на Ant, то подобная структура директорий подходит для абсолютно любого проекта. И неважно будет ли это Java website, Android приложение либо PHP website, на этом уровне все проекты могут выглядеть одинаково. Опять же вне зависимости от выбранного планировщика задач (Cruisecontrol, Hudson, etc) он будет запускать один и тот же процесс. Подключаемые библиотеки функций могут отвечать за запуск юнит-тестов (JUnit, PHPUnit, etc), тестировать исходный код на соответствие конвенциям стиля (Checkstyle for Java, PMD for Java, C, C#). Внутри директории vcs находится скрипт низкого уровня, который отвечает за сборку и упаковку. Планировщик, скорее всего, должен включать стандартный набор проектов:
  • Nightly – полная сборка, тестирование и установка на выбранные среды (Dev, QA, Staging)
  • Automatic – автоматическая сборка проекта (возможно без установки) для верификации стабильности, обычно срабатывает при обновлении репозитория исходного кода
  • Forced – сборка, которую можно запустить принудительно, предназначена для выборочной проверки и\или установки приложения, когда это необходимо
Дальнейшая задача состоит в том, чтобы обкатать подобную структуру на нескольких небольших проектах, собрать отзывы разработчиков, понять обоснованность претензий и исправить недочеты. Один человек в состоянии справиться с этой задачей за человеко-месяц. Имеется ввиду потраченное время, а не календарный срок.

Стабилизация процесса

По мере того, как процесс, структура среды, применяемые средства будут обкатываться на реальных проектах, будут вноситься небольшие, но значимые изменения, расширится набор сторонних средств. Уже на этом этапе сервис стоит вносить в Level of Effort Estimate проекта. Несколько человеко-часов вполне достаточно, чтобы установить и настроить среду, а предложения и претензии со стороны заказчика и команды разработчиков помогут улучшить сам процесс. Улучшение и обкатка займет несколько человеко-месяцев, но часть этого времени может быть оплачена заказчиками. Итого финальная стоимость этого процесса – это выделение команды и два-три человеко-месяца ресурсов. По моим расчетам для полной загрузки одного инженера необходимо, чтобы в компании было несколько десятков проектов и не менее ста человек разработчиков. Эти расчеты эмпирические, основанные на опыте работы в большой компании и необходимым количеством инженеров для покрытия сервисом всех проектов.

Sales

Маленькое, но важное дополнение – к моменту начала стабилизации департамент продаж должен поменять свою парадигму и включить Continuous Integration в список продаваемых сервисов. Для облегчения этого стоит создать простую и понятную презентацию процесса, списка получаемых преимуществ и стоимости. Менеджер по продажам должен понимать, что он продает, и какую прибыль получит от этого заказчик, чтобы убедить его в необходимости за это заплатить.

Заключение

Заключение достаточно очевидное – не бывает серебряных пуль, если компания желает получать калькулируемую прибыль от процесса непрерывной интеграции, она должна вложить в него ресурсы и время, пройти несколько простых шагов. В результате в штате компании появятся люди, способные решить крайне широкий спектр задач по автоматизации процесса разработки, с высоким уровнем ответственности и высоким качеством результата.
Помогаете devby = помогаете ИТ-комьюнити.

Засапортить сейчас.

Хотите сообщить важную новость? Пишите в Telegram-бот

Главные события и полезные ссылки в нашем Telegram-канале

Обсуждение
Комментируйте без ограничений

Релоцировались? Теперь вы можете комментировать без верификации аккаунта.

Комментариев пока нет.