Using Mercurial to publish a PieCrust website
These days, all the cool hipster kids want to deploy stuff by pushing a Git or Mercurial repository up to their server.
And that’s pretty cool indeed, because you basically update your website by doing something like:
hg push myserver
So here’s how you can do it with PieCrust (although 90% of this article has nothing to do with PieCrust):
- Installing Git/Mercurial/whatever on your server
- Setting up your SSH keys
- Pushing your repository
- Defining hooks/triggers
Keep reading for the meaty details…
I’m going to use Dreamhost as the hosting provider in this pseudo-tutorial, but most of the information would be valid for another provider.
Installing the DSCM on your server
As far as I can tell, Git is installed on most servers at Dreamhost, so that’s already taken care of.
For Mercurial, they seem to have a super old version so you may want to install a more recent one yourself. It’s actually pretty easy since the steps are described on their community wiki. In my case, it boiled down to:
mkdir -p ~/srcs
cd ~/srcs
wget http://mercurial.selenic.com/release/mercurial-1.7.5.tar.gz
tar xvzf mercurial-1.7.5.tar.gz
cd mercurial-1.7.5
make local
make install-home-bin
And then adding the new paths to my ~/.bash_profile
and ~/.bashrc
:
export PYTHONPATH=~/lib/python
export PATH=~/bin:$PATH
Setting up your SSH keys
If you’re using BitBucket or GitHub, you probably already have some SSH keys lying around somewhere. If not, then, well, create an account at either one (depending on whether you use Mercurial or Git). Not only are those websites super useful, but they can also help you (somewhat) with setting up an SSH access:
The Git help pages are way better than the Mercurial ones, so even if you don’t like Git you may want to check them out if you’re lost.
If your SSH access works with Git/Mercurial, then enable password-less login on your Dreamhost account (you basically just need to copy/paste your public key into an ~/.ssh/authorized_keys
file… this should work on any other Unix-based host). This will make things super smooth in the future.
Pushing your repository to Dreamhost
Create a directory in your Dreamhost home to store your repository. For example, with Mercurial:
mkdir -p ~/hg/myproject
cd ~/hg/myproject
hg init .
Now back on your local machine, in your local repository, edit the .hg/hgrc
file with:
[paths]
dreamhost = ssh://yourlogin@yourdomain.ext/hg/myproject
If you type hg push dreamhost
, it should all work! If not… well… go back to the beginning and start again.
Things would look very similar with Git, and you should be able to do it yourself since you’re already a Git user!
Setting up hooks/triggers
Now’s the time to do actual work. The idea is to run a custom script on your server when you push updates to the repository you have up there.
- In Mercurial, you want to look at the
changegroup
hook. - In Git, you want to look at the
post-receive
hook.
For example, on the Dreamhost server and using Mercurial, you can edit the ~/hg/myproject/.hg/hgrc
file and add:
[hooks]
changegroup = ~/scripts/bake_site.sh
Now you only need to write the actual script bake_site.sh
! You probably want something that does:
- Export the repository into a temporary folder.
- Bake your site in that temporary folder.
- If all went well, copy the baked site into your home.
- Clean up.
This would look something like:
#!/bin/sh
set -e
HG_REPO_DIR=~/hg/myproject
ARCHIVE_DIR=~/tmp/hg_archival
PUBLIC_DIR=~/yourdomain.com
# Archive (export) the repo.
echo "Archiving repository to ${ARCHIVE_DIR}"
if [ -d ${ARCHIVE_DIR} ]; then
rm -fr ${ARCHIVE_DIR}
fi
mkdir -p ${ARCHIVE_DIR}
hg archive -r tip ${ARCHIVE_DIR}
# Bake your website
mkdir -p ${ARCHIVE_DIR}/baked
${ARCHIVE_DIR}/_piecrust/chef bake -r http://yourdomain.com/ -o ${ARCHIVE_DIR}/baked ${ARCHIVE_DIR}/mywebsite
# Move baked website into the public directory.
echo "Copying website to ${PUBLIC_DIR}"
cp -R ${ARCHIVE_DIR}/baked/* ${PUBLIC_DIR}
# Clean up.
echo "Cleaning up"
rm -fr ${ARCHIVE_DIR}
But don’t use that script!
Obviously it won’t work for you unless you change a lot of directory names, tweak the options for chef
, etc. But it should be a good starting point.
- I recommend you test your script by first running it manually while logged in via SSH, and after changing the
PUBLIC_DIR
to some temporary directory. You’ll probably get it wrong a couple times at first, especially if you’re quite rusty with Bash syntax like me. - When it’s working as expected, do a repository push and check that the script is baking everything correctly in the temporary directory.
- If that’s all good, then you can revert
PUBLIC_DIR
back to its intended path.
Now you can enjoy your new coolness: hg push dreamhost
!