ln.build/ln.build/CIJob.cs

176 lines
5.8 KiB
C#

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<PipeLine> pipeLines = new List<PipeLine>();
Dictionary<string,string> variables = new Dictionary<string, string>();
Dictionary<string,MemoryStream> logStreams = new Dictionary<string, MemoryStream>();
Dictionary<string,Logger> logStreamLoggers = new Dictionary<string, Logger>();
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");
}
}
}