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 "========================================"
相关推荐
切糕师学AI1 天前
GitLab 是什么?
gitlab
明月心9523 天前
git remote add 用法
gitlab
only_Klein3 天前
jenkins流水线报错:Connection reset by peer
ci/cd·kubernetes·gitlab·jenkins·ssl
梁萌4 天前
docker部署gitlab和gitlab runner
docker·eureka·gitlab
johnnyAndCode4 天前
Idea 设置GitLab时使用账密,而不是token的配置方法
gitlab·idea
天外飞雨4 天前
Gitlab使用
gitlab
BUTCHER55 天前
GitLab SSH 密钥配置
运维·ssh·gitlab
明月心9525 天前
GitLab使用
gitlab
明月心9526 天前
gitlab pull requets
gitlab
BUTCHER56 天前
GitLab基本设置
gitlab