Analysis
BitBucket has a number of service hooks, but none of the ones I've
used are explicitly for triggering deployment scripts. You could role
your own using the BitBucket broker API, but this is generally not
the right thing to do.
The received wisdom is to use deployment scripts from continuous
integration, so that you're only deploying successful builds. Note that
I said "deploying," not "pushing," because you can't push to a
repository with a working tree.
However, it's certainly possible to trigger a Rails update without
continuous integration, post-receive hooks, or deployment tools such as
Capistrano. Polling is one alternative.
Solution
While a post-receive or service hook can trigger an arbitrary action on
commits, the simplest thing to do is just to poll Git from your web
server. For example, you could run a cron job every minute to pull the
current master branch into a working tree under your web root.
First, install and test your polling script. I generally use a variation
of this:
#!/bin/bash
# Script:
# git_poll.sh <appname>
# Purpose:
# Poll your Rails repository for changes.
set -e
WEBROOT='/var/www'
MY_RAILS_APPNAME="$1"
shift
# Use the flock(1) utility to guard against long-running fetch or merge
# operations using the flock(2) system call. On Debian-based systems,
# this tool is found in the util-linux package.
(
flock -n 9
cd "$WEBROOT/$MY_RAILS_APPNAME"
git fetch origin master
# Check if heads point to the same commit.
if ! cmp --quiet <(git rev-parse master) <(git rev-parse origin/master)
then
git pull --force origin master
touch "$WEBROOT/$MY_RAILS_APPNAME/tmp/restart.txt"
fi
) 9> "/var/lock/polling4${MY_RAILS_APPNAME}"
This script assumes you're using Phusion Passenger. If you're using
something else, you may need to modify the script to take some other
action after Git pulls from the remote repository.
Next, make sure the script is executable. chmod 755
/usr/local/bin/git_poll.sh
should do it.
Finally, update your Rails user or system crontab with something similar
to the following:
* * * * * /usr/local/bin/git_poll.sh example_app
Since we're using exclusive locking in the script, polling every minute
should be fine. If you don't use locking, or want to reduce load on your
systems, then set a longer polling interval in your crontab.
That's it! Now when you push to origin from development or QA, your
Rails server should update itself within a minute or so. That's usually
sufficient for most purposes, and hopefully yours as well.