Thursday, May 14, 2009

Automated Deployment Crash Course

I've been spending a lot of time this week working out my first automated deployment process.  And, as usual, it's not going to end up being a nice, simple one.  We've got branches, tags, and only one developer actually comfortable with subversion (me).  We've got external developers who, by their own admission, know just enough to be dangerous.  Schema updates.  SFTP connections.  Firewalls.  Heck, there's probably a ninja riding a shark somewhere in this project.

Anyway, I've played with ANT a little in the past, but I had trouble getting it to connect over SFTP and more issues with integrating SVN due to our self-signed certificate on the repo.  Plus, the external developers were already clamoring to "just have FTP access" to the production server, and I figured I was going to have a hard enough time getting them to use SVN, much less ANT.

On the production server, the app's code exists as a working copy checked out from the repo.  This has made deployment simple thus far; connect to server, update working copy.  It also made the current situation more difficult (If someone DOES edit the files on the production server, we risk conflicts on an update, and that will put non-CFML into the conflicted files, probably bringing the whole site down).

The solution I settled on was to use CFEXECUTE to trigger the svn command on the server through a web interface.  I'd tried this before with little luck, but this time I pressed further and managed to solve all my issues.

The first step was grabbing an svn executable.  The app in question is on a Windows server, and we'd been using TortoiseSVN, which doesn't have a (traditional) command line interface.  Enter SlikSVN.

Next came about three hours of experiments getting CFEXECUTE to call the executable, skip interactive questions ( --non-interactive ), accept our self-signed certificate ( --trust-server-cert ), pass in a username and password (even for list and status commands?).

The largest waste of time came while I was getting zero results and couldn't tell why.  I figured SVN was showing an error, but CFEXECUTE wasn't capturing error output.  That's when I stumbled across a neat feature added in 8.0.1: CFEXECUTE's errorVariable attributes.  Works just like "variable", except it catches the error output, not the standard output.  Turns out I was forgetting the /svn/ part of our repo URL.  Oops.

Anyway, We now have a setup where the site is a working copy attached to the trunk and external developers have access to the trunk and the ability to force deployments though a web interface.  Meanwhile, my team will concentrate on adding features in a new branch, and merge to the trunk when we're ready to deploy.

This is still not ideal.  The next step in the process will involve creating a separate staging version of the site for testing, and a new process for deploying to the production site that will utilize tags to keep production as stable as possible.

In other words, my Automated Deployment is currently a manual process.  But it's a good first step.

Still, I was able to come up with a solution that satisfies the needs of the external developers and lets us retain the power of svn.  And also start training people that editing live web sites directly is a Bad Idea.  Honestly, what we've got right now isn't too much different, but we'll solve that once I separate Staging from Production.

No comments:

Post a Comment