如何自动化删除GitLab群组6中tobedeleted_开头且创建超30天的分支?
自动化清理GitLab中指定规则的旧分支方案
嘿,我来帮你搞定这个自动化清理分支的需求!你已经掌握了基础的cURL命令,现在只需要把这些步骤串起来,写个Shell脚本就能实现全流程自动化,不管是用Jenkins还是GitLab定时任务都能直接调度执行。
一、完整Shell脚本实现
我推荐用jq来解析JSON(比sed/awk处理JSON可靠得多,避免特殊字符导致的解析错误),先确保你的执行环境安装了jq、curl和coreutils(处理时间用)。下面是完整脚本:
#!/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
二、脚本关键逻辑说明
- 参数配置区:把可变参数放在开头,方便后续修改维护,比如调整过期天数、切换目标群组。
- 分页处理:GitLab API默认每页最多返回100条数据,脚本自动遍历所有分页,确保不会遗漏项目或分支。
- 分支筛选规则:
- 用
startswith("tobedeleted_")精准匹配分支命名规则 - 把GitLab返回的
created_at格式(如2024-01-01T12:00:00.000Z)转换为时间戳,和30天前的时间戳对比,确保只删除旧分支
- 用
- 删除反馈:捕获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定时执行
- 创建一个自由风格项目
- 添加「执行Shell」步骤,粘贴脚本内容(或拉取脚本文件)
- 在「构建触发器」中选择「Build periodically」,填写cron表达式(比如
0 0 1 * *表示每月1号凌晨执行) - 确保Jenkins服务器已安装
curl、jq、coreutils
四、安全测试建议
- 测试先行:先在测试环境执行脚本,或者暂时把删除命令改成
echo "模拟删除: $BRANCH",确认筛选出的分支符合预期,避免误删。 - 权限检查:确保你的GitLab私人令牌拥有目标项目的分支删除权限(至少需要Maintainer角色)。
- 日志记录:把脚本输出重定向到日志文件,方便后续排查,比如
./cleanup_branches.sh >> cleanup_logs.txt 2>&1。
内容的提问来源于stack exchange,提问作者Sameer Atharkar




