Azure DevOps Rest Api. 24. View Team Project Release Definitions

To work with releases, you need to add the Microsoft.VisualStudio.Services.Release.Client package that contains ReleaseHttpClient. We consider the following operations here:

  • View release definitions of a team project
  • View releases of a team project
  • View work items and commits are referenced to a release

We can use the GetReleaseDefinitionsAsync method to get a release definitions list. The method may use only team project name as a parameter. If you want to limit a count of returning release definitions, you can use the searchText (to search by template) or path (to search by path). By default, the method returns the list only with basic information such as:

  • ID
  • Name
  • Description
  • Path
  • Etc.

If you want to see more details (such as environments and artifacts), you can specify that in the expand parameter. Example to get a release definitions list and configured environments:

var reldefList = ReleaseClient.GetReleaseDefinitionsAsync(teamProjectName, expand: ReleaseDefinitionExpands.Environments).Result;

foreach (var reldef in reldefList)

{

Console.WriteLine(“===========RELEASE DEFINITION==================================”);

Console.WriteLine(“ID: {0} PATH: {1} NAME: {2}”, reldef.Id, reldef.Path, reldef.Name);

Console.WriteLine(“—————————————————————“);

Console.Write(“STAGES:”);


if (reldef.Environments != null) foreach (var env in reldef.Environments) Console.Write(env.Name + “; “);

Console.WriteLine();

}

To get a list of created releases of a team project, we can use the GetReleasesAsync method with a team project name. The method returns all team project releases. If we want to find releases of a specific release definition, we can add a release definition id to the parameters. The resulting list also contains only a basic information. If you want see additional data (environments, artifacts, etc), you can specify that in the expand parameter. Example to get last 10 releases and state of their environments:

var rels = ReleaseClient.GetReleasesAsync(teamProjectName, reldefId, expand: ReleaseExpands.Environments, top: 10).Result;

foreach (var rel in rels)

{

Console.WriteLine(“———–RELEASE———————————————“);

Console.WriteLine(“ID: {0} REASON: {1} NAME: {2}”, rel.Id, rel.Reason, rel.Name);

Console.WriteLine(“—————————————————————“);

Console.WriteLine(“STAGES:”);


if (rel.Environments != null) foreach (var env in rel.Environments) Console.Write(env.Name + ” : “ + env.Status + “; “);

Console.WriteLine();

}

Additionally, we can find changes and items that were passed with a release. Here we should use BuildHttpClient with the GetBuildChangesAsync and GetBuildWorkItemsRefsAsync methods. These methods use a team project name and build id as parameters. If a release is linked to a build, that build will be in the Artifacts property and the Type member of the Artifact property should be equal to “Build”. In this case, we can find a build id in the DefinitionReference dictionary with “version” key. Example to view work items and commits of a release:

var relDetails = ReleaseClient.GetReleaseAsync(teamProjectName, relId).Result;

if (relDetails.Artifacts != null)

{


foreach (var artifact in relDetails.Artifacts)

{


if (artifact.Type == “Build”)

{


int buildId;


if (Int32.TryParse(artifact.DefinitionReference[“version”].Name, out buildId))

{


var commits = BuildClient.GetBuildChangesAsync(teamProjectName, buildId, top: 10).Result;


var workItems = BuildClient.GetBuildWorkItemsRefsAsync(teamProjectName, buildId, top: 10).Result;

Console.WriteLine(“BUILDID : {0}”, buildId);

Console.WriteLine(“COMMITS : {0}”, String.Join(“; “, from x in commits select x.Id.Substring(0, 8)));

Console.WriteLine(“WORK ITEMS: {0}”, String.Join(“; “, from x in workItems select x.Id));

}

}

}

}

The sample application:

https://github.com/ashamrai/TFRestApi/tree/master/24.TFRestApiAppExploreReleases

Clone Azure DevOps Work Items through REST API

Azure DevOps contains function of manual copy of work items Copy or clone work items. However if you need to clone several or several dozen work items, the manual method is not very easy way. Here we consider basic functions to clone work items through the Rest API client Microsoft.TeamFoundationServer.Client.

The operation includes two parts:

  1. Get all information about a work item.
  2. Pass the information into a new work item.

To get a work item, we can use the GetWorkItemAsync method. If we need only a list of fields, we use a work item id. To get work item links, add additional expand parameter with value: WorkItemExpand.Relations. Example:

WorkItem wiToClone = (CopyLink) ?

witClient.GetWorkItemAsync(wiIdToClone, expand: WorkItemExpand.Relations).Result

: witClient.GetWorkItemAsync(wiIdToClone).Result;

The list of fields is stored in the Fields property, the work item links are in the Relations property. Therefore, we can just copy this information into a new work item. However, some items should be skipped:

  1. System fields. As example, the System.Id and System.Rev fields are defined by the system, the System.State field may contain the Closed value. The list of these system field you can find at the end of this note.
  2. Automatically defined fields and fields not available on the Proposed state. As example, Azure DevOps sets a new value to the Microsoft.VSTS.Common.ActivatedDate field by internal rules of a work item type.
  3. Links with conflicts. As example, child links should be skipped because one child work item can have only one parent work item.

Then we can create a new work item with the CreateWorkItemAsync method. Example to copy fields and links and to create a new work item:

foreach (var key in wiToClone.Fields.Keys)

if (!systemFields.Contains(key) && !customFields.Contains(key))

patchDocument.Add(new JsonPatchOperation()

{

Operation = Operation.Add,

Path = “/fields/” + key,

Value = wiToClone.Fields[key]

});

foreach (var link in wiToClone.Relations)

{

if (link.Rel != ChildRefStr)

{

patchDocument.Add(new JsonPatchOperation()

{

Operation = Operation.Add,

Path = “/relations/-“,

Value = new

{

rel = link.Rel,

url = link.Url

}

});

}

}

WorkItem clonedWi = witClient.CreateWorkItemAsync(patchDocument, teamProjectName, wiType).Result;

Here is the full example: https://github.com/ashamrai/AzureDevOpsExtensions/tree/master/CustomNetTasks/CloneWorkItem

Additional references of the Rest API methods: