Skip to main content
GameDev.net gamedev.net
🔒 Locked

How code actually gets "rolled out"

Started by plywood Oct 8, 2010 at 2:02 PM 10 replies 2.8k views
Original Post
plywood
plywood
So, using SVN as an example:

"MyProject" has a svn repo called myproject. Inside of this, in keeping with standard SVN/VC practices, I create three folders: trunk\, branches\ and tags\.

Let's say the project is a web application and so has a dedicated test server for its "testing" environment, as well as a production server for prod. Code needs to migrate from individual developers' sandboxes (say, Apache running as localhost on each dev machine) to the test server, then on to the production server.

My *understanding* is that there is only 1 repo per project regardless of however many environments (sandbox, testing, production, etc.) you have configured. This means that if code is declared as being ready for testing, the buildmaster (or whoever has the appropriate privs) must "move"/"copy"/"checkout" code from, say, branches\dev\ to the project root residing on the appropriate server (test server or prod).

How does this "rollout" take place, and similarly, "rollbacks" when unstable code is replaced with a stable, previous version?

Does SVN have an "export" tool that allows you to copy/deploy one of its folders (branches\dev) to a particular URL?

I'm sure everybody does it differently, so I'm just looking for what the normal procedures are for this.

Thanks,
ply
KulSeran
KulSeran
You could always setup something like CruiseControl to do this "Continuous Integration" for you. Someone would still manually have to migrate code between branches when it is deemed stable. But, it would get published to the right locations as it is changed.
plywood
plywood
What if I want to do the code migration manually? I'm struggling with how code gets "pushed out" (copied, checked out, whatever the applicable term is!) from one environment to the next. For instance, let's say we were ready for a 1.0 release. The tested code is already in SVN and is ready to get copied/checked out/rolled out from the test server to the production server. How does one do this manually?
Alpha_ProgDes
Alpha_ProgDes
Well unfortunately where I work, we do: Ctrl-A, Ctrl-C, navigate to prod folder, Ctrl-V.

So I'm also curious on the proper way (or ways) to accomplish this as well.
Beginner in Game Development?  Read here. And read here.  
coderx75
coderx75
http://producingoss.com/en/development-cycle.html

This pertains more to open source projects but gives a pretty good overview of release strategies. For instance, on a project with many developers where development is not interrupted during release, development is carried out in real-time on the main branch while release managers will branch the project and apply patches they decide to include in the release. Once a stable release has been achieved, it is tagged. All changes should be applied in patches so that they can be easily applied to separate branches and reapplied after a rollback. I would recommend exploring the above link. The entire book is very informative.
Quit screwin' around! - Brock Samson
coderx75
coderx75
Quote:
Original post by Alpha_ProgDes
Well unfortunately where I work, we do: Ctrl-A, Ctrl-C, navigate to prod folder, Ctrl-V.

So I'm also curious on the proper way (or ways) to accomplish this as well.

Man, that's just sadistic.
Quit screwin' around! - Brock Samson
plywood
plywood
coderx75 - Thanks for the good link, I will start digesting it this weekend!

Although I'm very interested in release strategies "best practices", I think everybody is so far ahead of me here, that my real question is being overlooked!

All I'm asking is: how does code get migrated from a test server to a production server? Is it really just a copy-n-paste? I would think that there would be some automated check to ensure that only the most current release code gets rolled out to prod, eliminating the possibility of (mistakenly) rolling a 5.0 config back to a 2.3 version (which could very well happen if you have human beings copying and pasting targets between directories, etc.).

Let's say, just pretend here!, that we had a SVN repo for our project called myproject. And in this repo were many folders, but only the wombat\ folder contained code that should always be in production. When you're ready to launch, your buildmeister uses SVN move to copy files into wombat\. Now then, how do we update production with the configuration that is in wombat\ ?
rip-off
rip-off
We have two branches at work, effectively CURRENT_ITERATION and LATEST_ITERATION. We have test servers running each branch. LATEST_ITERATION is trunk, and often unstable. LATEST_ITERATION is what is running on the Live servers, plus any backported bug fixes. It is mostly stable.

Before a release, we suspend commits to LATEST_ITERATION and do a special build (I'm not sure if it is tagged). The build produces an RPM that can be deployed on any server (test or otherwise). The RPM is totally independent of any configuration, making it portable between systems.

This RPM is deployed on the test servers and extensively tested. When passed, it is given over to our sysadmins who have some really cool system based on cfengine to handle deployment. I don't know much about this process, but from some of the things I've overheard it sounds fascinating. Apparently we can cloudburst if necessary, say if our live system were to go down completely despite redundancy, etc. A pity I don't know more because this sounds like the part you are most interested in.

The sysadmins have some kind of repository for these RPMs, so a rollback just involves taking the previously live RPM and redeploying using that.

Its a small company (5 developers) so the process mostly works, but we would like to have a few more systems, one major thing that is missing is a test server that has the live code on it, minus any bugfixes since last deployment. I don't know how "normal" such a setup is.
KulSeran
KulSeran
I'd still suggest setting up a continuous integration tool for that. CruiseControl is just a wrapper. You specify the process it takes when you want to deploy. When you update the "wombat/" branch of SVN you could have CruiseControl run whatever scripts you wanted. It could force a backup on the production server, then copy over the relevant files, then run some scripts to test that the deployment went ok and restore the backup on failure. It does the same thing for all your test branches, and can email the site admins in the event of failure/success. The whole process is automatic, and gives quick feedback to developers in the event that they check stuff in that breaks their test/release branches. All of your work and scripts is in source control, so there are no manual steps/processes to screw up.

Copy pasting stuff around is bad. At the minimum, just setup your stuff so you literally just checkout the repository on the production server as if it were anyone else's machine running svn. You want the process to be as automatic as possible so that people don't forget steps along the way. A long deployment process means more steps to screw up.
Rycross
Rycross
The simplest method involves running your build script to create some sort of deployable package. You install the package on the test server, do your testing, and then take the package and promote it to the next server in the test chain until you get up to production. If you're fancy, you can have continuous integration which runs unit tests and builds a package each time someone commits code. If you're even fancier, you'll have a deploy system which holds built packages in a repository and handles installation and promotion. Where I work, we have the latter.
hdctambien
hdctambien
Here is how I do it:

SVN folders:
/trunk
/branches
/qa
/tags

Trunk holds the live code
branches holds development branches
/branches/project1
/branches/project2

QA holds the testable versions of development branches
/qa/project1
/qa/project2

and tags holds versioned versions of tested branches ready for release
/tags/1.0
/tags/1.1
/tags/2.0


When I'm done with development in project2 (or done with some testable part of development) I run a SVN copy from /branches/project2 to /tags/project2

On the QA server, that branch is checked out, built and deployed. Then tested.

Maybe I make changes to the dev branch. Then I delete the /qa/project2 branch and copy the /branches/project2 back to /qa/project2. Checkout, build, deploy, test...

Eventually the project is ready for release to production. Then I do an SNV copy from /qa/project2 to /tags/2.1 (or whatever version this release will be)

On my build machine (this could be the QA machine, the Dev machine, or my local machine) I check out the /tags/2.1 branch, build it, then package it into a tar file. (I don't have SVN installed on production)

SCP the tar file to the production machine and unzip the contents to their proper location.

A quick second on the structure of the production machine (a Linux box)

an example directory structure:

/www/mywebsite
/apps/myapp/live
/apps/myapp/version
/apps/myapp/version/1
/apps/myapp/version/1.1
/apps/myapp/version/2.0

Apache loops at /www/mywebsite to load the site.
/www/mywebsite is a symlink to /apps/myapp/live
/apps/myapp/live is a symlink to the current live version folder (/apps/myapp/version/2.0)

each /version/#.# folder hold the code for that version of the website.

So, when I release version 2.1 I create a new folder: "/apps/myapp/version/2.1" and that is where I untar my code to.

WHen I am ready to move my code live, I change the symlink of /apps/myapp/live to point to /apps/myapp/version/2.1

Tada, the site is live. If I want to roll-back to the previous version, because of some bummer of a bug then all I have to do is change the symlink of /apps/myapp/live back to /apps/myapp/version/2.0

Now, I check out trunk on my build machine, merge /tags/2.1 into trunk and check trunk in. If I have any other projects open that have not been released, then I have to merge trunk into those /branch/project# branches.

Ultimately the entire build process can be scripted and you can type:
buildMyProject 2.1 <-- check out, build, tar
deployMyProject 2.1 <-- scp, create /version folder, untar file
releaseMyProject 2.1 <-- change symlink on /live folder

When you have this (or any process) scripted, then you can use something like CruiseControl to automatically run these scripts (I wouldn't recommend that for a live server, but it's nice on a Development and QA server)

Good luck.
_the_phantom_
_the_phantom_
Where I work we have the following setup (using Perforce);

The main game is keep in a Mainline branch. This is stable, known good, set of code and data. No one can check code in here directly. (Well, apart from sysadmins).

From here there are multiple branches; be it personal or team branches. Off those can be other branches.

For example;
- Mainline
-- phantom
-- rendering
--- phantom_rendering

Now, to get code/data from a branch to mainline they have to be 'published', however this can only go to the branch directly above you in the tree.

Publishing involves selected a change list and using an internal tool which queues a publish to be integrated.

When it comes to your turn in the queue an automated tool will grab the changes and merges them with the branch you are publishing to. It then compiles the code, rebuilds the data and then runs various tests on various platforms.

If all of the above passes then the changes are submitted into the branch and it moves onto the next publish.

If it fails you get an email saying why, the changes are rolled back on the branch and it moves onto the next publish.

This system, while it can take a while (testing can take around an hour on its own) it does make sure that we always have 'good' code that a build can be taken from.

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.