A rather longish and detailed installation manual along with an example usage (well down below).


In order to use plug-in Tagmod, you need to fullfil the following requirements:

  • CruiseControl, any version should do.
  • CVS as source code repository (other repository types currently not supported)
  • Java +1.4
  • A UNIX like operating system (Solaris, Linux, MacOS) or a POSIX like interface (Cygwin). Tagmod is written in Java and operating system independent. Some necessary shell scripts however, requires porting.
  • You need to be able to plug-in a shell script into your CVS server. This requires administrator rights on the CVS server

How it works ..

Plug-in a shell script into your CVS installation. The script will keep a record of tag operations carried out by updating the log message of a dedicated CVS controlled file. Then, when a tag is added or deleted, the following command is essentially being executed on the CVS server side:

cvs commit -m "tag related info goes here"  path/to/tag.log

Doing so, the log message of file path/to/tag.log contains a chronological list of tag operations. This list can be easily queried from anywhere by

cvs rlog path/to/tag.log

In a second step CruiseControl needs to be configured. Each CruiseControl project whishing to be triggered by a tag operation uses a modificaton like

<tagmod project="foo/bar" />

where foo/bar is the project to be monitored and where tag.log is a local file, supposed to be updated periodically by a command like cvs rlog path/to/tag.log > tag.log. Updating this file could be done by a cron job for example or – much better – by using CruiseControl.

Below are the details of what exactly needs to be done.


The following naming conventions are used in the description following:

  • refers to be binary package of Tagmod in version x.y.
  • var/taglog/tag.log the name of a CVS controlled file keeping track of tag operations; the name of the file (tag.log) is hardwired and should not be changed, while the path (var/taglog) can be changed at will.
  • %cvs> should indicate that this operation needs to be carried out on the CVS server host.
  • %cc> indicates the machine hosting CruiseControl.
  • %any> indicates that this command can be executed from any host
  • /var/cvsroot is assumed to be the root folder of your CVS repository, i.e. the folder containing CVSROOT as sub folder.
  • foo/bar is assumed to be a buildable project in your CVS repository, i.e. the folder /var/cvsroot/foo/bar must exist on the CVS host. To be recognized as buildable project, at least on of the files build.xml,v, pom.xml,v, project.xml,v, Makefile,v or Rakefile,v must exist therein.

Configuring CVS

Determine and create a file in your CVS repository to hold a record of all tag operations. You can do this by

%cvs> mkdir dummy
%cvs> cd dummy
%cvs> echo > tag.log
%cvs> cvs import -m "tag.log initially created" var/taglog start init
%cvs> cd ..
%cvs> rm -rf dummy

Next, download and unzip the latest version of on your CVS host. Script sbin/ is the script that must be plugged into your CVS server. Now edit the configuration section of to your liking and start testing by running the script from the command line:

%cvs> unzip
%cvs> vi tagmod-x.y/sbin/   # or any other editor

Simulate a tag event by calling like

%cvs> tagmod-x.y/sbin/ r-1_0 add foo/bar /var/cvsroot

If all went well, project foo/bar must pop up in the tag.log’s log. You can verify this by querying the log like:

%any> cvs rlog var/taglog/tag.log | grep '0x1'
=> 0x1 p="foo/bar" o="add" D="[..]" U="[..]"

Otherwise you need to debug what went wrong (to do so you may want to set environment variable debug=true and watch file $TMP/taglog.log or you may want to excute the script like /bin/sh -x ..). What usually goes wrong here is that you are testing a project which is not identified as buildable (cause a build file is missing or not recognized).

At this point you have a working script. Well done so far. All what is on the CVS server left to be done is to save permanently and to plug it into your CVS server. As root, take a copy of this script and save it permanently. Make sure that the script is readable by your CVS server and also executable. For example:

%cvs> sudo cp tagmod-x.y/sbin/ /opt/sbin/
%cvs> sudo chmod 550 /opt/sbin/
%cvs> sudo chown cvs:cvs /opt/sbin/

Next we plug into CVS by

%cvs> cvs co CVSROOT
$cvs> echo "ALL /opt/sbin/ %t %o %p %r" >> CVSROOT/taginfo
%cvs> cvs commit -m "run on tag ops"  CVSROOT/taginfo

Now it’s again time to check this plug-in again. Do so by tagging a project of your choice and by checking that cvs rlog contains a tag log:

%any> cvs rtag r-2_0 foo/bar
%any> cvs rlog var/taglog/tag.log | grep 0x1

Puuh, the hardest part is done. Would be good to have things automated setup, though. Nevertheless, this setup needs to be carried out only once!

Setup CruiseControl

Download and unzip tagmod. Then, add tagmod-x.y.jar to CruiseControl’s classpath. An recommended way to do so is to create a folder for all additional libraries plugged into CruiseControl, save the jar therein and use option -lib folder; when starting up. This way you can switch to another version of CruiseControl without worrying what you stored into CruiseControl’s library folder. Then register plug-in tagmod to make it available like


This example shows the usage of all (but project) attributes available. Only name and classname are mandatory, all others are optional. In fact, the attribute values shown here are the default values and are listed for illustration purposes only. Once registered, tagmod would be used like shown next:

<project name="release-foo_bar">
 <modificationset quietperiod="0">
  <tagmod project="foo/bar"/>
 <schedule interval="5">
 <exec command="echo"
   args="*** make a release build for foo/bar using tag ${tagmod.tag}"/>

In this illustration example, the build of project foo/bar is a simple echo command which reports the tag to be used. Notice the usage of property tagmod.tag. This property is set by plug-in tagmod and passed down to build engines. When using build tools like Ant or Maven, this properties are automatically made available. Otherwise, they must be explicitly passed like shown above. See also here for further information and a list of properties made available.

Now, there is only one thing left to be done and this is to update regularly the file tag.log with the output of command cvs rlog var/taglog/tag.log. This could be done by a simple cron job or by CruiseControl itself. Since CruiseControl offers so many possibilities how and when to update, this is the recommended way. Add the following artificial project to the list of projects watched by CruiseControl:

<project name="update-tag-log">
 <modificationset quietperiod="0">
 <schedule interval="60">
  <exec workingdir = "." command="/bin/sh"
   args = " var/taglog/tag.log"
  <delete every="0" unit="DAY" ignoreSuffix="true" />

Adapt this project to your liking. The script being called here ( is a simple wrapper around cvs rlog $@ > tag.log since this command can’t be executed directly in CruiseControl. The script is part of the tagmod package (see folder sbin). In this example, must be in CruiseControl’s working directory to get it working. This will also be the folder in which tag.log is created and updated. You may want to change this to suit your needs.

It’s again time to check your setup by assigning a tag as done before:

%any> cvs rtag r-3_0 foo/bar

This time, a log message like *** build project with tag=r-3_0 will appear in CruiseControl’s log file and/or console output and you are done!