From a85336b030eb9cc8fc7d5b6a626dad2313aa0c65 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henri=20Hyyryl=C3=A4inen?= Date: Thu, 9 Jan 2025 20:52:35 +0200 Subject: [PATCH] Add a new deploy mode to not use a container --- Dockerfile | 3 +- Scripts/Deployer.cs | 78 ++++++++++++++++++++++++++++++++++++--------- 2 files changed, 65 insertions(+), 16 deletions(-) diff --git a/Dockerfile b/Dockerfile index 09ef152b..c96f9d1a 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,5 +1,6 @@ # If the image version is updated here also Scripts/ContainerTool.cs needs to be updated -# Also the Ansible control node uses this +# The Ansible control node has a copy of this part of this file, so if this is updated things +# need to be updated there as well FROM almalinux:9 as builder ENV DOTNET_VERSION "9.0" diff --git a/Scripts/Deployer.cs b/Scripts/Deployer.cs index 6e552ea9..1b755114 100644 --- a/Scripts/Deployer.cs +++ b/Scripts/Deployer.cs @@ -19,7 +19,8 @@ public class Deployer { private const string NET_VERSION = "net9.0"; - private const string BUILD_DATA_FOLDER = "build"; + private const string BUILD_DATA_FOLDER_CONTAINER = "build"; + private const string BUILD_DATA_FOLDER_PLAIN = "."; private const string CONTAINER_NUGET_CACHE_HOST = "build/nuget"; private const string CONTAINER_NUGET_CACHE_TARGET = "/root/.nuget"; private const string BUILDER_CONTAINER_NAME = "thrive/devcenter-builder:latest"; @@ -32,12 +33,6 @@ public class Deployer private const string MIGRATION_FILE = "migration.sql"; private const string BLAZOR_BOOT_FILE = "blazor.boot.json"; - private const string CLIENT_BUILT_WEBROOT = BUILD_DATA_FOLDER + "/Client/bin/{0}/{1}/publish/wwwroot/"; - private const string SERVER_BUILT_BASE = BUILD_DATA_FOLDER + "/Server/bin/{0}/{1}/publish/"; - - private const string CI_EXECUTOR_BUILT_FILE = - BUILD_DATA_FOLDER + "/CIExecutor/bin/{0}/{1}/linux-x64/publish/CIExecutor"; - private const string DEFAULT_PRODUCTION_DATABASE = "revwebapp"; private const string DEFAULT_STAGING_DATABASE = "revwebapp"; @@ -97,11 +92,17 @@ public enum DeployMode Production, } - private string ClientBuiltWebroot => string.Format(CLIENT_BUILT_WEBROOT, options.BuildMode, NET_VERSION); + private string BuildDataFolder => options.DisableContainer ? BUILD_DATA_FOLDER_PLAIN : BUILD_DATA_FOLDER_CONTAINER; + + private string ClientBuiltWebroot => string.Format(BuildDataFolder + "/Client/bin/{0}/{1}/publish/wwwroot/", + options.BuildMode, NET_VERSION); - private string ServerBuiltBase => string.Format(SERVER_BUILT_BASE, options.BuildMode, NET_VERSION); + private string ServerBuiltBase => + string.Format(BuildDataFolder + "/Server/bin/{0}/{1}/publish/", options.BuildMode, NET_VERSION); - private string CIExecutorBuiltFile => string.Format(CI_EXECUTOR_BUILT_FILE, options.BuildMode, NET_VERSION); + private string CIExecutorBuiltFile => + string.Format(BuildDataFolder + "/CIExecutor/bin/{0}/{1}/linux-x64/publish/CIExecutor", options.BuildMode, + NET_VERSION); public async Task Run(CancellationToken cancellationToken) { @@ -161,9 +162,22 @@ public async Task Run(CancellationToken cancellationToken) cancellationToken.ThrowIfCancellationRequested(); ColourConsole.WriteNormalLine($"Building {options.BuildMode} files in a container"); - if (!await PerformBuild(cancellationToken)) + + if (options.DisableContainer) { - return false; + ColourConsole.WriteNormalLine("Performing a non-container build. Hopefully the environment is setup " + + "correctly!"); + if (!await PerformNonContainerBuild(cancellationToken)) + { + return false; + } + } + else + { + if (!await PerformBuild(cancellationToken)) + { + return false; + } } cancellationToken.ThrowIfCancellationRequested(); @@ -316,7 +330,7 @@ private async Task PerformMigration(string targetHost, string? hashToVerif private async Task PerformBuild(CancellationToken cancellationToken) { - Directory.CreateDirectory(BUILD_DATA_FOLDER); + Directory.CreateDirectory(BuildDataFolder); Directory.CreateDirectory(CONTAINER_NUGET_CACHE_HOST); if (Directory.Exists(BUILD_FOLDER_TO_ALWAYS_DELETE)) @@ -325,7 +339,7 @@ private async Task PerformBuild(CancellationToken cancellationToken) var nugetCache = Path.GetFullPath(CONTAINER_NUGET_CACHE_HOST); var sourceDirectory = Path.GetFullPath("."); - var buildTarget = Path.GetFullPath(BUILD_DATA_FOLDER); + var buildTarget = Path.GetFullPath(BuildDataFolder); ColourConsole.WriteDebugLine("Storing build result in: " + buildTarget); @@ -384,6 +398,14 @@ private async Task PerformBuild(CancellationToken cancellationToken) ColourConsole.WriteSuccessLine("Build within the build container succeeded"); + await VerifyBlazorBootFile(cancellationToken); + + ColourConsole.WriteSuccessLine("Build finished."); + return true; + } + + private async Task VerifyBlazorBootFile(CancellationToken cancellationToken) + { ColourConsole.WriteNormalLine("Making sure blazor.boot.json has correct hashes"); bool foundABootFile = false; @@ -399,6 +421,28 @@ private async Task PerformBuild(CancellationToken cancellationToken) if (!foundABootFile) ColourConsole.WriteWarningLine($"No {BLAZOR_BOOT_FILE} files found"); + } + + private async Task PerformNonContainerBuild(CancellationToken cancellationToken) + { + ColourConsole.WriteNormalLine("Writing published artifacts to current source tree"); + + var startInfo = new ProcessStartInfo("dotnet"); + startInfo.ArgumentList.Add("publish"); + startInfo.ArgumentList.Add("-c"); + startInfo.ArgumentList.Add(options.BuildMode); + + var result = await ProcessRunHelpers.RunProcessAsync(startInfo, cancellationToken, false); + + if (result.ExitCode != 0) + { + ColourConsole.WriteErrorLine("Failed to run publish command. Is there a build or environment error?"); + return false; + } + + ColourConsole.WriteSuccessLine("Publish with dotnet succeeded"); + + await VerifyBlazorBootFile(cancellationToken); ColourConsole.WriteSuccessLine("Build finished."); return true; @@ -415,7 +459,7 @@ private async Task CopyFiles(string targetFolder, CancellationToken cancel // And it also needs extra files... foreach (var extraResource in CIExecutorExtraResources) { - var resource = Path.Join(BUILD_DATA_FOLDER, string.Format(extraResource, options.BuildMode, NET_VERSION)); + var resource = Path.Join(BuildDataFolder, string.Format(extraResource, options.BuildMode, NET_VERSION)); var destination = Path.Join(ClientBuiltWebroot, Path.GetFileName(resource)); File.Copy(resource, destination, true); await BlazorBootFileHandler.RegenerateCompressedFiles(destination, cancellationToken); @@ -548,5 +592,9 @@ public class DeployOptions : ScriptOptionsBase [Option("override-deploy-username", Default = null, MetaValue = "ROLE", HelpText = "Override the role that is given access to new database resources")] public string? OverrideUsername { get; set; } + + [Option("disable-container", Default = false, + HelpText = "Specify to not use a container build (should be only done if already inside a container)")] + public bool DisableContainer { get; set; } } }