使用 Node.js 建立提取要求狀態伺服器
Azure DevOps Services |Azure DevOps Server 2022 - Azure DevOps Server 2019
拉取請求(PR)工作流程為開發人員提供了一個機會,可以從同儕和自動化工具獲得對其程式碼的意見反饋。 非Microsoft工具和服務可以使用PR 狀態 API參與PR工作流程。 本文將引導您完成建立狀態伺服器的過程,以驗證存在於 Azure DevOps Services Git 存放庫中的 Pull Request (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 事件所需的基本功能。
從命令行建立 Web 伺服器的新項目資料夾。
mkdir pr-server cd pr-server
使用
npm init
命令,為專案建立新的package.json
檔案。npm init
選取 ,然後輸入,以接受所有選項的預設值,但進入點除外。 將它變更為
app.js
entry point: (index.js) app.js
使用下列命令,在
pr-server
目錄中安裝 Express。 這會安裝 Express,並將它儲存至相依性清單。npm install express
為 PR 狀態伺服器建立 Express 應用程式。 下列步驟是以 Express Hello world 範例為基礎。 從
pr-server
資料夾執行下列命令,以在 VS Code 中開啟項目資料夾。code .
建立新的檔案
(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!') })
將檔案儲存為
app.js
。使用下列命令執行基本 Web 伺服器:
node app.js
流覽至
http://localhost:3000/
以確認伺服器正在執行。
監聽 HTTP POST 請求
Web 伺服器將會從 Azure DevOps Services 接收 POST
要求,因此您必須在伺服器中處理這些要求。
在
app.js
檔案的結尾,加入以下程式碼,然後儲存檔案。app.post('/', function (req, res) { res.send('Received the POST') })
使用下列命令重新執行網頁伺服器:
node app.js
設定PR事件的服務攔截
服務勾點是 Azure DevOps Services 功能,可在發生特定事件時警示外部服務。 在此範例中,設定PR事件的兩個服務攔截,以便通知狀態伺服器。 第一個是針對 拉取請求建立 事件,第二個是針對 拉取請求更新 事件。
若要接收服務掛鉤通知,請將埠公開至公用網際網路。 ngrok 公用程式對於在開發環境中這樣做很有用。
下載並解壓縮適合您平台的適當 ngrok 版本。
使用 ngrok 在與範例伺服器相同的埠(埠 3000)上開始監聽。 在新命令視窗中執行下列命令。
ngrok http 3000
Ngrok 會建立公用 URL,轉送至
localhost:3000
。 記下 URL,因為您在下一個步驟中需要它。 它看起來像下列範例:http://c3c1bffa.ngrok.io
流覽至 Azure DevOps 中的專案,例如
https://dev.azure.com/<your account>/<your project name>
從導覽功能表中,將滑鼠停留在 齒輪 上,然後選取 [Service Hooks]。
如果這是您的第一個服務勾點,請選擇 [+ 建立訂用帳戶。
如果您已設定其他服務攔截,請選取加號
(+)
來建立新的服務攔截訂用帳戶。在 [新增服務掛鈎訂閱] 對話框中,從服務列表中選取 [Web Hooks],然後選取 [下一步]。
從事件觸發程式清單中選取 [已建立 提取要求],然後選取 [下一步]。
在 [動作] 頁面中,在 [URL] 方塊中輸入 ngrok 的 URL。 選取 [測試],以將測試事件傳送至您的伺服器。
在 ngrok 控制台視窗中,傳入
POST
會傳回200 OK
,指出您的伺服器收到服務攔截事件。HTTP Requests ------------- POST / 200 OK
在 [測試通知] 視窗中,選取 [回應] 索引標籤以查看伺服器回應的詳細數據。 您應該會看到內容長度為 17,符合 POST 處理程式中字串的長度(例如「已接收 POST」)。
關閉 [測試通知] 視窗,然後選取 [完成] 以建立服務掛鉤。
再次執行步驟 3-9,但這次設定 提取請求已更新事件。
重要
務必執行上述步驟兩次,並為 拉取請求建立 事件和 拉取請求更新 事件建立服務勾點。
將狀態張貼至 PR
現在,您的伺服器可以在建立新的PR時接收服務攔截事件,請將它更新為將狀態回傳至PR。
服務鉤子請求包含描述事件的 JSON 承載。 為了協助剖析服務鉤子傳回的 JSON,請安裝 body-parser 套件。
npm install body-parser
更新
app.js
使用 body-parser 來剖析application/json
。var bodyParser = require('body-parser') app.use(bodyParser.json())
若要簡化對 Azure Repos 進行 REST API 呼叫,請安裝 azure-devops-node-api 套件。
npm install azure-devops-node-api
更新
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); } );
為您的集合 URL 建立環境變數,並將
<your account>
取代為您的 Azure DevOps 組織名稱。setx COLLECTIONURL "https://dev.azure.com/<your account>"
依照下列指示,為您的應用程式建立個人驗證令牌 (PAT),請遵循下列指示:使用個人存取令牌進行驗證。 您應該為用來存取帳戶的每個服務建立新的 PAT,並適當地命名它。
為您的 PAT 建立環境變數。
setx TOKEN "yourtokengoeshere"
更新
post()
函式,以從服務勾點有效負載讀取 PR 詳細數據。 您需要這些值才能回傳狀態。var repoId = req.body.resource.repository.id var pullRequestId = req.body.resource.pullRequestId var title = req.body.resource.title
建立要張貼在 PR(拉取請求)上的 status 物件。
State
是 GitStatusState類型的列舉。 使用succeeded
來指出PR已通過狀態檢查,且已準備好合併。description
是字串值,會在PR詳細數據檢視的 [狀態] 區段和活動摘要中向用戶顯示。targetUrl
是 URL,用來建立 [狀態] 區段和活動動態中描述文字的連結,也就是使用者可以前往其中取得更多關於狀態的資訊,例如組建報表或測試運行。 如果未指定 URL,描述會顯示為沒有連結的文字。內容
name
和genre
可用來分類狀態,並將其與其他服務張貼狀態區別。var prStatus = { "state": "succeeded", "description": "Ready for review", "targetUrl": "https://visualstudio.microsoft.com", "context": { "name": "wip-checker", "genre": "continuous-integration" } }
在發佈
succeeded
狀態之前,請檢查 PR 標題,查看使用者是否透過在標題中加入 WIP 來表示 PR 為進行中工作。 如果是,請變更張貼回 PR 的狀態。if (title.includes("WIP")) { prStatus.state = "pending" prStatus.description = "Work in progress" }
最後,使用
createPullRequestStatus()
方法張貼狀態。 它需要狀態物件、存放庫標識碼和提取要求標識碼。 將回應輸出至 Node 控制台,讓您可以看到發送請求的結果。vstsGit.createPullRequestStatus(prStatus, repoId, pullRequestId).then( result => { console.log(result) })
產生的方法看起來應該像這樣:
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") })
儲存
app.js
並重新啟動您的節點應用程式。node app.js
建立新的 PR 以測試狀態伺服器
既然您的伺服器正在執行並接聽服務攔截通知,請建立提取要求以進行測試。
請從檔案視圖開始。 編輯儲存庫中的 readme.md 檔案(如果您沒有 readme.md,則編輯任何其他檔案)。
進行編輯並提交到版本庫。
請務必將變更認可至新的分支,以便在下一個步驟中建立 PR。
選取 建立提取要求 連結。
在標題中新增 WIP,以測試應用程式的功能。 選取 建立 來建立 PR。
建立 PR 之後,狀態區段會顯示一條 工作進行中 目錄,連結到在承載中指定的 URL。
更新PR標題,並移除WIP文字,且注意狀態將從進行中 變更為準備檢閱。