Skip to content

Instantly share code, notes, and snippets.

@grenade
Last active August 29, 2015 14:15
Show Gist options
  • Save grenade/cce374cb4e27e366bc5b to your computer and use it in GitHub Desktop.
Save grenade/cce374cb4e27e366bc5b to your computer and use it in GitHub Desktop.
Generate common build definition in TFS
#[void][System.Reflection.Assembly]::LoadWithPartialName("Microsoft.TeamFoundation.Client")
#[void][System.Reflection.Assembly]::LoadWithPartialName("Microsoft.TeamFoundation.Build.Client")
#[void][System.Reflection.Assembly]::LoadWithPartialName("Microsoft.TeamFoundation.Build.Common")
#[void][System.Reflection.Assembly]::LoadWithPartialName("Microsoft.TeamFoundation.VersionControl.Client")
#[void][System.Reflection.Assembly]::LoadWithPartialName("Microsoft.TeamFoundation.VersionControl.Client.VersionSpec")
function Update-AssemblyInfo {
param(
[string] $assemblyInfoFile,
[hashtable] $parameters
)
Write-Host ("`$assemblyInfoFile: {0}" -f $assemblyInfoFile)
foreach ($key in $($parameters.Keys)) {
if ($parameters[$key] -ne $null) {
$assemblyInfo = Get-Content $assemblyInfoFile
$pattern = ('\[assembly: {0}\("(.*)"\)\]' -f $key)
try{
$oldValue = ($assemblyInfo | Select-String -Pattern $pattern | % { $_.Matches } ).Groups[1].Value
}
catch{
$oldValue = $null
}
if($oldValue){
$match = ('[assembly: {0}("{1}")]' -f $key, $oldValue)
$replace = ('[assembly: {0}("{1}")]' -f $key, $parameters[$key])
Set-ItemProperty $assemblyInfoFile -name IsReadOnly -value $false
(($assemblyInfo) | ForEach-Object { % { $_ -Replace [regex]::escape($match), $replace } }) | Set-Content $assemblyInfoFile
Write-Host ("{0} changed from: '{1}', to: '{2}'." -f $key, $oldValue, $parameters[$key])
} else {
Write-Host ("No value for {0} found." -f $key)
}
}
}
}
function New-Version {
param(
[string] $packageId,
[string] $nugetSource,
[string] $versionSuffix = $null,
[string] $nugetExe,
[string] $incrementPosition = "patch",
[int] $majorDefault = 0,
[int] $minorDefault = 0,
[int] $patchDefault = 0
)
if($nugetSource.ToUpper().Contains($env:USERDNSDOMAIN.ToUpper())){
#if nuget finds a proxy setting in env vars, it'll use it. disable that for local nuget sources
$http_proxy_tmp = $env:HTTP_PROXY
$https_proxy_tmp = $env:HTTPS_PROXY
$env:HTTP_PROXY=''
$env:HTTPS_PROXY=''
}
$nugetArgs = "list", $packageId, "-s", $nugetSource
if ($versionSuffix) { $nugetArgs += "-pre" }
try {
(& $nugetExe $nugetArgs) | Where { $_.StartsWith(("{0} " -f $packageId)) } | % { $publishedVersion = $_.Split(" ")[1] }
}
catch {
Write-Error ("Failed to query NuGet source: {0}, for package: {1}." -f $nugetSource, $packageId)
}
if($nugetSource.ToUpper().Contains($env:USERDNSDOMAIN.ToUpper())){
#reset proxy vars
$env:HTTP_PROXY = $http_proxy_tmp
$env:HTTPS_PROXY = $https_proxy_tmp
}
if (!$publishedVersion) {
Write-Host ("Assuming no published version of package id: {0}, on NuGet source: {1}." -f $packageId, $nugetSource)
$publishedVersion = ("{0}.{1}.{2}" -f $majorDefault, $minorDefault, $patchDefault)
if ($versionSuffix) {
$publishedVersion += $versionSuffix
}
}
if ($versionSuffix) {
$major, $minor, $patch, $build = $publishedVersion.Split("-")[0].Split(".")
} else {
$major, $minor, $patch, $build = $publishedVersion.Split(".")
}
if ($majorDefault -gt ([int] $major)) {
$major = $majorDefault
}
if ($minorDefault -gt ([int] $minor)) {
$minor = $minorDefault
}
Write-Host ("Incrementing {0} position of semver: {1}." -f $incrementPosition, $publishedVersion)
switch ($incrementPosition) {
"major" { $semanticVersion = ("{0}.{1}.{2}" -f (([int] $major) + 1), 0, 0) }
"minor" { $semanticVersion = ("{0}.{1}.{2}" -f $major, (([int] $minor) + 1), 0) }
default { $semanticVersion = ("{0}.{1}.{2}" -f $major, $minor, (([int] $patch) + 1)) }
}
return $semanticVersion
}
function Get-Version {
param(
[string] $assemblyInfoFile
)
Write-Host ("`$assemblyInfoFile: {0}" -f $assemblyInfoFile)
$assemblyInfo = Get-Content $assemblyInfoFile
$pattern = ('\[assembly: {0}\("(.*)"\)\]' -f 'AssemblyInformationalVersion')
try{
$version = ($assemblyInfo | Select-String -Pattern $pattern | % { $_.Matches } ).Groups[1].Value.Split('+')[0]
}
catch{
$version = $null
}
return $version
}
function Pack {
param(
[string] $projectFile,
[string] $packageDirectory,
[string] $version,
[string] $nugetExe,
[string] $properties
)
$projectDirectory = (Split-Path -Parent $projectFile)
Copy-Item ("{0}\..\build\nuget.config" -f $projectDirectory) "$projectDirectory"
#Get-ReleaseNotes $tfsBuildName
if ($version) {
$nugetArgs = 'pack', "$projectFile", '-OutputDirectory', "$packageDirectory", '-Version', "$version", '-IncludeReferencedProjects', '-Properties', "$properties"
} else {
$nugetArgs = 'pack', "$projectFile", '-OutputDirectory', "$packageDirectory", '-IncludeReferencedProjects', '-Properties', "$properties"
}
& $nugetExe $nugetArgs
}
function Publish {
param(
[string] $package,
[string] $apiKey,
[string] $nugetSource,
[string] $nugetExe
)
if($nugetSource.ToUpper().Contains($env:USERDNSDOMAIN.ToUpper())){
#if nuget finds a proxy setting in env vars, it'll use it. disable that for local nuget sources
$http_proxy_tmp = $env:HTTP_PROXY
$https_proxy_tmp = $env:HTTPS_PROXY
$env:HTTP_PROXY=''
$env:HTTPS_PROXY=''
}
$nugetArgs = "push", "$package", "-ApiKey", $apiKey, "-Source", $nugetSource
& $nugetExe $nugetArgs
if($nugetSource.ToUpper().Contains($env:USERDNSDOMAIN.ToUpper())){
#reset proxy vars
$env:HTTP_PROXY = $http_proxy_tmp
$env:HTTPS_PROXY = $https_proxy_tmp
}
}
function Restore {
param(
[string] $packagesConfig,
[string] $nugetSource,
[string] $nugetExe
)
Write-Host ("`$packagesConfig: {0}" -f $packagesConfig)
$projectDirectory = (Split-Path -Parent $packagesConfig)
if($nugetSource.ToUpper().Contains($env:USERDNSDOMAIN.ToUpper())){
#if nuget finds a proxy setting in env vars, it'll use it. disable that for local nuget sources
$http_proxy_tmp = $env:HTTP_PROXY
$https_proxy_tmp = $env:HTTPS_PROXY
$env:HTTP_PROXY=''
$env:HTTPS_PROXY=''
}
$nugetArgs = 'install', "$packagesConfig", '-Source', $nugetSource, '-NonInteractive', '-RequireConsent', '-SolutionDir', ($projectDirectory, ".." -join '\')
& $nugetExe $nugetArgs
if($nugetSource.ToUpper().Contains($env:USERDNSDOMAIN.ToUpper())){
#reset proxy vars
$env:HTTP_PROXY = $http_proxy_tmp
$env:HTTPS_PROXY = $https_proxy_tmp
}
}
#function Get-ReleaseNotes {
# param (
# [string] $tfsCollectionUrl = 'https://imstfs.bisinfo.org/tfs/DevBIS',
# [string] $tfsBuildName,
# [string] $tfsPath,
# [string] $tfsProjectName = $tfsPath.Split('/')[1]
# )
# $server = New-Object Microsoft.TeamFoundation.Client.TfsTeamProjectCollection(New-Object Uri($tfsCollectionUrl))
# $buildServer = $server.GetService([Microsoft.TeamFoundation.Build.Client.IBuildServer])
# $buildDetail = $buildServer.QueryBuilds("$tfsProjectName", "$tfsBuildName") | where { $_.BuildDefinition.LastGoodBuildUri -eq $_.Uri }
# $versionControlServer = $server.GetService([Microsoft.TeamFoundation.VersionControl.Client.VersionControlServer])
# $dateVersionSpec = New-Object Microsoft.TeamFoundation.VersionControl.Client.DateVersionSpec($buildDetail.StartTime)
# $latest = [Microsoft.TeamFoundation.VersionControl.Client.VersionSpec]::Latest
# $recursionType = [Microsoft.TeamFoundation.VersionControl.Client.RecursionType]::Full
# $historySinceLastGoodBuild = $versionControlServer.QueryHistory($tfsPath, $latest, 0, $recursionType, $null, $dateVersionSpec, $latest,[Int32]::MaxValue, $true, $false)
# $workItemsSinceLastGoodBuild = $historySinceLastGoodBuild | foreach-object {$_.workitems}
# return $workItemsSinceLastGoodBuild | foreach-object {$_.Id, $_.Title, $_.State}
#}
using System.Collections.Generic;
namespace devopsutil
{
internal static class Config
{
internal const string TfsCollectionUrl = "https://tfs.example.com/tfs/some-collection";
internal const string TfsBuildController = "some-controller";
internal const string TeamProject = "SomeProject Common";
internal const string TeamProjectNamespace = "SomeProject.Common";
internal const string Configuration = "Release";
internal const string Platform = "AnyCPU";
private const string OutputPath = "bin";
internal static readonly string[] AgentTags = { "some-tag" };
private const string NuGetApiKey = "00000000-0000-0000-0000-000000000000";
internal static readonly KeyValuePair<string, string> PreBuildScript = new KeyValuePair<string, string>(string.Format("$/{0}/Trunk/build/set-version.ps1", TeamProject), null);
internal static readonly KeyValuePair<string, string> PostBuildScript = new KeyValuePair<string, string>(string.Format("$/{0}/Trunk/build/publish-project.ps1", TeamProject), string.Format("-apiKey {0}", NuGetApiKey));
internal static readonly Dictionary<string, string> MsBuildProperties = new Dictionary<string, string>
{
{ "Configuration", Configuration },
{ "Platform", Platform },
{ "OutputPath", OutputPath },
{ "DefineConstants", "TRACE" },
{ "TargetFrameworkVersion", "v4.5" }
};
internal static Dictionary<string, object> GetAgentSettings(
IEnumerable<string> tags,
string maxExecutionTime = "00:00:00",
string maxWaitTime = "00:30:00",
string name = "*",
string tagComparison = "MatchAtLeast")
{
return new Dictionary<string, object>
{
{ "MaxExecutionTime", maxExecutionTime },
{ "MaxWaitTime", maxWaitTime },
{ "Name", name },
{ "Tags", tags },
{ "TagComparison", tagComparison }
};
}
internal static Dictionary<string, string> GetDefaultMappings(string project)
{
return new Dictionary<string, string>
{
{
string.Format("$/{0}/Trunk/build", TeamProject),
@"$(SourceDir)\build"
},
{
string.Format("$/{0}/Trunk/src/Common/.nuget", TeamProject),
@"$(SourceDir)\.nuget"
},
{
string.Format("$/{0}/Trunk/src/Common/{1}", TeamProject, project),
@"$(SourceDir)\src"
},
{
string.Format("$/{0}/Trunk/src/Common/SharedAssemblyInfo.cs", TeamProject),
@"$(SourceDir)\SharedAssemblyInfo.cs"
}
};
}
}
}
using System;
using System.Linq;
using Microsoft.TeamFoundation.Build.Client;
namespace devopsutil
{
static class Program
{
static void Main(string[] args)
{
var buildDefinitionNames = args.Any()
? args
: TfsUtil.GetBuildDefinitionNames(Config.TeamProject);
foreach (var buildDefinitionName in buildDefinitionNames)
CreateBuildDefinition(buildDefinitionName);
Console.WriteLine("All done.");
Console.ReadKey();
}
private static void CreateBuildDefinition(string project)
{
if ((project ?? string.Empty).StartsWith(Config.TeamProjectNamespace))
TfsUtil.CreateBuildDefinition(
projectPath: string.Format("src/{0}.csproj", project),
teamProject: Config.TeamProject,
buildDefinitionName: project,
workspaceMappings: Config.GetDefaultMappings(project),
buildDefinitionDescription: string.Format("NuGet Release: build, package and publish for {0}.", project),
msBuildProperties: Config.MsBuildProperties,
preBuildScript: Config.PreBuildScript,
postBuildScript: Config.PostBuildScript,
continuousIntegrationType: ContinuousIntegrationType.Batch,
agentTags: Config.AgentTags);
}
}
}
<#
.Synopsis
- Create and publish NuGet package from project source
#>
param(
[string] $projectDirectory = ("{0}\..\src" -f (Split-Path -Parent $MyInvocation.MyCommand.Path)),
[string] $project = (Get-ChildItem -Path $projectDirectory -Filter "*.csproj" | Select -ExpandProperty Name).Replace('.csproj', ''),
[string] $nugetSource = 'http://nuget.example.com',
[string] $nugetExe = "$projectDirectory\..\.nuget\nuget.exe",
[string] $configuration = "Release",
[string] $platform = "AnyCPU",
[string] $outputPath = "bin",
[string] $apiKey = '00000000-0000-0000-0000-000000000000'
)
Import-Module ("{0}\build-util.psm1" -f (Split-Path -Parent $MyInvocation.MyCommand.Path))
$packageDirectory = ($projectDirectory, "..", ".nuget" -join '\')
$version = Get-Version ($projectDirectory, 'Properties', 'AssemblyInfo.cs' -join '\')
$projectFile = ($projectDirectory, "$project.csproj" -join '\')
Pack -projectFile $projectFile -packageDirectory $packageDirectory -version $version -nugetExe $nugetExe -properties "Configuration=$configuration;Platform=$platform;OutputPath=$outputPath"
Publish ($packageDirectory, ($project, $version, 'nupkg' -join '.') -join '\') $apiKey $nugetSource $nugetExe
<#
.Synopsis
- Create and publish NuGet package from project source
#>
param(
[string] $projectDirectory = ("{0}\..\src" -f (Split-Path -Parent $MyInvocation.MyCommand.Path)),
[string] $project = (Get-ChildItem -Path $projectDirectory -Filter "*.csproj" | Select -ExpandProperty Name).Replace('.csproj', ''),
[string] $nugetSource = 'http://nuget.exampl.com/api/v2/',
[string] $nugetExe = "$projectDirectory\..\.nuget\nuget.exe",
[int] $buildNumber = $env:TF_BUILD_BUILDNUMBER.Split('.')[-1],
[string] $vcsRevision = $env:TF_BUILD_SOURCEGETVERSION,
[string] $versionSuffix = $null,
[string] $revisionPrefix = $null,
[string] $tfsProjectPath = ('$/SomeProject Common/Trunk/src/Common/{0}' -f $project)
)
$workDirectory = (Split-Path -Parent (Split-Path -Parent $MyInvocation.MyCommand.Path))
Import-Module ("{0}\build-util.psm1" -f (Split-Path -Parent $MyInvocation.MyCommand.Path))
Write-Host ("projectDirectory: {0}" -f $projectDirectory)
Write-Host ("project: {0}" -f $project)
$sourceVersion = (Get-Version ($projectDirectory, 'Properties', 'AssemblyInfo.cs' -join '\'))
Write-Host ("sourceVersion: {0}" -f $sourceVersion)
$majorDefault, $minorDefault, $patchDefault, $buildDefault = $sourceVersion.Split(".")
$semanticVersion = New-Version -packageId $project -nugetSource $nugetSource -nugetExe $nugetExe -majorDefault $majorDefault -minorDefault $minorDefault -patchDefault $patchDefault
Write-Host ("New semver: [{0}]." -f $semanticVersion)
$assemblyVersion = ("{0}.{1}" -f $semanticVersion, $buildNumber)
$assemblyInformationalVersion = $semanticVersion
if ($versionSuffix) {
$assemblyInformationalVersion += $versionSuffix
}
$assemblyInformationalVersion += ("+{0}{1}.{2}" -f $revisionPrefix, $vcsRevision, $buildNumber)
$assemblyInfoValues = @{ AssemblyVersion = $assemblyVersion; AssemblyFileVersion = $assemblyVersion; AssemblyInformationalVersion = $assemblyInformationalVersion }
Update-AssemblyInfo ($projectDirectory, 'Properties', 'AssemblyInfo.cs' -join "\") $assemblyInfoValues
#$tfsPath = ('{0}/{1}' -f $tfsProjectPath, $project)
#$notes = (Get-ReleaseNotes -tfsBuildName "$env:TF_BUILD_BUILDDEFINITIONNAME" -tfsPath "$tfsPath")
#Write-Host ($notes | Format-Table | Out-String)
$packagesConfig = ($workDirectory, 'src', 'packages.config' -join '\')
if (Test-Path "$packagesConfig")
{
Restore -packagesConfig "$packagesConfig" -nugetSource "$nugetSource" -nugetExe "$nugetExe"
} else {
Write-Host ("Package restore skipped because config not found: '{0}'" -f $packagesConfig)
}
using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.TeamFoundation.Build.Common;
using Microsoft.TeamFoundation.Client;
using Microsoft.TeamFoundation.Build.Client;
using Microsoft.TeamFoundation.Build.Workflow;
using Microsoft.TeamFoundation.VersionControl.Client;
namespace devopsutil
{
internal static class TfsUtil
{
private static TfsTeamProjectCollection _tfsTeamProjectCollection;
private static TfsTeamProjectCollection TfsTeamProjectCollection
{
get
{
if (_tfsTeamProjectCollection == null)
{
_tfsTeamProjectCollection = new TfsTeamProjectCollection(new Uri(Config.TfsCollectionUrl));
_tfsTeamProjectCollection.EnsureAuthenticated();
}
return _tfsTeamProjectCollection;
}
}
private static IBuildServer _buildServer;
private static IBuildServer BuildServer
{
get { return _buildServer ?? (_buildServer = TfsTeamProjectCollection.GetService<IBuildServer>()); }
}
private static VersionControlServer _versionControlServer;
private static VersionControlServer VersionControlServer
{
get
{
return _versionControlServer ??
(_versionControlServer = TfsTeamProjectCollection.GetService<VersionControlServer>());
}
}
public static void CreateBuildDefinition(
string projectPath,
string teamProject,
string buildDefinitionName,
IEnumerable<KeyValuePair<string, string>> workspaceMappings,
IEnumerable<string> cloakedWorkspaceMappings = null,
string buildDefinitionDescription = null,
IDictionary<string, string> msBuildProperties = null,
string platform = Config.Platform,
string configuration = Config.Configuration,
KeyValuePair<string, string> preBuildScript = new KeyValuePair<string, string>(),
KeyValuePair<string, string> postBuildScript = new KeyValuePair<string, string>(),
ContinuousIntegrationType continuousIntegrationType = ContinuousIntegrationType.Individual,
int continuousIntegrationQuietPeriod = 10,
string outputLocation = "AsConfigured",
bool includeTestRunSettings = false,
string symbolStorePath = null, // eg: @"\\server\symbols\somepath"
string dropLocation = null, // eg: "#/"
string[] agentTags = null
)
{
var buildDefinition = GetOrCreateBuildDefinition(teamProject, buildDefinitionName);
if (!string.IsNullOrWhiteSpace(buildDefinitionDescription))
buildDefinition.Description = buildDefinitionDescription;
Console.WriteLine("set continuous integration type: {0}", continuousIntegrationType);
buildDefinition.ContinuousIntegrationType = continuousIntegrationType;
if (continuousIntegrationType == ContinuousIntegrationType.Batch)
{
Console.WriteLine("set continuous integration quiet period: {0}", continuousIntegrationQuietPeriod);
buildDefinition.ContinuousIntegrationQuietPeriod = continuousIntegrationQuietPeriod;
}
//Controller and default build process template
buildDefinition.BuildController = BuildServer.GetBuildController(Config.TfsBuildController);
var defaultTemplate =
BuildServer.QueryProcessTemplates(teamProject).First(p => p.TemplateType == ProcessTemplateType.Default);
Console.WriteLine("set template: {0}", defaultTemplate.Description);
buildDefinition.Process = defaultTemplate;
//Drop location
if (!string.IsNullOrWhiteSpace(dropLocation))
{
Console.WriteLine("set default drop location: {0}", dropLocation);
buildDefinition.DefaultDropLocation = dropLocation;
}
//Source Settings
foreach (var workspaceMapping in workspaceMappings)
{
Console.WriteLine("add mapping: server: {0}, local: {1}", workspaceMapping.Key, workspaceMapping.Value);
buildDefinition.Workspace.AddMapping(workspaceMapping.Key, workspaceMapping.Value, WorkspaceMappingType.Map);
}
foreach (var cloakedWorkspaceMapping in (cloakedWorkspaceMappings ?? Enumerable.Empty<string>()))
{
Console.WriteLine("add cloaked mapping: {0}", cloakedWorkspaceMapping);
buildDefinition.Workspace.AddMapping(cloakedWorkspaceMapping, string.Empty, WorkspaceMappingType.Cloak);
}
//Process params
var processParameters = WorkflowHelpers.DeserializeProcessParameters(buildDefinition.ProcessParameters);
//What to build
Console.WriteLine("set ProjectsToBuild: {0}", projectPath);
if (processParameters.ContainsKey("ProjectsToBuild"))
processParameters["ProjectsToBuild"] = new[] {projectPath};
else
processParameters.Add("ProjectsToBuild", new[] {projectPath});
Console.WriteLine("set ConfigurationsToBuild: {0}", string.Format("{0}|{1}", platform, configuration));
if (processParameters.ContainsKey("ConfigurationsToBuild"))
processParameters["ConfigurationsToBuild"] = new[] { string.Format("{0}|{1}", platform, configuration) };
else
processParameters.Add("ConfigurationsToBuild", new[] { string.Format("{0}|{1}", platform, configuration) });
if (processParameters.ContainsKey("OutputLocation"))
processParameters["OutputLocation"] = outputLocation;
else
processParameters.Add("OutputLocation", outputLocation);
//Advanced build settings
var buildParams = new Dictionary<string, string>();
if (msBuildProperties != null && msBuildProperties.Any())
{
var msBuildArguments = string.Concat("/p:", string.Join(";", msBuildProperties.Select(p => string.Concat(p.Key, '=', p.Value))));
Console.WriteLine("set MSBuildArguments: {0}", msBuildArguments);
buildParams.Add("MSBuildArguments", msBuildArguments);
}
if (!string.IsNullOrWhiteSpace(preBuildScript.Key))
{
Console.WriteLine("set PreActionScriptPath: {0}", preBuildScript.Key);
buildParams.Add("PreActionScriptPath", preBuildScript.Key);
}
if (!string.IsNullOrWhiteSpace(preBuildScript.Value))
{
Console.WriteLine("set PreActionScriptArguments: {0}", preBuildScript.Value);
buildParams.Add("PreActionScriptArguments", preBuildScript.Value);
}
if (!string.IsNullOrWhiteSpace(postBuildScript.Key))
{
Console.WriteLine("set PostActionScriptPath: {0}", postBuildScript.Key);
buildParams.Add("PostActionScriptPath", postBuildScript.Key);
}
if (!string.IsNullOrWhiteSpace(postBuildScript.Value))
{
Console.WriteLine("set PostActionScriptArguments: {0}", postBuildScript.Value);
buildParams.Add("PostActionScriptArguments", postBuildScript.Value);
}
if (buildParams.Any())
{
if (processParameters.ContainsKey("AdvancedBuildSettings"))
processParameters["AdvancedBuildSettings"] = new BuildParameter(buildParams);
else
processParameters.Add("AdvancedBuildSettings", new BuildParameter(buildParams));
}
else if (processParameters.ContainsKey("AdvancedBuildSettings"))
{
processParameters.Remove("AdvancedBuildSettings");
}
//test settings
if (includeTestRunSettings)
{
if (processParameters.ContainsKey("AutomatedTests"))
processParameters["AutomatedTests"] = new[] {new BuildParameter(GetTestParameters())};
else
processParameters.Add("AutomatedTests", new[] {new BuildParameter(GetTestParameters())});
}
else if (processParameters.ContainsKey("AutomatedTests"))
{
processParameters.Remove("AutomatedTests");
}
//Symbol settings
if (!string.IsNullOrWhiteSpace(symbolStorePath))
{
if (processParameters.ContainsKey("SymbolStorePath"))
processParameters["SymbolStorePath"] = symbolStorePath;
else
processParameters.Add("SymbolStorePath", symbolStorePath);
}
else if (processParameters.ContainsKey("SymbolStorePath"))
{
processParameters.Remove("SymbolStorePath");
}
if (agentTags != null && agentTags.Any())
{
if (processParameters.ContainsKey("AgentSettings"))
processParameters["AgentSettings"] = new BuildParameter(Config.GetAgentSettings(agentTags));
else
processParameters.Add("AgentSettings", new BuildParameter(Config.GetAgentSettings(agentTags)));
}
buildDefinition.ProcessParameters = WorkflowHelpers.SerializeProcessParameters(processParameters);
//Retention policy
buildDefinition.RetentionPolicyList.Clear();
buildDefinition.AddRetentionPolicy(BuildReason.Triggered, BuildStatus.Succeeded, 10, DeleteOptions.All);
buildDefinition.AddRetentionPolicy(BuildReason.Triggered, BuildStatus.Failed, 10, DeleteOptions.All);
buildDefinition.AddRetentionPolicy(BuildReason.Triggered, BuildStatus.Stopped, 1, DeleteOptions.All);
buildDefinition.AddRetentionPolicy(BuildReason.Triggered, BuildStatus.PartiallySucceeded, 10, DeleteOptions.All);
Console.WriteLine("save build definition: {0}", buildDefinition.Name);
buildDefinition.Save();
}
private static IBuildDefinition GetOrCreateBuildDefinition(string teamProject, string buildDefinitionName)
{
IBuildDefinition buildDefinition;
if ((BuildServer.QueryBuildDefinitions(teamProject).Any(d => d.Name == buildDefinitionName)))
{
Console.WriteLine("update build definition: {0}/{1}", teamProject, buildDefinitionName);
buildDefinition = BuildServer.GetBuildDefinition(teamProject, buildDefinitionName);
RemoveWorkspaceMappings(buildDefinition);
}
else
{
Console.WriteLine("create build definition: {0}/{1}", teamProject, buildDefinitionName);
buildDefinition = BuildServer.CreateBuildDefinition(teamProject);
buildDefinition.Name = buildDefinitionName;
}
return buildDefinition;
}
private static void DeleteBuilds(IBuildDefinition buildDefinition)
{
var builds = BuildServer.QueryBuilds(buildDefinition);
if (builds != null && builds.Any())
{
Console.WriteLine("delete {0} builds for build definition: {1}", builds.Count(),
buildDefinition.Name);
BuildServer.DeleteBuilds(builds);
}
}
private static void RemoveWorkspaceMappings(IBuildDefinition buildDefinition)
{
if (buildDefinition.Workspace.Mappings.Any())
{
var mappings = buildDefinition.Workspace.Mappings.Select(m => m.ServerItem).ToArray();
foreach (var mapping in mappings)
{
Console.WriteLine("remove workspace mapping: {0}", mapping);
buildDefinition.Workspace.RemoveMapping(mapping);
}
}
}
private static void DeleteWorkspaces(string buildDefinitionId)
{
var workspaceNamePrefix = string.Concat(buildDefinitionId, '_');
var workSpaces = VersionControlServer.QueryWorkspaces(null, null, null).Where(w => w.Name.StartsWith(workspaceNamePrefix)).ToArray();
for (var i = workSpaces.Count() - 1; i > -1; i--)
{
try
{
workSpaces[i].Delete();
Console.WriteLine("delete workspace: {0}", workSpaces[i].Name);
}
catch (ResourceAccessException rae)
{
Console.ForegroundColor = ConsoleColor.Yellow;
Console.WriteLine(rae.Message);
Console.ForegroundColor = ConsoleColor.Red;
Console.WriteLine("workspace needs to be deleted by an administrator using the following command:");
Console.ForegroundColor = ConsoleColor.Green;
Console.WriteLine("tf workspace /delete {0};{1}", workSpaces[i].Name, workSpaces[i].OwnerName);
Console.ResetColor();
}
}
}
private static Dictionary<string, object> GetTestParameters()
{
return new Dictionary<string, object>
{
{ "AssemblyFileSpec", "*.exe" },
{ "HasRunSettingsFile", true },
{ "ExecutionPlatform", "X86" },
{ "FailBuildOnFailure", true },
{ "RunName", "MyTestRunName" },
{ "HasTestCaseFilter", false },
{ "TestCaseFilter", null },
{ "RunSettingsForTestRun", new Dictionary<string, object>
{
{ "HasRunSettingsFile", true },
{ "ServerRunSettingsFile", "" },
{ "TypeRunSettings", "CodeCoverageEnabled" }
}
}
};
}
public static IEnumerable<string> GetBuildDefinitionNames(string teamProject)
{
return BuildServer.QueryBuildDefinitions(teamProject).Select(d => d.Name);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment