У меня есть сервер Gitlab (Ubuntu 14.04), где я пытаюсь использовать его как хост для моих репозиториев, а также как сервер тестирования для моих проектов PHP. В идеале я хотел бы, чтобы Gitlab / Git экспортировал ветку «release» в /var/www/git/<project-name>
когда эта ветка обновляется.
Мой вопрос: Как я могу экспортировать определенную ветку в Gitlab, в определенный каталог на локальном хосте, когда ветка обновляется?
Я знаю, что в Gitlab есть веб-хуки, но кажется ненужным и расточительным иметь сервер POST для локальной операции.
Я полагаю, вы работаете с сообществом Gitlab.
Тогда только администратор сервера может настроить подключаемые сценарии, скопировав необходимые сценарии в соответствующие репозитории.
Гитлаб сам использует $GIT_DIR/hooks
каталог для собственных скриптов уже. К счастью, они передают управление любому скрипту хука в специфическом для gitlab $GIT_DIR/custom_hooks
каталог. Смотрите также этот вопрос о том, как запустить несколько хуков одного типа на 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
Сценарий был запущен на основе этот скрипт post-receive.send_email который уже цитируется на SO несколько раз.
Настройте область выпуска в переменной, жестко закодированной в сценарии, или, например, добавить механизм для чтения конфигурационного файла в репозитории. Может быть, вы хотите дать пользователям контроль над этой областью. Зависит от ваших обстоятельств безопасности.
Область выпуска должна быть доступна пользователю git @ gitlab и, конечно, любому клиенту, ожидающему экспорт.
Ветка для экспорта жестко закодирована в скрипте.
Область релиза будет заполнена так:
$release_root/$group_name/$repo_name/dated/$release_date
Плюс символическая ссылка latest
указывая на последние $release_date
, Идея заключается в том, что это расширяется, чтобы позже иметь возможность экспортировать теги. Если вы планируете экспортировать различные ветви, $branch
также должен быть включен как компонент пути.
Контроль доступа к серверу gitlab не передается структуре каталогов. В настоящее время я делаю это вручную, и поэтому я не автоматически заполняю все новые репозитории с этим хуком. Я бы предпочел настроить вручную, а затем настроить разрешения группы Unix (и / или ACL) на $release_root/$groupname
пути соответственно. Это должно быть сделано только один раз для каждой группы и работает, потому что больше никому не разрешено создавать новые группы в моем экземпляре gitlab. Это сильно отличается от значения по умолчанию.
Что-нибудь еще, что мы можем сделать для вас? 😉
Других решений пока нет …