using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Net.Http; using System.Reflection; using System.Security.Cryptography.X509Certificates; using System.Text; using ln.json; using ln.logging; using ln.threading; namespace ln.build { public class CIJob : PoolJob { static HttpClient httpClient = new HttpClient(); public string JobID { get; } = Guid.NewGuid().ToString("N"); public string RepositoryURL { get; } public string RepositoryName { get; } public string Commit { get; } public string NotifyEMail { get; set; } public string WorkingDirectory { get; set; } public Logger Logger { get; private set; } List pipeLines = new List(); Dictionary variables = new Dictionary(); Dictionary logStreams = new Dictionary(); Dictionary logStreamLoggers = new Dictionary(); public CIJob(string repositoryName, string repositoryURL, string commit, string notifyEMail) { WorkingDirectory = Path.Combine(Path.GetTempPath(), JobID); Logger = new Logger(new FileLogger(Path.Combine(Path.GetTempPath(), String.Format("{0}.log", JobID)))); Logger.Backends.Add(Logger.ConsoleLogger); RepositoryName = repositoryName; RepositoryURL = repositoryURL; Commit = commit; NotifyEMail = notifyEMail; } public Stream GetLogStream(string name) { if (!logStreams.TryGetValue(name,out MemoryStream logStream)) { logStream = new MemoryStream(); logStreams.Add(name, logStream); } return logStream; } public Logger GetLogger(string name) { if (!logStreamLoggers.TryGetValue(name, out Logger logStreamLogger)) { logStreamLogger = new Logger(GetLogStream(name)); logStreamLogger.Backends.Add(Logger.ConsoleLogger); logStreamLoggers.Add(name, logStreamLogger); } return logStreamLogger; } public string GetVariable(string varName) => GetVariable(varName, null); public string GetVariable(string varName,string defValue) { if (!variables.TryGetValue(varName,out string value)) value = defValue; return value; } public void SetVariable(string varName,string value) { if (value != null) variables[varName] = value; else variables.Remove(varName); } public void ExtendVariable(string varName,string value) => ExtendVariable(varName, value, ':'); public void ExtendVariable(string varName, string value, char seperator) { String currentValue = GetVariable(varName, ""); if (String.Empty.Equals(currentValue)) { currentValue = value; } else { currentValue = string.Format("{0}{1}{2}",currentValue, seperator, value); } SetVariable(varName, currentValue); } public async void UpdateBuildState(BuildState buildState) { string buildStateURL = String.Format("https://git.l--n.de/api/v1/repos/{0}/{1}/statuses/{2}", GetVariable("REPO_OWNER"), GetVariable("REPO_NAME"), GetVariable("COMMIT_ID") ); if (buildStateURL != null) { JSONObject stateObject = new JSONObject(); stateObject.Add("context", "ln.build"); stateObject.Add("description", "build job pending"); stateObject.Add("state", buildState.ToString().ToLower()); stateObject.Add("target_url", JSONNull.Instance); HttpResponseMessage response = await httpClient.PostAsync(buildStateURL, new StringContent(stateObject.ToString(),Encoding.UTF8,"application/json")); Logger.Log(LogLevel.DEBUG, "UpdateBuildState({0}): {1}", buildState, buildStateURL); Logger.Log(LogLevel.DEBUG, "Response: {0}", response ); } } public override void RunJob() { CloneRepository(); DetectPipelines(); try{ foreach (PipeLine pipeLine in pipeLines) { pipeLine.Run(this); } UpdateBuildState(BuildState.SUCCESS); } catch (Exception e) { UpdateBuildState(BuildState.FAILURE); } Notify(); Cleanup(); } void DetectPipelines() { string[] sln = Directory.GetFileSystemEntries(WorkingDirectory,"*.sln"); if (sln.Length > 0) { pipeLines.Add(new DotNetPipeLine()); } } public void CloneRepository() { Logging.Log("cloning repository to {0}", WorkingDirectory); new CommandRunner(Logger, "git", "clone",RepositoryURL,WorkingDirectory).Run(); new CommandRunner(Logger, "git", "checkout", Commit).Run(); } public void Notify() { } public void Cleanup() { Directory.Delete(WorkingDirectory, true); } static CIJob() { httpClient.DefaultRequestHeaders.Add("Authorization","token 1d03e9577c404b5b4f46b340147b1d500ff95b2e"); } } }