Redmine — контроль за обновлением production

в 11:12, , рубрики: Git, php, redmine, web, управление проектами, метки: , , ,

В процессе разработки веб приложений, у нас часто возникает 2 вопроса:
1. Какие задачи уже решены, но ещё не залиты на боевой сервер. Другими словами — что именно зальется на боевой сервер при апдейте git
2. Как быстро посмотреть логи — что и когда заливалось на сервер.

В качестве системы контроля версий используется git (через него и обновляется production сервер). В качестве таск-менеджера Redmine.
Пару слов про redmine. Для него мы взяли самый дешевый VPS у хетцнера, и к редмайну привязали наш репозиторий. Получилось очень удобно, когда комментарии к коммиту в виде "re #111 Комментарий" автоматически привязываются к задаче №111. Соответственно "fix #111" закроет эту задачу. Ну и плюшки в виде указания ссылок на ревизии, просмотр диффов между коммитами и тд. Основной «мастер» репозиторий у нас в гитхабе, но я собираюсь от него отказаться.

Итак, на поставленные выше вопросы можно получить ответы довольно легко при помощи команд в консоле:
1.

git config --global alias.incoming '!git remote update -p; git log ..@{u}'

И далее по команде git incoming видим что именно к нам зальется. Подробнее тут (ссылку дали в q&a)
2.

git reflog

и

git log HEAD@{1}..HEAD@{0}

Однако, данный способ не всегда удобен. В частности не сразу понятно, что именно за задача #111, которая промелькнет в логах.
Как я это реализовал, чтобы было более удобно.
В редмайне для задач было добавлено новое логическое поле Production, да — залито на сервер, нет — не залито.
Так же, в редмайн был добавлен пользователь Робот.
При заливке на сервер используется hook post-merge. Этот хук смотрит, какие именно коммиты были залиты, пробегается по каждому из них, если там есть номер задачи, помечает эту задачу в редмайне Production=true, а в конце составляет итоговый список изменений, создает задачу на Робота (со статусом «решена») и туда записывает изменений.
Хук написан на php, т.к. была найдена отличная библиотека ActiveResource.php для работы с Ruby on Rails REST APIs.
Код приведу весь, т.к. там немного:

#!/usr/bin/php
<?php
require_once ('ActiveResource.php');
// Создаем класс для работы с тасками. Для работы с юзерами надо создать свой класс User и тд.
class Issue extends ActiveResource {
   var $site = 'http://redmine.site.com/';
   var $request_format = 'xml';
   var $extra_params = '?key=API_KEY';
}
$issue = new Issue();
// Смотрим, какие коммиты были залиты.
exec('git log --pretty="%h=!=%an=!=%s" HEAD@{1}..HEAD@{0}',$logs);
// Итоговый список, чего именно было загружено
$s = "";
// Пробежимся по логам
foreach($logs as $log){
  // короткий хеш, имя коммитера, коммент к комиту
  list($hash, $name, $comment) = explode("=!=", $log);
  // для наглядности выведем на экран
  echo $hash . " " . $name . " " . $comment . "n";
  // # - символ нумерованного списка для редмайна. 
  $s .= "# ";
  // Если есть в комментарии указание на номер задачи
  if(preg_match("/#d+/", $comment, $ids)){
    $id = substr($ids[0],1);
    $issue->find($id);
    // То ставим поле Production  в true. Поле смотрится по его ID. У меня оно равно 2.
    $issue->set("custom_fields", array("@type"=>"array", array("custom_field"=>array("@id"=>"2", "value"=>1))));
    $issue->save();
    // Строчку начинаем со слова "Задача " и номер задачи. Редмайн сам превратит задачу в ссылку и добавит alt с названием задачи. Плюсики в начале и конце - подчеркивание. 
    $s .= "+Задача " . $ids[0] . "+ ";
  }
  // Т.к. у нас репозиторий привязан к редмайну - оставляем ссылку на ревизию. Можно будет посмотреть что именно правилось.
  $s .= "commit:" . $hash;
  // Имя автора коммита жирненьким
  $s .= " *".$name."*";
  // Убираем из коммента номер задачи, что бы не путаться, а то будет 2 ссылки на одну и туже задачу
  $comment = trim(preg_replace("/^.*#d+/", "", $comment));
  if(!empty($comment)){
    $s .= ", _" . $comment . "_";
  }
  $s .= "n";
}

// Создаем новую задачу. 
$newIssue = new Issue(array ('subject' => 'Обновление Production', 'project_id' => '2'));
// Описание
$newIssue->set("description", $s);
// Решена
$newIssue->set("status_id",3);
// Назначена на робота
$newIssue->set("assigned_to_id",12);
$newIssue->save();

Задача с итоговым описанием выглядит так:
Redmine — контроль за обновлением production

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

Кстати, добавьте себе в .bashrc

alias gl='git log  --pretty="%Cgreen%h %Cblue%an%Creset %s %Cred%ar"'

и используйте gl вместо git log.

Автор: Voenniy

* - обязательные к заполнению поля