diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 0000000..3f4c490 --- /dev/null +++ b/.github/workflows/build.yml @@ -0,0 +1,18 @@ +name: Build Plogon +on: [push, pull_request] + +jobs: + build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - name: Setup .NET Core SDK + uses: actions/setup-dotnet@v2 + with: + dotnet-version: "6.0.x" + - name: Install dependencies + working-directory: Plogon + run: dotnet restore + - name: Build + working-directory: Plogon + run: dotnet build --configuration Release --no-restore diff --git a/Plogon/BuildProcessor.cs b/Plogon/BuildProcessor.cs index e2bc383..9895d3f 100644 --- a/Plogon/BuildProcessor.cs +++ b/Plogon/BuildProcessor.cs @@ -18,9 +18,11 @@ public class BuildProcessor private readonly DirectoryInfo repoFolder; private readonly DirectoryInfo manifestFolder; private readonly DirectoryInfo workFolder; + private readonly DirectoryInfo staticFolder; + private readonly DockerClient dockerClient; - + private PluginRepository pluginRepository; private ManifestStorage manifestStorage; private DalamudReleases dalamudReleases; @@ -28,42 +30,45 @@ public class BuildProcessor private const string DOCKER_IMAGE = "mcr.microsoft.com/dotnet/sdk"; private const string DOCKER_TAG = "6.0.300"; - public BuildProcessor(DirectoryInfo repoFolder, DirectoryInfo manifestFolder, DirectoryInfo workFolder) + public BuildProcessor(DirectoryInfo repoFolder, DirectoryInfo manifestFolder, DirectoryInfo workFolder, + DirectoryInfo staticFolder) { this.repoFolder = repoFolder; this.manifestFolder = manifestFolder; this.workFolder = workFolder; + this.staticFolder = staticFolder; this.pluginRepository = new PluginRepository(repoFolder); this.manifestStorage = new ManifestStorage(manifestFolder); this.dalamudReleases = new DalamudReleases(workFolder.CreateSubdirectory("dalamud_releases_work")); - this.dockerClient = new DockerClientConfiguration(new Uri("npipe://./pipe/docker_engine")).CreateClient(); + this.dockerClient = new DockerClientConfiguration().CreateClient(); } public async Task SetupDockerImage() { await this.dockerClient.Images.CreateImageAsync(new ImagesCreateParameters - { - //FromImage = "fedora/memcached", - FromImage = DOCKER_IMAGE, - //FromSrc = DOCKER_REPO, - Tag = DOCKER_TAG, - }, null, new Progress(progress => - { - Log.Verbose("Docker image pull ({Id}): {Status}", progress.ID, progress.Status); - })); + { + //FromImage = "fedora/memcached", + FromImage = DOCKER_IMAGE, + //FromSrc = DOCKER_REPO, + Tag = DOCKER_TAG, + }, null, + new Progress(progress => + { + Log.Verbose("Docker image pull ({Id}): {Status}", progress.ID, progress.Status); + })); var images = await this.dockerClient.Images.ListImagesAsync(new ImagesListParameters { All = true, }); } - + public ISet GetTasks() { var tasks = new HashSet(); - + foreach (var channel in this.manifestStorage.Channels) { foreach (var manifest in channel.Value) @@ -97,7 +102,7 @@ public async Task ProcessTask(BuildTask task) //work.Delete(true); //work.Create(); } - + var repoPath = Repository.Clone(task.Manifest.Plugin.Repository, work.FullName, new CloneOptions { Checkout = false, @@ -108,9 +113,9 @@ public async Task ProcessTask(BuildTask task) return true; } }); - + var repo = new Repository(repoPath); - Commands.Fetch(repo, "origin", new string[] {task.Manifest.Plugin.Commit}, new FetchOptions + Commands.Fetch(repo, "origin", new string[] { task.Manifest.Plugin.Commit }, new FetchOptions { OnProgress = output => { @@ -134,42 +139,43 @@ public async Task ProcessTask(BuildTask task) } var dalamudAssemblyDir = await this.dalamudReleases.GetDalamudAssemblyDirAsync(task.Channel); - - var containerCreateResponse = await this.dockerClient.Containers.CreateContainerAsync(new CreateContainerParameters - { - Image = $"{DOCKER_IMAGE}:{DOCKER_TAG}", - - // TODO: This depends on a change in DalamudPackager to extract dependencies on dev machines - // NetworkDisabled = true, - - AttachStderr = true, - AttachStdout = true, - HostConfig = new HostConfig + + var containerCreateResponse = await this.dockerClient.Containers.CreateContainerAsync( + new CreateContainerParameters { - Privileged = false, - IpcMode = "none", - AutoRemove = false, - Binds = new List() + Image = $"{DOCKER_IMAGE}:{DOCKER_TAG}", + + // TODO: This depends on a change in DalamudPackager to extract dependencies on dev machines + // NetworkDisabled = true, + + AttachStderr = true, + AttachStdout = true, + HostConfig = new HostConfig { - $"{work.FullName}:/work/repo", - $"{dalamudAssemblyDir.FullName}:/work/dalamud:ro", - "D:\\xivbuild\\static:/static:ro", - $"{output.FullName}:/output", + Privileged = false, + IpcMode = "none", + AutoRemove = false, + Binds = new List() + { + $"{work.FullName}:/work/repo", + $"{dalamudAssemblyDir.FullName}:/work/dalamud:ro", + $"{staticFolder.FullName}:/static:ro", + $"{output.FullName}:/output", + } + }, + Env = new List + { + $"PLOGON_PROJECT_DIR={task.Manifest.Plugin.ProjectPath}", + $"PLOGON_PLUGIN_NAME={task.InternalName}", + $"PLOGON_PLUGIN_COMMIT={task.Manifest.Plugin.Commit}", + "DALAMUD_LIB_PATH=/work/dalamud/" + }, + Entrypoint = new List + { + "/static/entrypoint.sh" } - }, - Env = new List - { - $"PLOGON_PROJECT_DIR={task.Manifest.Plugin.ProjectPath}", - $"PLOGON_PLUGIN_NAME={task.InternalName}", - $"PLOGON_PLUGIN_COMMIT={task.Manifest.Plugin.Commit}", - "DALAMUD_LIB_PATH=/work/dalamud/" - }, - Entrypoint = new List - { - "/static/entrypoint.sh" - } - }); - + }); + var startResponse = await this.dockerClient.Containers.StartContainerAsync(containerCreateResponse.ID, new ContainerStartParameters()); @@ -192,7 +198,7 @@ await this.dockerClient.Containers.StartContainerAsync(containerCreateResponse.I { var inspectResponse = await this.dockerClient.Containers.InspectContainerAsync(containerCreateResponse.ID); hasExited = inspectResponse.State.Running == false; - + // Get logs from multiplexed stream var buffer = new byte[4096]; var eof = false; @@ -200,15 +206,16 @@ await this.dockerClient.Containers.StartContainerAsync(containerCreateResponse.I { var result = await logResponse.ReadOutputAsync(buffer, 0, buffer.Length, CancellationToken.None); eof = result.EOF; - + var log = System.Text.Encoding.UTF8.GetString(buffer, 0, result.Count); Log.Information(log.Replace("\n", string.Empty)); } } - - var containerInspectResponse = await this.dockerClient.Containers.InspectContainerAsync(containerCreateResponse.ID); + + var containerInspectResponse = + await this.dockerClient.Containers.InspectContainerAsync(containerCreateResponse.ID); var exitCode = containerInspectResponse.State.ExitCode; - + Log.Information("Container for build exited, exit code: {Code}", exitCode); await this.dockerClient.Containers.RemoveContainerAsync(containerCreateResponse.ID, diff --git a/Plogon/Manifests/ManifestStorage.cs b/Plogon/Manifests/ManifestStorage.cs index 49af3c3..e8dd71c 100644 --- a/Plogon/Manifests/ManifestStorage.cs +++ b/Plogon/Manifests/ManifestStorage.cs @@ -24,10 +24,10 @@ private void Load() var channels = new Dictionary>(); var stableDir = new DirectoryInfo(Path.Combine(this.baseDirectory.FullName, "stable")); - var testingDir = new DirectoryInfo(Path.Combine(this.baseDirectory.FullName, "testing")); + var testingDir = new DirectoryInfo(Path.Combine(this.baseDirectory.FullName, "testing")); channels.Add(stableDir.Name, GetManifestsInDirectory(stableDir)); - + foreach (var testingChannelDir in testingDir.EnumerateDirectories()) { var manifests = GetManifestsInDirectory(testingChannelDir); @@ -40,7 +40,7 @@ private void Load() private static Dictionary GetManifestsInDirectory(DirectoryInfo directory) { var manifests = new Dictionary(); - + foreach (var manifestDir in directory.EnumerateDirectories()) { try diff --git a/Plogon/Program.cs b/Plogon/Program.cs index 0088610..38ecc53 100644 --- a/Plogon/Program.cs +++ b/Plogon/Program.cs @@ -12,18 +12,21 @@ class Program /// The folder used for storing output and state. /// The folder used for storing plugin manifests. /// The folder to store temporary files and build output in. - static async Task Main(DirectoryInfo outputFolder, DirectoryInfo manifestFolder, DirectoryInfo workFolder) + /// The 'static' folder that holds script files. + static async Task Main(DirectoryInfo outputFolder, DirectoryInfo manifestFolder, DirectoryInfo workFolder, + DirectoryInfo staticFolder) { SetupLogging(); - var buildProcessor = new BuildProcessor(outputFolder, manifestFolder, workFolder); + var buildProcessor = new BuildProcessor(outputFolder, manifestFolder, workFolder, staticFolder); var tasks = buildProcessor.GetTasks(); await buildProcessor.SetupDockerImage(); - + foreach (var task in tasks) { - Log.Information("Need: {Name} - {Sha} (have {HaveCommit})", task.InternalName, task.Manifest.Plugin.Commit, task.HaveCommit ?? "nothing"); + Log.Information("Need: {Name} - {Sha} (have {HaveCommit})", task.InternalName, task.Manifest.Plugin.Commit, + task.HaveCommit ?? "nothing"); var status = await buildProcessor.ProcessTask(task); if (!status) diff --git a/Plogon/static/entrypoint.sh b/Plogon/static/entrypoint.sh old mode 100644 new mode 100755