Использование Функций Azure для создания пользовательских политик ветвей

Azure DevOps Services | Azure DevOps Server 2022 — Azure DevOps Server 2019

Рабочий процесс запроса на вытягивание (PR) предоставляет разработчикам возможность получать отзывы об их коде от одноранговых узлов, а также от автоматизированных средств. Сторонние инструменты и службы могут участвовать в рабочем процессе pr с помощью API состояния PR. В этой статье описывается процесс создания пользовательской политики ветви с помощью Функции Azure для проверки PR в репозитории Git Azure DevOps Services. При Функции Azure вам не нужно беспокоиться о подготовке и обслуживании серверов, особенно при росте рабочей нагрузки. Функции Azure обеспечить полностью управляемую платформу вычислений с высокой надежностью и безопасностью.

Дополнительные сведения о состоянии pr см. в разделе "Настройка и расширение рабочих процессов запроса на вытягивание" с состоянием запроса на вытягивание.

Необходимые компоненты

Организация в Azure DevOps с репозиторием Git. Если у вас нет организации, зарегистрируйтесь для отправки и совместного использования кода в бесплатных частных репозиториях Git.

Создание базовой функции 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 Services, которая может оповещать внешние службы при возникновении определенных событий. В этом примере вы хотите настроить перехватчик службы для событий PR, функция Azure будет уведомлена при изменении запроса на вытягивание. Чтобы получать POST запросы при изменении запросов на вытягивание, необходимо предоставить перехватчик службы с URL-адресом функции Azure.

Для этого примера необходимо настроить 2 перехватчика службы. Первый будет для созданного события запроса на вытягивание, а второй — для обновленного события запроса на вытягивание.

  1. Получите URL-адрес функции из портал Azure, щелкнув URL-адрес функции Get в представлении функций Azure и скопируйте URL-адрес.

    Получение URL-адреса функции

    Url-адрес функции копирования

  2. Перейдите к проекту в Azure DevOps, например. https://dev.azure.com/<your organization>/<your project name>

  3. В меню навигации наведите указатель мыши на шестеренку и выберите "Перехватчики служб".

    Выбор перехватчиков служб в меню администрирования

  4. Если это первый перехватчик службы, нажмите кнопку +Создать подписку.

    Выберите

    Если у вас уже настроены другие перехватчики служб, выберите зеленый плюс (+) , чтобы создать подписку на перехватчик службы.

    Выберите зеленый плюс, чтобы создать подписку на перехватчик службы.

  5. В диалоговом окне "Новая подписка перехватчиков служб" выберите веб-перехватчики из списка служб, а затем нажмите кнопку "Далее".

    Выберите веб-перехватчики из списка служб

  6. Выберите запрос на вытягивание, созданный из списка триггеров событий, а затем нажмите кнопку "Далее".

    Выберите запрос на вытягивание, созданный из списка триггеров событий

  7. На странице действия введите URL-адрес, скопированный на шаге 1 в поле URL-адреса . Выберите "Тест" , чтобы отправить тестовое событие на сервер.

    Введите URL-адрес и выберите

    В окне журнала функций Azure вы увидите входящие POST , возвращающие 200 OKфункцию, указывающую, что функция получила событие перехватчика службы.

    HTTP Requests
    -------------
    
    POST /                         200 OK
    

    В окне "Уведомление о тестировании" выберите вкладку "Ответ", чтобы просмотреть сведения об ответе с сервера. Вы увидите ответ с сервера.

    Выберите вкладку ответа, чтобы просмотреть результаты теста

  8. Закройте окно "Уведомление о тестировании" и нажмите кнопку "Готово ", чтобы создать перехватчик службы.

Повторите шаги 2-8, но на этот раз настройте обновленное событие запроса на вытягивание.

Внимание

Обязательно дважды выполните описанные выше действия и создайте перехватчики служб для созданных запросов на вытягивание и обновленных событий запроса на вытягивание .

Создайте запрос на вытягивание, чтобы убедиться, что функция 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-запроса для тестирования сервера состояния

Теперь, когда сервер работает и прослушивает уведомления об перехватчике служб, создайте запрос на вытягивание, чтобы протестировать его.

  1. Запустите представление файлов. Измените файл readme.md в репозитории (или любой другой файл, если у вас нет readme.md).

    Выберите

  2. Внесите изменения и зафиксируйте изменения в репозитории.

    Измените файл и выберите

  3. Обязательно зафиксируйте изменения в новой ветви, чтобы создать PR на следующем шаге.

    Введите новое имя ветви и нажмите кнопку

  4. Выберите ссылку "Создать запрос на вытягивание".

    Выберите

  5. Добавьте WIP в заголовок, чтобы проверить функциональные возможности приложения. Нажмите кнопку "Создать", чтобы создать pr.

    Добавление WIP в заголовок PR по умолчанию

  6. После создания pr вы увидите раздел состояния с записью "Работа в процессе ", которая ссылается на URL-адрес, указанный в полезных данных.

    Раздел состояния с записью

  7. Обновите заголовок PR и удалите текст WIP и обратите внимание, что состояние выполняется на "Готово для проверки".

Next Steps

  • В этой статье вы узнали, как создать бессерверную функцию Azure, которая прослушивает события PR через перехватчики служб и может публиковать сообщения о состоянии с помощью API состояния. Дополнительные сведения об API состояния запроса на вытягивание см. в документации по REST API.
  • Настройте политику ветви для внешней службы.