7

My Google-fu is failing me for what seems obvious if I can only find the right manual.

I have a Gitlab server which was installed by our hosting provider The Gitlab server has many projects. For some of these projects, I want that Gitlab automatically pushes to a remote repository (in this case Github) every time there is a push from a local client to Gitlab. Like this: client --> gitlab --> github Any tags and branches should also be pushed.

AFAICT I have 3 options:

  1. Configure the local client with two remotes, and push simultaneous to Gitlab and Github. I want to avoid this because developers.
  2. Add a git post-receive hook in the repository on the Gitlab server. This would be most flexible (I have sufficient Linux experience to write shell scripts as git hooks) and I have found documentation on how to do this, but I want to avoid this too because then the hosting provider will need to give me shell access.
  3. I use webhooks in Gitlab. I am unfamiliar with what the very basics of webhooks are, and I am unable to locate understandable documentation or even a simple step-by-step example. This is the documentation from Gitlab that I found and I do not understand it: http://demo.gitlab.com/help/web_hooks/web_hooks

I would appreciate good pointers, and I will summarize and document a solution when I find it.

EDIT

I'm using this Ruby code for a web hook:

class PewPewPew < Sinatra::Base
  post '/pew' do
    push = JSON.parse(request.body.read)
    puts "I got some JSON: #{push.inspect}"
  end
end

Next: find out how to tell the gitlab server that it has to push a repository. I am going back to the GitLab API.

EDIT

I think I have an idea. On the server where I run the webhook, I pull from GitLab and then I push to Github. I can even do some "magic" (running tests, building jars, deploying to Artifactory,...) before I push to GitHub. In fact it would be great if Jenkins were able to push to a remote repository after a succesful build, then I wouldn't need to write my own webhook, because I'm pretty sure Jenkins already provides a webhook for Gitlab, either native or via a plugin. But I don't know. Yet.

EDIT

I solved it in Jenkins. You can set more than one git remote in an Jenkins job. I used Git Publisher as a Post-Build Action and it worked like a charm, exactly what I wanted.

Amedee Van Gasse
  • 7,280
  • 5
  • 55
  • 101

2 Answers2

4
  1. would work of course.

  2. is possible but dangerous because GitLab shell automatically symlinks hooks into repositories for you, and those are necessary for permission checks: https://github.com/gitlabhq/gitlab-shell/tree/823aba63e444afa2f45477819770fec3cb5f0159/hooks so I'd rather stay away from it.

  3. Web hooks are not suitable directly: they make an HTTP request with fixed format on certain events, in your case push, not Git protocol requests.

    Of course, you could write a server that consumes the hook, clones and pushes, but a service (single push and no deployment) or GitLab CI (already implements hook management) would be strictly better solutions.

  4. services are a the best option if someone implements it: live in the source tree, would do a single push, and require no extra deployment overhead.

  5. GitLab CI or othe CIs like Jenkins are the best option currently available. They are essentially already implemented server for the webhooks, which automatically clone for you: all you have to do then is to push from them.

The keywords you want to Google for are "gitlab mirror github". That has led me to: Gitlab repository mirroring for instance. There seems to be no perfect, easy solution today.

Also this has already been proposed at the feature request forum at: http://feedback.gitlab.com/forums/176466-general/suggestions/4614663-automatic-push-to-remote-mirror-repo-after-push-to Always check there ;) Go and upvote the request.

The key difficulty now is how to store the push credentials.

Community
  • 1
  • 1
Ciro Santilli OurBigBook.com
  • 347,512
  • 102
  • 1,199
  • 985
  • I'm sorry but I don't understand your answer "Web hooks are not suitable". I have zero Ruby experience, but in less than a day I was able to write a web hook that prints out the latest commit message on the server that consumes the web hook. What I need next, is in that same Ruby script, to issue a command back from the web server to the GitLab server, to push the branch to GitHub. I don't know yet how, but I feel like I am on the right track. Your Google search is not ok, because GitLab no longer uses Gitolite. – Amedee Van Gasse Nov 04 '14 at 15:54
  • @AmedeeVanGasse true, if you write a server that consumes the hook, that would work of course: just take the hook, then git clone, the git push. But I think it is not the simplest solution: a service for example would strictly more efficient (single push) and easier to deploy. – Ciro Santilli OurBigBook.com Nov 04 '14 at 16:54
  • true, but I don't know (yet) how to do it the simplest way, I only know how to do it in one way that would work. My principle is: first make it work, then make it work better. Not the other way around, premature optimization killed a lot of projects before they even started. – Amedee Van Gasse Nov 05 '14 at 09:40
  • @AmedeeVanGasse I agree. Your comment made me think and I've updated the answer. I believe that gitlab CI is the easiest way to do it since it already implements the push webhook consumer server for you. – Ciro Santilli OurBigBook.com Nov 05 '14 at 09:45
  • Would't Gitlab CI perform the same function as our current Jenkins? Anyway, I will install Gitlab CI on a separate server and try it. – Amedee Van Gasse Nov 05 '14 at 13:34
  • @AmedeeVanGasse you can run arbitrary commands on it, but I don't know if it works in parallel with Jenkins. In that case, why don't you push with jenkins already? – Ciro Santilli OurBigBook.com Nov 05 '14 at 15:11
  • Didn't know you could? (a common problem with Jenkins - it is too complex) Anyway it's an older version of Jenkins, and currently the repos are in SVN, I am preparing for a Git migration. – Amedee Van Gasse Nov 05 '14 at 15:26
  • 1
    I have decided to upgrade Jenkins and continue from there. It seems like the git plugin for jenkins is able to push to any arbitrary git repository after a successful build. That would answer my question. – Amedee Van Gasse Dec 03 '14 at 14:20
2

I solved it in Jenkins. You can set more than one git remote in an Jenkins job. I used Git Publisher as a Post-Build Action and it worked like a charm, exactly what I wanted.

I added "-publisher" jobs that run after "" is built successfully. I could have done it in one job, but I decided to split it up. The build jobs are triggered by a web hook in GitLab; the publisher jobs are using a @daily schedule from the BuildResultTrigger plugin.

Amedee Van Gasse
  • 7,280
  • 5
  • 55
  • 101