Codders, resources for programmers by Vokimon
Managing Application Releases with CVS

Managing Application Releases with CVS

Because CVS documentation is so large and sparse, and, becasue it gives you too much freedom on how you use it, often is not that easy to choose the suited life cycle to follow for your CVS project.

This tutorial, first presents a model for project life cycle, and then, shows how it can be implemented using CVS. The reader will be guided to create a dummy project example and perform on it the key steps of such life cycle.

Index

  1. The project releases policy
    1. Version numbers
    2. Kinds of releases
    3. Development progress
    4. Experimental development
  2. An example of CVS implementation
    1. Create a testing module
    2. Do some 'development'
    3. Release an snapshot
    4. Issue an official release
    5. Fixing a bug on a released version
    6. Merge the fix on the main branch
    7. Fixing and merging a second fix
    8. Backporting fixes from the main branch
    9. Creating an experimental branch
    10. Exporting tagged releases as source tarballs
  3. Other CVS documentation
  4. Multilingual terms glossary

The project releases policy

This section describes a typical release policy which includes most of the events a project may consider. Projects vary a lot on their release needs so take it just as an example.

Version numbers

A distributed team of programmers is going to develop an aplication named 'theapp'. They have choosen a 'M.m.r' version numbering schema being:

Major version number (M):
Will change when the release implies incompatibility with previous version or an important architectural change.
'theapp 2.4.1' -> 'theapp 3.0.0'
Minor version number (m):
Will change when some features have been added but there is no major changes.
'theapp 2.4.1' -> 'theapp 2.5.0'
Release (minor-minor) version number (r):
Will change when only bug fixes have been added without adding any user detectable feature.
'theapp 2.4.1' -> 'theapp 2.4.2'

Kinds of releases

The team can do differents kinds of releases for the project:

Development progress

Achieving millestones
Evolutive development on the main branch

The features to be reached at the next featured version (i.e. '2.4.0') are previously specified. The development team develops towards this millestone. When those features are reached (or abandoned), 'theapp' is released as 'theapp 2.4.0' and the the next millestone (2.5.0 or 3.0.0) starts to be developed.

Once you have started the development of the next featured version (say 2.5.0), you may detect bugs on 2.4.0. You can do the bug fixing on the 2.4.0 base code and then release that as 2.4.1.

Bugfixing released versions
Corrective development on the bug fixing branch

The bug fixing can be done on the 2.4.1 line and then applied back to 2.5.0 line or the reverse process, that is fixing on 2.5.0 and applying back to 2.4.1. This mechanism will keep the 2.4.0 user bug fixed without having to wait new featured versions.

Experimental development

Another issue we have to deal are experimental development lines. Experimental development appears when you are trying to implement features that you don't know whether it will be part of any official release.

Experimental branches
Experimental development

The same mechanism as for the experimental development is used to develop forward releases. That is, advancing the development of some features that they will not be present on the current featured version but in the next one. For example, you may want to start the implementation of 3.0.0 features while you are still developing 2.5.0

Rationale: One can think that the better way to manage an experiment is outside the repository (CVS) control. This is far from true. By evolving it in a branch you could get the benefits of frequent commits for change tracking, and it is also easier to make diffs and merges with the main trunk.

Notice: Experimental branches should have a very short life. As the code diverges from the main branch, the merge will be harder. To lighten this you should limit the files or folders under experimentation and do frequent merges from the main branch to the experimental one.

An example of CVS implementation

Now, I am going to guide you on creating a dummy CVS project and applying to it some of the key steps of the life cycle explained before.

Let's do the development from one featured version to another to be the main CVS branch. We will place CVS tags on snapshots points and create branches whenever a new featured version is reached. Bugfixed version will be performed on such branches and merged back to the main branch if necessary. Experimental development also takes part on a separated branch and it can be merged to the main branch anytime.

After the tutorial your cvs repository will get a look similar to this one:

CVS content after some releases
CVS content after some releases.

The tutorial suposes that you have already an available cvs repository and that you have the CVSROOT environment variable pointing to it. It also suposes that you know the basic of CVS usage. That is:

I recommend you to create a directory named 'cvstutorial' or something like that where to place all the stuff of this tutorial. Consider that all the paths are relatives to that directory.

Create a testing module

Let's create our dummy project named 'theapp' and let's add it as a new module named 'mymodule' on the cvs.

Note: It's common to put to the same name for the module and the application, but because this can be not your case, we will use different names for you to know which one we are talking about each time.

The steps are:

Once the repository has been created you can forget about the initial directory.

Do some 'development'

Now we will start the development of 'theapp 1.0.0'.

Release an snapshot

Now that you have implemented the first feature it could be a good idea to get a development release.

Issue an official release

First of all we will do the 1.0.0 release

Now, let's prepare the bug fixing branch for 1.0

Now you have two branches: the main branch, ready for the development of the 1.1.0 release and the 1.0 bugfixing branch ready for the development of the 1.0.1 release.

Fixing a bug on a released version

The workcopy is assigned to the main branch so further development on this working copy aplies to the 1.1.0 development. If you want to fix a bug for the 1.0.1 version, you must create a new working copy from the 1.0 branch.

Merge the fix on the main branch

Hint: This exercise will be more interesting if you perform and commit some development towards 1.1.0 on 'workcopy'.

Now you want to apply the fixes to the main branch.

Fixing and merging a second fix

Additional fixings on this branch must be merged in a different way. We will use the tag 'theapp_1_0_merged_to_main' placed on the previous merging, as a reference point in order to specify which changes must be applied.

Backporting fixes from the main branch

Often bug fixes are done on the main branch as part of the normal development, and you want to apply this fixes to an older release.

The easiest way to proceed is to delimitate the changes, using dates or tags. In that case, you can apply the same steps used to apply fixes to the main branch but in the inverse sense, from the main branch to the BugFixed branch.

Just because having delimited changes is not always possible, you have to deal with patching files separately, using file revision numbers. File revisions are very different from application releases. Revisions are the name of differents commitments for a file. So dealing with revision you can isolate the changes done between two commitments of a file.

CVS content after some releases
CVS content after some releases.

Creating an experimental branch

TODO

Exporting tagged releases as source tarballs

When you do a development release or an official release, you may want to offer a tarball containing the project files.

Because a working copy done with a ckeckout has, not only the project files but also some CVS administration files, is not a good idea to tarballing from it.

You can use the CVS 'export' subcommand that creates a clean copy of the project files with a concrete tag. So for a official release you will do:

cvs -d $CVSROOT export -r theapp_1_0_0_release -dtheapp mymodule
tar cvfz theapp1.1.0-src.tar.gz theapp/*

and for a development relese you will do:

cvs -d $CVSROOT export -r theapp_1_0_0_20020110-1 -dtheapp mymodule
tar cvfz theapp1.1.0-20020110-1-src.tar.gz theapp/*

Other CVS documentation

Multilingual terms glossary

The following table is provided to localize the project management vocabulary used on this tutorial. It is intended to help giving courses based on this tutorial but without abusing of english terms when native terms exists. I will be glad to receive additions, corrections and translations to your own languages.

EnglishSpanishCatalanYour Language Here
RepositoryRepositorioRepositori?
SandboxCopia de trabajoCòpia de treball?
MillestoneHitoFita?
ReleaseEntregaEntrega?
VersionVersiónVersió?
BranchRamaBranca?
TagMarcaMarca?
PolicyPolíticaPolítica?
TeamEquipoEquip?
Life cycleCiclo de vidaCicle de vida?
FeatureCaracterística, FuncionalidadCaracterística, Funcionalitat?
BugFalloFalla?
FixCorrecciónCorrecció?
MergeFusiónFusió?
DevelopDesarrollarDesenvolupar?
SnapshotInstantáneaInstantània?
PathRuta, LocalizaciónCamí, Localització?
CommitConfirmarConfirmar?
UpdateActualizarActualitzar?
CheckoutCrear copia de trabajoCrear còpia de treball?