Utiliser Azure Functions pour créer des stratégies de branche personnalisées
Azure DevOps Services | Azure DevOps Server 2022 | Azure DevOps Server 2019
Le workflow de demande de tirage permet aux développeurs d’obtenir des commentaires sur leur code des pairs ainsi que des outils automatisés. Les outils et services tiers peuvent participer au flux de travail de demande de tirage à l’aide de l’API d’état de la demande de tirage. Cet article vous guide tout au long du processus de création d’une stratégie de branche personnalisée à l’aide d’Azure Functions pour valider les demandes de tirage dans un référentiel Git Azure DevOps Services. Avec Azure Functions, vous n’avez pas à vous soucier de l’approvisionnement et de la maintenance des serveurs, en particulier lorsque votre charge de travail augmente. Azure Functions fournit une plateforme de calcul entièrement managée avec une fiabilité et une sécurité élevées.
Pour plus d’informations sur l’état des demandes de tirage, consultez Personnaliser et étendre les flux de travail de demande de tirage avec l’état des demandes de tirage.
Prérequis
Une organisation dans Azure DevOps avec un référentiel Git. Si vous n’avez pas d’organisation, inscrivez-vous pour charger et partager du code dans des référentiels Git privés gratuits illimités.
Créer une fonction Azure de base pour écouter les événements Azure Repos
Suivez la documentation de création de votre première fonction Azure pour créer une fonction simple. Modifiez le code dans l’exemple pour qu’il ressemble à ceci :
using System;
using System.Net;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text;
using Newtonsoft.Json;
public static async Task<HttpResponseMessage> Run(HttpRequestMessage req, TraceWriter log)
{
try
{
log.Info("Service Hook Received.");
// Get request body
dynamic data = await req.Content.ReadAsAsync<object>();
log.Info("Data Received: " + data.ToString());
// Get the pull request object from the service hooks payload
dynamic jObject = JsonConvert.DeserializeObject(data.ToString());
// Get the pull request id
int pullRequestId;
if (!Int32.TryParse(jObject.resource.pullRequestId.ToString(), out pullRequestId))
{
log.Info("Failed to parse the pull request id from the service hooks payload.");
};
// Get the pull request title
string pullRequestTitle = jObject.resource.title;
log.Info("Service Hook Received for PR: " + pullRequestId + " " + pullRequestTitle);
return req.CreateResponse(HttpStatusCode.OK);
}
catch (Exception ex)
{
log.Info(ex.ToString());
return req.CreateResponse(HttpStatusCode.InternalServerError);
}
}
Configurer un crochet de service pour les événements de demande de tirage
Les crochets de service sont une fonctionnalité Azure DevOps Services qui peut alerter les services externes lorsque certains événements se produisent. Pour cet exemple, si vous souhaitez configurer un crochet de service pour les événements de demande de tirage, votre fonction Azure sera avertie lorsqu’une demande de tirage changera. Pour recevoir des requêtes POST
lorsque les demandes de tirage changent, vous devez fournir le crochet de service avec l’URL de la fonction Azure.
Pour cet exemple, vous devez configurer 2 crochets de service. Le premier est destiné à l’événement Demande de tirage créée et le second est destiné à l’événement Demande de tirage mise à jour.
Obtenez l’URL de la fonction à partir du portail Azure en cliquant sur Obtenir l’URL de la fonction dans la vue de votre fonction Azure et copiez l’URL.
Accédez à votre projet dans Azure DevOps, par exemple
https://dev.azure.com/<your organization>/<your project name>
Dans le menu de navigation, pointez sur l’engrenage et sélectionnez Crochets de service.
S’il s’agit de votre premier crochet de service, sélectionnez + Créer un abonnement.
Si vous avez déjà configuré d’autres crochets de service, sélectionnez le
(+)
vert plus pour créer un abonnement de crochet de service.Dans la boîte de dialogue Nouvel abonnement de crochets de service, sélectionnez Webhooks dans la liste des services, puis sélectionnez Suivant.
Sélectionnez Demande de tirage créée dans la liste des déclencheurs d’événements, puis sélectionnez Suivant.
Dans la page Action, entrez l’URL que vous avez copiée à l’étape 1 dans la zone URL. Sélectionnez Test pour envoyer un événement de test à votre serveur.
Dans la fenêtre du journal des fonctions Azure, vous verrez un entrant
POST
qui a retourné un200 OK
, indiquant que votre fonction a reçu l’événement de crochet de service.HTTP Requests ------------- POST / 200 OK
Dans la fenêtre Notification de test, sélectionnez l’onglet Réponse pour afficher les détails de la réponse à partir de votre serveur. Vous devez voir la réponse de votre serveur.
Fermez la fenêtre Notification de test, puis sélectionnez Terminer pour créer le crochet de service.
Passez à nouveau par les étapes 2 à 8, mais cette fois, configurez l’événement Demande de tirage mise à jour.
Important
Veillez à parcourir les étapes précédentes à deux reprises et à créer des crochets de service pour les événements Demande de tirage créée et Demande de tirage mise à jour.
Créez une demande de tirage pour vérifier que votre fonction Azure reçoit des notifications.
Publier l’état sur les demandes de tirage
Maintenant que votre serveur peut recevoir des événements de crochet de service lorsque de nouvelles demandes de tirage sont créées, mettez-le à jour pour publier l’état de retour à la demande de tirage. Vous pouvez utiliser la charge utile JSON publiée par le crochet de service pour déterminer l’état à définir sur votre demande de tirage.
Mettez à jour le code de votre fonction Azure pour qu’il ressemble à l’exemple suivant.
Veillez à mettre à jour le code avec le nom de votre organisation, le nom du projet, le nom du référentiel et le jeton PAT. Pour avoir l’autorisation de modifier l’état de la demande de tirage, le PAT nécessite l’étendue vso.code_status, que vous pouvez accorder en sélectionnant l’étendue Code (état) dans la page Créer un jeton d’accès personnel.
Important
Cet exemple de code stocke le PAT dans le code pour simplifier l’exemple. Il est recommandé de stocker des secrets dans KeyVault et de les récupérer à partir de là.
Cet exemple inspecte le titre de la demande de tirage pour voir si l’utilisateur a indiqué si la demande de tirage est un travail en cours en ajoutant WIP au titre. Si c’est le cas, l’exemple de code modifie l’état de retour publié sur la demande de tirage. Remplacez le code dans votre fonction Azure par le code suivant pour implémenter la mise à jour de l’état de retour publié dans la demande de tirage.
using System;
using System.Net;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text;
using Newtonsoft.Json;
private static string organizationName = "[Organization Name]"; // Organization name
private static string projectName = "[Project Name]"; // Project name
private static string repositoryName = "[Repo Name]"; // Repository name
/*
This is here just to simplify the sample, it is recommended to store
secrets in KeyVault and retrieve them from there.
*/
private static string pat = "[PAT TOKEN]";
public static async Task<HttpResponseMessage> Run(HttpRequestMessage req, TraceWriter log)
{
try
{
log.Info("Service Hook Received.");
// Get request body
dynamic data = await req.Content.ReadAsAsync<object>();
log.Info("Data Received: " + data.ToString());
// Get the pull request object from the service hooks payload
dynamic jObject = JsonConvert.DeserializeObject(data.ToString());
// Get the pull request id
int pullRequestId;
if (!Int32.TryParse(jObject.resource.pullRequestId.ToString(), out pullRequestId))
{
log.Info("Failed to parse the pull request id from the service hooks payload.");
};
// Get the pull request title
string pullRequestTitle = jObject.resource.title;
log.Info("Service Hook Received for PR: " + pullRequestId + " " + pullRequestTitle);
PostStatusOnPullRequest(pullRequestId, ComputeStatus(pullRequestTitle));
return req.CreateResponse(HttpStatusCode.OK);
}
catch (Exception ex)
{
log.Info(ex.ToString());
return req.CreateResponse(HttpStatusCode.InternalServerError);
}
}
private static void PostStatusOnPullRequest(int pullRequestId, string status)
{
string Url = string.Format(
@"https://dev.azure.com/{0}/{1}/_apis/git/repositories/{2}/pullrequests/{3}/statuses?api-version=4.1",
organizationName,
projectName,
repositoryName,
pullRequestId);
using (HttpClient client = new HttpClient())
{
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", Convert.ToBase64String(
ASCIIEncoding.ASCII.GetBytes(
string.Format("{0}:{1}", "", pat))));
var method = new HttpMethod("POST");
var request = new HttpRequestMessage(method, Url)
{
Content = new StringContent(status, Encoding.UTF8, "application/json")
};
using (HttpResponseMessage response = client.SendAsync(request).Result)
{
response.EnsureSuccessStatusCode();
}
}
}
private static string ComputeStatus(string pullRequestTitle)
{
string state = "succeeded";
string description = "Ready for review";
if (pullRequestTitle.ToLower().Contains("wip"))
{
state = "pending";
description = "Work in progress";
}
return JsonConvert.SerializeObject(
new
{
State = state,
Description = description,
TargetUrl = "https://visualstudio.microsoft.com",
Context = new
{
Name = "PullRequest-WIT-App",
Genre = "pr-azure-function-ci"
}
});
}
Créer une nouvelle demande de tirage pour tester le serveur d’état
Maintenant que votre serveur est en cours d’exécution et écoute des notifications de crochet de service, créez une demande de tirage pour la tester.
Démarrez dans la vue fichiers. Modifiez le fichier readme.md dans votre référentiel (ou tout autre fichier si vous n’avez pas de readme.md).
Apportez une modification et validez les modifications apportées au référentiel.
Veillez à valider les modifications apportées à une nouvelle branche afin de pouvoir créer une demande de tirage à l’étape suivante.
Sélectionnez le lien Créer une demande de tirage.
Ajoutez WIP dans le titre pour tester les fonctionnalités de l’application. Sélectionnez Créer pour créer la demande de tirage.
Une fois la demande de tirage créée, vous verrez la section d’état, avec l’entrée Travail en cours qui lie l’URL spécifiée dans la charge utile.
Mettez à jour le titre de la demande de tirage et supprimez le texte WIP et notez que l’état passe de Travail en cours à Prêt pour la révision.
Étapes suivantes
- Dans cet article, vous avez appris les bases de la création d’une fonction Azure serverless qui écoute les événements de demande de tirage via des crochets de service et peut publier des messages d’état à l’aide de l’API d’état. Pour plus d’informations sur l’API d’état de la demande de tirage, consultez la documentation de l’API REST.
- Configurer une stratégie de branche pour un service externe.