8

I was wondering what is the best way to create a pre-push hook (in a git repo) which does the following:

  • Run JSHint / JSLint
  • Run Unit and functional tests
  • If everything is ok then accept the update
  • Otherwise refuse the update
Gareth
  • 133,157
  • 36
  • 148
  • 157
Lt.
  • 1,268
  • 1
  • 13
  • 28
  • 2
    Github (the git hosting service) doesn't let you add arbitrary hooks to the hosted copies of your repos. Setting hooks on the *local* version of your repositories is certainly possible, but then the question isn't Github-specific :) – Gareth Sep 04 '13 at 15:19
  • 2
    So, the only way to add a hook is using the pre-defined ones by [GitHub](http://developer.github.com/v3/repos/hooks/#create-a-hook)? – Lt. Sep 04 '13 at 15:44
  • 1
    Well first, be aware that pre-push is run on the machine doing the pushing, and that will never be Github. The 'push' event that Github offers a Web Hook for is actually triggered as a post-receive, as it says at the top of the page you linked to. So, it can only really be used for notifications – Gareth Sep 04 '13 at 15:51
  • related: https://stackoverflow.com/questions/31681746 – tkruse Jul 26 '18 at 10:11

1 Answers1

4

You could use a Git pre commit hook to do this. I've set up pre commit hooks to check for debug statements, etc.

Client side hooks like this belong in the .git/hooks folder. But since you can't commit anything in the .git repo into version control you're kind of stuck.

What you need to do then is to keep your shell command that checks correctness in some folder in your git repo, say a top level tools directory.

Then "just" tell people to install it via:

chmod u+x tools/precommit-checks.sh

ln -s $PWD/tools/precommit-checks.sh .git/hooks/pre-commit

and, assuming that everyone installs it, you can have checking like you ask.

Probably a better way is to just catch this server side: have some kind of continuous integration server pulling the latest commits from your Github repo and checking the codebase.

No, it won't give you the "deny a push" capabilities you'd like.

Assuming you were to host your git repo yourself, there's also another wrinkle: I thought pre-receive hooks on the server would hang the clients for as long as the hook takes. (This is documented to be true for post-recieve hooks, so I'm guessing it's true here too). So if the CI tests take 2 minutes some developer is typing git push and waiting 2 minutes for their console to do anything again.

So probably better to do post push analysis using a CI server or other quality tests.

RyanWilcox
  • 13,890
  • 1
  • 36
  • 60
  • 3
    why make this is a pre-commit instead of a pre-push hook? As a pre-push hook, it would give the option to deny a push -- http://git-scm.com/docs/githooks#_pre-push – Mike 'Pomax' Kamermans Nov 07 '13 at 17:31
  • If pre-push happens on the client machine, then it might be a good idea. If it happens on the server, like pre-recieve, then see my problem about it hanging. But pre-push might be interesting: I know I do a bunch of work, then make a bunch of commits extracting the different pieces out. pre-push could avoid "Yes, I know the unit tests fail for this commit, gimme a second". Unless you _want_ that feature (aka: your team uses git-bisect a lot, so unit tests have to pass) – RyanWilcox Nov 07 '13 at 18:38
  • 1
    if you add it to your local .git/hooks dir, all hooks are local. pre-push will kick in just before the push is allowed through, and if whatever script(s) run return something other than 0, the push gets cancelled. – Mike 'Pomax' Kamermans Nov 07 '13 at 22:46