Usar Azure Functions para crear directivas de rama personalizadas
Azure DevOps Services | Azure DevOps Server 2022 | Azure DevOps Server 2019
El flujo de trabajo de PR proporciona a los desarrolladores una oportunidad para obtener comentarios sobre su código de homólogos, así como de herramientas automatizadas. Las herramientas y servicios de terceros pueden participar en el flujo de trabajo de PR mediante la API de estado de la PR. Este artículo le guía por el proceso de creación de una directiva de rama personalizada mediante Azure Functions para validar las solicitudes de incorporación de cambios en un repositorio de Git de Azure DevOps Services. Con Azure Functions no tiene que preocuparse por el aprovisionamiento y el mantenimiento de servidores, especialmente cuando crece la carga de trabajo. Azure Functions proporcionar una plataforma de proceso totalmente administrada con alta confiabilidad y seguridad.
Para obtener más información sobre el estado de la PR, vea Personalización y extensión de flujos de trabajo de PR con el estado de la PR.
Requisitos previos
Una organización en Azure DevOps con un repositorio de Git. Si no tiene una organización, regístrese para cargar y compartir código en repositorios ilimitados de Git privados y gratuitos.
Creación de una función básica de Azure para escuchar eventos Azure Repos
Siga la documentación Creación de la primera función Azure para crear una función sencilla. Modifique el código del ejemplo para que tenga este aspecto:
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 de Azure DevOps Services que puede avisar a servicios externos cuando se producen determinados eventos. En este ejemplo, querrá configurar un enlace de servicio para eventos de solicitud de incorporación de cambios, se notificará a la función de Azure cuando cambie una solicitud de incorporación de cambios. Para recibir POST
solicitudes cuando cambien las solicitudes de incorporación de cambios, deberá proporcionar el enlace de servicio con la dirección URL de la función de Azure.
Para este ejemplo, deberá configurar 2 enlaces de servicio. El primero será para el evento de Solicitud de incorporación de cambios creada y el segundo será para el evento de Solicitud de incorporación de cambios actualizada.
Obtenga la dirección URL de la función de la Azure Portal haciendo clic en la dirección URL de obtención de la función en la vista de funciones 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 Enlaces de servicio.
Si este es el primer enlace de servicio, seleccione + Crear suscripción.
Si ya tiene configurados otros enlaces de servicio, seleccione el signo verde más
(+)
para crear una suscripción de enlace de servicio.En el cuadro de diálogo Nueva suscripción de enlaces de servicio, seleccione Enlaces web en la lista de servicios y, después, seleccione Siguiente.
Seleccione Solicitud de incorporación de cambios creada en la lista de desencadenadores de eventos y, después, 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 de registro de funciones de Azure, verá una entrada
POST
que devolvió un200 OK
, que indica que la función recibió el evento de enlace de servicio.HTTP Requests ------------- POST / 200 OK
En 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 Solicitud de incorporación de cambios actualizada.
Importante
Asegúrese de seguir los pasos anteriores dos veces y crear enlaces de servicio para los eventos de Solicitud de incorporación de cambios creada y Solicitud de incorporación de cambios actualizada.
Cree una solicitud de incorporación de cambios para comprobar que la función de Azure recibe notificaciones.
Publicación del estado en PR
Ahora que el servidor puede recibir eventos de enlace de servicio cuando se crean PR, actualícelo para publicar el estado de devolución a la PR. Puede usar la carga JSON publicada por el enlace de servicio para determinar qué estado se debe establecer en la solicitud de incorporación de cambios.
Actualice el código de la función de Azure para que tenga un aspecto similar al del 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 del RP, el PAT requiere el ámbito 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 solicitud de incorporación de cambios para ver si el usuario ha indicado si la solicitud de incorporación de cambios es un trabajo en curso agregando WIP al título. Si es así, el código de ejemplo cambia el estado que se devuelve a la solicitud de incorporación de cambios. Reemplace el código de la función de Azure por el código siguiente para implementar la actualización del estado que se devuelve a la solicitud de incorporación de cambios.
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 PR para probar el servidor de estado
Ahora que el servidor está en ejecución y escucha notificaciones de enlace de servicio, cree una PR para probarlo.
Comience en la vista de archivos. Edite el archivo readme.md en el repositorio (o cualquier otro archivo si no tiene uno readme.md).
Realice una edición y confirme los cambios en el repositorio.
Asegúrese de confirmar los cambios en una nueva rama para que pueda crear una PR en el paso siguiente.
Seleccione el vínculo Crear una solicitud de incorporación de cambios.
Agregue WIP en el título para probar la función de la aplicación. Seleccione Crear para crear la PR.
Una vez creada la PR, verá la sección Estado, con la entrada Trabajo en curso que vincula a la dirección URL especificada en la carga.
Actualice el título de la PR, quite el texto WIP y observe que el estado cambia de Trabajo en curso a Listo para revisión.
Pasos siguientes
- En este artículo, ha descubierto los conceptos básicos de cómo crear una función de Azure sin servidor que escucha eventos de solicitud de incorporación de cambios a través de enlaces de servicio y puede publicar mensajes de estado mediante la API de estado. Para obtener más información sobre la API de estado de la PR, vea la documentación de la API REST.
- Configurar una directiva de rama para un servicio externo.