So how would you integrate git-commit-notifier with GitHub? First you need to clone the branch on the host that can receive these POST requests. Because GitHub sends a post-receive hook for each merge, you can often receive multiple web requests being sent to your Sinatra server. The naive way would be to launch the script within the POST command (i.e. %x in Ruby), but using this approach requires any operation you perform to be completed before the HTTP connection is closed.
require 'rubygems' require 'json' require 'sinatra' post '/' do if params[:payload] push = JSON.parse(params[:payload]) print "JSON response: #{push.inspect}" end # Tried to run as a daemon, fork, but maybe just doing an exec will produce fewer dup msgs. system("mirror_repo.sh ") end
The script that would perform the merge_repo.sh task would then be something of the following:
cd /home/myrepo git fetch github # Sends diffs between our branch and origin/master CURRENT_HASH=`git log HEAD -1 --pretty=%H` NEW_HASH=`git log origin/master -1 --pretty=%H` # git merge will actually be a fast-forward git merge origin git log --no-merges --pretty=format:"%P %H" $CURRENT_HASH..$NEW_HASH | awk '{print "echo " $0 " refs/heads/master | git-commit-notifier /usr/local/config/git-commit-notifier.yml"}' | sh git checkout master exit 0
The basic approach fetches the branch (assuming it's located on 'github'), pipes the changes listed by the parent and git hash into using the git-commit-notifier script before merging the branch. Assuming the upstream branch is simply an ancestor of the current branch, the merging should be a fast-forward.
If you plan on mirroring the repository (i.e. via Gitosis), you could setup a post-receive hook that would be configured to send diffs each time they were merged.
while read oldrev newrev ref do if [ "$REFSPEC" == "refs/heads/master" ]; then echo "$oldrev $newrev $ref" | git-commit-notifier /usr/local/config/git-commit-notifier.yml fi done
Thanks, this helped me to setup email notification for github repository. I even skipped the POST receive from GitHub - just polling it periodically via cron, works fine without messages duplication. I had one thing to fix from your article:
ReplyDelete"git log HEAD -1 --pretty=format:%H" instead of "git log HEAD -1 --pretty=%H"
A snippet to notify about changes in selected branches:
branches = %w(master rc some_other_branch)
branches.each do |branch|
exec("git checkout #{branch}")
last_rev_cmd = "git log HEAD -1 --pretty=format:%H"
old_rev = exec(last_rev_cmd)
exec("git pull")
new_rev = exec(last_rev_cmd)
next if old_rev == new_rev
exec("git-commit-notifier #{CONFIG_PATH} #{old_rev} #{new_rev} refs/heads/#{branch}")
end
Best regards,
Artem
Both -pretty=format:%H and --pretty=%H seem to work with git 1.7.9.5. What version are you using?
ReplyDeleteThanks, this is useful. I took this info and inserted some information in the README.md of git-commit-notifier.
ReplyDeleteWhy not use the JSON parameters available sent by GitHub to determine what has changed? See the example WebHook here:
https://github.com/git-commit-notifier/git-commit-notifier
The change-notify.sh script listed there assumes the repository and branches exist already. I've modified it to automatically clone a valid repository and create a remote tracking branch when necessary.