TFS 2015 - 删除构建工件

时间:2016-06-20 21:36:49

标签: tfsbuild tfs2015

如何在删除构建时升级TFS 2015 Update 2以删除工件?

这可能吗?

enter image description here

编辑:添加保留屏幕截图

我正在使用默认保留策略,但它不会从驱动器中删除工件。

enter image description here

编辑:添加复制和发布构建工件

enter image description here

编辑:添加工作文件夹

我添加了一个powershell来显示所有环境变量,它说我的workingFolder = E:TfsBuilds \ Agent1_WorkPlace \ 5 \ s

你有一个powershell将workingFolder设置为默认值吗?

这是我的文件结构:

enter image description here

2 个答案:

答案 0 :(得分:2)

如果您specify build retention policies,保留政策将删除以下项目:

  • 构建记录
  • 日志
  • 已发布的工件
  • 自动化测试结果
  • 已发布的工件
  • 已发布的符号

您可以在SO中提及类似问题的详细信息:Should artifacts associated with a build record be deleted when the build record is deleted?

此外,如果手动删除构建,则构建的所有内容都将被删除。

<强>更新

目前,删除构建时删除服务器丢弃但不会删除到UNC共享。这也是一个已知问题:Build.Preview - Drop Folder not deleted when build is deleted

如果是这样,您可能必须手动删除

<强> UPDATE2

我想知道你是否错过了drop文件夹中的工作文件夹。默认工作文件夹位置是代理程序安装目录下的_work文件夹。此文件夹中的文件将始终保留或删除,直到触发下一个构建。您可以在构建日志中找到该目录以进行仔细检查。更多详情请参阅MSDN的定义。

enter image description here

<强> UPDATE3

每个代理都有自己的工作文件夹。例如XXX \ Agent1,XXX \ Agent2,... XXX \ Agent6。我认为问题是你混淆了文件结构。

使用您的文件结构,部署到服务器的文件将复制到名为XXX \ builds的文件夹中。但是,这些文件不是已发布的工件。有类似临时文件的东西。如果要自动删除构建下的文件,可以在最后一步添加Delete files task.。即使在构建期间删除了这些文件。您可以在构建完成后仍然从服务器下载工件。 enter image description here

答案 1 :(得分:0)

我在这里假设我们知道TFS2015 Update2不支持开箱即用,并且MS声称已经在TFS15中解决了这个问题。

我将为每个人的利益粘贴整个程序。此代码有效,我正在使用它。我运行此实用程序来清除已从TFS中清除的构建的构建工件位置位置。我们假设我们将使用两个参数作为文件夹路径来调用exe:

DeleteBuild.exe "D:\TFSDropLocation" "D:\DumpFolderBeforeIDeleteThis"

其中 TFSDropLocation 是TFS放弃构建工件的地方,而 DumpFolderBeforeIDelete这个是我收集所有构建的文件夹,我会永久删除它们。我们可以直接从 TFSDropLocation 中删除它们,但是我喜欢这个额外的步骤,我们将它们移到一个单独的位置,以防万一,我们碰巧需要它们,它们是它们或者从这个中删除它们经过一轮验证后的位置 - 如果您觉得舒服。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.TeamFoundation.Build.WebApi;
using Microsoft.TeamFoundation.Core.WebApi;
using Microsoft.VisualStudio.Services.Client;
using System.IO;
using System.Configuration;

namespace DeleteBuild
{
    class Program
    {
        static void Main(string[] args)
        {
            if (args.Length!=2)
            {
                Console.WriteLine("Correct usage is: DeleteBuild.exe 'Absolute Folderpath Path to TFS drop location' 'Absolute Dump Location'");
                Console.WriteLine("for e.g. something with quotes around the paths: DeleteBuild.exe D:\\TFSDropLocation D:\\Dumplocation");
                return;
            }

            string BuildDropLocation = args[0];
            string BuildDumpLocation = args[1];
            #region TFSConnection
            string accountUrl = ConfigurationManager.AppSettings["accountUrl"];
            VssConnection connection = new VssConnection(new Uri(accountUrl), new VssAadCredential());
            ProjectHttpClient projectClient = connection.GetClient<ProjectHttpClient>();
            TeamProject project = projectClient.GetProject(ConfigurationManager.AppSettings["TeamProject"]).Result;
            BuildHttpClient buildClient = connection.GetClient<BuildHttpClient>();
            var builds = buildClient.GetBuildsAsync(project.Id, resultFilter: BuildResult.Succeeded).Result;
            #endregion

            //the parent directory that is the build definition name
            DirectoryInfo directory = new DirectoryInfo(BuildDropLocation);
            // list of subdirectories which are the actual buildnumber folders
            DirectoryInfo[] ParentFolders = directory.GetDirectories();

            foreach (DirectoryInfo ParentFolder in ParentFolders)
            {
                Console.WriteLine(Environment.NewLine + "Build Definition name: " + ParentFolder.Name + " contains the below mentioned builds");
                //list of all folders inside the build definition folder which are buildnumber folders
                DirectoryInfo[] ChildFolders = ParentFolder.GetDirectories();
                //We evaluate each build number folder one by one
                foreach (DirectoryInfo ChildFolder in ChildFolders)
                {
                    Console.WriteLine(Environment.NewLine + "Evaluating folder: " + ChildFolder.Name);
                    //Create an array of builds where the definition name matches the parent foldername
                    Build[] RelevantBuilds = builds.Where(b => b.Definition.Name == ParentFolder.Name).Reverse().ToArray();
                    //set flag to false to 
                    Boolean flag = false;
                    // traverse through each build in tfs
                    foreach (Build build in RelevantBuilds)
                    {
                        {
                            //compare build number with child folder name to see if it matches
                            if (string.Compare(build.BuildNumber, ChildFolder.Name) == 0)
                            {
                                Console.WriteLine("Found build existing, hence leaving here " + build.BuildNumber);
                                //this build has yet not been deleted from tfs so set flag to true and traverse to the next build
                                flag = true;
                            }

                        }
                    }
                    // if after travering the builds, we did not find any build that matches the foldername, flag will be set to initial value of false and this folder will be deleted
                    if (flag == false)
                    {
                        DirectoryInfo DropLocation = new DirectoryInfo(BuildDumpLocation);
                        string intermediatPath = Path.Combine(BuildDumpLocation, ParentFolder.Name);
                        DirectoryInfo IntermediateDirectory = new DirectoryInfo(intermediatPath);
                        if (!IntermediateDirectory.Exists)
                        {
                            DropLocation.CreateSubdirectory(ParentFolder.Name);
                        }
                        string sourcePath = ChildFolder.Name;
                        string targetPath = Path.Combine(DropLocation.FullName, ParentFolder.Name, ChildFolder.Name);
                        System.IO.Directory.Move(ChildFolder.FullName, targetPath);
                        Console.WriteLine("Did not find build in TFS hence moving: " + ChildFolder.Name + " to a separate dump location.");
                    }
                }
                Console.WriteLine("******************************************************");
            }
            Console.WriteLine("end of directory" + Environment.NewLine);
        }
    }
}