Git 🌙
Chapters â–Ÿ 2nd Edition

6.5 GitHub - Écriture de scripts pour GitHub

Écriture de scripts pour GitHub

Nous avons pour l’instant traitĂ© de toutes les principales fonctionnalitĂ©s et des cycles de travail de GitHub mais tous les grands groupes ou projets ont des personnalisations qu’ils souhaiteront intĂ©grer ou des services externes qu’ils voudront intĂ©grer.

Heureusement pour nous, il est facile de « bidouiller » GitHub de diffĂ©rentes façons. Dans cette section nous traiterons de la façon d’utiliser le systĂšme de crochets (hooks) de GitHub et son interface de programmation (API) afin que GitHub fonctionne de la façon que nous souhaitons.

Services et Crochets (Hooks)

La section « Hooks & Services » (crochets et services) de l’administration de dĂ©pĂŽt GitHub est la façon la plus facile de faire interagir GitHub avec des systĂšmes externes.

Services

IntĂ©ressons-nous d’abord aux services. Les intĂ©grations de services et de crochets se trouvent tous les deux dans la section Settings (paramĂštres) de votre dĂ©pĂŽt oĂč nous avions prĂ©cĂ©demment ajoutĂ© des collaborateurs et modifiĂ© la branche par dĂ©faut de votre projet. La figure Section configuration des crochets et services. vous montre ce que vous verrez en cliquant sur l’onglet « Webhooks and Services ».

Services et crochets
Figure 129. Section configuration des crochets et services.

Vous pouvez choisir parmi des dizaines de services, la plupart sont des intĂ©grations vers d’autres systĂšmes commerciaux et open source. Certains sont des services d’intĂ©gration continue, des analyseurs de bogues et d’anomalies, des systĂšmes de salon de discussion et des systĂšmes de documentation. Nous examinerons le paramĂ©trage de l’un d’eux, le crochet Email (courriel). Si vous sĂ©lectionnez « email » dans la liste dĂ©roulante « Add Service », vous verrez un Ă©cran de configuration comme Configuration du service Email..

Service Email
Figure 130. Configuration du service Email.

Dans ce cas, si vous cliquez sur le bouton « Add service » (Ajouter le service), un courriel est envoyĂ© Ă  l’adresse Ă©lectronique que vous avez indiquĂ©e Ă  chaque fois que quelqu’un pousse vers le dĂ©pĂŽt. Les services peuvent Ă©couter un grand nombre d’évĂ©nements de diffĂ©rents types mais la plupart n’écoutent que les Ă©vĂ©nements de poussĂ©e puis font quelque chose avec ces donnĂ©es.

Si vous utilisez un systĂšme et souhaitez l’intĂ©grer avec GitHub, vous devriez vĂ©rifier ici s’il existe dĂ©jĂ  un service d’intĂ©gration disponible. Par exemple, si vous utilisez Jenkins pour lancer des tests sur votre code, vous pouvez activer l’intĂ©gration du service intĂ©grĂ© Jenkins pour lancer une sĂ©rie de tests Ă  chaque fois que quelqu’un pousse vers votre dĂ©pĂŽt.

Crochets (Hooks)

Si vous avez besoin de quelque chose de plus spĂ©cifique ou que vous voulez intĂ©grer un service ou un site qui n’est pas dans la liste, vous pouvez utiliser Ă  la place le systĂšme plus gĂ©nĂ©ral des crochets. Les crochets de dĂ©pĂŽt GitHub sont assez simples. Vous indiquez un URL et GitHub envoie (post) des informations par HTTP (payload) vers cet URL pour n’importe quel Ă©vĂ©nement que vous souhaitez.

En général, la façon dont cela fonctionne est que vous configurez un petit service Web qui écoute des informations de crochet GitHub puis font quelque chose avec les données reçues.

Pour activer un crochet, vous cliquez sur le bouton « Add webhook » (Ajouter un crochet Web) de la figure Section configuration des crochets et services.. Cela vous redirige vers une page qui ressemble Ă  Configuration d’un crochet Web..

Crochet Web
Figure 131. Configuration d’un crochet Web.

La configuration d’un crochet Web est assez simple. Dans la plupart des cas, vous saisissez simplement un URL et une clĂ© secrĂšte puis cliquez sur « Add webhook ». Il existe quelques options pour choisir l’évĂ©nement pour lequel GitHub envoie des informations — par dĂ©faut seul l’évĂ©nement push envoie des informations lorsque quelqu’un pousse un nouveau code vers une branche de votre dĂ©pĂŽt.

Examinons un petit exemple de service Web que vous pourriez configurer pour gĂ©rer un crochet Web. Nous utiliserons l’architecture Web Ruby appelĂ©e Sinatra car c’est assez concis et vous devriez ĂȘtre capable de voir facilement ce que nous faisons.

Disons que vous voulez recevoir un courriel si une personne précise pousse vers une branche spécifique de notre projet un fichier particulier. Nous pourrions faire facilement cela avec le code suivant :

require 'sinatra'
require 'json'
require 'mail'

post '/payload' do
  push = JSON.parse(request.body.read) # parse the JSON

  # gather the data we're looking for
  pusher = push["pusher"]["name"]
  branch = push["ref"]

  # get a list of all the files touched
  files = push["commits"].map do |commit|
    commit['added'] + commit['modified'] + commit['removed']
  end
  files = files.flatten.uniq

  # check for our criteria
  if pusher == 'schacon' &&
     branch == 'ref/heads/special-branch' &&
     files.include?('special-file.txt')

    Mail.deliver do
      from     'tchacon@example.com'
      to       'tchacon@example.com'
      subject  'Scott Changed the File'
      body     "ALARM"
    end
  end
end

Ici nous récupérons les informations JSON que GitHub nous délivre et cherchons qui les a poussées, vers quelle branche et quels fichiers ont été touchés dans tous les commits qui ont été poussés. Puis nous comparons cela à nos critÚres et envoyons un courriel si cela correspond.

Afin de dĂ©velopper et tester quelque chose comme cela, il existe une console dĂ©veloppeur sympa sur la mĂȘme fenĂȘtre que celle oĂč vous avez activĂ© le crochet. Vous pouvez afficher les quelques derniĂšres livraisons que GitHub a essayĂ© de faire pour ce crochet Web. Pour chaque crochet, vous pouvez afficher plus d’informations pour savoir quand il s’est exĂ©cutĂ©, s’il a rĂ©ussi et pour connaĂźtre les en-tĂȘtes et le corps de la requĂȘte et de la rĂ©ponse. Ceci rend incroyablement facile de tester et dĂ©bugger vos crochets.

Webhook debug
Figure 132. informations de debuggage du crochet web

L’autre fonctionnalitĂ© intĂ©ressante est que vous pouvez redĂ©clencher la livraison de n’importe quel message pour tester votre service.

Pour plus d’information sur l’écriture de crochets web et tous les diffĂ©rents types d’évĂ©nement que vous pouvez Ă©couter, rendez-vous Ă  la documentation du Developpeur GitHub Ă  l’adresse https://docs.github.com/en/developers/webhooks-and-events/webhooks/about-webhooks.

L’interface de programmation (API) GitHub

Les services et les crochets vous fournissent un moyen de recevoir des notifications de poussĂ©e sur des Ă©vĂ©nements qui arrivent sur vos dĂ©pĂŽts, mais que faire si vous avez besoin de plus d’informations sur ces Ă©vĂ©nements ? Que faire si vous avez besoin d’automatiser quelque chose comme ajouter des collaborateurs ou Ă©tiqueter des problĂšmes (issues) ?

C’est lĂ  que l’Interface de Programmation (API) GitHub s’avĂšre utile. GitHub a des tas de points d’entrĂ©e sur l’interface d’application pour faire presque tout ce que vous pouvez faire sur le site web de façon automatisĂ©e. Dans cette section, nous apprendrons comment s’authentifier et se connecter Ă  l’interface de programmation, comment commenter un problĂšme et comment changer le statut d’une requĂȘte de tirage (pull request) Ă  travers l’interface de programmation.

Utilisation Basique

La chose la plus basique que vous pouvez faire est une simple requĂȘte GET sur une entrĂ©e qui ne requiert pas d’authentification. Cela peut ĂȘtre un utilisateur ou une information en lecture seule sur un projet open source. Par exemple, si nous voulons en savoir plus sur un utilisateur appelĂ© « schacon », nous pouvons lancer quelque chose comme ceci :

$ curl https://api.github.com/users/schacon
{
  "login": "schacon",
  "id": 70,
  "avatar_url": "https://avatars.githubusercontent.com/u/70",
# 

  "name": "Scott Chacon",
  "company": "GitHub",
  "following": 19,
  "created_at": "2008-01-27T17:19:28Z",
  "updated_at": "2014-06-10T02:37:23Z"
}

Il y a des tas de points d’entrĂ©e comme celui-ci pour obtenir des informations sur des regroupements, projets, problĂšmes, commits — en fait tout ce que vous pouvez voir sur le site de GitHub. Vous pouvez mĂȘme utiliser l’interface de programmation pour Ă©crire du texte en Markdown ou trouver un modĂšle .gitignore.

$ curl https://api.github.com/gitignore/templates/Java
{
  "name": "Java",
  "source": "*.class

# Mobile Tools for Java (J2ME)
.mtj.tmp/

# Package Files #
*.jar
*.war
*.ear

# virtual machine crash logs, see https://www.java.com/en/download/help/error_hotspot.xml
hs_err_pid*
"
}

Commenter un problĂšme

Cependant, si vous voulez faire une action sur le site web comme commenter un problĂšme ou une requĂȘte de tirage ou si vous voulez voir ou interagir avec du contenu privĂ©, vous aurez besoin de vous authentifier.

Il y a plusieurs moyens de s’authentifier. Vous pouvez utiliser l’authentification basique avec seulement votre nom d’utilisateur et votre mot de passe, mais en gĂ©nĂ©ral c’est mieux d’utiliser un jeton d’accĂšs personnel. Vous pouvez en gĂ©nĂ©rer depuis l’onglet « Applications » de votre page de paramĂštres.

Access Token
Figure 133. GĂ©nĂ©rez votre jeton d’accĂšs depuis l’onglet « Applications » de votre page de paramĂštres.

On vous demandera le pĂ©rimĂštre applicatif que vous voulez pour ce jeton ainsi qu’une description. Assurez-vous d’utiliser une bonne description pour ĂȘtre certain de supprimer le bon jeton quand votre script ou application ne sera plus utilisĂ©.

GitHub ne vous montrera le jeton qu’une seule fois, alors assurez-vous de le copier. Vous pouvez maintenant l’utiliser pour vous authentifier dans votre script au lieu d’utiliser un nom d’utilisateur et un mot de passe. C’est agrĂ©able parce que vous pouvez limiter la portĂ©e de ce que vous voulez faire et le jeton est rĂ©vocable.

Ceci a l’avantage supplĂ©mentaire d’augmenter votre limite horaire du nombre d’accĂšs. Sans authentification, vous serez limitĂ© Ă  60 requĂȘtes par heure. Avec authentification, vous pouvez faire jusqu’à 5 000 requĂȘtes par heure.

Maintenant utilisons-le pour faire un commentaire sur un de nos problĂšmes. Disons que nous voulons laisser un commentaire sur un problĂšme en particulier, le problĂšme n°6. Pour faire cela, nous devons faire une requĂȘte HTTP POST Ă  repos/<utilisateur>/<dĂ©pĂŽt>/issues/<num>/comments avec le jeton que nous venons de gĂ©nĂ©rer en tant qu’en-tĂȘte "Authorization".

$ curl -H "Content-Type: application/json" \
       -H "Authorization: token TOKEN" \
       --data '{"body":"A new comment, :+1:"}' \
       https://api.github.com/repos/schacon/blink/issues/6/comments
{
  "id": 58322100,
  "html_url": "https://github.com/schacon/blink/issues/6#issuecomment-58322100",
  ...
  "user": {
    "login": "tonychacon",
    "id": 7874698,
    "avatar_url": "https://avatars.githubusercontent.com/u/7874698?v=2",
    "type": "User",
  },
  "created_at": "2014-10-08T07:48:19Z",
  "updated_at": "2014-10-08T07:48:19Z",
  "body": "A new comment, :+1:"
}

Maintenant si vous allez Ă  ce problĂšme, vous pouvez voir le commentaire que nous avons postĂ© avec succĂšs comme dans Un commentaire postĂ© depuis l’interface de programmation GitHub.

API Comment
Figure 134. Un commentaire postĂ© depuis l’interface de programmation GitHub

Vous pouvez utiliser l’interface de programmation pour faire Ă  peu prĂšs tout ce que vous pouvez faire sur le site web — crĂ©er et dĂ©finir des jalons, assigner des gens Ă  des problĂšmes ou Ă  des requĂȘtes de tirage, crĂ©er et changer des Ă©tiquettes, accĂ©der Ă  des donnĂ©es de commit, crĂ©er de nouveaux commits et des branches, ouvrir, fermer ou fusionner des requĂȘtes de tirage, crĂ©er et Ă©diter des Ă©quipes, commenter des lignes de code dans une requĂȘte de tirage, chercher dans le site et bien plus encore.

Changer le statut d’une requĂȘte de tirage

Nous allons voir un dernier exemple trĂšs utile si vous travaillez avec des requĂȘtes de tirage. Chaque commit peut avoir un ou plusieurs statuts associĂ©s et il y a une interface de programmation pour ajouter et demander ce statut.

La plupart des services d’IntĂ©gration Continue et de test utilisent cette interface de programmation pour rĂ©agir aux poussĂ©es en testant le code qui a Ă©tĂ© poussĂ©, et en signalant si ce commit a passĂ© tous les tests. Vous pourriez aussi utiliser ceci pour vĂ©rifier que le message de validation est formatĂ© proprement, si l’auteur a suivi les recommandations de contribution, si la signature du commit est valide — vous pouvez faire autant de choses que vous le souhaitez.

Supposons que vous souhaitez définir un crochet web sur votre dépÎt qui atteint un petit service web qui vérifie que le message de validation contient la chaßne Signed-off-by.

require 'httparty'
require 'sinatra'
require 'json'

post '/payload' do
  push = JSON.parse(request.body.read) # parse the JSON
  repo_name = push['repository']['full_name']

  # examine chaque message de validation
  push["commits"].each do |commit|

    # cherche la chaĂźne "Signed-off-by"
    if /Signed-off-by/.match commit['message']
      state = 'success'
      description = 'Successfully signed off!'
    else
      state = 'failure'
      description = 'No signoff found.'
    end

    # envoie le statut Ă  GitHub
    sha = commit["id"]
    status_url = "https://api.github.com/repos/#{repo_name}/statuses/#{sha}"

    status = {
      "state"       => state,
      "description" => description,
      "target_url"  => "https://example.com/how-to-signoff",
      "context"     => "validate/signoff"
    }
    HTTParty.post(status_url,
      :body => status.to_json,
      :headers => {
        'Content-Type'  => 'application/json',
        'User-Agent'    => 'tonychacon/signoff',
        'Authorization' => "token #{ENV['TOKEN']}" }
    )
  end
end

Ça devrait ĂȘtre simple Ă  suivre. Dans ce crochet web, nous examinons chaque commit qui vient d’ĂȘtre poussĂ©, nous cherchons la chaĂźne "Signed-off-by" dans le message de validation et enfin nous faisons un POST via HTTP au point d’entrĂ©e applicatif /repos/<utilisateur>/<dĂ©pĂŽt>/statuses/<commit_sha> avec le statut.

Dans ce cas, vous pouvez envoyer un Ă©tat ("success", "failure", "error"), une description de ce qui s’est passĂ©, un URL cible oĂč l’utilisateur peut aller pour plus d’informations et un « contexte » dans le cas oĂč il y a de multiples statuts pour un seul commit. Par exemple, un service de test peut fournir un statut et un service de validation comme celui-ci peut aussi fournir un statut — le champ « contexte » permet de les diffĂ©rencier.

Si quelqu’un ouvre une nouvelle requĂȘte de tirage sur GitHub et que ce crochet est opĂ©rationnel, vous pouvez voir quelque chose comme Statut de commit via l’interface de programmation..

Commit status
Figure 135. Statut de commit via l’interface de programmation.

Vous pouvez voir maintenant une petite coche verte prĂšs du commit qui contient la chaĂźne « Signed-off-by » dans le message et une croix rouge pour celui que l’auteur Ă  oubliĂ© de signer. Vous pouvez aussi voir que la requĂȘte de tirage prend le statut du dernier commit de la branche et avertit si c’est un Ă©chec. C’est trĂšs utile si vous utilisez cette interface de programmation pour des rĂ©sultats de test pour que vous ne fusionniez pas accidentellement quelque chose oĂč le dernier commit Ă©choue aux tests.

Octokit

Bien que nous ayons presque tout fait Ă  travers curl et de simples requĂȘtes HTTP dans ces exemples, il existe plusieurs bibliothĂšques open source qui rendent cette interface de programmation plus idiomatique. Au moment de la rĂ©daction de ce document, les langages supportĂ©s incluent Python, Go, Objective-C, Ruby et .NET. Consultez https://github.com/octokit pour plus d’informations Ă  ce propos, puisqu’ils gĂšrent une bonne partie de HTTP pour vous.

Heureusement ces outils devraient vous aider Ă  personnaliser et modifier GitHub pour travailler mieux suivant vos mĂ©thodes de travail spĂ©cifiques. Pour une documentation complĂšte de l’ensemble de l’interface de programmation ainsi que pour des guides pour les tĂąches habituelles, consultez https://docs.github.com/en/developers.

scroll-to-top