Creare un server di stato della richiesta pull con Node.js

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

Il flusso di lavoro della richiesta pull offre agli sviluppatori l'opportunità di ottenere commenti e suggerimenti sul codice dai peer e dagli strumenti automatizzati. Gli strumenti e i servizi di terze parti possono partecipare al flusso di lavoro delle richieste pull usando l'API Stato richiesta pull. Questo articolo illustra il processo di creazione di un server di stato per convalidare le richieste pull in un repository Git di Azure DevOps Services. Per altre informazioni sullo stato della richiesta pull, vedere Personalizzare ed estendere i flussi di lavoro delle richieste pull con stato della richiesta pull.

Prerequisiti

  • Un'organizzazione in Azure DevOps con un repository Git. Se non si ha un'organizzazione, iscriversi per caricare e condividere codice in repository Git privati gratuiti senza limiti.
  • Installare VS Code o un altro editor di codice preferito. Le istruzioni in questa guida usano VS Code, ma i passaggi in altri editor di codice sono simili.

Installare Node.js

Per installare Node.js, scaricare la versione LTS appropriata per la piattaforma. Il download contiene un programma di installazione, che è possibile eseguire per installare il runtime di Node.js nel computer locale. Quando si installa Node.js, assicurarsi di mantenere la parte di gestione pacchetti npm dell'installazione, selezionata per impostazione predefinita.

Creare un server Web di base con Express

I passaggi descritti in questa sezione usano Express, un framework Web leggero per Node.js che fornisce diversi metodi di utilità HTTP che semplificano la creazione di un server Web. Questo framework fornisce le funzioni di base necessarie per ascoltare gli eventi della richiesta pull.

  1. Dalla riga di comando creare una nuova cartella di progetto per il server Web.

    mkdir pr-server
    cd pr-server
    
  2. Usare il npm init comando per creare un nuovo package.json file per il progetto.

    npm init
    

    Premere INVIO per accettare le impostazioni predefinite per tutte le opzioni, ad eccezione del punto di ingresso. Sostituirla con app.js

    entry point: (index.js) app.js
    
  3. Installare Express nella directory pr-server usando il comando seguente. Viene installato Express e salvato nell'elenco delle dipendenze.

    npm install express
    
  4. Creare una semplice app Express su cui basarsi per il server di stato della richiesta pull. I passaggi seguenti si basano sull'esempio Express Hello world. Aprire la cartella del progetto in VS Code eseguendo il comando seguente dalla pr-server cartella .

    code .
    
  5. Creare un nuovo file (Ctrl + N) e incollarlo nel codice di esempio seguente.

    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. Salvare il file come app.js.

  7. Eseguire il server Web di base usando il comando seguente:

    node app.js
    

    Verificare che il server sia in esecuzione passando a http://localhost:3000/.

Ascolto delle richieste HTTP POST

Il server Web riceverà POST richieste da Azure DevOps Services, quindi è necessario gestire tali richieste nel server.

  1. Alla fine del app.js file aggiungere il codice seguente e salvare il file.

    app.post('/', function (req, res) {
        res.send('Received the POST')
    })
    
  2. Eseguire nuovamente il server Web usando il comando seguente:

    node app.js
    

Configurare un hook del servizio per gli eventi di richiesta pull

Gli hook del servizio sono una funzionalità di Azure DevOps Services che può avvisare i servizi esterni quando si verificano determinati eventi. Per questo esempio, è necessario configurare due hook del servizio per gli eventi di richiesta pull, in modo che il server di stato possa ricevere una notifica. Il primo sarà per l'evento creato dalla richiesta pull e il secondo sarà per l'evento aggiornato della richiesta pull.

Per ricevere le notifiche di hook del servizio, è necessario esporre una porta alla rete Internet pubblica. L'utilità ngrok è molto utile per eseguire questa operazione in un ambiente di sviluppo.

  1. Scaricare e decomprimere la versione ngrok appropriata per la piattaforma.

  2. Usare ngrok per avviare l'ascolto sulla stessa porta del server di esempio- porta 3000. Eseguire il comando seguente in una nuova finestra di comando.

    ngrok http 3000
    

    Ngrok creerà un URL pubblico che inoltra a localhost:3000. Si noti che l'URL sarà necessario nel passaggio successivo. Sarà simile alla seguente:

    http://c3c1bffa.ngrok.io
    
  3. Passare al progetto in Azure DevOps, ad esempio https://dev.azure.com/<your account>/<your project name>

  4. Dal menu di spostamento passare il puntatore del mouse sull'ingranaggio e selezionare Hook di servizio.

    Scegliere Hook di servizio dal menu di amministrazione

  5. Se si tratta del primo hook del servizio, selezionare + Crea sottoscrizione.

    Selezionare Crea una nuova sottoscrizione dalla barra degli strumenti

    Se sono già stati configurati altri hook del servizio, selezionare il segno più (+) verde per creare una nuova sottoscrizione hook del servizio.

    Selezionare il segno più verde per creare una nuova sottoscrizione hook del servizio.

  6. Nella finestra di dialogo Nuova sottoscrizione hook del servizio selezionare Web Hook nell'elenco dei servizi e quindi selezionare Avanti.

    Selezionare web hook dall'elenco dei servizi

  7. Selezionare Richiesta pull creata dall'elenco dei trigger di eventi e quindi selezionare Avanti.

    Selezionare la richiesta pull creata dall'elenco dei trigger di evento

  8. Nella pagina Azione immettere l'URL da ngrok nella casella URL . Selezionare Test per inviare un evento di test al server.

    Immettere l'URL e selezionare Test per testare l'hook del servizio

    Nella finestra della console di ngrok verrà visualizzato un oggetto in ingresso POST che ha restituito un 200 OKoggetto , che indica che il server ha ricevuto l'evento di hook del servizio.

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

    Nella finestra Notifica test selezionare la scheda Risposta per visualizzare i dettagli della risposta dal server. Dovrebbe essere visualizzata una lunghezza del contenuto pari a 17 che corrisponde alla lunghezza della stringa dal gestore POST( ad esempio "Received the POST").

    Selezionare la scheda risposta per visualizzare i risultati del test

  9. Chiudere la finestra Notifica test e selezionare Fine per creare l'hook del servizio.

Eseguire nuovamente i passaggi da 3 a 9, ma questa volta configurare l'evento aggiornato della richiesta pull.

Importante

Assicurarsi di eseguire due volte i passaggi precedenti e creare hook del servizio per gli eventi aggiornati della richiesta pull creata e della richiesta pull.

Registrare lo stato nelle richieste pull

Ora che il server può ricevere eventi di hook del servizio quando vengono create nuove richieste pull, aggiornarlo per registrare lo stato della richiesta pull.

  1. Le richieste di hook del servizio includono un payload JSON che descrive l'evento. Per analizzare il codice JSON restituito dall'hook del servizio, installare il pacchetto body-parser .

    npm install body-parser
    
  2. Aggiornare app.js per usare body-parser per l'analisi di application/json.

    var bodyParser = require('body-parser')
    
    app.use(bodyParser.json())
    
  3. Per semplificare l'esecuzione di chiamate API REST ad Azure Repos, installare il pacchetto azure-devops-node-api .

    npm install azure-devops-node-api 
    
  4. Eseguire l'aggiornamento app.js per usare il pacchetto azure-devops-node-api, configurare i dettagli per una connessione all'account e ottenere un'istanza dell'API 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. Creare una variabile di ambiente per l'URL della raccolta, sostituendo <your account> con il nome dell'organizzazione Azure DevOps.

    setx COLLECTIONURL "https://dev.azure.com/<your account>"
    
  6. Creare un token di autenticazione personale (PAT) per l'app da usare, seguendo queste istruzioni: Autenticazione con token di accesso personali. È consigliabile creare un nuovo pat per ogni servizio usato per accedere all'account, assegnandogli un nome appropriato.

  7. Creare una variabile di ambiente per il pat.

    setx TOKEN "yourtokengoeshere"
    
  8. Aggiornare la post() funzione per leggere i dettagli della richiesta pull dal payload dell'hook del servizio. Questi valori saranno necessari per eseguire il postback dello stato.

    var repoId = req.body.resource.repository.id
    var pullRequestId = req.body.resource.pullRequestId
    var title = req.body.resource.title
    
  9. Compilare l'oggetto stato da pubblicare nella richiesta pull.

    State è un'enumerazione di tipo GitStatusState. Usare succeeded per indicare che la richiesta pull ha superato il controllo dello stato ed è pronta per l'unione.

    description è un valore stringa che verrà visualizzato all'utente nella sezione Stato e nel feed attività nella visualizzazione dei dettagli della richiesta pull.

    targetUrl è un URL che verrà usato per creare un collegamento per il testo della descrizione nella sezione Stato e nel feed attività. Questa è la posizione in cui gli utenti possono accedere per ottenere altre informazioni sullo stato, ad esempio un report di compilazione o un'esecuzione di test. Se non viene specificato alcun URL, la descrizione verrà visualizzata come testo senza collegamento.

    Il contesto name e genre vengono usati per classificare lo stato e distinguerlo dallo stato di registrazione di altri servizi.

        var prStatus = {
            "state": "succeeded",
            "description": "Ready for review",
            "targetUrl": "https://visualstudio.microsoft.com",
            "context": {
                "name": "wip-checker",
                "genre": "continuous-integration"
            }
        }
    
  10. Invece di registrare in modo cieco lo succeeded stato, controllare il titolo della richiesta pull per verificare se l'utente ha indicato se la richiesta pull è un lavoro in corso aggiungendo WIP al titolo. In tal caso, modificare lo stato inviato nuovamente alla richiesta pull.

        if (title.includes("WIP")) {
            prStatus.state = "pending"
            prStatus.description = "Work in progress"
        }
    
  11. Infine, pubblicare lo stato usando il createPullRequestStatus() metodo . Richiede l'oggetto di stato, l'ID repository e l'ID richiesta pull. Restituire la risposta alla console del nodo in modo da visualizzare il risultato del post.

    vstsGit.createPullRequestStatus(prStatus, repoId, pullRequestId).then( result => {
        console.log(result)
    })
    
  12. Il metodo risultante dovrebbe essere simile al seguente:

    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. Salvare app.js e riavviare l'app node.

    node app.js
    

Creare una nuova richiesta pull per testare il server di stato

Ora che il server è in esecuzione e in ascolto delle notifiche di hook del servizio, creare una richiesta pull per testarla.

  1. Iniziare nella visualizzazione file. Modificare il file readme.md nel repository (o qualsiasi altro file se non si dispone di un readme.md).

    Selezionare Modifica dal menu di scelta rapida

  2. Apportare una modifica ed eseguire il commit delle modifiche nel repository.

    Modificare il file e selezionare Commit dalla barra degli strumenti

  3. Assicurarsi di eseguire il commit delle modifiche in un nuovo ramo in modo da poter creare una richiesta pull nel passaggio successivo.

    Immettere un nuovo nome di ramo e selezionare Commit

  4. Selezionare il collegamento Crea una richiesta pull.

    Selezionare Crea una richiesta pull dalla barra dei suggerimenti

  5. Aggiungere WIP nel titolo per testare la funzionalità dell'app. Selezionare Crea per creare la richiesta pull.

    Aggiungere WIP al titolo predefinito della richiesta pull

  6. Dopo aver creato la richiesta pull, verrà visualizzata la sezione relativa allo stato, con la voce Lavoro in corso che collega all'URL specificato nel payload.

    Sezione Stato con la voce Lavoro in corso.

  7. Aggiornare il titolo della richiesta pull e rimuovere il testo wip e notare che lo stato cambia da Lavoro in corso a Pronto per la revisione.

Passaggi successivi

  • In questo articolo sono state illustrate le nozioni di base su come creare un servizio in ascolto degli eventi di richiesta pull tramite hook del servizio e pubblicare messaggi di stato usando l'API di stato. Per altre informazioni sull'API di stato della richiesta pull, vedere la documentazione dell'API REST.
  • Configurare un criterio di ramo per un servizio esterno.