如果构建仍在运行,则无法设置keepforever

时间:2016-07-26 09:06:21

标签: c# tfsbuild

我有一个简单的c#客户端,如果构建完成,它将完全正常工作:

WebClient client = new WebClient();
client.Encoding = System.Text.Encoding.UTF8;
client.Headers.Add("Content-Type", "application/json");
client.UploadString(url, "PATCH", "{keepForever : true}");
Console.WriteLine(reply);

但是:当作为构建步骤的一部分运行时,代码不会抛出任何错误,并且UploadString中的JSON表明keepForever已被更改,但它不会保留。

只有在构建完成后,才能可靠地运行。

在我写下冗长的工作之前,有什么明显的东西我不知道了吗?在构建运行时是否可以强制更新?

1 个答案:

答案 0 :(得分:1)

我实施了一项工作:

首先创建一个控制台应用程序,这将在构建步骤中调用:

private static void Main(string[] args)
      {
         // All this does is dispatch the call to a new process, so that the build can complete independently
         // before attempting to update the keepForever field
         // This is because you cannot update this field while the build is running

         if (args.Length < 1)
         {
            throw new Exception("No Build Number Provided");
         }

         var buildId = args[0];

         Console.WriteLine("Dispatching task to retain build: " + buildId);

         var workingDir = Path.GetDirectoryName(Assembly.GetEntryAssembly().Location);

         Console.WriteLine("Working Directory Set: " + workingDir);

         if (workingDir == null)
         {
            throw new Exception("Working directory is null");
         }

         var p = new Process
         {
            StartInfo =
            {
               WorkingDirectory = workingDir,
               FileName = "RetainBuildIndefinitely.exe",
               Arguments = buildId,
               RedirectStandardOutput = false,
               UseShellExecute = true,
               CreateNoWindow = false
            }
         };
         p.Start();
      }

现在你可能会注意到它在自己的进程中调用了RetainBuildIndefinitely.exe。这样就可以调度此任务,然后退出并完成构建。

RetainBuildIndefinitely.exe也是一个控制台应用程序:

namespace RetainBuildIndefinitely
{
   class Program
   {
      static void Main(string[] args)
      {
         var client = new WebApiCalls();
         client.RetainBuildIndefinately(args[0]);
      }
   }
}

然后执行:

namespace RetainBuildIndefinitely
{
   public class WebApiCalls
   {
      public void RetainBuildIndefinately(string buildId)
      {
         // Max retry attempts
         var retryCount = 30;

         // The Tfs Url
         var url = [YourURL eg: http://server:8080/tfs/TeamCollection/Project/_apis/build/builds/{buildId}?api-version=2.0";

         // Poll until the build is finished
         // Since this call should be made in the last build step, there shouldn't be too much waiting for this to complete

         using (var client = new WebClient {UseDefaultCredentials = true})
         {
            client.Headers.Add("Content-Type", "application/json");
            client.Encoding = Encoding.UTF8;

            var completed = false;
            var attempt = 1;

            while (completed == false)
            {
               if (attempt == retryCount)
               {
                  // Couldn't complete? Clearly something went very wrong
                  // TODO: Sent out a notification email, but to who? 
                  return;
               }

               var source = client.DownloadString(url);
               dynamic data = JObject.Parse(source);

               if (data.status == "completed")
               {
                  // Completed, let's move on!
                  completed = true;
               }

               attempt = attempt + 1;

               Thread.Sleep(2000);
            }
         }            ;

         // Set the keepForever property
         using (var client2 = new WebClient {UseDefaultCredentials = true})
         {

            client2.Headers.Add("Content-Type", "application/json");
            client2.Encoding = Encoding.UTF8;
            client2.UploadString(url, "PATCH", "{keepForever : true}");
         }

      }
   }
}