private static int Main2(string [] arguments) { Lock process_lock; ReportBuildBotStatusResponse status_response; BuildBotStatus status; try { if (!Configuration.LoadConfiguration(arguments)) { Logger.Log("Could not load configuration."); return(1); } if (!Configuration.VerifyBuildBotConfiguration()) { Logger.Log("Configuration verification failed."); return(1); } process_lock = Lock.Create("MonkeyWrench.Builder"); if (process_lock == null) { Logger.Log("Builder could not acquire lock. Exiting"); return(1); } Logger.Log("Builder lock aquired successfully."); } catch (Exception ex) { Logger.Log("Could not aquire lock: {0}", ex.Message); return(1); } try { WebService = WebServices.Create(); WebService.CreateLogin(Configuration.Host, Configuration.WebServicePassword); status = new BuildBotStatus(); status.Host = Configuration.Host; status.FillInAssemblyAttributes(); status_response = WebService.ReportBuildBotStatus(WebService.WebServiceLogin, status); if (status_response.Exception != null) { Logger.Log("Failed to report status: {0}", status_response.Exception.Message); return(1); } if (!string.IsNullOrEmpty(status_response.ConfiguredVersion) && status_response.ConfiguredVersion != status.AssemblyVersion) { if (!Update(status, status_response)) { Console.Error.WriteLine("Automatic update to: {0} / {1} failed (see log for details). Please update manually.", status_response.ConfiguredVersion, status_response.ConfiguredRevision); return(2); /* Magic return code that means "automatic update failed" */ } else { Console.WriteLine("The builder has been updated. Please run 'make build' again."); return(1); } } response = WebService.GetBuildInfoMultiple(WebService.WebServiceLogin, Configuration.Host, true); if (!response.Host.enabled) { Logger.Log("This host is disabled. Exiting."); return(0); } Logger.Log("Builder will now build {0} lists of work items.", response.Work.Count); for (int i = 0; i < response.Work.Count; i++) { //foreach (var item in response.Work) Logger.Log("Building list #{0}/{1}", i + 1, response.Work.Count); Build(response.Work [i]); //item); } Logger.Log("Builder finished successfully."); return(0); } catch (Exception ex) { Logger.Log("An exception occurred: {0}", ex.ToString()); return(1); } finally { process_lock.Unlock(); } }
private static bool Update(BuildBotStatus status, ReportBuildBotStatusResponse status_response) { StringBuilder output = new StringBuilder(); Logger.Log("This host is at version {0}, while it should be running version {1} ({2}). Will try to update.", status.AssemblyVersion, status_response.ConfiguredVersion, status_response.ConfiguredRevision); try { /* Check with git status if working copy is clean */ using (Process git = new Process()) { git.StartInfo.FileName = "git"; git.StartInfo.Arguments = "status -s"; git.StartInfo.UseShellExecute = false; git.StartInfo.RedirectStandardError = true; git.StartInfo.RedirectStandardOutput = true; git.OutputDataReceived += delegate(object sender, DataReceivedEventArgs e) { lock (output) { output.AppendLine(e.Data); } }; git.ErrorDataReceived += delegate(object sender, DataReceivedEventArgs e) { lock (output) { output.AppendLine(e.Data); } }; git.Start(); git.BeginErrorReadLine(); git.BeginOutputReadLine(); if (!git.WaitForExit((int)TimeSpan.FromMinutes(1).TotalMilliseconds)) { Logger.Log("Builder.Update (): Could not get git status, git didn't get any status in 1 minute."); return(false); } if (git.ExitCode != 0) { Logger.Log("Builder.Update (): git status failed: {0}", output.ToString()); return(false); } string stdout = output.ToString().Trim(); if (string.IsNullOrEmpty(stdout)) { /* OK */ } else if (stdout.Contains("nothing to commit (working directory clean)")) { /* OK - git 1.6 doesn't seem to understand the -s flag */ } else { Logger.Log("Builder.Update (): git status shows that there are local changes: \n{0}", output); return(false); } } /* git status shows we're clean, now run git fetch */ output.Length = 0; using (Process git = new Process()) { git.StartInfo.FileName = "git"; git.StartInfo.Arguments = "fetch"; git.StartInfo.UseShellExecute = false; git.StartInfo.RedirectStandardError = true; git.StartInfo.RedirectStandardOutput = true; git.OutputDataReceived += delegate(object sender, DataReceivedEventArgs e) { lock (output) { output.AppendLine(e.Data); } }; git.ErrorDataReceived += delegate(object sender, DataReceivedEventArgs e) { lock (output) { output.AppendLine(e.Data); } }; git.Start(); git.BeginErrorReadLine(); git.BeginOutputReadLine(); if (!git.WaitForExit((int)TimeSpan.FromMinutes(1).TotalMilliseconds)) { Logger.Log("Builder.Update (): git fetch didn't finish in 1 minute"); return(false); } if (git.ExitCode != 0) { Logger.Log("Builder.Update (): git status failed: {0}", output.ToString()); return(false); } } /* git fetch done, checkout the revision we want */ output.Length = 0; using (Process git = new Process()) { git.StartInfo.FileName = "git"; git.StartInfo.Arguments = "reset --hard " + status_response.ConfiguredRevision; git.StartInfo.UseShellExecute = false; git.StartInfo.RedirectStandardError = true; git.StartInfo.RedirectStandardOutput = true; git.OutputDataReceived += delegate(object sender, DataReceivedEventArgs e) { lock (output) { output.AppendLine(e.Data); } }; git.ErrorDataReceived += delegate(object sender, DataReceivedEventArgs e) { lock (output) { output.AppendLine(e.Data); } }; git.Start(); git.BeginErrorReadLine(); git.BeginOutputReadLine(); if (!git.WaitForExit((int)TimeSpan.FromMinutes(1).TotalMilliseconds)) { Logger.Log("Builder.Update (): Could not checkout the required revision in 1 minute."); return(false); } if (git.ExitCode != 0) { Logger.Log("Builder.Update (): git reset failed: {0}", output.ToString()); return(false); } } Logger.Log("Successfully updated to {0} {1})", status_response.ConfiguredVersion, status_response.ConfiguredRevision); } catch (Exception ex) { Logger.Log("Builder.Update (): exception caught: {0}", ex.Message); return(false); } return(true); }