I recently wanted to update our install of WordPress to the latest version. WordPress is a fairly easy install, and we could learn a thing or two about application set-up by examining their code. But I recently switched to using subversion to deploy and maintain our install. In just the little bit I’ve used subversion so far, I believe development and deployment of our internal applications would be simplified by employing it for all our projects. Here’s a quick outline of the process, with examples based on my WordPress deployment.
Workflow
Since we’re not using an IDE that has integrated subversion capability, and because I wanted to keep the process as simple as possible, I decided to try a combined approach to development. A working copy of project files are checked out from subversion to the development server. Dreamweaver uses the working copy for its remote. Code development will continue as usual in Dreamweaver. When a development milestone is reached the changes are committed to subversion. When the project is ready for deployment, we use tagging to mark a stable copy in the repository and check it out to the production server.
The main problem I’ve found with this setup right now is that there is no way to hide the subversion structure from Dreamweaver. Subversion creates a directory to house control files for each directory in the working copy. The subversion control directories can be cloaked, allowing Dreamweaver to function as if these directories don’t exist, but this is not as feasible for a project with lots of directories.
I found an extension that can automatically cloak any subversion directories, but it only works for the local copy. So if you’re willing to go through the process of downloading the entire site you can use the extension to cloak all subversion directories automatically. Read about the extension on Adobe Exchange; I’veĀ saved a copy of the extension on the techlog.
I have set up subversion to ignore the typical Dreamweaver development files (lock files, notes, backups). This allows the benefits of using the Dreamwever environment to its fullest without mucking up the subversion repository with unnecessary data.
We should also implement configuration options in a single file that is not part of the project files. We would still want to provide a sample configuration file, but the actual configuration file should be created during initial deployment by copying the sample and modifying the parameters. Using a sample file instead of actual configuration in the repository will allow us to upgrade the production server without having to worry about overwriting local settings. Overwriting the configuration is actually not much of a concern so long as the configuration file is not updated in the repository. But implementing this kind of setup does give us a little more security in that regard.
Subversion setup
First step in the process is to create a subversion repository. We’ll create this on the production server because we can see the production server from the development server, but not vice versa. To set up the subversion repository in /inet/svn, run the following command on the production server:
svnadmin create /inet/svn
Next we’ll populate the repository with a project. Since we’re just getting started with subversion we’ll utilize a well-known repository layout: project, project/branches, project/tags, project/trunk. Create the directory structure on the development server and place the current development files in project/trunk. There are a number of ways to access a subversion server, but for now we’ll use file-based access over ssh. If I create the project directory in /tmp, I would run the following command to import the project:
svn import /tmp/benchmarks svn+ssh://production.server/inet/svn
Working with project files
Now that we have the data in the repository we need to set up a working copy for Dreamweaver. First change to the directory where you want to store the working copy. Then run the following command to check out a working copy:
svn checkout svn+ssh://production.server/inet/svn/benchmarks/trunk .
Set up this directory as your remote in Dreamweaver and edit as usual.
At some point in the future you’ll want to record the changes in the subversion repository. This can be at any time in the development process, but at the very least it’ll need to be done when a project has reached a stable state and is ready for deployment. Run the following command from the working copy directory:
svn commit
Once the project has reached a stable state we need to have a way of maintaining that stable copy in the face of future modifications. This is where the branches/tags/trunk structure really comes in handy. The in-development files are always in /trunk. To create a stable release we merely need to create a copy in the /tags directory (where ver.no is the version number, such as 1.0):
svn copy svn+ssh://production.server/inet/svn/benchmarks/trunk svn+ssh://production.server/inet/svn/benchmarks/tags/ver.no
Deploy the project
Whether we’re talking about a home-brewed application or one from an external organization, the steps for deployment are the same. Check out a working copy or export a clean copy to the appropriate directory on the production server. I prefer to check out a working copy because it enables greater flexibility in deployment. If we need to modify a file in the production environment, a working copy enables non-destructive upgrades in the future. Only the files that have been modified in the repository will be updated during a version upgrade. Any conflicting updates will be noted by the subversion client so that they can be addressed. (Of course, this is only really a benefit if significant modifications have not been made to the project between versions.)
Updating a working copy to a new version is as simple as the following command (executed from the working copy directory):
svn switch repository_address .
Belt and suspenders
To avoid loss of our subversion repository we should consider creating a copy on our development server. This would only be used to restore the subversion repository in case of loss or corruption. This can be done using the svnsync
command and should be done automatically (via cron
). This may not be a necessity as much as a convenience, however, since the repository should be included in the nightly backup.
General Reading
What I attempted to provide here was the core commands needed to get started. There’s a lot more to working with subversion than what I covered and I would recommend .
- Version Control with Subversion (all you need to know)
- Tracking PeopleAggregator releases with Subversion vendor branches
- Subversion Vendor Branches Howto
- Vendor Branches in Subversion
I found the vendor branch concept a bit confusing; so a few extra links for that.
I forgot to mention that since we’re using Dreamweaver there’s a lot of files in the development directory that we don’t really want in the repository. Luckily subversion includes a configuration option that specifies files that should be ignored when performing operations.
The following entry in /etc/subversion/config will configure the files/directories that subversion should ignore:
[miscellany]
global-ignores = *.o *.lo *.la #*# .*.rej *.rej .*~ *~ .#* .DS_Store _baks* _mm* _notes* *.lck *.LCK *.bak *.BAK dwsync.xml