Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Custom post-receive file using GitLab

Tags:

git

gitlab

I'm trying to replace my post-receive hook, auto-generated by GitLab by a new file which enables mail-support and thus has to be triggered "post receive".

This is the previous version of my file:

#!/usr/bin/env bash

# This file was placed here by GitLab. It makes sure that your pushed commits
# will be processed properly.

while read oldrev newrev ref
do
  # For every branch or tag that was pushed, create a Resque job in redis.
  repo_path=`pwd`
  env -i redis-cli rpush "resque:gitlab:queue:post_receive" "{\"class\":\"PostRe
ceive\",\"args\":[\"$repo_path\",\"$oldrev\",\"$newrev\",\"$ref\",\"$GL_USER\"]}
" > /dev/null 2>&1
done

When I replace that file by a new one which includes the above mentioned lines at the end of the file, GitLab says: "Project has invalid post-receive file" in the admin area but emails are correctly sent.

Do you know how to handle that problem of multiple post-receive support. At the moment I don't know if the gitlab specific part of the file is correctly executed at all.

Thanks for help!

Update:

The scripts within the folders are invoked now by using the below mentioned solution (pull request). But I don't understand why the standard "post-receive-email"-script doesn't send any mails if it is included in the directory. It works fine if it is invoked directly as post-receive.

Don't know why I have to change the order, but the following works for me (even I don't know if resque jobs are now created properly:

#!/usr/bin/env bash

repo_path=`pwd`

if [ -d hooks/post-receive.secondary.d ]; then

  for i in hooks/post-receive.secondary.d/*
  do
      [ -x "$i" ] || continue
      # call the hooklet with the same arguments we got
      path=$repo_path"/"$i
      "$path" "$@" || {
          # hooklet failed; we need to log it...
          echo hooklet $i failed
          perl -I$GL_BINDIR -Mgitolite -e "log_it('hooklet $i failed')"
          # ...and send back some non-zero exit code ;-)
          exit 1
      }
  done

fi

while read oldrev newrev ref
do
  # For every branch or tag that was pushed, create a Resque job in redis.
  env -i redis-cli rpush "resque:gitlab:queue:post_receive" "{\"class\":\"PostReceive\",\"args\":[\"$repo_path\",\"$oldrev\",\"$newrev\",\"$ref\",\"$GL_USER\"]}" > /dev/null 2>&1
done

exit 0
like image 401
John Rumpel Avatar asked Jan 14 '13 11:01

John Rumpel


3 Answers

Update 2014, with GitLab not using gitolite anymore:

As mentioned below by Ciro Santilli, there is now an official way to setup custom hooks (GitLab 7.5.0+, Nov. 2014).

  1. Pick a project that needs a custom git hook.
  2. On the GitLab server, navigate to the project's repository directory.
    For a manual install 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.

Original answer (January 2013)

This (allowing custom hooks) has been resolved with pull request 555 and commit 2245a6bbe, at the time where GitLab was using post-update hooks.

You need to declare a hooks/post-receive.secondary.d in your git bare repo managed by gitolite and GitLab.
Put all your post-update hooks in there.

You could modify the post-update hook posted by gitolite following that model: it will call all your post-update hooks if detected.


The issue is:

With Gitolite V2, GitLab finally delegated that management to Gitolite, because you could declare post-update.secondary hooks, that Gitolite itself would call.

With Gitolite V3, there is no longer any reserved hook (beside the update one in the gitolite-admin repo), so there is no gitolite "secondary" mechanism.
But GitLab (which now uses post-receive hook), hasn't yet updated its hook management to take into account that new reality (of gitolite not allowing anymore secondary hooks).

like image 185
VonC Avatar answered Nov 11 '22 14:11

VonC


Custom hooks

GitLab recently added a custom hooks feature since the regular hooks are used internally: https://github.com/gitlabhq/gitlabhq/blob/667c0a909bde1cf71f21d8ec9768e98b1c489030/doc/hooks/custom_hooks.md

Basically, you just create a custom_hooks directory in you bare Git repo and put the hooks in it, and GitLab makes sure they get run.


Another possible solution to this particular problem could be:

#!/usr/bin/env bash

while read oldrev newrev ref
do
  # For every branch or tag that was pushed, create a Resque job in redis.
  repo_path=`pwd`
  env -i redis-cli rpush "resque:gitlab:queue:post_receive" "{\"class\":\"PostReceive\",\"args\":[\"$repo_path\",\"$oldrev\",\"$newrev\",\"$ref\",\"$GL_USER\"]}" > /dev/null 2>&1
  /path/to/your/hook $oldrev $newrev $ref

done

As far as the mail notifications are concerned, I suggest using this email hook. Alternatively, you could use git-notifier and replace /path/to/your/hook $oldrev $newrev $ref with /path/to/git-notifier/

like image 39
voo Avatar answered Nov 11 '22 16:11

voo