Vous pouvez utiliser l’API REST pour déployer vos projets hébergés dans GitHub sur un serveur dont vous êtes propriétaire. Pour plus d’informations sur les points de terminaison permettant de gérer les déploiements et les états, consultez AUTOTITLE. Vous pouvez également utiliser l’API REST pour coordonner vos déploiements au moment où votre code arrive sur la branche par défaut. Pour plus d’informations, consultez « AUTOTITLE ».
Ce guide utilise l’API REST pour illustrer une configuration possible. Dans notre scénario, nous allons :
- Fusionner une pull request.
- Une fois l’intégration continue (CI) terminée, nous définirons l’état de la demande de tirage en conséquence.
- Une fois que le pull request est fusionné, nous lancerons notre déploiement sur notre serveur.
Notre système CI et notre serveur hôte seront le fruit de notre imagination. Il pourrait s’agir de Heroku, d’Amazon, ou de toute autre chose. Ce guide porte principalement sur l’installation et la configuration du serveur gérant la communication.
Si vous ne l’avez pas déjà fait, veillez à télécharger , puis apprenez à l’utiliser. Cet outil est très utile pour exposer des applications locales sur Internet.
Remarque
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 « AUTOTITLE ».
Remarque : Vous pouvez télécharger le code source complet de ce projet à partir du dépôt platform-samples.
Écriture de votre serveur
Nous allons écrire rapidement une application Sinatra pour prouver que nos connexions locales fonctionnent. Commençons par ceci :
require 'sinatra'
require 'json'
post '/event_handler' do
payload = JSON.parse(params[:payload])
"Well, it worked!"
end
(Si vous n’êtes pas familiarisé avec le fonctionnement de Sinatra, nous vous recommandons de lire le guide Sinatra.)
Démarrez ce serveur. Par défaut, Sinatra démarre sur le port . Vous devez également donc configurer pour qu’il commence à écouter ce port.
Pour 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.
Créez un dépôt dans lequel vous vous sentez à l’aise pour expérimenter. Pourquoi pas le référentiel De Spoon/Knife de ?
Après cela, vous allez créer un webhook dans votre dépôt, en lui fournissant l’URL que vous a donnée et en choisissant comme type de contenu.
Cliquez sur Mettre à jour le webhook. Vous devriez voir la réponse de corps suivante : . Très bien ! Cliquez sur Me laisser sélectionner des événements individuels, puis sélectionnez ce qui suit :
- Déploiement
- état du déploiement
- Demande de tirage (pull request)
Il s’agit des événements que GitHub enverra à notre serveur chaque fois que l’action appropriée se produira. Nous allons configurer notre serveur pour qu'il gère uniquement lorsque les pull requests sont fusionnées dès maintenant.
post '/event_handler' do
@payload = JSON.parse(params[:payload])
case request.env['HTTP_X_GITHUB_EVENT']
when "pull_request"
if @payload["action"] == "closed" && @payload["pull_request"]["merged"]
puts "A pull request was merged! A deployment should start now..."
end
end
end
Que se passe-t-il ? Chaque événement qu'GitHub envoie comporte un en-tête HTTP X-GitHub-Event joint. Pour l’instant, nous allons uniquement nous occuper des événements de demande de tirage. Lors de la fusion d’une demande de tirage (son état est , et est ), nous lançons un déploiement.
Pour tester cette preuve de concept, apportez des modifications à une branche dans votre dépôt de test, ouvrez une pull request et fusionnez-la. Votre serveur doit répondre en conséquence !
Travail avec les déploiements
Avec notre serveur en place, le code en cours d'examen et notre pull request fusionnée, nous voulons que notre projet soit déployé.
Nous allons commencer par modifier notre écouteur d’événements pour traiter les demandes de tirage lors de leur fusion, et commencer à prêter attention aux déploiements :
when "pull_request"
if @payload["action"] == "closed" && @payload["pull_request"]["merged"]
start_deployment(@payload["pull_request"])
end
when "deployment"
process_deployment(@payload)
when "deployment_status"
update_deployment_status
end
En fonction des informations reçues de la pull request, nous allons commencer par remplir la méthode :
def start_deployment(pull_request)
user = pull_request['user']['login']
payload = JSON.generate(:environment => 'production', :deploy_user => user)
@client.create_deployment(pull_request['head']['repo']['full_name'], pull_request['head']['sha'], {:payload => payload, :description => "Deploying my sweet branch"})
end
Des déploiements peuvent avoir des métadonnées attachées, sous la forme d’une et d’une . Bien que ces valeurs soient facultatives, elles sont utiles pour la journalisation et la représentation des informations.
Lorsqu'un nouveau déploiement est créé, un événement entièrement distinct est déclenché. C’est pourquoi nous avons un nouveau cas dans le gestionnaire d’événements pour . Vous pouvez utiliser ces informations pour être averti lors du déclenchement d’un déploiement.
Les déploiements pouvant prendre un peu de temps, nous voulons écouter divers événements, tels que le moment de création du déploiement et l’état dans lequel il se trouve.
Simulons un déploiement qui effectue un certain travail, et observons son effet sur la sortie. Commençons par compléter notre méthode :
def process_deployment
payload = JSON.parse(@payload['payload'])
# you can send this information to your chat room, monitor, pager, etc.
puts "Processing '#{@payload['description']}' for #{payload['deploy_user']} to #{payload['environment']}"
sleep 2 # simulate work
@client.create_deployment_status("repos/#{@payload['repository']['full_name']}/deployments/#{@payload['id']}", 'pending')
sleep 2 # simulate work
@client.create_deployment_status("repos/#{@payload['repository']['full_name']}/deployments/#{@payload['id']}", 'success')
end
Enfin, nous allons simuler le stockage des informations d’état en tant que sortie de console :
def update_deployment_status
puts "Deployment status for #{@payload['id']} is #{@payload['state']}"
end
Décomposons ce qui se passe. Un nouveau déploiement est créé par , ce qui déclenche l’événement . À partir de là, nous appelons à simuler le travail en cours. Pendant ce traitement, nous effectuons également un appel à , qui permet à un récepteur de savoir ce qui se passe lorsque nous basculons l’état sur .
Une fois le déploiement terminé, nous définissons l’état sur .
Conclusion
À GitHub, nous avons utilisé une version de Heaven pour gérer nos déploiements depuis des années. Un flux commun est essentiellement le même que celui du serveur que nous avons généré ci-dessus :
- Attendez une réponse sur l’état des vérifications de CI (réussite ou échec)
- Si les vérifications requises passent, fusionnez la pull request.
- Heaven prend le code fusionné et le déploie sur des serveurs intermédiaires et de production
- Entre-temps, Heaven informe également tout le monde de la build, via la présence de Hubot dans nos salles de conversation
Et voilà ! Vous n’avez pas besoin de générer votre propre configuration de déploiement pour utiliser cet exemple. Vous pouvez toujours vous appuyer sur des intégrations GitHub.