Search code examples
gitgitlabgit-post-receive

Multiple git post-receive hooks


i'm using Gitlab. Gitlab is creating following link to distribute the same hooks through all repositories

hooks -> /opt/gitlab/embedded/service/gitlab-shell/hooks

Within this directory there's already a post-receive hook to process the commits properly within Gitlab which is written in ruby. I'd like to add an additional hook written in bash. Is this possible?

Best regards


Solution

  • Gitlab supports project hooks in a $GIT_DIR/custom_hooks directory.

    This is supported for the pre-receive, post-receive and update hooks.

    From the above webpage:

    Normally, git hooks are placed in the repository or project's hooks directory. GitLab creates a symlink from each project's hooks directory to the gitlab-shell hooks directory for ease of maintenance between gitlab-shell upgrades. As such, custom hooks are implemented a little differently. Behavior is exactly the same once the hook is created, though. Follow these steps to set up a custom hook.

    1. Pick a project that needs a custom git hook.
    2. On the GitLab server, navigate to the project's repository directory. For an installation from source the path is usually /home/git/repositories/<group>/<project>.git. For Omnibus installs the path is usually /var/opt/gitlab/git-data/repositories/<group>/<project>.git.
    3. Create a new directory in this location called custom_hooks.
    4. Inside the new custom_hooks directory, create a file with a name matching the hook type. For a pre-receive hook the file name should be pre-receive with no extension.
    5. Make the hook file executable and make sure it's owned by git.
    6. Write the code to make the git hook function as expected. Hooks can be in any language. Ensure the 'shebang' at the top properly reflects the language type. For example, if the script is in Ruby the shebang will probably be #!/usr/bin/env ruby.

    That's it! Assuming the hook code is properly implemented the hook will fire as appropriate.

    Running multiple hooks of the same type

    This now can be done like any other git repository: Write a delegation script to forward operation to all the hook implementations which you want to be triggered. For example:

    #!/bin/bash
    
    # Allow to run multiple hooks
    # For each hook type (post-receive, post-update, ...) create a type.d subdirectory, e.g. post-receive.d/
    # Then put all hook scripts into that directory and make them executable.
    
    # Requires the "pee" utility from moreutils package: http://joeyh.name/code/moreutils/ or use "apt install moreutils"
    # pee duplicates stdinput to all scripts
    
    script_dir=$(dirname $0)
    hook_name=$(basename $0)
    
    hook_dir="$script_dir/$hook_name.d"
    if [[ -d $hook_dir ]]; then
        pee $hook_dir/* $*
    fi
    
    exit 0