Verwenden von Azure Functions zum Erstellen benutzerdefinierter Branchrichtlinien
Azure DevOps Services | Azure DevOps Server 2020 | Azure DevOps Server 2019 | TFS 2018
Der Pull request (PR)-Workflow bietet Entwicklern die Möglichkeit, Feedback zu ihrem Code von Peers sowie von automatisierten Tools zu erhalten. Tools und Dienste von Drittanbietern können mithilfe der PR-Status-API an dem PR-Workflow teilnehmen. Dieser Artikel führt Sie durch den Prozess des Erstellens einer benutzerdefinierten Verzweigungsrichtlinie mithilfe von Azure Functions, um PRs in einem Azure DevOps Services Git-Repository zu überprüfen. Mit Azure Functions müssen Sie sich keine Gedanken über die Bereitstellung und Wartung von Servern machen, insbesondere, wenn Ihre Arbeitsauslastung wächst. Azure Functions bieten eine voll verwaltete Computeplattform mit hoher Zuverlässigkeit und Sicherheit.
Weitere Informationen zum PR-Status finden Sie unter Anpassen und Erweitern von Pullanforderungsworkflows mit Pullanforderungsstatus.
Voraussetzungen
Eine Organisation in Azure DevOps mit einem Git-Repo. Wenn Sie keine Organisation haben, registrieren Sie sich, um Code in kostenlosen privaten Git-Repositorys hochzuladen und freizugeben.
Erstellen einer grundlegenden Azure-Funktion zum Überwachen von Azure Repos Ereignissen
Folgen Sie der Erstellung Ihrer ersten Azure-Funktionsdokumentation , um eine einfache Funktion zu erstellen. Ändern Sie den Code im Beispiel so, dass es wie folgt aussieht:
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);
}
}
Konfigurieren eines Diensthakens für PR-Ereignisse
Diensthaken sind ein Azure DevOps Services Feature, das externe Dienste benachrichtigen kann, wenn bestimmte Ereignisse auftreten. In diesem Beispiel möchten Sie einen Dienst-Hook für PR-Ereignisse einrichten, ihre Azure-Funktion wird benachrichtigt, wenn sich eine Pullanforderung ändert. Um Anforderungen zu empfangen POST
, wenn Pullanforderungen geändert werden, müssen Sie den Dienst-Hook mit der Azure-Funktions-URL bereitstellen.
Für dieses Beispiel müssen Sie 2 Dienst-Hooks konfigurieren. Die erste wird für das erstellte Pull-Anforderungsereignis verwendet, und der zweite wird für das aktualisierte Pull-Anforderungsereignis verwendet.
Rufen Sie die Funktions-URL aus dem Azure-Portal ab, indem Sie in der Azure-Funktionsansicht auf die URL der Get-Funktion klicken und die URL kopieren.
Navigieren Sie zu Ihrem Projekt in Azure DevOps, z. B.
https://dev.azure.com/<your organization>/<your project name>
Zeigen Sie im Navigationsmenü auf das Zahnrad , und wählen Sie "Service Hooks" aus.
Wenn dies Ihr erster Dienst-Hook ist, wählen Sie +Abonnement erstellen aus.
Wenn Sie bereits andere Dienst-Hooks konfiguriert haben, wählen Sie das grüne Plus aus
(+)
, um ein neues Dienst-Hook-Abonnement zu erstellen.Wählen Sie im Dialogfeld "Neues Dienst-Hooks-Abonnement" Web-Hooks aus der Liste der Dienste aus, und wählen Sie dann "Weiter" aus.
Wählen Sie pull-Anforderung aus der Liste der Ereignistrigger aus, und wählen Sie dann "Weiter" aus.
Geben Sie auf der Seite "Aktion" die URL ein, die Sie in Schritt 1 im URL-Feld kopiert haben. Wählen Sie "Testen " aus, um ein Testereignis an Ihren Server zu senden.
Im Azure-Funktionsprotokollfenster wird ein eingehender Wert angezeigt, der ein
200 OK
eingehendesPOST
Ereignis zurückgibt, das angibt, dass Ihre Funktion das Dienst-Hook-Ereignis empfangen hat.HTTP Requests ------------- POST / 200 OK
Wählen Sie im Fenster "Benachrichtigung testen" die Registerkarte "Antwort" aus, um die Details der Antwort von Ihrem Server anzuzeigen. Sie sollten die Antwort von Ihrem Server sehen.
Schließen Sie das Fenster "Benachrichtigung testen", und wählen Sie " Fertig stellen" aus, um den Dienst-Hook zu erstellen.
Führen Sie die Schritte 2-8 erneut durch, aber dieses Mal konfigurieren Sie das aktualisierte Pull-Anforderungsereignis .
Wichtig
Führen Sie die vorherigen Schritte zweimal durch und erstellen Sie Dienst-Hooks für die aktualisierten Ereignisse der Pullanforderung und pull-Anforderung.
Erstellen Sie eine Pullanforderung, um zu überprüfen, ob Ihre Azure-Funktion Benachrichtigungen empfängt.
Poststatus für PRs
Nachdem Ihr Server Dienst-Hook-Ereignisse empfangen kann, wenn neue PRs erstellt werden, aktualisieren Sie sie, um den Status zurück auf die PR zu posten. Sie können die JSON-Nutzlast verwenden, die vom Dienst-Hook gepostet wurde, um zu bestimmen, welcher Status für Ihre PR festgelegt werden soll.
Aktualisieren Sie den Code Ihrer Azure-Funktion so, dass es wie im folgenden Beispiel aussieht.
Aktualisieren Sie den Code mit dem Namen Ihrer Organisation, dem Projektnamen, dem Repositorynamen und dem PAT-Token. Um über die Berechtigung zum Ändern des PR-Status zu verfügen, erfordert das PAT vso.code_status Bereich, den Sie erteilen können, indem Sie den Codebereich (Status) auf der Seite "Erstellen eines persönlichen Zugriffstokens" auswählen.
Wichtig
In diesem Beispielcode wird der PAT im Code gespeichert, um das Beispiel zu vereinfachen. Es wird empfohlen, geheime Schlüssel in KeyVault zu speichern und von dort abzurufen.
In diesem Beispiel wird der PR-Titel überprüft, um festzustellen, ob der Benutzer angegeben hat, ob es sich bei der PR um eine Arbeit handelt, indem WIP zum Titel hinzugefügt wird. Wenn ja, ändert der Beispielcode den Status, der wieder in die PR gepostet wurde. Ersetzen Sie den Code in Ihrer Azure-Funktion durch den folgenden Code, um die Aktualisierung des Status zu implementieren, der zurück in die PR gepostet wurde.
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"
}
});
}
Erstellen eines neuen PR zum Testen des Statusservers
Nachdem Ihr Server jetzt ausgeführt wird und Dienst-Hook-Benachrichtigungen lauscht, erstellen Sie eine Pullanforderung, um sie auszutesten.
Beginnen Sie in der Dateiansicht. Bearbeiten Sie die readme.md Datei in Ihrem Repository (oder eine andere Datei, wenn Sie keine readme.md haben).
Nehmen Sie eine Bearbeitung vor, und übernehmen Sie die Änderungen am Repository.
Stellen Sie sicher, dass Sie die Änderungen an einer neuen Verzweigung übernehmen, damit Sie im nächsten Schritt eine PR erstellen können.
Wählen Sie den Link " Pullanforderung erstellen" aus.
Fügen Sie WIP im Titel hinzu, um die Funktionalität der App zu testen. Wählen Sie "Erstellen" aus, um die PR zu erstellen.
Nachdem die PR erstellt wurde, wird der Statusabschnitt mit dem Statuseintrag "Arbeit in Bearbeitung " angezeigt, der eine Verknüpfung mit der in der Nutzlast angegebenen URL enthält.
Aktualisieren Sie den PR-Titel, und entfernen Sie den WIP-Text , und beachten Sie, dass sich der Status von "Arbeit" in"Bereit zur Überprüfung" ändert.
Nächste Schritte
- In diesem Artikel haben Sie die Grundlagen erfahren, wie Sie eine serverlose Azure-Funktion erstellen, die pr-Ereignisse über Dienst-Hooks lauscht und Statusmeldungen mithilfe der Status-API posten kann. Weitere Informationen zur Pull-Anforderungsstatus-API finden Sie in der REST-API-Dokumentation.
- Konfigurieren Sie eine Verzweigungsrichtlinie für einen externen Dienst.