Автоматизируем выбор ревьюра с помощью GitLab CI и Danger JS

Моя цель - предложение широкого ассортимента товаров и услуг на постоянно высоком качестве обслуживания по самым выгодным ценам.

Всем здравствуйте! Меня зовут Михаил Авдеев и я работаю в проекте Облако Mail.ru! Я расскажу о том, как решал задачу ускорения проверки merge request’ов(MR)  в нашей команде. Почему вообще это понадобилось? Потому что разработчики ленивы экономят силы и обычно не стремятся брать новые MR на проверку, либо выбирают что попроще. Так что я решил сделать бота, который для каждого MR автоматически расставлял бы приоритеты и назначал проверяющего.

Идея

Сначала мы пытались решить задачу с помощью бота, идею для которого мы почерпнули у команды Календаря. Он должен был выбирать открытые merge request’ы и слать их в рабочий чат. Написали бота на TypeScript и создали чат. Но схема была рабочая, пока команда была небольшой, а когда она разраслась и количество MR увеличилось, люди смотрели на список задач в чате и старались выбрать ту, что поменьше да попроще. В результате я решил делать бота для GitLab, который принудительно распределял бы обязанности в коллективе высокомотивированных и высокоинтеллектуальных работников умственного труда. Заодно бот избавил бы авторов от творческих мук выбора проверяющих для своего кода.

Ещё бот должен был быть универсальным, чтобы им могли пользоваться не только в нашей команде. Для этого требовалось продумать его настройки и интеграцию с сервисом VK Teams. Идея была в том, что бот не только назначает проверяющего для MR, но и шлёт об этом сообщение ему и автору кода.

Решение

У меня уже был опыт создания ботов, поэтому я выбрал знакомые мне технологии: Gitlab CI и Danger-js. Сколько времени у вас может уйти на создание подобного инструмента, не подскажу, всё зависит от вашего CI. Мне нужно было интегрировать бота с VK Teams, а у вас может быть другой мессенджер, Slack или Telegram, к примеру. В настройки я заложил возможность выбирать количество проверяющих для каждого MR, чтобы бот подходил под разные рабочие конвейеры.

Мой бот шлёт в мессенджер такие сообщения:

А в конвейер GitLab — такие:

Также бот позволяет добавлять к каждому MR какой-нибудь тег, чтобы удобно было классифицировать изменения в коде. В нашем проекте, к примеру используется тег need-review. Если в настройках вашего проекта это предусмотрено, вы можете выделить специальный тег, позволяющий пропускать проверку конкретного merge request’а. Также бот должен пропускать запуск, если MR помечен как draft или wip.

Бот интегрирован в нашу внутреннюю платформу Mail Core CI, чтобы его могли использовать многие другие команды в компании, но вы можете приспособить его и под вашу среду. Как это сделано у нас:

# Джоба для вызова dangerjs в пайплайне через нашу обертку (npx ts-node cli danger)
.mail-core:job:danger-init:
 stage: test
 needs: []
 variables:
   DANGER_ID: "<<required>>"
   DANGERFILE: "<<required>>"
 script:
   - echo "danger:" $([[ -f ./node_modules/.bin/danger ]] && (./node_modules/.bin/danger --version 2>/dev/null || "[--version not found]") || echo "[file not found]")
   - echo "dangerfile:" $DANGERFILE
   - time [[ -d cli/command/danger ]] && npx ts-node cli danger ci --dangerfile=$DANGERFILE --id=$DANGER_ID -f
 
# Джоба для вызова ревью рулетки
.mail-core:job:review-roulette:
 extends: .mail-core:job:danger-init
 variables:
   # Минимальное количество Review Approvers
   REVIEW_ROULETTE_MIN_APPROVERS: 1
   DANGER_ID: "review-roulette"
   DANGERFILE: "./node_modules/@mail-core/ci/dangerfiles/review-roulette/index.js"

Логика работы бота

При появлении нового merge request’а Gitlab СI автоматически запускает свой runner. Бот просматривает настройки проекта:

const {REVIEW_ROULETTE_LABEL, REVIEW_ROULETTE_MIN_APPROVERS} = process.env;
const {mr, approvals, api, metadata} = danger.gitlab;
const {repoSlug, pullRequestID} = metadata;
const {iid, author, reviewers, web_url, title, description, labels, draft} = mr as MR;
const {suggested_approvers, project_id, approved_by, approvals_required} = approvals as Approvals;
const mrLink = `[${repoSlug}!${pullRequestID}](${web_url})`;
const approvalsCount = approvals_required || Number(REVIEW_ROULETTE_MIN_APPROVERS);

И проверяет, можно ли пропустить проверку (в зависимости от присвоенного тега, количества ревьюеров и т.д.):

const skipReview = draft || isWip || hasApprove || hasSkipReviewLabel || reviewers.length !== 0;

Если пропустить нельзя, то бот берёт список доступных сейчас проверяющих:       

// алгоритм подбора рекомендуемых апруверов (у нас он реализован на основе файла CODEOWNERS)
const approvers = getSuggestedApprovers();

Случайным образом выбирает нужное количество людей:

// алгоритм выбора ревьюеров на ваше усмотрение
const reviewers = getReviewers(approvers, approvalsCount);

и отправляет им сообщения в мессенджеры (если те интегрированы) и в сам MR.

// Достаем из массива ревьеюров только их id (необходимы для отправки в gitlab api)
const reviewerIds = reviewers.map(({id}) => id);
const reviewerNames = reviewers.map(({name}) => name).join(', ');
const reviewerCountText = reviewers.length > 1 ? 'ревьюеров' : 'ревьюера';
// Получаем на основе ревьюеров email
const reviewerEmails = await getReviewerEmails(reviewers, api.Users);
const mentionedUsers = reviewerEmails.map((v) => `@[${v}]`).join(',');
 
// Добавляем выбранных ревьюеров в MR
await api.MergeRequests.edit(project_id, iid, {reviewer_ids: reviewerIds});


// Информируем автора MR о выбраных ревьюерах в VK Teams
await communicator.sendMessage(
      'author',
      `
      ${REVIEW_ICON} Я подобрал для *${mrLink}* (${title}) ${reviewerCountText}: ${mentionedUsers} 						
Источник: https://habr.com/ru/company/vk/blog/672372/


Интересные статьи

Интересные статьи

Привет, Хабр! Меня зовут Евгений Симигин, я занимаюсь внедрением DevOps-практик в Центре компетенций по разработке облачных и интернет-решений МТС Digital. А еще я – куратор практикумов docker и kub...
В этой статье мы рассмотрим, как система управления 1С-Битрикс справляется с большими нагрузками. Данный вопрос особенно актуален сегодня, когда электронная торговля начинает конкурировать по обороту ...
Некоторое время назад меня попросили сделать видео-инструкцию по настройке сети в операционной системе DOS. К сожалению в съёмке видео я не силен, поэтому постараюсь максимально подробно письменн...
Этот пост будет из серии, об инструментах безопасности, которые доступны в Битриксе сразу «из коробки». Перечислю их все, скажу какой инструмент в какой редакции Битрикса доступен, кратко и не очень р...
Несмотря на то, что все прекрасно знают, что тестировать свой софт важно и нужно, а многие давно делают это автоматически, на просторах Хабра не нашлось ни одного рецепта по настройке связки таки...