Статьи

Использование Github Webhooks с PHP

В первой части нашей серии мы говорили об API Github и создавали демонстрацию в процессе. В этой части мы собираемся исследовать API Webhooks и создадим демонстрацию, чтобы продемонстрировать использование API. Давайте начнем.

Github logo

Что мы строим

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

Настройка среды

Мы будем использовать Laravel 5 в качестве нашей среды, и поскольку наше приложение должно быть доступно из Интернета для работы с Github Webhooks, мы можем использовать Heroku для размещения нашего кода. Вы можете проверить этот пост, чтобы начать работу с Heroku.

конфигурация

Добавление Mysql

После создания нашего приложения на Heroku нам нужно добавить MySQL для хранения полученных данных.

heroku addons:add cleardb

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

 MYSQL_HOST=‘HOST’
MYSQL_DATABASE=‘DB’
MYSQL_USERNAME=‘USERNAME’
MYSQL_PASSWORD=‘PASSWORD’

Зарегистрироваться Github Hooks

Чтобы зарегистрировать новый хук, перейдите в репозиторий внутри своей учетной записи, затем перейдите на вкладку настроек и выберите Webhooks & Services

Register Webhook

После настройки конечной точки URL-адреса приложения для получения полезной нагрузки вы можете установить секретный ключ для отправки вместе с полезной нагрузкой для проверки источника запроса. По умолчанию Github будет отправлять вам только push-события, но вы можете выбрать отдельные события из списка. Для нашей демонстрации достаточно push-события.

Создание демо

Создание таблиц базы данных

 php artisan make:migration create_hooks_table
 // database/migrations/XXX_create_hooks_table.php

class CreateHooksTable extends Migration
{

  public function up()
  {
    Schema::create('hooks', function (Blueprint $table) {
      $table->increments('id');
      $table->string('event_name', 100);
      //you can separate the sender, repo...etc. but let's just keep it simple
      $table->text('payload');
      $table->timestamps();
    });
  }

  public function down()
  {
    Schema::drop('hooks');
  }

}

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

После запуска миграции с использованием php artisan migrateHook

 // app/Hook.php

class Hook extends Model
{

  protected $table = ‘hooks’;

}

Создание маршрутов

Наше демо-приложение будет иметь только два маршрута.

  • маршрут events
  • /report/contributions
 // app/Http/routes.php

Route::post(/events’, [‘uses’ => ‘GithubController@storeEvents’]);
 // app/Http/Controllers/GithubController.php

public function storeEvents(Request $request) {
  $event_name = $request->header(X-Github-Event’);
  $body = json_encode(Input::all());

  $hook = new Hook;
  $hook->event_name = $event_name;
  $hook->payload = $body;

  $hook->save();

  return ‘’;// 200 OK
}

Значение заголовка X-Github-Event В этом случае он будет равен push Если вы хотите проверить источник запроса, используя секретный ключ, который вы предоставили ранее на Github, вы можете использовать значение заголовка X-Hub-Signature Вы можете прочитать больше в документации .

Github отправит вам запрос почти в реальном времени. Если вы используете Heroku для развертывания, вы можете использовать регистратор для мониторинга запросов во время тестирования. Вы можете прочитать больше об этом в документации . Вы также можете перейти к своей конфигурации Webhook на Github и прокрутить до вкладки « Recent Deliveries

 heroku logs —tail -n 0 —ps router

Test push

Для отображения списка участников я собираюсь использовать JavaScript-библиотеку ChartJs . Вы можете проверить это руководство по началу работы для хорошего вступления.

 // app/Http/routes.php

Route::get(/reports/contributions.json’, [‘uses’ => ‘GithubController@contributionsJson’]);
 // app/Http/Controllers/GithubController.php
public function contributionsJson()
{
  $hooks = Hook::where('event_name', '=', 'push')->get(['payload']);

  $users = [];
  $hooks->each(function ($item) use (&$users) {
    $item = json_decode($item['payload']);

    $pusherName = $item->pusher->name;
    $commitsCount = count($item->commits);

    $users[$pusherName] = array_pull($users, $pusherName, 0) + $commitsCount;
  });

  return [
      'users'   => array_keys($users),
      'commits' => array_values($users)
  ];
}

Маршрут /reports/contributions.json Затем мы возвращаем список пользователей и фиксируем их отдельно, чтобы удовлетворить потребности библиотеки. Тем не менее, вы также можете сделать это во внешнем интерфейсе, используя некоторый Javascript.

 // app/Http/routes.php

Route::get(/reports/contributions’, [‘uses’ => ‘GithubController@contributions’]);
 // app//Http/Contrllers/GithubController.php

public function contributions()
{
  
  return View::make('reports.contributions');
}
 // resources/views/reports/contributions.blade.php

<canvas id=“contributions” width=400” height=400></canvas>

<script>
    var ctx = document.getElementById(“contributions”).getContext(2d”);

    $.ajax({
        url:/reports/contributions.json”,
        dataType: “json”,
        type:GET,
        success: function(response){
            var data = {
                labels: response.users,
                datasets: [
                {
                    data: response.commits
                }]
            };

            new Chart(ctx).Bar(data, {});
        }
    });
</script>

После получения данных от нашей конечной точки JSON мы создаем новый объект Chart Вы можете прочитать больше о доступных опциях в документации .

Contributors chart

Вывод

Вот пример из реальной жизни — если вы когда-либо участвовали в проекте Symfony на Github, вы заметили, что когда вы отправляете запрос на извлечение, ваш код проверяется внешней службой с именем fabbot.io . Этот сервис следит за хранилищем для каждого нового запроса и проверяет ваш код. Вы можете посетить веб-сайт для получения дополнительной информации, а также вы можете зарегистрировать свой собственный репозиторий для проверки.

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