ado
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
Chinese<!-- markdownlint-disable-file MD041 -->
STARTER_CHARACTER = 🔷
<!-- markdownlint-disable-file MD041 -->
STARTER_CHARACTER = 🔷
Azure DevOps Operations
Azure DevOps 操作
Use the CLI and ADO REST API to interact with Azure DevOps resources.
az使用 CLI 和 ADO REST API 与 Azure DevOps 资源进行交互。
azPrerequisites
前置条件
Auth: (always set). No login needed.
$AZURE_DEVOPS_EXT_PATRepo ops require ADO remote ( or ).
dev.azure.comvisualstudio.com身份验证:(始终设置)。无需登录。
$AZURE_DEVOPS_EXT_PAT存储库操作需要 ADO 远程仓库( 或 )。
dev.azure.comvisualstudio.comDefault Org and Project
默认组织和项目
The shell environment provides default values via and . Use these as fallbacks when org or project cannot be parsed from the git remote, or when operating outside a git repo.
$ADO_DEFAULT_ORG$ADO_DEFAULT_PROJECTbash
org="${org:-$ADO_DEFAULT_ORG}"
project="${project:-$ADO_DEFAULT_PROJECT}"Pass them to commands via and .
az--org "https://dev.azure.com/${org}"--project "$project"Shell 环境通过 和 提供默认值。当无法从 Git remote 解析出组织或项目,或者在 Git 仓库之外执行操作时,使用这些值作为回退。
$ADO_DEFAULT_ORG$ADO_DEFAULT_PROJECTbash
org="${org:-$ADO_DEFAULT_ORG}"
project="${project:-$ADO_DEFAULT_PROJECT}"通过 和 将它们传递给 命令。
--org "https://dev.azure.com/${org}"--project "$project"azURL Parsing
URL 解析
Azure DevOps remotes come in three formats. Parse org, project, and repo from the remote URL to construct web URLs and pass parameters to commands.
azbash
remote_url=$(git remote get-url origin 2>/dev/null)Azure DevOps remote 有三种格式。解析 remote URL 中的组织、项目和存储库,以构建 Web URL 并向 命令传递参数。
azbash
remote_url=$(git remote get-url origin 2>/dev/null)Format 1: dev.azure.com HTTPS
格式 1:dev.azure.com HTTPS
Pattern: or
https://dev.azure.com/{org}/{project}/_git/{repo}https://{user}@dev.azure.com/{org}/{project}/_git/{repo}bash
clean_url=$(echo "$remote_url" | sed 's|https://[^@]*@|https://|')
org=$(echo "$clean_url" | sed -n 's|https://dev\.azure\.com/\([^/]*\)/.*|\1|p')
project=$(echo "$clean_url" | sed -n 's|https://dev\.azure\.com/[^/]*/\([^/]*\)/_git/.*|\1|p')
repo=$(echo "$clean_url" | sed -n 's|.*/_git/\(.*\)|\1|p')模式: 或
https://dev.azure.com/{org}/{project}/_git/{repo}https://{user}@dev.azure.com/{org}/{project}/_git/{repo}bash
clean_url=$(echo "$remote_url" | sed 's|https://[^@]*@|https://|')
org=$(echo "$clean_url" | sed -n 's|https://dev\\.azure\\.com/\\([^/]*\\)/.*|\\1|p')
project=$(echo "$clean_url" | sed -n 's|https://dev\\.azure\\.com/[^/]*/\\([^/]*\\)/_git/.*|\\1|p')
repo=$(echo "$clean_url" | sed -n 's|.*/_git/\\(.*\\)|\\1|p')Format 2: visualstudio.com
格式 2:visualstudio.com
Pattern:
https://{org}.visualstudio.com/DefaultCollection/{project}/_git/{repo}bash
clean_url=$(echo "$remote_url" | sed 's|https://[^@]*@|https://|')
org=$(echo "$clean_url" | sed -n 's|^https://\([^.]*\)\..*|\1|p')
project=$(echo "$clean_url" | sed -n 's|.*/DefaultCollection/\([^/]*\)/_git/.*|\1|p')
repo=$(echo "$clean_url" | sed -n 's|.*/_git/\(.*\)|\1|p')模式:
https://{org}.visualstudio.com/DefaultCollection/{project}/_git/{repo}bash
clean_url=$(echo "$remote_url" | sed 's|https://[^@]*@|https://|')
org=$(echo "$clean_url" | sed -n 's|^https://\\([^.]*\\)\\..*|\\1|p')
project=$(echo "$clean_url" | sed -n 's|.*/DefaultCollection/\\([^/]*\\)/_git/.*|\\1|p')
repo=$(echo "$clean_url" | sed -n 's|.*/_git/\\(.*\\)|\\1|p')Format 3: SSH
格式 3:SSH
Pattern:
git@ssh.dev.azure.com:v3/{org}/{project}/{repo}bash
org=$(echo "$remote_url" | sed -n 's|git@ssh\.dev\.azure\.com:v3/\([^/]*\)/.*|\1|p')
project=$(echo "$remote_url" | sed -n 's|git@ssh\.dev\.azure\.com:v3/[^/]*/\([^/]*\)/.*|\1|p')
repo=$(echo "$remote_url" | sed -n 's|.*[^/]*/\([^/]*\)$|\1|p')模式:
git@ssh.dev.azure.com:v3/{org}/{project}/{repo}bash
org=$(echo "$remote_url" | sed -n 's|git@ssh\\.dev\\.azure\\.com:v3/\\([^/]*\\)/.*|\\1|p')
project=$(echo "$remote_url" | sed -n 's|git@ssh\\.dev\\.azure\\.com:v3/[^/]*/\\([^/]*\\)/.*|\\1|p')
repo=$(echo "$remote_url" | sed -n 's|.*[^/]*/\\([^/]*\\)$|\\1|p')Constructing Web URLs
构建 Web URL
URL-encode spaces in project names (), then build:
%20text
base_url=https://dev.azure.com/{org}/{project}/_git/{repo}
pr_url={base_url}/pullrequest/{pr_id}On macOS, open URLs with .
open "$url"对项目名称中的空格进行 URL 编码(),然后构建:
%20text
base_url=https://dev.azure.com/{org}/{project}/_git/{repo}
pr_url={base_url}/pullrequest/{pr_id}在 macOS 上,使用 打开 URL。
open "$url"Browse
浏览
Open Repo
打开存储库
Parse the remote URL, construct the web URL, and open it.
bash
open "https://dev.azure.com/${org}/${project}/_git/${repo}"解析 remote URL,构建 Web URL,然后打开。
bash
open "https://dev.azure.com/${org}/${project}/_git/${repo}"Open PR
打开 PR
bash
open "https://dev.azure.com/${org}/${project}/_git/${repo}/pullrequest/${pr_id}"bash
open "https://dev.azure.com/${org}/${project}/_git/${repo}/pullrequest/${pr_id}"Projects
项目
List Projects
列出项目
bash
az devops project list --organization "https://dev.azure.com/${org}" --query "value[].{Name:name,ID:id,State:state}" -o tablebash
az devops project list --organization "https://dev.azure.com/${org}" --query "value[].{Name:name,ID:id,State:state}" -o tableShow Project Details
显示项目详细信息
bash
az devops project show --project "$project" --organization "https://dev.azure.com/${org}"bash
az devops project show --project "$project" --organization "https://dev.azure.com/${org}"Get Project ID
获取项目 ID
bash
az devops project show --project "$project" --organization "https://dev.azure.com/${org}" --query id -o tsvbash
az devops project show --project "$project" --organization "https://dev.azure.com/${org}" --query id -o tsvRepositories
存储库
Create
创建
bash
az repos create \
--name "<repo-name>" \
--project "$project" \
--org "https://dev.azure.com/${org}" \
--output table \
--query "{Name:name,Project:project.name,URL:webUrl}"bash
az repos create \\
--name "<repo-name>" \\
--project "$project" \\
--org "https://dev.azure.com/${org}" \\
--output table \\
--query "{Name:name,Project:project.name,URL:webUrl}"Delete
删除
Step 1: Look up the repository ID.
bash
repo_id=$(az repos show \
--repository "<repo-name>" \
--project "$project" \
--query id --output tsv)Step 2: Delete by ID.
bash
az repos delete \
--id "$repo_id" \
--project "$project" \
--yes步骤 1:查找存储库 ID。
bash
repo_id=$(az repos show \\
--repository "<repo-name>" \\
--project "$project" \\
--query id --output tsv)步骤 2:按 ID 删除。
bash
az repos delete \\
--id "$repo_id" \\
--project "$project" \\
--yesList
列出
bash
az repos list --organization "https://dev.azure.com/${org}" --project "$project" --query "[].{Name:name,ID:id,DefaultBranch:defaultBranch}" -o tablebash
az repos list --organization "https://dev.azure.com/${org}" --project "$project" --query "[].{Name:name,ID:id,DefaultBranch:defaultBranch}" -o tableShow
显示
bash
az repos show --repository <REPO_NAME> --organization "https://dev.azure.com/${org}" --project "$project"bash
az repos show --repository <REPO_NAME> --organization "https://dev.azure.com/${org}" --project "$project"Get Clone URL
获取克隆 URL
bash
az repos show --repository <REPO_NAME> --organization "https://dev.azure.com/${org}" --project "$project" --query remoteUrl -o tsvbash
az repos show --repository <REPO_NAME> --organization "https://dev.azure.com/${org}" --project "$project" --query remoteUrl -o tsvPull Requests (CLI)
Pull Request(CLI)
All PR commands use JMESPath queries for structured output. The variable is constructed from the parsed remote URL (see URL Parsing above).
base_url所有 PR 命令都使用 JMESPath 查询生成结构化输出。 变量基于解析后的 remote URL 构建(参见上方的“URL 解析”)。
base_urlCreate
创建
bash
az repos pr create \
"$@" \
--output table \
--query "{PR:pullRequestId,Status:status,URL:join(\`\`,[\ \`${base_url}\`,\`/pullrequest/\`,to_string(pullRequestId)])}"Common flags: , , , , , ,
--title--description--source-branch--target-branch--reviewers--auto-complete--draftbash
az repos pr create \\
"$@" \\
--output table \\
--query "{PR:pullRequestId,Status:status,URL:join(\\`\\`,[\\ \\`${base_url}\\`,\\`/pullrequest/\\`,to_string(pullRequestId)])}"常用参数:、、、、、、
--title--description--source-branch--target-branch--reviewers--auto-complete--draftList
列出
bash
az repos pr list \
--output table \
--query "[].{PR:pullRequestId,Title:title,Creator:createdBy.uniqueName,Created:creationDate,URL:join(\`\`,[\`${base_url}\`,\`/pullrequest/\`,to_string(pullRequestId)])}"Common flags: , , , ,
--status--creator--reviewer--source-branch--target-branchbash
az repos pr list \\
--output table \\
--query "[].{PR:pullRequestId,Title:title,Creator:createdBy.uniqueName,Created:creationDate,URL:join(\\`\\`,[\\`${base_url}\\`,\\`/pullrequest/\\`,to_string(pullRequestId)])}"常用参数:、、、、
--status--creator--reviewer--source-branch--target-branchShow
显示
bash
az repos pr show \
--id <pr-id> \
--output table \
--query "{PR:pullRequestId,Title:title,Creator:createdBy.uniqueName,Created:creationDate,URL:join(\`\`,[\`${base_url}\`,\`/pullrequest/\`,to_string(pullRequestId)])}"bash
az repos pr show \\
--id <pr-id> \\
--output table \\
--query "{PR:pullRequestId,Title:title,Creator:createdBy.uniqueName,Created:creationDate,URL:join(\\`\\`,[\\`${base_url}\\`,\\`/pullrequest/\\`,to_string(pullRequestId)])}"Update
更新
bash
az repos pr update \
--id <pr-id> \
--output table \
--query "{PR:pullRequestId,Status:status,URL:join(\`\`,[\`${base_url}\`,\`/pullrequest/\`,to_string(pullRequestId)])}"Common flags: , , , ,
--title--description--status--auto-complete--draftbash
az repos pr update \\
--id <pr-id> \\
--output table \\
--query "{PR:pullRequestId,Status:status,URL:join(\\`\\`,[\\`${base_url}\\`,\\`/pullrequest/\\`,to_string(pullRequestId)])}"常用参数:、、、、
--title--description--status--auto-complete--draftComplete
完成
Complete (merge) a pull request by setting status to completed with policy bypass.
bash
az repos pr update \
--id <pr-id> \
--status completed \
--bypass-policy true \
--output table \
--query "{PR:pullRequestId,Status:status,URL:join(\`\`,[\`${base_url}\`,\`/pullrequest/\`,to_string(pullRequestId)])}"Additional flags:
--merge-commit-messageCompletion is async. The response will still show status. Follow up with to confirm and .
activeaz repos pr show --id <pr-id>status: completedmergeStatus: succeeded通过将状态设置为 completed 并绕过策略来完成(合并)Pull Request。
bash
az repos pr update \\
--id <pr-id> \\
--status completed \\
--bypass-policy true \\
--output table \\
--query "{PR:pullRequestId,Status:status,URL:join(\\`\\`,[\\`${base_url}\\`,\\`/pullrequest/\\`,to_string(pullRequestId)])}"其他参数:
--merge-commit-message完成操作是异步的。响应中仍会显示 状态。随后运行 ,确认 和 。
activeaz repos pr show --id <pr-id>status: completedmergeStatus: succeededAbandon
放弃
bash
az repos pr update \
--id <pr-id> \
--status abandoned \
--output table \
--query "{PR:pullRequestId,Status:status,URL:join(\`\`,[\`${base_url}\`,\`/pullrequest/\`,to_string(pullRequestId)])}"bash
az repos pr update \\
--id <pr-id> \\
--status abandoned \\
--output table \\
--query "{PR:pullRequestId,Status:status,URL:join(\\`\\`,[\\`${base_url}\\`,\\`/pullrequest/\\`,to_string(pullRequestId)])}"Vote/Approve
投票/批准
bash
az repos pr set-vote \
--id <pr-id> \
--vote approveAfter voting, show the PR details:
bash
az repos pr show \
--id <pr-id> \
--output table \
--query "{PR:pullRequestId,Title:title,Creator:createdBy.uniqueName,Created:creationDate,URL:join(\`\`,[\`${base_url}\`,\`/pullrequest/\`,to_string(pullRequestId)])}"Valid vote values: , , , ,
approveapprove-with-suggestionswait-for-authorrejectresetbash
az repos pr set-vote \\
--id <pr-id> \\
--vote approve投票后显示 PR 详细信息:
bash
az repos pr show \\
--id <pr-id> \\
--output table \\
--query "{PR:pullRequestId,Title:title,Creator:createdBy.uniqueName,Created:creationDate,URL:join(\\`\\`,[\\`${base_url}\\`,\\`/pullrequest/\\`,to_string(pullRequestId)])}"有效投票值:、、、、
approveapprove-with-suggestionswait-for-authorrejectresetPR Comments and Threads (REST API)
PR 评论和 Threads(REST API)
Post Comment
发布评论
bash
curl -s -u ":${AZURE_DEVOPS_EXT_PAT}" -X POST \
"https://dev.azure.com/${org}/${project}/_apis/git/repositories/<REPO_NAME>/pullRequests/<PR_ID>/threads?api-version=7.0" \
-H "Content-Type: application/json" \
-d '{
"comments": [{"parentCommentId": 0, "content": "Comment text here", "commentType": 1}],
"status": 1
}'bash
curl -s -u ":${AZURE_DEVOPS_EXT_PAT}" -X POST \\
"https://dev.azure.com/${org}/${project}/_apis/git/repositories/<REPO_NAME>/pullRequests/<PR_ID>/threads?api-version=7.0" \\
-H "Content-Type: application/json" \\
-d '{
"comments": [{"parentCommentId": 0, "content": "Comment text here", "commentType": 1}],
"status": 1
}'Get Comments/Threads
获取评论/Threads
bash
curl -s -u ":${AZURE_DEVOPS_EXT_PAT}" \
"https://dev.azure.com/${org}/${project}/_apis/git/repositories/<REPO_NAME>/pullRequests/<PR_ID>/threads?api-version=7.0" \
| jq '.value[] | {id: .id, status: .status, comments: [.comments[] | {author: .author.displayName, content: .content}]}'bash
curl -s -u ":${AZURE_DEVOPS_EXT_PAT}" \\
"https://dev.azure.com/${org}/${project}/_apis/git/repositories/<REPO_NAME>/pullRequests/<PR_ID>/threads?api-version=7.0" \\
| jq '.value[] | {id: .id, status: .status, comments: [.comments[] | {author: .author.displayName, content: .content}]}'Search for Comment Containing Text
搜索包含指定文本的评论
bash
curl -s -u ":${AZURE_DEVOPS_EXT_PAT}" \
"https://dev.azure.com/${org}/${project}/_apis/git/repositories/<REPO_NAME>/pullRequests/<PR_ID>/threads?api-version=7.0" \
| jq '.value[].comments[] | select(.content | contains("SEARCH_TEXT")) | {author: .author.displayName, content: .content}'bash
curl -s -u ":${AZURE_DEVOPS_EXT_PAT}" \\
"https://dev.azure.com/${org}/${project}/_apis/git/repositories/<REPO_NAME>/pullRequests/<PR_ID>/threads?api-version=7.0" \\
| jq '.value[].comments[] | select(.content | contains("SEARCH_TEXT")) | {author: .author.displayName, content: .content}'Service Connections
Service Connections
List
列出
bash
az devops service-endpoint list --organization "https://dev.azure.com/${org}" --project "$project" --query "[].{Name:name,Type:type,ID:id,Scheme:authorization.scheme}" -o tablebash
az devops service-endpoint list --organization "https://dev.azure.com/${org}" --project "$project" --query "[].{Name:name,Type:type,ID:id,Scheme:authorization.scheme}" -o tableShow Details
显示详细信息
bash
az devops service-endpoint show --id <ENDPOINT_ID> --organization "https://dev.azure.com/${org}" --project "$project"bash
az devops service-endpoint show --id <ENDPOINT_ID> --organization "https://dev.azure.com/${org}" --project "$project"Get by Name
按名称获取
bash
az devops service-endpoint list --organization "https://dev.azure.com/${org}" --project "$project" --query "[?name=='<NAME>']" -o jsonbash
az devops service-endpoint list --organization "https://dev.azure.com/${org}" --project "$project" --query "[?name=='<NAME>']" -o jsonDelete
删除
bash
az devops service-endpoint delete --id <ENDPOINT_ID> --organization "https://dev.azure.com/${org}" --project "$project" --yesbash
az devops service-endpoint delete --id <ENDPOINT_ID> --organization "https://dev.azure.com/${org}" --project "$project" --yesGet WIF Details (REST API)
获取 WIF 详细信息(REST API)
bash
curl -s -u ":${AZURE_DEVOPS_EXT_PAT}" \
"https://dev.azure.com/${org}/${project}/_apis/serviceendpoint/endpoints?api-version=7.1" \
| jq ".value[] | select(.name == \"<NAME>\") | {issuer: .authorization.parameters.workloadIdentityFederationIssuer, subject: .authorization.parameters.workloadIdentityFederationSubject}"bash
curl -s -u ":${AZURE_DEVOPS_EXT_PAT}" \\
"https://dev.azure.com/${org}/${project}/_apis/serviceendpoint/endpoints?api-version=7.1" \\
| jq ".value[] | select(.name == \\"<NAME>\\") | {issuer: .authorization.parameters.workloadIdentityFederationIssuer, subject: .authorization.parameters.workloadIdentityFederationSubject}"Authorize for All Pipelines (REST API)
为所有 Pipelines 授权(REST API)
bash
SC_ID=$(az devops service-endpoint list --organization "https://dev.azure.com/${org}" --project "$project" --query "[?name=='<NAME>'].id" -o tsv)
curl -s -u ":${AZURE_DEVOPS_EXT_PAT}" -X PATCH \
"https://dev.azure.com/${org}/${project}/_apis/pipelines/pipelinePermissions/endpoint/${SC_ID}?api-version=7.1-preview.1" \
-H "Content-Type: application/json" \
-d '{"allPipelines": {"authorized": true}}'bash
SC_ID=$(az devops service-endpoint list --organization "https://dev.azure.com/${org}" --project "$project" --query "[?name=='<NAME>'].id" -o tsv)
curl -s -u ":${AZURE_DEVOPS_EXT_PAT}" -X PATCH \\
"https://dev.azure.com/${org}/${project}/_apis/pipelines/pipelinePermissions/endpoint/${SC_ID}?api-version=7.1-preview.1" \\
-H "Content-Type: application/json" \\
-d '{"allPipelines": {"authorized": true}}'Agent Pools
Agent Pools
Pools are organization-level and shared across projects.
Pool 属于组织级别,可在项目之间共享。
List All
列出所有 Pool
bash
az pipelines pool list --organization "https://dev.azure.com/${org}" --query "[].{Name:name,ID:id,PoolType:poolType,IsHosted:isHosted,Size:size}" -o tablebash
az pipelines pool list --organization "https://dev.azure.com/${org}" --query "[].{Name:name,ID:id,PoolType:poolType,IsHosted:isHosted,Size:size}" -o tableList by Name Pattern
按名称模式列出
bash
az pipelines pool list --organization "https://dev.azure.com/${org}" --query "[?contains(name, '<PATTERN>')].{Name:name,ID:id,PoolType:poolType,Size:size}" -o tablebash
az pipelines pool list --organization "https://dev.azure.com/${org}" --query "[?contains(name, '<PATTERN>')].{Name:name,ID:id,PoolType:poolType,Size:size}" -o tableGet Pool ID by Name
按名称获取 Pool ID
bash
az pipelines pool list --organization "https://dev.azure.com/${org}" --query "[?name=='<POOL_NAME>'].id" -o tsvbash
az pipelines pool list --organization "https://dev.azure.com/${org}" --query "[?name=='<POOL_NAME>'].id" -o tsvShow Details
显示详细信息
bash
az pipelines pool show --organization "https://dev.azure.com/${org}" --pool-id <POOL_ID>bash
az pipelines pool show --organization "https://dev.azure.com/${org}" --pool-id <POOL_ID>Create (REST API)
创建(REST API)
bash
curl -s -u ":${AZURE_DEVOPS_EXT_PAT}" -X POST \
"https://dev.azure.com/${org}/_apis/distributedtask/pools?api-version=7.1" \
-H "Content-Type: application/json" \
-d '{"name": "<POOL_NAME>", "poolType": "automation", "isHosted": false, "autoProvision": false}'bash
curl -s -u ":${AZURE_DEVOPS_EXT_PAT}" -X POST \\
"https://dev.azure.com/${org}/_apis/distributedtask/pools?api-version=7.1" \\
-H "Content-Type: application/json" \\
-d '{"name": "<POOL_NAME>", "poolType": "automation", "isHosted": false, "autoProvision": false}'Delete (REST API)
删除(REST API)
bash
POOL_ID=$(az pipelines pool list --organization "https://dev.azure.com/${org}" --query "[?name=='<POOL_NAME>'].id" -o tsv)
curl -s -u ":${AZURE_DEVOPS_EXT_PAT}" -X DELETE \
"https://dev.azure.com/${org}/_apis/distributedtask/pools/${POOL_ID}?api-version=7.1"bash
POOL_ID=$(az pipelines pool list --organization "https://dev.azure.com/${org}" --query "[?name=='<POOL_NAME>'].id" -o tsv)
curl -s -u ":${AZURE_DEVOPS_EXT_PAT}" -X DELETE \\
"https://dev.azure.com/${org}/_apis/distributedtask/pools/${POOL_ID}?api-version=7.1"Agents
Agents
Agents run within pools.
Agent 在 Pool 中运行。
List Agents in Pool
列出 Pool 中的 Agent
bash
POOL_ID=$(az pipelines pool list --organization "https://dev.azure.com/${org}" --query "[?name=='<POOL_NAME>'].id" -o tsv)
az pipelines agent list --organization "https://dev.azure.com/${org}" --pool-id $POOL_ID --query "[].{Name:name,ID:id,Status:status,Version:version}" -o tablebash
POOL_ID=$(az pipelines pool list --organization "https://dev.azure.com/${org}" --query "[?name=='<POOL_NAME>'].id" -o tsv)
az pipelines agent list --organization "https://dev.azure.com/${org}" --pool-id $POOL_ID --query "[].{Name:name,ID:id,Status:status,Version:version}" -o tableList Online Agents
列出在线 Agent
bash
POOL_ID=$(az pipelines pool list --organization "https://dev.azure.com/${org}" --query "[?name=='<POOL_NAME>'].id" -o tsv)
az pipelines agent list --organization "https://dev.azure.com/${org}" --pool-id $POOL_ID --query "[?status=='online'].{Name:name,ID:id,Version:version}" -o tablebash
POOL_ID=$(az pipelines pool list --organization "https://dev.azure.com/${org}" --query "[?name=='<POOL_NAME>'].id" -o tsv)
az pipelines agent list --organization "https://dev.azure.com/${org}" --pool-id $POOL_ID --query "[?status=='online'].{Name:name,ID:id,Version:version}" -o tableShow Agent Details
显示 Agent 详细信息
bash
az pipelines agent show --organization "https://dev.azure.com/${org}" --pool-id <POOL_ID> --agent-id <AGENT_ID>bash
az pipelines agent show --organization "https://dev.azure.com/${org}" --pool-id <POOL_ID> --agent-id <AGENT_ID>Count Online Agents
统计在线 Agent 数量
bash
POOL_ID=$(az pipelines pool list --organization "https://dev.azure.com/${org}" --query "[?name=='<POOL_NAME>'].id" -o tsv)
az pipelines agent list --organization "https://dev.azure.com/${org}" --pool-id $POOL_ID --query "[?status=='online']" -o tsv | wc -lbash
POOL_ID=$(az pipelines pool list --organization "https://dev.azure.com/${org}" --query "[?name=='<POOL_NAME>'].id" -o tsv)
az pipelines agent list --organization "https://dev.azure.com/${org}" --pool-id $POOL_ID --query "[?status=='online']" -o tsv | wc -lQueues
Queues
Queues are project-level references to organization-level pools. Pipeline authorization works on queues, not pools.
Queue 是对组织级 Pool 的项目级引用。Pipeline 授权作用于 Queue,而不是 Pool。
List All
列出所有 Queue
bash
az pipelines queue list --organization "https://dev.azure.com/${org}" --project "$project" --query "[].{Name:name,QueueID:id,PoolID:pool.id}" -o tablebash
az pipelines queue list --organization "https://dev.azure.com/${org}" --project "$project" --query "[].{Name:name,QueueID:id,PoolID:pool.id}" -o tableList by Name Pattern
按名称模式列出
bash
az pipelines queue list --organization "https://dev.azure.com/${org}" --project "$project" --query "[?contains(name, '<PATTERN>')].{Name:name,QueueID:id,PoolID:pool.id}" -o tablebash
az pipelines queue list --organization "https://dev.azure.com/${org}" --project "$project" --query "[?contains(name, '<PATTERN>')].{Name:name,QueueID:id,PoolID:pool.id}" -o tableGet Queue ID for Pool
获取 Pool 对应的 Queue ID
bash
POOL_ID=$(az pipelines pool list --organization "https://dev.azure.com/${org}" --query "[?name=='<POOL_NAME>'].id" -o tsv)
az pipelines queue list --organization "https://dev.azure.com/${org}" --project "$project" --query "[?pool.id==\`${POOL_ID}\`].id" -o tsvbash
POOL_ID=$(az pipelines pool list --organization "https://dev.azure.com/${org}" --query "[?name=='<POOL_NAME>'].id" -o tsv)
az pipelines queue list --organization "https://dev.azure.com/${org}" --project "$project" --query "[?pool.id==\\`${POOL_ID}\\`].id" -o tsvCreate Queue for Pool (REST API)
为 Pool 创建 Queue(REST API)
bash
POOL_ID=$(az pipelines pool list --organization "https://dev.azure.com/${org}" --query "[?name=='<POOL_NAME>'].id" -o tsv)
curl -s -u ":${AZURE_DEVOPS_EXT_PAT}" -X POST \
"https://dev.azure.com/${org}/${project}/_apis/distributedtask/queues?api-version=7.1" \
-H "Content-Type: application/json" \
-d '{"name": "<QUEUE_NAME>", "pool": {"id": '${POOL_ID}'}}'bash
POOL_ID=$(az pipelines pool list --organization "https://dev.azure.com/${org}" --query "[?name=='<POOL_NAME>'].id" -o tsv)
curl -s -u ":${AZURE_DEVOPS_EXT_PAT}" -X POST \\
"https://dev.azure.com/${org}/${project}/_apis/distributedtask/queues?api-version=7.1" \\
-H "Content-Type: application/json" \\
-d '{"name": "<QUEUE_NAME>", "pool": {"id": '${POOL_ID}'}}'Authorize Queue for All Pipelines (REST API)
为所有 Pipelines 授权 Queue(REST API)
bash
QUEUE_ID=$(az pipelines queue list --organization "https://dev.azure.com/${org}" --project "$project" --query "[?name=='<QUEUE_NAME>'].id" -o tsv)
curl -s -u ":${AZURE_DEVOPS_EXT_PAT}" -X PATCH \
"https://dev.azure.com/${org}/${project}/_apis/pipelines/pipelinePermissions/queue/${QUEUE_ID}?api-version=7.1-preview.1" \
-H "Content-Type: application/json" \
-d '{"allPipelines": {"authorized": true}}'bash
QUEUE_ID=$(az pipelines queue list --organization "https://dev.azure.com/${org}" --project "$project" --query "[?name=='<QUEUE_NAME>'].id" -o tsv)
curl -s -u ":${AZURE_DEVOPS_EXT_PAT}" -X PATCH \\
"https://dev.azure.com/${org}/${project}/_apis/pipelines/pipelinePermissions/queue/${QUEUE_ID}?api-version=7.1-preview.1" \\
-H "Content-Type: application/json" \\
-d '{"allPipelines": {"authorized": true}}'Authorize Queue for Specific Pipeline (REST API)
为特定 Pipeline 授权 Queue(REST API)
bash
curl -s -u ":${AZURE_DEVOPS_EXT_PAT}" -X PATCH \
"https://dev.azure.com/${org}/${project}/_apis/pipelines/pipelinePermissions/queue/<QUEUE_ID>?api-version=7.1-preview.1" \
-H "Content-Type: application/json" \
-d '{"pipelines": [{"id": <PIPELINE_ID>, "authorized": true}]}'bash
curl -s -u ":${AZURE_DEVOPS_EXT_PAT}" -X PATCH \\
"https://dev.azure.com/${org}/${project}/_apis/pipelines/pipelinePermissions/queue/<QUEUE_ID>?api-version=7.1-preview.1" \\
-H "Content-Type: application/json" \\
-d '{"pipelines": [{"id": <PIPELINE_ID>, "authorized": true}]}'Pipelines
Pipelines
List All
列出所有 Pipeline
bash
az pipelines list --organization "https://dev.azure.com/${org}" --project "$project" --query "[].{Name:name,ID:id,Folder:folder,QueueStatus:queueStatus}" -o tablebash
az pipelines list --organization "https://dev.azure.com/${org}" --project "$project" --query "[].{Name:name,ID:id,Folder:folder,QueueStatus:queueStatus}" -o tableList by Name Pattern
按名称模式列出
bash
az pipelines list --organization "https://dev.azure.com/${org}" --project "$project" --name "<PATTERN>*" --query "[].{Name:name,ID:id}" -o tablebash
az pipelines list --organization "https://dev.azure.com/${org}" --project "$project" --name "<PATTERN>*" --query "[].{Name:name,ID:id}" -o tableShow Details
显示详细信息
bash
az pipelines show --organization "https://dev.azure.com/${org}" --project "$project" --name <PIPELINE_NAME>bash
az pipelines show --organization "https://dev.azure.com/${org}" --project "$project" --name <PIPELINE_NAME>Get Pipeline ID by Name
按名称获取 Pipeline ID
bash
az pipelines list --organization "https://dev.azure.com/${org}" --project "$project" --query "[?name=='<PIPELINE_NAME>'].id" -o tsvbash
az pipelines list --organization "https://dev.azure.com/${org}" --project "$project" --query "[?name=='<PIPELINE_NAME>'].id" -o tsvCreate
创建
bash
az pipelines create \
--organization "https://dev.azure.com/${org}" \
--project "$project" \
--name <PIPELINE_NAME> \
--repository <REPO_NAME> \
--repository-type tfsgit \
--branch main \
--yml-path azure-pipelines.yml \
--skip-first-runbash
az pipelines create \\
--organization "https://dev.azure.com/${org}" \\
--project "$project" \\
--name <PIPELINE_NAME> \\
--repository <REPO_NAME> \\
--repository-type tfsgit \\
--branch main \\
--yml-path azure-pipelines.yml \\
--skip-first-runDelete
删除
bash
PIPELINE_ID=$(az pipelines list --organization "https://dev.azure.com/${org}" --project "$project" --query "[?name=='<PIPELINE_NAME>'].id" -o tsv)
az pipelines delete --id $PIPELINE_ID --organization "https://dev.azure.com/${org}" --project "$project" --yesbash
PIPELINE_ID=$(az pipelines list --organization "https://dev.azure.com/${org}" --project "$project" --query "[?name=='<PIPELINE_NAME>'].id" -o tsv)
az pipelines delete --id $PIPELINE_ID --organization "https://dev.azure.com/${org}" --project "$project" --yesPipeline Runs (Builds)
Pipeline Runs(Builds)
Run Pipeline
运行 Pipeline
bash
az pipelines run --organization "https://dev.azure.com/${org}" --project "$project" --name <PIPELINE_NAME>bash
az pipelines run --organization "https://dev.azure.com/${org}" --project "$project" --name <PIPELINE_NAME>Run and Get Run ID
运行并获取 Run ID
bash
RUN_ID=$(az pipelines run --organization "https://dev.azure.com/${org}" --project "$project" --name <PIPELINE_NAME> --query id -o tsv)
echo "Run ID: $RUN_ID"bash
RUN_ID=$(az pipelines run --organization "https://dev.azure.com/${org}" --project "$project" --name <PIPELINE_NAME> --query id -o tsv)
echo "Run ID: $RUN_ID"Run with Variables
使用变量运行
bash
az pipelines run --organization "https://dev.azure.com/${org}" --project "$project" --name <PIPELINE_NAME> --variables "VAR1=value1" "VAR2=value2"bash
az pipelines run --organization "https://dev.azure.com/${org}" --project "$project" --name <PIPELINE_NAME> --variables "VAR1=value1" "VAR2=value2"List Recent Runs
列出最近的运行
bash
az pipelines runs list --organization "https://dev.azure.com/${org}" --project "$project" --top 10 --query "[].{ID:id,Pipeline:definition.name,Status:status,Result:result,StartTime:startTime}" -o tablebash
az pipelines runs list --organization "https://dev.azure.com/${org}" --project "$project" --top 10 --query "[].{ID:id,Pipeline:definition.name,Status:status,Result:result,StartTime:startTime}" -o tableList Runs for Specific Pipeline
列出特定 Pipeline 的运行
bash
PIPELINE_ID=$(az pipelines list --organization "https://dev.azure.com/${org}" --project "$project" --query "[?name=='<PIPELINE_NAME>'].id" -o tsv)
az pipelines runs list --organization "https://dev.azure.com/${org}" --project "$project" --pipeline-ids $PIPELINE_ID --query "[].{ID:id,Status:status,Result:result}" -o tablebash
PIPELINE_ID=$(az pipelines list --organization "https://dev.azure.com/${org}" --project "$project" --query "[?name=='<PIPELINE_NAME>'].id" -o tsv)
az pipelines runs list --organization "https://dev.azure.com/${org}" --project "$project" --pipeline-ids $PIPELINE_ID --query "[].{ID:id,Status:status,Result:result}" -o tableShow Run Status
显示运行状态
bash
az pipelines runs show --organization "https://dev.azure.com/${org}" --project "$project" --id <RUN_ID> --query "{Status:status,Result:result}" -o jsonbash
az pipelines runs show --organization "https://dev.azure.com/${org}" --project "$project" --id <RUN_ID> --query "{Status:status,Result:result}" -o jsonWatch Run Until Complete
监控运行直至完成
bash
RUN_ID=<RUN_ID>
while true; do
STATUS=$(az pipelines runs show --organization "https://dev.azure.com/${org}" --project "$project" --id $RUN_ID --query status -o tsv)
RESULT=$(az pipelines runs show --organization "https://dev.azure.com/${org}" --project "$project" --id $RUN_ID --query result -o tsv)
echo "Status: $STATUS, Result: ${RESULT:-pending}"
if [ "$STATUS" == "completed" ]; then break; fi
sleep 10
donebash
RUN_ID=<RUN_ID>
while true; do
STATUS=$(az pipelines runs show --organization "https://dev.azure.com/${org}" --project "$project" --id $RUN_ID --query status -o tsv)
RESULT=$(az pipelines runs show --organization "https://dev.azure.com/${org}" --project "$project" --id $RUN_ID --query result -o tsv)
echo "Status: $STATUS, Result: ${RESULT:-pending}"
if [ "$STATUS" == "completed" ]; then break; fi
sleep 10
doneBuild Logs
构建日志
Get Build Timeline (Stages/Jobs)
获取构建时间线(Stages/Jobs)
bash
curl -s -u ":${AZURE_DEVOPS_EXT_PAT}" \
"https://dev.azure.com/${org}/${project}/_apis/build/builds/<RUN_ID>/timeline?api-version=7.1" \
| jq '.records[] | {name: .name, type: .type, state: .state, result: .result}'bash
curl -s -u ":${AZURE_DEVOPS_EXT_PAT}" \\
"https://dev.azure.com/${org}/${project}/_apis/build/builds/<RUN_ID>/timeline?api-version=7.1" \\
| jq '.records[] | {name: .name, type: .type, state: .state, result: .result}'List Build Logs
列出构建日志
bash
curl -s -u ":${AZURE_DEVOPS_EXT_PAT}" \
"https://dev.azure.com/${org}/${project}/_apis/build/builds/<RUN_ID>/logs?api-version=7.1" \
| jq '.value[] | {id: .id, type: .type, lineCount: .lineCount}'bash
curl -s -u ":${AZURE_DEVOPS_EXT_PAT}" \\
"https://dev.azure.com/${org}/${project}/_apis/build/builds/<RUN_ID>/logs?api-version=7.1" \\
| jq '.value[] | {id: .id, type: .type, lineCount: .lineCount}'Download Specific Log
下载指定日志
bash
curl -s -u ":${AZURE_DEVOPS_EXT_PAT}" \
"https://dev.azure.com/${org}/${project}/_apis/build/builds/<RUN_ID>/logs/<LOG_ID>?api-version=7.1"bash
curl -s -u ":${AZURE_DEVOPS_EXT_PAT}" \\
"https://dev.azure.com/${org}/${project}/_apis/build/builds/<RUN_ID>/logs/<LOG_ID>?api-version=7.1"Get Failed Step Logs
获取失败步骤日志
bash
curl -s -u ":${AZURE_DEVOPS_EXT_PAT}" \
"https://dev.azure.com/${org}/${project}/_apis/build/builds/<RUN_ID>/timeline?api-version=7.1" \
| jq '.records[] | select(.result == "failed") | {name: .name, log: .log.url}'bash
curl -s -u ":${AZURE_DEVOPS_EXT_PAT}" \\
"https://dev.azure.com/${org}/${project}/_apis/build/builds/<RUN_ID>/timeline?api-version=7.1" \\
| jq '.records[] | select(.result == "failed") | {name: .name, log: .log.url}'Git Operations (REST API)
Git 操作(REST API)
For programmatic Git workflows (branches, commits, pushes) without a local clone.
用于在无本地克隆的情况下执行程序化 Git 工作流(分支、提交、推送)。
Get Repository by Name
按名称获取存储库
bash
curl -s -u ":${AZURE_DEVOPS_EXT_PAT}" \
"https://dev.azure.com/${org}/${project}/_apis/git/repositories/<REPO_NAME>?api-version=7.0" \
| jq '{id: .id, name: .name, defaultBranch: .defaultBranch}'bash
curl -s -u ":${AZURE_DEVOPS_EXT_PAT}" \\
"https://dev.azure.com/${org}/${project}/_apis/git/repositories/<REPO_NAME>?api-version=7.0" \\
| jq '{id: .id, name: .name, defaultBranch: .defaultBranch}'Get Branch Refs
获取分支引用
bash
curl -s -u ":${AZURE_DEVOPS_EXT_PAT}" \
"https://dev.azure.com/${org}/${project}/_apis/git/repositories/<REPO_NAME>/refs?filter=heads/main&api-version=7.0" \
| jq '.value[] | {name: .name, objectId: .objectId}'bash
curl -s -u ":${AZURE_DEVOPS_EXT_PAT}" \\
"https://dev.azure.com/${org}/${project}/_apis/git/repositories/<REPO_NAME>/refs?filter=heads/main&api-version=7.0" \\
| jq '.value[] | {name: .name, objectId: .objectId}'Get Main Branch Commit SHA
获取主分支 Commit SHA
bash
curl -s -u ":${AZURE_DEVOPS_EXT_PAT}" \
"https://dev.azure.com/${org}/${project}/_apis/git/repositories/<REPO_NAME>/refs?filter=heads/main&api-version=7.0" \
| jq -r '.value[0].objectId'bash
curl -s -u ":${AZURE_DEVOPS_EXT_PAT}" \\
"https://dev.azure.com/${org}/${project}/_apis/git/repositories/<REPO_NAME>/refs?filter=heads/main&api-version=7.0" \\
| jq -r '.value[0].objectId'Create Branch from Main
从 main 创建分支
bash
MAIN_SHA=$(curl -s -u ":${AZURE_DEVOPS_EXT_PAT}" \
"https://dev.azure.com/${org}/${project}/_apis/git/repositories/<REPO_NAME>/refs?filter=heads/main&api-version=7.0" \
| jq -r '.value[0].objectId')
curl -s -u ":${AZURE_DEVOPS_EXT_PAT}" -X POST \
"https://dev.azure.com/${org}/${project}/_apis/git/repositories/<REPO_NAME>/refs?api-version=7.0" \
-H "Content-Type: application/json" \
-d '[{"name": "refs/heads/<BRANCH_NAME>", "oldObjectId": "0000000000000000000000000000000000000000", "newObjectId": "'${MAIN_SHA}'"}]'bash
MAIN_SHA=$(curl -s -u ":${AZURE_DEVOPS_EXT_PAT}" \\
"https://dev.azure.com/${org}/${project}/_apis/git/repositories/<REPO_NAME>/refs?filter=heads/main&api-version=7.0" \\
| jq -r '.value[0].objectId')
curl -s -u ":${AZURE_DEVOPS_EXT_PAT}" -X POST \\
"https://dev.azure.com/${org}/${project}/_apis/git/repositories/<REPO_NAME>/refs?api-version=7.0" \\
-H "Content-Type: application/json" \\
-d '[{"name": "refs/heads/<BRANCH_NAME>", "oldObjectId": "0000000000000000000000000000000000000000", "newObjectId": "'${MAIN_SHA}'"}]'Delete Branch
删除分支
bash
curl -s -u ":${AZURE_DEVOPS_EXT_PAT}" -X POST \
"https://dev.azure.com/${org}/${project}/_apis/git/repositories/<REPO_NAME>/refs?api-version=7.0" \
-H "Content-Type: application/json" \
-d '[{"name": "refs/heads/<BRANCH_NAME>", "oldObjectId": "<LAST_COMMIT_SHA>", "newObjectId": "0000000000000000000000000000000000000000"}]'bash
curl -s -u ":${AZURE_DEVOPS_EXT_PAT}" -X POST \\
"https://dev.azure.com/${org}/${project}/_apis/git/repositories/<REPO_NAME>/refs?api-version=7.0" \\
-H "Content-Type: application/json" \\
-d '[{"name": "refs/heads/<BRANCH_NAME>", "oldObjectId": "<LAST_COMMIT_SHA>", "newObjectId": "0000000000000000000000000000000000000000"}]'Push a Commit (Add/Edit Files)
推送提交(添加/编辑文件)
bash
curl -s -u ":${AZURE_DEVOPS_EXT_PAT}" -X POST \
"https://dev.azure.com/${org}/${project}/_apis/git/repositories/<REPO_NAME>/pushes?api-version=7.0" \
-H "Content-Type: application/json" \
-d '{
"refUpdates": [{"name": "refs/heads/<BRANCH_NAME>", "oldObjectId": "<BASE_COMMIT_SHA>"}],
"commits": [{
"comment": "Commit message here",
"changes": [
{
"changeType": "edit",
"item": {"path": "/path/to/file"},
"newContent": {"content": "file content here", "contentType": "rawtext"}
}
]
}]
}'bash
curl -s -u ":${AZURE_DEVOPS_EXT_PAT}" -X POST \\
"https://dev.azure.com/${org}/${project}/_apis/git/repositories/<REPO_NAME>/pushes?api-version=7.0" \\
-H "Content-Type: application/json" \\
-d '{
"refUpdates": [{"name": "refs/heads/<BRANCH_NAME>", "oldObjectId": "<BASE_COMMIT_SHA>"}],
"commits": [{
"comment": "Commit message here",
"changes": [
{
"changeType": "edit",
"item": {"path": "/path/to/file"},
"newContent": {"content": "file content here", "contentType": "rawtext"}
}
]
}]
}'Push Initial Commit (New Repository)
推送初始提交(新存储库)
bash
curl -s -u ":${AZURE_DEVOPS_EXT_PAT}" -X POST \
"https://dev.azure.com/${org}/${project}/_apis/git/repositories/<REPO_NAME>/pushes?api-version=7.0" \
-H "Content-Type: application/json" \
-d '{
"refUpdates": [{"name": "refs/heads/main", "oldObjectId": "0000000000000000000000000000000000000000"}],
"commits": [{
"comment": "Initial commit",
"changes": [
{
"changeType": "add",
"item": {"path": "/README.md"},
"newContent": {"content": "# Repo Title", "contentType": "rawtext"}
}
]
}]
}'bash
curl -s -u ":${AZURE_DEVOPS_EXT_PAT}" -X POST \\
"https://dev.azure.com/${org}/${project}/_apis/git/repositories/<REPO_NAME>/pushes?api-version=7.0" \\
-H "Content-Type: application/json" \\
-d '{
"refUpdates": [{"name": "refs/heads/main", "oldObjectId": "0000000000000000000000000000000000000000"}],
"commits": [{
"comment": "Initial commit",
"changes": [
{
"changeType": "add",
"item": {"path": "/README.md"},
"newContent": {"content": "# Repo Title", "contentType": "rawtext"}
}
]
}]
}'Push with Base64-Encoded Content
推送 Base64 编码内容
bash
CONTENT_B64=$(echo -n "file contents here" | base64)
curl -s -u ":${AZURE_DEVOPS_EXT_PAT}" -X POST \
"https://dev.azure.com/${org}/${project}/_apis/git/repositories/<REPO_NAME>/pushes?api-version=7.0" \
-H "Content-Type: application/json" \
-d '{
"refUpdates": [{"name": "refs/heads/<BRANCH>", "oldObjectId": "<SHA>"}],
"commits": [{
"comment": "Add file",
"changes": [{
"changeType": "add",
"item": {"path": "/file.txt"},
"newContent": {"content": "'${CONTENT_B64}'", "contentType": "base64encoded"}
}]
}]
}'bash
CONTENT_B64=$(echo -n "file contents here" | base64)
curl -s -u ":${AZURE_DEVOPS_EXT_PAT}" -X POST \\
"https://dev.azure.com/${org}/${project}/_apis/git/repositories/<REPO_NAME>/pushes?api-version=7.0" \\
-H "Content-Type: application/json" \\
-d '{
"refUpdates": [{"name": "refs/heads/<BRANCH>", "oldObjectId": "<SHA>"}],
"commits": [{
"comment": "Add file",
"changes": [{
"changeType": "add",
"item": {"path": "/file.txt"},
"newContent": {"content": "'${CONTENT_B64}'", "contentType": "base64encoded"}
}]
}]
}'Pull Requests (REST API)
Pull Requests(REST API)
Alternative to commands when more control is needed.
az repos pr当需要更多控制时,可替代 命令。
az repos prCreate
创建
bash
curl -s -u ":${AZURE_DEVOPS_EXT_PAT}" -X POST \
"https://dev.azure.com/${org}/${project}/_apis/git/repositories/<REPO_NAME>/pullrequests?api-version=7.0" \
-H "Content-Type: application/json" \
-d '{
"sourceRefName": "refs/heads/<SOURCE_BRANCH>",
"targetRefName": "refs/heads/main",
"title": "PR Title",
"description": "PR description"
}' | jq '{pullRequestId: .pullRequestId, status: .status}'bash
curl -s -u ":${AZURE_DEVOPS_EXT_PAT}" -X POST \\
"https://dev.azure.com/${org}/${project}/_apis/git/repositories/<REPO_NAME>/pullrequests?api-version=7.0" \\
-H "Content-Type: application/json" \\
-d '{
"sourceRefName": "refs/heads/<SOURCE_BRANCH>",
"targetRefName": "refs/heads/main",
"title": "PR Title",
"description": "PR description"
}' | jq '{pullRequestId: .pullRequestId, status: .status}'Get Details
获取详细信息
bash
curl -s -u ":${AZURE_DEVOPS_EXT_PAT}" \
"https://dev.azure.com/${org}/${project}/_apis/git/repositories/<REPO_NAME>/pullRequests/<PR_ID>?api-version=7.0" \
| jq '{id: .pullRequestId, title: .title, status: .status, sourceRefName: .sourceRefName}'bash
curl -s -u ":${AZURE_DEVOPS_EXT_PAT}" \\
"https://dev.azure.com/${org}/${project}/_apis/git/repositories/<REPO_NAME>/pullRequests/<PR_ID>?api-version=7.0" \\
| jq '{id: .pullRequestId, title: .title, status: .status, sourceRefName: .sourceRefName}'List
列出
bash
curl -s -u ":${AZURE_DEVOPS_EXT_PAT}" \
"https://dev.azure.com/${org}/${project}/_apis/git/repositories/<REPO_NAME>/pullrequests?api-version=7.0" \
| jq '.value[] | {id: .pullRequestId, title: .title, status: .status}'bash
curl -s -u ":${AZURE_DEVOPS_EXT_PAT}" \\
"https://dev.azure.com/${org}/${project}/_apis/git/repositories/<REPO_NAME>/pullrequests?api-version=7.0" \\
| jq '.value[] | {id: .pullRequestId, title: .title, status: .status}'Abandon
放弃
bash
curl -s -u ":${AZURE_DEVOPS_EXT_PAT}" -X PATCH \
"https://dev.azure.com/${org}/${project}/_apis/git/repositories/<REPO_NAME>/pullRequests/<PR_ID>?api-version=7.0" \
-H "Content-Type: application/json" \
-d '{"status": "abandoned"}'bash
curl -s -u ":${AZURE_DEVOPS_EXT_PAT}" -X PATCH \\
"https://dev.azure.com/${org}/${project}/_apis/git/repositories/<REPO_NAME>/pullRequests/<PR_ID>?api-version=7.0" \\
-H "Content-Type: application/json" \\
-d '{"status": "abandoned"}'Complete (Merge)
完成(合并)
bash
curl -s -u ":${AZURE_DEVOPS_EXT_PAT}" -X PATCH \
"https://dev.azure.com/${org}/${project}/_apis/git/repositories/<REPO_NAME>/pullRequests/<PR_ID>?api-version=7.0" \
-H "Content-Type: application/json" \
-d '{
"status": "completed",
"lastMergeSourceCommit": {"commitId": "<LAST_COMMIT_SHA>"},
"completionOptions": {"deleteSourceBranch": true, "mergeStrategy": "squash"}
}'bash
curl -s -u ":${AZURE_DEVOPS_EXT_PAT}" -X PATCH \\
"https://dev.azure.com/${org}/${project}/_apis/git/repositories/<REPO_NAME>/pullRequests/<PR_ID>?api-version=7.0" \\
-H "Content-Type: application/json" \\
-d '{
"status": "completed",
"lastMergeSourceCommit": {"commitId": "<LAST_COMMIT_SHA>"},
"completionOptions": {"deleteSourceBranch": true, "mergeStrategy": "squash"}
}'Code Search (REST API)
代码搜索(REST API)
Search code across repositories. Uses the host, not .
almsearch.dev.azure.comdev.azure.com跨存储库搜索代码。使用 主机,而不是 。
almsearch.dev.azure.comdev.azure.comSearch in Project
在项目中搜索
bash
curl -s -u ":${AZURE_DEVOPS_EXT_PAT}" -X POST \
"https://almsearch.dev.azure.com/${org}/${project}/_apis/search/codesearchresults?api-version=7.1" \
-H "Content-Type: application/json" \
-d '{"searchText":"<TEXT>","$top":25}' \
| jq '{count: .count, results: [.results[] | {repo: .repository.name, path: .path}]}'bash
curl -s -u ":${AZURE_DEVOPS_EXT_PAT}" -X POST \\
"https://almsearch.dev.azure.com/${org}/${project}/_apis/search/codesearchresults?api-version=7.1" \\
-H "Content-Type: application/json" \\
-d '{"searchText":"<TEXT>","$top":25}' \\
| jq '{count: .count, results: [.results[] | {repo: .repository.name, path: .path}]}'Search Across Org with Filters
使用过滤器跨组织搜索
bash
curl -s -u ":${AZURE_DEVOPS_EXT_PAT}" -X POST \
"https://almsearch.dev.azure.com/${org}/_apis/search/codesearchresults?api-version=7.1" \
-H "Content-Type: application/json" \
-d '{
"searchText":"<TEXT>",
"filters":{"Project":["<PROJECT>"],"Repository":["<REPO>"],"Branch":["main"],"Path":["/src"]},
"$top":25
}' \
| jq '.results[] | {project: .project.name, repo: .repository.name, path: .path}'Available filter keys: , , , , (e.g. ).
ProjectRepositoryBranchPathCodeElement["def","class"]bash
curl -s -u ":${AZURE_DEVOPS_EXT_PAT}" -X POST \\
"https://almsearch.dev.azure.com/${org}/_apis/search/codesearchresults?api-version=7.1" \\
-H "Content-Type: application/json" \\
-d '{
"searchText":"<TEXT>",
"filters":{"Project":["<PROJECT>"],"Repository":["<REPO>"],"Branch":["main"],"Path":["/src"]},
"$top":25
}' \\
| jq '.results[] | {project: .project.name, repo: .repository.name, path: .path}'可用过滤器键:、、、、(例如 )。
ProjectRepositoryBranchPathCodeElement["def","class"]Search Operators
搜索运算符
The field accepts ADO search syntax:
searchText- -- file extension filter
ext:go quiver-bolt - -- filename filter
file:Makefile quiver-bolt - -- function/method definitions
def:MyFunction - -- exact match
"exact phrase" - ,
foo AND bar,foo OR bar-- booleanfoo NOT bar
searchText- —— 文件扩展名过滤
ext:go quiver-bolt - —— 文件名过滤
file:Makefile quiver-bolt - —— 函数/方法定义
def:MyFunction - —— 精确匹配
"exact phrase" - 、
foo AND bar、foo OR bar—— 布尔运算foo NOT bar
Webhooks (REST API)
Webhooks(REST API)
List Service Hooks
列出 Service Hooks
bash
curl -s -u ":${AZURE_DEVOPS_EXT_PAT}" \
"https://dev.azure.com/${org}/_apis/hooks/subscriptions?api-version=7.0" \
| jq '.value[] | {id: .id, eventType: .eventType, consumerActionId: .consumerActionId, publisherInputs: .publisherInputs}'bash
curl -s -u ":${AZURE_DEVOPS_EXT_PAT}" \\
"https://dev.azure.com/${org}/_apis/hooks/subscriptions?api-version=7.0" \\
| jq '.value[] | {id: .id, eventType: .eventType, consumerActionId: .consumerActionId, publisherInputs: .publisherInputs}'Create Webhook for PR Events
为 PR 事件创建 Webhook
bash
curl -s -u ":${AZURE_DEVOPS_EXT_PAT}" -X POST \
"https://dev.azure.com/${org}/_apis/hooks/subscriptions?api-version=7.0" \
-H "Content-Type: application/json" \
-d '{
"publisherId": "tfs",
"eventType": "git.pullrequest.created",
"resourceVersion": "1.0",
"consumerId": "webHooks",
"consumerActionId": "httpRequest",
"publisherInputs": {
"projectId": "<PROJECT_ID>",
"repository": "<REPO_ID>"
},
"consumerInputs": {
"url": "<WEBHOOK_URL>"
}
}'bash
curl -s -u ":${AZURE_DEVOPS_EXT_PAT}" -X POST \\
"https://dev.azure.com/${org}/_apis/hooks/subscriptions?api-version=7.0" \\
-H "Content-Type: application/json" \\
-d '{
"publisherId": "tfs",
"eventType": "git.pullrequest.created",
"resourceVersion": "1.0",
"consumerId": "webHooks",
"consumerActionId": "httpRequest",
"publisherInputs": {
"projectId": "<PROJECT_ID>",
"repository": "<REPO_ID>"
},
"consumerInputs": {
"url": "<WEBHOOK_URL>"
}
}'Delete Webhook
删除 Webhook
bash
curl -s -u ":${AZURE_DEVOPS_EXT_PAT}" -X DELETE \
"https://dev.azure.com/${org}/_apis/hooks/subscriptions/<SUBSCRIPTION_ID>?api-version=7.0"bash
curl -s -u ":${AZURE_DEVOPS_EXT_PAT}" -X DELETE \\
"https://dev.azure.com/${org}/_apis/hooks/subscriptions/<SUBSCRIPTION_ID>?api-version=7.0"Diagnostics
诊断
Check ADO Infrastructure Health
检查 ADO 基础设施运行状况
bash
echo "=== Service Connections ==="
az devops service-endpoint list --organization "https://dev.azure.com/${org}" --project "$project" --query "[].{Name:name,Type:type}" -o table
echo ""
echo "=== Agent Pools ==="
az pipelines pool list --organization "https://dev.azure.com/${org}" --query "[].{Name:name,Size:size,IsHosted:isHosted}" -o table
echo ""
echo "=== Queues ==="
az pipelines queue list --organization "https://dev.azure.com/${org}" --project "$project" --query "[].{Name:name,QueueID:id}" -o tablebash
echo "=== Service Connections ==="
az devops service-endpoint list --organization "https://dev.azure.com/${org}" --project "$project" --query "[].{Name:name,Type:type}" -o table
echo ""
echo "=== Agent Pools ==="
az pipelines pool list --organization "https://dev.azure.com/${org}" --query "[].{Name:name,Size:size,IsHosted:isHosted}" -o table
echo ""
echo "=== Queues ==="
az pipelines queue list --organization "https://dev.azure.com/${org}" --project "$project" --query "[].{Name:name,QueueID:id}" -o tableCheck Agents in a Pool
检查 Pool 中的 Agent
bash
POOL_ID=$(az pipelines pool list --organization "https://dev.azure.com/${org}" --query "[?name=='<POOL_NAME>'].id" -o tsv)
if [ -n "$POOL_ID" ]; then
az pipelines agent list --organization "https://dev.azure.com/${org}" --pool-id $POOL_ID --query "[].{Name:name,Status:status}" -o table
fibash
POOL_ID=$(az pipelines pool list --organization "https://dev.azure.com/${org}" --query "[?name=='<POOL_NAME>'].id" -o tsv)
if [ -n "$POOL_ID" ]; then
az pipelines agent list --organization "https://dev.azure.com/${org}" --pool-id $POOL_ID --query "[].{Name:name,Status:status}" -o table
fiWait for Agents to Come Online
等待 Agent 上线
bash
POOL_ID=$(az pipelines pool list --organization "https://dev.azure.com/${org}" --query "[?name=='<POOL_NAME>'].id" -o tsv)
MAX_WAIT=300
ELAPSED=0
while [ $ELAPSED -lt $MAX_WAIT ]; do
ONLINE=$(az pipelines agent list --organization "https://dev.azure.com/${org}" --pool-id $POOL_ID --query "[?status=='online']" -o tsv | wc -l)
if [ "$ONLINE" -gt 0 ]; then
echo "Found $ONLINE online agent(s)"
break
fi
echo "Waiting for agents... ($ELAPSED/${MAX_WAIT}s)"
sleep 10
ELAPSED=$((ELAPSED + 10))
donebash
POOL_ID=$(az pipelines pool list --organization "https://dev.azure.com/${org}" --query "[?name=='<POOL_NAME>'].id" -o tsv)
MAX_WAIT=300
ELAPSED=0
while [ $ELAPSED -lt $MAX_WAIT ]; do
ONLINE=$(az pipelines agent list --organization "https://dev.azure.com/${org}" --pool-id $POOL_ID --query "[?status=='online']" -o tsv | wc -l)
if [ "$ONLINE" -gt 0 ]; then
echo "Found $ONLINE online agent(s)"
break
fi
echo "Waiting for agents... ($ELAPSED/${MAX_WAIT}s)"
sleep 10
ELAPSED=$((ELAPSED + 10))
doneKey Concepts
核心概念
Pool vs Queue
Pool 与 Queue
- Pools are organization-level (shared across projects)
- Queues are project-level references to pools
- Pipeline authorization works on queues, not pools
- Pools 属于组织级别(跨项目共享)
- Queues 是对 Pool 的项目级引用
- Pipeline 授权作用于 queues,而不是 pools
Workload Identity Federation
Workload Identity Federation
Service connections use WIF (OIDC). No secrets stored in ADO. Federated credentials are managed in App Registration.
Service Connections 使用 WIF(OIDC)。ADO 中不会存储 Secret。联合凭据由 App Registration 管理。
REST API vs CLI
REST API 与 CLI
Some operations require REST API (no CLI equivalent):
- Creating pools with specific settings
- Authorizing queues for pipelines
- Querying WIF subjects from service connections
- Git push operations (branches, commits)
- PR comment threads
- Webhooks
有些操作必须使用 REST API(没有等效的 CLI 命令):
- 使用特定设置创建 Pools
- 为 Pipelines 授权 Queues
- 查询 Service Connections 中的 WIF subject
- Git push 操作(分支、提交)
- PR 评论线程
- Webhooks