-
Notifications
You must be signed in to change notification settings - Fork 312
Custom hooks #190
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Custom hooks #190
Conversation
def hook_files(type) | ||
# Get all files for this repo and hook type. | ||
# i.e. ${custom_hooks_dir}/${namespace}/${repo_name}/(pre-receive|update|etc) | ||
end |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually, this would not be multiple files. Only one hook per type per repo.
The idea is ok. Ping me when ready for review |
else | ||
exit 1 | ||
end | ||
exit 1 unless GitlabCustomHook.new.pre_receive(repo_path, key_id, refs).exec |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
hi @dblessing. Good job. Where would the custom hooks be located?
Some comments on the pre-receive hook changes:
- You're calling the custom hook before the gitlab acccess control check. I think this is akin to making a pre-authorization hook and the hook name should reflect that.
- You should also have a call to the custom hook after the gitlab hook access control check. You can call this one the pre-receive one as it will then be equivalent (in my eyes) to where a standard git hook would be called. For example, if accessing that repo thru ssh.
If you only intend to have one such call to a custom hook, I'd give a preference to have this be for a custom pre-receive hook and that it be called after the gitlab access control check. - The gitlab pre-receive hooks sets up an environment variable called 'GL_ID' . Further on, the exec method in the gitLabCustomHook exec method unsets this variable if the access control check fails. A comment there says "reset GL_ID env since we stop git push here" (gitlab_access.rb). I didn't look into detail into the code to see why this environment variable has to be setup. However, as it's set up in one place and unset elsewhere, this seems to point out that you should do the same before the call to exit 1. You could do this in the GitlabCustomHook function and document that the custom hook must return true or false rather than exit.
However, a best practice would be to set and unset those variables in the same place. That's what I would do myself and instead of having multiple exit 1, just have a single exit 0 and and an exit 1 and unset the env. variable before the call to the exit 1.
end | ||
|
||
def hook_file(hook_type, repo_path) | ||
hook_path = repo_path.gsub(/hooks$/, 'custom_hooks') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Useless assignment to variable - hook_path
.
@jkbzh I have a possible implementation (see commits). I'm still testing, but if you're interested I would appreciate some further testing by you and others in development/test environments. I'm not yet certain args are being passed correctly. |
def pre_receive(old_value, new_value, ref_name, repo_path) | ||
hook = hook_file('pre-receive', repo_path) | ||
return 0 if hook.nil? | ||
return system(*hook, old_value, new_value, ref_name) ? 0 : 1 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Redundant return
detected.
a96367f
to
a876393
Compare
@@ -23,9 +23,12 @@ def exec | |||
def update_redis | |||
queue = "#{config.redis_namespace}:queue:post_receive" | |||
msg = JSON.dump({'class' => 'PostReceive', 'args' => [@repo_path, @actor, @changes]}) | |||
unless system(*config.redis_command, 'rpush', queue, msg, err: '/dev/null', out: '/dev/null') | |||
if system(*config.redis_command, 'rpush', queue, msg, | |||
err: '/dev/null', out: '/dev/null') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Align the parameters of a method call if they span more than one line.
a876393
to
7f95e3f
Compare
@randx I think this is ready for your review. |
There's not a really great way to document this in |
7f95e3f
to
d082978
Compare
@randx Fixed return values |
@dblessing forked and look at it right now. Could you tell me where are the arguments you're not sure you're passing to and in which files? If we could irc that would save time. |
@jkbzh I'll be on #gitlab IRC in about 45 min. (dblessing). I'm interested in whether I have the right args in the right order for the diff hook types. For example, |
@dblessing comparing against a stand-alone git setting, the hooks expect to be feed the changes line thru stdin, not as cli arguments. I'll shortly send a PR with a modified gitlab_custom_hook.rb that shows how to do it. |
d082978
to
ce73915
Compare
|
||
def receive(type, refs, repo_path) | ||
unless type == 'pre-receive' || type == 'post-receive' | ||
puts "GitLab: An unexpected error occurred " \ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Prefer single-quoted strings when you don't need string interpolation or special symbols.
ce73915
to
ac6338c
Compare
@jkbzh I updated this PR so the pre-receive now should receive all stdin. Post-receive already supported this. Update hook is called once per branch pushed so it does not need this type of support. |
ac6338c
to
3ef7cdf
Compare
hook_file = "#{hook_path}/#{hook_type}" | ||
hook_file if File.exist?(hook_file) | ||
end | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Extra empty line detected at body end.
786c378
to
668e583
Compare
private | ||
|
||
def call_receive_hook(hook, changes) | ||
require 'open3' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I dont like require inside method
- Reset G_ID if the custom pre-receive hook fails - Use a pipe to feed stdin to the custom pre- and post-receive hooks, in the same way that the standalone git works
668e583
to
b6d84f6
Compare
Looks good! Thank you @dblessing and @jkbzh |
One thing I forgot to ask is to update CHANGELOG. Can you please submit PR for this? |
@randx Which version should this be under? v2.1.0 is already released, correct? What will the next version be? |
2.2.0 |
@dblessing Would you be so kind to add documentation for this in the doc directory? I think it can be linked from the administrator documentation http://doc.gitlab.com/ce/ |
@dblessing Just noticed you already made https://github.com/gitlabhq/gitlabhq/pull/8276/files Awesome! |
This custom hook implementation support pre-receive, post-receive and update hooks. If a gitlab administrator wants to add a custom hook they need to follow these steps:
custom_hooks
directory in the repository directory adjacent to the normalhooks
directory. For example, if the repo path is/home/git/repositories/my_group/my_project.git
, the custom hook path will be/home/git/repositories/my_group/my_project.git/custom_hooks
custom_hooks
directory.What's missing?