Автоматизация в разработке: 5 инструментов

0
417
views

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

Большинство из них достаточно просто внедрить в рабочий процесс. Но мы составили более подробные описания там, где есть какие-то особенности.

1. Dependabot

Автоматическое обновление зависимостей.

Dependabot создает пул-реквесты для поддержания зависимостей в обновленном состоянии.

Dependabot чертовски прост, а из описания кристально ясно, для чего он нужен. Мы начали использовать его пару лет назад, незадолго до того как его приобрел GitHub.

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

Сейчас Dependabot — нативная часть GitHub, так что добавить его в свои процессы еще проще, чем раньше. Настройку можно посмотреть в документации. Но в конечном итоге все сводится к файлу dependabot.yml в вашей папке .github.

Наш выглядит так:

version: 2
updates:
  - package-ecosystem: "npm" # See documentation for possible values
    directory: "/" # Location of package manifests
    schedule:
      interval: "daily"
    open-pull-requests-limit: 2
    commit-message:
       prefix: "BleedingEdge"

Несколько вещей у нас отличаются от настроек по умолчанию:

  • мы выбрали npm в качестве экосистемы пакетов
  • ограничили число открытых пул-реквестов двумя
  • добавили префикс для дефолтных сообщений коммитов Dependabot (позже вы увидите, зачем).

Четыре года назад у нас было три фронтенд-репозитория, сейчас их около 14 (активных). Поддержка всех зависимостей во всех репозиториях вручную отнимала бы слишком много времени. Dependabot очень помогает, но проверка и мерж всех пул-реквестов все равно требуют времени. Обычно мы выделяем один день после еженедельного релиза, чтобы смержить пул-реквесты Dependabot.

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

2. Auto Assign

Добавление ревьюеров / ответственных в пул-реквесты при открытии.

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

Это дело вполне можно доверить боту.

Настройка простая. Переходите по ссылке probot.github.io/apps/auto-assign, нажимаете кнопку Add to GitHub — и все, вам больше не нужно добавлять ревьюеров вручную!

Как и в случае с Dependabot, настройки хранятся в одном файле — auto_assing.yml.

# Set to true to add reviewers to pull requests
addReviewers: true

# Set to true to add assignees to pull requests
addAssignees: false

# A list of reviewers to be added to pull requests (GitHub user name)
reviewers:
  - teammember1
  - teammember2
  - teammember3
  - ...


# A number of reviewers added to the pull request
# Set 0 to add all the reviewers (default: 0)
numberOfReviewers: 0

# A list of keywords to be skipped the process that add reviewers if pull requests include it
skipKeywords:
  - BleedingEdge

У нас тут ничего неординарного. Мы используем опцию skipKeywords с ключевым словом BleedingEdge. Благодаря этому пропускаются пул-реквесты с указанным ключевым словом. Это слово мы установили в качестве префикса для всех пул-реквестов Dependabot. С ними мы разбираемся отдельно и не хотим нагружать этим делом ревьюеров.

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

Вы также можете попробовать использовать дефолтные настройки, которые GitHub предоставляет для Code Review Assignments. Просто перейдите на страницу вашей команды, в верхнем правом углу нажмите Settings — и вы найдете там вкладку Code review assignments. Мы это попробовали, но нам не подошло.

3. Merge Freeze

Инструмент замораживания кода для блокировки мержа и деплоймента.

Причина добавить Merge Freeze проистекает из простого вопроса:

«Можете сказать всем разработчикам прекратить мержить код, потому что мы начинаем регрессионное тестирование?»

Мы можем сообщать об этом в канале команды в надежде, что все вовремя прочитают сообщение. Или можем интегрировать специальный инструмент. Он позволяет QA-специалистам запустить в Slack команду, которая заморозит (или разморозит) мерж в репозиторий. Этот инструмент — Merge Freeze.

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

Для решения этой проблемы мы использовали Slack Apps и AWS Lambda.

Мы создали пользовательское Slack-приложение для нашего рабочего пространства (назвали его Deployment). В нем есть две слэш-команды: /freeze_all и /unfreeze_all. Обе они имеют Request URL, для которого установлен наш Lambda url. Команды передают значение freeze в виде параметра запроса: ?freeze=true | false.

Использование всего этого в Slack выглядит следующим образом:

Для каждого добавляемого вами репозитория Merge Freeze предоставляет конечную точку API. Ее вы можете использовать для замораживания или размораживания этого репозитория. Это упрощает задачу Lambda: сервис просто отправляет POST-запрос на каждую из конечных точек, предоставляемых Merge Freeze.

const https = require('https');

exports.handler = async (event) => {

  const freezeValue = getFreezeValue(event);
  if (!freezeValue) {
    return {
      statusCode: 400,
      body: JSON.stringify('BOOM! You need to provide a freeze value as a query param, either true or false'),
    };
  }

  const userName = getUserName(event)

  const baseOptions = {
    hostname: 'mergefreeze.com',
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      'Content-Length': 0,
    },
  };

  const appOneOptions = {
    path: `/api/branches/your-organization/your-repo/main/?access_token=${process.env.ACCESS_TOKEN}&frozen=${freezeValue}&user_name=${userName}`,
    ...baseOptions,
  };
  ...
  /** Removed the rest of declaration to keep the preview short */


  await Promise.all([
    doRequest(appOneOptions),
    ...
    doRequest(appElevenOptions),
  ]);

  console.log("I'm done with all your promises!");

  // Text that gets return to Slack that is only visible to the person entering the command
  return {
    statusCode: 200,
    body: JSON.stringify('You have such power!!!'),
  };

  function doRequest(options) {
    return new Promise((resolve, reject) => {
      const req = https.request(options, (res) => {
        res.setEncoding('utf8');
        let responseBody = '';
        res.on('data', (chunk) => responseBody += chunk);
        res.on('end', () => resolve(responseBody));
      });

      req.on('error', (err) => reject(err));
      req.end();
    });
  }

  function getFreezeValue(event) {
    let freezeQueryString;
    let freeze;

    if (event && event.queryStringParameters && event.queryStringParameters.freeze) {
      freezeQueryString = event.queryStringParameters.freeze;
    }

    if (freezeQueryString === 'true' || freezeQueryString === 'false') {
        freeze = freezeQueryString;
    }

    return freeze;
  }

  function getUserName(event) {
    const bodyQueryParams = new URLSearchParams(event.body);
    return bodyQueryParams.get('user_name') || 'Web API';     
  }
};

После ввода команды Merge Freeze перечисляет все репозитории, которые были заморожены или разморожены, а вы получаете сообщение с подтверждением от Slack.

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

4. Husky

Легкое создание современных нативных хуков Git.

В качестве инструмента менеджмента мы пользуемся Jira. Поэтому добавляем идентификатор тикета к именам веток и к сообщениям коммитов, чтобы при просмотре issue использовать и панель Development, и расширение GitLens (VS Code).

Это означает, что каждый раз при создании ветки нужно не забыть включить в ее имя issue-ID из Jira. Пример имени с таким префиксом — task-ND-123-add-authentication. Само по себе это не составляет проблемы: быстро входит в привычку. Но вот добавление этого префикса к каждому сообщению коммита — настоящая головная боль.

Первая попытка автоматизации заключалась в настройке git-хука prepare-commit-message на локальной машине. Но по мере роста команды мы стали нуждаться в лучшем решении, которым стал Husky!

Сочетание Husky с jira-prepare-commit-msg нам отлично подошло:

...
  "private": true,
  "husky": {
    "hooks": {
      "prepare-commit-msg": "jira-prepare-commit-msg"
    }
  },
  "jira-prepare-commit-msg": {
    "messagePattern": "$J $M",
    "jiraTicketPattern": "(\\w+-\\w+-\\d+)"
  },
  "dependencies": {
...
  "devDependencies": {
    "husky": "^4.3.8",
    "jira-prepare-commit-msg": "^1.5.2",
...

ID тикета JIRA берется из имени ветки git. После этого вы просто пишете commit -m "Fixing a typo" и получаете сообщение коммита типа task-ND-123-Fixing a typo.

Если вы вдруг неправильно назовете свою ветку, скажем, пропустите тикет-ID, вы получите ошибку:

my-application git:(main) ✗ git commit -m "Add authentication methods"
husky > prepare-commit-msg (node v14.15.0)
JIRA prepare commit msg > start
JIRA prepare commit msg > Error: The JIRA ticket ID not found
JIRA prepare commit msg > done

Все настройки хранятся в package.json. Каждый новый член команды просто выполняет npm i — и настройка готова, конфигурировать хуки вручную не нужно.

Но наибольшую пользу нам принесло сочетание тикет-ID Jira в сообщениях коммитов с GitLens.

GitLens с примечаниями Git blame:

У нас было много случаев, когда нам приходилось (по разным причинам) открывать и читать Jira issue, к которому было привязано изменение кода. Когда у вас во всей кодовой базе идентификаторы тикетов находятся на расстоянии клика мыши, это экономит много времени.

(Открывать issue в браузере тоже просто. Возьмите Jira ID и добавьте после .../browse/ + ND-123. Например, https://your-organization.atlassian.net/browse/ND-123).

GitLens — очень крутой инструмент, которым я пользуюсь ежедневно. Он помогает визуализировать авторство кода при помощи примечаний Git blame и линз кода. Вы также можете запросто перемещаться назад по истории, чтобы просмотреть предыдущие коммиты — это тоже полезно.

5. Напоминания о пул-реквестах, приходящие по расписанию

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

Это улучшение в своей работе мы внедрили относительно недавно: незадолго до перехода на архитектуру микрофронтендов.

Одной из причин изменений послужило то, что число репозиториев возросло с 4 до 14. Это сподвигло нас завести отдельный канал для открытых пул-реквестов.

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

Уведомления приходят каждый рабочий день раз в час с 8 до 16. Здесь мы также выставили игнорирование BleedingEdge, чтобы пропускать пул-реквесты, открытые Dependabot.

Настройка уведомлений, приходящих по расписанию, тоже простая. О ней можно почитать в документации.

На скриншоте ниже видно, как это выглядит, когда все настроено. В нашем случае сообщения постятся в приватный канал frontend-pull-requests.

Заключение

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

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

Если у вас есть свои интересные варианты автоматизации — поделитесь в комментариях!

Перевод статьи «5 tools to automate your development».