Gitlab 自动化部署pre-receive

以下是针对 GitLab 仓库路径为哈希结构的自动化部署方案,提供 Jenkins Pipeline 实现Shell 脚本优化版


方案 1: Jenkins Pipeline 实现

文件结构

deploy-gitlab-hooks/
├── Jenkinsfile       # 流水线定义
└── hooks/
    └── pre-receive   # 要部署的钩子脚本

Jenkinsfile 内容

pipeline {
    agent any
    environment {
        GITLAB_REPO_ROOT = '/var/opt/gitlab/git-data/repositories'  // 根据实际路径修改
        HOOK_SOURCE = "${WORKSPACE}/hooks/pre-receive"
    }
    stages {
        stage('Prepare') {
            steps {
                script {
                    // 验证钩子文件存在
                    if (!fileExists(HOOK_SOURCE)) {
                        error "钩子文件 ${HOOK_SOURCE} 不存在"
                    }
                }
            }
        }
        stage('Deploy Hooks') {
            steps {
                script {
                    // 查找所有 .git 目录(兼容哈希结构)
                    def repoDirs = findGitRepos(GITLAB_REPO_ROOT)
                    
                    repoDirs.each { repo ->
                        dir(repo) {
                            // 创建目标目录
                            sh """
                                mkdir -p custom_hooks
                                chown git:git custom_hooks
                                cp -vf ${HOOK_SOURCE} custom_hooks/
                                chmod +x custom_hooks/pre-receive
                                chown git:git custom_hooks/pre-receive
                            """
                            echo "已部署到 ${repo}"
                        }
                    }
                }
            }
        }
    }
}

// 自定义方法:查找所有 Git 仓库
def findGitRepos(String rootPath) {
    def output = sh(
        script: "find ${rootPath} -type d -name '*.git' -print0 | xargs -0 -I {} readlink -f {}",
        returnStdout: true
    ).trim()
    return output.split('\n') as List
}

方案 2: Shell 脚本实现 (直接运行)

部署脚本 deploy_hooks.sh

1. 需要 root 或 git 用户权限执行
2. 需要在 GitLab 服务器执行
#!/bin/bash

# 配置参数
GITLAB_REPO_ROOT="/var/opt/gitlab/git-data/repositories"
HOOK_SOURCE="/path/to/pre-receive"  # 修改为实际路径
HOOK_NAME="pre-receive"

# 安全校验
if [ ! -f "$HOOK_SOURCE" ]; then
    echo "错误: 钩子文件 $HOOK_SOURCE 不存在"
    exit 1
fi

# 遍历所有 .git 目录(处理哈希结构)
find "$GITLAB_REPO_ROOT" -type d -name '*.git' -print0 | while IFS= read -r -d '' git_dir; do
    # 跳过非仓库目录
    [ ! -d "$git_dir/objects" ] && continue

    # 创建目标目录
    hook_dir="${git_dir}/custom_hooks"
    [ ! -d "$hook_dir" ] && mkdir -p "$hook_dir"
    
    # 部署钩子
    hook_target="${hook_dir}/${HOOK_NAME}"
    if [ -e "$hook_target" ]; then
        echo "[WARN] 已存在钩子: $hook_target (跳过)"
    else
        cp -v "$HOOK_SOURCE" "$hook_target"
        chmod +x "$hook_target"
        chown -R git:git "$hook_dir"
        echo "已部署到: $hook_target"
    fi
done

echo "部署完成"

关键功能说明

哈希结构兼容性

# 查找逻辑适应任意目录结构
find /var/opt/gitlab/git-data/repositories -type d -name '*.git'

安全防护

措施 说明
-print0 + read -d '' 处理带空格/特殊字符的路径
存在性检查 -d 确保找到的是真实 Git 目录
权限控制 chown 保持 git 用户所有权

验证方法

检查随机仓库

# 随机选择一个仓库检查
RANDOM_REPO=$(find /var/opt/gitlab/git-data/repositories -name '*.git' | shuf -n1)
ls -l "$RANDOM_REPO/custom_hooks/pre-receive"

# 预期输出:
# -rwxr-xr-x 1 git git 1234 Oct  5 12:34 /var/opt/gitlab/.../custom_hooks/pre-receive

测试钩子触发

# 创建测试提交
git commit --allow-empty -m "test hook"
git push origin main

# 预期看到钩子的拦截行为

扩展建议

版本控制

建议将钩子脚本存储在独立的版本库中,通过以下方式管理:

1. 创建 hooks-management 仓库
2. 使用 CI/CD 自动同步到所有仓库

灰度部署

添加白名单机制,分批部署:

# 在脚本中添加仓库过滤
DEPLOY_WHITELIST=("repo1.git" "repo2.git")
if [[ " ${DEPLOY_WHITELIST[@]} " =~ " $(basename "$git_dir") " ]]; then
    # 执行部署
fi

回滚方案

创建删除钩子的脚本:

find "$GITLAB_REPO_ROOT" -type f -name 'pre-receive' -delete
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 5-4 持续集成与持续部署 课程介绍 那些大厂们,天天DevOps、持续集成的?到底在讲些什么?这堂课来给你揭开持...
    ioufev阅读 4,319评论 1 8
  • Composer Repositories Composer源 Firegento - Magento模块Comp...
    零一间阅读 3,973评论 1 66
  • 170+道钉钉前端扫盲知识点 基础知识 基础知识主要包含以下几个方面: 基础:计算机原理、编译原理、数据结构、算法...
    抽疯的稻草绳阅读 944评论 0 8
  • Awesome PHP 一个PHP资源列表,内容包括:库、框架、模板、安全、代码分析、日志、第三方库、配置工具、W...
    guanguans阅读 5,918评论 0 47
  • 一、Jenkins 是什么 Jenkins是一个开源软件项目,是基于java开发的一种持续集成工具,用于监控持续重...
    码农很低调阅读 759评论 0 14