{"meta":{"title":"Создание сервера непрерывной интеграции","intro":"Создайте собственную систему непрерывной интеграции с помощью API состояния.","product":"REST API","breadcrumbs":[{"href":"/ru/enterprise-cloud@latest/rest","title":"REST API"},{"href":"/ru/enterprise-cloud@latest/rest/guides","title":"Guides"},{"href":"/ru/enterprise-cloud@latest/rest/guides/building-a-ci-server","title":"Создание сервера непрерывной интеграции"}],"documentType":"article"},"body":"# Создание сервера непрерывной интеграции\n\nСоздайте собственную систему непрерывной интеграции с помощью API состояния.\n\nС помощью REST API можно связать фиксации со службой тестирования, чтобы каждый push-запрос можно протестировать и представить в запросе GitHub на вытягивание. Дополнительные сведения о соответствующих конечных точках см. в разделе [Конечные точки REST API для состояния фиксации](/ru/enterprise-cloud@latest/rest/commits/statuses).\n\nВ этом руководстве данный интерфейс API используется для демонстрации возможной конфигурации.\nВ описываемом сценарии мы выполним указанные ниже действия.\n\n* Запустите наш набор непрерывной интеграции (CI) при открытии запроса на вытягивание (мы зададим состояние CI \"в ожидании\").\n* По завершении непрерывной интеграции мы зададим соответствующее состояние запроса на вытягивание.\n\nСистема непрерывной интеграции и сервер размещения будут вымышленными. Это может быть Travis, Jenkins или что-то совершенно иное. Основная цель этого руководства — настроить сервер, управляющий взаимодействием.\n\nЕсли вы еще не сделали этого, [скачайте `ngrok`](https://ngrok.com/)и узнайте, как [его](https://ngrok.com/docs/getting-started/) использовать. Мы считаем, что это очень полезное средство для предоставления локальных приложений в Интернете.\n\n> \\[!NOTE]\n> Кроме того, вы можете использовать перенаправление веб-перехватчиков для настройки локальной среды для получения веб-перехватчиков. Дополнительные сведения см. в разделе [Использование GitHub CLI для пересылки вебхуков для тестирования](/ru/enterprise-cloud@latest/webhooks/testing-and-troubleshooting-webhooks/using-the-github-cli-to-forward-webhooks-for-testing).\n\nПримечание. Полный исходный код для этого проекта можно скачать из [репозитория platform-samples](https://github.com/github/platform-samples/tree/master/api/ruby/building-a-ci-server).\n\n## Создание сервера\n\nМы создадим небольшое приложение Sinatra, чтобы подтвердить работоспособность локальных подключений.\nНачнем с этого:\n\n```ruby\nrequire 'sinatra'\nrequire 'json'\n\npost '/event_handler' do\n  payload = JSON.parse(params[:payload])\n  \"Well, it worked!\"\nend\n```\n\n(Если вы не знакомы с тем, как работает Sinatra, рекомендуем [ознакомиться с руководством по Sinatra](http://www.sinatrarb.com/).)\n\nЗапустите этот сервер. По умолчанию Sinatra начинается с порта `4567`, поэтому вы также хотите настроить `ngrok` для этого прослушивание.\n\nЧтобы этот сервер работал, необходимо настроить репозиторий с веб-перехватчиком. Веб-перехватчик должен быть настроен так, чтобы он активировался каждый раз при создании или слиянии запроса на вытягивание.\n\nДавайте создадим репозиторий, с которым можно спокойно экспериментировать. Мы предлагаем [репозиторий @octocat Spoon/Knife](https://github.com/octocat/Spoon-Knife).\n\nПосле этого вы создадите в репозитории новый веб-перехватчик, задав URL-адрес, `ngrok` который дал вам, и выберите `application/x-www-form-urlencoded` тип контента.\n\nЩелкните **Обновить веб-перехватчик**. Вы должны увидеть текст ответа `Well, it worked!`.\nОтлично! Установите переключатель в положение **Разрешить мне выбрать отдельные события** и выберите следующее:\n\n* Состояние\n* Запрос на вытягивание\n\nЭто события GitHub , которые будут отправляться на наш сервер всякий раз, когда происходит соответствующее действие. Давайте обновим сервер так, чтобы пока он обрабатывал *только* сценарий запроса на вытягивание:\n\n```ruby\npost '/event_handler' do\n  @payload = JSON.parse(params[:payload])\n\n  case request.env['HTTP_X_GITHUB_EVENT']\n  when \"pull_request\"\n    if @payload[\"action\"] == \"opened\"\n      process_pull_request(@payload[\"pull_request\"])\n    end\n  end\nend\n\nhelpers do\n  def process_pull_request(pull_request)\n    puts \"It's #{pull_request['title']}\"\n  end\nend\n```\n\nПочему? Каждое событие, GitHub которое отправляет присоединенный `X-GitHub-Event` заголовок HTTP. Пока нас интересуют только события, связанные с запросами на вытягивание. Из них мы возьмем полезные данные и вернем поле заголовка. В идеальном сценарии сервер должен обрабатывать каждое обновление запроса на вытягивание, а не только его открытие. Это позволяет гарантировать, что каждая новая отправка проходит тесты CI.\nОднако в этой демонстрации нас будет интересовать только открытие запроса.\n\nЧтобы проверить этот эксперимент, внесите какие-нибудь изменения в ветвь тестового репозитория и откройте запрос на вытягивание. Ваш сервер должен вернуть соответствующий ответ.\n\n## Работа с состояниями\n\nРеализовав сервер, мы готовы приступить к выполнению первого требования: заданию (и обновлению) состояний CI. Обратите внимание, что при каждом обновлении сервера можно щелкнуть **Доставить повторно**, чтобы отправить те же полезные данные. Создавать новый запрос на вытягивание каждый раз, когда вы вносите изменения, не нужно.\n\nТак как мы взаимодействуем с GitHub API, мы будем использовать [Octokit.rb](https://github.com/octokit/octokit.rb) для управления нашими взаимодействиями. Мы настроим этот клиент с [помощью personal access token](/ru/enterprise-cloud@latest/authentication/keeping-your-account-and-data-secure/managing-your-personal-access-tokens):\n\n```ruby\n# !!! DO NOT EVER USE HARD-CODED VALUES IN A REAL APP !!!\n# Instead, set and test environment variables, like below\nACCESS_TOKEN = ENV['MY_PERSONAL_TOKEN']\n\nbefore do\n  @client ||= Octokit::Client.new(:access_token => ACCESS_TOKEN)\nend\n```\n\nПосле этого необходимо просто обновить запрос GitHub на вытягивание, чтобы убедиться, что мы обрабатываем ci:\n\n```ruby\ndef process_pull_request(pull_request)\n  puts \"Processing pull request...\"\n  @client.create_status(pull_request['base']['repo']['full_name'], pull_request['head']['sha'], 'pending')\nend\n```\n\nЗдесь мы выполняем три основных задачи:\n\n* Мы ищем полное имя репозитория\n* Мы ищем последний SHA запроса на вытягивание\n* Мы устанавливаем состояние \"ожидающий\"\n\nВот и все! Далее можно запустить любой необходимый процесс для выполнения набора тестов. Возможно, вы собираетесь передать код в Jenkins или вызвать другую веб-службу через ее API, например [Travis](https://api.travis-ci.com/docs/). После этого потребуется еще раз обновить состояние. В нашем примере мы просто задаем `\"success\"`:\n\n```ruby\ndef process_pull_request(pull_request)\n  @client.create_status(pull_request['base']['repo']['full_name'], pull_request['head']['sha'], 'pending')\n  sleep 2 # do busy work...\n  @client.create_status(pull_request['base']['repo']['full_name'], pull_request['head']['sha'], 'success')\n  puts \"Pull request processed!\"\nend\n```\n\n## Заключение\n\nВ GitHub мы уже много лет используем версию [Janky](https://github.com/github/janky) для управления нашим CI.\nПроцесс в целом такой же, как и в случае с созданным выше сервером.\nВ GitHub мы:\n\n* активируем Jenkins при создании или обновлении запроса на вытягивание (через Janky);\n* ожидаем ответа о состоянии CI;\n* если код зеленый, выполняется слияние запроса на вытягивание.\n\nВсе это взаимодействие передается в наши комнаты чата. Чтобы использовать этот пример, не нужно создавать собственную конфигурацию CI.\nВсегда можно положиться на интеграции [GitHub ](https://github.com/integrations)."}