Создать подписку на перехватчик события с помощью программных средств

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

С помощью REST API подписок можно программно создать подписку, которая выполняет действие во внешней или потребительской службе при возникновении определенного события в проекте Azure DevOps. Например, вы можете создать подписку для уведомления службы о сбое сборки.

Поддерживаемые события:

  • Сборка завершена
  • Код вживлен (для проектов Git)
  • Создание или обновление запроса на вытягивание (для проектов Git)
  • Код возвращен (проекты TFVC)
  • Рабочий элемент создан, обновлен, удален, восстановлен или закомментирован

Вы можете настроить в подписках фильтры, чтобы управлять тем, какие события запускают действие. Например, можно отфильтровать событие завершения сборки по состоянию сборки. Полный набор поддерживаемых событий и параметров фильтра см. в статье Справочные материалы по событиям.

Полный набор поддерживаемых служб и действий потребителей см. в статье Справочные материалы по потребителям.

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

Чтобы создать подписку, требуются следующие данные:

  • Идентификатор проекта. Используйте REST API Project для получения идентификатора проекта.
  • Идентификатор события и параметры. См. справочник по событиям.
  • Идентификаторы и идентификаторы потребителей и действий. См. справочник по потребителю.

Создание запроса

Создайте текст HTTP-запроса POST, чтобы создать подписку на основе идентификатора проекта, события, потребителя и действия.

См. следующий пример запроса на создание подписки, которая приводит к возникновению события сборки POST https://myservice/event при сбое сборки WebSite.CI .

Запросить

{
    "publisherId": "tfs",
    "eventType": "build.complete",
    "resourceVersion": "1.0",
    "consumerId": "webHooks",
    "consumerActionId": "httpRequest",
    "publisherInputs": {
        "buildStatus": "failed",
        "definitionName": "WebSite.CI",
        "projectId": "56479caf-1eeb-4bca-86ab-aaa6f29399d9",
    },
    "consumerInputs": {
        "url": " https://myservice/event"
    },
}

Настоятельно рекомендуется использовать безопасные URL-адреса HTTPS для безопасности частных данных в объекте JSON.

Ответ см. в следующем ответе на запрос для создания подписки:

{
    "id": "74aeeed0-bf5d-48dc-893f-f862b80987e9",
    "url": "https://dev.azure.com/fabrikam/DefaultCollection/_apis/hooks/subscriptions/74aeeed0-bf5d-48dc-893f-f862b80987e9",
    "publisherId": "tfs",
    "eventType": "build.complete",
    "resourceVersion": "1.0",
    "consumerId": "webHooks",
    "consumerActionId": "httpRequest",
    "createdBy": {
        "id": "00ca946b-2fe9-4f2a-ae2f-40d5c48001bc"
    },
    "createdDate": "2014-03-28T16:10:06.523Z",
    "modifiedBy": {
        "id": "1c4978ae-7cc9-4efa-8649-5547304a8438"
    },
    "modifiedDate": "2014-04-25T18:15:26.053Z",
    "publisherInputs": {
        "buildStatus": "failed",
        "definitionName": "WebSite.CI",
        "hostId": "17f27955-99bb-4861-9550-f2c669d64fc9",
        "projectId": "56479caf-1eeb-4bca-86ab-aaa6f29399d9",
        "tfsSubscriptionId": "29cde8b4-f37e-4ef9-a6d4-d57d526d82cc"
    },
    "consumerInputs": {
        "url": "http://myservice/event"
    }
}

Если запрос на подписку завершается сбоем, вы получите код ответа HTTP 400 с сообщением, которое содержит дополнительные сведения.

Что происходит при возникновении события?

При возникновении события оцениваются все включенные подписки в проекте, а действие потребителя выполняется для всех соответствующих подписок.

Версии ресурсов (расширенные)

Управление версиями ресурсов применимо, если API находится в предварительной версии. Для большинства сценариев, указывая 1.0 версию ресурса, является самым безопасным маршрутом.

Полезные данные события, отправленные определенным потребителям, таким как веб-перехватчики, Служебная шина Azure и служба хранилища Azure, включают представление json субъекта ресурса (например, сборку или рабочий элемент). Представление этого ресурса может иметь разные формы или версии.

Вы можете указать версию ресурса, который вы хотите отправить в службу потребителей с помощью resourceVersion поля в подписке. Версия ресурса совпадает с версией API. Не указывая версию ресурса, означает "последнюю версию". Всегда следует указать версию ресурса, которая гарантирует согласованность полезных данных событий с течением времени.

Вопросы и ответы

Вопрос. Есть ли службы, на которые я могу подписаться вручную?

Ответ. Да. Дополнительные сведения о службах, которые можно подписаться на страницу администрирования проекта, см. в разделе " Обзор".

Вопрос. Существуют ли библиотеки C#, которые можно использовать для создания подписок?

Ответ. Нет, но вот пример, который поможет вам приступить к работе.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Web.Mvc;

namespace Microsoft.Samples.VisualStudioOnline
{
    public class ServiceHookEventController : Controller
    {

        // POST: /ServiceHookEvent/workitemcreated
        [HttpPost]
        public HttpResponseMessage WorkItemCreated(Content workItemEvent)
        {
            //Grabbing the title for the new workitem
            var value = RetrieveFieldValue("System.field", workItemEvent.Resource.Fields);

            //Acknowledge event receipt
            return new HttpResponseMessage(HttpStatusCode.OK);
        }

        /// <summary>
        /// Gets the value for a specified work item field.
        /// </summary>
        /// <param name="key">Key used to retrieve matching value</param>
        /// <param name="fields">List of fields for a work item</param>
        /// <returns></returns>
        public String RetrieveFieldValue(String key, IList<FieldInfo> fields)
        {
            if (String.IsNullOrEmpty(key))
                return String.Empty;

            var result = fields.Single(s => s.Field.RefName == key);

            return result.Value;
        }

	}

    public class Content
    {
        public String SubscriptionId { get; set; }

        public int NotificationId { get; set; }

        public String EventType { get; set; }

        public WorkItemResource Resource { get; set; }

    }

    public class WorkItemResource
    {
        public String UpdatesUrl { get; set; }

        public IList<FieldInfo> Fields { get; set;}

        public int Id { get; set; }

        public int Rev { get; set; }

        public String Url { get; set; }

        public String WebUrl { get; set; }
    }

    public class FieldInfo
    {
        public FieldDetailedInfo Field { get; set; }

        public String Value { get; set; }

    }

    public class FieldDetailedInfo
    {
        public int Id { get; set; }

        public String Name { get; set; }

        public String RefName { get; set; }
    }
}