使用 Node.js 建立提取要求狀態伺服器

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

提取要求 (PR) 工作流程可讓開發人員有機會從對等以及自動化工具取得其程式代碼的意見反應。 第三方工具和服務可以使用PR狀態 API 參與PR工作流程。 本文會引導您完成建立狀態伺服器以驗證 Azure DevOps Services Git 存放庫中 PR 的程式。 如需PR狀態的詳細資訊,請參閱 使用提取要求狀態自定義和擴充提取要求工作流程。

必要條件

  • Azure DevOps 中具有 Git 存放庫的組織。 如果您沒有組織, 請註冊 以免費無限制的私人 Git 存放庫上傳和共用程序代碼。
  • 安裝 VS Code 或其他您選擇的程式碼編輯器。 本指南中的指示使用 VS Code,但其他程式碼編輯器中的步驟類似。

安裝 Node.js

若要安裝Node.js, 請下載 適合您平臺的 LTS 版本。 下載包含安裝程式,您可以在本機計算機上安裝Node.js運行時間。 安裝Node.js時,請務必保留 預設選取的安裝 npm 套件管理員 部分。

使用 Express 建立基本網頁伺服器

本節中的步驟使用 Express,這是適用於 Node.js 的輕量型 Web 架構,可提供許多可簡化建立網頁伺服器的 HTTP 公用程式方法。 此架構提供接聽 PR 事件所需的基本函式。

  1. 從命令行建立 Web 伺服器的新項目資料夾。

    mkdir pr-server
    cd pr-server
    
  2. npm init使用 命令建立專案的新package.json檔案。

    npm init
    

    按 Enter 以接受所有選項的預設值,但進入點除外。 將它變更為 app.js

    entry point: (index.js) app.js
    
  3. 使用下列命令在 pr-server 目錄中安裝 Express。 這會安裝 Express,並將它儲存至相依性清單。

    npm install express
    
  4. 建立簡單的 Express 應用程式,以建置 PR 狀態伺服器。 下列步驟是以 Express Hello world 範例為基礎。 從 pr-server 資料夾執行下列命令,以在 VS Code 中開啟項目資料夾。

    code .
    
  5. 建立新的檔案 (Ctrl + N) ,並貼上下列範例程序代碼。

    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. 將檔案儲存為 app.js

  7. 使用下列命令執行基本 Web 伺服器:

    node app.js
    

    流覽至 以確認 http://localhost:3000/伺服器正在執行。

接聽 HTTP POST 要求

Web 伺服器會 POST 接收來自 Azure DevOps Services 的要求,因此您必須在伺服器中處理這些要求。

  1. 在檔案結尾 app.js ,新增下列程式代碼,然後儲存盤案。

    app.post('/', function (req, res) {
        res.send('Received the POST')
    })
    
  2. 使用下列命令重新執行網頁伺服器:

    node app.js
    

設定PR事件的服務攔截

服務勾點是 Azure DevOps Services 功能,可在發生特定事件時警示外部服務。 在此範例中,您會想要為PR事件設定兩個服務攔截,以便通知狀態伺服器。 第一個會針對 提取要求建立 的事件,而第二個則用於 提取要求更新 事件。

若要接收服務攔截通知,您必須向公用因特網公開埠。 ngrok 公用程式對於在開發環境中執行這項操作非常有用。

  1. 下載 並解壓縮適合您平台的適當 ngrok 版本。

  2. 使用 ngrok 開始接聽與範例伺服器相同的埠 - 埠 3000。 在新命令視窗中執行下列命令。

    ngrok http 3000
    

    Ngrok 會建立轉送至 localhost:3000的公用URL。 請注意,在下一個步驟中,您需要該 URL。 回應會看起來像這樣:

    http://c3c1bffa.ngrok.io
    
  3. 流覽至 Azure DevOps 中的專案,例如 https://dev.azure.com/<your account>/<your project name>

  4. 從導覽功能表中,將滑鼠停留在齒輪,然後選取 [服務勾點]。

    從管理功能表選擇 [服務勾點]

  5. 如果這是您的第一個服務勾點,請選取 [+ 建立訂用帳戶]。

    從工具列選取 [建立新的訂用帳戶]

    如果您已設定其他服務勾點,請選取綠色加號 (+) 以建立新的服務勾點訂用帳戶。

    選取綠色加號以建立新的服務勾點訂用帳戶。

  6. 在 [新增服務攔截訂閱] 對話框中,從服務列表中選取 [Web Hooks ],然後選取 [ 下一步]。

    從服務清單中選取 Web 攔截

  7. 選取從事件觸發程式清單中建立的提取要求,然後選取 [下一步]。

    選取從事件觸發程式清單中建立的提取要求

  8. 在 [動作] 頁面中,於 [URL] 方塊中輸入 ngrok 的 URL 。 選取 [測試 ] 以將測試事件傳送至您的伺服器。

    輸入 URL,然後選取 [測試] 以測試服務勾點

    在 ngrok 控制台視窗中,您會看到傳200 OK回 的連入POST,指出您的伺服器收到服務攔截事件。

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

    在 [測試通知] 視窗中,選取 [回應] 索引標籤以查看伺服器回應的詳細數據。 您應該會看到內容長度為 17,符合 POST 處理程式中字串的長度(亦即「已收到 POST」)。

    選取 [回應] 索引標籤以查看測試結果

  9. 關閉 [測試通知] 視窗,然後選取 [ 完成 ] 以建立服務勾點。

再次執行步驟 3-9,但這次設定 提取要求更新 事件。

重要

請務必執行上述步驟兩次,並針對已建立提取要求和提取要求更新事件建立服務攔截。

將狀態張貼至 PR

現在,您的伺服器可以在建立新的PR時接收服務攔截事件,請將它更新為將狀態回傳至PR。

  1. 服務攔截要求包含描述事件的 JSON 承載。 若要協助剖析服務攔截所傳回的 JSON,請安裝 body-parser 套件。

    npm install body-parser
    
  2. 更新 app.js 以使用本文剖析器進行剖析 application/json

    var bodyParser = require('body-parser')
    
    app.use(bodyParser.json())
    
  3. 若要簡化對 Azure Repos 進行 REST API 呼叫,請安裝 azure-devops-node-api 套件。

    npm install azure-devops-node-api 
    
  4. 更新 app.js 以使用 azure-devops-node-api 套件、設定帳戶連線的詳細數據,並取得 Git API 的實例。

    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. 為您的集合 URL 建立環境變數,並將 <your account> 取代為您的 Azure DevOps 組織名稱。

    setx COLLECTIONURL "https://dev.azure.com/<your account>"
    
  6. 依照下列指示建立個人驗證令牌(PAT),讓您的應用程式使用: 使用個人存取令牌進行驗證。 您應該為用來存取帳戶的每個服務建立新的 PAT,並適當地命名它。

  7. 為您的 PAT 建立環境變數。

    setx TOKEN "yourtokengoeshere"
    
  8. 更新 函式 post() ,以從服務攔截承載讀取PR詳細數據。 您需要這些值,才能回傳狀態。

    var repoId = req.body.resource.repository.id
    var pullRequestId = req.body.resource.pullRequestId
    var title = req.body.resource.title
    
  9. 建置要張貼在PR上的 status物件。

    State是 GitStatusState 類型的列舉。 使用 succeeded 來表示PR已通過狀態檢查,且已準備好合併。

    description是字串值,將會在PR詳細數據檢視的 [狀態] 區段和活動摘要中向用戶顯示。

    targetUrl是 URL,將用來建立 [狀態] 區段和活動摘要中描述文字的連結。 這是使用者可以前往的位置,以取得狀態的詳細資訊,例如組建報表或測試回合。 如果未指定 URL,描述會顯示為沒有連結的文字。

    內容 namegenre 可用來分類狀態,並區別於其他服務張貼狀態。

        var prStatus = {
            "state": "succeeded",
            "description": "Ready for review",
            "targetUrl": "https://visualstudio.microsoft.com",
            "context": {
                "name": "wip-checker",
                "genre": "continuous-integration"
            }
        }
    
  10. 不要只盲目張貼succeeded狀態,而是檢查PR標題,以查看使用者是否已透過將WIP新增至標題來指出PR是否為進行中的工作。 如果是,請變更張貼回 PR 的狀態。

        if (title.includes("WIP")) {
            prStatus.state = "pending"
            prStatus.description = "Work in progress"
        }
    
  11. 最後,使用 createPullRequestStatus() 方法張貼狀態。 它需要狀態物件、存放庫標識碼和提取要求標識碼。 將響應輸出至節點控制台,讓您可以查看文章的結果。

    vstsGit.createPullRequestStatus(prStatus, repoId, pullRequestId).then( result => {
        console.log(result)
    })
    
  12. 產生的方法看起來應該像這樣:

    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. 儲存 app.js 並重新啟動您的節點應用程式。

    node app.js
    

建立新的 PR 以測試狀態伺服器

既然您的伺服器正在執行並接聽服務攔截通知,請建立提取要求以進行測試。

  1. 從檔案檢視開始。 編輯存放庫中的 readme.md 檔案(如果您沒有 readme.md,則為任何其他檔案)。

    從操作選單中選取 [編輯]

  2. 進行編輯並認可存放庫的變更。

    編輯檔案,然後從工具欄中選取 [認可]

  3. 請務必將變更認可至新的分支,以便在下一個步驟中建立 PR。

    輸入新的分支名稱,然後選取 [認可]

  4. 選取 [ 建立提取要求 ] 連結。

    從建議列中選取 [建立提取要求]

  5. 在標題中新增 WIP ,以測試應用程式的功能。 選取 [建立] 以建立 PR。

    將 WIP 新增至預設 PR 標題

  6. 建立 PR 之後,您會看到 [狀態] 區段,其中 [ 工作進行 中] 專案會連結到承載中指定的 URL。

    [工作進行中] 項目的狀態區段。

  7. 更新PR標題並移除WIP文字,並注意狀態會從 [工作進行中] 變更為 [準備檢閱]。

後續步驟

  • 在本文中,您已瞭解如何建立服務,以透過服務攔截接聽PR事件,並使用狀態 API 張貼狀態消息的基本概念。 如需提取要求狀態 API 的詳細資訊,請參閱 REST API 檔
  • 設定外部服務的分支原則