It's all about the answers!

Ask a question

Autoincrementing build numbers


Scott Chapman (3216547) | asked Sep 04 '08, 9:45 a.m.
In our current build environment we have a mechanism which creates autoincrementing buildnumbers.

I do not see anything similar in the Jazz build environment.

Am I missing something? How do folks do this?

6 answers



permanent link
Ryan Manwiller (1.3k1) | answered Sep 04 '08, 10:48 a.m.
JAZZ DEVELOPER
Jazz build doesn't have a mechanism to generate such build numbers. If using
the jazz build engine, the build label will be set to the default of
YYYYMMDD-HHMM, such as 20071031-1530. If you set the build property
buildLabelPrefix in the build definition, it will get prepended to that. For
example, if you set the prefix to I, the label will be I20071031-1530. The
prefix can be any string, it's not limited to 1 character.

You can change the build label from your build script using the
BuildResultPublisherTask
(https://jazz.net/jazzdocs/topic/com.ibm.team.build.doc/topics/r_buildresultpublisher.html)

If you are not using the jazz build engine, then the only way to set the
label is to use the BuildResultPublisherTask.


---
Ryan Manwiller
Jazz Team

permanent link
Alan Plante (4621) | answered Oct 29 '08, 12:02 p.m.
Prereqs:
Download the RTC SDK from the all downloads page and unzip somewhere.

1. Add a build.number property to your build definition
2. Compile the attached JazzVersion.java class including the RTC SDK in your classpath (sorry can't seem to attach anything, so it is at the bottom of this post) in order to create an ant task (see ant documentation on creating your own ant task and also how to include it into your build.xml). Alternatively you could modify this to not be an ant task - create a main method and pass in args. The code around authenticating/connecting was taken from the samples - the code in the execute method is what I put together. Use it however you wish but I make no guarantees.
3. To get the version number in your scripts:

Assumes you have userId and password properties
<buildResultPublisher repositoryAddress="${repositoryAddress}"
userId="${userId}"
password="${password}"
buildResultUUID="${buildResultUUID}"
label="${buildLabelPrefix}${build.number}" />

3. To bump the version number:

Assumes you have userId and password properties
<jazzVersion repositoryAddress="${repositoryAddress}"
userId="${userId}"
password="${password}"
buildDefinitionId="Your Build Definition Id" />

Keep in mind though that if there is some failure before the build result .publish runs, you will still see the built in Jazz built number in your Builds view

-----------------------------------------------------------------

package somepackage.taskdefs;

import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.Task;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.NullProgressMonitor;

import com.ibm.team.build.client.ITeamBuildClient;
import com.ibm.team.build.common.model.IBuildDefinition;
import com.ibm.team.build.common.model.IBuildProperty;
import com.ibm.team.build.internal.common.model.impl.BuildDefinitionImpl;
import com.ibm.team.repository.client.ITeamRepository;
import com.ibm.team.repository.client.TeamPlatform;
import com.ibm.team.repository.client.ITeamRepository.ILoginHandler;
import com.ibm.team.repository.client.ITeamRepository.ILoginHandler.ILoginInfo;
import com.ibm.team.repository.common.TeamRepositoryException;

public class JazzVersion extends Task{
public static ITeamRepository login(String repositoryURI, String userId, String password,
IProgressMonitor monitor)throws TeamRepositoryException{
ITeamRepository teamRepository = TeamPlatform.getTeamRepositoryService().getTeamRepository(repositoryURI);
teamRepository.registerLoginHandler(new LoginHandler(userId, password));
teamRepository.login(monitor);
return teamRepository;
}

private String _userId = "";
private String _password = "";
private String _repositoryAddress = "";
private String _buildDefinitionId = "";

public String getUserId(){ return _userId;}
public void setUserId(String value){ _userId = value;}
public String getPassword(){return _password;}
public void setPassword(String value){ _password = value;}
public String getRepositoryAddress(){return _repositoryAddress;}
public void setRepositoryAddress(String value){_repositoryAddress = value;}
public String getBuildDefinitionId(){return _buildDefinitionId;}
public void setBuildDefinitionId(String value){_buildDefinitionId = value;}

@Override
public void execute() throws BuildException{
TeamPlatform.startup();

IProgressMonitor monitor = new NullProgressMonitor();
ITeamRepository teamRepository = null;

try {
teamRepository = login(_repositoryAddress,
_userId, _password, monitor);
ITeamBuildClient buildClient = (ITeamBuildClient) teamRepository.getClientLibrary(ITeamBuildClient.class);
IBuildDefinition buildDefinition;
buildDefinition = buildClient.getBuildDefinition(_buildDefinitionId, monitor);
monitor = new NullProgressMonitor();

BuildDefinitionImpl item = (BuildDefinitionImpl)buildDefinition.getWorkingCopy();
item.setImmutable(false);
IBuildProperty prop = item.getProperty("build.number");
prop.setGenericEditAllowed(true); //Is this needed?
String versionStr = prop.getValue();
int version = Integer.parseInt(versionStr);
version++;
prop.setValue(String.valueOf(version));

buildClient.save(item, monitor);
} catch (TeamRepositoryException e) {
e.printStackTrace();
}
}

private static class LoginHandler implements ILoginHandler, ILoginInfo {
private String fUserId;
private String fPassword;

private LoginHandler(String userId, String password) {
fUserId = userId;
fPassword = password;
}

public String getUserId() {return fUserId; }
public String getPassword() {return fPassword;}
public ILoginInfo challenge(ITeamRepository repository) {return this;}
}
}


permanent link
Don Weinand (7851) | answered Oct 29 '08, 1:38 p.m.
JAZZ DEVELOPER
You could drastically simplify and pick up support for missing features(i.e.
using a password file, etc) in your task by deriving from the public
AbstractTeamBuildTask. It will take care of all the platform and login
related work for you automatically. In addition it handles exceptions and
logging in a consistent manner as well as provides a framework for
consistent attribute validation. Also...it's not good practice to use
anything in the internal packages especially the implementation classes from
any component's storage model(i.e.
com.ibm.team.build.internal.common.model.impl.BuildDefinitionImpl). You are
almost guaranteed to be broken at some point if you do. You should be able
to retrieve the properties using the public facade interface
IBuildDefinition. One last thing....getting the working copy automatically
puts the item into a state where it can be saved. There is no need to
manually set the immutable property yourself. I don't believe that method
would even be available to you when using the facade.

BuildDefinitionImpl item =
(BuildDefinitionImpl)buildDefinition.getWorkingCopy();
item.setImmutable(false);

Don Weinand
Jazz Team Build

P.S. You don't need this line either..."prop.setGenericEditAllowed(true);
//Is this needed?". It's used to let the property editor know if the the
property can be edited.


"andrealp99" <aplante> wrote in message
news:gea1ou$6hc$1@localhost.localdomain...
Prereqs:
Download the RTC SDK from the all downloads page and unzip somewhere.

1. Add a build.number property to your build definition
2. Compile the attached JazzVersion.java class including the RTC SDK
in your classpath (sorry can't seem to attach anything, so it is at
the bottom of this post) in order to create an ant task (see ant
documentation on creating your own ant task and also how to include
it into your build.xml). Alternatively you could modify this to not
be an ant task - create a main method and pass in args. The code
around authenticating/connecting was taken from the samples - the
code in the execute method is what I put together. Use it however
you wish but I make no guarantees.
3. To get the version number in your scripts:

Assumes you have userId and password properties
buildResultPublisher

3. To bump the version number:

Assumes you have userId and password properties
jazzVersion

Keep in mind though that if there is some failure before the build
result .publish runs, you will still see the built in Jazz built
number in your Builds view

-----------------------------------------------------------------

package somepackage.taskdefs;

import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.Task;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.NullProgressMonitor;

import com.ibm.team.build.client.ITeamBuildClient;
import com.ibm.team.build.common.model.IBuildDefinition;
import com.ibm.team.build.common.model.IBuildProperty;
import
com.ibm.team.build.internal.common.model.impl.BuildDefinitionImpl;
import com.ibm.team.repository.client.ITeamRepository;
import com.ibm.team.repository.client.TeamPlatform;
import com.ibm.team.repository.client.ITeamRepository.ILoginHandler;
import
com.ibm.team.repository.client.ITeamRepository.ILoginHandler.ILoginInfo;
import com.ibm.team.repository.common.TeamRepositoryException;

public class JazzVersion extends Task{
public static ITeamRepository login(String repositoryURI, String
userId, String password,
IProgressMonitor monitor)throws TeamRepositoryException{
ITeamRepository teamRepository =
TeamPlatform.getTeamRepositoryService().getTeamRepository(repositoryURI);
teamRepository.registerLoginHandler(new LoginHandler(userId,
password));
teamRepository.login(monitor);
return teamRepository;
}

private String _userId = "";
private String _password = "";
private String _repositoryAddress = "";
private String _buildDefinitionId = "";

public String getUserId(){ return _userId;}
public void setUserId(String value){ _userId =
value;}
public String getPassword(){return _password;}
public void setPassword(String value){ _password =
value;}
public String getRepositoryAddress(){return
_repositoryAddress;}
public void setRepositoryAddress(String
value){_repositoryAddress = value;}
public String getBuildDefinitionId(){return
_buildDefinitionId;}
public void setBuildDefinitionId(String
value){_buildDefinitionId = value;}

@Override
public void execute() throws BuildException{
TeamPlatform.startup();

IProgressMonitor monitor = new NullProgressMonitor();
ITeamRepository teamRepository = null;

try {
teamRepository = login(_repositoryAddress,
_userId, _password, monitor);
ITeamBuildClient buildClient = (ITeamBuildClient)
teamRepository.getClientLibrary(ITeamBuildClient.class);
IBuildDefinition buildDefinition;
buildDefinition =
buildClient.getBuildDefinition(_buildDefinitionId, monitor);
monitor = new NullProgressMonitor();

BuildDefinitionImpl item =
(BuildDefinitionImpl)buildDefinition.getWorkingCopy();
item.setImmutable(false);
IBuildProperty prop =
item.getProperty("build.number");
prop.setGenericEditAllowed(true); //Is this needed?
String versionStr = prop.getValue();
int version = Integer.parseInt(versionStr);
version++;
prop.setValue(String.valueOf(version));

buildClient.save(item, monitor);
} catch (TeamRepositoryException e) {
e.printStackTrace();
}
}

private static class LoginHandler implements ILoginHandler,
ILoginInfo {
private String fUserId;
private String fPassword;

private LoginHandler(String userId, String password)
{
fUserId = userId;
fPassword = password;
}

public String getUserId() {return fUserId;
}
public String getPassword() {return
fPassword;}
public ILoginInfo challenge(ITeamRepository
repository) {return this;}
}
}




permanent link
Alan Plante (4621) | answered Oct 29 '08, 3:19 p.m.
Cool. Thanks for the tips.

Any idea where I can get the source for the JavaClientApi or at least the javadocs?

permanent link
Alan Plante (4621) | answered Oct 29 '08, 3:59 p.m.
I'd say that using AbstractTeaamBuildTask as my base class cleaned things up. Thanks again!


package somepackage.taskdefs;

import java.util.List;

import org.apache.tools.ant.BuildException;
import org.eclipse.core.runtime.NullProgressMonitor;

import com.ibm.team.build.ant.task.AbstractTeamBuildTask;
import com.ibm.team.build.client.ITeamBuildClient;
import com.ibm.team.build.common.model.IBuildDefinition;
import com.ibm.team.build.common.model.IBuildProperty;
import com.ibm.team.repository.common.TeamRepositoryException;

public class JazzVersion extends AbstractTeamBuildTask{
private String _buildDefinitionId = "";
public String getBuildDefinitionId() {return _buildDefinitionId;}
public void setBuildDefinitionId(String value){ _buildDefinitionId = value; }

@Override
protected void collectAntAttributes(List antAttributes)
{
antAttributes.add(new AbstractTeamBuildTask.AntAttribute("buildDefinitionId", _buildDefinitionId, true));
}

@Override
public void doExecute() throws BuildException
{
try {
ITeamBuildClient buildClient = getTeamBuildClient();
IBuildDefinition buildDefinition = buildClient.getBuildDefinition(_buildDefinitionId, new NullProgressMonitor());

IBuildDefinition item = (IBuildDefinition)buildDefinition.getWorkingCopy();
IBuildProperty prop = item.getProperty("build.number");
String versionStr = prop.getValue();
int version = Integer.parseInt(versionStr);
version++;
prop.setValue(String.valueOf(version));

buildClient.save(item, new NullProgressMonitor());
} catch (TeamRepositoryException e) {

e.printStackTrace();
}
}
}

permanent link
Alan Plante (4621) | answered Oct 29 '08, 4:16 p.m.
Note to the initial poster - Keep in mind though that by not using the built in Jazz build numbers some other things end up not being tied together very nicely. For instance, up to the point that you run the buildresultpublisher, the label in the Builds view will show the Jazz label; only once you've published your custom label will it show up. Also, in the Contribution summary in the build results, the Snapshot that gets created uses the Jazz label.

Even though I've gone down this path myself and created support for it, I'm actually going to go back to just using the built-in version numbering.

Your answer


Register or to post your answer.


Dashboards and work items are no longer publicly available, so some links may be invalid. We now provide similar information through other means. Learn more here.