Уведомления о коммитах и деплоях в Trello через web-hooks gitlab

December 6, 2015

Зачем это всё?

Для автоматического добавления комментариев в trello при каждом коммите и перемещении тикета в столбец с проверкой после деплоя при упоминании номера карточки в commit message.

Что нужно?

  1. Ruby On Rails 3+
  2. Гем ruby-trello
  3. Репозиторий в GitLab

Приступим!

Добавляем gem в Gemfile

Gemfile:

gem 'ruby-trello'

и устанавливаем:

bundle

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

https://trello.com/1/connect?key=KEY&name=APPNAME&response_type=token&scope=read,write

где KEY – это полученный после перехода по первой ссылке ключ разработчика, а APPNAME – любое имя приложения, которое нравится :)

После этого выдадут токен, который надо запомнить и использовать на следующем шаге.

Добавляем обработчик для web-hook GitLab

Сначала надо добавить web hook в проект. Для этого надо зайти в настройки проекта, там выбрать пункт Web Hooks, в качестве URL указать http://example.com/api/trello, затем проверить, что стоит галочка на Push events, нажать ADD WEB HOOK. Собственно, example.com – это публичный адрес сайта.

Затем надо в config/initializers создать файл trello.rb, содержащий авторизационные данные для ruby-trello:

Trello.configure do |config|
  config.developer_public_key = KEY
  config.member_token = TOKEN
end

где KEY – это тот самый ключ разработчика, а TOKEN – это полученный на прошлом шаге токен.

После этого создаём контроллер для web-hook:

$ rails g controller api/trello

В app/controllers/api/trello_controller.rb пишем:

class Api::TrelloController < ApplicationController
  # пропускаем проверку csrf
  skip_before_action :verify_authenticity_token

  def create
    # получаем список коммитов
    commits = params[:commits]
    commits.each do |commit|
      message = commit[:message] # commit message
      # ищем в коммите номер тикета в trello вида #1234
      commit_id = message.scan(/#(\d+)/).flatten.first
      if commit_id # если найден
        # ищем доску по ID (для получения списка досок в `rails c` достаточно ввести Trello::Board.all и найти там id)
        # а затем ищем карту по id в этой доске
        card = Trello::Board.find(SOME_BOARD_ID).find_card(commit_id)
        # добавляем комментарий
        card.add_comment "Готово, отправляется на сервер"
      end
    end
    # отправляем ответ, что всё ок
    render json: { status: :ok }
  end
end

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

Интеграция с capistrano

Есть костыльный способ и не очень. Не очень костыльный – сделать rake таск с отправкой уведомления. Но гораздо проще и чуть быстрее отправлять комментарий прямо в коллбеке capistrano. Это сделать достаточно просто.

В config/deploy.rb в after_restart пишем:

run_locally do # запускаем локально
  current_revision = fetch :current_revision # текущая ревизия
  previous_revision = fetch :previous_revision # ревизия прошлого деплоя
  # получаем список сообщений при коммитах
  commits = capture(:git, "log #{previous_revision}..#{current_revision} --format=%s")
  # загружаем ruby-trello
  require 'trello'
  # настраиваем также, как и в initializers
  Trello.configure do |config|
    config.developer_public_key = KEY
    config.member_token = TOKEN
  end
  # проходим по каждому коммиту
  commits.each_line do |line|
    # ищем ID карточки, если есть
    commit_id = line.scan(/#(\d+)/).flatten.first
    if commit_id
      # если есть – то точно также находим карточки в доске, как получить BOARD_ID описано выше
      card = Trello::Board.find(BOARD_ID).find_card(commit_id)
      card.add_comment "Деплой завершен, можно тестировать" # пишем какой-нибудь комментарий
      # Чтобы найти LIST_ID, требуется в `rails c` получить список всех досок:
      # Trello::Board.find("5311a78d4d674001563407a4").lists.map{|list| [list.id, list.name]}
      # и найти нужный ID списка
      card.move_to_list(LIST_ID) # Перемещаем в список "Сделано"
      card.pos = "top" # Перемещаем в верх списка (можно указать bottom или число с позицией)
      card.save # Применяем изменения
    end
  end
end

Заключение

Такие простые действия позволяют быстро и просто автоматизировать отображение изменений в trello.

При желании, данный способ можно использовать для других задач, например, на основе коммит сообщений формировать CHANGELOG приложения или творить другие безумия :)

comments powered by Disqus