I am trying to get a particular build from TFS but it is frustratingly difficult. I have an MVC application that triggers a build like this:
IBuildServer buildServer = (IBuildServer)Server.GetService(typeof(IBuildServer));
IBuildDefinition def = buildServer.GetBuildDefinition(TeamProject, BuildDefinition);
var queuedBuild = buildServer.QueueBuild(def);
QueueBuild returns IQueuedBuild and I was hoping to do something like this:
return queuedBuild.Build.BuildNumber
So that I would have some unique value that I could use to query the build server with to get the correct build back. Unfortunately Build may or may not be null when execution exits this method so that is a no go.
After the build is queued I then poll this method
public string GetBuildStatus(string TeamProject, string BuildDefinition, string BuildNumber)
{
string status = string.Empty;
IBuildDetailSpec buildDetailSpec = buildServer.CreateBuildDetailSpec(TeamProject, BuildDefinition);
buildDetailSpec.MaxBuildsPerDefinition = 1;
buildDetailSpec.Status = BuildStatus.InProgress | BuildStatus.None;
buildDetailSpec.QueryOrder = BuildQueryOrder.FinishTimeDescending;
IBuildQueryResult queryResult = buildServer.QueryBuilds(buildDetailSpec);
if (queryResult.Builds.Length > 0)
{
status = queryResult.Builds[0].Status.ToString();
}
return status;
}
This works to some degree but if there are multiple builds in the queue I have no way of knowing in this polling method if the build I am working with is the one I queued in the first method. Does anyone have any idea what I could do to get back the specific build that is Queued up in the first method?
Thanks!
The key to this scenario is to use the ID of the queued build. So what I did was:
public int QueuBuild(string TeamProject, string BuildDefinition)
{
IBuildServer buildServer = (IBuildServer)Server.GetService(typeof(IBuildServer));
IBuildDefinition def = buildServer.GetBuildDefinition(TeamProject, BuildDefinition);
var queuedBuild = buildServer.QueueBuild(def);
return queuedBuild.Id;
}
Then in the polling method
public string GetBuildStatus(string TeamProject, string BuildDefinition, int BuildID)
{
IBuildServer buildServer = (IBuildServer)Server.GetService(typeof(IBuildServer));
string status = string.Empty;
IQueuedBuildSpec qbSpec = buildServer.CreateBuildQueueSpec(TeamProject, BuildDefinition);
IQueuedBuildQueryResult qbResults = buildServer.QueryQueuedBuilds(qbSpec);
if(qbResults.QueuedBuilds.Length > 0)
{
IQueuedBuild build = qbResults.QueuedBuilds.Where(x => x.Id == BuildID).FirstOrDefault();
status = build.Status.ToString();
}
return status;
}
Hope this helps someone down the road.
If a build is Queued waiting for an agent, you can call queueBuild.WaitForStart();
Then return the queryResult.Build.Uri;
property and use that to poll with, build number is not assigned straight away.
You can then use the method IBuildDetail buildDetail = server.GetBuild(buildUri);
to get the state of the build.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With