Create a draft release and start it using the TFS REST API

The code below uses the preview API to retrieve a release definition, create a new draft release from the latest build, update some variables, then activate the release and start the deployment on a specific environment.
It serves as a reference regarding how to use the RM API.

I used the following nuget packages:
<packages>
  <package id="Microsoft.AspNet.WebApi.Client" targetframework="net452" version="5.2.3"/>
  <package id="Microsoft.AspNet.WebApi.Core" targetframework="net452" version="5.2.3"/>
  <package id="Microsoft.IdentityModel.Clients.ActiveDirectory" targetframework="net452" version="3.14.1"/>
  <package id="Microsoft.TeamFoundation.DistributedTask.Common.Contracts" targetframework="net452" version="15.118.0-preview"/>
  <package id="Microsoft.TeamFoundationServer.Client" targetframework="net452" version="15.118.0-preview"/>
  <package id="Microsoft.Tpl.Dataflow" targetframework="net452" version="4.5.24"/>
  <package id="Microsoft.VisualStudio.Services.Client" targetframework="net452" version="15.118.0-preview"/>
  <package id="Microsoft.VisualStudio.Services.InteractiveClient" targetframework="net452" version="15.118.0-preview"/>
  <package id="Microsoft.VisualStudio.Services.Release.Client" targetframework="net452" version="15.118.0-preview"/>
  <package id="Microsoft.Web.Xdt" targetframework="net452" version="2.1.1"/>
  <package id="Newtonsoft.Json" targetframework="net452" version="10.0.3"/>
  <package id="NuGet.Core" targetframework="net452" version="2.14.0"/>
  <package id="System.IdentityModel.Tokens.Jwt" targetframework="net452" version="4.0.2.206221351"/>
  <package id="WindowsAzure.ServiceBus" targetframework="net452" version="3.3.2"/>
</packages>

I am using a Personal Access Token to access the instance.
Here is the code.

var serverUrl = new Uri("https://account.visualstudio.com");
var credentials = new VssBasicCredential("", PAT);
var teamProjectName = "[replace with team project name]";

using (var connection = new VssConnection(serverUrl, credentials))
using (var rmClient = connection.GetClient<ReleaseHttpClient2>())
using (var buildClient = connection.GetClient<BuildHttpClient>())
{
    // Get the first build definition
    var releaseDefinition = rmClient.GetReleaseDefinitionsAsync(teamProjectName, null, ReleaseDefinitionExpands.Artifacts).Result[0];
    var primaryArtifact = releaseDefinition.Artifacts.Where(a => a.IsPrimary).SingleOrDefault();
    var projectName = primaryArtifact.DefinitionReference["project"].Id;
    var buildDefinitionId = Convert.ToInt32(primaryArtifact.DefinitionReference["definition"].Id);

    // Get the latest successful build from the project and build definition id
    var lastBuild = buildClient.GetBuildsAsync(projectName, new[] { buildDefinitionId }, statusFilter: BuildStatus.Completed).Result
                                .OrderByDescending(b => b.Id)
                                .FirstOrDefault();

    // Create the draft release, and associate it to the latest corresponding build
    var metadata = new ReleaseStartMetadata
    {
        DefinitionId = releaseDefinition.Id,
        IsDraft = true,
        Description = "Draft",
        Artifacts = new[]
        {
            new ArtifactMetadata
            {
                Alias = primaryArtifact.Alias,
                InstanceReference = new BuildVersion
                {
                    Id = lastBuild.Id.ToString(),
                    Name = lastBuild.BuildNumber
                }
            }
        }
    };
    var release = rmClient.CreateReleaseAsync(metadata, teamProjectName).Result;

    // Update the draft release variable
    release.Variables["Variable-A"].Value = "Test A";
    release.Variables["Variable-B"].Value = "Test B";
    release.Environments[0].Variables["Var-Env-A"].Value = "Test C";
    release = rmClient.UpdateReleaseAsync(release, teamProjectName, release.Id).Result;

    // Activate the release
    var updateMetadata = new ReleaseUpdateMetadata { Status = ReleaseStatus.Active, Comment = "Yeah baby, yeah" };
    release = rmClient.UpdateReleaseResourceAsync(updateMetadata, teamProjectName, release.Id).Result;

    // Trigger the deployment on a specific environment
    release.Environments[0].Status = EnvironmentStatus.InProgress;
    release = rmClient.UpdateReleaseAsync(release, teamProjectName, release.Id).Result;

Popular posts from this blog

Handling exceptions the right way in WCF (part 2)

Adding a delay before processing Textbox events

Change the deployment URL of a ClickOnce application