С каждым полугодием команда 1С-Битрикс презентует новый функционал облачных корпоративных порталов Битрикс24. Одной из востребованных функций портала можно назвать «Задачи», позволяющие Битрикс24 занимать места в рейтинге таск-трекеров (например, Количество и качество: как развиваются таск-трекеры в условиях конкуренции). Поэтому многие веб-студии, особенно связанные с разработкой на 1С-Битрикс и Битрикс24, используют функционал задач в разработке.
В каждой задаче могут быть и постановщик, и соисполнители, и наблюдатели, в том числе и заказчики. В большинстве случаев работа с задачей длится не один день и может получится так, что в задаче (в комментариях к ней) не наблюдается активность разработчика (разработчиков), а наблюдателям кажется, что их задача не взята в работу и просто «динамится». Помимо названной проблемы хочется иметь полную информацию о том, что происходило с задачей от её начала до завершения.
В связи с этим и возникла необходимость отправлять информацию о ходе разработки во время коммитов, что бы фиксировать все изменения в комментариях к задачам не отвлекаясь на написание комментариев к ней — достаточно добавить информативный комментарий при коммите.
В работе используется CVS Mercurial, для которой и описана настройка отправки информации о коммите в комментарии задачи портала.
Для отправки комментариев при коммите Mercurial в портал Битрикс24 необходимо проделать следующие шаги:
Код из статьи.
Использованные материалы:
В каждой задаче могут быть и постановщик, и соисполнители, и наблюдатели, в том числе и заказчики. В большинстве случаев работа с задачей длится не один день и может получится так, что в задаче (в комментариях к ней) не наблюдается активность разработчика (разработчиков), а наблюдателям кажется, что их задача не взята в работу и просто «динамится». Помимо названной проблемы хочется иметь полную информацию о том, что происходило с задачей от её начала до завершения.
В связи с этим и возникла необходимость отправлять информацию о ходе разработки во время коммитов, что бы фиксировать все изменения в комментариях к задачам не отвлекаясь на написание комментариев к ней — достаточно добавить информативный комментарий при коммите.
В работе используется CVS Mercurial, для которой и описана настройка отправки информации о коммите в комментарии задачи портала.
Для отправки комментариев при коммите Mercurial в портал Битрикс24 необходимо проделать следующие шаги:
- На сайте, где будет размещаться приложение необходимо наличие SSL-сертификата.
- Установить используя composer следующие пакеты:
- mesilov/bitrix24-php-sdk — обёртка на php для работы с BX24 REST API
- defuse/php-encryption — необходима для формирования ключа доступа
Установка осуществляется командой
$ composer require "mesilov/bitrix24-php-sdk: ^0.2.0" "defuse/php-encryption: ^2.0"
- Загрузить на сайт файлы приложения:
- install.php — установочный файл приложения для Битрикс24. Необходим для получения приложением токенов доступа при установке приложения.
install.php<?php /** * Установка приложения. * * Выполнить из окружения портала Битрикс24 для создания конфигурационного файла */ error_reporting(E_ALL & ~E_NOTICE); require __DIR__ . '/vendor/autoload.php'; require __DIR__ . '/lib.php'; if (null === $_REQUEST['DOMAIN'] || null === $_REQUEST['member_id'] || null === $_REQUEST['AUTH_ID'] || null === $_REQUEST['REFRESH_ID']) { die('Приложение необходимо установить из портала Битрикс24'); } $params = AddMessageToBitrix24Task::load(); if (0 === count($params)) { $params = [ //Идентификатор приложения в портале (из настроек приложения в портале) 'B24_APPLICATION_ID' => '<CLIENT_ID>', //Секретное слово приложения в портале (из настроек приложения в портале) 'B24_APPLICATION_SECRET' => '<CLIENT_SECRET>', //Требуемые для работы сущности портала (из настроек приложения в портале) 'B24_APPLICATION_SCOPE' => ['task'], //URL приложения после установки (из настроек приложения в портале) 'B24_REDIRECT_URI' => 'https://<APP_DOMAIN>/app.php', //Домен портала 'DOMAIN' => $_REQUEST['DOMAIN'], //Уникальный идентификатор приложения 'MEMBER_ID' => $_REQUEST['member_id'], //Токен авторизации 'AUTH_ID' => $_REQUEST['AUTH_ID'], //Токен обновления 'REFRESH_ID' => $_REQUEST['REFRESH_ID'], ]; //Сохранить настройки в кофигурационный файл AddMessageToBitrix24Task::save($params); } //Проверка, что настроки сохранены корректно if (AddMessageToBitrix24Task::check()) { //Загружаем настройки для вывода в интерфейсе Битрикс24 ключа доступа $params = AddMessageToBitrix24Task::load(); $result = 'Приложение установлено.<br>'; $result .= 'Добавьте в скрипт hook.php ключ доступа:<br>'; $result .= $params['KEY']; } else { $result = 'Приложение установлено c ошибками.<br>'; } die($result);
- app.php — основной файл приложения, добавляющий комментарии к задачам при срабатывании хука Mercurial…
app.php<?php /** * Приложение добавляющее комментарии к указанной задаче */ error_reporting(E_ALL & ~E_NOTICE); require __DIR__ . '/vendor/autoload.php'; require __DIR__ . '/lib.php'; //Загрузить настройки $params = AddMessageToBitrix24Task::load(); try { //Формируем ключ для проверки $key = $params['B24_APPLICATION_ID'] . $params['MEMBER_ID'] . $params['B24_APPLICATION_SECRET']; //Дешифруем полученный ключ и сравниваем с текущим if (AddMessageToBitrix24Task::decrypt($_REQUEST['key']) !== $key) { die('Некорректный ключ доступа'); } } catch (Exception $e) { die('Некорректный формат ключа доступа'); } if (!is_numeric($_REQUEST['task'])) { die('Не задан номер задачи'); } if (null === $_REQUEST['message'] || '' === trim($_REQUEST['message'])) { die('Не задан комментарий'); } try { //Получить объект для работы с Bitrix24 $bx24 = AddMessageToBitrix24Task::getBX24Instance($params); //Добавить комментарий к задаче $result = AddMessageToBitrix24Task::add($bx24, $_REQUEST['task'], $_REQUEST['message']); die($result); } catch (Exception $e) { die('Ошибка при доавлении комментария к задаче'); }
- lib.php — набор функций, необходимых для работы приложения
lib.php<?php /** * Основной класс приложения */ use Defuse\Crypto\Crypto; use Defuse\Crypto\Key; /** * Добавить комментарий к задачи в портале Битрикс24 * * Class AddMessageToBitrix24Task */ class AddMessageToBitrix24Task { /** * @var string Путь к настройкам приложения. Файл не должен находится в корне сайта. */ private static $config = __DIR__ . '/../bx24.auth'; /** * @var string Ключ шифрования */ private static $safeKey; /** * Шифровать переменную * * @param string $var Переменная для шифрования * * @return string Шифрованная переменная * * @throws \Defuse\Crypto\Exception\BadFormatException * @throws \Defuse\Crypto\Exception\EnvironmentIsBrokenException */ public static function encrypt($var) { return Crypto::encrypt($var, self::getKey()); } /** * Дешифровать переменую * * @param string $var Переменная для дешифрации * * @return string Дешифрованная переменная * * @throws \Defuse\Crypto\Exception\BadFormatException * @throws \Defuse\Crypto\Exception\EnvironmentIsBrokenException */ public static function decrypt($var) { return Crypto::decrypt($var, self::getKey()); } /** * Получить ключ шифрования * * @return Key Ключ шифрования * * @throws \Defuse\Crypto\Exception\BadFormatException * @throws \Defuse\Crypto\Exception\EnvironmentIsBrokenException */ public static function getKey() { if (null === self::$safeKey) { $params = self::load(); //Получить ключ шифрования в бинарно-безопасном виде if (null === $params || null === $params['PRIVATE_KEY']) { self::$safeKey = Key::createNewRandomKey()->saveToAsciiSafeString(); } else { self::$safeKey = $params['PRIVATE_KEY']; } } return Key::loadFromAsciiSafeString(self::$safeKey); } /** * Получить объект для работы с Bitrix24 * * @param array $params Параметры для работы с Битрикс24 * * @return \Bitrix24\Bitrix24 Объект для работы с Битрикс24 * * @throws \Bitrix24\Bitrix24Exception * @throws \Defuse\Crypto\Exception\BadFormatException * @throws \Defuse\Crypto\Exception\EnvironmentIsBrokenException */ public static function getBX24Instance(array $params) { $bx24 = new \Bitrix24\Bitrix24(false); $bx24->setApplicationScope($params['B24_APPLICATION_SCOPE']); $bx24->setApplicationId($params['B24_APPLICATION_ID']); $bx24->setApplicationSecret($params['B24_APPLICATION_SECRET']); $bx24->setRedirectUri($params['B24_REDIRECT_URI']); $bx24->setDomain($params['DOMAIN']); $bx24->setMemberId($params['MEMBER_ID']); $bx24->setAccessToken($params['AUTH_ID']); $bx24->setRefreshToken($params['REFRESH_ID']); //Если время жизни токенов истекло if ($bx24->isAccessTokenExpire()) { //ПОлучитть новый токен доступа $temp = $bx24->getNewAccessToken(); //Обновить токены в объекте $params['AUTH_ID'] = $temp['access_token']; $params['REFRESH_ID'] = $temp['refresh_token']; $bx24->setAccessToken($params['AUTH_ID']); $bx24->setRefreshToken($params['REFRESH_ID']); //Сохранить обновленные токены self::save($params); } return $bx24; } /** * Добавить комментарий к задаче * * @param \Bitrix24\Bitrix24 $bx24 Объект для работы с Битрикс24 * @param int $task Идентификатор задачи * @param string $message Комментарий * * @return string */ public static function add(\Bitrix24\Bitrix24 $bx24, $task, $message) { $str = ''; try { //Проверить есть ли такая задача на портале $bx24->call( 'task.item.getdata', [ 'TASKID' => $task ] ); $str .= 'Задача #' . $task . ' на портале ' . $bx24->getDomain() . ' найдена' . PHP_EOL; //Добавить комментарий к задаче $bx24->call( 'task.commentitem.add', [ 'TASKID' => $task, 'FIELDS' => [ 'POST_MESSAGE' => $message ] ] ); $str .= 'Комментарий к задаче успешно добавлен'; } catch (Exception $e) { $str .= 'Ошибка при добавлении комментация к задаче'; } return $str; } /** * Сохранить настройки в конфигурационный файл * * @param array $params Настройки * * @return bool * * @throws \Defuse\Crypto\Exception\BadFormatException * @throws \Defuse\Crypto\Exception\EnvironmentIsBrokenException */ public static function save(array $params) { //Ключ для доступа к приложению для добавления комментария $params['KEY'] = AddMessageToBitrix24Task::encrypt($params['B24_APPLICATION_ID'] . $params['MEMBER_ID'] . $params['B24_APPLICATION_SECRET']); //Ключ шифрования $params['PRIVATE_KEY'] = self::$safeKey; //Сохраняем данные в файл конфигурации $result = json_encode($params, JSON_UNESCAPED_UNICODE); return file_put_contents(self::$config, $result) > 0; } /** * Получить настройки из конфигурационного файла * * @return array Настройки */ public static function load() { if (!file_exists(self::$config)) { return []; } //Получить настройки приложения $params = file_get_contents(self::$config); return json_decode($params, true); } /** * Проверка, что приложение установлено из заданого портала Битрикс24. * * @return bool */ public static function check() { try { $params = AddMessageToBitrix24Task::load(); $bx24 = self::getBX24Instance($params); $result = $bx24->call('app.info'); return $result['result']['CODE'] === $params['B24_APPLICATION_ID']; } catch (\Exception $e) { return false; } } }
- install.php — установочный файл приложения для Битрикс24. Необходим для получения приложением токенов доступа при установке приложения.
- Загрузить на web-сервер, где используется CVS Mercurial файл hghook-commit-to-bx24.php, выполняющий обращение к приложению при коммите. Размещать файл необходимо вне корня сайта. Для работы скрипта необходимо наличие следующих функций:
- shell_exec — выполнение консольных команд для формирования информации о коммите
- curl_exec — для отправки данных в приложение
hghook-commit-to-bx24.php<?php /** * Хук срабатывающий после выполнения команды hg commit */ //Адрес приложения Битрикс24 define('BX24_APP_URL', 'https://<APP_DOMAIN>/app.php'); //Ключ для обращения к приложению. Получить можно после установки из конфигурационного файла define('KEY', '<ACCESS_KEY>'); echo 'Запущен хук Mercurial, добавляющий информацию о коммите в задачу на портал' . PHP_EOL; if(!function_exists('shell_exec')){ echo 'Ошибка: функция «shell_exec» недоступна' . PHP_EOL; echo 'Завершение хука' . PHP_EOL; exit(0); } if(!function_exists('curl_exec')){ echo 'Ошибка: функция «curl_exec» недоступна' . PHP_EOL; echo 'Завершение хука' . PHP_EOL; exit(0); } //Путь к исполняемому файлу Mercurial $hg = $_SERVER['HG']; if (!is_file($hg) || !is_executable($hg)) { echo 'Ошибка: не найден исполняемый файл Mercurial' . PHP_EOL; echo 'Завершение хука' . PHP_EOL; exit(0); } echo 'Получение информации о коммите' . PHP_EOL; //Получить полное название хоста, на котором работает Mercurial $hostname = trim(shell_exec('hostname -f')); //Абсолютный путь к текущему репозиторию $pwd = $_SERVER['PWD']; //Текущая активная ветка Mercurial $branch = shell_exec("$hg branch"); //Получаем информацию о сделанном коммите $log = trim(shell_exec("$hg log -l 1")); //Автор коммита $matches = null; $user = preg_match('/user:\s+(?<user>\S.*)/ium', $log, $matches) ? $matches['user'] : 'unknown'; //Комментарий коммита $summary = preg_match('/summary:\s+(?<summary>\S.*)/ium', $log, $matches) ? $matches['summary'] : ''; //Получить список файлов текущего коммита за исключюенеи удаленных $files = trim(shell_exec("$hg st -amr")); //Количество файлов текущего коммита $filesCount = substr_count($files, PHP_EOL); //Получить номер задачи из названия текущей ветки Mercurial или из комментария к коммиту echo 'Поиск номера задачи в названии ветки или комментарии' . PHP_EOL; $task = 0; if (preg_match('/^task[#\@\$](?<id>\d+)/iu', $branch, $matches)) { $task = (int)$matches['id']; } elseif (preg_match('/^task[#\@\$](?<id>\d+)/iu', $summary, $matches)) { $task = (int)$matches['id']; } //Если номер не обнаружен, то предлагаем пользователю его ввести if ($task <= 0) { echo 'Номер задачи не найден' . PHP_EOL; echo 'Введите номер задачи на портале или нажмите Enter, чтобы пропустить: '; $count = fscanf(STDIN, "%d\n", $task); if ($count <= 0) { echo 'Номер задачи не введен.' . PHP_EOL; echo 'Информация о коммите не будет отправлена на портал' . PHP_EOL; echo 'Завершение хука' . PHP_EOL; exit(0); } } echo 'Отправка информации о коммите на портал' . PHP_EOL; $message = <<<EOT Новый набор изменений закоммичен пользователем $user в $pwd на $hostname: $summary ====== Техническая информация о коммите: $log Список закоммиченных файлов (всего $filesCount шт): $files Комментарий сгенерирован автоматически. EOT; //Данные для отправки $postData = [ 'message' => $message, 'task' => $task, 'key' => KEY ]; //Формируем запрос к приложению $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, BX24_APP_URL); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); curl_setopt($ch, CURLOPT_POST, 1); curl_setopt($ch, CURLOPT_POSTFIELDS, $postData); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0); $result = curl_exec($ch); echo $result . PHP_EOL; echo 'Завершение хука' . PHP_EOL;
- Добавить в hgrc путь к загруженному файлу hghook-commit-to-bx24.php
[hooks] commit = php -f /home/bitrix/hghook-commit-to-bx24.php
- Выбрать в левом меню портала пункт «Добавить приложение», если оно не видно, то развернуть пункт «Приложения»
- На странице выбираем тип приложения «Для личного пользования», так как мы его не собираемся выкладывать в облачный Маркетплейс
Выбор типа приложения
- На странице настроек нового приложения указываем
- Название приложения
- Название пункта меню на нужном языке
- Установить права доступа на «Задачи (task)»
- Указываем ссылку на исполняемый файл приложения
- Указываем ссылку на установочный файл приложения
Настройки приложения
После ввода всех настроек сохраняем приложение. Настройки можно всегда отредактировать и дополнить при необходимости, выбрав соответствующий пункт на списке задач в разделе «Мои приложения»
- После сохранения приложения мы попадаем на страницу со списком приложений. Для каждого приложения Битрикс24 присваивает два уникальных параметра «Код приложения (client_id)» и «Ключ приложения (client_secret)», которые необходимо указать в файле install.php
Список приложений
- Теперь необходимо перейти к установке приложения, кликнув по ссылке на приложение в левом меню. Если все сделано верно, то будет показано сообщение вида
Приложение установлено. Добавьте в скрипт hghook-commit-to-bx24.php ключ доступа: <ACCESS_KEY>
Установка приложения
Если ничего не было выведено (белая область вместо приложения), то скорее всего у вас установлен заголовок
Header set X-Frame-Options SAMEORIGIN
Он запрещает показывать ваш сайт во фреймах. Что бы исправить это, в директории с приложением достаточно создать (или отредактировать) файл .htaccess, добавив строку
Header unset X-Frame-Options
Полученный код доступа необходимо записать в файл hghook-commit-to-bx24.php
- Если всё корректно настроено, то для добавления информации о коммите к задаче потребуется её номер. Номер задачи в Битрикс24 отображается около ее названия.
Задача в портале
Для добавления информации о коммите к задаче можно указать номер в тексте коммита в самом начале после «task#», «task@» или «task$».
[bitrix@dhcppc5 www]$ hg st M composer.json [bitrix@dhcppc5 www]$ hg ci -u testuser -m 'task#62 Выполнен пункт #1 чеклиста: сделано то-то и то-то' Запущен хук Mercurial, добавляющий информацию о коммите в задачу на портал Получение информации о коммите Поиск номера задачи в названии ветки или комментарии Отправка информации о коммите на портал Задача #62 на портале <PORTAL_NAME>.bitrix24.ru найдена Комментарий к задаче успешно добавлен Завершение хука [bitrix@dhcppc5 www]$
Комментарий к задаче #1
Также можно получить номер задачи из названия рабочей ветки Mercurial, если она имеет название начинающееся с «task#», «task@» или «task$».
Если номер задачи не найден ни в комментарии, ни в названии ветки, то его можно ввести вручную.
[bitrix@dhcppc5 www]$ hg ci -u testuser -m 'Выполнен пункт #2 чеклиста: сделано то-то и то-то' Запущен хук Mercurial, добавляющий информацию о коммите в задачу на портал Получение информации о коммите Поиск номера задачи в названии ветки или комментарии Номер задачи не найден Введите номер задачи на портале или нажмите Enter, чтобы пропустить: 62 Отправка информации о коммите на портал Задача #62 на портале <PORTAL_NAME>.bitrix24.ru найдена Комментарий к задаче успешно добавлен Завершение хука [bitrix@dhcppc5 www]$
Комментарий к задаче #2
Если ввод номера задачи пропущен, то комментарий не будет отправлен.
[bitrix@dhcppc5 www]$ hg ci -u testuser -m 'Выполнен пункт #3 чеклиста: сделано то-то и то-то' Запущен хук Mercurial, добавляющий информацию о коммите в задачу на портал Получение информации о коммите Поиск номера задачи в названии ветки или комментарии Номер задачи не найден Введите номер задачи на портале или нажмите Enter, чтобы пропустить: Номер задачи не введен Информация о коммите не будет отправлена на портал Завершение хука [bitrix@dhcppc5 www]$
Если будет указан несуществующий номер задачи, то будет выведено соответствующее уведомление об ошибке.
[bitrix@dhcppc5 www]$ hg ci -u testuser -m 'task$65445642 Выполнен пункт #3 чеклиста: сделано то-то и то-то' Запущен хук Mercurial, добавляющий информацию о коммите в задачу на портал Получение информации о коммите Поиск номера задачи в названии ветки или комментарии Отправка информации о коммите на портал Ошибка при добавлении комментария к задаче Завершение хука [bitrix@dhcppc5 www]$
Код из статьи.
Использованные материалы:
Поделиться с друзьями
wir_wolf
Это конечно все круто, но данный функционал давно реализован в аналогичных так трекерах на уровне ядра(смайл непонимания как в айтишном так трекере такого нет в коробке)