Slightly OT: SVN deployment of Rails apps

I need advice from deployment gurus.

I'm working on setting up a "permanent" stable deployment environment for a large app that is going live. The application will be undergoing significant new feature development after deployment, so we will be keeping svn branches to separate stable from new features.

Right now, code is deployed by hand (svn up && mongrel_cluster restart) from trunk. I will be setting up Capistrano for deployment and misc. tasks. We aim to have 3 environments on the production server: development (features branch), staging, and production.

My primary question is: should I deploy from trunk or a "release" branch? Cal Henderson's "Building Scalable Web Sites" suggests deploying from a branch for larger projects and/or teams. This is a large project, but not a large team (2 developers). If I deploy from a branch, would that limit my ability to concurrently develop multiple features in other branches? What would be the purpose of trunk, then?

My primary question is: should I deploy from trunk or a "release"
branch? Cal Henderson's "Building Scalable Web Sites" suggests
deploying from a branch for larger projects and/or teams. This is a
large project, but not a large team (2 developers). If I deploy from
a branch, would that limit my ability to concurrently develop
multiple features in other branches? What would be the purpose of
trunk, then?

Doesn't matter. Subversion doesn't really have a "trunk" or HEAD in the sense that CVS does. It's just a convention (at least as I understand it). They are all just copies of the repository at one point or another...

For what it's worth, we have a "trunk" copy with the rule that it can be pushed at any time and will work. This lets our designers tweak things easily and 99% of the time don't have to deal with any branches (please, no comments about designers pushing content :slight_smile:

Then for things that take more than a couple of hours/days us developers create a branch, work, test, then merge back into trunk and push.

So we have a lot of short lived branches and one main trunk.

Seems to work for us, but we push constantly it seems.

If you are more structured you could certainly have a "production" branch that you merged into... definitely a lot more stable that way as little things won't creep in unless you intentionally put them there...

i got into trouble once by deploying from a tag, which is functionally
equivalent to branches in subversion. eventually it came time to
upgrade, and as i had no automatic deployment tool (was in php) i wanted
to run something like `svn update`. well, thing is, the new code was in
the trunk (or possibly another tag), which meant that `svn update` just
wouldn't work. svn doesn't do smart updates when you're switching repo
paths at the same time (svn switch may have helped, but i didn't learn
about it until too late).

now this may not apply to your situation because capistrano, per my
superficial understanding, doesn't use `svn update`. but still, it's
something to think about. i personally will be shy for a while about
deploying from anything except trunk. =)

Brad Ediger wrote:

I use a main trunk that deploys to staging and then production by
passing a parameter to the cap call. You can see how I do it on my
blog [1].

Then after I deploy to production, I tag the release as the current
production release. I use svnmerge.py on this tag, so that I can merge
changes into it as needed. This way I can merge back into it needed
changes, or even fix on it specific release related bugs. And I can
redeploy both to staging and production from it. I have a pretty
complex script that does the checkout, svnmerge.py actions and also
prepare the plugins for that. But after the script does it's thing, I
only have to use svnmerge.py merge, and svn ci to update this tag.

Please note that like Philip said, in svn trunk/branch/tag are all
just conventions. They are exactly the same as far as you are
concerened. That's why I can continue development on a tag if needed.

Bye,

Guy.

[1] Deploying to staging and production:
http://devblog.famundo.com/articles/2006/09/28/deploying-to-staging-and-production-with-capistrano

Thanks to everyone for the help and advice. I think I might end up deploying from trunk for 2 reasons:

1) Less cognitive overload -- just use branches for feature development
2) Because it's a web app, it only has one 'release' version at a time. There would never be a situation where we have to support an old release.

Thanks again for the help.
Brad

I use a main trunk that deploys to staging and then production by
passing a parameter to the cap call. You can see how I do it on my
blog [1].

Then after I deploy to production, I tag the release as the current
production release. I use svnmerge.py on this tag, so that I can merge
changes into it as needed. This way I can merge back into it needed
changes, or even fix on it specific release related bugs. And I can
redeploy both to staging and production from it. I have a pretty
complex script that does the checkout, svnmerge.py actions and also
prepare the plugins for that. But after the script does it's thing, I
only have to use svnmerge.py merge, and svn ci to update this tag.

Please note that like Philip said, in svn trunk/branch/tag are all
just conventions. They are exactly the same as far as you are
concerened. That's why I can continue development on a tag if needed.

Thanks to everyone for the help and advice. I think I might end up
deploying from trunk for 2 reasons:

1) Less cognitive overload -- just use branches for feature development

Might be worth downloading this and giving it a read through "just
because".

http://www.phptr.com/bookstore/product.asp?isbn=0131855182&rl=1#info4

(look for the downloads section)

2) Because it's a web app, it only has one 'release' version at a
time. There would never be a situation where we have to support an
old release.

Write this on a piece of paper and stick it to your wall for when the time
comes you have to do exactly that. heh heh :slight_smile:

I use a main trunk that deploys to staging and then production by
passing a parameter to the cap call. You can see how I do it on my
blog [1].

Then after I deploy to production, I tag the release as the current
production release. I use svnmerge.py on this tag, so that I can merge
changes into it as needed. This way I can merge back into it needed
changes, or even fix on it specific release related bugs. And I can
redeploy both to staging and production from it. I have a pretty
complex script that does the checkout, svnmerge.py actions and also
prepare the plugins for that. But after the script does it's thing, I
only have to use svnmerge.py merge, and svn ci to update this tag.

Please note that like Philip said, in svn trunk/branch/tag are all
just conventions. They are exactly the same as far as you are
concerened. That's why I can continue development on a tag if needed.

Thanks to everyone for the help and advice. I think I might end up
deploying from trunk for 2 reasons:

1) Less cognitive overload -- just use branches for feature development

Might be worth downloading this and giving it a read through "just
because".

http://www.phptr.com/bookstore/product.asp?isbn=0131855182&rl=1#info4

(look for the downloads section)

Neat, thanks for the pointer.

2) Because it's a web app, it only has one 'release' version at a
time. There would never be a situation where we have to support an
old release.

Write this on a piece of paper and stick it to your wall for when the time
comes you have to do exactly that. heh heh :slight_smile:

Yeah, I've been bitten by making those kind of statements before. Luckily, I control the deployment environment, so... they get the releases I tell them they get. :wink:

Thanks again--
be

You can also keep a tag called LATEST_STABLE to which you can copy a
tag or a known revision point on trunk.