Использование Функций Azure для создания пользовательских политик ветвей
Azure DevOps Services | Azure DevOps Server 2022 — Azure DevOps Server 2019
Рабочий процесс пулл-реквестов (PR) позволяет разработчикам получать отзывы о своем коде от коллег и автоматизированных инструментов. Немайкрософтовские инструменты и службы также могут участвовать в рабочем процессе PR с помощью API состояния PR. В этой статье описано, как создать настраиваемую политику ветви с помощью функций Azure для проверки PR в репозитории Azure DevOps Git. Функции Azure устраняют необходимость подготовки и обслуживания серверов, даже при росте рабочей нагрузки. Они предоставляют полностью управляемую платформу вычислений с высокой надежностью и безопасностью.
Дополнительные сведения о состоянии pull request см. в разделе Настройка и расширение рабочих процессов pull request со статусом.
Предпосылки
Категория | Требования |
---|---|
Предприятие | Организация в Azure DevOps с репозиторием Git. |
Функция Azure | Функция Azure, которая реализует бессерверное решение, управляемое событиями, которое интегрируется с Azure DevOps для создания настраиваемых политик ветви и автоматизации проверки PR. |
Хуки сервисов | Настройте веб-хуки службы для событий запроса на вытягивание (PR), чтобы уведомить функцию Azure при изменении запроса на вытягивание. |
Личный маркер доступа (PAT) | Создайте PAT с областью кода (статуса), чтобы иметь разрешение на изменение статуса PR. Дополнительные сведения см. в разделе "Использование PATs для проверки подлинности". |
Создание базовой функции Azure для прослушивания событий Azure Repos
Создайте первую функцию Azure. Затем измените код в примере, чтобы выглядеть следующим образом:
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);
}
}
Настройка перехватчика службы для событий PR
Сервисные хуки — это возможность Azure DevOps, которая может оповещать внешние службы о возникновении определенных событий. В этом примере настройте перехватчик службы для событий PR, функция Azure уведомляется при изменении запроса на вытягивание. Чтобы получать POST
запросы при изменении запросов на вытягивание, укажите перехватчик службы URL-адресом функции Azure.
В этом примере настройте два перехвата службы. Первое — для события создания запроса на вытягивание, а второе — для события обновления запроса на вытягивание.
Получите URL-адрес функции на портале Azure, щелкнув Получить URL-адрес функции в представлении вашей функции Azure и скопируйте URL-адрес.
Перейдите к проекту в Azure DevOps, например
https://dev.azure.com/<your organization>/<your project name>
В меню навигации наведите курсор на шестерёнку и выберите хуки службы.
Если это ваш первый сервисный хук, выберите + Создать подписку.
Если у вас уже настроены другие веб-хуки, выберите значок зеленого плюса
(+)
, чтобы создать новую подписку на веб-хук.В диалоговом окне "Новая подписка перехватчиков служб" выберите веб-перехватчики из списка служб, а затем выберите Далее.
Выберите запрос на вытягивание, созданный из списка триггеров событий, а затем выберите Далее.
На странице действия введите URL-адрес, скопированный на шаге 1 в поле URL-адреса . Выберите Test, чтобы отправить тестовое событие на сервер.
В окне журнала функций Azure отображается входящий
POST
, который вернул статус200 OK
, указывая, что ваша функция получила событие перехватчика службы.HTTP Requests ------------- POST / 200 OK
В окне "Уведомление о тестировании" выберите вкладку "Ответ", чтобы просмотреть сведения об ответе с сервера. Вы увидите ответ с сервера.
Закройте окно уведомления о тестировании и выберите Завершить, чтобы создать веб-хук службы.
Повторите шаги 2-8, но на этот раз настройте обновленное событие запроса на вытягивание .
Это важно
Обязательно дважды выполните описанные выше действия и создайте хуки сервисов для события созданного запроса на вытягивание и события обновленного запроса на вытягивание.
Создайте pull request, чтобы убедиться, что ваша функция Azure получает уведомления.
Состояние публикации в PR
Теперь, когда сервер может получать события хуков при создании новых PR, обновите его, чтобы отправить статус обратно в PR. Полезные данные JSON, отправленные вебхуком сервиса, можно использовать для определения статуса, который нужно установить для вашего PR.
Обновите код функции Azure, как показано в следующем примере.
Обязательно обновите код с именем организации, именем проекта, именем репозитория и маркером PAT. Чтобы иметь разрешение на изменение состояния PR, ПАТ требует область vso.code_status, которую можно предоставить, выбрав область Код (состояние) на странице Создать личный маркер доступа.
Это важно
Этот пример кода хранит PAT в коде, упрощая пример. Рекомендуется хранить секреты в KeyVault и извлекать их из него.
В этом примере проверяется заголовок PR, чтобы узнать, указал ли пользователь, находится ли PR в разработке, добавив WIP в заголовок. В этом случае пример кода изменяет состояние, переданное обратно в PR. Замените код в функции Azure следующим кодом, который обновляет статус, размещенный обратно в PR.
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"
}
});
}
Создайте новый PR и проверьте статус сервера
Теперь, когда ваш сервер работает и прослушивает уведомления веб-хуков, создайте pull request, чтобы протестировать его.
Начните с просмотра файлов. Измените файл readme.md в репозитории (или любой другой файл, если у вас нет readme.md).
Внесите изменения и зафиксируйте изменения в репозитории.
Обязательно зафиксируйте изменения в новой ветви, чтобы создать PR на следующем шаге.
Выберите ссылку Создать пулл-реквест.
Добавьте WIP в заголовке, чтобы проверить функциональные возможности приложения. Выберите Создать, чтобы создать PR.
После создания PR отображается раздел состояния с записью «В работе», которая ссылается на URL-адрес, указанный в пакете данных.
Обновите заголовок PR и удалите текст WIP и заметьте, что статус изменяется с В работе на Готово для проверки.