Sdílet prostřednictvím


Vytvoření vlastních zásad větvení pomocí Azure Functions

Azure DevOps Services | Azure DevOps Server 2022 – Azure DevOps Server 2019

Pracovní postup pro pull requesty (PR) umožňuje vývojářům získávat zpětnou vazbu ke svému kódu od kolegů a automatizovaných nástrojů. Nástroje a služby, které nejsou od Microsoftu, se mohou také zapojit do PR workflow pomocí PR Status API. Tento článek vás provede vytvořením vlastních zásad pro větve pomocí Azure Functions pro ověřování pull requestů v úložišti Git Azure DevOps. Azure Functions eliminuje potřebu zřizování a údržby serverů, i když roste zatížení. Poskytují plně spravovanou výpočetní platformu s vysokou spolehlivostí a zabezpečením.

Další informace o stavu žádosti o přijetí změn (PR) najdete v části Přizpůsobení a rozšíření pracovních postupů pro žádosti o přijetí změn s ohledem na jejich stav.

Požadavky

Kategorie Požadavky
Organizace Organizace v Azure DevOps s úložištěm Git.
Funkce Azure Funkce Azure, která implementuje bezserverové řešení řízené událostmi, které se integruje s Azure DevOps za účelem vytvoření vlastní zásady pro větve a automatizace validace pull requestů.
Service Hooks Nakonfigurujte webhooky služby pro události pull requestů tak, aby informovaly vaši funkci Azure, když dojde ke změně v pull requestu.
Personal Access Token (PAT) Vytvořte osobní přístupový token s rozsahem Code (stav), abyste měli oprávnění ke změně stavu pull requestu. Další informace najdete v tématu Použití PATů k autentizaci.

Vytvoření základní funkce Azure Functions pro naslouchání událostem Azure Repos

Vytvořte svou první funkci Azure. Potom upravte kód v ukázce tak, aby vypadal jako následující kód:

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);
    }
}

Konfigurace webhooku pro události pull requestů

Háky služeb jsou funkce Azure DevOps, která může upozornit externí služby, když dojde k určitým událostem. Pro tuto ukázku nastavte služební hák pro události pull requestu, vaše funkce Azure je upozorněna, když se pull request změní. Pokud chcete přijímat POST žádosti při změně žádostí o přijetí změn, poskytněte háku služby s adresou URL funkce Azure.

Pro tuto ukázku nakonfigurujte dva háky služby. První je událost Vytvoření žádosti o přijetí změn a druhá je událost Aktualizace žádosti o přijetí změn.

  1. Získejte adresu URL funkce z Azure portálu kliknutím na Získat adresu URL funkce ve vašem zobrazení funkce Azure a zkopírujte adresu URL.

    Získejte adresu URL funkce

    Kopírovat adresu URL funkce

  2. Přejděte ke svému projektu v Azure DevOps, například https://dev.azure.com/<your organization>/<your project name>

  3. V navigační nabídce najeďte myší na ozubené kolo a vyberte Service Hooks.

    V nabídce správce zvolte háky služby.

  4. Pokud se jedná o první háček služby, vyberte + Vytvořit předplatné.

    Na panelu nástrojů vyberte Vytvořit nové předplatné.

    Pokud už máte nakonfigurované další háky služeb, vyberte zelené plus (+) a vytvořte nové předplatné háku služby.

    Výběrem zeleného plus vytvořte nové předplatné háku služby.

  5. V dialogovém okně nového odběru služeb „Service Hooks“ vyberte Web Hooks ze seznamu služeb a pak vyberte Další.

    Výběr webových háků ze seznamu služeb

  6. V seznamu spouštěčů událostí vyberte Žádost o přijetí změn, poté vyberte Další.

    Vyberte pull request vytvořený ze seznamu spouštěčů událostí

  7. Na stránce Akce zadejte adresu URL, kterou jste zkopírovali v kroku 1 do pole Adresa URL . Vyberte Test pro odeslání testovací události na server.

    Zadejte adresu URL a výběrem možnosti Test otestujte připojení služby.

    V okně protokolu funkce Azure se zobrazí příchozí POST, která vrátila 200 OK, což označuje, že vaše funkce přijala událost háčku služby.

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

    V okně Testovací oznámení vyberte kartu Odpověď a zobrazte podrobnosti odpovědi ze serveru. Měla by se zobrazit odpověď ze serveru.

    Výběrem karty odpovědi zobrazíte výsledky testu.

  8. Zavřete okno Testovací oznámení a výběrem Dokončit vytvořte háček služby.

Znovu si projděte kroky 2 až 8, ale tentokrát nakonfigurujte událost Pull request updated.

Důležité

Nezapomeňte dvakrát projít předchozí kroky a vytvořit připojení služby jak pro událost vytvoření žádosti o přijetí změn, tak pro událost aktualizaci žádosti o přijetí změn.

Vytvořte pull request, abyste ověřili, že vaše funkce Azure přijímá oznámení.

Zveřejnění stavu do pull requestů

Teď, když váš server může přijímat události háku služby při vytváření nových žádostí o přijetí změn, aktualizujte ho tak, aby odeslal stav žádosti o přijetí změn zpět. Datovou část JSON, kterou publikoval prvok aplikace služby, můžete použít k určení stavu, který se má nastavit pro vaši žádost o přijetí změn.

Aktualizujte kód funkce Azure, podobně jako v následujícím příkladu.

Nezapomeňte aktualizovat kód názvem organizace, názvem projektu, názvem úložiště a tokenem PAT. Pokud chcete mít oprávnění ke změně stavu PR, vyžaduje PAT rozsah vso.code_status, který můžete udělit výběrem rozsahu Code (status) na stránce Vytvořit osobní přístupový token.

Důležité

Tento vzorový kód ukládá PAT do kódu, což zjednodušuje příklad. Doporučujeme ukládat tajné kódy do služby KeyVault a načítat je odtud.

Tato ukázka kontroluje název PR, aby zjistila, jestli uživatel označil PR jako rozpracovaný přidáním WIP do názvu. Pokud ano, vzorový kód změní stav vrácený zpět do požadavku na úpravy. Nahraďte kód ve funkci Azure následujícím kódem, který aktualizuje stav publikovaný zpět do žádosti o přijetí změn.

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"
            }
        });
}

Vytvořte novou žádost o přijetí změn (PR) a otestujte stavový server

Teď, když je váš server spuštěný a naslouchá oznámení o service hook, vytvořte žádost o přijetí změn, abyste ji otestovali.

  1. Začněte v zobrazení souborů. Upravte readme.md soubor v úložišti (nebo jakýkoli jiný soubor, pokud nemáte readme.md).

    V místní nabídce vyberte Upravit.

  2. Proveďte úpravy a potvrďte změny v úložišti.

    Upravte soubor a na panelu nástrojů vyberte Potvrdit.

  3. Nezapomeňte potvrdit změny do nové větve, abyste mohli v dalším kroku vytvořit pull request.

    Zadejte název nové větve a vyberte Potvrdit.

  4. Vyberte odkaz Vytvořit pull request.

    V návrhové liště vyberte možnost Vytvořit pull request.

  5. Přidejte do názvu WIP a otestujte funkčnost aplikace. Vyberte Vytvořit a vytvořte PR.

    Přidání WIP do výchozího názvu žádosti o přijetí změn

  6. Po vytvoření PR se část stavu zobrazí s položkou Rozpracováno, která odkazuje na adresu URL zadanou v datové části.

    Sekce stavu s položkou Práce probíhá

  7. Aktualizujte název PR a odeberte text WIP a všimněte si, že se stav mění z Práce na dokončení na Připraveno k recenzi.

Další kroky