Release and Revision Control Using CVS $Revision: 1.5 $ The purpose of this document is to simplify some of the more complicated concepts in CVS by providing a simple recipe for producing production releases while continuing to work on an ongoing development line. I intend to avoid the overused and vaguely defined jargon in the CVS docs, so don't expect to find reference to Trunks, Tags, Branches, Branch Tags, and RCS versions. Where below I refer to QA, understand that this could as easily be Staging, or Production depending on your procedure. Ideally, all Staging and production code should pass through QA anyway. (One bit of CVS stuff, however: This document describes a strategy which uses the HEAD for mainline development.This is effective if you have only one team developing new functionality and this team or one other maintaining released code. If you have two or more teams developing new functionality you will probably not develop in the HEAD. For the more complicated case, look at the the merge-branch.pl script which should accompanies this document. It handles this more complicated approach as well as the simpler case.) As an example, we will use a new project. All of the developers have checked their code in to CVS, and now the build coordinator, "Bob the Builder," will checkout their code and create the first release. This is an exciting moment. Let's watch. Development System Variables* ========================================================== = Widgets_Project = v_0_1_0 = v_0_3_0 = Branch_0_2_0 = Branch_0_4_0 = v_0_2_1 = widgets = Whatever deployment tool ========================================================== * Here are a few variables to keep in mind. When reading, wherever you see these, substitute the text after the "=". When you are performing this proceedure sustitute the appropriate values at the time. Note that both versions are broken up into Major_Minor_PatchLevel values. Also notice that the minor version number of development versions are even and that release versions are odd. Creating a release for QA (Bob) ------------------------------- cvs co cd # Bob compiles and tests the code cvs tag cvs rtag -b -r #Bob performs the actions in "Deploying" Deploying (Bob) -------------------------------- #Bob cleans up with the following commands. cd .. cvs release -d # Bob uses the CVS export command to create a directory containing only # the things which need to go to QA. He then creates a tar of these files # and pushes the code to QA. cd ~/qa cvs export tar cvf _ _ Developing a patch for QA (Alice) ------------------------- # In cvs update -r # Alice makes changes # Alice Compiles and Tests Code # Alice Commits Code to CVS # Alice returns to work on the main-line code cvs update -A Creating a patch for QA (Bob) ----------------------- cvs co -r cd # Bob compiles and tests the code # The following sets a convenient marker # To find what we pushed as patch cvs tag # Bob performs the action in "Deploying" Working on new code for development (Alice) ----------------------------------- # In cvs update -A # Alice makes changes # Alice Compiles and Tests Code # Alice Commits Code to CVS cvs commit -m "some comment" Merge Development with QA (Alice) -------------------------- # WARNING: During this process Alice is the only Developer # Allowed to use the repository. NO EXCEPTIONS! # Alice has been working on other things so she starts # with a fresh slate. There are faster ways to merge code # much as the fastest way from the top of a building to the # first floor is to step off the ledge. We use the elevator # here. The entire process has been scripted to make it # less error-prone. mv .some_backup_name merge_branch.pl rm -rf mv .some_backup_name # Alice hands off to Bob, so he can make a release to QA. # Bob is going to repeat the "Creating a first release for # QA" scenario except now the tag will be "cvs tag " and # rtag will use "cvs rtag -b -r " # Bob will also need to go to QA and commit the changes in # the "next" workspace (see below). After that he will follow # an identical proceedure to "Patch the Current Config" except # he will be working in "next" instead of "current." =====================================[QA]====================================== additional QA System Variables* ========================================================== = fenixConfig = Patch_0_2_2 = /home/admin/configurations/current = /home/admin/configurations/next ========================================================== * Here are a few variables to keep in mind. When reading, wherever you see these, substitute the text after the "=". When you are performing this proceedure sustitute the appropriate values at the time. Note that both versions are broken up into Major_Minor_PatchLevel values. Also notice that the minor version number of development versions are even and that release versions are odd. The following is for Bob only. Bob has access to the QA system Alice does not. In QA, we keep the configuration files that are unique to QA. These are files that might contain QA only IP addresses or hostnames, for example. Staging and Production will have the same files with different values in them. Dev will probably also have most if not all of these files with values that make sense in Dev. Sometimes Alice will need to ask that a new configuration file be added or that an existing file be changed We want to track these changes as they come in and only implement them once the next version is deployed to QA. Alice may also need to request immediate changes as patches to the current version. We want to track these changes and keep them separate, so we use one directory for patches to the current, deployed version in QA, and a directory for the changes requested for the next release. Lets walk through both scenarios. Patch the current config ------------------------ # Alice requests a change to a connection pool configuration file # in QA to reflect the addition of a new connection pool in Dev. # Bob goes to work. cd cvs co # Bob updates the file. If it were a new file he would use # "cvs add" to add it to the repository. cvs add NewConfigFile.properties cvs commit -m "Alice added another ##$@#%%$ connection pool." newConfigFile.properties # Bob restarts the application and tests it. If it fails he goes back to # and tinkers with the settings, repeating the process until # it works. Once it all works, he marks it good, and calls it a patch. cvs tag # Remember we used earlier for a code patch. This tag is not in # Dev because there would be nothing to put there. Change the next config --------------------- # Alice requests a change be added to QA to take effect on the next release. # Bob goes to work. cd # This is the first request so we checkout, notice that we DO NOT release at # the bottom here! If this were not the first time we wouldn't do the checkout. cvs co cd # Bob updates the file. If it were a new file he would use # "cvs add" to add it to the repository. # Bob does NOT commit the changes, Bob also does NOT release the repository # Bob is done and should recognize this and feel secure and self-actualized. Commiting configuration changes for a new release ------------------------------------------------- # Above in "Change the next config" Bob carefully avoided commiting # changes to the QA configuration which belong in the next release. # When the time comes to push to QA Bob will also # commit the config changes in and test them # with the new code pushed for the release. We join Bob now as he # begins the process of commiting the changes! cd # If doesn't exist under next, there were no config changes cd cvs update # Bob edits the 'C' files, resolving any conflicts. cvs commit -m "Config changes to go with " # Bob then changes directory to the directory used by # the running application cd cvs update # There should be no 'C' files. If there are they should be resolved as # above in Next and Bob should feel bad for not checking in his last # changes. He should then also repeat the process in . See how # much trouble you caused, Bob? Bad Bob! Bob restarts the application # and tests it. If it fails, he tinkers with the files, repeating # the process until it works. Once it all works, he marks it good, and # calls it a release. cvs tag Notes ----- o Avoid adding files to CVS while working on patches (See the FAQ at the URL above). If you have to add a file to then be sure to add a dummy file in the main development. (The one you get with the "update -A") with the same name so that it will all come together properly later. It's a CVS thing. Don't ask. o If you don't know what expressions like 2>&1 mean, you should not be Alice. Bob can get by with a simple set of rules, but Alice must make difficult decisions which can effect the stability of the system. o If you are interested in the whys and wherefores be sure to read http://www.loria.fr/~molli/fom-serve/cache/1.html or the CVS man pages. o Remember the 0_1_0 was the number for the completed development work. You don't get to 0_3_0 until you finish the 0_3_0 work. =============================================================================== for questions or comments contact: ._________________________________________. | Bill Glover: Senior Java Architect | ( | ------------------------------------- | ) |-----------------------------------------|1 1..* ___ | company = "Sun Microsystems Inc." |---------> c\_/ | cellPhone = "(806) 433-0866" | `-----' | email = "Bill.Glover@Sun.com" | +-----------------------------------------+