Perhaps unsurprisingly, I ended up neglecting my blog again. Six months have passed since I last posted. Oh boy.
Let me tell you where it all went wrong… See, there are two versions of this website: this one, which we’ll call “live”, and a second one, running only on my MacBook, which we’ll call “dev”.
In theory, live and dev should be in sync most of the time. However, there might be draft pages and code under development on dev. Once an item of content or a new code release is ready, then I would SFTP it up to the server (live) for all the world to see.
The reality was that sometimes I would create content locally (dev), sometimes directly on live. Same with code revisions. If I wanted a new feature badly enough, or needed to fix a bug, I would often find myself working directly on the live server (breaking every web-developer rule I know). My fuck-it-all-up mistake came in my failing to port my changes from one to the other while they were still fresh in my memory.
As a consequence, dev and live got terribly out of sync. I had different code-bases on both and I had content, in both draft and complete forms, that existed in one place but not the other. To cap it all, there was a new version of the underlying CMS (GetSimple) and I didn’t dare deploy it because of the mess I had created.
The net result of all this was an ambivalence on my part towards the website and thus the stagnation of the whole project.
Why Did I Work Directly On Live?
In a word? Laziness.
The process I have described above (develop code/produce content locally, then synchronise with live) should have been painless, but there were a couple of niggles that got in the way. One irritant was GetSimple’s insistence on using absolute URLs throughout. This meant that any item of content I produced locally (www.staging.perpetual-beta.org) would have all links, image sources and so on referencing that URL. That was no problem on my machine, but it meant that I had to do a search and replace on all the relevant files before I pushed them to live (www.perpetual-beta.org). Now, okay, a simple Perl one-liner was enough to do the trick, but it irked me nonetheless.
Then there was the actual process of transferring files up to the live server. I could either do this by carefully selecting those that were new or changed, or I could use my SFTP client’s automated synchronisation tool. This would connect to the live server, then walk the entire directory tree to build up a map of changes. It was a slow, slow process.
I ended up writing a shell script to do the search-and-replace followed by an rsync to the server. That improved things, but it meant that there was still that extra step to take to actually get content/code from my computer up to the live site.
The final step in my process was to clear the page cache on the live server, otherwise you’d never see anything new. This meant additional fiddling in my SFTP client, or I could log on to the admin interface of my CMS and purge the cache from there.
Thus publishing became a chore. So, you guessed it, I chose the path of least resistance and wrote directly to live. Yeah, not my smartest move.
Picking Up the Pieces
I recently realised that was drawing near, so I decided to get my ass in gear and fix it.
I started by putting my local (dev) files under source control (SVN). I then merged the latest GetSimple revision source into mine, a mammoth task in itself since I have customised my version of the code.
Then I merged the code on live into my local repository. Fortunately this was considerably easier than the first merge. Then I brought together all the content and assets and put them too under version control.
At that point I had both a working CMS and single source of content. So I was in a much better position than I had been. I made revisions and performed some commits (57 actually). Everything was going swimmingly.
Automated Builds
What I wanted next was to streamline my publishing process. Get rid of the cumbersome workflow described above and automate as much as I possibly could. I defined my “perfect” process as:
- Create content
- Proof-read in situ on dev
- Edit as necessary
- Commit revisions
To that end, I rolled up my sleeves, did a little Googling and got to work.
The first thing I did was trawl through the CMS and rework the URL handling to allow relative URIs by default. This made my content and templates portable and I could now transpose freely between dev and live. However, a curve-ball appeared when my RSS client pulled down the feed. The relative URLs in my content didn’t work at all in a feed-reader. So I wrote a funky little parser, with a DOMDocument base, to handle the conversion of relative-to-absolute URLs and thus fixing my RSS feed.
Then, through the magic that is Google, I learned about a wonderful little collection of PHP scripts called “svn2web” and a secret sauce, otherwise known as the SVN hook. With a combination of pre and post commit hooks and svn2web, I could automate the actual deployment of my code and content, from dev to live, with every SVN commit. Yay!
Back in Business
It took some determined exploration and little effort to get here, but I’ve now got my perfect publishing platform. GetSimple is a lovely little CMS and this, combined with a handful of customisations and my new workflow, will hopefully mean that I find myself creating more content, more frequently.
Because now I have no more excuses!
Updated: 28th September, 2013.
The process described above has changed a little. The SVN repository is now on a remote server rather than on my own laptop. This means that the website is automatically updated with a post commit hook that performs a svn update
from that repository. Thus there is no longer any need for the svn2web software. This has removed a potential point of failure.
Because the web-server now has a checked-out clone of the SVN repository on it, it’s important that we prevent the web-browser from accessing the SVN files. We do this with the following code in our httpd.conf
(or .htaccess
) file:
# Protect SVN file-system from web access
RedirectMatch 404 /\\.svn(/|$)
This code simply results in a 404 error for any requests to a SVN file or directory.
Updated: 25th November, 2015.
I no longer use SVN for version control on the Perpetual βeta. I have switched to Git.