{"meta":{"title":"Création d’un serveur CI","intro":"Générez votre propre système CI à l’aide de l’API État.","product":"API REST","breadcrumbs":[{"href":"/fr/rest","title":"API REST"},{"href":"/fr/rest/guides","title":"Guides"},{"href":"/fr/rest/guides/building-a-ci-server","title":"Création d’un serveur CI"}],"documentType":"article"},"body":"# Création d’un serveur CI\n\nGénérez votre propre système CI à l’aide de l’API État.\n\nVous pouvez utiliser l’API REST pour lier les commits à un service de test afin que chaque poussée (push) que vous effectuez puisse être testée et représentée dans une demande de tirage (pull request) GitHub. Pour plus d’informations sur les points de terminaison pertinents, consultez [Points de terminaison de l’API REST pour les statuts de commit](/fr/rest/commits/statuses).\n\nCe guide utilise cette API pour illustrer une configuration que vous pouvez utiliser.\nDans notre scénario, nous allons :\n\n* Exécuter notre suite CI quand une demande de tirage est ouverte (nous définirons l’état de CI sur pending).\n* Une fois le CI terminé, nous définirons l’état de la demande de tirage en conséquence.\n\nNotre système CI et notre serveur hôte seront le fruit de notre imagination. Vous pouvez utiliser Travis, Jenkins ou autre chose. Ce guide porte principalement sur l’installation et la configuration du serveur gérant la communication.\n\nSi vous ne l’avez pas déjà fait, [téléchargez `ngrok`](https://ngrok.com/), puis apprenez à [l’utiliser](/fr/webhooks-and-events/webhooks/configuring-your-server-to-receive-payloads#using-ngrok). Cet outil est très utile pour exposer des applications locales sur Internet.\n\n> \\[!NOTE]\n> Vous pouvez également utiliser le transfert de webhook pour configurer votre environnement local afin qu'il puisse recevoir des webhooks. Pour plus d’informations, consultez « [Utilisation de l’interface CLI GitHub pour transférer des webhooks à des fins de test](/fr/webhooks-and-events/webhooks/receiving-webhooks-with-the-github-cli) ».\n\nRemarque : Vous pouvez télécharger le code source complet de ce projet [à partir du dépôt platform-samples](https://github.com/github/platform-samples/tree/master/api/ruby/building-a-ci-server).\n\n## Écriture de votre serveur\n\nNous allons écrire rapidement une application Sinatra pour prouver que nos connexions locales fonctionnent.\nCommençons par ceci :\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(Si vous n’êtes pas familiarisé avec le fonctionnement de Sinatra, nous vous recommandons de [lire le guide Sinatra](http://www.sinatrarb.com/).)\n\nDémarrez ce serveur. Par défaut, Sinatra démarre sur le port `4567`. Vous devez également donc configurer `ngrok` pour qu’il commence à écouter ce port.\n\nPour que ce serveur fonctionne, nous devons configurer un dépôt avec un webhook. Le webhook doit être configuré pour se déclencher à chaque création ou fusion d'une pull request.\n\nCréez un dépôt dans lequel vous vous sentez à l’aise pour expérimenter. Pourquoi pas le référentiel Spoon/Knife d’[@octocat](https://github.com/octocat/Spoon-Knife) ?\n\nAprès cela, vous allez créer un webhook dans votre dépôt, en lui fournissant l’URL que `ngrok` vous a donnée et en choisissant `application/x-www-form-urlencoded` comme type de contenu.\n\nCliquez sur **Mettre à jour le webhook**. Vous devriez voir la réponse de corps suivante : `Well, it worked!`.\nTrès bien ! Cliquez sur **Me laisser sélectionner des événements individuels**, puis sélectionnez ce qui suit :\n\n* Statut\n* Demande de tirage (pull request)\n\nIl s’agit des événements que GitHub enverra à notre serveur chaque fois que l’action appropriée se produira. Mettons à jour notre serveur pour gérer *uniquement* le scénario de pull request dès maintenant.\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\nQue se passe-t-il ? Chaque événement que GitHub envoie est accompagné d'un en-tête HTTP `X-GitHub-Event`. Pour l’instant, nous allons uniquement nous occuper des événements de demande de tirage. À partir de là, nous prendrons la charge utile d’informations et retournerons le champ de titre. Dans un scénario idéal, notre serveur devrait s'intéresser à chaque fois qu'une pull request est mise à jour, pas simplement lorsqu'elle est ouverte. Nous aurions ainsi la confirmation que chaque nouvelle poussée réussit les tests CI.\nMais pour les besoins de cette démonstration, nous allons simplement nous intéresser à l’ouverture.\n\nPour tester cette preuve de concept, apportez des modifications à une branche dans votre dépôt de test et ouvrez une pull request. Votre serveur doit répondre en conséquence !\n\n## Gestion des statuts\n\nUne fois notre serveur en place, nous sommes prêts à démarrer notre première exigence, qui consiste à définir (et à mettre à jour) les états de CI. Chaque fois que vous mettez à jour votre serveur, vous pouvez cliquer sur **Relivrer** pour envoyer la même charge utile. Il n'est pas nécessaire de créer une nouvelle pull request chaque fois que vous apportez une modification !\n\nÉtant donné que nous interagissons avec l’API GitHub, nous utiliserons [Octokit.rb](https://github.com/octokit/octokit.rb) pour gérer nos interactions. Nous allons configurer ce client avec [un personal access token](/fr/authentication/keeping-your-account-and-data-secure/creating-a-personal-access-token) :\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\nAprès cela, nous devrons simplement mettre à jour la pull request sur GitHub pour indiquer clairement que nous traitons sur le 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\nNous effectuons trois opérations basiques ici :\n\n* Nous recherchons le nom complet du référentiel\n* Nous recherchons le dernier SHA de la pull request\n* Nous définissons l’état sur « en attente »\n\nEt voilà ! À partir de là, vous pouvez exécuter n’importe quel processus dont vous avez besoin pour exécuter votre suite de tests. Vous pouvez par exemple transmettre votre code à Jenkins ou appeler un autre service web par le biais de son API, comme [Travis](https://api.travis-ci.com/docs/). Après cela, pensez à mettre à jour l’état une fois de plus. Dans notre exemple, nous allons simplement le définir sur `\"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## Conclusion\n\nChez GitHub, nous avons utilisé une version de [Janky](https://github.com/github/janky) pour gérer notre CI depuis des années.\nLe flux de base est essentiellement le même que celui du serveur que nous avons créé ci-dessus.\nChez GitHub, nous :\n\n* déclenchons un travail Jenkins lorsqu’une demande de tirage est créée ou mise à jour (via Janky) ;\n* attendons une réponse sur l’état du CI ;\n* Si le code est vert, nous fusionnons la pull request.\n\nToutes ces communications sont synthétisées dans nos salles de conversation. Vous n’avez pas besoin de créer votre propre configuration CI pour utiliser cet exemple.\nVous pouvez toujours vous appuyer sur des intégrations [GitHub](https://github.com/integrations)."}