gitlab 仓库所有分支开启分支保护脚本

bash 复制代码
#!/bin/bash
# 批量为目标 GitLab 所有项目的默认分支开启 protected branch 保护
# 保护规则:禁止 force push,只有 Maintainer 可以 push 和 merge

set -euo pipefail

# ===================== 配置项 =====================
DST_GITLAB_URL="https://127.0.0.1"
DST_ACCESS_TOKEN="yehMwepEcx8ivwd2ewd"
PER_PAGE=100
# 保护级别:
#   40 = Maintainer
#   30 = Developer
#   0  = No one
PUSH_ACCESS_LEVEL=40
MERGE_ACCESS_LEVEL=40
ALLOW_FORCE_PUSH=false
# ==================================================

echo "========================================"
echo "批量开启目标 GitLab 项目的分支保护"
echo "目标 GitLab: $DST_GITLAB_URL"
echo "保护规则: push=${PUSH_ACCESS_LEVEL}(Maintainer), merge=${MERGE_ACCESS_LEVEL}(Maintainer), force_push=${ALLOW_FORCE_PUSH}"
echo "========================================"
echo ""

PAGE=1
TOTAL=0
SUCCESS=0
SKIP=0
FAIL=0

while true; do
    # 获取项目列表(分页)
    projects=$(curl -s -k \
        --header "PRIVATE-TOKEN: $DST_ACCESS_TOKEN" \
        "$DST_GITLAB_URL/api/v4/projects?per_page=$PER_PAGE&page=$PAGE&membership=true")

    # 检查是否还有项目
    count=$(echo "$projects" | jq 'length')
    if [ "$count" -eq 0 ] 2>/dev/null; then
        break
    fi

    echo "$projects" | jq -c '.[]' | while IFS= read -r proj; do
        proj_id=$(echo "$proj" | jq -r '.id')
        proj_name=$(echo "$proj" | jq -r '.path_with_namespace')
        default_branch=$(echo "$proj" | jq -r '.default_branch')

        TOTAL=$((TOTAL + 1))

        if [ -z "$default_branch" ] || [ "$default_branch" = "null" ]; then
            echo "  [跳过] $proj_name - 无默认分支(空仓库)"
            SKIP=$((SKIP + 1))
            continue
        fi

        # 检查该分支是否已被保护
        check=$(curl -s -k \
            --header "PRIVATE-TOKEN: $DST_ACCESS_TOKEN" \
            "$DST_GITLAB_URL/api/v4/projects/$proj_id/protected_branches/$default_branch")

        if echo "$check" | jq -e '.name' > /dev/null 2>&1; then
            echo "  [已保护] $proj_name ($default_branch)"
            SKIP=$((SKIP + 1))
            continue
        fi

        # 设置保护
        result=$(curl -s -k -X POST \
            --header "PRIVATE-TOKEN: $DST_ACCESS_TOKEN" \
            "$DST_GITLAB_URL/api/v4/projects/$proj_id/protected_branches" \
            --data-urlencode "name=$default_branch" \
            --data "push_access_level=$PUSH_ACCESS_LEVEL" \
            --data "merge_access_level=$MERGE_ACCESS_LEVEL" \
            --data "allow_force_push=$ALLOW_FORCE_PUSH")

        if echo "$result" | jq -e '.name' > /dev/null 2>&1; then
            echo "  [成功] $proj_name ($default_branch)"
            SUCCESS=$((SUCCESS + 1))
        else
            error_msg=$(echo "$result" | jq -r '.message // .error // "未知错误"' 2>/dev/null)
            echo "  [失败] $proj_name ($default_branch) - $error_msg"
            FAIL=$((FAIL + 1))
        fi
    done

    # 下一页
    PAGE=$((PAGE + 1))
done

echo ""
echo "========================================"
echo "执行完毕!"
echo "  - 已保护/跳过: $SKIP"
echo "  - 新增保护: $SUCCESS"
echo "  - 失败: $FAIL"
echo "========================================"
相关推荐
Aliex_git3 天前
Dockerfile 优化实践笔记
笔记·学习·gitlab
成为你的宁宁4 天前
Jenkins 自动化部署前后端分离若依项目全攻略:涵盖环境配置、Maven/Node.js 工具安装、GitLab 项目协同,及前后端构建、服务器推送与代码更新验证全步骤
node.js·自动化·gitlab·jenkins·maven
sunshinebo4 天前
一次 GitLab 无法启动的排查:Docker 日志把 500G 磁盘打满
docker·eureka·gitlab
何以不说话4 天前
DevOps、Git 和 GitLab
git·gitlab·devops
ZAEQgyKFs7 天前
永磁同步电机模型预测电流控制+滑模控制 [1]速度环采用滑模控制 滑模控制器采用新型趋近律与扰...
gitlab
马克Markorg7 天前
使用 Docker Compose 本地部署 GitLab 教程
docker·容器·gitlab
大尚来也10 天前
CI/CD 流水线搭建实战:GitHub Actions vs GitLab CI 2026 深度对比与选型指南
ci/cd·gitlab·github
ProgramHan11 天前
github、gitlab、gitee分别都是什么,为什么不能访问?
gitee·gitlab·github
Aliex_git13 天前
Gitlab Runner 配置实践
笔记·学习·ci/cd·gitlab
阿莫西林夹馍13 天前
GitLab的IP地址发生变更导致Runner掉线
gitlab