Git Hook, Line and Sinker

Selfhosting your git repositories is not a bad idea. In fact it is a great idea and it’s pretty simple too.

First you make a new directory on an accessible machine which by convention ends on .git. Something like /allmycode/repo1.git

Move into the directory and execute

 git init --bare --share

Great, we got ourselves a shareable git repository. If you dont’ want ro be the only one to be working on that repository and have no intention of making it public either you should create a user specific for git operations on the machine you serve your repositories from.
Let’s assume your specialized user is called “git”

You can now add ssh-public-keys from all parties that should have access on the repos via copy-ssh-id to /home/git/.ssh/id_rsa.pub and have a nice passwordless access-control.

Now we can start to work on the remote repository.
In you local working directory we

git init

and provide the user information that is used in the commit message

git config --global user.name "Your Name"

git config --gloabl user.email your@email.sth

This was all local, so let’s add the information about remote

git remote add origin git@server:/allmycode/repo1.git

this enables us to make a push to remote with the shorter

git push origin master

It is completely viable to add differently labeled remote repositories e.g.

 git remote add github sth@github

and push a specialised branch (without passwords for example) there via

 git push github public

Nice, self-hosted remote repositories! You can start collaborating. And when you do you, you might want to automate transferring the newest version to a testing server. You could do this with a cronjob and some copying, or, you could use git’s very own hooks, to be specific a post-push hook.
Connect to the remote repository and enter the directory hooks/. Here you find some nice samples, but we want something different. We want a post-receive hook, which means everytime somebody pushes changes to
the remote repository this action is called. So we create that hook:

touch post-receive

then we paste in

#!/bin/sh
GIT_WORK_TREE=/path/to/serverroot/ git checkout -f

and save. Make it executable and you made a git hook. Congrats!
Since we have a user named git who is the owner of all the repos on our remote machine we must add him to the group that controls the webserver paths (www-data or else) Full instructions to make the checkout work.

Now every push to the remote repository should trigger a checkout which hopefully makes the newest version available on the webserver.

But let’s tweak things a little. Say we want to be notified whenever a commit has been pushed. Email and telephone are viable but timeconsuming and you don’t want to, and frankly should not have to, bother. I think Jabber is a great way of getting the information across without spamming the whole team. So I made a little script to send a message to everybody who cares to give me his jabber-id. You can get it here via

git clone https://github.com/kodekitchen/punobo.git

If you add to the post-receive hook

 python /<path-to-repo>/pushbot.py "Something has been pushed."

not only will your testing/demo/development server automatically have been updated, but all listed members of the working group will be informed about it on Jabber.

Advertisements

Sinatra, Mustache and Heroku

I’ve been playing around with Sinatra, in order to see how it would do in the wild I decided to use Heroku as a comfortable hosting solution.

Heroku

Begin creating your Sinatra app. Add a Gemfile, since Heroku runs a bundle install.

Commit to git.

To deploy to heroku install the heroku gem and create an instance for your app by calling “heroku create”. By default, this is enough to get going if you want the application to be run under a subdomain (e.g. http://codebrigade.heroku.com) you can do so by adding the desired name to the create.

If you push your app to &quote;heroku master&quote; it should boot and be running. If it doesn’t look into the log-files by typing &quote;heroku logs&quote; in your Command line.

Mustache

Mustache is a logic-less templating language derived from c-templates. Adding it to Sinatra is quite simple, install the mustache gem and add to your app.rb

require 'mustache/sinatra'
set :public => './public/'
register Mustache::Sinatra
require_relative 'views/layout'
set :mustache, {:views => './views/', :templates => './templates/'}

&quote;public&quote; holds static files like css. It works without explicitly setting it on my local machine but won’t do with Heroku, adding this fixes it.

It is important to include and provide the layout file since the engine looks for it.
The layout file includes the frame for all the views. For example:


<!DOCTYPE html>
<html>
<head>
<title>{{title}}</title>
<link rel="stylesheet" type="text/css" href="layout.css">
</head>
<body>
<div id="header">{{> _header}}</div>
<div id="main">{{{yield}}}</div>
<div id="footer">{{> _footer}}</div>
</body>
</html>

My layout shows a custom Title for each view, header and footer are partials.
You will need a view and a layout for every page. All views extend the layout if they use it:

class Codebrigade
  module Views
    class Index < Layout
       def title
           "Hello there"
       end
    end
  end
end

Next steps are CouchDB and Sinatra integration…