Azure DevOps指定用户创建PR绕过分支策略自动完成的Bash方案
Azure DevOps 特定授权用户PR自动绕过策略+自动完成实现方案(Bash任务版)
前置准备
- 提前创建有代码读写、PR管理权限的个人访问令牌(PAT),权限勾选
Code (Read & write)、Pull Request Threads (Read & write),将PAT存入流水线机密变量,变量名设为AZURE_DEVOPS_PAT,不要在脚本里明文写令牌 - 整理需要授权自动放行的用户邮箱列表,后续直接维护在脚本的白名单数组里即可
- 调整目标分支的保护策略:将构建验证、工作项关联等原有校验策略从「强制必过」改为可选,避免API层面的绕过逻辑失效
核心实现逻辑
- 把该Bash任务放在PR流水线的第一个执行步骤,流水线触发条件设为PR创建时自动触发
- 脚本运行后首先拉取当前PR的创建者信息,匹配白名单列表
- 匹配到授权用户时,直接调用Azure DevOps原生REST API更新PR配置,开启绕过分支策略开关,同时设置PR为自动完成状态
- 未匹配到授权用户时,不做额外操作,流水线正常执行后续构建、校验流程
可直接使用的Bash任务代码
#!/bin/bash set -euo pipefail # -------------------------- 可自定义配置区域 -------------------------- # 授权白名单用户邮箱,替换为实际需要放行的用户即可 ALLOWED_USERS=("dev-lead@yourcompany.com" "ops-admin@yourcompany.com") # PR自动完成后的配置:是否删除源分支、合并提交信息、合并策略 DELETE_SOURCE_BRANCH_AFTER_MERGE=true MERGE_COMMIT_MESSAGE="Authorized user PR auto-completed, bypass policy" # 合并策略:1=无快进合并 2=压缩合并 3=变基+快进 MERGE_STRATEGY=2 BYPASS_REASON="授权白名单用户自动放行,跳过构建校验流程" # --------------------------------------------------------------------- # 从流水线注入的环境变量取上下文参数,无需手动修改 ORG_URL=$(echo "$SYSTEM_TEAMFOUNDATIONCOLLECTIONURI" | sed 's/\/$//') PROJECT_NAME="$SYSTEM_TEAMPROJECT" PR_ID="$SYSTEM_PULLREQUEST_PULLREQUESTID" PAT="$AZURE_DEVOPS_PAT" # 构造API鉴权头 BASIC_AUTH=$(echo -n ":$PAT" | base64 -w 0) DEFAULT_HEADER=(-H "Authorization: Basic $BASIC_AUTH") JSON_HEADER=("${DEFAULT_HEADER[@]}" -H "Content-Type: application/json") # 拉取当前PR的基础信息 PR_DETAILS=$(curl -s "${DEFAULT_HEADER[@]}" "$ORG_URL/$PROJECT_NAME/_apis/git/pullrequests/$PR_ID?api-version=7.1") PR_CREATOR_EMAIL=$(echo "$PR_DETAILS" | jq -r '.createdBy.uniqueName') PR_CREATOR_ID=$(echo "$PR_DETAILS" | jq -r '.createdBy.id') PR_REPO_ID=$(echo "$PR_DETAILS" | jq -r '.repository.id') # 校验当前PR创建者是否在白名单内 IS_AUTHORIZED=0 for user in "${ALLOWED_USERS[@]}"; do if [ "$user" = "$PR_CREATOR_EMAIL" ]; then IS_AUTHORIZED=1 break fi done if [ $IS_AUTHORIZED -eq 1 ]; then echo "✅ 检测到当前PR创建者[$PR_CREATOR_EMAIL]为授权用户,将绕过分支策略并设置自动完成" # 构造更新PR的请求体 REQUEST_PAYLOAD=$(jq -n \ --arg creator_id "$PR_CREATOR_ID" \ --argjson bypass_policy true \ --arg bypass_reason "$BYPASS_REASON" \ --argjson delete_source "$DELETE_SOURCE_BRANCH_AFTER_MERGE" \ --arg commit_msg "$MERGE_COMMIT_MESSAGE" \ --argjson merge_strategy "$MERGE_STRATEGY" \ '{ autoCompleteSetBy: {id: $creator_id}, completionOptions: { bypassPolicy: $bypass_policy, bypassReason: $bypass_reason, deleteSourceBranch: $delete_source, mergeCommitMessage: $commit_msg, mergeStrategy: $merge_strategy, transitionWorkItems: true } }' ) # 发送请求更新PR配置 curl -s -X PATCH "${JSON_HEADER[@]}" -d "$REQUEST_PAYLOAD" "$ORG_URL/$PROJECT_NAME/_apis/git/repositories/$PR_REPO_ID/pullrequests/$PR_ID?api-version=7.1" echo "✅ PR自动完成配置已生效,所有分支策略将被绕过,满足基础条件后将自动合入目标分支" else echo "ℹ️ 当前PR创建者[$PR_CREATOR_EMAIL]不在授权白名单内,将正常执行全量分支校验流程" fi
注意事项
- 脚本依赖
jq工具做JSON解析,微软官方托管的Ubuntu、Windows、macOS代理默认预装该工具;如果使用自托管代理,需要提前在代理机器上安装jq并加入环境变量 - 存储PAT的流水线变量必须勾选「机密」选项,避免令牌被打印到流水线日志造成泄露;PAT只分配必要的最小权限即可,不要开多余的组织级权限
- 如果需要叠加其他放行规则,比如仅放行hotfix分支发起的PR、仅放行特定目录改动的PR,直接在白名单判断的逻辑块里补充对应判断条件即可
- 自动完成触发后,PR会在所有可选策略(如果有)跑完后自动合入,如果需要完全跳过所有流水线直接合入,可以在API请求里额外加参数终止当前正在运行的流水线即可
内容的提问来源于stack exchange,提问作者MIHIR UPADHYAY
相关产品推荐
相关产品推荐

