【问题标题】:How to deploy Gitlab project branch to directory如何将Gitlab项目分支部署到目录
【发布时间】:2015-10-25 23:28:00
【问题描述】:

我有一个 Gitlab 服务器(Ubuntu 14.04),我正在尝试将它用作我的存储库的主机以及我的 PHP 项目的测试服务器。理想情况下,当该分支更新时,我希望 Gitlab/Git 将“发布”分支导出到 /var/www/git/<project-name>

我的问题:当分支更新时,如何将 Gitlab 中的特定分支导出到本地主机上的特定目录?

我知道 Gitlab 中有可用的 webhook,但是让服务器 POST 到自身进行本地操作似乎没有必要且浪费。

【问题讨论】:

    标签: php git apache ubuntu gitlab


    【解决方案1】:

    我想你正在运行社区版的 gitlab。

    然后,只有服务器管理员可以通过将所需脚本复制到受影响的存储库来配置挂钩脚本。

    gitlab 本身已经将$GIT_DIR/hooks 目录用于自己的脚本。幸运的是,他们将控制权转发给 gitlab 特定的 $GIT_DIR/custom_hooks 目录中的任何钩子脚本。另见this question about how to run multiple hooks with the same type on gitlab

    脚本本身可能如下所示:

    #!/bin/bash
    #
    # Hook script to export current state of repo to a release area
    #
    # Always hardcode release area - if configured in the repo this might incur data loss
    # or security issues
    
    echo "Git hook: $0 running"
    
    . $(dirname $0)/functions
    
    git=git
    release_root=/gitlab/release
    # The above release directory must be accessible from the gitlab server
    # and any client machines that want to access the exports. Please configure.
    
    
    if [ $(git rev-parse --is-bare-repository) = true ]; then
        group_name=$(basename $(dirname "$PWD"))
        repo_name=$(basename "$PWD")
    else
        cd $(git rev-parse --show-toplevel)
        group_name=$(basename $(readlink -nf "$PWD"/../..))
        repo_name=$(basename $(readlink -nf "$PWD"/..))
    fi
    
    
    
    function do_release {
        ref=$1
        branch=$2
    
        # Decide on name for release
        release_date=$(git show -s --format=format:%ci $ref -- | cut -d' ' -f1-2 | tr -d -- -: | tr ' ' -)
        if [[ !  "$release_date" =~ [0-9]{8}-[0-9]{6} ]]; then
            echo "Could not determine release date for ref '$ref': '$release_date'"
            exit 1
        fi
    
        dest_root="$release_root/$group_name/$repo_name"
        dated_dir="dated/$release_date"
        export_dir="$dest_root/$dated_dir"
        # Protect against multiple releases in the same second
        if [[ -e "$export_dir" ]]; then
            export_dir="$export_dir-02"
            dated_dir="$dated_dir-02"
            while [[ -e "$export_dir" ]]; do
                export_dir=$(echo $export_dir | perl -pe 'chomp; print ++$_')
                dated_dir=$(echo $dated_dir | perl -pe 'chomp; print ++$_')
            done
        fi
        # Create release area
        if ! mkdir -pv "$export_dir"; then
            echo 'Failed to create export directory: ' "$export_dir"
            exit 1
        fi
        # Release
        if ! git archive $branch | tar -x -C "$export_dir"; then
            echo 'Failed to export!'
            exit 1
        fi
        chmod a-w -R "$export_dir"      # Not even me should change this dir after release
        echo "Exported $branch to $export_dir"
    
        ( cd "$dest_root" && rm -f latest && ln -s "$dated_dir" latest )
        echo "Adjusted $dest_root/latest pointer"
    }
    
    
    process_ref() {
        oldrev=$(git rev-parse $1)
        newrev=$(git rev-parse $2)
        refname="$3"
    
        set_change_type
        set_rev_types
        set_describe_tags
    
        echo "  Ref: $refname","$rev_type"
    
        case "$refname","$rev_type" in
            refs/heads/*,commit)
                # branch
                refname_type="branch"
                function="branch"
                short_refname=${refname##refs/heads/}
                if [[ $short_refname == release ]]; then
                    echo "    Push accepted. Releasing export for $group_name/$repo_name $short_refname"
                    do_release "$refname" "$short_refname"
                else
                    echo "    Push accepted. No releases done for $group_name/$repo_name $short_refname"
                fi
            ;;
            refs/tags/*,tag)
              # annotated tag
              refname_type="annotated tag"
              function="atag"
              short_refname=${refname##refs/tags/}
            ;;
        esac
    }
    
    while read REF; do process_ref $REF; done
    
    exit 0
    

    脚本是基于this post-receive.send_email script 启动的,该this post-receive.send_email script 已在 SO 上多次引用。

    在脚本中硬编码的变量中配置发布区域,或者例如添加一种机制来读取 repo 中的配置文件。也许你想让用户控制这个区域。取决于您的安全情况。

    发布区域必须可供 git@gitlab 用户访问,当然还有任何期望导出的客户。

    要导出的分支在脚本中是硬编码的。

    发布区域将如下填充:

    $release_root/$group_name/$repo_name/dated/$release_date
    

    加上一个符号链接latest 指向最新的$release_date。这个想法是,这可以扩展,以便以后也能够导出标签。如果您希望导出不同的分支,也应将$branch 作为路径组件包含在内。

    gitlab 服务器的访问控制没有传递到目录结构。目前我手动执行此操作,这就是为什么我不使用此挂钩自动填充所有新存储库的原因。我宁愿手动配置,然后相应地调整 $release_root/$groupname 路径上的 unix 组权限(和/或 ACL)。这需要每个组只执行一次并且有效,因为不允许其他人在我的 gitlab 实例上创建新组。这与默认值有很大不同。

    我们还能为您做什么? ;-)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-07-29
      • 2022-08-11
      • 2017-01-28
      • 2019-07-26
      • 2013-05-20
      • 2018-03-19
      • 2012-08-09
      相关资源
      最近更新 更多