cleanup from adding test project (#3)
* initial commit of Tapas.CICD.ReleaseHelper v0.5.3 * added Tapas.CICD.ReleaseHelper.Test * cleanup from adding test project
This commit is contained in:
Родитель
406e98cc6c
Коммит
73ea0ac6dd
|
@ -1,36 +0,0 @@
|
|||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
// General Information about an assembly is controlled through the following
|
||||
// set of attributes. Change these attribute values to modify the information
|
||||
// associated with an assembly.
|
||||
[assembly: AssemblyTitle("Tapas.CICD.ReleaseHelper")]
|
||||
[assembly: AssemblyDescription("")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("")]
|
||||
[assembly: AssemblyProduct("Tapas.CICD.ReleaseHelper")]
|
||||
[assembly: AssemblyCopyright("Copyright © 2018")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
|
||||
// Setting ComVisible to false makes the types in this assembly not visible
|
||||
// to COM components. If you need to access a type in this assembly from
|
||||
// COM, set the ComVisible attribute to true on that type.
|
||||
[assembly: ComVisible(false)]
|
||||
|
||||
// The following GUID is for the ID of the typelib if this project is exposed to COM
|
||||
[assembly: Guid("1c4ade56-13e8-4da8-93f0-ba62b3d5288c")]
|
||||
|
||||
// Version information for an assembly consists of the following four values:
|
||||
//
|
||||
// Major Version
|
||||
// Minor Version
|
||||
// Build Number
|
||||
// Revision
|
||||
//
|
||||
// You can specify all the values or you can default the Build and Revision Numbers
|
||||
// by using the '*' as shown below:
|
||||
// [assembly: AssemblyVersion("1.0.*")]
|
||||
[assembly: AssemblyVersion("1.0.0.0")]
|
||||
[assembly: AssemblyFileVersion("1.0.0.0")]
|
|
@ -1,139 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ProjectGuid>{1C4ADE56-13E8-4DA8-93F0-BA62B3D5288C}</ProjectGuid>
|
||||
<OutputType>Library</OutputType>
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<RootNamespace>Tapas.CICD.ReleaseHelper</RootNamespace>
|
||||
<AssemblyName>Tapas.CICD.ReleaseHelper</AssemblyName>
|
||||
<TargetFrameworkVersion>v4.6.1</TargetFrameworkVersion>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
<Deterministic>true</Deterministic>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DebugType>full</DebugType>
|
||||
<Optimize>false</Optimize>
|
||||
<OutputPath>bin\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<Optimize>true</Optimize>
|
||||
<OutputPath>bin\Release\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="Microsoft.IdentityModel.Clients.ActiveDirectory, Version=3.17.2.31801, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
|
||||
<HintPath>packages\Microsoft.IdentityModel.Clients.ActiveDirectory.3.17.2\lib\net45\Microsoft.IdentityModel.Clients.ActiveDirectory.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Microsoft.IdentityModel.Clients.ActiveDirectory.Platform, Version=3.17.2.31801, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
|
||||
<HintPath>packages\Microsoft.IdentityModel.Clients.ActiveDirectory.3.17.2\lib\net45\Microsoft.IdentityModel.Clients.ActiveDirectory.Platform.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Microsoft.IdentityModel.Logging, Version=5.2.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
|
||||
<HintPath>packages\Microsoft.IdentityModel.Logging.5.2.1\lib\net451\Microsoft.IdentityModel.Logging.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Microsoft.IdentityModel.Tokens, Version=5.2.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
|
||||
<HintPath>packages\Microsoft.IdentityModel.Tokens.5.2.1\lib\net451\Microsoft.IdentityModel.Tokens.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Microsoft.TeamFoundation.Build2.WebApi, Version=16.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
|
||||
<HintPath>packages\Microsoft.TeamFoundationServer.Client.16.140.0-preview\lib\net45\Microsoft.TeamFoundation.Build2.WebApi.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Microsoft.TeamFoundation.Common, Version=16.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
|
||||
<HintPath>packages\Microsoft.VisualStudio.Services.Client.16.140.0-preview\lib\net45\Microsoft.TeamFoundation.Common.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Microsoft.TeamFoundation.Core.WebApi, Version=16.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
|
||||
<HintPath>packages\Microsoft.TeamFoundationServer.Client.16.140.0-preview\lib\net45\Microsoft.TeamFoundation.Core.WebApi.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Microsoft.TeamFoundation.Dashboards.WebApi, Version=16.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
|
||||
<HintPath>packages\Microsoft.TeamFoundationServer.Client.16.140.0-preview\lib\net45\Microsoft.TeamFoundation.Dashboards.WebApi.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Microsoft.TeamFoundation.DistributedTask.Common.Contracts, Version=16.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
|
||||
<HintPath>packages\Microsoft.TeamFoundation.DistributedTask.Common.Contracts.16.140.0-preview\lib\net45\Microsoft.TeamFoundation.DistributedTask.Common.Contracts.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Microsoft.TeamFoundation.Policy.WebApi, Version=16.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
|
||||
<HintPath>packages\Microsoft.TeamFoundationServer.Client.16.140.0-preview\lib\net45\Microsoft.TeamFoundation.Policy.WebApi.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Microsoft.TeamFoundation.SourceControl.WebApi, Version=16.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
|
||||
<HintPath>packages\Microsoft.TeamFoundationServer.Client.16.140.0-preview\lib\net45\Microsoft.TeamFoundation.SourceControl.WebApi.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Microsoft.TeamFoundation.Test.WebApi, Version=16.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
|
||||
<HintPath>packages\Microsoft.TeamFoundationServer.Client.16.140.0-preview\lib\net45\Microsoft.TeamFoundation.Test.WebApi.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Microsoft.TeamFoundation.TestManagement.WebApi, Version=16.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
|
||||
<HintPath>packages\Microsoft.TeamFoundationServer.Client.16.140.0-preview\lib\net45\Microsoft.TeamFoundation.TestManagement.WebApi.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Microsoft.TeamFoundation.Wiki.WebApi, Version=16.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
|
||||
<HintPath>packages\Microsoft.TeamFoundationServer.Client.16.140.0-preview\lib\net45\Microsoft.TeamFoundation.Wiki.WebApi.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Microsoft.TeamFoundation.Work.WebApi, Version=16.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
|
||||
<HintPath>packages\Microsoft.TeamFoundationServer.Client.16.140.0-preview\lib\net45\Microsoft.TeamFoundation.Work.WebApi.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Microsoft.TeamFoundation.WorkItemTracking.Process.WebApi, Version=16.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
|
||||
<HintPath>packages\Microsoft.TeamFoundationServer.Client.16.140.0-preview\lib\net45\Microsoft.TeamFoundation.WorkItemTracking.Process.WebApi.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Microsoft.TeamFoundation.WorkItemTracking.WebApi, Version=16.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
|
||||
<HintPath>packages\Microsoft.TeamFoundationServer.Client.16.140.0-preview\lib\net45\Microsoft.TeamFoundation.WorkItemTracking.WebApi.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Microsoft.VisualStudio.Services.Client.Interactive, Version=16.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
|
||||
<HintPath>packages\Microsoft.VisualStudio.Services.InteractiveClient.16.140.0-preview\lib\net45\Microsoft.VisualStudio.Services.Client.Interactive.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Microsoft.VisualStudio.Services.Common, Version=16.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
|
||||
<HintPath>packages\Microsoft.VisualStudio.Services.Client.16.140.0-preview\lib\net45\Microsoft.VisualStudio.Services.Common.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Microsoft.VisualStudio.Services.ReleaseManagement.WebApi, Version=17.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
|
||||
<HintPath>packages\Microsoft.VisualStudio.Services.Release.Client.16.140.0-preview\lib\net45\Microsoft.VisualStudio.Services.ReleaseManagement.WebApi.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Microsoft.VisualStudio.Services.TestManagement.TestPlanning.WebApi, Version=16.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
|
||||
<HintPath>packages\Microsoft.TeamFoundationServer.Client.16.140.0-preview\lib\net45\Microsoft.VisualStudio.Services.TestManagement.TestPlanning.WebApi.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Microsoft.VisualStudio.Services.TestResults.WebApi, Version=16.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
|
||||
<HintPath>packages\Microsoft.TeamFoundationServer.Client.16.140.0-preview\lib\net45\Microsoft.VisualStudio.Services.TestResults.WebApi.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Microsoft.VisualStudio.Services.WebApi, Version=16.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
|
||||
<HintPath>packages\Microsoft.VisualStudio.Services.Client.16.140.0-preview\lib\net45\Microsoft.VisualStudio.Services.WebApi.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Newtonsoft.Json, Version=11.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
|
||||
<HintPath>packages\Newtonsoft.Json.11.0.2\lib\net45\Newtonsoft.Json.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Core" />
|
||||
<Reference Include="System.IdentityModel.Tokens.Jwt, Version=5.2.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
|
||||
<HintPath>packages\System.IdentityModel.Tokens.Jwt.5.2.1\lib\net451\System.IdentityModel.Tokens.Jwt.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Net.Http.Formatting, Version=5.2.3.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
|
||||
<HintPath>packages\Microsoft.AspNet.WebApi.Client.5.2.3\lib\net45\System.Net.Http.Formatting.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Runtime.Serialization" />
|
||||
<Reference Include="System.Web.Http, Version=5.2.3.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
|
||||
<HintPath>packages\Microsoft.AspNet.WebApi.Core.5.2.3\lib\net45\System.Web.Http.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System.Xml.Linq" />
|
||||
<Reference Include="System.Data.DataSetExtensions" />
|
||||
<Reference Include="Microsoft.CSharp" />
|
||||
<Reference Include="System.Data" />
|
||||
<Reference Include="System.Net.Http" />
|
||||
<Reference Include="System.Xml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="TfsRelease.CloneReleaseEnvironment.cs" />
|
||||
<Compile Include="TfsRelease.cs" />
|
||||
<Compile Include="TfsRelease.GetDeploymentErrors.cs" />
|
||||
<Compile Include="TfsRelease.GetTfsReleaseEnvironmentNames.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="app.config" />
|
||||
<None Include="packages.config" />
|
||||
<None Include="README.md" />
|
||||
<None Include="Tapas.CICD.ReleaseHelper.nuspec" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
</Project>
|
|
@ -1,18 +0,0 @@
|
|||
<?xml version="1.0"?>
|
||||
<package >
|
||||
<metadata>
|
||||
<id>$id$</id>
|
||||
<version>$version$</version>
|
||||
<title>$title$</title>
|
||||
<authors>$author$</authors>
|
||||
<owners>$author$</owners>
|
||||
<licenseUrl>https://github.com/Microsoft/release-helper</licenseUrl>
|
||||
<projectUrl>https://github.com/Microsoft/release-helper</projectUrl>
|
||||
<iconUrl>http://icon_url_here_or_delete_this_line/</iconUrl>
|
||||
<requireLicenseAcceptance>false</requireLicenseAcceptance>
|
||||
<description>$description$</description>
|
||||
<releaseNotes>Alpha version of release helper library</releaseNotes>
|
||||
<copyright>Copyright 2018</copyright>
|
||||
<tags>azuredevops tfs release</tags>
|
||||
</metadata>
|
||||
</package>
|
|
@ -1,251 +0,0 @@
|
|||
using Microsoft.VisualStudio.Services.ReleaseManagement.WebApi;
|
||||
using Microsoft.VisualStudio.Services.ReleaseManagement.WebApi.Contracts;
|
||||
using Newtonsoft.Json;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace Tapas.CICD.ReleaseHelper
|
||||
{
|
||||
public partial class TfsRelease
|
||||
{
|
||||
public string CloneReleaseEnvironment(string SourceEnvName, string TargetEnvName)
|
||||
{
|
||||
string result = "";
|
||||
|
||||
var definitions = relclient.GetReleaseDefinitionsAsync(TfsEnvInfo.ProjectName, TfsEnvInfo.ReleaseDefinitionName, ReleaseDefinitionExpands.Environments, isExactNameMatch: true).Result;
|
||||
|
||||
if (definitions.Count() > 0)
|
||||
{
|
||||
//This call is to get the project GUID
|
||||
var project = projclient.GetProject(TfsEnvInfo.ProjectName).Result;
|
||||
//This returns everything in a definition including properties such as Owner in an Environment
|
||||
var def = relclient.GetReleaseDefinitionAsync(project.Id, definitions.First().Id).Result;
|
||||
|
||||
var envcount = def.Environments.Count;
|
||||
|
||||
var defenvlist = def.Environments.Where(e => e.Name == SourceEnvName);
|
||||
if (defenvlist.Count() > 0)
|
||||
{
|
||||
var source = defenvlist.First();
|
||||
|
||||
var newrank = def.Environments.Select(e => e.Rank).ToList().Max() + 1;
|
||||
|
||||
if (def.Environments.Where(e => e.Name == TargetEnvName).Count() == 0)
|
||||
{
|
||||
//Environment must have a minimum RetentionPolicy, Rank, Owner,
|
||||
//PreDeployApprovals, PostDeployApprovals and DeployPhases
|
||||
var target = new ReleaseDefinitionEnvironment()
|
||||
{
|
||||
Name = TargetEnvName,
|
||||
RetentionPolicy = source.RetentionPolicy,
|
||||
Rank = newrank,
|
||||
Owner = source.Owner,
|
||||
PreDeployApprovals = source.PreDeployApprovals,
|
||||
PostDeployApprovals = source.PostDeployApprovals,
|
||||
DeployPhases = source.DeployPhases
|
||||
};
|
||||
def.Environments.Add(target);
|
||||
|
||||
var newdef = relclient.UpdateReleaseDefinitionAsync(def, project.Id).Result;
|
||||
|
||||
var envinfo = new TfsCloneReleaseEnvInfo()
|
||||
{
|
||||
ReleaseName = newdef.Name,
|
||||
EnvironmentName = target.Name,
|
||||
CloneFrom = SourceEnvName,
|
||||
RetentionPolicy = target.RetentionPolicy.ToString(),
|
||||
Rank = target.Rank,
|
||||
Owner = target.Owner.DisplayName,
|
||||
PreDeployApprovals = target.PreDeployApprovals.Approvals.Where(e => e.Approver != null).OrderBy(e => e.Approver.DisplayName).Select(e => e.Approver.DisplayName).ToArray(),
|
||||
PostDeployApprovals = target.PostDeployApprovals.Approvals.Where(e => e.Approver != null).OrderBy(e => e.Approver.DisplayName).Select(e => e.Approver.DisplayName).ToArray(),
|
||||
DeployPhases = target.DeployPhases.OrderBy(e => e.Name).Select(e => e.Name).ToArray(),
|
||||
success = (newdef.Environments.Count > envcount) ? true : false //Basic detection if environment was added
|
||||
};
|
||||
|
||||
result = JsonConvert.SerializeObject(envinfo, Formatting.Indented);
|
||||
}
|
||||
else { result = $"**Warning** An Env with name \"{TargetEnvName}\" already exists"; }
|
||||
}
|
||||
else { result = $"**Warning** Failed to find Env with name \"{SourceEnvName}\""; }
|
||||
}
|
||||
else { result = $"**Warning** Failed to find Release Definition with name \"{TfsEnvInfo.ReleaseDefinitionName}\""; }
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public string CloneReleaseEnvironment(string SourceEnvName, string TargetEnvName, int DeployGroupId)
|
||||
{
|
||||
string result = "";
|
||||
|
||||
var definitions = relclient.GetReleaseDefinitionsAsync(TfsEnvInfo.ProjectName, TfsEnvInfo.ReleaseDefinitionName, ReleaseDefinitionExpands.Environments, isExactNameMatch: true).Result;
|
||||
|
||||
if (definitions.Count() > 0)
|
||||
{
|
||||
//This call is to get the project GUID
|
||||
var project = projclient.GetProject(TfsEnvInfo.ProjectName).Result;
|
||||
//This returns everything in a definition including properties such as Owner in an Environment
|
||||
var def = relclient.GetReleaseDefinitionAsync(project.Id, definitions.First().Id).Result;
|
||||
|
||||
var envcount = def.Environments.Count;
|
||||
|
||||
var defenvlist = def.Environments.Where(e => e.Name == SourceEnvName);
|
||||
if (defenvlist.Count() > 0)
|
||||
{
|
||||
var source = defenvlist.First();
|
||||
|
||||
var newrank = def.Environments.Select(e => e.Rank).ToList().Max() + 1;
|
||||
|
||||
if (def.Environments.Where(e => e.Name == TargetEnvName).Count() == 0)
|
||||
{
|
||||
//Environment must have a minimum RetentionPolicy, Rank, Owner,
|
||||
//PreDeployApprovals, PostDeployApprovals and DeployPhases
|
||||
var target = new ReleaseDefinitionEnvironment()
|
||||
{
|
||||
Name = TargetEnvName + " - Clone from " + SourceEnvName,
|
||||
RetentionPolicy = source.RetentionPolicy,
|
||||
Rank = newrank,
|
||||
Owner = source.Owner,
|
||||
PreDeployApprovals = source.PreDeployApprovals,
|
||||
PostDeployApprovals = source.PostDeployApprovals
|
||||
};
|
||||
|
||||
//Clone phases and tasks
|
||||
var newphases = source.DeployPhases.ToList();
|
||||
|
||||
//Update deployment group name in phases
|
||||
foreach (var p in newphases)
|
||||
{
|
||||
if (p.PhaseType == DeployPhaseTypes.MachineGroupBasedDeployment)
|
||||
{
|
||||
var m = ((MachineGroupBasedDeployPhase)p);
|
||||
var inputs = m.GetDeploymentInput();
|
||||
var newinputs = (MachineGroupDeploymentInput)inputs.Clone();
|
||||
newinputs.QueueId = DeployGroupId;
|
||||
m.DeploymentInput = newinputs;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
target.DeployPhases = newphases;
|
||||
def.Environments.Add(target);
|
||||
var newdef = relclient.UpdateReleaseDefinitionAsync(def, project.Id).Result;
|
||||
|
||||
var envinfo = new TfsCloneReleaseEnvInfo()
|
||||
{
|
||||
ReleaseName = newdef.Name,
|
||||
EnvironmentName = target.Name,
|
||||
CloneFrom = SourceEnvName,
|
||||
RetentionPolicy = target.RetentionPolicy.ToString(),
|
||||
Rank = target.Rank,
|
||||
Owner = target.Owner.DisplayName,
|
||||
PreDeployApprovals = target.PreDeployApprovals.Approvals.Where(e => e.Approver != null).OrderBy(e => e.Approver.DisplayName).Select(e => e.Approver.DisplayName).ToArray(),
|
||||
PostDeployApprovals = target.PostDeployApprovals.Approvals.Where(e => e.Approver != null).OrderBy(e => e.Approver.DisplayName).Select(e => e.Approver.DisplayName).ToArray(),
|
||||
DeployPhases = target.DeployPhases.OrderBy(e => e.Name).Select(e => e.Name).ToArray(),
|
||||
success = (newdef.Environments.Count > envcount) ? true : false //Basic detection if environment was added
|
||||
};
|
||||
|
||||
result = JsonConvert.SerializeObject(envinfo, Formatting.Indented);
|
||||
}
|
||||
else { result = $"**Warning** An Env with name \"{TargetEnvName}\" already exists"; }
|
||||
}
|
||||
else { result = $"**Warning** Failed to find Env with name \"{SourceEnvName}\""; }
|
||||
}
|
||||
else { result = $"**Warning** Failed to find Release Definition with name \"{TfsEnvInfo.ReleaseDefinitionName}\""; }
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
public bool CloneReleaseEnvironment(string SourceEnvName, string TargetEnvName)
|
||||
{
|
||||
bool success = false;
|
||||
|
||||
var definitions = relclient.GetReleaseDefinitionsAsync(TfsEnvInfo.ProjectName, TfsEnvInfo.ReleaseDefinitionName, ReleaseDefinitionExpands.Environments, isExactNameMatch: true).Result;
|
||||
|
||||
//This call is to get the project GUID
|
||||
var project = projclient.GetProject(TfsEnvInfo.ProjectName).Result;
|
||||
//This returns everything in a definition including properties such as Owner in an Environment
|
||||
var def = relclient.GetReleaseDefinitionAsync(project.Id, definitions.First().Id).Result;
|
||||
|
||||
var envcount = def.Environments.Count;
|
||||
var source = def.Environments.Where(e => e.Name == SourceEnvName).First();
|
||||
|
||||
//Environment must have a minimum RetentionPolicy, Rank, Owner,
|
||||
//PreDeployApprovals, PostDeployApprovals and DeployPhases
|
||||
var target = new ReleaseDefinitionEnvironment()
|
||||
{
|
||||
Name = TargetEnvName,
|
||||
RetentionPolicy = source.RetentionPolicy,
|
||||
Rank = source.Rank++,
|
||||
Owner = source.Owner,
|
||||
PreDeployApprovals = source.PreDeployApprovals,
|
||||
PostDeployApprovals = source.PostDeployApprovals,
|
||||
DeployPhases = source.DeployPhases
|
||||
};
|
||||
def.Environments.Add(target);
|
||||
var newdef = relclient.UpdateReleaseDefinitionAsync(def, project.Id).Result;
|
||||
|
||||
//Basic detection if environment was added
|
||||
if (newdef.Environments.Count > envcount)
|
||||
success = true;
|
||||
|
||||
return success;
|
||||
}
|
||||
*/
|
||||
/*
|
||||
public bool CloneReleaseEnvironment(string SourceEnvName, string TargetEnvName, int DeployGroupId)
|
||||
{
|
||||
bool success = false;
|
||||
|
||||
//This call is to get the project GUID
|
||||
var project = projclient.GetProject(TfsEnvInfo.ProjectName).Result;
|
||||
//This returns everything in a definition including properties such as Owner in an Environment
|
||||
var def = relclient.GetReleaseDefinitionAsync(project.Id, TfsEnvInfo.ReleaseDefinitionID).Result;
|
||||
|
||||
var envcount = def.Environments.Count;
|
||||
var source = def.Environments.Where(e => e.Name == SourceEnvName).First();
|
||||
var newrank = def.Environments.Select(e => e.Rank).ToList().Max() + 1;
|
||||
|
||||
//Environment must have a minimum RetentionPolicy, Rank, Owner,
|
||||
//PreDeployApprovals, PostDeployApprovals and DeployPhases
|
||||
var target = new ReleaseDefinitionEnvironment()
|
||||
{
|
||||
Name = TargetEnvName + " - Clone from " + SourceEnvName,
|
||||
RetentionPolicy = source.RetentionPolicy,
|
||||
Rank = newrank,
|
||||
Owner = source.Owner,
|
||||
PreDeployApprovals = source.PreDeployApprovals,
|
||||
PostDeployApprovals = source.PostDeployApprovals
|
||||
};
|
||||
|
||||
//Clone phases and tasks
|
||||
var newphases = source.DeployPhases.ToList();
|
||||
|
||||
//Update deployment group name in phases
|
||||
foreach (var p in newphases)
|
||||
{
|
||||
if (p.PhaseType == DeployPhaseTypes.MachineGroupBasedDeployment)
|
||||
{
|
||||
var m = ((MachineGroupBasedDeployPhase)p);
|
||||
var inputs = m.GetDeploymentInput();
|
||||
var newinputs = (MachineGroupDeploymentInput)inputs.Clone();
|
||||
newinputs.QueueId = DeployGroupId;
|
||||
m.DeploymentInput = newinputs;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
target.DeployPhases = newphases;
|
||||
def.Environments.Add(target);
|
||||
var newdef = relclient.UpdateReleaseDefinitionAsync(def, project.Id).Result;
|
||||
|
||||
//Basic detection if environment was added
|
||||
if (newdef.Environments.Count > envcount)
|
||||
success = true;
|
||||
|
||||
return success;
|
||||
}
|
||||
*/
|
||||
}
|
||||
}
|
|
@ -1,254 +0,0 @@
|
|||
using Microsoft.VisualStudio.Services.ReleaseManagement.WebApi.Contracts;
|
||||
using Microsoft.VisualStudio.Services.ReleaseManagement.WebApi;
|
||||
using Newtonsoft.Json;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.IO;
|
||||
using System;
|
||||
|
||||
namespace Tapas.CICD.ReleaseHelper
|
||||
{
|
||||
public partial class TfsRelease
|
||||
{
|
||||
public string GetDeploymentErrors(int PastInstances)
|
||||
{
|
||||
string result = "";
|
||||
List<TfsReleaseError> errorlist = new List<TfsReleaseError>();
|
||||
Dictionary<string, string> inputs = new Dictionary<string, string>();
|
||||
|
||||
var def = relclient.GetReleaseDefinitionsAsync(TfsEnvInfo.ProjectName, TfsEnvInfo.ReleaseDefinitionName, isExactNameMatch: true).Result;
|
||||
|
||||
if (def.Count() > 0)
|
||||
{
|
||||
var id = def.First().Id;
|
||||
|
||||
var runs = relclient.GetDeploymentsAsync(project: TfsEnvInfo.ProjectName, definitionId: id, deploymentStatus: DeploymentStatus.Failed, operationStatus: DeploymentOperationStatus.PhaseFailed, queryOrder: ReleaseQueryOrder.Descending, top: PastInstances).Result;
|
||||
|
||||
foreach (var run in runs)
|
||||
{
|
||||
var rel = relclient.GetReleaseAsync(TfsEnvInfo.ProjectName, run.Release.Id).Result;
|
||||
var env = rel.Environments.First(e => e.Id == run.ReleaseEnvironmentReference.Id);
|
||||
var attempt = env.DeploySteps.First(s => s.Attempt == run.Attempt);
|
||||
var phase = attempt.ReleaseDeployPhases.First(p => p.Status == DeployPhaseStatus.Failed);
|
||||
|
||||
//assumption here is each phase has only one job that failed
|
||||
var job = phase.DeploymentJobs.First(j => j.Job.Status == Microsoft.VisualStudio.Services.ReleaseManagement.WebApi.TaskStatus.Failed);
|
||||
var failedtask = job.Tasks.Where(t => t.Status == Microsoft.VisualStudio.Services.ReleaseManagement.WebApi.TaskStatus.Failed).First();
|
||||
|
||||
var error = new TfsReleaseError()
|
||||
{
|
||||
ReleaseName = rel.Name,
|
||||
EnvironmentName = env.Name,
|
||||
Attempt = attempt.Attempt,
|
||||
PhaseType = phase.PhaseType.ToString(),
|
||||
AgentName = failedtask.AgentName,
|
||||
TaskName = failedtask.Name,
|
||||
StartTime = failedtask.StartTime,
|
||||
FinishTime = failedtask.FinishTime,
|
||||
ErrorMessages = failedtask.Issues.Where(i => i.Message != "").Select(i => i.Message).ToArray()
|
||||
};
|
||||
|
||||
var snapshot = env.DeployPhasesSnapshot.First(dps => dps.Rank == phase.Rank);
|
||||
if (failedtask.Task != null) //failing at download artifacts
|
||||
{
|
||||
inputs = snapshot.WorkflowTasks.First(w => w.TaskId == failedtask.Task.Id).Inputs;
|
||||
}
|
||||
|
||||
error.TaskInputs = inputs;
|
||||
|
||||
List<TfsArtifact> artifacts = new List<TfsArtifact>();
|
||||
foreach (var a in rel.Artifacts)
|
||||
{
|
||||
var build = a.DefinitionReference.Where(d => d.Key == "version").Select(v => v.Value.Name).First();
|
||||
var buildurl = a.DefinitionReference.Where(d => d.Key == "artifactSourceVersionUrl").Select(v => v.Value.Id).First();
|
||||
artifacts.Add(new TfsArtifact()
|
||||
{
|
||||
Build = build,
|
||||
BuildUrl = buildurl
|
||||
});
|
||||
}
|
||||
error.Artifacts = artifacts.ToArray();
|
||||
|
||||
errorlist.Add(error);
|
||||
}
|
||||
|
||||
//To download all logs for a given release
|
||||
//docs: https://docs.microsoft.com/en-us/rest/api/vsts/release/releases/get%20logs?view=vsts-rest-4.1
|
||||
//GET https://{accountName}.vsrm.visualstudio.com/{project}/_apis/release/releases/{releaseId}/logs?api-version=4.1-preview.2
|
||||
//client.DownloadFile(rel.LogsContainerUrl, rel.Name + ".zip");
|
||||
//The return data seems to have bad encoding; looks like a bug
|
||||
//var logs = tfsclient.GetLogsAsync(tfsinfo.ProjectName, id).Result;
|
||||
|
||||
//Handle case when no errors are found
|
||||
if (errorlist.Count > 0)
|
||||
{
|
||||
result = JsonConvert.SerializeObject(errorlist, Formatting.Indented);
|
||||
}
|
||||
else { result = $"**Warning** No errors found"; }
|
||||
}
|
||||
else { result = $"**Warning** Failed to find Release Definition with name \"{TfsEnvInfo.ReleaseDefinitionName}\""; }
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public string GetLatestError()
|
||||
{
|
||||
string result = "";
|
||||
List<TfsReleaseError> errorlist = new List<TfsReleaseError>();
|
||||
|
||||
var deflist = relclient.GetReleaseDefinitionsAsync(TfsEnvInfo.ProjectName, TfsEnvInfo.ReleaseDefinitionName, isExactNameMatch: true, expand: ReleaseDefinitionExpands.Environments).Result;
|
||||
|
||||
if (deflist.Count() > 0)
|
||||
{
|
||||
var def = deflist.First();
|
||||
var defenvlist = def.Environments.Where(e => e.Name == TfsEnvInfo.EnvironmentName);
|
||||
|
||||
if (defenvlist.Count() > 0)
|
||||
{
|
||||
var defenv = defenvlist.First();
|
||||
var rellist = relclient.GetReleasesAsync(def.Id, defenv.Id).Result;
|
||||
|
||||
if (rellist.Count() > 0)
|
||||
{
|
||||
var rel = rellist.Where(r => r.Name == TfsEnvInfo.ReleaseName);
|
||||
|
||||
if (rel.Count() > 0)
|
||||
{
|
||||
var relid = rel.First().Id;
|
||||
var reldetails = relclient.GetReleaseAsync(TfsEnvInfo.ProjectName, relid).Result;
|
||||
var env = reldetails.Environments.Where(e => e.Name == TfsEnvInfo.EnvironmentName).First();
|
||||
var steplist = env.DeploySteps.Where(s => s.Status == DeploymentStatus.Failed);
|
||||
|
||||
foreach (var step in steplist)
|
||||
{
|
||||
//assuming only one phase that fails in any one deployment
|
||||
var phase = step.ReleaseDeployPhases.Where(p => p.Status == DeployPhaseStatus.Failed).First();
|
||||
//assumption here is each phase has only one job that failed
|
||||
var job = phase.DeploymentJobs.First(j => j.Job.Status == TaskStatus.Failed);
|
||||
var failedtask = job.Tasks.Where(t => t.Status == TaskStatus.Failed).First();
|
||||
var error = new TfsReleaseError()
|
||||
{
|
||||
ReleaseName = reldetails.Name,
|
||||
EnvironmentName = env.Name,
|
||||
Attempt = step.Attempt,
|
||||
PhaseType = phase.PhaseType.ToString(),
|
||||
AgentName = failedtask.AgentName,
|
||||
TaskName = failedtask.Name,
|
||||
StartTime = failedtask.StartTime,
|
||||
FinishTime = failedtask.FinishTime,
|
||||
ErrorMessages = failedtask.Issues.Where(i => i.Message != "").Select(i => i.Message).ToArray()
|
||||
};
|
||||
|
||||
var logstream = relclient.GetTaskLogAsync(TfsEnvInfo.ProjectName, reldetails.Id, env.Id, phase.Id, failedtask.Id).Result;
|
||||
var reader = new StreamReader(logstream);
|
||||
var logstring = reader.ReadToEnd();
|
||||
|
||||
var lines = logstring.Replace("\n", "").Split('\r');
|
||||
|
||||
var errorindex = Array.FindIndex(lines, l => l.Contains(error.ErrorMessages.First()));
|
||||
string logsample = "";
|
||||
var samplelength = 10;
|
||||
int begin = (errorindex - samplelength) > 0 ? (errorindex - samplelength) : 0;
|
||||
int end = (errorindex + samplelength) < lines.Length ? (errorindex + samplelength) : lines.Length;
|
||||
for (int i = begin; i < end; i++)
|
||||
{
|
||||
logsample += lines[i];
|
||||
}
|
||||
|
||||
error.ErrorLog = logstring;
|
||||
errorlist.Add(error);
|
||||
}
|
||||
|
||||
//Handle case when no errors are found
|
||||
if (errorlist.Count > 0)
|
||||
{
|
||||
result = JsonConvert.SerializeObject(errorlist, Formatting.Indented);
|
||||
}
|
||||
else { result = $"**Warning** No errors found"; }
|
||||
}
|
||||
else { result = $"**Warning** Failed to find Release Details with name \"{TfsEnvInfo.ReleaseName}\""; }
|
||||
}
|
||||
else { result = $"**Warning** Failed to find Release with name \"{TfsEnvInfo.ReleaseName}\""; }
|
||||
}
|
||||
else { result = $"**Warning** Failed to find Env with name \"{TfsEnvInfo.EnvironmentName}\""; }
|
||||
}
|
||||
else { result = $"**Warning** Failed to find Release Definition with name \"{TfsEnvInfo.ReleaseDefinitionName}\""; }
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public string GetDeploymentErrors(DateTime mindate, DateTime maxdate)
|
||||
{
|
||||
string result = "";
|
||||
List<TfsReleaseError> errorlist = new List<TfsReleaseError>();
|
||||
Dictionary<string, string> inputs = new Dictionary<string, string>();
|
||||
|
||||
var runs = relclient.GetDeploymentsAsync(project: TfsEnvInfo.ProjectName, minStartedTime: mindate, maxStartedTime: maxdate, deploymentStatus: DeploymentStatus.Failed, operationStatus: DeploymentOperationStatus.PhaseFailed, queryOrder: ReleaseQueryOrder.Descending).Result;
|
||||
|
||||
foreach (var run in runs)
|
||||
{
|
||||
var rel = relclient.GetReleaseAsync(TfsEnvInfo.ProjectName, run.Release.Id).Result;
|
||||
var env = rel.Environments.First(e => e.Id == run.ReleaseEnvironmentReference.Id);
|
||||
var attempt = env.DeploySteps.First(s => s.Attempt == run.Attempt);
|
||||
var phase = attempt.ReleaseDeployPhases.First(p => p.Status == DeployPhaseStatus.Failed);
|
||||
|
||||
//assumption here is each phase has only one job that failed
|
||||
var job = phase.DeploymentJobs.First(j => j.Job.Status == TaskStatus.Failed);
|
||||
var failedtask = job.Tasks.Where(t => t.Status == TaskStatus.Failed).First();
|
||||
|
||||
//GetDeploymentsAsync return top 50 regardless of minStartedTime or maxStartedTime
|
||||
//looks like a bug
|
||||
if (failedtask.StartTime >= mindate && failedtask.StartTime <= maxdate)
|
||||
{
|
||||
var error = new TfsReleaseError()
|
||||
{
|
||||
ReleaseName = rel.Name,
|
||||
EnvironmentName = env.Name,
|
||||
Attempt = attempt.Attempt,
|
||||
PhaseType = phase.PhaseType.ToString(),
|
||||
AgentName = failedtask.AgentName,
|
||||
TaskName = failedtask.Name,
|
||||
StartTime = failedtask.StartTime,
|
||||
FinishTime = failedtask.FinishTime,
|
||||
ErrorMessages = failedtask.Issues.Where(i => i.Message != "").Select(i => i.Message).ToArray()
|
||||
};
|
||||
|
||||
var snapshot = env.DeployPhasesSnapshot.First(dps => dps.Rank == phase.Rank);
|
||||
if (failedtask.Task != null) //failing at download artifacts
|
||||
{
|
||||
inputs = snapshot.WorkflowTasks.First(w => w.TaskId == failedtask.Task.Id).Inputs;
|
||||
}
|
||||
|
||||
error.TaskInputs = inputs;
|
||||
|
||||
List<TfsArtifact> artifacts = new List<TfsArtifact>();
|
||||
foreach (var a in rel.Artifacts)
|
||||
{
|
||||
var build = a.DefinitionReference.Where(d => d.Key == "version").Select(v => v.Value.Name).First();
|
||||
var q = a.DefinitionReference.Where(d => d.Key == "artifactSourceVersionUrl").Select(v => v.Value.Id);
|
||||
var buildurl = (q.Count() > 0) ? q.First() : "";
|
||||
artifacts.Add(new TfsArtifact()
|
||||
{
|
||||
Build = build,
|
||||
BuildUrl = buildurl
|
||||
});
|
||||
}
|
||||
error.Artifacts = artifacts.ToArray();
|
||||
|
||||
errorlist.Add(error);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//Handle case when no errors are found
|
||||
if (errorlist.Count > 0)
|
||||
{
|
||||
result = JsonConvert.SerializeObject(errorlist, Formatting.Indented);
|
||||
}
|
||||
else { result = $"**Warning** No errors found"; }
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,40 +0,0 @@
|
|||
using Microsoft.VisualStudio.Services.ReleaseManagement.WebApi.Contracts;
|
||||
using Newtonsoft.Json;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace Tapas.CICD.ReleaseHelper
|
||||
{
|
||||
public partial class TfsRelease
|
||||
{
|
||||
public string GetTfsReleaseEnvironmentNames()
|
||||
{
|
||||
string result = "";
|
||||
var definitions = relclient.GetReleaseDefinitionsAsync(TfsEnvInfo.ProjectName, TfsEnvInfo.ReleaseDefinitionName, ReleaseDefinitionExpands.Environments, isExactNameMatch: true).Result;
|
||||
if (definitions.Count() > 0)
|
||||
{
|
||||
var def = definitions.First();
|
||||
|
||||
var releaseinfo = new TfsReleaseInfo()
|
||||
{
|
||||
ReleaseName = def.Name,
|
||||
ReleaseNameFormat = def.Name,
|
||||
Comment = def.Comment,
|
||||
IsDeleted = def.IsDeleted,
|
||||
ModifiedOn = def.ModifiedOn,
|
||||
ModifiedBy = def.ModifiedBy.DisplayName,
|
||||
CreatedOn = def.CreatedOn,
|
||||
CreatedBy = def.CreatedBy.DisplayName,
|
||||
Description = def.Description,
|
||||
Revision = def.Revision,
|
||||
EnvironmentNames = def.Environments.OrderBy(e => e.Name).Select(e => e.Name).ToArray()
|
||||
};
|
||||
|
||||
result = JsonConvert.SerializeObject(releaseinfo, Formatting.Indented);
|
||||
}
|
||||
else { result = $"**Warning** Failed to find Release Definition with name \"{TfsEnvInfo.ReleaseDefinitionName}\""; }
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
176
TfsRelease.cs
176
TfsRelease.cs
|
@ -1,176 +0,0 @@
|
|||
using Microsoft.TeamFoundation.Core.WebApi;
|
||||
using Microsoft.VisualStudio.Services.Client;
|
||||
using Microsoft.VisualStudio.Services.Common;
|
||||
using Microsoft.VisualStudio.Services.ReleaseManagement.WebApi.Clients;
|
||||
using Microsoft.VisualStudio.Services.WebApi;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Net;
|
||||
|
||||
namespace Tapas.CICD.ReleaseHelper
|
||||
{
|
||||
//Sample output
|
||||
//release name: Release_20181017.1
|
||||
//phase type: PhaseDeployment
|
||||
//attempt #: 1
|
||||
//agent name: BUILD_Agent1
|
||||
//task name: Build Solution
|
||||
//task starttime: 10/17/2018 10:22:20 PM
|
||||
//task endtime: 10/17/2018 10:22:32 PM
|
||||
//errors messages:
|
||||
// Issues[0].Message
|
||||
// Issues[1].Message
|
||||
// Issues[2].Message
|
||||
|
||||
public struct TfsReleaseError
|
||||
{
|
||||
public string ReleaseName;
|
||||
public string EnvironmentName;
|
||||
public string PhaseType;
|
||||
public int Attempt;
|
||||
public string AgentName;
|
||||
public string TaskName;
|
||||
public DateTime? StartTime;
|
||||
public DateTime? FinishTime;
|
||||
public string[] ErrorMessages;
|
||||
public string ErrorLog;
|
||||
public Dictionary<string, string> TaskInputs;
|
||||
public TfsArtifact[] Artifacts;
|
||||
}
|
||||
|
||||
public struct TfsArtifact
|
||||
{
|
||||
public string Build;
|
||||
public string BuildUrl;
|
||||
}
|
||||
|
||||
public struct TfsInfo
|
||||
{
|
||||
public string ProjectCollectionUrl;
|
||||
public string ProjectName;
|
||||
public string ReleaseDefinitionName;
|
||||
public int ReleaseDefinitionID;
|
||||
public string ReleaseName;
|
||||
public string EnvironmentName;
|
||||
}
|
||||
|
||||
public struct TfsCloneReleaseEnvInfo
|
||||
{
|
||||
public string ReleaseName;
|
||||
public string EnvironmentName;
|
||||
public string CloneFrom;
|
||||
public string RetentionPolicy;
|
||||
public int Rank;
|
||||
public string Owner;
|
||||
public string[] PreDeployApprovals;
|
||||
public string[] PostDeployApprovals;
|
||||
public string[] DeployPhases;
|
||||
public bool success;
|
||||
}
|
||||
|
||||
public struct TfsReleaseInfo
|
||||
{
|
||||
public string ReleaseName;
|
||||
public string Comment;
|
||||
public string ReleaseNameFormat;
|
||||
public bool IsDeleted;
|
||||
public DateTime ModifiedOn;
|
||||
public string ModifiedBy;
|
||||
public DateTime CreatedOn;
|
||||
public string CreatedBy;
|
||||
public string Description;
|
||||
public int Revision;
|
||||
public string[] EnvironmentNames;
|
||||
}
|
||||
|
||||
public partial class TfsRelease : IDisposable
|
||||
{
|
||||
// Dispose pattern. Refer https://msdn.microsoft.com/en-us/library/system.idisposable(v=vs.110).aspx
|
||||
// Track whether Dispose has been called.
|
||||
private bool disposed = false;
|
||||
|
||||
private WebClient client;
|
||||
private ReleaseHttpClient relclient;
|
||||
private ProjectHttpClient projclient;
|
||||
|
||||
public TfsInfo TfsEnvInfo { get; internal set; }
|
||||
|
||||
public TfsRelease(TfsInfo TfsEnvInfo)
|
||||
{
|
||||
this.TfsEnvInfo = TfsEnvInfo;
|
||||
|
||||
// Interactively ask the user for credentials, caching them so the user isn't constantly prompted
|
||||
VssCredentials credentials = new VssClientCredentials();
|
||||
credentials.Storage = new VssClientCredentialStorage();
|
||||
|
||||
VssConnection connection = new VssConnection(new Uri(this.TfsEnvInfo.ProjectCollectionUrl), credentials);
|
||||
relclient = connection.GetClient<ReleaseHttpClient>();
|
||||
projclient = connection.GetClient<ProjectHttpClient>();
|
||||
|
||||
client = new WebClient();
|
||||
client.Credentials = credentials.Windows.Credentials;
|
||||
|
||||
}
|
||||
|
||||
public TfsRelease(TfsInfo TfsEnvInfo, string pat)
|
||||
{
|
||||
this.TfsEnvInfo = TfsEnvInfo;
|
||||
|
||||
// Use PAT in order to perform rest calls
|
||||
VssConnection connection = new VssConnection(new Uri(this.TfsEnvInfo.ProjectCollectionUrl), new VssBasicCredential(string.Empty, pat));
|
||||
relclient = connection.GetClient<ReleaseHttpClient>();
|
||||
projclient = connection.GetClient<ProjectHttpClient>();
|
||||
}
|
||||
|
||||
// Implement IDisposable.
|
||||
// Do not make this method virtual.
|
||||
// A derived class should not be able to override this method.
|
||||
public void Dispose()
|
||||
{
|
||||
Dispose(true);
|
||||
// This object will be cleaned up by the Dispose method.
|
||||
// Therefore, you should call GC.SupressFinalize to
|
||||
// take this object off the finalization queue
|
||||
// and prevent finalization code for this object
|
||||
// from executing a second time.
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
|
||||
// Dispose(bool disposing) executes in two distinct scenarios.
|
||||
// If disposing equals true, the method has been called directly
|
||||
// or indirectly by a user's code. Managed and unmanaged resources
|
||||
// can be disposed.
|
||||
// If disposing equals false, the method has been called by the
|
||||
// runtime from inside the finalizer and you should not reference
|
||||
// other objects. Only unmanaged resources can be disposed.
|
||||
protected virtual void Dispose(bool disposing)
|
||||
{
|
||||
// Check to see if Dispose has already been called.
|
||||
if (!this.disposed)
|
||||
{
|
||||
// If disposing equals true, dispose all managed
|
||||
// and unmanaged resources.
|
||||
if (disposing)
|
||||
{
|
||||
// Dispose resources.
|
||||
}
|
||||
|
||||
// Note disposing has been done.
|
||||
disposed = true;
|
||||
|
||||
}
|
||||
}
|
||||
// Use C# destructor syntax for finalization code.
|
||||
// This destructor will run only if the Dispose method
|
||||
// does not get called.
|
||||
// It gives your base class the opportunity to finalize.
|
||||
// Do not provide destructors in types derived from this class.
|
||||
~TfsRelease()
|
||||
{
|
||||
// Do not re-create Dispose clean-up code here.
|
||||
// Calling Dispose(false) is optimal in terms of
|
||||
// readability and maintainability.
|
||||
Dispose(false);
|
||||
}
|
||||
}
|
||||
}
|
11
app.config
11
app.config
|
@ -1,11 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<configuration>
|
||||
<runtime>
|
||||
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral" />
|
||||
<bindingRedirect oldVersion="0.0.0.0-11.0.0.0" newVersion="11.0.0.0" />
|
||||
</dependentAssembly>
|
||||
</assemblyBinding>
|
||||
</runtime>
|
||||
</configuration>
|
|
@ -1,15 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="Microsoft.AspNet.WebApi.Client" version="5.2.3" targetFramework="net461" />
|
||||
<package id="Microsoft.AspNet.WebApi.Core" version="5.2.3" targetFramework="net461" />
|
||||
<package id="Microsoft.IdentityModel.Clients.ActiveDirectory" version="3.17.2" targetFramework="net461" />
|
||||
<package id="Microsoft.IdentityModel.Logging" version="5.2.1" targetFramework="net461" />
|
||||
<package id="Microsoft.IdentityModel.Tokens" version="5.2.1" targetFramework="net461" />
|
||||
<package id="Microsoft.TeamFoundation.DistributedTask.Common.Contracts" version="16.140.0-preview" targetFramework="net461" />
|
||||
<package id="Microsoft.TeamFoundationServer.Client" version="16.140.0-preview" targetFramework="net461" />
|
||||
<package id="Microsoft.VisualStudio.Services.Client" version="16.140.0-preview" targetFramework="net461" />
|
||||
<package id="Microsoft.VisualStudio.Services.InteractiveClient" version="16.140.0-preview" targetFramework="net461" />
|
||||
<package id="Microsoft.VisualStudio.Services.Release.Client" version="16.140.0-preview" targetFramework="net461" />
|
||||
<package id="Newtonsoft.Json" version="11.0.2" targetFramework="net461" />
|
||||
<package id="System.IdentityModel.Tokens.Jwt" version="5.2.1" targetFramework="net461" />
|
||||
</packages>
|
Загрузка…
Ссылка в новой задаче