Идеальное создание бота Slack для вызова действий GitHub через Hubot

Если вы используете GitHub Actions в качестве своего конвейера сборки и развертывания, а ваша команда также использует Slack, знаете ли вы, что вам даже не нужно покидать Slack? Создайте Slack бота для вызова рабочих процессов GitHub Actions непосредственно из Slack автоматически!

В этом руководстве вы узнаете, как настроить нового чат-бота Slack с использованием инструмента для создания ботов под названием Hubot и автоматически запустите рабочий процесс GitHub Actions для развертывания кода на сервер.

Давайте погружаться!

Необходимые условия

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

  • A Slack Workspace
  • A GitHub account and a GitHub personal token
  • A Linux server to deploy code to – This tutorial will use Ubuntu 19.
  • A local Linux machine – This tutorial will use Ubuntu so that all local commands will be Linux. If you’re running another operating system, the commands may be slightly different.
  • SSH-полномочия для подключения к серверу, на который вы будете разворачивать код.
  • A code editor of your choice that understands YAML like Visual Studio Code.

Создание проекта и рабочего процесса GitHub Actions

Прежде чем вы сможете быстро вызывать рабочие процессы GitHub Actions из Slack, вам нужно создать рабочий процесс.

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

1. Откройте ваше любимое приложение терминала.

2. Теперь выполните набор команд ниже, чтобы создать папку проекта с именем Hubot и перейти в нее.

mkdir ~/Hubot # Создать каталог с именем Hubot
cd ~/Hubot    # Перейти в каталог Hubot

3. Затем выполните npm init для создания файла package.json для Node.JS. Запуск npm init создает стандартный проект Node.JS, включая файл package.json, который содержит различную информацию о проекте и любых зависимых NPM-пакетах.

npm init      # Инициализирует файл package.json

4. Теперь создайте каталог workflows и файл deploy.yml файла рабочего процесса. Файл рабочего процесса – это последовательность шагов, определенных в последовательности, которую будут выполнять действия GitHub.

mkdir .github/workflows && touch deploy.yml

5. Затем определите каждый из секретов GitHub, которые будет читать ваш рабочий процесс. Созданный вами рабочий процесс будет ссылаться на эти секреты. Поскольку вам понадобится адрес вашего сервера, имя пользователя, пароль и порт вашего сервера для SSH, создадим секреты GitHub.

Посетите этот URL https://github.com/yourusername/yourrepository/settings/secrets/actions, где вы добавите ваши секреты GitHub. Замените yourusername своим именем пользователя GitHub и yourrepository своим репозиторием GitHub.

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

Adding GitHub Secrets

6. Теперь заполните поля Имя и Значение секрета, затем нажмите «Добавить секрет», чтобы сохранить его. Страница перенаправится на страницу секретов GitHub, где вы увидите все ваши секреты. Чтобы добавить еще секреты, нажмите кнопку Новый секрет репозитория, как вы делали ранее.

Убедитесь, что вы сохраняете секреты для заданных переменных с точно таким же именем, какое вы будете использовать при ссылке на эти переменные, а именно HOST, USERNAME, PASSWORD и PORT.

Filling up Information for a GitHub Secret
Viewing All GitHub Secrets

7. Наконец, откройте файл рабочего процесса ~/Hubot/.github/workflows/deploy.yml в вашем редакторе кода и скопируйте/вставьте следующий код. Код ниже представляет собой рабочий процесс, который будет выполняться всякий раз, когда вы запускаете рабочий процесс через Slack позже.

При вызове рабочего процесса произойдут несколько действий:

  • GitHub Действия будут анализировать файл рабочего процесса ниже для SSH-подключения к целевому хосту, определенному в секрете HOST, с ИМЕНЕМ ПОЛЬЗОВАТЕЛЯ и ПАРОЛЕМ, определенными как секреты.
  • Затем рабочий процесс загрузит содержимое репозитория GitHub для определенной ветки ($branchName), запустив git pull origin$branchName. Убедитесь, что имя ветки содержит код, который вы хотели бы развернуть.
  • Вы будете использовать Пакет рабочего процесса из Маркетплейса GitHub под названием ssh-remote-commands. Этот пакет имеет удобную оболочку для обхода, где вам нужно будет указать только хост, имя пользователя, пароль, порт и команду для запуска на производстве.

Убедитесь, что на вашем сервере установлен git с необходимыми учетными данными для входа для вытягивания кода из репозитория GitHub

# Имя, на которое будет ссылаться, делает с ним намного больше программируемо 
name: deploy 
on:
  # Событие respository_dispatch означает, что при каждом триггере API,
  # выполняется весь этот файл
  repository_dispatch: 
    types: [deploy-service]
# Может быть несколько задач, но в данный момент,
# в этом руководстве будет работать только одна
jobs:
  deploy:
    name: Deploy
    # Название базового образа, где выполняется весь код в YAML
    runs-on: ubuntu-latest
    steps:
    - name: executing remote ssh commands using password
      # appleboy/ssh-action@master - это открытый пакет,
      # который входит на сервер через ssh и выполняет скрипт
      uses: appleboy/ssh-action@master
      # Это, в основном, переменные, которые нужны пакету,
      # чтобы войти на сервер и выполнить скрипт
      with:
       # Секреты - это переменные из
       # https://docs.github.com/en/actions/security-guides/encrypted-secrets

       # Ваш хост сервера хранится в секретах GitHub с тем же именем HOST
        host: ${{ secrets.HOST }} 
        # Имя пользователя вашего сервера для входа,
        # которое хранится в секретах GitHub с именем USERNAME
        username: ${{ secrets.USERNAME }} 
        # Пароль вашего сервера для входа,
        # который хранится в секретах GitHub с именем PASSWORD
        password: ${{ secrets.PASSWORD }} 
        # Порт вашего сервера для входа,
        # который хранится в секретах GitHub с именем PORT
        port: ${{ secrets.PORT }}  
        # deploy-app.sh может быть чем угодно, например,
        # вы можете выгрузить код из GitHub
        # и перезапустить ваш веб-сервер или очереди и так далее
        # Убедитесь, что вы склонировали репозиторий на свой сервер
        script: git pull origin {{ github.event.client_payload.branch 

Выполнение рабочего процесса вручную

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

Выполнение серии команд ниже сообщает git, откуда должен загружаться и куда должен загружаться код, в данном примере – из вашего удаленного репозитория GitHub. В команде git remote add origin ниже замените yourusername и yourrepository на свое имя пользователя и репозиторий GitHub

# Откройте github.com и создайте репозиторий
git init # Инициализирует git
git remote add origin https://github.com/yourusername/yourrepository.git
git add . # Добавляет новые созданные файлы для отслеживания git
git commit -m "Created GitHub workflow file"
git push -u origin master

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

Выполните команду ниже, чтобы выполнить POST-запрос к вашему репозиторию GitHub по адресу https://github.com/username/repository/dispatches, чтобы сообщить GitHub о запуске файла рабочего процесса deploy.yml, который вы создали ранее. Замените username на ваше актуальное имя пользователя GitHub и repository на ваш репозиторий GitHub.

Замените $github_personal_token в приведенном ниже коде на ваш персональный токен.

# Отправляет запрос типа post по адресу https://github.com/username/repository/dispatches
curl-X POST  https://github.com/username/repository/dispatches \
# Добавляет заголовок для принятия типа содержимого
-H 'Accept: application/vnd.github.everest-preview+json' \
# Добавляет заголовок для авторизации
-H "Authorization: token $github_personal_token" \
# Добавляет содержимое json в тело post-запроса, чтобы можно было отправлять несколько параметров
# из этого раздела данных, и вы можете выполнять различные действия на основе аргументов
--data '{"event_type": "deploy-service", "client_payload": {"environment": "'"$1"'", "ref": "'"$2"'"}}' # Вы можете передать имя среды и ref в качестве имени ветки, чтобы знать, на каком сервере развертывать ветку

Создайте Slack Bot с Hubot

Поскольку вам удалось вручную запустить рабочий процесс GitHub Action, это хороший старт. Теперь давайте попробуем автоматизировать те же самые шаги через Slack Bot. Вы создадите Slack Bot, который слушает вашу команду и запускает GitHub Action с аргументами.

У вас есть два варианта создания Slack Bot: либо с нуля, либо с использованием предварительно созданного пакета Hubot для рабочих пространств Slack. В этом учебнике вы будете использовать предварительно созданный пакет Bot под названием Hubot. Hubot – это инструмент автоматизации с открытым исходным кодом, который интегрируется с чат-сервисами, такими как Slack, Discord, Gitter, TeamSpeak и др.

Пересоздание пользовательского бота без использования приложения, например, Hubot, занимает много времени. Почему? Потому что вы обрабатываете все процессы настройки, прослушивание вебхуков и размещение бота. Так что в этом учебнике вы будете использовать приложение Hubot Slack для упрощения всех этих процессов.

Установка Hubot с помощью Npm

Поскольку вы используете Hubot для создания Slack Bot, давайте сначала скачаем и установим Hubot на вашем локальном компьютере. Hubot будет соединителем, который связывает Slack и действия GitHub.

1. В вашем терминале перейдите (cd) в каталог вашего проекта (~/Hubot).

cd ~/Hubot

2. Установите пакеты yo и generator-hubot глобально (-g) на вашем локальном компьютере с помощью команды npm install ниже. Пакет yo помогает устанавливать новые проекты, генерируя их на любом языке (Web, Java, Python, C# и т.д.). Пакет generator-hubot использует пакет yo для установки всех зависимостей вместе с начальными настройками.

После установки вы можете запустить команду yo откуда угодно, так как она была установлена глобально.

npm install -g yo generator-hubot

3. Теперь создайте базовый шаблон Hubot с помощью следующей команды. Шаблон – это раздел кода, включенный во многие места. Без шаблона вам всегда придется писать код с нуля.

Команда ниже создает базовый шаблон Hubot в вашем каталоге проекта. Шаблон Hubot связывает Slack (--adapter=slack), чтобы бот мог прослушивать и отвечать на сообщения внутри канала Slack. yo hubot --adapter=slack

yo hubot --adapter=slack

Добавление Hubot в ваше рабочее пространство Slack

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

Давайте установим Hubot в вашем рабочем пространстве Slack.

1. Откройте веб-браузер и перейдите в настройки администратора Slack по URL-адресу, например, https://workspacename.slack.com/admin/settings. Замените workspacename на фактическое имя вашего рабочего пространства Slack.

Нажмите на Настроить приложения о в левой панели, как показано ниже, чтобы вы могли искать Hubot в маркетплейсе. У Slack есть маркетплейс, где вы можете найти готовые приложения.

Accessing Slack Admin Settings

2. Нажмите на строку поиска, затем введите hubot, чтобы найти Hubot в маркетплейсе и выберите Hubot.

Теперь нажмите кнопку Добавить в Slack, как показано ниже, чтобы добавить Hubot в ваше рабочее пространство Slack.

Searching Hubot and Adding it to Slack Workspace

3. Наконец, заполните некоторую общую информацию о вашем боте, такую как имя (deployerhubot) и значок. Обратите внимание на API-токен, поскольку вы будете использовать его позже в Hubot Deployer, чтобы активировать бота из вашего проекта Hubot, который вы создали ранее.

Setting up Bot Information and Taking Note of the API Token

Тестирование интеграции рабочего процесса GitHub Actions с Slack

Теперь у вас установлен Hubot в вашем рабочем пространстве Slack, так что давайте протестируем бота, прослушивая и отправляя сообщения в канал. Но сначала вам нужно активировать бота.

1. Выполните команду ниже в корневом каталоге проекта, чтобы активировать бота для Slack (--adapter slack) из вашего репозитория Hubot (./bin/hubot). Обязательно замените $token на API-токен, который вы ранее отметили

HUBOT_SLACK_TOKEN=$token ./bin/hubot --adapter slack

2. Выполните следующую команду, чтобы пригласить (/invite) бота (botusername) в ваш канал Slack. Замените botusername на имя бота, которое вы зарегистрировали на третьем шаге раздела «Добавление Hubot в ваше рабочее пространство Slack».

/invite deployerhubot

Теперь упомяните бота с текстом в Slack, например, @deployerhubot ping, чтобы проверить, работает ли интеграция. Если бот отвечает PONG, как показано ниже, значит, все настроено правильно.

Testing Hubot and Slack Integration

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

Viewing Failed Workflows

Ниже вы можете видеть, что сбой произошел при выполнении удаленных ssh-команд с использованием пароля в executing remote ssh commands using password. После устранения этой проблемы вернитесь на шаг 3 и проверьте, отвечает ли бот PONG.

Navigating to GitHub repository to fix failed workflow

Запуск рабочего процесса GitHub Actions из Slack

Теперь, когда вы активировали своего Slack бота, пришло время запустить рабочий процесс GitHub Actions из Slack!

Вам нужна гибкость для развертывания заданной ветки на заданный сервер, например, для выгрузки кода из заданной ветки. Вы научите бота автоматически реагировать, когда кто-то вводит ***@*bot deploy API feature-x to production в канале Slack. Вы можете проверить имя среды, в которой позже люди могут развертывать только определенные среды и ветки.

Чтобы автоматизировать ответы бота:

1. Создайте каталог с именем ~/Hubot/scripts. Каталог ~/Hubot/scripts – это место, где вы сохраните сценарий, который вызывает ваш рабочий процесс GitHub.

2. В вашем редакторе кода создайте файл с именем bot.js внутри каталога ~/Hubot/scripts. Теперь скопируйте приведенный ниже код и вставьте его в файл bot.js.

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

const validServices = ['api','app'];
const validEnvironments = ['production'];
robot.hear (`@${process.env.BOT_ID}`,async (bot) => {
    // Бот заинтересован только в прослушивании сообщения 
    // например, @deploy api featurex на производство 
    // Настройка повторно используемой переменной
	  const payload = bot.message.text.split(" ")
    const service = payload[2];
    const branch = payload[3];
    const environment = payload[5];
    const username = bot.message.user.name;
    // Уведомить пользователя о том, что мы обрабатываем
    bot.send(`Roger that! Please wait.`);
// Проверить, является ли использованная команда допустимой или нет 
// потому что пользователь также может использовать недопустимые команды 
if(!validateCommand(bot,username,service,branch,environment)) {
      return;
    }
    // Если команда кажется допустимой, то запустить рабочий процесс
    await triggerWorkflow(bot,username,service,environment,branch)
    
    // Уведомить пользователя о том, что рабочий процесс успешно запущен
    bot.send(`Github Action has been triggered successfully`);
  })
  const validateCommand = (bot,username,service,branch,environment) => {
    // Ограничить услуги, так как пользователи могут использовать услуги, которые не указаны 
    // которые попытаются запустить рабочий процесс и получат ошибку
    if(!validServices.includes(service)) {
       bot.send(`${service} is not availble, Only ${validServices.join(', ')} are available`);
      return false;
      }
      // Ограничить среду, так как пользователи могут использовать недопустимый список сред
      if(!validEnvironments.includes(environment)) {
        bot.send(`${environment} is not availble. Only ${validEnvironments.join(', ')} are available`);
        return false;
      }
      return true;
  }

  const triggerWorkflow = (bot,username,service,environment,branch) => {
    try {
      // Это тот же код ручного запуска рабочего процесса, преобразованный 
      // из curl в фактический запрос на javascript post
      const data = await axios.post(`https://api.github.com/repos/yourusername/yourreponame/dispatches`,{
        'event_type': 'deploy-service',
        'client_payload': {'environment': environment, 'ref': branch}
      },{headers:{
      Authorization: `token ${token}`,
      }})
    }
      catch(e) {
        bot.send(`Sorry @${username} could not trigger github action. Please check my logs ${e.message}`);
      }
  }

3. Наконец, отправьте сообщение @botusername deploy api staging to dev в Slack, и вы увидите аналогичный ответ, как показано ниже.

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

send the @botusername deploy api staging to dev message in slack

Заключение

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

Вы возьмете этот новый опыт на новый уровень, возможно, добавив Бота-напоминалку или создание интерактивных сообщений?

Source:
https://adamtheautomator.com/create-slack-bot/