Azure DevOps Services |Azure DevOps Server |Azure DevOps Server 2022 |Azure DevOps Server 2020
pull request (PR) ワークフローを使用すると、開発者はピアや自動化されたツールからコードに関するフィードバックを得ることができます。 Microsoft 以外のツールとサービスは、PR Status APIを使用して PR ワークフローに参加できます。 この記事では、Azure DevOps Services Git リポジトリで PR を検証するステータス サーバーを作成するプロセスについて説明します。 PR ステータスの詳細については、「プル要求の状態を使用して pull request ワークフローをカスタマイズおよび拡張する」を参照してください。
前提 条件
| カテゴリ | 要求事項 |
|---|---|
| 組織 | Git リポジトリを持つ Azure DevOps 内の組織。 |
| ツール |
-
Visual Studio Code または選択したその他のコード エディター。 - Node.js. ダウンロードにはインストーラーが含まれており、ローカル コンピューターに Node.js ランタイムをインストールするために実行できます。 Node.jsをインストールするときは、既定で選択されている npm パッケージ マネージャー インストールの一部を保持してください。 |
| 認証 | PR 状態を変更する権限を持つコード (状態)スコープを使用できるMicrosoft Entra ID トークン。 詳細については、Microsoft Entra 認証に関するページを参照してください。 |
Express を使用して基本的な Web サーバーを作成する
このセクションの手順では、Expressを使用します。これは、Web サーバーの作成を簡略化する多くの HTTP ユーティリティ メソッドを提供する、Node.js 用の軽量 Web フレームワークです。 このフレームワークでは、PR イベントをリッスンするために必要な基本的な機能を提供します。
コマンド ラインから、Web サーバー用の新しいプロジェクト フォルダーを作成します。
mkdir pr-server cd pr-servernpm initコマンドを使用して、プロジェクトの新しいpackage.jsonファイルを作成します。npm initEnter キーを押して、エントリ ポイント以外のすべてのオプションの既定値を受け入れます。
app.jsに変更するentry point: (index.js) app.js次のコマンドを使用して、
pr-serverディレクトリに Express をインストールします。 これにより、Express がインストールされ、依存関係の一覧に保存されます。npm install expressPR ステータス サーバー用に構築する Express アプリを作成します。 次の手順は、Express Hello world の例に基づいています。
a.
pr-serverフォルダーから次のコマンドを実行して、Visual Studio Code でプロジェクト フォルダーを開きます。code .b。 新しいファイル
(Ctrl + N)を作成し、次のサンプル コードに貼り付けて基本的な Express サーバーを作成します。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!') })c. ファイルを
app.jsとして保存します。次のコマンドを使用して、基本的な Web サーバーを実行します。
node app.jshttp://localhost:3000/を参照して、サーバーが実行されていることを確認します。
HTTP POST 要求をリッスンする
Web サーバーは Azure DevOps Services から POST 要求を受信するため、サーバーでそれらの要求を処理する必要があります。
app.jsファイルの末尾に次のコードを追加し、ファイルを保存します。app.post('/', function (req, res) { res.send('Received the POST') })次のコマンドを使用して、Web サーバーを再実行します。
node app.js
PR イベントのサービス フックを構成する
サービス フックは、特定のイベントが発生したときに外部サービスにアラートを送信できる Azure DevOps Services 機能です。 このサンプルでは、状態サーバーに通知できるように、PR イベント用に 2 つのサービス フックを設定します。 1 つ目はイベントで作成された Pull request 用で、2 つ目は更新された Pull request イベント用です。
サービス フック通知を受信するには、パブリック インターネットにポートを公開します。 ngrok ユーティリティは、開発環境でこれを行う場合に便利です。
プラットフォームに適した ngrok リリースをダウンロードして解凍します。
ngrok を使用して、サンプル サーバーと同じポート (ポート 3000) でリッスンを開始します。 新しいコマンド ウィンドウで次のコマンドを実行します。
ngrok http 3000Ngrok は、
localhost:3000に転送するパブリック URL を作成します。 次の手順で必要に応じて、URL を書き留めます。 次の例のようになります。http://c3c1bffa.ngrok.ioAzure DevOps でプロジェクトを参照します (例:
https://dev.azure.com/<your account>/<your project name>ナビゲーション メニューから、の歯車 上にマウス ポインターを合わせ、サービス フック 選択します。
最初のサービス フックの場合は、[ + サブスクリプションの作成] を選択します。
他のサービス フックが既に構成されている場合は、プラス
(+)を選択して新しいサービス フック サブスクリプションを作成します。
[新しいサービス フック サブスクリプション] ダイアログで、サービス一覧から [Web フック] を選択し、[次へ] を選択します。
イベント トリガーの一覧から [Pull request created] を選択し、[次へ] を選択します。
[アクション] ページで、[URL ボックスに ngrok の URL を入力します。 テスト を選択して、テスト イベントをサーバーに送信します。
ngrok コンソール ウィンドウで、受信
POSTは、サーバーがサービス フック イベントを受信したことを示す200 OKを返します。HTTP Requests ------------- POST / 200 OK[テスト通知] ウィンドウで、[応答] タブを選択して、サーバーからの応答の詳細を表示します。 POST ハンドラーからの文字列の長さに一致するコンテンツの長さが 17 である必要があります (例: "Received the POST")。
[テスト通知] ウィンドウを閉じ、[完了] 選択してサービス フックを作成します。
手順 3 から 9 をもう一度実行しますが、今回は、Pull request updated イベントを構成します。
重要
前の手順を 2 回実行し、作成された Pull request と、更新された pull request イベント 両方のサービス フックを作成してください。
PR に状態をポストする
新しい PR が作成されたときにサーバーがサービス フック イベントを受信できるようになったので、それを更新して状態を PR にポストバックします。
サービス フック要求には、イベントを記述する JSON ペイロードが含まれます。 サービス フックによって返される JSON を解析するには、body-parser パッケージをインストールします。
npm install body-parserapp.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-apiazure-devops-node-api パッケージを使用するように
app.jsを更新し、アカウントへの接続の詳細を設定し、Git API のインスタンスを取得します。const vsts = require("azure-devops-node-api") const collectionURL = process.env.COLLECTIONURL const token = process.env.TOKEN var authHandler = vsts.getBearerHandler(token) var connection = new vsts.WebApi(collectionURL, authHandler) var vstsGit = connection.getGitApi()コレクション URL の環境変数を作成し、
<your account>を Azure DevOps 組織の名前に置き換えます。setx COLLECTIONURL "https://dev.azure.com/<your account>"アプリで使用する Microsoft Entra ID トークンを取得します。 Microsoft Entra ID トークンは、Azure DevOps REST API に推奨される認証方法です。 これらのトークンは、次の方法で取得できます。
- オプション 1: Azure CLI (開発/テスト用)
az account get-access-token --resource 499b84ac-1321-427f-aa17-267ca6975798 --query "accessToken" --output tsv - オプション 2: サービス プリンシパル (運用環境向け)
- Microsoft Entra ID でアプリケーションの登録
- アプリケーションのクライアント シークレットを作成する
- Azure DevOps でアプリケーションに適切なアクセス許可を付与する
- サービス プリンシパルの資格情報を使用してプログラムでトークンを取得する
詳細については、Microsoft Entra 認証に関するページを参照してください。
- オプション 1: Azure CLI (開発/テスト用)
Microsoft Entra ID トークンの環境変数を作成します。
setx TOKEN "your-entra-id-token-here"
Microsoft Entra ID トークンをプログラムで取得する (運用環境に推奨)
運用アプリケーションの場合は、静的トークンを使用するのではなく、プログラムで Microsoft Entra ID トークンを取得する必要があります。 Node.js用の Microsoft Authentication Library (MSAL) を使用してこれを実装する方法を次に示します。
MSAL Node パッケージをインストールします。
npm install @azure/msal-nodeトークン プロバイダー モジュール (
tokenProvider.js) を作成します。const { ConfidentialClientApplication } = require('@azure/msal-node'); const clientConfig = { auth: { clientId: process.env.CLIENT_ID, clientSecret: process.env.CLIENT_SECRET, authority: `https://login.microsoftonline.com/${process.env.TENANT_ID}` } }; const cca = new ConfidentialClientApplication(clientConfig); async function getAccessToken() { const clientCredentialRequest = { scopes: ['499b84ac-1321-427f-aa17-267ca6975798/.default'] }; try { const response = await cca.acquireTokenByClientCredential(clientCredentialRequest); return response.accessToken; } catch (error) { console.error('Error acquiring token:', error); throw error; } } module.exports = { getAccessToken };トークン プロバイダーを使用するように
app.jsを更新します。const { getAccessToken } = require('./tokenProvider'); // Instead of using a static token, get a fresh token app.post("/", async function (req, res) { try { const token = await getAccessToken(); var authHandler = vsts.getBearerHandler(token); var connection = new vsts.WebApi(collectionURL, authHandler); // ... rest of your POST handler code } catch (error) { console.error('Authentication error:', error); res.status(500).send('Authentication failed'); } });post()関数を更新して、サービス フック ペイロードから PR の詳細を読み取る。 状態をポストバックするには、これらの値が必要です。var repoId = req.body.resource.repository.id var pullRequestId = req.body.resource.pullRequestId var title = req.body.resource.titlePR に投稿する状態オブジェクトをビルドします。
Stateは、GitStatusState 型の列挙型です。succeededを使用して、PR がステータス チェックに合格し、マージの準備ができていることを示します。descriptionは、PR 詳細ビューの [状態] セクションとアクティビティ フィードにユーザーに表示される文字列値です。targetUrlは、Status セクションとアクティビティ フィードの説明テキストのリンクを作成するために使用される 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()メソッドを使用して状態を投稿します。 状態オブジェクト、リポジトリ ID、およびプル要求 ID が必要です。 投稿の結果を確認できるように、ノード コンソールに応答を出力します。vstsGit.createPullRequestStatus(prStatus, repoId, pullRequestId).then( result => { console.log(result) })結果のメソッドは次のようになります。
app.post("/", async function (req, res) { try { // 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" } // Get the Git API instance and post the status to the PR const gitApi = await vstsGit const result = await gitApi.createPullRequestStatus(prStatus, repoId, pullRequestId) console.log(result) res.send("Received the POST") } catch (error) { console.error('Error processing PR status:', error) res.status(500).send('Error processing request') } })app.js保存し、ノード アプリを再起動します。node app.js
ステータス サーバーをテストするための新しい PR を作成する
サーバーが実行され、サービスフック通知をリッスンできる状態になったら、「プルリクエスト」を作成してテストします。
ファイル ビューから開始します。 リポジトリ内の readme.md ファイル (または readme.md がない場合は他のファイル) を編集します。
編集を行い、変更をリポジトリにコミットします。
次の手順で PR を作成できるように、必ず新しいブランチに変更をコミットしてください。
[プルリクエストの作成] リンクを選択します。
タイトル WIP を追加して、アプリの機能をテストします。 [作成] を選択して、PR を作成します。
PR が作成されると、ペイロードで指定された URL にリンクする進行中の作業エントリ が状態セクションに表示されます。
PR タイトルを更新し、WIP テキストを削除すると、状態が "進行中の作業" から "レビュー準備完了" に変わることに注意してください。
関連記事
- REST API のドキュメント
- 外部サービス のブランチ ポリシーを構成する