Хабрахабр

Один бот от всех забот

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

6 букв.
Консервативный распорядок и метод работы, рабское следование заведённому шаблону, превратившееся в механическую привычку.

Есть такая работа, которую делать не хочется, но нужно. В этой статье не будет больших вставок с кодом и инструкции как создать своего бота с нуля. Лучше я расскажу как устроен релизный процесс у нас в Dodo Pizza, как мы автоматизируем и ускоряем его, отдавая часть скучной рутины нашему боту, написанному на C#. Уделю внимание функционалу и логике работы бота. Будет круто, если этот материал вдохновит вас на написание своего помощника, который облегчит жизнь вам и вашим коллегам.

В мае 2018, имея максимальный показатель 147 часов на релиз, мы ставили цель релизиться каждый день. Пару лет назад мы выпускали один релиз раз в неделю. Мы хотим закрепить рекорд и иметь возможность свести весь процесс к нажатию одной кнопки. Сейчас наш минимум: четыре часа на релиз, но такое происходит не часто.

Релизный цикл

Сейчас в Dodo IS семь команд по очереди занимаются выпуском релиза. Один человек от команды становится «счастливчиком» – релизмэном. Релизмэн как пилот самолета: у него куча рычажков и приборов, которыми нужно умело орудовать, чтобы выкатить очередные обновления. Мы подумали и решили: «Пришло время сделать автопилот, а своё время лучше потратим на что-то более захватывающее, чем заполнение скучных таблиц со статистикой и слежку за прогонами автотестов».

Чтобы всё было наглядно и никто не путался, мы наклеили на стену стикеры с названиями команд. Итак, чтобы стать релизмэном, нужно чтобы до твоей команды дошла очередь. Релизная команда получает почетную корону, которую мы каждый раз передвигаем ручками.

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

Пришло время отдать часть скучной рутины боту. Собрав волю в кулак, мы решили, что хватит это терпеть. Когда, если не сейчас? Кто, если не мы?

Что нам удалось автоматизировать

Решение принято, пора начинать конструировать наш автопилот! Найдя Kaiten API тут: https://faq.kaiten.io/docs/api, мы всего одним запросом создали карточку для нового релизмэна.

// Делаем POST запрос на создание карточки
var createCardRequest = new RestRequest("https://<domain>.kaiten.io/api/latest/cards/", Method.POST); // Добавляем информацию для авторизации
AddBasicAuth(createCardRequest); // В теле запроса укажем на какой доске со-дать карточку и как ее назвать
createCardRequest.AddJsonBody( new " }
);

Теперь эту карточку нужно вручить команде, которая релизит следующей.

Логика здесь такая:

Предыдущий релизмэн завершает релиз, набирая в Slack команду для бота.
2. 1. Для этого бот пробегается по группам пользователей Slack и смотрит, в какой их них состоит наш релизмэн.
3. Бот берет ID релизмэна в Slack и ищет, в какой команде разработчиков числится наш счастливчик. В сообщении бот заботливо дает ссылку на уже созданный чек-лист, чтобы никуда за ним не ходить. Найдя группу, бот смотрит, какая команда будет релизить следующей и отправляет в общий чат оповещение.

Теперь у нас есть подсказка что делать дальше. Прекрасно! Осталось научить этому нашего бота. Открываем чек-лист, смотрим в него: «Создайте канал для релиза в Slack, пригласите туда все команды, чьи изменения есть в релизе и узнайте у них, нужно ли будет ручное тестирование».

Открываем документацию по Slack API тут https://api.slack.com и ищем там метод создания канала.

Все сводится к отправке одного POST запроса с двумя обязательными параметрами (это те, напротив которых написано required). Как видите, в Slack, как и в других инструментах, нет ничего сложного. Обратите внимание на строчку «Works with: Token type — user, required scope(s) — channels: write». В запросе нам нужно передать название создаваемого канала (параметр name) и авторизационный токен (параметр token).

При выдаче токена, мы определяем какими правами наделить его владельца. У Slack есть два типа токенов: user – выдается пользователям и bot – выдается приложениям. Чтобы создавать каналы, нам нужен пользовательский токен (token type — user), у которого есть права на запись каналов (channels: write).

Изначально мы не продумали, что будем делать, если что-то пойдет не так. Хочу отметить один нюанс нашей отправки сообщений в Slack. А что будет, если на одной из задач в составе команды упадет? Мы набираем команду в Slack, и она выполняет все задачи, которые мы в нее вложили. И это плохо. В нашем случае ответ был: «ничего». Решением для нас стало писать в релизный чат, какое действие сейчас выполняется, и если команда не выполнилась, сообщать об ошибке в чат и логировать ошибку.

Теперь, стартовав новый релиз с помощью команды “/startregress” мы не боимся что что-то упадет, а при повторном вызове команды будут выполняться с начала по второму разу. Вторым удачным решением стало подключение базы данных, в которой мы храним состояние выполнения действий команд. Создали канал в Slack – записали в базу статус об успешном выполнении и больше не возвращаемся к этому действию. Нам ведь не нужно каждый раз создавать новый канал в Slack, делать пулл-реквест и т.д.

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

Работаем мы по Gitflow. Следующими на очереди стали интеграция с Github и TeamCity. Когда хотим релизиться, берём ветку DEV, рабочую = зеленую = на которой проходят тесты, и от нее создаем релизную ветку.

Если тесты зеленые, как трава у дома, — вперед в GitHub, создавать релизную ветку и пулл-реквест! Для этого наш бот идет в TeamCity, смотрит там на запуск тестового прогона для ветки DEV.

Тут нам на помощь приходит Kaiten. При создании пулл-реквеста нам нужно добавить описание изменений, которые мы выкатываем. Так мы знаем и видим что у нас будет зарелижено. Наш бот создает колонку с названием релиза, берет задачи из колонки DEV и перемещает их в релиз. Теперь мы можем по каждому релизу посмотреть, какие задачи в нем вышли и, открыв карточку по ссылке, узнать все подробности по этим задачам. После перемещения бот копирует названия карточек и добавляет их в описание пулл-реквеста со ссылкой на сами карточки.

Для этого релизная ветка деплоится на окружение, приближенное к продакшн (называем мы его stage), и после деплоя тестируется. Почти можно релизить, осталось только хорошенько протестировать наши изменения. Бот запускает пайплайн во время старта регресса. Деплой и тесты у нас собраны в один пайплайн в TeamCity, а наша задача сводится к его запуску, и ожиданию, скрестив пальцы, что тесты пройдут нормально.

Стиснув кулаки, релизмэн переключался по ссылкам и инструментам: TeamCity, Kaiten, Slack, Github и это еще не всё! Напомню, что мы начинали с того, что все это делалось вручную. Релизмен набирает “/startregress” и откинувшись на спинку кресла наблюдает как наш бот: А теперь у нас есть целый набор действий из которых уже сформирована первая команду для бота.

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

Это дает разработке и бизнесу понимание, на что тратится время и что тормозит нас в доставке новых фич пользователям. Весь релизный процесс мы анализируем, записываем, сколько времени занимает каждый этап релиза. Значит что-то не так с нашими тестами, нужно уделить им больше времени и внимания. Сидим два дня и не можем прогнать тесты?! Каждый раз вписывая туда по одной дате и ставя время. Раньше, выполняя действия нашего чек-листа, мы заходили в Google Sheets минимум 5 раз.

Чтобы легко и непринужденно работать с таблицами подключаем к проекту нашего бота nuget-пакет Google. Окей, Google, автоматизируем и тебя! Sheets.v4. Apis. Выглядит этот запрос так: А дальше все происходит по аналогичной с другими сервисами по схеме: мы отправляем запрос, в котором говорим какое значение в какую ячейку вставить.

public void InsertEntry(string cellAddress, string value)
{
// Задаем из настроек лист в который будем вставлять значение - _googleSettings.SheetName и адрес ячейки в которую вставляем значение - cellAddress var range = $"{_googleSettings.SheetName}!{cellAddress}"; var valueRange = new ValueRange(); // Добавляем значпение которе нужно вставить в ячейку - value var objectsList = new List<object> {$"{value}"}; valueRange.Values = new List<IList<object>> {objectsList}; // Используя метод библиотеки Google.Apis.Sheets.v4 отправляем запрос на вставку значения в ячейку таблицы и идентификатором SpreadsheetId var insertEntryRequest = _service.Spreadsheets.Values.Update(valueRange, _googleSettings.SpreadsheetId, range); insertEntryRequest.ValueInputOption = SpreadsheetsResource.ValuesResource.UpdateRequest.ValueInputOptionEnum.USERENTERED; insertEntryRequest.Execute();
}

Настроив интеграцию с Google, мы подготовили вторую команду нашего бота “/update” и вот что она делает:

  • добавляет пустую строку, чтобы вставлять в нее значения
  • идет в GitHub, смотрит когда создали релизную ветку и добавляет дату ее создания в табличку
  • из TeamCity берет данные о первом запуске пайплайна и информацию о том, когда пайплайн успешно финишировал

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

Одним из решений было то, что теперь релизмен просто смотрит статус в одном из каналов Slack, где инфраструктура вывешивает разрешение на «взлет». Мы собрали встречу по оптимизации процесса релиза. Это удобней, чем постоянно спрашивать одно и то же и в 90% случаев получать ответ «Можно».

Отдельное спасибо стоит сказать новым разработчикам в компании. Такие, казалось бы, элементарные вещи почему-то сразу не пришли в голову. Ребятам, которые работали у нас давно, процесс не казался чем-то сложным, скорее чем-то привычным. Придя к нам они рано или поздно становились релизмэнами. Новые члены команды обратили наше внимание на точки роста и приняли активное участие в организации работы по улучшениям.

Наш релизный лайнер приземлился, от конца нас отделяет всего одна команда “/releasecomplete”. Тем временем мы подошли к последнему этапу. Что она делает:

  • мерджит пулл-реквест с релизом в ветку master
  • удаляет релизную ветку
  • создает описание релиза в GitHub
  • архивирует релизный канала в Slack
  • передвигает карточки в Kaiten из колонки «release-...» в колонку «Done» и удаляет релизную колонку
  • передает эстафету, приглашая релизить следующую команду

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

Теги
Показать больше

Похожие статьи

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

Кнопка «Наверх»
Закрыть