You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何自动化删除GitLab群组6中tobedeleted_开头且创建超30天的分支?

自动化清理GitLab中指定规则的旧分支方案

嘿,我来帮你搞定这个自动化清理分支的需求!你已经掌握了基础的cURL命令,现在只需要把这些步骤串起来,写个Shell脚本就能实现全流程自动化,不管是用Jenkins还是GitLab定时任务都能直接调度执行。

一、完整Shell脚本实现

我推荐用jq来解析JSON(比sed/awk处理JSON可靠得多,避免特殊字符导致的解析错误),先确保你的执行环境安装了jqcurlcoreutils(处理时间用)。下面是完整脚本:

#!/bin/bash

# -------------------------- 配置参数 --------------------------
GITLAB_API_URL="$CI_API_V4_URL"  # 直接复用CI环境变量,本地测试可替换为你的GitLab API地址
PRIVATE_TOKEN="<your_private_token>"  # 替换成你的GitLab私人令牌
GROUP_ID=6  # 目标群组ID
EXPIRE_DAYS=30  # 过期天数,这里设为30天
# -------------------------------------------------------------

# 计算30天前的时间戳(秒级),用于对比分支创建时间
EXPIRE_TIMESTAMP=$(date -d "-$EXPIRE_DAYS days" +%s)

# -------------------------- 处理项目分页 --------------------------
# 如果群组下项目超过100个,自动遍历所有分页获取项目ID
PAGE=1
PROJECT_IDS=""
while true; do
    RESPONSE=$(curl -s --header "PRIVATE-TOKEN: $PRIVATE_TOKEN" "$GITLAB_API_URL/groups/$GROUP_ID/projects?per_page=100&page=$PAGE")
    # 若返回空数组,说明已遍历完所有分页
    if [ "$(echo "$RESPONSE" | jq 'length')" -eq 0 ]; then
        break
    fi
    PROJECT_IDS="$PROJECT_IDS $(echo "$RESPONSE" | jq -r '.[].id')"
    PAGE=$((PAGE+1))
done
# ----------------------------------------------------------------

# 遍历每个项目,清理符合条件的分支
for PROJECT_ID in $PROJECT_IDS; do
    echo "=== 开始处理项目ID: $PROJECT_ID ==="
    
    # -------------------------- 处理分支分页 --------------------------
    BRANCH_PAGE=1
    BRANCHES=""
    while true; do
        BRANCH_RESPONSE=$(curl -s --header "PRIVATE-TOKEN: $PRIVATE_TOKEN" "$GITLAB_API_URL/projects/$PROJECT_ID/repository/branches?per_page=100&page=$BRANCH_PAGE")
        if [ "$(echo "$BRANCH_RESPONSE" | jq 'length')" -eq 0 ]; then
            break
        fi
        # 筛选:名称以tobedeleted_开头 + 创建时间超过30天的分支
        BRANCHES="$BRANCHES $(echo "$BRANCH_RESPONSE" | jq -r --arg ts "$EXPIRE_TIMESTAMP" '
            .[] | 
            select(.name | startswith("tobedeleted_")) | 
            select((.created_at | sub("\\.[0-9]+Z$"; "") | strptime("%Y-%m-%dT%H:%M:%S") | mktime) <= $ts) | 
            .name
        ')"
        BRANCH_PAGE=$((BRANCH_PAGE+1))
    done
    # ----------------------------------------------------------------

    # 删除符合条件的分支
    for BRANCH in $BRANCHES; do
        echo "正在删除分支: $BRANCH"
        DELETE_RESPONSE=$(curl -s -w "%{http_code}" --request DELETE --header "PRIVATE-TOKEN: $PRIVATE_TOKEN" "$GITLAB_API_URL/projects/$PROJECT_ID/repository/branches/$BRANCH")
        HTTP_CODE=$(echo "$DELETE_RESPONSE" | tail -n1)
        if [ "$HTTP_CODE" -eq 200 ]; then
            echo "✅ 成功删除分支: $BRANCH"
        else
            echo "❌ 删除失败,HTTP状态码: $HTTP_CODE,分支: $BRANCH"
        fi
        # 添加1秒延迟,避免触发GitLab API速率限制
        sleep 1
    done
done

二、脚本关键逻辑说明

  1. 参数配置区:把可变参数放在开头,方便后续修改维护,比如调整过期天数、切换目标群组。
  2. 分页处理:GitLab API默认每页最多返回100条数据,脚本自动遍历所有分页,确保不会遗漏项目或分支。
  3. 分支筛选规则
    • startswith("tobedeleted_")精准匹配分支命名规则
    • 把GitLab返回的created_at格式(如2024-01-01T12:00:00.000Z)转换为时间戳,和30天前的时间戳对比,确保只删除旧分支
  4. 删除反馈:捕获HTTP状态码,明确显示删除结果,方便排查问题。

三、在Jenkins/GitLab CI中调度

GitLab CI定时执行

在项目根目录创建.gitlab-ci.yml,添加以下内容:

cleanup_old_branches:
  image: alpine:latest
  before_script:
    - apk add --no-cache curl jq coreutils  # 安装依赖工具
  script:
    - chmod +x cleanup_branches.sh
    - ./cleanup_branches.sh
  only:
    - schedules  # 仅在定时任务触发时执行

然后在GitLab项目的「CI/CD → 定时任务」中创建定时规则(比如每月1号凌晨执行)。

Jenkins定时执行

  1. 创建一个自由风格项目
  2. 添加「执行Shell」步骤,粘贴脚本内容(或拉取脚本文件)
  3. 在「构建触发器」中选择「Build periodically」,填写cron表达式(比如0 0 1 * *表示每月1号凌晨执行)
  4. 确保Jenkins服务器已安装curljqcoreutils

四、安全测试建议

  • 测试先行:先在测试环境执行脚本,或者暂时把删除命令改成echo "模拟删除: $BRANCH",确认筛选出的分支符合预期,避免误删。
  • 权限检查:确保你的GitLab私人令牌拥有目标项目的分支删除权限(至少需要Maintainer角色)。
  • 日志记录:把脚本输出重定向到日志文件,方便后续排查,比如./cleanup_branches.sh >> cleanup_logs.txt 2>&1

内容的提问来源于stack exchange,提问作者Sameer Atharkar

火山引擎 最新活动