views:

660

answers:

6

We are a small team of 4 developers working on a web application. We use trac+svn on a shared server for version control and ticketing and we are happy and satisfied with this. The same shared server also hosts our web application. The application itself is a Perl CGI application that uses CGI::Application and a moderate number of standard (CPAN) and custom Perl modules that are installed in the usual (/usr/lib/perl...) and a few unusual locations (/home/user/lib/perl..). While the broad details might be irrelevant, the most important point is that the location/layout of libraries on our development machines is different from that on the production (shared) server. We have to live with this as a given. The library layout is identical on all development machines though.

Here is a typical, but clearly sub-optimal work-cycle that my colleagues and I follow:

  1. Code and test on development machines
  2. Checkout/Commit/Update our code onto the SVN
  3. Periodically "svn export" onto the appropriate DocumentRoot of the server
  4. Hand edit the exported tree to set the library includes match the library layout on the server
  5. Test application on live server, raise tickets for each other
  6. Go to 1

Clearly there must be a better way and would appreciate hearing from others who might be handling this better than we are. For example is there a way to svn export and fix the library locations in an automated way? Or is there some completely different way to handle this situation than we have been doing so far.

Thank you for your attention

A: 

If this is a Linux box you could write a cron job to take care of this for you. You could use sed/awk to replace the needed strings in the code and svn export works fine from a cron job. You would need to maintain the script but it seems faster than doing it by hand every time.

trent
+3  A: 

Keep a config file (e.g. config.pl) that stores all the system-dependant paths and variables. Then set the svn:ignore property on this file so that it is never commited. This will allow you to easily keep a local configuration script per system that is separate from the commited tree.

marcog
The only issue I see with this is that you have stuff you need to develope not in source control. You'd have to keep that file somewhere and give people the file when setting up a new dev box.
Alan Jackson
I wrote that answer on the assumption that the configurations for each dev system were different. If they are not, then it is possible to keep track a set of "common" configuration scripts and create a symbolic link one for your system.
marcog
Good suggestion in general. In Perl however library locations (the includes, inheritance etc.) are parsed at compile time and require special handling that reading from config files might not allow.
Gurunandan
+1  A: 

If you don't have the possibility of mirroring your development server in production, why can't you mirror your production server in development? That might take some reconfiguring, but what's the risk? Everything's checked into svn.

But maybe that really, really isn't an option for you. My preference for deploying web applications is to do an svn checkout and then run a symlinking script. The idea is that you write a system of rules that logically maps the contents of one folder to the contents of another. Of course, if you drop folder symlinks in your document root, you have to tell Apache to follow them.

Frankly, the absolute safest scenario would be to set up a virtual machine that you can configure exactly like your production machine. This way you can actually test the contents of your deployment script and submit tickets. Then, when the problem is discovered, you modify the script to make it more likely that development deployment will follow the new and improved procedure.

And, as a side note: I much prefer to use svn checkouts in place rather than svn exports. It shouldn't be hard (especially if you use a deployment script) to make sure that apache or whatever your web server is doesn't have permission on the .svn folders. Ideally, anything you can do to make an svn rollback a one-line command is absolutely key.

David Berger
+4  A: 

You should have scripts that do this for you that can be run from a local box. Mine always look something like:

$> checkout from source or copy from working
$> run sed/perl -pi/copy to convert configs to the production values 
     (ie cp production.config myconfig)
$> upload to web server (rsync/ssh/ftp/etc)
$> ssh $SERVER migrate_db, set permissions, run unit tests, etc

The last one requires ssh access which I always look for but everything else can be done locally. You'd usually have a set of dev configs and a set of production configs (or a script to convert from dev to production

One step uploads are always a really good idea.

Alan Jackson
This would require that all developers (distributed in our case), would have to keep these scripts in sync. I would rather export from the svn into the DocumentRoot on the same server and fix all locations through a single script.
Gurunandan
I usually have these scripts checked into source control so they are kept in sync and everyone gets any changes. Your order of operations would be different, but the idea is still a same, figure out all the manual steps then just write a script to automate them for you.
Alan Jackson
Right. Thats whatI hve decided to do. Thanks for the advice
Gurunandan
A: 

For the hand-editing part, I would have a separate branch in Subversion for the local modifications you need. The developers commit into trunk and when you need to deploy, use 'svn merge' or svnmerge.py to merge changes from trunk to the branch.

After creating the branch the first time, make your local modifications in there.

On the servers, have the directories in DocumentRoot and /usr/lib/perl and /home/user/lib/perl be Subversion working copies checked out from the branch.

Do not use svn export, just have a checkout so you can 'cd /usr/lib/perl; svn up'.

The one thing to be careful about is not exposing your .svn directories in DocumentRoot, use this:

# Prevent any access to .svn directories.
<DirectoryMatch "^/.*/\.svn/">
    Options None
    AllowOverride None
    Order allow,deny
    Deny from all
</DirectoryMatch>

Having working copies deployed in DocumentRoot is also nice, if you need to rollback a change, just 'svn up -r PREV'.

Blair Zajac
A: 

Codesion offers enterprise grade subversion and trac on demand. In addition, we now have the ability to one-click publish / deploy your code via ftp, scp, rsync and many other methods. This will be an easy and quick way for you to accomplish what you are trying to do.

See our Codesion Publisher features:

https://help.codesion.com/View.jsp?procId=01fabe5e83381dda4edda959b97b2c5b