6

My requirement is that whenever developers are pushing to github, then before the push a CI build should trigger on Jenkins server. If that build fails, then push to github should be rejected. I need to write hooks for this, but I don't want to write client-side hooks as they can be disabled by developers. I want server-side github webhooks or pre-receive hooks.

Now, is this even possible to achieve ? If yes, then where to begin? Do I need knowledge of Rest API? Do I need to write shell scripts?

Gauranga Rathod
  • 348
  • 5
  • 16

3 Answers3

8

This isn't generally the workflow possible with GitHub.
You would rather use a "guarded commits" model with 2 GitHub repo:


that's what the requirement is for my project, which can't be changed

In that case, It is best to follow Building a CI server which will:

  • detect the pushes and trigger a compilation
  • push back on dedicated branch for valid comimt (it could be the master branch for instance)

That means the devs should push only to a "dev" branch, monitored by your server, and your CI engine would push those commits to the master branch if the compilation passes.

Community
  • 1
  • 1
VonC
  • 1,262,500
  • 529
  • 4,410
  • 5,250
  • I agree that my workflow isn't commonly used, but that's what the requirement is for my project, which can't be changed. So, I just wanted to know whether the webhooks solution is even feasible. – Gauranga Rathod Jul 10 '15 at 06:53
  • @GaurangaRathod then the general idea remains the same, with only one GitHub repo but two branches: I have edited my answer accordingly. – VonC Jul 10 '15 at 06:57
  • You're changing my workflow again. I have to use Github webhooks and I need that into picture. – Gauranga Rathod Jul 10 '15 at 07:02
  • @GaurangaRathod https://developer.github.com/guides/building-a-ci-server/ uses GitHub webhooks. – VonC Jul 10 '15 at 07:03
1

It's not possible to do exactly what you're asking for but it's possible to do something that should be close enough.

You can configure GitHub's hooks to invoke your CI server to run a build on every push. When the CI job is started, it should clone the repository and then forcibly push the branch to its previous state. If the build succeeds, push the branch again.

This requires your Jenkins job to have credentials that enable it to write to the repository.

However, you should understand that this method is prone to merge conflicts. It's possible that someone will push to the same branch while the first job is running (or worse, queued). You might have two jobs working on the same branch. Queued jobs are bound to cause problems, the least of which is that the branch will be updated on GitHub until the job runs and someone might pull the changes.

Having said this, my advice is that this workflow is not scalable. A possible alternative is to use protected branches and let your CI jobs merge feature branches into protected branches after successful builds (as long as it's a fast-forward merge).

Hosam Aly
  • 41,555
  • 36
  • 141
  • 182
0

After some research, I've found that it is possible to trigger jenkins build using github's webhooks, but it's not possible to reject the github push request if the jenkins' build fails. So, basically, we cannot control the github's push, atleast not in free github account.

Gauranga Rathod
  • 348
  • 5
  • 16
  • That is why I proposed a different workflow in my answer: once the push is done on GitHub (and triggers a webhook), you cannot indeed "refuse" the push on GitHub. – VonC Jul 14 '15 at 10:35
  • @VonC Different workflow is definitely a better solution, but do you know if it's possible to refuse the push on Github enterprise or github's private repository? – Gauranga Rathod Jul 14 '15 at 10:48
  • Yes, if you control the Git repos hosting server, then you can add hooks (instead of webhooks), which means you can refuse a push if a policy is not enforced. – VonC Jul 14 '15 at 11:03