Usar Azure Functions para crear directivas de rama personalizadas
Azure Repos | Azure DevOps Server 2020 | Azure DevOps Server 2019 | TFS 2018
El flujo de trabajo de solicitud de extracción (PR) proporciona a los desarrolladores la oportunidad de obtener comentarios sobre el código de los elementos del mismo nivel, así como de las herramientas automatizadas. Los servicios y herramientas de terceros pueden participar en el flujo de trabajo de la solicitud de integración mediante la API de estado de la solicitud de solicitud. Este artículo le guía por el proceso de creación de una directiva de rama personalizada mediante Azure Functions para validar las opciones de solicitud en un repositorio Azure DevOps Services Git. Con Azure Functions no tiene que preocuparse por el aprovisionamiento y el mantenimiento de servidores, especialmente cuando crece la carga de trabajo. Azure Functions una plataforma de proceso totalmente administrada con alta confiabilidad y seguridad.
Para más información sobre el estado de la solicitud de solicitud de extracción, consulte Personalización y ampliación de flujos de trabajo de solicitud de extracción con el estado de solicitud de extracción.
Prerrequisitos
Una organización de Azure DevOps con un repositorio de Git. Si no tiene una organización, regístrese para cargar y compartir código en repositorios de Git privados ilimitados gratuitos.
Creación de una función básica de Azure para escuchar Azure Repos eventos
Siga la documentación de creación de la primera función de Azure para crear una función sencilla. Modifique el código del ejemplo para que se parezca a este:
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);
}
}
Configuración de un enlace de servicio para eventos de PR
Los enlaces de servicio son una característica Azure DevOps Services que puede alertar a servicios externos cuando se producen determinados eventos. En este ejemplo, querrá configurar un enlace de servicio para eventos de solicitud de cambios; la función de Azure recibirá una notificación cuando cambie una solicitud de extracción. Para recibir solicitudes cuando cambien las solicitudes de extracción, deberá proporcionar el enlace POST de servicio con la dirección URL de la función de Azure.
Para este ejemplo, deberá configurar dos enlaces de servicio. El primero será para el evento de creación de la solicitud de extracción y el segundo para el evento de actualización de la solicitud de extracción.
Obtenga la dirección URL de la función Azure Portal haga clic en Obtener la dirección URL de la función en la vista de función de Azure y copie la dirección URL.


Vaya al proyecto en Azure DevOps, por ejemplo,
https://dev.azure.com/<your organization>/<your project name>En el menú de navegación, mantenga el puntero sobre el engranaje y seleccione Service Hooks (Enlaces de servicio).

Si este es el primer enlace de servicio, seleccione + Crear suscripción.

Si ya tiene otros enlaces de servicio configurados, seleccione el signo más verde
(+)para crear una nueva suscripción de enlace de servicio.
En el cuadro de diálogo Nueva suscripción de enlaces de servicio, seleccione Web Hooks en la lista de servicios y, a continuación, seleccione Siguiente.

Seleccione Solicitud de extracción creada en la lista de desencadenadores de eventos y, a continuación, seleccione Siguiente.

En la página Acción, escriba la dirección URL que copió en el paso 1 en el cuadro DIRECCIÓN URL. Seleccione Probar para enviar un evento de prueba al servidor.

En la ventana del registro de funciones de Azure, verá una entrada que devolvió un , que indica que la función
POSTrecibió el evento de enlace de200 OKservicio.HTTP Requests ------------- POST / 200 OKEn la ventana Notificación de prueba, seleccione la pestaña Respuesta para ver los detalles de la respuesta del servidor. Debería ver la respuesta del servidor.

Cierre la ventana Notificación de prueba y seleccione Finalizar para crear el enlace de servicio.
Vuelva a seguir los pasos del 2 al 8, pero esta vez configure el evento de actualización de la solicitud de extracción.
Importante
Asegúrese de seguir los pasos anteriores dos veces y crear enlaces de servicio tanto para la solicitud de extracción creada como para los eventos actualizados de la solicitud de extracción.
Cree una solicitud de extracción para comprobar que la función de Azure está recibiendo notificaciones.
Publicación del estado en las solicitud de solicitud
Ahora que el servidor puede recibir eventos de enlace de servicio cuando se crean nuevos PR, actualíctelo para devolver el estado a la SOLICITUD. Puede usar la carga JSON publicada por el enlace de servicio para determinar qué estado se va a establecer en la solicitud de solicitud.
Actualice el código de la función de Azure para que se parezca al ejemplo siguiente.
Asegúrese de actualizar el código con el nombre de la organización, el nombre del proyecto, el nombre del repositorio y el token pat. Para tener permiso para cambiar el estado de la solicitud de cambio, el PAT requiere un ámbito de vso.code_status, que puede conceder seleccionando el ámbito Código (estado) en la página Crear un token de acceso personal.
Importante
Este código de ejemplo almacena el PAT en el código para simplificar el ejemplo. Se recomienda almacenar secretos en KeyVault y recuperarlos desde allí.
En este ejemplo se inspecciona el título de la pr para ver si el usuario ha indicado si la PR es un trabajo en curso agregando WIP al título. Si es así, el código de ejemplo cambia el estado publicado de nuevo en la pr. Reemplace el código de la función de Azure por el código siguiente para implementar la actualización del estado publicado de nuevo en la 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"
}
});
}
Creación de una nueva pr para probar el servidor de estado
Ahora que el servidor está ejecutando y escuchando notificaciones de enlace de servicio, cree una solicitud de extracción para probarla.
Comience en la vista de archivos. Edite readme.md archivo en el repositorio (o cualquier otro archivo si no tiene un readme.md).

Realice una edición y confirme los cambios en el repositorio.

Asegúrese de confirmar los cambios en una nueva rama para poder crear una pr. en el paso siguiente.

Seleccione el vínculo Crear una solicitud de extracción.

Agregue WIP en el título para probar la funcionalidad de la aplicación. Seleccione Crear para crear la pr.

Una vez creada la solicitud de solicitud de acceso, verá la sección de estado, con la entrada Trabajo en curso que se vincula a la dirección URL especificada en la carga.

Actualice el título de la pr. y quite el texto de WIP y observe que el estado cambia de Trabajo en curso a Listo para revisión.
Pasos siguientes
- En este artículo, ha aprendido los conceptos básicos de cómo crear una función de Azure sin servidor que escucha eventos de solicitud de recursos mediante enlaces de servicio y puede publicar mensajes de estado mediante la API de estado. Para más información sobre la API de estado de la solicitud de extracción, consulte la documentación de la API rest.
- Configure una directiva de rama para un servicio externo.