Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

setting up a git post-receive hook

Tags:

git

jekyll

I'm trying to follow along with the instructions http://jekyllrb.com/docs/deployment-methods/ for setting up a git post-receive hook for Jekyll deployment, however, I'm finding them a little dense for me. At that link, there's a paragraph that says

To have a remote server handle the deploy for you every time you push changes using Git, you can create a user account which has all the public keys that are authorized to deploy in its authorized_keys file. With that in place, setting up the post-receive hook is done as follows:

Question 1: It's not clear to me where the 'user account' should be created (on Github? on the remote server), and (Question 2) where this authorized_keys file would be. I have a known_hosts file in my home directory on my local machine with keys for github etc. Is that the authorized_keys file?

The instructions go onto tell you to set up a post-receive hook like this

laptop$ ssh [email protected]
server$ mkdir myrepo.git
server$ cd myrepo.git
server$ git --bare init
server$ cp hooks/post-receive.sample hooks/post-receive
server$ mkdir /var/www/myrepo

The instruction mkdir myrepo.git is a little unclear to me. For example, I put my Jekyll site into git version control on my local machine, and it gave me this path /Users/me/Sites/nginxjekyll/_site/.git/

Question 3) Does that mean, then, that, following the mkdir myrepo.git instruction, I should create a directory mkdir /Users/me/Sites/nginxjekyll/_site/.git/ on my remote server? Moving on, it says,

   cp hooks/post-receive.sample hooks/post-receive

However, I don't have a hooks/post-receive.sample file to copy? In the git repository on my local machine, I have a post-update.sample but not post-receive.sample. Furthermore, when I created the directory mkdir /Users/me/Sites/nginxjekyll/_site/.git/ on my remote server, it didn't create the post-update.sample file in it.

Can you clarify these instructions for me if you have a moment. Thank you in advance.

like image 684
Leahcim Avatar asked Jul 23 '13 03:07

Leahcim


People also ask

How do I setup a git hook?

To install the hook, you can either create a symlink to it in . git/hooks , or you can simply copy and paste it into the . git/hooks directory whenever the hook is updated. As an alternative, Git also provides a Template Directory mechanism that makes it easier to install hooks automatically.

What is post-commit hook in git?

These hooks give you a change to inject functionality at particular points in the standard pipeline: Before committing ("pre-commit") Before writing a commit message ("prepare-commit-msg") After writing a commit message ("commit-msg")

How do I make a git hook executable?

Open a terminal window by using option + T in GitKraken Client. Once the terminal windows is open, change directory to . git/hooks . Then use the command chmod +x pre-commit to make the pre-commit file executable.


1 Answers

Question 1: They are referring to the user on the remote server.

Question 2: This depends, two scenarios: 1. You will need to add the public key of your local user to push to your remote server. 2. You will need to add a public key to a the local user who runs the post-receive hook if an ssh is required to deploy to another server. Most likely only 1 is your concern and 2 is not because the remote server will house the remote git repo and the www server.

This means you add the public key to the authorized_keys file in a linux/unix environment. This file is typically located in /home/$USER/.ssh/authorized_keys The authorized_keys file is located in the same directory as the known_hosts file for a user.

Question 3: They are explaining how to setup the remote git repository. It does not need to be at the same path as your local repository.

OK - now to clarify what is actually going on here. The tutorial is teaching you how to setup a remote repository that will deploy a jekyll install every time it is pushed to.

This means that if you have a github repo, you cannot setup the server-side hook there. Rather you would set up a new remote on your remote server. So say that you log into your server (with ssh typically), run pwd to learn your full path or set it in an environment variable:

$DIR=`pwd`

Now you can create a bare repo on this server:

git init --bare $DIR/<SOMEDIRNAME>.git

Now you have a remote bare git repository on your server. Next you need to add the hook that allows it to deploy your Jekyll site upon receiving a push. The site you have listed has a rather simple deploy, but basically all it is doing is making the _site dir the served html pages, you could do this several ways, I suggest that you do it without disrupting your users as much as possible, here is a sample script that might do such a thing:

#!/bin/bash
# Assuming a directory structure for www:
# $www_root/releases 
# $www_root/shared
# $www_root/current
# all releases go in releases dir as timestamps dirs
# any logs or other shared items go in shared dir - shared/logs
# current is a symlink to latest release
unset GIT_DIR
WWW_ROOT=/PATH/TO/WWW
REPO_PATH=/PATH/TO/REPO
REPO_BRANCH=master
SITE_DIR=/PATH/TO/_SITE/DIR/IN/REPO
DATE=$(date +"%Y%m%d%H%M")

# get code
if [ ! -d $WWW_ROOT/shared/git_maint ]; then 
  mkdir -p $WWW_ROOT/shared/git_maint
  cd $WWW_ROOT/shared/git_maint
  git clone $REPO_PATH $WWW_ROOT/shared/git_maint
  git checkout master
else
  cd $WWW_ROOT/shared/git_maint
  git pull
  git checkout master
fi

# do deploy
if [ ! -d $WWW_ROOT/releases/$DATE ]; then mkdir $WWW_ROOT/releases/$DATE; fi 
cp -ar $WWW_ROOT/shared/git_maint/$SITE_DIR $WWW_ROOT/releases/$DATE
ln -snf $WWW_ROOT/releases/$DATE $WWW_ROOT/current

exit 0

Something like that would be a good deploy. If you save this script on your remote server in the bare repo hooks/post-receive file then it will run each time the repository is pushed to. Just remember to make it executable: chmod 755 hooks/post-receive So if you add this new remote to your git repo with:

git remote add DEPLOY_PROD [email protected]:/path/to/bare/repo

Then git push DEPLOY_PROD - it will push to your remote and then your remote repo will fire its post-receive hook and then copy the bare repo down to a maintenance directory that can be blown away at almost any point. This directory is then used to cp the site dir to a releases dir and then that is linked up to the main directory.

Of course all of this is most likely overkill and you can just create a deploy script that runs from you local host to do all this over ssh.

The problem is you are unable to run server side hooks directly from github for this methodology so you have to work around it. I would suggest you check out capistrano as a deployment strategy - the current/releases/shared dirs and git_maint dir is taken from their schema, it works well.

Let me know if you would like any help here, I have a lot of experience developing deploy and automated deploy strategies, so depending on your situation, things will vary.

like image 92
Michael Avatar answered Sep 22 '22 00:09

Michael