Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get a specific build with the TFS API

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!

like image 951
dparsons Avatar asked May 11 '12 19:05

dparsons


2 Answers

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.

like image 133
dparsons Avatar answered Sep 30 '22 17:09

dparsons


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.

like image 21
DaveShaw Avatar answered Sep 30 '22 18:09

DaveShaw