如果构建仍然 运行,则无法设置 keepforever
Can't set keepforever if the build is still running
我有一个简单的 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 已更改,但不会持久保存。
只有在构建完成后,它才能可靠地工作。
在我写冗长的解决方法之前,有什么明显的我遗漏的吗?当构建 运行ning 时,是否可以强制更新?
我实施了一个解决方法:
首先创建了一个控制台应用程序,这就是在构建步骤中调用的应用程序:
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}");
}
}
}
}
我有一个简单的 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 已更改,但不会持久保存。
只有在构建完成后,它才能可靠地工作。
在我写冗长的解决方法之前,有什么明显的我遗漏的吗?当构建 运行ning 时,是否可以强制更新?
我实施了一个解决方法:
首先创建了一个控制台应用程序,这就是在构建步骤中调用的应用程序:
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}");
}
}
}
}