2015-02-09 5 views
0

При создании TFS построения определений через API, мне нужно сначала удалить, если определение предварительно существует:Удалять определения сборки в TFS через API

if (BuildServer.QueryBuildDefinitions(teamProject).Any(d => d.Name == buildDefinitionName)) 
{ 
    buildDefinition = BuildServer.GetBuildDefinition(teamProject, buildDefinitionName); 
    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); 
    } 
    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); 
     } 
    } 
    Console.WriteLine("delete build definition: {0}", buildDefinition.Name); 
    BuildServer.DeleteBuildDefinitions(new[] { buildDefinition }); 
} 

Это работает, как это делает последующее:

buildDefinition = BuildServer.CreateBuildDefinition(teamProject); 
buildDefinition.Name = buildDefinitionName; 

Однако, когда первая сборка получает бежать, он выдает ошибку о конфликтующих рабочих пространствах:

Exception Message: Unable to create the workspace 'some-new-workspace' due to a mapping conflict. You may need to manually delete an old workspace. You can get a list of workspaces on a computer with the command 'tf workspaces /computer:%COMPUTERNAME%'. 
Details: The path C:\some-path is already mapped in workspace some-old-workspace. (type MappingConflictException) 

вы можете увидеть в первом фрагменте, моя попытка удалить рабочие области с .Workspace.RemoveMapping(), не имеет никакого эффекта. Рабочие пространства все еще существуют на контроллере сборки. Я могу удалить их вручную, но они действительно должны быть удалены, когда я удалю определение сборки. Есть ли другой механизм DeleteWorkspace() в API?

Более полный код суть здесь: https://gist.github.com/grenade/cce374cb4e27e366bc5b

ответ

1

Оказывается, что причина, что это сложно, что владелец различных рабочих пространств, созданных сборка может быть каким-то другой пользователя (что сборка агент работает под управлением) , Я нашел способ сделать это, опираясь на предыдущий идентификатор определения сборки, которая используется в рабочем пространстве именовании [build definition id]_[build agent id]_[workspace host]:

var workspaceNamePrefix = string.Concat(buildDefinition.Id, '_'); 
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(); 
    } 
} 

Я обновил суть: https://gist.github.com/grenade/cce374cb4e27e366bc5b

Смежные вопросы