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 "========================================"
相关推荐
有理想的打工人11 小时前
gitlab的参数设置与团队管理
gitlab
有理想的打工人13 小时前
gitlab群组管理与ssh链接
ssh·gitlab
M-Ellen14 小时前
从零搭建 Windows + WSL2 + Docker + GitLab CI/CD 完整手册
ci/cd·docker·gitlab
大脸胖柴1 天前
webStorm+gitLab操作学习
学习·gitlab·webstorm
jekc8683 天前
Ubuntu-GitLab
服务器·ubuntu·gitlab
在路上走着走着3 天前
openclaw v2026.4.5 版本 提示 pairing required 解决方案
gitlab
Gazer_S8 天前
【GitLab npm Registry 非标准端口安装问题解决方案】
前端·npm·gitlab
-KamMinG8 天前
Gitlab版本升级方案-13.x到17.x
gitlab
菜鸡000110 天前
把一个项目传到 GitLab 的某个群组
大数据·elasticsearch·gitlab
AlbertS10 天前
记一次推送lfs失败不能迁移git仓库到新的gitlab的问题
git·ai·gitlab·lfs·rejected