Оптимизируем рабочий процесс

Доброго времени суток. Решил поделиться опытом в организации рабочего процесса разработки веб-проектов и не только веб. Расскажу свое видение максимально удобного использования связки типа: bugtraker + git + ci + deploy.



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

Как-то посчастливилось мне поработать в стартап проекте. Могу сказать только то, что это был форекс брокер. Нашей команде требовалось разработать сайт, личный кабинет и сишные модули для торговой платформы. Команда маленькая, требования завышенные, в общем, типичный стартап.

Зачем что-то менять?


Начав разрабатывать проект я решил поставить для себя несколько целей:
  • уверенность в том, что именно сейчас работает на продакшене;
  • по возможности исключить человеческий фактор;
  • автоматизировать все возможное.

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

Еще одна из частых проблем это срочные фиксы, которые должны быть сделаны уже вчера. Иногда, программист вынужден сам лезть на сервер и делать правки на живую. К сожалению, это, зачастую, становится причиной бессмертных багов, которые просто забыли добавить в репозиторий. Будьте уверены, при следующем релизе баг снова всплывет.

Автоматизация рутиных задач необходима для освобождения рук, в условиях ограниченной команды и для помощи в самоконтроле.

Ингредиенты


После продолжительных поисков оптимальных решений я остановился на довольно интересной связке. В первую очередь у нас, естественно, имеется Git, с ветками master и staging. Master содержит то, что сейчас на продакшене. А ветка staging, является будущим ветки master. Стоит помнить, что staging это не тестовая ветка, как принято у многих, а именно будущий master и относиться к ней надо соответствующе. Нами, в качестве git’а был использован Bitbucket.

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

Для проверки проекта автоматическими тестами потребуется любая CI (Continious Integration) платформа. В нашем случае это был TeamCity. Перед использованием, следует настроить 3 отдельных этапа: только быстрые тесты, долгие тесты и вообще без тестов. Почему именно так, объясню ниже. И напоследок вооружаемся тулзой для деплоя, например capistrano.

Как это работает


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

На данном этапе еще никакой магии нет и все вполне привычно. В процессе работы над задачей разработчик может периодически оставлять комиты с комментариями. В каждом комментарии должно быть указано к какой или каким задачам он относится. Это достаточно важно, так как на сервере гита при каждом комите информация о нем отправляется в небольшой скрипт. Он парсит комментарий и постит в удобном виде ссылку на комит, сразу в багтрекер. Благодаря этому можно видеть историю изменений кода относительно именно этой задачи. В комите можно указывать несколько номеров, для случаев когда задача уже закрыта, а в ней нашли баг, который смогли исправить решая другую задачу. И чтобы потом долго не искать где это было исправлено, можно в комите с фиксом указать номер закрытой задачи, так сообщение отобразится в обоих тасках. Такой переброс комитов в багтрекер позволяет избавиться от постоянных отписываний в задачу о проделанной работе, и менеджер всегда в курсе процесса. Но, иногда удобнее сделать несколько комитов с коротким описанием и потом добавить более развернутый комментарий в таск о том, что в них было сделано.

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

В случае успешного прохождения тестов, CI переходит к автоматическому деплою проекта, на тестовый сервер, в отдельную папку, с номером таска в имени. На этом сервере стоит nginx и настроен так, чтобы имя папки было названием поддомена на тестовом домене. Тем самым разработчик может проверить свое творение на внешнем сервере. Это бывает полезным когда надо проверить работу, к примеру с платежными системами в которые передается ссылка для оповещения о смене статуса платежа.

Когда наш трудолюбивый программист решил, что закончил задачу, ему достаточно просто перевести в багтрекере ее статус в testing и приступить к следующей. После смены статуса тестировщик получает извещение о том что эту задачу можно проверять. Первым делом он должен проверить статус тестов с последнего комита, и в случае неудачи сразу вернуть таск автору. Если все тесты прошли, то соответственно, у него уже есть домен на котором он может их смело проверять. После проверки тестировщик добавляет комментарий в таск, что все ок или описывает найденные проблемы и возвращает программисту сменив статус задачи. Если есть проблемы, то все повторяем, а если нет, то мержим ветку задачи в staging. При появлении комита в staging CI запускает уже более длительные юнит-тесты и функциональные на реальной базе.

Кстати, про реальную базу… раз в неделю, небольшим скриптом, работающим по крону, делается клон реальной базы на staging сервер, естественно, с подменой емейлов и очисткой личных данных пользователей. По окончании всех тестов, в случае успеха, CI делает деплой на тестовый сервер, чтобы тестировщик мог еще раз проверить, что после мержа ничего не поломалось.

В конце спринта мы просто мержим staging в master и CI, без каких-либо тестов, деплоит проект в продакшен. Так как staging ветвится от конца master, и ни одна задача не мержится в master минуя staging, то проблем с мержем ветки staging в master никогда не бывает. Если все работало на staging, то оно будет работать и на master. Различные казусы связанные с железом или реальной базой решаются индивидуально. После чего надо привести staging в соответствие с master, чтобы в будущем подобную проблему видеть еще до деплоя на продакшен.

Что мы имеем в итоге?


В первую очередь достигнутые цели:
  • На продакшене мы всегда имеем только законченные и проверенные задачи.
  • Ни один из разработчиков не имеет прямого доступа на продакшн. Деплой происходит только через мержи веток.
  • По возможности автоматизированы рутиные процессы, связанные с ведением задач, запуском тестов, разворачиванием тестового пространства. У каждого в команде не больше 2-х рабочих инструментов (у разработчика багтрекер и git, у тестировщика багтрекер и CI).

Во-вторых, это удобство работы. Почти все управление и взаимодействие происходит через гит. А благодаря интеграции багтрекера Youtrack с jabber’ом, для управления карточками даже не надо заходить в веб-интерфейс. При грамотном использовании чат-ботов (например hubot) можно и от интерфейса CI уйти полностью, узнавая статусы через jabber.

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

Если у кого-нибудь появятся еще идеи по улучшению системы и оптимизации рабочего процесса, буду очень рад послушать. По возможности попробую внедрить и добавить в статью выводы и опыт.
AdBlock похитил этот баннер, но баннеры не зубы — отрастут

Подробнее
Реклама

Комментарии 21

    +2
    Фундаментальный вопрос: как вы делаете хотфиксы?

    Ну и по мелочи:

    >> Когда наш трудолюбивый программист решил, что закончил задачу, ему достаточно просто перевести в багтрекере ее статус в testing и приступить к следующей.
    >> После смены статуса тестировщик получает извещение о том что эту задачу можно проверять.
    >> Первым делом он должен проверить статус тестов с последнего комита, и в случае неудачи сразу вернуть таск автору.
    А почему проверка статуса тестов не делается автоматически с откатом задачи обратно разработчику?

    У нас, например, хотя так далеко все и не зашло, зато код, не проходящий быстрые тесты, нельзя даже зачекинить (в вашей терминологии — смержить в серверную ветку).
      –1
      Конечно любые правила не без исключений. Совсем в критичных ситуациях таск мержится в master минуя staging. После чего master сразу мержится в staging, про прогона тестов и для актуализации ветки. Такие случаи бывали, но в большинстве случаев мы все же решаем делать откат релиза и в течении спринта без аврала фиксим. Спринты у нас короткие всего 1 неделя, поэтому обновляем небольшими порциями и фиксы приходят быстро.

      По поводу возврата задачи, у нас тоже такая идея была, но просто рук не хватило пока реализовать. Но я думаю скоро тоже сделаем и я добавлю это в статью.
      А в Вашем случае, я так понимаю запрет сделан на прекомит хуках?
        0
        >> Совсем в критичных ситуациях таск мержится в master минуя staging.
        «и CI, без каких-либо тестов, деплоит проект в продакшен. „
        … не делайте так.

        >> Спринты у нас короткие всего 1 неделя, поэтому обновляем небольшими порциями и фиксы приходят быстро.
        У нас тоже итерации в неделю, но за неделю бывает до десятка хотфиксов.

        >> А в Вашем случае, я так понимаю запрет сделан на прекомит хуках?
        В нашем случае запрет сделан на TFS Gated Checkins.
          –1
          Критичными ситуациями я называю те в которых нет времени на долгие тесты. Быстрые тесты в любом случае пройдут, а долгие пойдут параллельно с деплоем при мерже ветки master в staging.

          Если проблема не критичная, но и до конца спринта ждать не может, то фикс проходит через staging и деплоится вместе с тем что уже накопилось за часть спринта.
            0
            >> фикс проходит через staging и деплоится вместе с тем что уже накопилось за часть спринта.
            Это уже не хотфикс — у вас может быть так, что в стейджинге есть проблемы, не связанные с фиксом, и они блокируют его выкатку.
              –1
              если с таском есть проблемы то он откатывается из staging и доделывается в своей ветке. при необходимости staging можно смержить в ветку таска для воспроизведения проблемы.
                0
                Линейность нарушается. Всего этого можно было бы избежать, имея тесты на мастере.
                  –1
                  Суть в том что надо рассматривать staging именно как будущий master и вести его так что бы его в любой необходимый момент можно было выкатить. Если на master'е проводить тесты, то они будут полностью дублировать тесты со staging'а. Это может очень сильно увеличить время деплоя. В нашем случае master служит только как метка для понимания того что сейчас на продакшене. Таким образом важной веткой за которой действительно надо следить становится staging.
                    +1
                    >> вести его так что бы его в любой необходимый момент можно было выкатить.
                    Для этого нужен автооткат любого мержа в стейджинг сразу по падению теста.
                      –1
                      Не спорю, нужен. Надеюсь в скорое время будет.
      +1
      Еще вопрос — как вы делаете откаты ошибочного функционала?
        +1
        Если срочно, то через capistrano делается rollback. В остальных случаях откатывается мерж коммит. Все мержи мы делаем с ключом --no-ff, поэтому они в истории в виде отдельного коммита, который можно дотаточно быстро откатить.
          +1
          почему не используете теги? после каждого релиза можно создавать теги, тем самым точно так же можно быстро откатывать функционал(кроме бд)
            0
            Можно и теги, но откатываем не так часто, поэтому нет смысла давать каждому релизу имя когда обычно нужно откатить не больше 1-2 мержей.
        +1
        У каждого в команде не больше 2-х рабочих инструментов

        Это вообще что за метрика такая, и чем наличие трех или четырёх инструментов хуже? Представьте себе специалиста вообще любой профессии, хвастающегося тем, что он работает всего двумя инструментами.
          0
          А представьте себе разработчика, которому надо помимо написания кода, написать о том что сделал в таске, запустить тесты, написать тестировщику что можно проверять, самому задеплоить, зайти еще на какой-нибудь сервис поставить там галочку, зайти еще в одно место чтобы указать время затраченное на задачу и т.д. В некоторых случаях список можно продолжать и продолжать. Чем больше используется инструментов, тем больше разработчику приходится отвлекаться от работы, тем чаще подстраиваться под разные интерфейсы, и как пример, тем дольше вводить в курс дела нового сотрудника.

          Не просто так большинство сервисов стремятся к принципу «все в одном».
            +1
            Дело не в количестве инструментов, а в общем построении рабочего процесса. Можно и с двумя инструментами такого наворотить, что по 5 минут будет на закрытие таска уходить, а можно и с тремя инструментами свести всё к трём кликам.
          0
          Git flow.
          Есть ли смысл рассказывать об удобствах?
            0
            Git flow это только идеология ведения git'а. Не спорю что здесь он присутствует, но акцент на связке с другими инструментами.
            0
            CI постоянно мониторит гит репозиторий и по каждому комиту в тасковых ветках запускает процесс выполнения тестов.

            А почему бы не сделать наоборот — git вызывает CI и прогонку тестов при выполнении каких-либо условий? В таком случае можно значительно снизить нагрузку на сам CI сервер, как мне кажется.
              0
              Для этого git должен уметь обращаться по api к CI. Не везде есть интеграция c api конкретного используемого CI. Придется писать дополнительный промежуточный скрипт. А вот мониторинг репозитория есть почти в каждом CI. Поэтому просто идем от того что проще.

            Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

            Самое читаемое