How to get the shelveset associated to queued CIs? - azure-devops-rest-api

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?

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!
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..
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.
picture below is associated with the following dimension tables:
DimBuild
DimChangeset
DimPerson
DimTeamProject
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

Related

List TFS Work Items during Jenkins Promote

I am looking for a way to produce all TFS Work Items from a Jenkins promote job.
We have an on prem deployment of TFS with service hooks in place to build the corresponding applications on check-in. The changeset Id is included with the notification, but I need the TFS work item for that Changeset.
More importantly - we will have several builds run; each with a singular changeset before we actuall run the promotion job.
What I would like to do is find a way to produce the list of TFS work items between releases. Looking a plug-in or tool that will help produce this.
Update
You should first get the built changeset info in Jenkins side.
There seems to be a build.changeSets variable which could retrieve all the changeset.
Then you could directly use rest api in TFS to query work items info from changeset ID. Detail steps kindly take a look at here: How to retrieve work items associated to a build in jenkins with pipeline?
According to your description, seems you just want to get all work items between releases (for example: the current release and a previous release).
Retrieve work items by calling
https://{account}.vsrm.visualstudio.com/[teamproject]/_apis/Release/releases/{current release id}/workitems?api-version=4.1-preview.1&baseReleaseId={release id}
It just return the id, url of work items, and then you need to get details of work item through Get a list of work items REST API.

Can i delete the Shelvesets created by TFS Build Service Account

I'm housekeeping the TFS Server and have 40,000 shelvesets of which 6,500 are for the Build Service Accounts.
I assume i can simple remove these as i don't think the builds will refer to old shelvesets.
I exported all current shelvesets.
Can someone confirm if we can just delete all of these? Or will we run into trouble if we want to run an old build
We are running TFS 2017.2
I don’t see any reason to keep them. Since commits should be occurring therefore giving you code history and reproducible builds.
If you delete a shelve set you cannot retrieve it latter for any old builds.
Shelve sets are not the same as code commits
Reference the MSDN documentation which applies to TFS 2017 and shelve sets for use cases.
the purpose is not to be a version history of code changes or
associate code with builds.Thats what commits are used for.
Shelve sets are temporary. However, no rule stopping you from keeping forever. Unlikely any value would be gained from so many
though.
there is not a need to reproduce a build with a shelf set that is older then your code release cycle because commits our occurring making the shelve sets moot.
#NOTE: I do not know why you would have the build agent doing code shelve sets. I would look at your build definition and take out anything automatically creating shelve sets.
Its always advised to find the details of shelveset unless you know its old enough to delete. You must be a shelveset owner, or your Administer shelved changes permission must be set to Allow as explained here. Shelveset commands to delete/find/list/... are listed here
TFS Sidekicks tool provides a dedicated UI for a number of clean-up actions, including old shelvesets till TFS2015. Not sure about its working in 2017

Is there a way to ask tfs what changesets were merge to form a changeset?

I'd like to see what changesets were merged to create a changeset on a branch in the history. This doesn't seem to be straight forward. I've tried to use the Track Changeset functionality, but I can't seem to see anything useful. I would also like it if I could do this from the command line so that I could potentially script a way to pull out appropriate changesets separately.
Edit
Ok, seems that using Timeline Tracking, I can get the changesets from the Track Changes feature. Now is there a way to do this from the command line?
Using Tracking Changeset window is the right way to View where and when changesets have been merged.
For the overview and some meaning of the elements in tracking changeset window, you could refer above link. And switch to timeline view will make the result more directly,clearly.
Afraid you could not do this through command line. There is a Merges Command, but could not specific a single changeset.
However, you could use TFS API to achieve this, take a look at below two similar questions:
Find changeset id parent of a branch in tfs
Is there a way to find out the source changeset from which a particular branch was created in TFS?
The answer contains a link to a blog post which contains many details, including TFS API and a custom command-line tool.

How can I filter TFS changeset history to exclude a certain user?

Is it possible to filter changesets in TFS 2012 to exclude the ones from a single user?
The commit history of the solution I currently work on contains quite a lot of noise due to an automated process making a commit each time a build is queued.
I'd like to filter it out to make the commit history more readable.
An alternative, try to install Team Foundation Sidekicks, and check History Sidekick. You can export the records to a .csv file and then filter the user in it:
There is no single query can achieve what you need. You may have to use TFS API.
If you want to get the changesets in a solution via TFS API. The folder history will be the simplest approach. Details please refer this: TFS client C# API - get all changesets of an Item You can exclude those changesets from the special user using Changeset.Committer Property which gets the user who committed the changeset.

TFS 2010 Build Work Items in a Certain State

We have been using TFS 2010 to manage work items and sprints for a while now and have recently added on a dedicated QA person. What I need to be able to do is to either create a build definition that I can run on a scheduled basis (Tuesdays at 9pm for instance) that will only build and/or deploy the Work Items that are in a State of "ReadyToDeploy". Or a way to get a list of files to push based on the TFS API.
My end goal is to have a way to automate the release process so that only the items that have passed QA are sent to our staging environment weekly. Then the customer or QA can approve that the items work in staging which is a mirror of production, and another process or build definition will deploy those items which will be in a different state.
I have modified the work items and work flows to accomplish the different states, but I am having an issue getting either a build of just the fixes or a list of all the files to push based on the state of the work item.
I am open to any ideas or solutions for this, the alternative is that I have to manage the list of files and manually push files every week and I am trying to get away from that.
Thanks,
Edit: The way we have it setup now, is that each developer has their own branch and own website, our software is server based and has to be run on a particular server. Our Trunk is linked to the main dev website. This is where QA initially does their testing to move an item to the ready to deploy status. When a dev is ready for QA they check in their changes in their branch and merge into the trunk. The builds are created off of the trunk at the moment. On our deployment nights I open up the trunk website in VS and do a publish then take those files compared against a list the developers have given me and ftp the compiled files to our production server.
I could be wrong, but I am not aware of a way to tell a build to avoid certain changesets based on the state of an attached work item.
I think the only way you could achieve this would be to create a Release branch and perform a daily merge of changesets that are in the "ReadyToDeploy" state. When you merge, you are able to cherry pick changesets, but they must be contiguous. This means that you would have to perform multiple merges to get the Release branch into the appropriate condition.
We have operated something similar for many years and it works well for us. Many people will tell you that it's bad practice, and it probably is, but that is for you to decide.
As for automating this for a build, I don't think it would be a trivial job. The hardest part will be the merge. You might think that there will be no conflicts as it is a one-way merge, but having done this for a number of years, I can tell you that conflicts do arise.
Step By Step Explanation
Create a branch off the trunk called release
When you want to do a deploy, merge from the trunk into release, but only cherry pick the ReadyToDeploy changesets. This may take several merges as the changesets must be contiguous.
Fire off a build / deploy of the release branch.
Repeat steps 2 - 3 as your release schedule allows.
You could do something automatic, it would require an extensive bit of coding. It would also require a branching strategy so that, Dev, Staging, and Production all come from their own branches.
Set up a process that uses the TFS API to scan for items in that state
Use API to Traverse Items to get check ins attached
Use API to Get latest of source and target branch
Use API to Merge by change set (identified in #2) (this is non trivial, have to handle lots of cases, but merging should all be 1 way with no conflicts, so doable)
Use API to Check In
Kick off Compile Build
If Compile Build Successful kick off Publish Build
To the best of my knowledge there is a major issue with this approach. Say you have two changesets: # 1 and 2. Both of them containing modification for the same file. Now changeset #2 contains its own changes plus changes from #1.
If you decide to pull in changeset 2 and skip #1 guess what's gonna happen. You are going to suck in changes from #1. This is obviously a problem.

Resources