简体   繁体   English

如何激活 GitLab 中的预接收挂钩?

[英]How do I activate a pre-receive hook in GitLab?

I need to check each commit coming into GitLab and block any of them which have a certain file in. I used the documentation here我需要检查进入 GitLab 的每个提交并阻止其中任何一个包含特定文件的提交。我使用了文档here

I have created a file named pre-receive in the .git/custom_hooks directory.我在.git/custom_hooks目录中创建了一个名为pre-receive的文件。

The file just has the contents:该文件仅包含以下内容:

#!/bin/sh
exit 1

Which, I believe, should reject any attempt to push code to the repo (?)我相信哪个应该拒绝将代码推送到仓库的任何尝试(?)

The file is owned by git and is executable:该文件归 git 所有,可执行:

ls -a gives the response: ls -a给出响应:

-rwxrwxrwx 1 git root 550... -rwxrwxrwx 1 git 根 550...

The custom_hooks directory is also executable and owned by the git user. custom_hooks 目录也是可执行的,归 git 用户所有。

But all commits go through without issue, the commit hook does not seem to activate in any way.但是所有提交 go 都没有问题,提交挂钩似乎没有以任何方式激活。

I do not see anything else in the documentation that I am supposed to do.我在文档中没有看到我应该做的任何其他事情。 Have I missed anything?我错过了什么吗?

One way to do that is to set a pre-commit hook on your local machine, and check for the presence of said file among the staged files:一种方法是在本地计算机上设置预提交挂钩,并检查暂存文件中是否存在所述文件:

# .git/hooks/pre-comit :

#!/bin/bash

forbidden=$(git diff --cached --diff-filter=ACMR -- forbidden/file)

if [ -n "$forbidden" ]; then
    echo "*** rejecting commit, file '$forbidden' is present" >&2
    exit 1
fi

One major benefit is: you (or other users) are informed right now that this file should not be committed, rather than later when the push is rejected.一个主要好处是:您(或其他用户)现在被告知不应提交此文件,而不是稍后推送被拒绝时。

Downsides are:缺点是:

  • this hook must be installed once per clone of your repo这个钩子必须在你的 repo 的每个克隆中安装一次
  • a user can skip that hook (uninstall it manually, modify the hook script, or run git commit -n to skip pre-commit and commit-msg hooks)用户可以跳过该钩子(手动卸载它,修改钩子脚本,或运行git commit -n以跳过pre-commitcommit-msg钩子)

If you need to be 100% positive this file does not reach the central repo, one way to prevent this is indeed to set a pre-receive hook, but this hook must be set on the server .如果你需要 100% 肯定这个文件没有到达中央仓库,防止这种情况的一种方法确实是设置一个pre-receive钩子,但是这个钩子必须在服务器上设置。

You tagged your question gitlab , here is the documentation page to set such a hook:您标记了您的问题gitlab ,这是设置此类挂钩的文档页面:

https://docs.gitlab.com/ee/administration/server_hooks.html https://docs.gitlab.com/ee/administration/server_hooks.html

You need to access your gitlab's install filesystem (eg: ssh to gitlab's server with the admin account), and set the pre-receive hook in the appropriate project(s).您需要使用管理员帐户访问 gitlab 的安装文件系统(例如:ssh 到 gitlab 的服务器),并在适当的项目中设置pre-receive挂钩。

Note that, since a user can push a whole branch (or even several branches) in one go, you should check the presence of said file in all new commits pushed to the server, not just the tip of each branch.请注意,由于用户可以在一个 go 中推送整个分支(甚至多个分支),因此您应该在推送到服务器的所有新提交中检查所述文件的存在,而不仅仅是每个分支的尖端。

Place this script in the hooks directory of your gitlab server.将此脚本放在 gitlab 服务器的 hooks 目录中。 Under hooks directory, create a new directory named - pre-receive.d and place the script file inside it.在 hooks 目录下,创建一个名为 - pre-receive.d 的新目录并将脚本文件放入其中。

#!/bin/bash

# Place this script in gitlab server directory -> <path_to_your_gitlab_server_root>/hooks/pre-receive.d
# Create directory,if it does not exists -> mkdir -p <path_to_your_gitlab_server_root>/hooks/pre-receive.d

# Get input data passed along pre-receive hook
read old_sha new_sha refname

# Default separator is ' ', change to ','
IFS=","

# Use env variable GL_USERNAME to get the matching details from users csv file
# This file can be easily generated from the database that you have configured for your gitlab instance.
# It contains records in following format - <username>,<user_email>,<user_name>
IFS=', ' read -r -a validuserarray <<< `grep -i "$GL_USERNAME," /tmp/gituser.csv `
valid_user_email=${validuserarray[1]}
valid_user_name=${validuserarray[2]}

# Get the last log user details from git log
IFS=', ' read -r -a incoming_committer_array <<< `git log -1 "$new_sha" --pretty=%ce,%cn | tr '[:upper:]' '[:lower:]'`
IFS=', ' read -r -a incoming_author_array <<< `git log -1 "$new_sha" --pretty=%ae,%an | tr '[:upper:]' '[:lower:]'`

# If no match found, fail the push
if [[ ${#validuserarray[@]} < 3 ]]; then
    echo "GL-HOOK-ERR: You are not authorised to perform this action."
    exit 1
fi

# Ensure no conflict markers are there
if git diff "$old_sha" "$new_sha" | grep -qE '^\+(<<<<<<<|>>>>>>>)'; then
    echo "GL-HOOK-ERR: Code has conflict markers. Please resolve and retry."
    exit 1
fi

# Validate author email ends with domain.com
if ! [[ "${incoming_author_array[0]}" =~ ^[A-Za-z0-9.]+[@]domain\.com$ ]]; then
        echo "GL-HOOK-ERR: Author email address ${incoming_author_array[0]} is invalid."
        exit 1
fi

# Validate committer email
if [ "${valid_user_email}" != "${incoming_committer_array[0]}" ]; then
    echo "GL-HOOK-ERR: Committer email address ${incoming_committer_array[0]} is invalid."
    exit 1
fi

# Validate committer name
if [ "${valid_user_name}" != "${incoming_committer_array[1]}" ]; then
    echo "GL-HOOK-ERR: Committer name ${incoming_committer_array[1]} is invalid."
    exit 1
fi
exit 0

For each push, gitlab will provide values - branch, old_sha, new_sha.对于每次推送,gitlab 将提供值 - branch、old_sha、new_sha。 In future, if you have any other use-case, simply put conditionals on these values.将来,如果您有任何其他用例,只需在这些值上加上条件即可。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM