Search code examples
azure-devops-rest-apishelveset

How to get the shelveset associated to queued CIs?


Imagine this:

You have an Azure DevOps 2019 server and a XAML Build definition.

You queue a few check-ins to the build definition. The first one is in progress of being checked in, the rest are waiting in queue.

How does one using the REST API get the shelvesets of the queued builds?

It's easy to get the shelveset associated with the InProgress build, because there's a BuildID present. I use it to get more details on the build using the API, e.g.: "Builds/33217/Details". From there on, I can get to the shelveset.

If a build is queued (or NotStarted), then the build details API returns:

{
"value": [],
"count": 0
}

... and therefore I cannot get the shelveset.

I was under the impression that a upgrade to DevOps 2019 amends the API, so that one can easily get the queued shelveset from XAML build definitions as well. However, I'm not sure what I'm missing here. Should I be using another API?


Solution

  • Short answer ref Microsoft backlogged/doesn't exist/no easy way explained in option 1, but I used option 2, and option 3, I hope this helps you, I struggled a good bit!

    1. Underlying issue is that you're querying from 1) Bottom to Top in DevOps build Hierarchy/Object Model, and you need to 2) Associate the shelveSets versioned changeSet & then to the build.

    2. TLDR, I simply followed a practice of prefixing/Tags from my shelveSets allowing me to custom query the build as listed in option 3. This allowed me to simplify it a good bit in the REST API Query tagFilters={tagFilters} for e.g. ShelveSetBuildTag-....

     // now modify you REST API filter `ShelveSetBuildTag-....` 
     GET https://dev.azure.com/{organization}/{project}/_apis/build/builds?definitions={definitions}&queues={queues}&buildNumber={buildNumber}
      &tagFilters={tagFilters}&buildIds={buildIds}&repositoryId={repositoryId}&repositoryType={repositoryType}&api-version=6.0
    

    Option 1: No example so, MS build docs was clear as mud for me, and was not helpful but its listed as possible, I gave up and took a different route, below.. Azure Devops Shelvesets RESTAPI


    Option 2:

    since shelveSets are unversioned Azure DevOps uses versioned changeSets per their ER/DB Design , I had to get the associated shelveSets via ChangeSets/or WorkItems in a build.

    First, a nice article I found to help me understand the relationship and difference between two key items, changeSet vs shelveSet Azure DevOps in relation to a build. The changeSet will allow you to find associated shelvesets to build, query it and get DimChangeset, I suspect you have to do this in a couple of steps.

    FactBuildChangeset picture below is associated with the following dimension tables:

    • DimBuild
    • DimChangeset
    • DimPerson
    • DimTeamProject

    Picture to show Azure Devops ER Changeset has a relationship with Build Per MSDN

    IMHO versioning allows you get your changeset associated with a build, and then you can get the shelveset that went into that changeset


    Step 1: get changetSets for a ShelveSet

    GET https://dev.azure.com/fabrikam/_apis/tfvc/shelvesets/changes?shelvesetId=My first shelveset;d6245f20-2af8-44f4-9451-8107cb2767db&api-version=6.0

    Step 2: get

    GET the changes in a build https://{instance}/DefaultCollection/{project}/_apis/build/builds/{buildId}/changes?api-version={version}

    Step 3: I manually join the Response in my middle ware


    option 3:

    Follow a practice of tagging your shelveSets

    Then, you query, using tags filer: tagFilters={tagFilters} in your build query

    Use the tags from your shelvesets and filter from your builds list tagFilters={tagFilters} , of course this assume you setup tags

    // ``tagFilters={tagFilters}``for your shelveset assuming you set those up
    
    GET https://dev.azure.com/{organization}/{project}/_apis/build/builds?definitions={definitions}&queues={queues}&buildNumber={buildNumber}&minTime={minTime}&maxTime={maxTime}&requestedFor={requestedFor}&reasonFilter={reasonFilter}&statusFilter={statusFilter}&resultFilter={resultFilter}&tagFilters={tagFilters}&properties={properties}&$top={$top}&continuationToken={continuationToken}&maxBuildsPerDefinition={maxBuildsPerDefinition}&deletedFilter={deletedFilter}&queryOrder={queryOrder}&branchName={branchName}&buildIds={buildIds}&repositoryId={repositoryId}&repositoryType={repositoryType}&api-version=6.0