192 lines
6.2 KiB
C#
192 lines
6.2 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.IO;
|
|
using ln.build.commands;
|
|
using ln.build.pipeline;
|
|
using ln.build.repositories;
|
|
using ln.build.secrets;
|
|
using ln.build.semver;
|
|
using ln.json;
|
|
using ln.logging;
|
|
using ln.threading;
|
|
|
|
namespace ln.build
|
|
{
|
|
public delegate void CIJobCompleted(CIJob cIJob);
|
|
public class CIJob : PoolJob
|
|
{
|
|
public event CIJobCompleted OnJobCompleted;
|
|
|
|
public string JobID { get; } = Guid.NewGuid().ToString("N");
|
|
public CIService CIService { get; }
|
|
public Repository Repository { get; set; }
|
|
public SecretStorage SecretStorage { get; set; }
|
|
|
|
public string WorkingDirectory { get; set; }
|
|
|
|
|
|
public Logger Logger { get; private set; }
|
|
|
|
public CommandEnvironment Environment { get; }
|
|
|
|
|
|
|
|
public DefaultPipeLine PipeLine { get; set; }
|
|
|
|
public BuildState BuildState { get; private set; }
|
|
|
|
Dictionary<string,MemoryStream> logStreams = new Dictionary<string, MemoryStream>();
|
|
Dictionary<string,Logger> logStreamLoggers = new Dictionary<string, Logger>();
|
|
|
|
public CIJob(CIService ciService, Repository repository, SecretStorage secretStorage)
|
|
:this(ciService, repository)
|
|
{
|
|
SecretStorage = secretStorage;
|
|
Environment.SecretStorage = secretStorage;
|
|
}
|
|
public CIJob(CIService ciService, Repository repository)
|
|
{
|
|
CIService = ciService;
|
|
Repository = repository;
|
|
|
|
WorkingDirectory = Path.Combine(Path.GetTempPath(), JobID);
|
|
Directory.CreateDirectory(Path.Combine(ciService.ReportsDirectory, JobID));
|
|
|
|
Logger = new Logger(new FileLogger(Path.Combine(ciService.ReportsDirectory, JobID, "build.log")));
|
|
Logger.Backends.Add(Logger.ConsoleLogger);
|
|
|
|
Environment = new CommandEnvironment(){ CIJob = this, WorkingDirectory = WorkingDirectory };
|
|
}
|
|
|
|
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 GetLoggedContent(string name)
|
|
{
|
|
logStreams[name].Position = 0;
|
|
using StreamReader sr = new StreamReader(logStreams[name]);
|
|
return sr.ReadToEnd();
|
|
}
|
|
public IEnumerable<string> GetLogStreamNames() => logStreams.Keys;
|
|
|
|
public string GetVariable(string varName) => Environment.Get(varName);
|
|
public string GetVariable(string varName,string defValue) => Environment.Get(varName, defValue);
|
|
public bool ContainsVariable(string varName) => Environment.Contains(varName);
|
|
public CIJob SetVariable(string varName,string varValue){ Environment.Set(varName,varValue); return this; }
|
|
|
|
public void UpdateBuildState(BuildState buildState)
|
|
{
|
|
BuildState = buildState;
|
|
Repository?.UpdateBuildState(this);
|
|
}
|
|
|
|
public override void RunJob()
|
|
{
|
|
if (CloneRepository())
|
|
{
|
|
try
|
|
{
|
|
LoadPipeLine();
|
|
|
|
PipeLine.Run();
|
|
|
|
UpdateBuildState(BuildState.SUCCESS);
|
|
} catch (Exception e)
|
|
{
|
|
Logger.Log(e);
|
|
UpdateBuildState(BuildState.FAILURE);
|
|
}
|
|
} else {
|
|
Logger.Log(LogLevel.ERROR, "CIJob failed at CloneRepository()");
|
|
}
|
|
|
|
OnJobCompleted?.Invoke(this);
|
|
|
|
Notify();
|
|
Cleanup();
|
|
}
|
|
|
|
public bool CloneRepository()
|
|
{
|
|
Repository?.CloneSources(this);
|
|
return true;
|
|
}
|
|
|
|
public void LoadPipeLine()
|
|
{
|
|
JSONObject jsonPipeLine = JSONParser.ParseFile(Path.Combine(WorkingDirectory, "build.ln")) as JSONObject;
|
|
if (jsonPipeLine != null)
|
|
{
|
|
DefaultPipeLine pipeLine = new DefaultPipeLine(CIService, Environment);
|
|
pipeLine.LoadJson(jsonPipeLine);
|
|
|
|
PipeLine = pipeLine;
|
|
}
|
|
}
|
|
|
|
public void Notify()
|
|
{
|
|
// foreach (string key in logStreams.Keys)
|
|
// {
|
|
// logStreams[key].Position = 0;
|
|
// string logContent;
|
|
// using (StreamReader sr = new StreamReader(logStreams[key]))
|
|
// logContent = sr.ReadToEnd();
|
|
|
|
// Logger.Log(LogLevel.INFO, "------------------- LogStream {0} ---------------------------\n{1}", key, logContent);
|
|
// }
|
|
}
|
|
|
|
public void Cleanup()
|
|
{
|
|
CIService.CreateReport(this);
|
|
|
|
if (Repository != null)
|
|
Directory.Delete(WorkingDirectory, true);
|
|
}
|
|
|
|
|
|
public void PublishRelease(SemVerLevels releaseLevel)
|
|
{
|
|
if (BuildState == BuildState.SUCCESS)
|
|
{
|
|
if (PipeLine.Versioning != null)
|
|
{
|
|
Versioning versioning = PipeLine.Versioning;
|
|
SemVersion version = versioning.GetCurrentVersion(this);
|
|
|
|
if (version.IsPreRelease)
|
|
{
|
|
SemVersion releaseVersion = new SemVersion(version);
|
|
releaseVersion.PreRelease = null;
|
|
|
|
versioning.SetVersion(this, releaseVersion);
|
|
} else if (version.IsRelease)
|
|
{
|
|
|
|
}
|
|
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|
|
}
|