如何将Gitlab项目分支部署到目录

时间:2015-08-03 18:33:12

标签: php git apache ubuntu gitlab

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

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

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

1 个答案:

答案 0 :(得分:0)

我想你正在运行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启动的,已经多次在SO上引用。

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

git @ gitlab用户必须可以访问发布区域,当然也可以是任何期望导出的客户端。

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

发布区域将填充如下:

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

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

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

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