public string GetBzrPath(BuildContext ctx, int sourceId) { string bzrDir = Path.Combine (ctx.LocalSettings.DataPath, "Bzr"); if (!Directory.Exists (bzrDir)) Directory.CreateDirectory (bzrDir); return Path.Combine (bzrDir, sourceId.ToString ()); }
public override void Fetch(BuildContext ctx, int sourceId, SourceTagInfo stag, StringBuilder output, StringBuilder error) { int i = stag.Url.IndexOf ('|'); string bname = stag.Url.Substring (i + 2); string url = stag.Url.Substring (0, i); UpdateRepo (ctx, sourceId, url, output); }
public override IEnumerable<SourceTagInfo> GetChildUrls(BuildContext ctx, SourceInfo source) { // URL syntax: // url|t<name>,b<name>,... List<string> selBranches = new List<string> (); List<string> selTags = new List<string> (); if (source.Branches != null) { foreach (string b in source.Branches.Split (new char[] {','}, StringSplitOptions.RemoveEmptyEntries)) selBranches.Add (b.Trim ()); } if (source.Tags != null) { foreach (string b in source.Tags.Split (new char[] {','}, StringSplitOptions.RemoveEmptyEntries)) selTags.Add (b.Trim ()); } if (selBranches.Count == 0 && selTags.Count == 0) selBranches.Add ("master"); UpdateRepo (ctx, source.Id, source.Url, null); string gitDir = GetGitPath (ctx, source.Id); string remotePrefix = "origin/"; if (selBranches.Count > 0) { foreach (string b in RunCommand (gitDir, "branch -r", null)) { if (b.Length < 3) continue; string br = b.Substring (2); int i = br.IndexOf (" -> "); if (i != -1) br = br.Substring (0, i); string branchName = br; if (br.StartsWith (remotePrefix)) branchName = br.Substring (remotePrefix.Length); if (Util.FindMatch (branchName, selBranches)) { string rev = GetCurrentRevision (gitDir, br); yield return new SourceTagInfo () { Url = source.Url + "|b" + br, Name = branchName, LastRevision = rev }; } } } if (selTags.Count > 0) { foreach (string t in RunCommand (gitDir, "tag", null)) { if (t.Trim ().Length == 0) continue; if (Util.FindMatch (t, selTags)) { string rev = GetCurrentRevision (gitDir, t); yield return new SourceTagInfo () { Url = source.Url + "|t" + t, Name = t, LastRevision = rev }; } } } }
public override void Fetch(BuildContext ctx, int sourceId, SourceTagInfo stag, StringBuilder output, StringBuilder error) { int i = stag.Url.IndexOf ('|'); string bname = stag.Url.Substring (i + 2); string url = stag.Url.Substring (0, i); UpdateRepo (ctx, sourceId, url, output); string gitDir = GetGitPath (ctx, sourceId); RunCommand (gitDir, "checkout " + bname, output); }
public override void Fetch(BuildContext ctx, int sourceId, SourceTagInfo stag, StringBuilder output, StringBuilder error) { string command; string args; string targetPath = GetSourceTagPath (ctx, sourceId, stag.Id); Util.ResetFolder (targetPath); command = SubversionCommand; args = "export --force " + stag.Url + " \"" + targetPath + "\""; output.AppendLine (command + " " + args); BuildService.RunCommand (command, args, output, error, Timeout); }
public override void Fetch(BuildContext ctx, int sourceId, SourceTagInfo stag, StringBuilder output, StringBuilder error) { string bzrDir = GetBzrPath (ctx, sourceId); string url = stag.Url; int i = stag.Url.IndexOf ('|'); if (i != -1) { url = url.Substring (0, i); UpdateRepo (ctx, sourceId, url, output); string bname = stag.Url.Substring (i + 2); RunCommand (bzrDir, "export -r tag:" + bname + " " + base.GetSourceTagPath (ctx, sourceId, stag.Id), output); } else UpdateRepo (ctx, sourceId, url, output); }
public override IEnumerable<SourceTagInfo> GetChildUrls(BuildContext ctx, SourceInfo source) { StringBuilder output = new StringBuilder (); StringBuilder error = new StringBuilder (); string url = source.Url; if (!url.EndsWith ("/*")) { BuildService.RunCommand (SubversionCommand, "info --xml " + url, output, error, Timeout); XmlDocument doc = new XmlDocument (); doc.LoadXml (output.ToString ()); XmlElement elem = (XmlElement) doc.SelectSingleNode ("/info/entry"); if (elem == null) { elem = (XmlElement)doc.SelectSingleNode ("/info"); if (elem != null) throw new Exception (elem.InnerText); else if (error.Length > 0) throw new Exception (error.ToString ()); else throw new Exception ("Error while getting repository information"); } yield return new SourceTagInfo () { Url = url, Name = elem.GetAttribute ("path"), LastRevision = elem.GetAttribute ("revision") }; } else { url = url.Substring (0, url.Length - 2); BuildService.RunCommand (SubversionCommand, "ls --xml " + url, output, error, Timeout); XmlDocument doc = new XmlDocument (); try { doc.LoadXml (output.ToString ()); } catch { if (error.Length > 0) throw new Exception (error.ToString ()); else throw new Exception ("Error while getting repository information"); } foreach (XmlElement elem in doc.SelectNodes ("/lists/list/entry")) { string name = elem["name"].InnerText; string revision = elem["commit"].GetAttribute ("revision"); yield return new SourceTagInfo () { Url = url + "/" + name, Name = name, LastRevision = revision }; } } }
void UpdateRepo(BuildContext ctx, int sourceId, string url, StringBuilder output) { string bzrDir = GetBzrPath (ctx, sourceId); if (!Directory.Exists (bzrDir)) RunCommand (".", "checkout " + url + " " + bzrDir, output); else { try { RunCommand (bzrDir, "update", output); } catch (Exception ex) { LogService.WriteLine (ex); // If something goes wrong while updating, reclone Directory.Delete (bzrDir, true); RunCommand (".", "checkout " + url + " " + bzrDir, output); } } }
public static string GetPackagePath(this SourceTagInfo stag, BuildContext ctx) { string path = ctx.LocalSettings.PackagesPath; return Path.GetFullPath (Path.Combine (path, stag.Id.ToString ())); }
public override void PrepareForBuild(BuildContext ctx, int sourceId, SourceTagInfo stag) { int i = stag.Url.IndexOf ('|'); string bname = stag.Url.Substring (i + 2); string gitDir = GetGitPath (ctx, sourceId); RunCommand (gitDir, "checkout " + bname, null); }
void BuildSource(BuildContext ctx, SourceInfo source, SourceTagInfo stag, string logFile) { SourcePuller sp = VersionControl.GetSourcePuller (source.Type); sp.PrepareForBuild (ctx, source.Id, stag); string destPath = Path.GetFullPath (source.GetAddinSourcePath (ctx, stag)); string sourcePath = destPath; if (!string.IsNullOrEmpty (source.Directory)) sourcePath = Path.Combine (sourcePath, NormalizePath (source.Directory)); sourcePath = Path.GetFullPath (sourcePath); if (sourcePath != destPath && !sourcePath.StartsWith (destPath)) throw new Exception ("Invalid source directory: " + source.Directory); string projectFile = Path.Combine (sourcePath, "addin-project.xml"); if (!File.Exists (projectFile)) { string msg = "addin-project.xml file not found"; if (!string.IsNullOrEmpty (source.Directory)) msg += " (looked in '" + source.Directory + "' directory)"; throw new Exception (msg); } AddinProject addinProject; StreamReader sr = new StreamReader (projectFile); using (sr) { XmlSerializer ser = new XmlSerializer (typeof(AddinProject)); addinProject = (AddinProject) ser.Deserialize (sr); } if (string.IsNullOrEmpty (addinProject.AppVersion)) throw new Exception ("Target application version not specified in addin-project.xml"); AppReleaseInfo rel = ctx.Server.GetAppReleases (ctx.AppId).Where (r => r.AppVersion == addinProject.AppVersion).FirstOrDefault (); if (rel == null) throw new Exception ("Application release " + addinProject.AppVersion + " not found."); RefreshAppRelease (ctx, rel); // Delete old packages foreach (string f in Directory.GetFiles (sourcePath, "*.mpack")) File.Delete (f); List<AddinData> addins = new List<AddinData> (); foreach (AddinProjectAddin addin in addinProject.Addins) { addins.Add (BuildProjectAddin (ctx, stag, logFile, sourcePath, rel, addin)); } ctx.Server.SetSourceTagBuildData (ctx.AppId, stag.Id, addins.ToArray ()); }
void BuildProjects(BuildContext ctx, ServerEventArgs ev) { foreach (SourceInfo source in ctx.Server.GetSources (ctx.AppId)) { if (ev.ProjectId != -1 && ev.ProjectId != source.ProjectId) continue; foreach (SourceTagInfo stag in source.SourceTags) { try { string sourcesPath = source.GetAddinSourcePath (ctx, stag); if (!Directory.Exists (sourcesPath) || !Directory.Exists (stag.GetPackagePath (ctx)) || stag.Status == SourceTagStatus.Waiting) { BuildSource (ctx, source, stag); } } catch (Exception ex) { try { File.AppendAllText (stag.GetLogFile (ctx), "<pre>" + HttpUtility.HtmlEncode (ex.ToString ()) + "</pre>"); PushFiles (ctx, source, stag, true); ctx.Server.SetSourceTagStatus (ctx.AppId, stag.Id, SourceTagStatus.BuildError); } catch { } } } } }
void FetchSource(BuildContext ctx, SourceInfo vcs, SourceTagInfo stag, string logFile) { StringBuilder sb = new StringBuilder (); try { SourcePuller sp = VersionControl.GetSourcePuller (vcs.Type); sp.Fetch (ctx, vcs.Id, stag, sb, sb); } finally { File.AppendAllText (logFile, "<pre>" + HttpUtility.HtmlEncode (sb.ToString ()) + "</pre><br/><br/>"); } }
public string GetGitPath(BuildContext ctx, int sourceId) { string gitDir = Path.Combine (ctx.LocalSettings.DataPath, "Git"); if (!Directory.Exists (gitDir)) Directory.CreateDirectory (gitDir); return Path.Combine (gitDir, sourceId.ToString ()); }
public override void PrepareForBuild(BuildContext ctx, int sourceId, SourceTagInfo stag) { int i = stag.Url.IndexOf ('|'); string bname = stag.Url.Substring (i + 2); string gitDir = GetGitPath (ctx, sourceId); RunCommand (gitDir, "reset --hard", null); RunCommand (gitDir, "checkout " + bname, null); RunCommand (gitDir, "submodule update --init --recursive", null); }
public static string GetLogFile(this SourceTagInfo stag, BuildContext ctx) { return Path.Combine (stag.GetPackagePath (ctx), "log.html"); }
bool BuildSource(BuildContext ctx, SourceInfo vcs, SourceTagInfo stag) { // Fetch the source ctx.Status = "Fetching project " + vcs.ProjectName + " (" + stag.Name + ")"; Util.ResetFolder (stag.GetPackagePath (ctx)); string logFile = stag.GetLogFile (ctx); File.AppendAllText (logFile, "<p><b>Fetching Source</b></p>"); ctx.Server.SetSourceTagStatus (ctx.AppId, stag.Id, SourceTagStatus.Fetching); try { FetchSource (ctx, vcs, stag, logFile); } catch (Exception ex) { File.AppendAllText (logFile, HttpUtility.HtmlEncode (ex.Message) + "<br/><br/>"); PushFiles (ctx, vcs, stag, true); ctx.Server.SetSourceTagStatus (ctx.AppId, stag.Id, SourceTagStatus.FetchError); ctx.Log (ex); return false; } // Build the add-in ctx.Status = "Building project " + vcs.ProjectName; File.AppendAllText (logFile, "<p><b>Building Solution</b></p>"); ctx.Server.SetSourceTagStatus (ctx.AppId, stag.Id, SourceTagStatus.Building); try { BuildSource (ctx, vcs, stag, logFile); } catch (Exception ex) { File.AppendAllText (logFile, "<p>" + HttpUtility.HtmlEncode (ex.Message) + "</p>"); PushFiles (ctx, vcs, stag, true); ctx.Server.SetSourceTagStatus (ctx.AppId, stag.Id, SourceTagStatus.BuildError); ctx.Log (ex); return false; } PushFiles (ctx, vcs, stag, false); ctx.Server.SetSourceTagBuiltAsync (ctx.AppId, stag.Id); return true; }
/* public static string GetAddinSourcePath (this SourceTagInfo stag) { string path = Settings.Default.SourcesPath; return Path.GetFullPath (Path.Combine (path, stag.Id.ToString ())); }*/ public static string GetAssembliesPath(this AppReleaseInfo rel, BuildContext ctx) { return Path.GetFullPath (Path.Combine (ctx.LocalSettings.AppReleasesPath, rel.AppVersion)); }
public static string GetAddinSourcePath(this SourceInfo source, BuildContext ctx, SourceTagInfo stag) { SourcePuller sp = VersionControl.GetSourcePuller (source.Type); return sp.GetSourceTagPath (ctx, source.Id, stag.Id); }
public static void CleanSources(this SourceInfo source, BuildContext ctx, SourceTagInfo sourceTag) { if (Directory.Exists (sourceTag.GetPackagePath (ctx))) Directory.Delete (sourceTag.GetPackagePath (ctx), true); }
void PushFiles(BuildContext ctx, SourceInfo source, SourceTagInfo stag, bool safe) { try { ctx.Status = "Uploading files for project " + source.ProjectName; foreach (string file in Directory.GetFiles (stag.GetPackagePath (ctx))) { ctx.Log (LogSeverity.Info, "Uploading [" + source.ProjectName + "] " + Path.GetFileName (file)); WebRequest req = HttpWebRequest.Create (ctx.ServerUrl + "/package/upload"); req.Headers ["applicationId"] = ctx.AppId.ToString (); req.Headers ["sourceTagId"] = stag.Id.ToString (); req.Headers ["fileName"] = Path.GetFileName (file); req.Method = "POST"; req.GetRequestStream ().WriteFile (file); using (StreamReader s = new StreamReader (req.GetResponse ().GetResponseStream ())) { if (s.ReadToEnd () != "OK") throw new Exception ("File upload failed"); } } } catch { if (!safe) throw; } finally { ctx.Status = "Files uploaded"; } }
bool HandleError(BuildContext ctx, Exception ex) { try { ctx.Status = "ERROR: " + ex.Message; ctx.Log (ex); return true; } catch (Exception e) { Console.WriteLine (e); ctx.Connected = false; return false; } }
public override IEnumerable<SourceTagInfo> GetChildUrls(BuildContext ctx, SourceInfo source) { List<string> selTags = new List<string> (); if (source.Tags != null) { foreach (string b in source.Tags.Split (new char[] {','}, StringSplitOptions.RemoveEmptyEntries)) selTags.Add (b.Trim ()); } UpdateRepo (ctx, source.Id, source.Url, null); string bzrDir = GetBzrPath (ctx, source.Id); if (selTags.Count > 0) { foreach (string t in RunCommand (bzrDir, "tags", null)) { int i = t.IndexOf (' '); string tn = t.Substring (0, i); if (Util.FindMatch (t, selTags)) { string rev = t.Substring (i+1).Trim (); yield return new SourceTagInfo () { Url = source.Url + "|t" + tn, Name = tn, LastRevision = rev }; } } } else { int i = source.Url.LastIndexOf ('/'); string rev = RunCommand (bzrDir, "revno", null).FirstOrDefault () ?? "Unknown"; yield return new SourceTagInfo () { Url = source.Url, Name = source.Url.Substring (i+1), LastRevision = rev }; } }
public abstract void Fetch(BuildContext ctx, int sourceId, SourceTagInfo stag, StringBuilder output, StringBuilder error);
public override string GetSourceTagPath(BuildContext ctx, int sourceId, int sourceTagId) { return GetGitPath (ctx, sourceId); }
public virtual string GetSourceTagPath(BuildContext ctx, int sourceId, int sourceTagId) { return Path.Combine (ctx.LocalSettings.DataPath, Path.Combine ("Source", sourceTagId.ToString ())); }
void UpdateRepo(BuildContext ctx, int sourceId, string url, StringBuilder output) { string gitDir = GetGitPath (ctx, sourceId); if (!Directory.Exists (gitDir)) RunCommand (".", "clone --depth=1 " + url + " " + gitDir, output); else { try { RunCommand (gitDir, "fetch origin", output); } catch (Exception ex) { Console.WriteLine ("Error: " + ex.Message); // If something goes wrong while updating, reclone Directory.Delete (gitDir, true); RunCommand (null, "clone --depth=1 " + url + " " + gitDir, output); } } }
public virtual void PrepareForBuild(BuildContext ctx, int sourceId, SourceTagInfo stag) { }
public abstract IEnumerable<SourceTagInfo> GetChildUrls(BuildContext ctx, SourceInfo source);
bool ConnectToServer(BuildContext ctx) { try { if (ctx.Connect ()) { ctx.Connected = true; return true; } else { if (ctx.FirstNotAuthorised) { Console.WriteLine ("ERROR: Connection to server not authorized."); Console.WriteLine ("To enable connections from this service, go to the administration page"); Console.WriteLine ("in the server and click on the Change Service option."); ctx.FirstNotAuthorised = false; } else Console.WriteLine ("Connection not authorized. Trying again."); } } catch (Exception ex) { Console.WriteLine ("Connection failed: " + ex.Message); } ctx.Connected = false; return false; }