protected override void Compile (BuildLogger logger, BuildConfig config, string cloneDirectory, GitHub_Commit commit) { MainClass.Plugins.ForEachPlugin ((plugin) => { plugin.BeforeCompile (this, logger, config, cloneDirectory, commit); }); //Print info Run (logger, MonoPath, $"--version", cloneDirectory); Run (logger, XbuildPath, $"/version", cloneDirectory); //Post build commands - Default: restore packages if (config == null || config.PreBuild == null || config.PreBuild.Length == 0) { Console.WriteLine ("No config pre-build commands"); Run (logger, "nuget", $"restore \"{config.SolutionFile}\"", cloneDirectory); } else { foreach (var command in config.PreBuild) { var line = command.Replace ("{mono-path}", MonoPath); var firstSpace = line.IndexOf (' '); var cmd = line.Substring (0, firstSpace); var args = line.Remove (0, firstSpace + 1); Run (logger, cmd, args, cloneDirectory); } } //Compile if (String.IsNullOrEmpty (config.BuildArgs)) { Run (logger, XbuildPath, $"\"{config.SolutionFile}\"", cloneDirectory); } else { Run (logger, XbuildPath, config.BuildArgs, cloneDirectory); } MainClass.Plugins.ForEachPlugin ((plugin) => { plugin.AfterCompile (this, logger, config, cloneDirectory, commit); }); }
private void Processor() { while (_pending.Count > 0) { GitHub_Commit commit; if (_pending.TryDequeue (out commit)) { //Generate the clone directory var cloneDirectory = GetProjectPath (commit.CommitId); #if !DEBUG using (var db = new RepoContext ()) { var commit = db.Commits.SingleOrDefault (x => x.RepositoryId == _repoId && x.SHA == sha); if (null == commit) { commit = new GitHook_Mono.Data.Models.Commit () { RepositoryId = _repoId, SHA = sha }; db.Commits.Add (commit); } commit.Status = GitHook_Mono.Data.Models.CommitStatus.Processing; db.SaveChanges (); #endif BuildConfig current = null; try { var logPath = commit.CommitId + ".log"; var logger = new BuildLogger (logPath); //Clone logger.WriteLine ("Cloning..."); Clone (logger, cloneDirectory, commit); logger.WriteLine ("Clone Completed."); //Load config var cfg = System.IO.Path.Combine (cloneDirectory, BuildFile); BuildConfig[] config; try { config = MainClass.LoadConfig<BuildConfig[]> (cfg); } catch { config = new BuildConfig[] { MainClass.LoadConfig<BuildConfig> (cfg) }; } if (null == config) { logger.WriteLine ($"Failed to load configuration file at: {cfg}"); return; } // Console.WriteLine ("Config: " + config.ToString ()); foreach (var build in config) { current = build; //For each build configuration we must ensure we are working with the freshest copy Run (logger, "git", "reset --hard origin/master", cloneDirectory); //Now that we have a clone, we can attempt to load some config if (String.IsNullOrEmpty (build.SolutionFile)) { var sln = System.IO.Directory.GetFiles (cloneDirectory, "*.sln"); if (sln != null && sln.Length > 0) { if (sln.Length == 1) { /*if (config == null) build = new BuildConfig () { SolutionFile = sln.First () }; else*/ build.SolutionFile = sln.First (); } else { throw new CompilerException (1, $"Too many solution files detected, please specify one in your {BuildFile}"); } } else { throw new CompilerException (1, $"No solution file specified in {BuildFile}"); } } //Start compilation logger.WriteLine ("Compiling..."); Compile (logger, build, cloneDirectory, commit); logger.WriteLine ("Compiling Completed."); MainClass.Plugins.ForEachPlugin ((plugin) => { plugin.OnPass (this, cloneDirectory, commit, current); }); } logger.Close (); MainClass.Plugins.ForEachPlugin ((plugin) => { plugin.LogClosed (this, logPath); }); #if !DEBUG commit.Status = GitHook_Mono.Data.Models.CommitStatus.Passed; #endif } catch (CompilerException ex) { #if !DEBUG commit.Status = GitHook_Mono.Data.Models.CommitStatus.Failed; #endif Console.WriteLine (ex.ToString ()); MainClass.Plugins.ForEachPlugin ((plugin) => { plugin.OnFail (this, cloneDirectory, commit, current); }); } #if !DEBUG db.Repositories.Single (x => x.Id == _repoId).Builds++; _builds++; db.SaveChanges (); } #endif } } }
protected abstract void Compile(BuildLogger logger, BuildConfig config, string cloneDirectory, GitHub_Commit commit);
protected virtual void Clone(BuildLogger logger, string cloneDirectory, GitHub_Commit commit) { //Touch the directory if (!System.IO.Directory.Exists (WorkingDirectory)) System.IO.Directory.CreateDirectory (WorkingDirectory); #if !TESTING //If for some reason the clone directory exists, then it must be removed for git will crash and burn. if (System.IO.Directory.Exists (cloneDirectory)) System.IO.Directory.Delete (cloneDirectory, true); //Clone from github into the target directory Run (logger, "git", $"clone --depth=50 --branch=master {_repository.CloneUrl} {cloneDirectory}"); #endif //Checkout the target commit Run (logger, "git", $"checkout -qf {commit.CommitId}", cloneDirectory); //Initialise sub modules Run (logger, "git", $"submodule init", cloneDirectory ); }
public void Run(BuildLogger logger, string command, string args, string workingPath = WorkingDirectory) { logger.WriteLine ($"{command} {args}"); var pc = new Process () { StartInfo = new ProcessStartInfo () { FileName = command, Arguments = args, WorkingDirectory = workingPath, RedirectStandardError = true, RedirectStandardOutput = true, UseShellExecute = false } }; if (pc == null) { Console.WriteLine ("Failed to start process"); throw new CompilerException (1); } using (var ar = new AutoResetEvent (false)) using (var outputWaitHandle = new AutoResetEvent (false)) using (var errorWaitHandle = new AutoResetEvent (false)) { pc.ErrorDataReceived += (sender, e) => { if (!String.IsNullOrEmpty (e.Data)) logger.WriteLine (e.Data); else if(e.Data == null) outputWaitHandle.Set (); }; pc.OutputDataReceived += (sender, e) => { if (!String.IsNullOrEmpty (e.Data)) logger.WriteLine (e.Data); else if(e.Data == null) errorWaitHandle.Set (); }; pc.Exited += (sender, e) => { ar.Set (); }; pc.Start (); pc.BeginErrorReadLine (); pc.BeginOutputReadLine (); Console.WriteLine ("Waiting"); var timeout = 1000 * 60 * 5; if (pc.WaitForExit (timeout) && outputWaitHandle.WaitOne (timeout) && errorWaitHandle.WaitOne (timeout)) { Console.WriteLine ("Done"); if (0 != pc.ExitCode) { throw new CompilerException (pc.ExitCode); } } else { Console.WriteLine ("Process timed out"); throw new CompilerException (1); } } }
/// <summary> /// Called before any compilation steps are performed. /// </summary> /// <param name="compiler">Compiler being used.</param> /// <param name="logger">The build log.</param> /// <param name="config">Config.</param> /// <param name="cloneDirectory">Clone directory.</param> /// <param name="commit">Commit details.</param> public virtual void BeforeCompile(IProjectCompiler compiler, BuildLogger logger, BuildConfig config, string cloneDirectory, GitHub_Commit commit) { }