Criar um servidor de status de solicitação de pull com o Node.js

Azure DevOps Services | Azure DevOps Server 2022 - Azure DevOps Server 2019

O fluxo de trabalho de PR (solicitação de pull) oferece aos desenvolvedores a oportunidade de obter feedback de colegas sobre seu código, bem como de ferramentas automatizadas. Ferramentas e serviços de terceiros podem participar do fluxo de trabalho de PR usando a API de Status de PR. Este artigo orienta você ao longo do processo de criação de um servidor de status para validar PRs em um Repositório do Git do Azure DevOps Services. Para obter mais informações sobre status de PR, consulte Personalizar e estender fluxos de trabalho de solicitação de pull com status de solicitação de pull.

Pré-requisitos

  • Uma organização no Azure DevOps com um Repositório do Git. Se você não tiver uma organização, inscreva-se para carregar e compartilhar código em repositórios Git privados, ilimitados e gratuitos.
  • Instale o VS Code ou outro editor de código de sua escolha. As instruções neste guia usam o VS Code, mas as etapas em outros editores de código são semelhantes.

Instalar o Node.js

Para instalar Node.js, baixe a versão LTS apropriada para sua plataforma. O download contém um instalador, que você pode executar para instalar o runtime do Node.js em seu computador local. Ao instalar o Node.js, assegure-se de conservar a parte do gerenciador de pacotes npm da instalação, que é selecionada por padrão.

Criar um servidor Web básico usando o Express

As etapas nesta seção usam o Express, que é uma estrutura da Web leve para Node.js que fornece uma série de métodos utilitários HTTP que simplificam a criação de um servidor Web. Essa estrutura fornece as funções básicas necessárias para monitorar eventos de PR.

  1. Na linha de comando, crie uma nova pasta de projeto para seu servidor Web.

    mkdir pr-server
    cd pr-server
    
  2. Use o comando npm init para criar um novo arquivo package.json para o projeto.

    npm init
    

    Pressione Enter para aceitar os padrões de todas as opções, exceto o ponto de entrada. Mude-a para app.js

    entry point: (index.js) app.js
    
  3. Instale o Express no diretório pr-server usando o comando a seguir. Isso instala o Express e o salva na lista de dependências.

    npm install express
    
  4. Crie um aplicativo Express simples para servir de base para o servidor de status de PR. As etapas a seguir se baseiam no exemplo "Alô mundo" do Express. Abra a pasta do projeto no VS Code executando o comando a seguir na pasta pr-server.

    code .
    
  5. Crie um novo arquivo (Ctrl + N) e cole o código de exemplo a seguir.

    const express = require('express')
    const app = express()
    
    app.get('/', function (req, res) {
    res.send('Hello World!')
    })
    
    app.listen(3000, function () {
    console.log('Example app listening on port 3000!')
    })
    
  6. Salve o arquivo como app.js.

  7. Execute o servidor Web básico usando o seguinte comando:

    node app.js
    

    Verifique se o servidor está em execução navegando até http://localhost:3000/.

Monitorar solicitações HTTP POST

O servidor Web receberá solicitações de POST do Azure DevOps Services, portanto você precisa lidar com essas solicitações no servidor.

  1. No final do arquivo app.js, adicione o código a seguir e salve o arquivo.

    app.post('/', function (req, res) {
        res.send('Received the POST')
    })
    
  2. Execute novamente seu servidor Web usando o seguinte comando:

    node app.js
    

Configurar um gancho de serviço para eventos de PR

Os ganchos de serviço são um recurso do Azure DevOps Services capaz de alertar serviços externos na ocorrência de determinados eventos. Para este exemplo, você desejará configurar dois ganchos de serviço para eventos de PR, para que o servidor de status possa ser notificado. O primeiro será para o evento de solicitação de pull criado e o segundo será para o evento de solicitação de pull atualizado .

Para receber as notificações do gancho de serviço, você precisará expor uma porta à Internet pública. O utilitário ngrok é muito útil para fazer isso em um ambiente de desenvolvimento.

  1. Baixe e descompacte a versão apropriada do ngrok para sua plataforma.

  2. Use o ngrok para começar a rastrear na mesma porta que seu servidor de exemplo – porta 3000. Execute o seguinte comando em uma nova janela de comando.

    ngrok http 3000
    

    O Ngrok criará uma URL pública que encaminha para localhost:3000. Fique atento a essa URL, pois você precisará dela na próxima etapa. Ficará semelhante ao seguinte:

    http://c3c1bffa.ngrok.io
    
  3. Navegue até o projeto do Azure DevOps, por exemplo, https://dev.azure.com/<your account>/<your project name>

  4. No menu de navegação, passe o mouse sobre a engrenagem e selecione Ganchos de Serviço.

    Escolher ganchos de serviço no menu de administração

  5. Se esse for seu primeiro gancho de serviço, selecione + Criar assinatura.

    Selecione Criar uma nova assinatura na barra de ferramentas

    Se você já tiver outros ganchos de serviço configurados, selecione o sinal verde de mais (+) para criar uma nova assinatura de gancho de serviço.

    Selecione o sinal verde de mais para criar uma nova assinatura de gancho de serviço.

  6. Na caixa de diálogo Nova Assinatura de Ganchos de Serviço, selecione Web Hooks na lista de serviços e, em seguida, selecione Avançar.

    Selecionar ganchos da Web na lista de serviços

  7. Selecione Solicitação de pull criada na lista de gatilhos de evento e selecione Avançar.

    Selecionar solicitação de pull criada na lista de gatilhos de evento

  8. Na página Ação, insira a URL do ngrok na caixa URL . Selecione Testar para enviar um evento de teste para o servidor.

    Insira a URL e selecione Testar para testar o gancho de serviço

    Na janela do console do ngrok, você verá uma entrada POST que retornou um 200 OK, indicando que o servidor recebeu o evento de gancho de serviço.

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

    Na janela Notificação de Teste, selecione a guia Resposta para ver os detalhes da resposta do servidor. Você provavelmente um comprimento de conteúdo de 17 que corresponde ao comprimento da cadeia de caracteres do manipulador POST (ou seja, "Recebido o POST").

    Selecione a guia de resposta para ver os resultados do teste

  9. Feche a janela Notificação de Teste e selecione Concluir para criar o gancho de serviço.

Percorra as etapas 3 a 9 novamente, mas desta vez configure o evento de Solicitação de pull atualizado.

Importante

Siga as etapas anteriores duas vezes e crie ganchos de serviço tanto para os eventos de solicitação de pull criados e os de solicitação de pull atualizados .

Postar status em PRs

Agora que o servidor pode receber eventos de gancho de serviço quando novas PRs forem criadas, atualize-o para fazer o postback do status para a PR.

  1. As solicitações de gancho de serviço incluem uma carga JSON que descreve o evento. Para ajudar a analisar o JSON retornado pelo gancho de serviço, instale o pacote body-parser .

    npm install body-parser
    
  2. Atualize app.js para usar o body-parser para analisar application/json.

    var bodyParser = require('body-parser')
    
    app.use(bodyParser.json())
    
  3. Para simplificar a realização de chamadas da API REST para o Azure Repos, instale o pacote azure-devops-node-api.

    npm install azure-devops-node-api 
    
  4. Atualize app.js para usar o pacote azure-devops-node-api, configure os detalhes de uma conexão com sua conta e obtenha uma instância da API do Git.

    const vsts = require("azure-devops-node-api")
    
    const collectionURL = process.env.COLLECTIONURL    
    const token = process.env.TOKEN
    
    var authHandler = vsts.getPersonalAccessTokenHandler(token)
    var connection = new vsts.WebApi(collectionURL, authHandler)
    
    var vstsGit = connection.getGitApi().then( 
        vstsGit => {                                    
            vstsGit.createPullRequestStatus(prStatus, repoId, pullRequestId).then( result => {
                console.log(result);
            },
            error => {
                console.log(error);
            })
        }, 
        error => { 
            console.log(error);
        } 
    );
    
  5. Crie uma variável de ambiente para a URL da sua coleção, substituindo <your account> pelo nome da sua organização do Azure DevOps.

    setx COLLECTIONURL "https://dev.azure.com/<your account>"
    
  6. Crie um PAT (token de autenticação pessoal) para seu aplicativo usar, seguindo estas instruções: Autenticação com tokens de acesso pessoal. Você deve criar novo um PAT para cada serviço que usar para acessar sua conta, nomeando-a adequadamente.

  7. Criar uma variável de ambiente para seu PAT.

    setx TOKEN "yourtokengoeshere"
    
  8. Atualize a função post() para ler os detalhes de PR do conteúdo do gancho de serviço. Você precisará desses valores para fazer o postback do status.

    var repoId = req.body.resource.repository.id
    var pullRequestId = req.body.resource.pullRequestId
    var title = req.body.resource.title
    
  9. Compile o objeto status para postar na PR.

    State é uma enumeração do tipo GitStatusState. Use succeeded para indicar que a PR passou na verificação de status e está pronta para mesclagem.

    O description é um valor de cadeia de caracteres que será exibido para o usuário na seção Status e no feed de atividades na exibição de detalhes de PR.

    O targetUrl é uma URL que será usada para criar um link para o texto de descrição na seção Status e no feed de atividades. Esse é o local onde os usuários podem ir para obter mais informações sobre o status, por exemplo, de um relatório de build ou uma execução de teste. Se nenhuma URL for especificada, a descrição aparecerá como texto sem link.

    Os contextos name e genre são usados para categorizar o status e diferenciá-lo de outros serviços passando status.

        var prStatus = {
            "state": "succeeded",
            "description": "Ready for review",
            "targetUrl": "https://visualstudio.microsoft.com",
            "context": {
                "name": "wip-checker",
                "genre": "continuous-integration"
            }
        }
    
  10. Em vez de apenas postar cegamente o status succeeded, inspecione o título de PR para ver se o usuário indicou se a PR é um trabalho em andamento adicionando WIP ao título. Nesse caso, altere o status postado de volta para a PR.

        if (title.includes("WIP")) {
            prStatus.state = "pending"
            prStatus.description = "Work in progress"
        }
    
  11. Por fim, poste o status usando o método createPullRequestStatus(). Ele requer o objeto status, a ID do repositório e a ID da solicitação de pull. Gere a resposta para o console do nó para que você possa ver o resultado da postagem.

    vstsGit.createPullRequestStatus(prStatus, repoId, pullRequestId).then( result => {
        console.log(result)
    })
    
  12. O resultado deve ser semelhante a:

    app.post("/", function (req, res) {
    
        // Get the details about the PR from the service hook payload
        var repoId = req.body.resource.repository.id
        var pullRequestId = req.body.resource.pullRequestId
        var title = req.body.resource.title
    
        // Build the status object that we want to post.
        // Assume that the PR is ready for review...
        var prStatus = {
            "state": "succeeded",
            "description": "Ready for review",
            "targetUrl": "https://visualstudio.microsoft.com",
            "context": {
                "name": "wip-checker",
                "genre": "continuous-integration"
            }
        }
    
        // Check the title to see if there is "WIP" in the title.
        if (title.includes("WIP")) {
    
            // If so, change the status to pending and change the description.
            prStatus.state = "pending"
            prStatus.description = "Work in progress"
        }
    
        // Post the status to the PR
        vstsGit.createPullRequestStatus(prStatus, repoId, pullRequestId).then( result => {
            console.log(result)
        })
    
        res.send("Received the POST")
    })
    
  13. Salve app.js e reinicie seu aplicativo de nó.

    node app.js
    

Criar uma nova PR para testar o servidor de status

Agora que o servidor está em execução e monitorando notificações de gancho de serviço, crie uma solicitação de pull para testá-lo.

  1. Comece na exibição de arquivos. Edite o arquivo readme.md no repositório (ou em qualquer outro arquivo, se você não tiver um readme.md).

    Selecione Editar no menu de contexto

  2. Faça uma edição e confirme as alterações no repositório.

    Edite o arquivo e selecione Confirmar na barra de ferramentas

  3. Assegure-se de confirmar as alterações em um novo branch para que você possa criar uma PR na próxima etapa.

    Insira um novo nome de branch e selecione Confirmar

  4. Selecione o link Criar uma solicitação de pull .

    Selecione Criar uma solicitação de pull na barra de sugestões

  5. Adicione WIP no título para testar a funcionalidade do aplicativo. Selecione Criar para criar a PR.

    Adicionar WIP ao título de PR padrão

  6. Depois que a PR tiver sido criada, você verá a seção status, com a entrada Trabalho em andamento que vincula à URL especificada na carga.

    Seção de status com a entrada Trabalho em andamento.

  7. Atualize o título da PR e remova o texto WIP e observe que o status muda de Trabalho em andamento para Pronto para revisão.

Próximas etapas