Loosely Coupled Git Hooks
Jun 18, 2013
Git hooks may need to execute deployment actions they have no permissions for. Messaging provides a simple way to bridge that gap.
I’m a big fan of AMQP, it’s the current hammer solution to all my nails problems.
I’m developing a personal convention in my projects of having a push hook to automatically deploy the published branch. Instead of dealing with user privileges to let the hook process touch the application directory, I run a small daemon that subscribes to a message queue, and the hook does nothing except sending a message.
My current setup involves simply using the default direct exchange.
The hook then becomes:
1 2 3 4 5 6 7 8 9 10 11 | EM.run do connection = AMQP.connect(host: 'my.broker.host', vhost: '/my-vhost', user: 'my-user', password: 'my-password') channel = AMQP::Channel.new connection ex = channel.direct "" ex.publish '{"action":"generate"}', routing_key: "my-project" do connection.disconnect { EM.stop } end end |
And the daemon
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | $0 = "My project generator" Dir.chdir "/var/www/my-project" Dante.run "my-project", pid_path: '/var/www/my-project-generator.pid', user: 'www-data', group: 'www-data' do EM.run do connection = AMQP.connect host: "my.broker.host", vhost: "/my-vhost", user: "my-user", password: "my-password" channel = AMQP::Channel.new connection queue = channel.queue "my-project", auto_delete: true queue.subscribe do |payload| message = Oj.load payload case message["action"] when "generate" `my-deploy-script` end end end end |
Dante daemons are started like so:
1 | sudo /var/www/my-project-generator.rb -d |
See gist for full code.