TFS 2015 - 删除构建产物

5
如何升级 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个回答

3
如果您指定构建保留策略, 保留策略将删除以下内容:
  • 构建记录
  • 日志
  • 已发布的制品
  • 自动化测试结果
  • 已发布的符号

更多细节,请参考SO上类似问题:删除构建记录时是否应删除与之关联的制品?

此外,如果您手动删除构建,则会删除所有构建内容。

更新


目前,当一个构建被删除时,服务器上的构建文件会被删除,但是存储在UNC共享中的构建文件不会被删除。这也是一个已知的问题: Build.Preview - Drop Folder not deleted when build is deleted

如果是这样,您可能需要手动删除它们

更新2


我在想你是否混淆了工作文件夹和丢弃文件夹。默认的工作文件夹位置是代理安装目录下的一个名为"_work"的文件夹。该文件夹中的文件将保留或删除,直到下一次构建触发。您可以在构建日志中找到该目录以进行双重检查。更多详细信息,请参阅MSDN的定义。

enter image description here


更新3

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

根据您的文件结构,部署到服务器上的文件将复制到名为XXX\builds的文件夹中。然而,这些文件不是已发布的构件,而是一些类似临时文件的东西。如果您想自动删除builds下的文件,可以在最后一步添加一个删除文件任务。即使这些文件在构建过程中被删除,您仍然可以在构建完成后从服务器上下载构件


我正在使用默认的保留策略,但它并没有从驱动器中删除工件。 - Valter
我也尝试手动删除构建,但它并没有删除工件。 - Valter
我认为你是对的...我以为将文件复制到XXX\builds是已发布的artifact。当我从XXX\builds中删除构建时,它仍然显示在web portal下的artifact中。但是当我尝试下载它时,它会下载一个空的zip文件。当我尝试从zip文件夹中提取文件时,它会给我以下错误“Windows无法完成提取。压缩(Zipped)文件夹'C:\ Users \ username \ Deaktop \ artifact.zip'无效”。有任何想法为什么? - Valter
你应该使用环境变量SYSTEM_ARTIFACTSDIRECTORY来删除构件。 - Alex Kwitny
对于现在遇到这个问题的任何人... Connect 网站当然已经停用了,但我能够通过互联网档案馆找到该问题的副本:http://web.archive.org/web/20161012234209/https://connect.microsoft.com/VisualStudio/feedback/details/1513256/build-preview-drop-folder-not-deleted-when-build-is-deleted。该问题存在于 TFS 2015 中,并且据报告已在 TFS 2017 中修复。 - Holistic Developer
显示剩余8条评论

0

我在这里做一个假设,即我们知道TFS2015 Update2不支持此功能且微软声称在TFS15中已解决此问题。

我将为大家粘贴整个程序。这段代码是有效的,我正在使用它。我运行此实用程序来清理已从TFS中删除的构建的构建工件放置位置。我们假设要使用两个文件夹路径调用exe:

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

TFSDropLocation 是 TFS 存放构建产物的位置,DumpFolderBeforeIDeleteThis 是我在永久删除之前收集所有构建的文件夹。我们本可以直接从 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);
        }
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接