views:

1131

answers:

6

Here is the situation: we have multiple developers with varying degrees of commandline experience and we are putting together a deployment solution for our websites. The production environment is 2 SUSE Linux boxes. The development environment is a SUSE Linux box as well. Each developer has/will have a copy of the SVN tree in their home directory for development and testing.

The goal is to have a release system that is easy to use and easy to revert that will work with multiple production servers. It would be a bonus if a non-web developer (still a coder just not in the web world) could easily revert any of the websites as well. In an optimal world, release would be as simple as running a single command on the website that you want to release. This command would update the production servers and leave a revert path in it's wake.

Our current deployment solution is a bit clunky, quite difficult to revert and slow as dirt. We currently check in all files using SVN. Then a script is run that essentially creates a tag in SVN. A second script is then run that goes onto each of the 2 production servers and runs an 'svn up'.

Any suggestions?

A: 

One of the things you may run into is backwards and forwards through your different database structures at different versions. Moreso if you have initialization data that is required in it. I recall there being some similar questions here if you search but not quite like this..

Jas Panesar
We use a custom application server as middleware that is between our SQL servers (MYSQL and MSSQL) and a customer database server so our data is already handled.
uprise
A: 

Have you looked at existing build tools like ant/phing or even a CI solution like xinc or phpUnderControl?

Peter Bailey
phing looks pretty promising...
uprise
A: 

In my experience, the "revert" feature is almost impossible to maintain, since there is no simple way to handle destructive updates. That said, you can definitely do better than just svn up. At the very least, you'd want to have a script run after the code is checked out, that can patch the application (make changes to the database etc.). You'd probably want to make the actual update atomic as well, so I would recommend that you svn export to a temp folder, and then update a symlink to point to the folder once you're done. You'd probably want to stop any services during the running of patches as well.

You could look into using something like Capistrano for wrapping it all up in a nice package. It comes with a pretty we-based gui (Webistrano).

troelskn
A: 

I am a .net guy and therefore work with things in the windows world...having said that though the technologies that I work with on a daily basis to manage build processes came from your world! (Linux/java technologies are in parenthesis but I included their equivalent for the windows readers too) I use CruiseControl.NET (CruiseControl), VisualSVN (SVN), Tortoise, and NAnt (Ant) to take care of all of my build needs.

All of my builds are generally automatically pushed and tagged at the time of check in. This is done with CruiseControl as it monitors my source control (SVN or SubVersion). When CruiseControl (CC) sees that new code has been checked in it will execute a CC project which in turn calls out to the Ant script on the build server.

The Ant script does several things for me in a common build. It will check out a copy of the latest code and bring it down to the build server. It will then build the code to make sure that things at least compile. It then sets a clean copy of my database and executes any sql scripts to build that baseline db up to the current version. I then run all of my unit test projects. I then run integration tests which among other things test my repository layer to make sure that the code is still aligned with my back end (I generally use an ORM in my projects so they are rarely out of sync...but is a good step in the process). Once all of the tests have passed (or failed) I roll back the database to a clean state and execute scripts to bring it up to the current version (this is important as it provides the team with a clean database to develop against at the click of a button). If the build was successful then I will deploy the code out to the development server (I also have one click deployment to my staging servers and production servers). If you like to tag your code base with each check in you can do that here too.

Once all of this is complete I like to run some analysis on my code using NDepend, NDoc, and NCover. NDepend is a code analysis tool to make sure that things are architecturally correct, that naming standards are as they should be, and a WHOLE LOT MORE. NDoc extracts all of the code comments and creates MSDN style documentation for my code. NCover tells me if I have proper coverage with unit tests for my code.

I then have a custom Ant task that I wrote that parses all of my code for the various //TODO and //CodeDebt tags to generate yet another report to tell me (usually at the end of the sprint) just how much crap is building up in my code base. This can then be factored into the next sprint.

All of these reports are either included in the build email that goes out or is linked too appropriately.

Keep in mind that all of the above happens for each check in...and without anyone having to click even one button! This is true continuous integration and should be the goal of every build master.

CruiseControl has a web based console that will also allow non web dev guys (anyone really) to go in and execute this push without having to check in code...called forcing a build.

Given this framework you can easily also roll back a push as long as everything is under version control. You would need another Ant script that would perform the same process but with an additional first task in that it would have to get the last version of code rather than the most recent to perform the build process on. All of the Ant tasks can be reused with a different execution target.

Andrew Siemer
A: 

Just to keep it simple, give SpringLoops a try. It's a hosted svn service with options to deploy (and revert) to different servers. It's really easy to use and setup, the free version just lets you deploy to one server, but if you are willing to pay, you can deploy to different servers (i.e. staging, development and production).

You can get 30 days of any packages for free, so you can test with as many servers you need to. I'm not affiliated to springloops. I just use it and find it useful and plain simple.

Eduardo Romero
+1  A: 

Capistrano is a great solution. Although originally developed for the Ruby on Rails platform, I've used it successfully on a number of PHP projects. It automates actions performed via SSH. Deployments are atomic because each deployment is checked out to a new directory.

The current copy is switched on by use of a symbolic link. The latest version of the source is pulled from Subversion. You can also set up static configuration files to use in the production environment.

Capistrano also supports rollbacks, although you have to be careful here if you are making database changes between deployments. Consider using something like dbdeploy or rails migrations to solve this problem.

Clay