我有一个Gitlab服务器(Ubuntu 14.04),我尝试将它用作我的存储库的主机以及我的PHP项目的测试服务器。理想情况下,我希望让Gitlab / Git导出&#34;发布&#34;当分支更新时,分支到/var/www/git/<project-name>
。
我的问题:当分支更新时,如何将Gitlab中的特定分支导出到localhost上的特定目录?
我知道Gitlab中有可用的webhook,但是让服务器POST自己进行本地操作似乎是不必要和浪费的。
答案 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实例上创建新组。这与默认值非常不同。
我们能为您做点什么吗? ; - )