简体   繁体   中英

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

I have created a file named pre-receive in the .git/custom_hooks directory.

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:

ls -a gives the response:

-rwxrwxrwx 1 git root 550...

The custom_hooks directory is also executable and owned by the git user.

But all commits go through without issue, the commit hook does not seem to activate in any way.

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
  • 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)

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 .

You tagged your question gitlab , here is the documentation page to set such a hook:

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).

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.

Place this script in the hooks directory of your gitlab server. Under hooks directory, create a new directory named - pre-receive.d and place the script file inside it.

#!/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. In future, if you have any other use-case, simply put conditionals on these values.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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