Azure DevOps Services |Azure DevOps Server 2022 - Azure DevOps Server 2019 |TFS 2018
拉取请求 (PR) 工作流为开发人员提供了从对等方以及自动化工具获取代码反馈的机会。 第三方工具和服务可以使用 PR
状态 API
参与 PR 工作流。 本文指导你完成创建状态服务器以验证 Azure DevOps Services Git 存储库中的 PR 的过程。 有关 PR 状态的详细信息,请参阅
使用拉取请求状态自定义和扩展拉取请求工作流
。
包含 Git 存储库的 Azure DevOps 中的组织。 如果没有组织,
请注册
以免费无限制的专用 Git 存储库上传和共享代码。
安装所选
的 VS Code
或其他代码编辑器。 本指南中的说明使用 VS Code,但其他代码编辑器中的步骤类似。
安装 Node.js
若要安装Node.js,
请下载
适合平台的 LTS 版本。 下载包含一个安装程序,可以在本地计算机上安装Node.js运行时。 安装Node.js时,请务必保留默认选择的安装
npm 包管理器
部分。
使用 Express 创建基本 Web 服务器
本部分中的步骤使用
Express
,它是一个轻型 Web 框架,用于Node.js,提供许多简化创建 Web 服务器的 HTTP 实用工具方法。 此框架提供侦听 PR 事件所需的基本函数。
在命令行中,为 Web 服务器创建新的项目文件夹。
mkdir pr-server
cd pr-server
npm init
使用命令为项目创建新package.json
文件。
npm init
按 Enter 接受除入口点以外的所有选项的默认值。 请将其更改为 app.js
entry point: (index.js) app.js
使用以下命令在 pr-server 目录中安装 Express。 这会安装 Express 并将其保存到依赖项列表中。
npm install express
创建一个简单的 Express 应用,以便为 PR 状态服务器构建。 以下步骤基于 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 服务器将接收POST
来自Azure DevOps Services的请求,因此你需要在服务器中处理这些请求。
在文件末尾 app.js
,添加以下代码,并保存该文件。
app.post('/', function (req, res) {
res.send('Received the POST')
使用以下命令重新运行 Web 服务器:
node app.js
服务挂钩是一项Azure DevOps Services功能,可在发生某些事件时向外部服务发出警报。 对于此示例,需要为 PR 事件设置两个服务挂钩,以便可以通知状态服务器。 第一个用于 拉取请求创建 事件,第二个将用于 拉取请求更新 事件。
若要接收服务挂钩通知,需要向公共 Internet 公开端口。 ngrok 实用工具对于在开发环境中执行此操作非常有用。
下载 并解压缩平台的相应 ngrok 版本。
使用 ngrok 开始侦听与示例服务器相同的端口 - 端口 3000。 在新命令窗口中运行以下命令。
ngrok http 3000
Ngrok 将创建一个转发到 localhost:3000
的公共 URL。 请注意,在下一步中需要 URL。 它将如下所示:
http://c3c1bffa.ngrok.io
浏览到 Azure DevOps 中的项目,例如 https://dev.azure.com/<your account>/<your project name>
在导航菜单中,将鼠标悬停在 齿轮 上,然后选择 “服务挂钩”。
如果这是第一个服务挂钩,请选择“ + 创建订阅”。
如果已配置其他服务挂钩,请选择绿色挂钩 (+)
以创建新的服务挂钩订阅。
在“新建服务挂钩订阅”对话框中,从服务列表中选择 “Web 挂钩 ”,然后选择“ 下一步”。
选择从事件触发器列表中 创建的拉取请求 ,然后选择“ 下一步”。
在“操作”页中,在 URL 框中输入来自 ngrok 的 URL 。 选择 “测试 ”,将测试事件发送到服务器。
在 ngrok 控制台窗口中,你将看到返回的200 OK
传入POST
,指示服务器收到了服务挂钩事件。
HTTP Requests
-------------
POST / 200 OK
在“测试通知”窗口中,选择“响应”选项卡以查看服务器响应的详细信息。 应看到的内容长度为 17,该长度与 POST 处理程序中的字符串长度匹配, (即“收到 POST”) 。
关闭“测试通知”窗口,然后选择“ 完成 ”以创建服务挂钩。
再次执行步骤 3-9,但这次配置 拉取请求更新 事件。
请务必执行上述步骤两次,并为 创建的拉取请求 和 拉取请求更新 事件创建服务挂钩。
将状态发布到 PR
在创建新 PR 时,服务器可以接收服务挂钩事件,请将其更新为将状态回发到 PR。
服务挂钩请求包括描述事件的 JSON 有效负载。 若要帮助分析服务挂钩返回的 JSON,请安装 body-parser 包。
npm install body-parser
更新 app.js
以使用正文分析器进行分析 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 上发布的状态对象。
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"
通过向游戏添加 WIP,而不是盲目发布succeeded
状态,检查 PR 标题,以查看用户是否指示 PR 是否正在进行中工作。 如果是,请更改发布到 PR 的状态。
if (title.includes("WIP")) {
prStatus.state = "pending"
prStatus.description = "Work in progress"
最后,使用 createPullRequestStatus()
该方法发布状态。 它需要状态对象、存储库 ID 和拉取请求 ID。 输出到节点控制台的响应,以便查看帖子的结果。
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 文本,并注意状态将从“正在工作”更改为“准备审阅”。
本文介绍了如何通过服务挂钩创建侦听 PR 事件的服务的基础知识,并可以使用状态 API 发布状态消息。 有关拉取请求状态 API 的详细信息,请参阅 REST API 文档。
为外部服务配置分支策略。