From a9b141e7fd8db411adbbc327ec74065b035628c8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zolt=C3=A1n=20Leh=C3=B3czky?= Date: Tue, 27 Dec 2022 22:56:53 +0100 Subject: [PATCH 01/54] Add missing IOrchardServices registration --- Lombiq.Hosting.MediaTheme.Bridge/Startup.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Lombiq.Hosting.MediaTheme.Bridge/Startup.cs b/Lombiq.Hosting.MediaTheme.Bridge/Startup.cs index 1a48291..a74cbb3 100644 --- a/Lombiq.Hosting.MediaTheme.Bridge/Startup.cs +++ b/Lombiq.Hosting.MediaTheme.Bridge/Startup.cs @@ -1,4 +1,5 @@ -using Lombiq.Hosting.MediaTheme.Bridge.Deployment; +using Lombiq.HelpfulLibraries.OrchardCore.DependencyInjection; +using Lombiq.Hosting.MediaTheme.Bridge.Deployment; using Lombiq.Hosting.MediaTheme.Bridge.Middlewares; using Lombiq.Hosting.MediaTheme.Bridge.Navigation; using Lombiq.Hosting.MediaTheme.Bridge.Permissions; @@ -38,6 +39,7 @@ public override void ConfigureServices(IServiceCollection services) services.AddScoped, MediaThemeDeploymentStepDriver>(); services.AddScoped(); services.AddScoped(); + services.AddOrchardServices(); } public override void Configure(IApplicationBuilder app, IEndpointRouteBuilder routes, IServiceProvider serviceProvider) From ab7bf7fe582b5a734fd666da38975f5bbb8d4f76 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zolt=C3=A1n=20Leh=C3=B3czky?= Date: Tue, 27 Dec 2022 23:14:48 +0100 Subject: [PATCH 02/54] Note about why we can't show templates to admin users --- .../BlockMediaThemeTemplateDirectAccessMiddleware.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Lombiq.Hosting.MediaTheme.Bridge/Middlewares/BlockMediaThemeTemplateDirectAccessMiddleware.cs b/Lombiq.Hosting.MediaTheme.Bridge/Middlewares/BlockMediaThemeTemplateDirectAccessMiddleware.cs index f43a780..5a777d3 100644 --- a/Lombiq.Hosting.MediaTheme.Bridge/Middlewares/BlockMediaThemeTemplateDirectAccessMiddleware.cs +++ b/Lombiq.Hosting.MediaTheme.Bridge/Middlewares/BlockMediaThemeTemplateDirectAccessMiddleware.cs @@ -1,4 +1,4 @@ -using Lombiq.Hosting.MediaTheme.Bridge.Constants; +using Lombiq.Hosting.MediaTheme.Bridge.Constants; using Microsoft.AspNetCore.Http; using Microsoft.Extensions.Options; using OrchardCore.Media; @@ -29,6 +29,8 @@ public async Task InvokeAsync(HttpContext context) StringComparison.OrdinalIgnoreCase, out _); + // Since this middleware needs to run early (see comment in Startup), the user's authentication state won't yet + // be available. So, we can't let people with the ManageMediaTheme permission still see the templates. if (!isMediaThemeTemplateRequest) { await _next(context); From 98761ce962d68bb2628e9149bed4689b9024af97 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zolt=C3=A1n=20Leh=C3=B3czky?= Date: Tue, 27 Dec 2022 23:20:35 +0100 Subject: [PATCH 03/54] Making base theme optional during deployment --- Lombiq.Hosting.MediaTheme.Deployer/Program.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Lombiq.Hosting.MediaTheme.Deployer/Program.cs b/Lombiq.Hosting.MediaTheme.Deployer/Program.cs index 157072a..8f4366d 100644 --- a/Lombiq.Hosting.MediaTheme.Deployer/Program.cs +++ b/Lombiq.Hosting.MediaTheme.Deployer/Program.cs @@ -10,16 +10,16 @@ namespace Lombiq.Hosting.MediaTheme.Deployer; public class CommandLineOptions { - [Option('p', "path", Required = true, HelpText = "Path of your theme.")] + [Option('p', "path", Required = true, HelpText = "Path of your theme project.")] public string? PathOfTheTheme { get; set; } - [Option('i', "base-id", Required = true, HelpText = "Default theme ID.")] + [Option('i', "base-id", Required = false, HelpText = "ID of the base theme, if any.")] public string? BaseThemeId { get; set; } - [Option('c', "clear", Required = true, HelpText = "Whether or not to clear media hosting folder.")] + [Option('c', "clear", Required = true, HelpText = "Whether or not to clear the Media Theme media folder of all files.")] public bool ClearMediaHostingFolder { get; set; } - [Option('d', "deployment-path", Required = false, HelpText = "The path where you want the deployment package copied.")] + [Option('d', "deployment-path", Required = false, HelpText = "The path where you want the deployment package to be written to.")] public string? DeploymentPackagePath { get; set; } } From 258aba03bc1eeaaf9564aaad548fc54f4b3c72f7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zolt=C3=A1n=20Leh=C3=B3czky?= Date: Tue, 27 Dec 2022 23:23:31 +0100 Subject: [PATCH 04/54] Making --clear optional during deployment --- Lombiq.Hosting.MediaTheme.Deployer/Program.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Lombiq.Hosting.MediaTheme.Deployer/Program.cs b/Lombiq.Hosting.MediaTheme.Deployer/Program.cs index 8f4366d..27422c8 100644 --- a/Lombiq.Hosting.MediaTheme.Deployer/Program.cs +++ b/Lombiq.Hosting.MediaTheme.Deployer/Program.cs @@ -16,8 +16,8 @@ public class CommandLineOptions [Option('i', "base-id", Required = false, HelpText = "ID of the base theme, if any.")] public string? BaseThemeId { get; set; } - [Option('c', "clear", Required = true, HelpText = "Whether or not to clear the Media Theme media folder of all files.")] - public bool ClearMediaHostingFolder { get; set; } + [Option('c', "clear", Required = false, HelpText = "Whether or not to clear the Media Theme media folder of all files.")] + public bool ClearMediaHostingFolder { get; set; } = true; [Option('d', "deployment-path", Required = false, HelpText = "The path where you want the deployment package to be written to.")] public string? DeploymentPackagePath { get; set; } From 28480220ea65912d5b4e400da52707d214c4c76c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zolt=C3=A1n=20Leh=C3=B3czky?= Date: Tue, 27 Dec 2022 23:59:59 +0100 Subject: [PATCH 05/54] Basics or deployment GHA action and workflow --- .github/actions/deploy-media-theme/action.yml | 28 +++++++++++++ .github/workflows/deploy-media-theme.yml | 41 +++++++++++++++++++ .../Lombiq.Hosting.MediaTheme.Deployer.csproj | 2 + 3 files changed, 71 insertions(+) create mode 100644 .github/actions/deploy-media-theme/action.yml create mode 100644 .github/workflows/deploy-media-theme.yml diff --git a/.github/actions/deploy-media-theme/action.yml b/.github/actions/deploy-media-theme/action.yml new file mode 100644 index 0000000..6f71a79 --- /dev/null +++ b/.github/actions/deploy-media-theme/action.yml @@ -0,0 +1,28 @@ +name: Deploy Media Theme +description: Deploys an Orchard Core Media Theme to an Orchard site via Remote Deployment. + +inputs: + theme-path: + required: false + default: "." + description: Path to the theme project. + base-theme-id: + required: false + description: ID of the base theme of the theme project, if any. + clear-media-folder: + required: false + default: "true" + description: When set to "true", will clear the Media folder of the Media Theme before deployment. + +runs: + using: "composite" + steps: + - name: Install Lombiq.Hosting.MediaTheme.Deployer + shell: pwsh + run: | + dotnet tool install --global Lombiq.Hosting.MediaTheme.Deployer + + - name: Deploy Media Theme + shell: pwsh + run: | + media-theme-deploy --path ${{ inputs.theme-path }} --base-id ${{ inputs.base-theme-id }} --clear ${{ inputs.clear-media-folder }} --client-name ${{ env.CLIENT_NAME }} --client-api-key ${{ env.CLIENT_API_KEY }} diff --git a/.github/workflows/deploy-media-theme.yml b/.github/workflows/deploy-media-theme.yml new file mode 100644 index 0000000..f0d80ea --- /dev/null +++ b/.github/workflows/deploy-media-theme.yml @@ -0,0 +1,41 @@ +name: Deploy Media Theme + +on: + workflow_call: + secrets: + CLIENT_NAME: + required: true + description: The "Client Name" part of the Remote Deployment client's credentials. + CLIENT_API_KEY: + required: true + description: The "Client API Key" part of the Remote Deployment client's credentials. + inputs: + theme-path: + required: false + type: string + default: "." + description: Path to the theme project. + base-theme-id: + required: false + type: string + description: ID of the base theme of the theme project, if any. + clear-media-folder: + required: false + type: string + default: "true" + description: When set to "true", will clear the Media folder of the Media Theme before deployment. + +jobs: + deploy-media-theme: + runs-on: ubuntu-22.04 + steps: + - name: Deploy Media Theme + if: github.event.pull_request != '' + uses: Lombiq/Hosting-Media-Theme/.github/workflows/deploy-media-theme.yml@issue/OSOE-514 + env: + CLIENT_NAME: ${{ secrets.CLIENT_NAME }} + CLIENT_API_KEY: ${{ secrets.CLIENT_API_KEY }} + with: + theme-path: ${{ inputs.theme-path }} + base-theme-id: ${{ inputs.base-theme-id }} + clear-media-folder: ${{ inputs.clear-media-folder }} diff --git a/Lombiq.Hosting.MediaTheme.Deployer/Lombiq.Hosting.MediaTheme.Deployer.csproj b/Lombiq.Hosting.MediaTheme.Deployer/Lombiq.Hosting.MediaTheme.Deployer.csproj index e6fc48e..2f645ef 100644 --- a/Lombiq.Hosting.MediaTheme.Deployer/Lombiq.Hosting.MediaTheme.Deployer.csproj +++ b/Lombiq.Hosting.MediaTheme.Deployer/Lombiq.Hosting.MediaTheme.Deployer.csproj @@ -28,6 +28,8 @@ + + From e57a3b1f1bae2bd7fd61a6ace5cf872378f1ef8b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zolt=C3=A1n=20Leh=C3=B3czky?= Date: Wed, 28 Dec 2022 01:19:11 +0100 Subject: [PATCH 06/54] Adding Remote Deployment support to Deployer --- .../GlobalSuppressions.cs | 7 +++ .../Lombiq.Hosting.MediaTheme.Deployer.csproj | 2 +- Lombiq.Hosting.MediaTheme.Deployer/Program.cs | 57 ++++++++++++----- .../RemoteDeploymentHelper.cs | 62 +++++++++++++++++++ 4 files changed, 111 insertions(+), 17 deletions(-) create mode 100644 Lombiq.Hosting.MediaTheme.Deployer/GlobalSuppressions.cs create mode 100644 Lombiq.Hosting.MediaTheme.Deployer/RemoteDeploymentHelper.cs diff --git a/Lombiq.Hosting.MediaTheme.Deployer/GlobalSuppressions.cs b/Lombiq.Hosting.MediaTheme.Deployer/GlobalSuppressions.cs new file mode 100644 index 0000000..8c9b7f6 --- /dev/null +++ b/Lombiq.Hosting.MediaTheme.Deployer/GlobalSuppressions.cs @@ -0,0 +1,7 @@ +using System.Diagnostics.CodeAnalysis; + +[assembly: SuppressMessage( + "Globalization", + "CA1303:Do not pass literals as localized parameters", + Justification = "It's a console application, it doesn't need localization.", + Scope = "module")] diff --git a/Lombiq.Hosting.MediaTheme.Deployer/Lombiq.Hosting.MediaTheme.Deployer.csproj b/Lombiq.Hosting.MediaTheme.Deployer/Lombiq.Hosting.MediaTheme.Deployer.csproj index 2f645ef..6d633e2 100644 --- a/Lombiq.Hosting.MediaTheme.Deployer/Lombiq.Hosting.MediaTheme.Deployer.csproj +++ b/Lombiq.Hosting.MediaTheme.Deployer/Lombiq.Hosting.MediaTheme.Deployer.csproj @@ -23,7 +23,7 @@ - + diff --git a/Lombiq.Hosting.MediaTheme.Deployer/Program.cs b/Lombiq.Hosting.MediaTheme.Deployer/Program.cs index 27422c8..ec840e9 100644 --- a/Lombiq.Hosting.MediaTheme.Deployer/Program.cs +++ b/Lombiq.Hosting.MediaTheme.Deployer/Program.cs @@ -16,23 +16,40 @@ public class CommandLineOptions [Option('i', "base-id", Required = false, HelpText = "ID of the base theme, if any.")] public string? BaseThemeId { get; set; } - [Option('c', "clear", Required = false, HelpText = "Whether or not to clear the Media Theme media folder of all files.")] + [Option('c', "clear", Required = false, HelpText = "Whether or not to clear the Media Theme media folder of all files before deployment.")] public bool ClearMediaHostingFolder { get; set; } = true; [Option('d', "deployment-path", Required = false, HelpText = "The path where you want the deployment package to be written to.")] public string? DeploymentPackagePath { get; set; } + + [Option( + 'u', + "remote-deployment-url", + Required = false, + HelpText = "The URL to use for Remote Deployment, as indicated on the Orchard Core admin.")] + public string? RemoteDeploymenUrl { get; set; } + + [Option( + 'n', + "remote-deployment-client-name", + Required = false, + HelpText = "The \"Client Name\" part of the Remote Deployment client's credentials.")] + public string? RemoteDeploymenClientName { get; set; } + + [Option( + 'k', + "remote-deployment-client-api-key", + Required = false, + HelpText = "The \"Client API Key\" part of the Remote Deployment client's credentials.")] + public string? RemoteDeploymenClientApiKey { get; set; } } -[System.Diagnostics.CodeAnalysis.SuppressMessage( - "Globalization", - "CA1303:Do not pass literals as localized parameters", - Justification = "It's a console application, it doesn't need localization.")] internal static class Program { - public static void Main(string[] args) => + public static Task Main(string[] args) => Parser.Default.ParseArguments(args) - .WithParsed(options => RunOptions(options)) - .WithNotParsed(HandleParseError); + .WithNotParsed(HandleParseError) + .WithParsedAsync(options => RunOptionsAsync(options)); private static void HandleParseError(IEnumerable errors) { @@ -49,10 +66,10 @@ private static void HandleParseError(IEnumerable errors) } } - private static void RunOptions(CommandLineOptions values) + private static async Task RunOptionsAsync(CommandLineOptions options) { // Creating directory for the deployment. - var newDirectoryPath = CreateNewDirectoryPath(values); + var newDirectoryPath = CreateNewDirectoryPath(options); try { @@ -74,13 +91,13 @@ private static void RunOptions(CommandLineOptions values) return; } - var pathToTheme = values.PathOfTheTheme; + var pathToTheme = options.PathOfTheTheme; // Creating media theme step. dynamic mediaThemeStep = new JObject(); mediaThemeStep.name = "mediatheme"; - mediaThemeStep.BaseThemeId = values.BaseThemeId; - mediaThemeStep.ClearMediaThemeFolder = values.ClearMediaHostingFolder; + mediaThemeStep.BaseThemeId = string.IsNullOrEmpty(options.BaseThemeId) ? null : options.BaseThemeId; + mediaThemeStep.ClearMediaThemeFolder = options.ClearMediaHostingFolder; // Creating media step. var files = new JArray(); @@ -138,13 +155,21 @@ private static void RunOptions(CommandLineOptions values) CreateRecipeAndWriteIt(mediaThemeStep, mediaStep, newDirectoryPath); // Zipping the directory. - var zippedDirectoryPath = newDirectoryPath + ".zip"; - ZipFile.CreateFromDirectory(newDirectoryPath, zippedDirectoryPath); + var zipFilePath = newDirectoryPath + ".zip"; + ZipFile.CreateFromDirectory(newDirectoryPath, zipFilePath); // Getting rid of the original directory. Directory.Delete(newDirectoryPath, recursive: true); - WriteLine("{0} was created successfully. ", zippedDirectoryPath); + WriteLine("{0} was created successfully. ", zipFilePath); + + if (string.IsNullOrEmpty(options.RemoteDeploymenUrl)) + { + return; + } + + // This is a remote deployment. + await RemoteDeploymentHelper.DeployAsync(options, zipFilePath); } private static void CopyDirectory( diff --git a/Lombiq.Hosting.MediaTheme.Deployer/RemoteDeploymentHelper.cs b/Lombiq.Hosting.MediaTheme.Deployer/RemoteDeploymentHelper.cs new file mode 100644 index 0000000..3c2666f --- /dev/null +++ b/Lombiq.Hosting.MediaTheme.Deployer/RemoteDeploymentHelper.cs @@ -0,0 +1,62 @@ +namespace Lombiq.Hosting.MediaTheme.Deployer; + +internal static class RemoteDeploymentHelper +{ + private static readonly HttpClient _httpClient = new(); + + public static async Task DeployAsync(CommandLineOptions options, string deploymentPackagePath) + { + if (string.IsNullOrEmpty(options.RemoteDeploymenClientName) || string.IsNullOrEmpty(options.RemoteDeploymenClientApiKey)) + { + throw new InvalidOperationException( + "When doing a Remote Deployment, both the Client Name and Client API Key should be provided."); + } + + // The below code is largely taken from Orchard's ExportRemoteInstanceController. + HttpResponseMessage response; + + try + { + // It's disposed via requestContent. +#pragma warning disable CA2000 // Dispose objects before losing scope + using var requestContent = new MultipartFormDataContent + { + { + new StreamContent( + new FileStream( + deploymentPackagePath, + FileMode.Open, + FileAccess.Read, + FileShare.ReadWrite, + 1, + FileOptions.Asynchronous | FileOptions.SequentialScan) + ), + "Content", + Path.GetFileName(deploymentPackagePath) + }, + { new StringContent(options.RemoteDeploymenClientName), "ClientName" }, + { new StringContent(options.RemoteDeploymenClientApiKey), "ApiKey" }, + }; +#pragma warning restore CA2000 // Dispose objects before losing scope + + response = await _httpClient.PostAsync(options.RemoteDeploymenUrl, requestContent); + + if (response.StatusCode == System.Net.HttpStatusCode.OK) + { + Console.WriteLine("Remote deployment to {0} succeeded.", options.RemoteDeploymenUrl); + } + else + { + Console.WriteLine( + "Remote deployment to {0} failed with the HTTP code {1} and message \"{2}\".", + options.RemoteDeploymenUrl, + response.StatusCode, + response.RequestMessage); + } + } + finally + { + File.Delete(deploymentPackagePath); + } + } +} From d4c7de01e7ee936804b4c0f33162a94005e7e76a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zolt=C3=A1n=20Leh=C3=B3czky?= Date: Wed, 28 Dec 2022 01:32:07 +0100 Subject: [PATCH 07/54] Implementing GHA workflow/action for remote deployment --- .github/actions/deploy-media-theme/action.yml | 13 +++++++++++-- .github/workflows/deploy-media-theme.yml | 7 +++++-- 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/.github/actions/deploy-media-theme/action.yml b/.github/actions/deploy-media-theme/action.yml index 6f71a79..e5d2e2c 100644 --- a/.github/actions/deploy-media-theme/action.yml +++ b/.github/actions/deploy-media-theme/action.yml @@ -20,9 +20,18 @@ runs: - name: Install Lombiq.Hosting.MediaTheme.Deployer shell: pwsh run: | - dotnet tool install --global Lombiq.Hosting.MediaTheme.Deployer + dotnet tool install --global Lombiq.Hosting.MediaTheme.Deployer --version 2.0.1-alpha.0.osoe-514 - name: Deploy Media Theme shell: pwsh run: | - media-theme-deploy --path ${{ inputs.theme-path }} --base-id ${{ inputs.base-theme-id }} --clear ${{ inputs.clear-media-folder }} --client-name ${{ env.CLIENT_NAME }} --client-api-key ${{ env.CLIENT_API_KEY }} + $switches = @( + '--path', '${{ inputs.theme-path }}' + '--base-id', '${{ inputs.base-theme-id }}' + '--clear', '${{ inputs.clear-media-folder }}' + '--remote-deployment-url', '${{ env.URL }}' + '--remote-deployment-client-name', '${{ env.CLIENT_NAME }}' + '--remote-deployment-client-api-key', '${{ env.CLIENT_API_KEY }}' + ) + + media-theme-deploy @switches diff --git a/.github/workflows/deploy-media-theme.yml b/.github/workflows/deploy-media-theme.yml index f0d80ea..c778f8d 100644 --- a/.github/workflows/deploy-media-theme.yml +++ b/.github/workflows/deploy-media-theme.yml @@ -3,6 +3,9 @@ name: Deploy Media Theme on: workflow_call: secrets: + URL: + required: true + description: The URL to use for Remote Deployment, as indicated on the Orchard Core admin. CLIENT_NAME: required: true description: The "Client Name" part of the Remote Deployment client's credentials. @@ -30,9 +33,9 @@ jobs: runs-on: ubuntu-22.04 steps: - name: Deploy Media Theme - if: github.event.pull_request != '' - uses: Lombiq/Hosting-Media-Theme/.github/workflows/deploy-media-theme.yml@issue/OSOE-514 + uses: Lombiq/Hosting-Media-Theme/.github/actions/deploy-media-theme@issue/OSOE-514 env: + URL: ${{ secrets.URL }} CLIENT_NAME: ${{ secrets.CLIENT_NAME }} CLIENT_API_KEY: ${{ secrets.CLIENT_API_KEY }} with: From 4e71177a550d620074c1e267a7b137c4be297165 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zolt=C3=A1n=20Leh=C3=B3czky?= Date: Wed, 28 Dec 2022 01:39:18 +0100 Subject: [PATCH 08/54] Handling errors in the deploy command --- .github/actions/deploy-media-theme/action.yml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.github/actions/deploy-media-theme/action.yml b/.github/actions/deploy-media-theme/action.yml index e5d2e2c..90afe74 100644 --- a/.github/actions/deploy-media-theme/action.yml +++ b/.github/actions/deploy-media-theme/action.yml @@ -35,3 +35,8 @@ runs: ) media-theme-deploy @switches + + if (-not $?) + { + exit 1 + } From c9f0f967f5925667868de74664a8120f743c3ab4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zolt=C3=A1n=20Leh=C3=B3czky?= Date: Wed, 28 Dec 2022 01:41:08 +0100 Subject: [PATCH 09/54] And now better --- .github/actions/deploy-media-theme/action.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/actions/deploy-media-theme/action.yml b/.github/actions/deploy-media-theme/action.yml index 90afe74..3a5dd6f 100644 --- a/.github/actions/deploy-media-theme/action.yml +++ b/.github/actions/deploy-media-theme/action.yml @@ -36,7 +36,7 @@ runs: media-theme-deploy @switches - if (-not $?) + if (!$?) { exit 1 } From cab0484224c4b0768fd30f550962f213ed26d0d9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zolt=C3=A1n=20Leh=C3=B3czky?= Date: Wed, 28 Dec 2022 01:45:55 +0100 Subject: [PATCH 10/54] And even better --- .github/actions/deploy-media-theme/action.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/actions/deploy-media-theme/action.yml b/.github/actions/deploy-media-theme/action.yml index 3a5dd6f..d95d4c1 100644 --- a/.github/actions/deploy-media-theme/action.yml +++ b/.github/actions/deploy-media-theme/action.yml @@ -36,7 +36,7 @@ runs: media-theme-deploy @switches - if (!$?) + if ($LastExitCode -ne 0) { - exit 1 + Write-Error "Deployment failed, see the errors above." } From c1a1e5fd02d6874cc531537a8261c435fd593a50 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zolt=C3=A1n=20Leh=C3=B3czky?= Date: Wed, 28 Dec 2022 02:00:04 +0100 Subject: [PATCH 11/54] Deployer now failes with non-zero exit code --- Lombiq.Hosting.MediaTheme.Deployer/Program.cs | 27 ++++++++++++------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/Lombiq.Hosting.MediaTheme.Deployer/Program.cs b/Lombiq.Hosting.MediaTheme.Deployer/Program.cs index ec840e9..8ffba7b 100644 --- a/Lombiq.Hosting.MediaTheme.Deployer/Program.cs +++ b/Lombiq.Hosting.MediaTheme.Deployer/Program.cs @@ -67,28 +67,35 @@ private static void HandleParseError(IEnumerable errors) } private static async Task RunOptionsAsync(CommandLineOptions options) + { + try + { + await RunOptionsInnerAsync(options); + } + catch (Exception ex) + { + WriteLine("Deployment failed with the following exception: {0}", ex.ToString()); + Environment.ExitCode = 1; + } + } + + private static async Task RunOptionsInnerAsync(CommandLineOptions options) { // Creating directory for the deployment. var newDirectoryPath = CreateNewDirectoryPath(options); try { - // Determine whether the directory exists. - if (Directory.Exists(newDirectoryPath)) - { - WriteLine("That directory already exists."); - return; - } + if (Directory.Exists(newDirectoryPath)) Directory.Delete(newDirectoryPath, recursive: true); - // Try to create the directory. Directory.CreateDirectory(newDirectoryPath); WriteLine("The directory was created successfully. {0}", newDirectoryPath); } - catch (Exception exception) + catch (Exception) { - WriteLine("The directory creation failed: {0}", exception.ToString()); - return; + WriteLine("Creating the directory {0} failed.", newDirectoryPath); + throw; } var pathToTheme = options.PathOfTheTheme; From 30eb74d4510dda63f3ceaa48044e9c263197f387 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zolt=C3=A1n=20Leh=C3=B3czky?= Date: Wed, 28 Dec 2022 02:00:37 +0100 Subject: [PATCH 12/54] Updating alpha version number --- .github/actions/deploy-media-theme/action.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/actions/deploy-media-theme/action.yml b/.github/actions/deploy-media-theme/action.yml index d95d4c1..11ed32c 100644 --- a/.github/actions/deploy-media-theme/action.yml +++ b/.github/actions/deploy-media-theme/action.yml @@ -20,7 +20,7 @@ runs: - name: Install Lombiq.Hosting.MediaTheme.Deployer shell: pwsh run: | - dotnet tool install --global Lombiq.Hosting.MediaTheme.Deployer --version 2.0.1-alpha.0.osoe-514 + dotnet tool install --global Lombiq.Hosting.MediaTheme.Deployer --version 2.0.1-alpha.1.osoe-514 - name: Deploy Media Theme shell: pwsh From fc8f55dbfcab714792636df59a29c7c2d503c680 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zolt=C3=A1n=20Leh=C3=B3czky?= Date: Wed, 28 Dec 2022 02:11:03 +0100 Subject: [PATCH 13/54] Generating the deployment package not in the drive root but in the theme folder in GHA --- .github/actions/deploy-media-theme/action.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/actions/deploy-media-theme/action.yml b/.github/actions/deploy-media-theme/action.yml index 11ed32c..cf9c060 100644 --- a/.github/actions/deploy-media-theme/action.yml +++ b/.github/actions/deploy-media-theme/action.yml @@ -29,6 +29,7 @@ runs: '--path', '${{ inputs.theme-path }}' '--base-id', '${{ inputs.base-theme-id }}' '--clear', '${{ inputs.clear-media-folder }}' + '--deployment-path', '${{ inputs.theme-path }}' '--remote-deployment-url', '${{ env.URL }}' '--remote-deployment-client-name', '${{ env.CLIENT_NAME }}' '--remote-deployment-client-api-key', '${{ env.CLIENT_API_KEY }}' From dfb6ca4d238b5c94769cf493fbf5d98d53a47828 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zolt=C3=A1n=20Leh=C3=B3czky?= Date: Wed, 28 Dec 2022 02:16:03 +0100 Subject: [PATCH 14/54] Adding missing checkout --- .github/workflows/deploy-media-theme.yml | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/.github/workflows/deploy-media-theme.yml b/.github/workflows/deploy-media-theme.yml index c778f8d..7631f7c 100644 --- a/.github/workflows/deploy-media-theme.yml +++ b/.github/workflows/deploy-media-theme.yml @@ -3,6 +3,11 @@ name: Deploy Media Theme on: workflow_call: secrets: + CHECKOUT_TOKEN: + required: false + description: > + The GitHub token to authenticate checkout. Pass in a GitHub personal access token if authenticated submodules + are used. URL: required: true description: The URL to use for Remote Deployment, as indicated on the Orchard Core admin. @@ -32,6 +37,11 @@ jobs: deploy-media-theme: runs-on: ubuntu-22.04 steps: + - name: Checkout + uses: Lombiq/GitHub-Actions/.github/actions/checkout@dev + with: + token: ${{ secrets.CHECKOUT_TOKEN }} + - name: Deploy Media Theme uses: Lombiq/Hosting-Media-Theme/.github/actions/deploy-media-theme@issue/OSOE-514 env: From d8f7ba62f836c502c4fa44d22ada50fefa14723a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zolt=C3=A1n=20Leh=C3=B3czky?= Date: Wed, 28 Dec 2022 02:19:58 +0100 Subject: [PATCH 15/54] Better message --- Lombiq.Hosting.MediaTheme.Deployer/Program.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Lombiq.Hosting.MediaTheme.Deployer/Program.cs b/Lombiq.Hosting.MediaTheme.Deployer/Program.cs index 8ffba7b..934e9ee 100644 --- a/Lombiq.Hosting.MediaTheme.Deployer/Program.cs +++ b/Lombiq.Hosting.MediaTheme.Deployer/Program.cs @@ -90,7 +90,7 @@ private static async Task RunOptionsInnerAsync(CommandLineOptions options) Directory.CreateDirectory(newDirectoryPath); - WriteLine("The directory was created successfully. {0}", newDirectoryPath); + WriteLine("The \"{0}\" directory was created successfully.", newDirectoryPath); } catch (Exception) { From 990908000da43720453fb65a43e8152f6be73fb7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zolt=C3=A1n=20Leh=C3=B3czky?= Date: Wed, 28 Dec 2022 02:20:25 +0100 Subject: [PATCH 16/54] Throwing exception on remote deployment HTTP error so we can better handle it --- .../RemoteDeploymentHelper.cs | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/Lombiq.Hosting.MediaTheme.Deployer/RemoteDeploymentHelper.cs b/Lombiq.Hosting.MediaTheme.Deployer/RemoteDeploymentHelper.cs index 3c2666f..271aff8 100644 --- a/Lombiq.Hosting.MediaTheme.Deployer/RemoteDeploymentHelper.cs +++ b/Lombiq.Hosting.MediaTheme.Deployer/RemoteDeploymentHelper.cs @@ -47,11 +47,9 @@ public static async Task DeployAsync(CommandLineOptions options, string deployme } else { - Console.WriteLine( - "Remote deployment to {0} failed with the HTTP code {1} and message \"{2}\".", - options.RemoteDeploymenUrl, - response.StatusCode, - response.RequestMessage); + throw new HttpRequestException( + $"Remote deployment to {options.RemoteDeploymenUrl} failed with the HTTP code " + + $"{response.StatusCode} and message \"{response.RequestMessage}\"."); } } finally From 5dad0bfbaf6e584dc0aa12a1e7b9d9c0395508cc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zolt=C3=A1n=20Leh=C3=B3czky?= Date: Wed, 28 Dec 2022 02:21:05 +0100 Subject: [PATCH 17/54] Updating alpha version number --- .github/actions/deploy-media-theme/action.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/actions/deploy-media-theme/action.yml b/.github/actions/deploy-media-theme/action.yml index cf9c060..2be4e38 100644 --- a/.github/actions/deploy-media-theme/action.yml +++ b/.github/actions/deploy-media-theme/action.yml @@ -20,7 +20,7 @@ runs: - name: Install Lombiq.Hosting.MediaTheme.Deployer shell: pwsh run: | - dotnet tool install --global Lombiq.Hosting.MediaTheme.Deployer --version 2.0.1-alpha.1.osoe-514 + dotnet tool install --global Lombiq.Hosting.MediaTheme.Deployer --version 2.0.1-alpha.2.osoe-514 - name: Deploy Media Theme shell: pwsh From 2bc8c1724937975877bc8c7179a9522be772625a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zolt=C3=A1n=20Leh=C3=B3czky?= Date: Wed, 28 Dec 2022 02:40:53 +0100 Subject: [PATCH 18/54] Debug artifact --- .github/actions/deploy-media-theme/action.yml | 2 +- .github/workflows/deploy-media-theme.yml | 8 ++++++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/.github/actions/deploy-media-theme/action.yml b/.github/actions/deploy-media-theme/action.yml index 2be4e38..d57f338 100644 --- a/.github/actions/deploy-media-theme/action.yml +++ b/.github/actions/deploy-media-theme/action.yml @@ -29,7 +29,7 @@ runs: '--path', '${{ inputs.theme-path }}' '--base-id', '${{ inputs.base-theme-id }}' '--clear', '${{ inputs.clear-media-folder }}' - '--deployment-path', '${{ inputs.theme-path }}' + '--deployment-path', '${{ inputs.theme-path }}/Deployment' '--remote-deployment-url', '${{ env.URL }}' '--remote-deployment-client-name', '${{ env.CLIENT_NAME }}' '--remote-deployment-client-api-key', '${{ env.CLIENT_API_KEY }}' diff --git a/.github/workflows/deploy-media-theme.yml b/.github/workflows/deploy-media-theme.yml index 7631f7c..be4661d 100644 --- a/.github/workflows/deploy-media-theme.yml +++ b/.github/workflows/deploy-media-theme.yml @@ -52,3 +52,11 @@ jobs: theme-path: ${{ inputs.theme-path }} base-theme-id: ${{ inputs.base-theme-id }} clear-media-folder: ${{ inputs.clear-media-folder }} + + - name: Upload Deployment Package + uses: actions/upload-artifact@v3.1.1 + if: (success() || failure()) + with: + name: deployment-package + path: ${{ inputs.theme-path }}/Deployment + if-no-files-found: ignore From 7ac4ab63dd960ea806826e153f0b687090e51fcd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zolt=C3=A1n=20Leh=C3=B3czky?= Date: Wed, 28 Dec 2022 02:44:07 +0100 Subject: [PATCH 19/54] Not deleting the deployment package for debugging --- Lombiq.Hosting.MediaTheme.Deployer/RemoteDeploymentHelper.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Lombiq.Hosting.MediaTheme.Deployer/RemoteDeploymentHelper.cs b/Lombiq.Hosting.MediaTheme.Deployer/RemoteDeploymentHelper.cs index 271aff8..9902c0c 100644 --- a/Lombiq.Hosting.MediaTheme.Deployer/RemoteDeploymentHelper.cs +++ b/Lombiq.Hosting.MediaTheme.Deployer/RemoteDeploymentHelper.cs @@ -54,7 +54,8 @@ public static async Task DeployAsync(CommandLineOptions options, string deployme } finally { - File.Delete(deploymentPackagePath); + // Not deleting only for debugging. + ////File.Delete(deploymentPackagePath); } } } From b4296231a3577f5f81bb8b2b7fd4b421a4254858 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zolt=C3=A1n=20Leh=C3=B3czky?= Date: Wed, 28 Dec 2022 02:51:34 +0100 Subject: [PATCH 20/54] Updating alpha version number --- .github/actions/deploy-media-theme/action.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/actions/deploy-media-theme/action.yml b/.github/actions/deploy-media-theme/action.yml index d57f338..bf49eef 100644 --- a/.github/actions/deploy-media-theme/action.yml +++ b/.github/actions/deploy-media-theme/action.yml @@ -20,7 +20,7 @@ runs: - name: Install Lombiq.Hosting.MediaTheme.Deployer shell: pwsh run: | - dotnet tool install --global Lombiq.Hosting.MediaTheme.Deployer --version 2.0.1-alpha.2.osoe-514 + dotnet tool install --global Lombiq.Hosting.MediaTheme.Deployer --version 2.0.1-alpha.3.osoe-514 - name: Deploy Media Theme shell: pwsh From 52ce2876239c16c315f65d8926cf1ab3d5552895 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zolt=C3=A1n=20Leh=C3=B3czky?= Date: Wed, 28 Dec 2022 03:02:36 +0100 Subject: [PATCH 21/54] Trying Windows --- .github/workflows/deploy-media-theme.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/deploy-media-theme.yml b/.github/workflows/deploy-media-theme.yml index be4661d..cfe5ec0 100644 --- a/.github/workflows/deploy-media-theme.yml +++ b/.github/workflows/deploy-media-theme.yml @@ -35,7 +35,7 @@ on: jobs: deploy-media-theme: - runs-on: ubuntu-22.04 + runs-on: windows-2022 steps: - name: Checkout uses: Lombiq/GitHub-Actions/.github/actions/checkout@dev From 745509afbe3b16d1aed235e7c7db7c97f3a3f9f6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zolt=C3=A1n=20Leh=C3=B3czky?= Date: Wed, 28 Dec 2022 03:12:51 +0100 Subject: [PATCH 22/54] Fixing Linux incompatibility --- .../Constants/PathConstants.cs | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/Lombiq.Hosting.MediaTheme.Deployer/Constants/PathConstants.cs b/Lombiq.Hosting.MediaTheme.Deployer/Constants/PathConstants.cs index 62249e7..57927d6 100644 --- a/Lombiq.Hosting.MediaTheme.Deployer/Constants/PathConstants.cs +++ b/Lombiq.Hosting.MediaTheme.Deployer/Constants/PathConstants.cs @@ -1,4 +1,5 @@ namespace Lombiq.Hosting.MediaTheme.Deployer.Constants; + public static class PathConstants { public const string MediaThemeRootDirectory = "_MediaTheme"; @@ -8,12 +9,15 @@ public static class PathConstants public const string MediaThemeTemplatesDirectory = "Templates"; public const string MediaThemeAssetsDirectory = "Assets"; + // This needs to use slashes on every platform. public const string MediaThemeAssetsWebPath = MediaThemeRootDirectory + "/" + MediaThemeAssetsDirectory; - public const string MediaThemeAssetsCopyDirectoryPath = "\\" + MediaThemeRootDirectory + "\\" + MediaThemeAssetsDirectory; public const string MediaThemeTemplatesWebPath = MediaThemeRootDirectory + "/" + MediaThemeTemplatesDirectory; public const string MediaThemeTemplatesCopyDirectoryPath = "\\" + MediaThemeRootDirectory + "\\" + MediaThemeTemplatesDirectory; - public const string RecipeFile = "\\Recipe.json"; + public const string RecipeFile = "Recipe.json"; public const string LiquidFileExtension = ".liquid"; + + public static readonly string MediaThemeAssetsCopyDirectoryPath = + Path.DirectorySeparatorChar + MediaThemeRootDirectory + Path.DirectorySeparatorChar + MediaThemeAssetsDirectory; } From 397ddc670711cf7fb6a08e2148d583dfe11db1b7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zolt=C3=A1n=20Leh=C3=B3czky?= Date: Wed, 28 Dec 2022 03:12:56 +0100 Subject: [PATCH 23/54] Revert "Trying Windows" This reverts commit 52ce2876239c16c315f65d8926cf1ab3d5552895. --- .github/workflows/deploy-media-theme.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/deploy-media-theme.yml b/.github/workflows/deploy-media-theme.yml index cfe5ec0..be4661d 100644 --- a/.github/workflows/deploy-media-theme.yml +++ b/.github/workflows/deploy-media-theme.yml @@ -35,7 +35,7 @@ on: jobs: deploy-media-theme: - runs-on: windows-2022 + runs-on: ubuntu-22.04 steps: - name: Checkout uses: Lombiq/GitHub-Actions/.github/actions/checkout@dev From 11f4b22c9e101c25940f13673e740a41df789a7c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zolt=C3=A1n=20Leh=C3=B3czky?= Date: Wed, 28 Dec 2022 03:13:12 +0100 Subject: [PATCH 24/54] Fixing path creation --- Lombiq.Hosting.MediaTheme.Deployer/Program.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Lombiq.Hosting.MediaTheme.Deployer/Program.cs b/Lombiq.Hosting.MediaTheme.Deployer/Program.cs index 934e9ee..2cffd6b 100644 --- a/Lombiq.Hosting.MediaTheme.Deployer/Program.cs +++ b/Lombiq.Hosting.MediaTheme.Deployer/Program.cs @@ -262,7 +262,7 @@ private static void CreateRecipeAndWriteIt(JObject mediaThemeStep, JObject media recipe.steps = new JArray(mediaThemeStep, mediaStep); // Creating JSON file. - using var file = File.CreateText(Path.Join(newDirectoryPath + RecipeFile)); + using var file = File.CreateText(Path.Join(newDirectoryPath, RecipeFile)); using var writer = new JsonTextWriter(file) { Formatting = Formatting.Indented }; recipe.WriteTo(writer); From be41f1adf83e0679c9796b5ffbae9b7b33d53115 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zolt=C3=A1n=20Leh=C3=B3czky?= Date: Wed, 28 Dec 2022 03:13:27 +0100 Subject: [PATCH 25/54] Debug not deleting deploy path --- Lombiq.Hosting.MediaTheme.Deployer/Program.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Lombiq.Hosting.MediaTheme.Deployer/Program.cs b/Lombiq.Hosting.MediaTheme.Deployer/Program.cs index 2cffd6b..d930cdc 100644 --- a/Lombiq.Hosting.MediaTheme.Deployer/Program.cs +++ b/Lombiq.Hosting.MediaTheme.Deployer/Program.cs @@ -166,7 +166,8 @@ private static async Task RunOptionsInnerAsync(CommandLineOptions options) ZipFile.CreateFromDirectory(newDirectoryPath, zipFilePath); // Getting rid of the original directory. - Directory.Delete(newDirectoryPath, recursive: true); + // Not deleting only for debugging. + ////Directory.Delete(newDirectoryPath, recursive: true); WriteLine("{0} was created successfully. ", zipFilePath); From 808072f04ee5a95ddfa2493fb4af8b368cdef49f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zolt=C3=A1n=20Leh=C3=B3czky?= Date: Wed, 28 Dec 2022 03:13:55 +0100 Subject: [PATCH 26/54] Updating alpha version number --- .github/actions/deploy-media-theme/action.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/actions/deploy-media-theme/action.yml b/.github/actions/deploy-media-theme/action.yml index bf49eef..1aad85a 100644 --- a/.github/actions/deploy-media-theme/action.yml +++ b/.github/actions/deploy-media-theme/action.yml @@ -20,7 +20,7 @@ runs: - name: Install Lombiq.Hosting.MediaTheme.Deployer shell: pwsh run: | - dotnet tool install --global Lombiq.Hosting.MediaTheme.Deployer --version 2.0.1-alpha.3.osoe-514 + dotnet tool install --global Lombiq.Hosting.MediaTheme.Deployer --version 2.0.1-alpha.4.osoe-514 - name: Deploy Media Theme shell: pwsh From 790b4810002d0f50d7e55983d0646f8883d3c8b5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zolt=C3=A1n=20Leh=C3=B3czky?= Date: Wed, 28 Dec 2022 03:24:48 +0100 Subject: [PATCH 27/54] Another Linux incompatibility --- .../Constants/PathConstants.cs | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/Lombiq.Hosting.MediaTheme.Deployer/Constants/PathConstants.cs b/Lombiq.Hosting.MediaTheme.Deployer/Constants/PathConstants.cs index 57927d6..cf2800f 100644 --- a/Lombiq.Hosting.MediaTheme.Deployer/Constants/PathConstants.cs +++ b/Lombiq.Hosting.MediaTheme.Deployer/Constants/PathConstants.cs @@ -9,15 +9,16 @@ public static class PathConstants public const string MediaThemeTemplatesDirectory = "Templates"; public const string MediaThemeAssetsDirectory = "Assets"; - // This needs to use slashes on every platform. + // These need to use slashes on every platform. public const string MediaThemeAssetsWebPath = MediaThemeRootDirectory + "/" + MediaThemeAssetsDirectory; - public const string MediaThemeTemplatesWebPath = MediaThemeRootDirectory + "/" + MediaThemeTemplatesDirectory; - public const string MediaThemeTemplatesCopyDirectoryPath = "\\" + MediaThemeRootDirectory + "\\" + MediaThemeTemplatesDirectory; public const string RecipeFile = "Recipe.json"; public const string LiquidFileExtension = ".liquid"; public static readonly string MediaThemeAssetsCopyDirectoryPath = - Path.DirectorySeparatorChar + MediaThemeRootDirectory + Path.DirectorySeparatorChar + MediaThemeAssetsDirectory; + Path.Combine(MediaThemeRootDirectory, MediaThemeAssetsDirectory); + + public static readonly string MediaThemeTemplatesCopyDirectoryPath = + Path.Combine(MediaThemeRootDirectory, MediaThemeTemplatesDirectory); } From de9438b1a822e3de07885df24fc751ae5fc202cf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zolt=C3=A1n=20Leh=C3=B3czky?= Date: Wed, 28 Dec 2022 03:25:16 +0100 Subject: [PATCH 28/54] Updating alpha version number --- .github/actions/deploy-media-theme/action.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/actions/deploy-media-theme/action.yml b/.github/actions/deploy-media-theme/action.yml index 1aad85a..5381543 100644 --- a/.github/actions/deploy-media-theme/action.yml +++ b/.github/actions/deploy-media-theme/action.yml @@ -20,7 +20,7 @@ runs: - name: Install Lombiq.Hosting.MediaTheme.Deployer shell: pwsh run: | - dotnet tool install --global Lombiq.Hosting.MediaTheme.Deployer --version 2.0.1-alpha.4.osoe-514 + dotnet tool install --global Lombiq.Hosting.MediaTheme.Deployer --version 2.0.1-alpha.5.osoe-514 - name: Deploy Media Theme shell: pwsh From 0c538fbbbe9751edda106acaf1eb9c8ffe10c0ee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zolt=C3=A1n=20Leh=C3=B3czky?= Date: Wed, 28 Dec 2022 03:33:25 +0100 Subject: [PATCH 29/54] Removing debug code --- .github/workflows/deploy-media-theme.yml | 8 -------- Lombiq.Hosting.MediaTheme.Deployer/Program.cs | 3 +-- .../RemoteDeploymentHelper.cs | 3 +-- 3 files changed, 2 insertions(+), 12 deletions(-) diff --git a/.github/workflows/deploy-media-theme.yml b/.github/workflows/deploy-media-theme.yml index be4661d..7631f7c 100644 --- a/.github/workflows/deploy-media-theme.yml +++ b/.github/workflows/deploy-media-theme.yml @@ -52,11 +52,3 @@ jobs: theme-path: ${{ inputs.theme-path }} base-theme-id: ${{ inputs.base-theme-id }} clear-media-folder: ${{ inputs.clear-media-folder }} - - - name: Upload Deployment Package - uses: actions/upload-artifact@v3.1.1 - if: (success() || failure()) - with: - name: deployment-package - path: ${{ inputs.theme-path }}/Deployment - if-no-files-found: ignore diff --git a/Lombiq.Hosting.MediaTheme.Deployer/Program.cs b/Lombiq.Hosting.MediaTheme.Deployer/Program.cs index d930cdc..2cffd6b 100644 --- a/Lombiq.Hosting.MediaTheme.Deployer/Program.cs +++ b/Lombiq.Hosting.MediaTheme.Deployer/Program.cs @@ -166,8 +166,7 @@ private static async Task RunOptionsInnerAsync(CommandLineOptions options) ZipFile.CreateFromDirectory(newDirectoryPath, zipFilePath); // Getting rid of the original directory. - // Not deleting only for debugging. - ////Directory.Delete(newDirectoryPath, recursive: true); + Directory.Delete(newDirectoryPath, recursive: true); WriteLine("{0} was created successfully. ", zipFilePath); diff --git a/Lombiq.Hosting.MediaTheme.Deployer/RemoteDeploymentHelper.cs b/Lombiq.Hosting.MediaTheme.Deployer/RemoteDeploymentHelper.cs index 9902c0c..271aff8 100644 --- a/Lombiq.Hosting.MediaTheme.Deployer/RemoteDeploymentHelper.cs +++ b/Lombiq.Hosting.MediaTheme.Deployer/RemoteDeploymentHelper.cs @@ -54,8 +54,7 @@ public static async Task DeployAsync(CommandLineOptions options, string deployme } finally { - // Not deleting only for debugging. - ////File.Delete(deploymentPackagePath); + File.Delete(deploymentPackagePath); } } } From 760411d0fe86ace9adb84ab3f8e801e9001ea4f4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zolt=C3=A1n=20Leh=C3=B3czky?= Date: Wed, 28 Dec 2022 03:34:20 +0100 Subject: [PATCH 30/54] Updating alpha version number --- .github/actions/deploy-media-theme/action.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/actions/deploy-media-theme/action.yml b/.github/actions/deploy-media-theme/action.yml index 5381543..648401d 100644 --- a/.github/actions/deploy-media-theme/action.yml +++ b/.github/actions/deploy-media-theme/action.yml @@ -20,7 +20,7 @@ runs: - name: Install Lombiq.Hosting.MediaTheme.Deployer shell: pwsh run: | - dotnet tool install --global Lombiq.Hosting.MediaTheme.Deployer --version 2.0.1-alpha.5.osoe-514 + dotnet tool install --global Lombiq.Hosting.MediaTheme.Deployer --version 2.0.1-alpha.6.osoe-514 - name: Deploy Media Theme shell: pwsh From d194b277ad510286e6e4f77984293d6e3ef4c967 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zolt=C3=A1n=20Leh=C3=B3czky?= Date: Wed, 28 Dec 2022 03:36:27 +0100 Subject: [PATCH 31/54] Docs --- Readme.md | 32 +++++++++++++++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) diff --git a/Readme.md b/Readme.md index e7dab42..bc60fb2 100644 --- a/Readme.md +++ b/Readme.md @@ -91,7 +91,37 @@ media-theme-deploy --path . --base-id TheTheme --clear true --deployment-path .\ You can then take the resulting ZIP file and import it on your site from the Admin UI → Configuration → Import/Export → Package Import. -You can use Remote Deployment to accept such exported packages to deploy your theme remotely from your local development environment or CI too. +#### Remote deployment with the Deployer tool + +You can use [Remote Deployment](https://docs.orchardcore.net/en/latest/docs/reference/modules/Deployment.Remote/) to accept packages created with the above-explained Deployer too via the internet. You can use this to deploy your theme remotely from your local development environment or CI workflow too. + +For this, do the following: + +1. Create a Remote Client on the Orchard admin UI → Configuration → Import/Export → Remote Clients. Use a suitable name and a strong, unique API key. +2. Configure the Client API Key as a [repository secret](https://docs.github.com/en/actions/security-guides/encrypted-secrets#creating-encrypted-secrets-for-a-repository). While not strictly necessary, we recommend also storing the Client Name and Remote Deployment URL as secrets too. +3. Add a workflow to the _.github/workflows_ folder of your repository that executes the `deploy-media-theme` reusable workflow with some suitable configuration: + +```yaml +name: Deploy Media Theme to DotNest + +on: + push: + branches: + - my-dev + paths: + - 'src/Themes/My.Theme/**' + +jobs: + deploy-media-theme: + uses: Lombiq/Hosting-Media-Theme/.github/workflows/deploy-media-theme.yml@dev + secrets: + URL: ${{ secrets.MY_THEME_DEPLOYMENT_URL }} + CLIENT_NAME: ${{ secrets.MY_THEME_DEPLOYMENT_CLIENT_NAME }} + CLIENT_API_KEY: ${{ secrets.MY_THEME_DEPLOYMENT_CLIENT_API_KEY }} + with: + theme-path: "src/Themes/My.Theme" + base-theme-id: "TheBlogTheme" +``` ## Contributing and support From 39670867c667df9ab002a2b1748202f93059f078 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zolt=C3=A1n=20Leh=C3=B3czky?= Date: Wed, 28 Dec 2022 03:47:48 +0100 Subject: [PATCH 32/54] Typos --- Lombiq.Hosting.MediaTheme.Deployer/Program.cs | 8 ++++---- .../RemoteDeploymentHelper.cs | 12 ++++++------ 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/Lombiq.Hosting.MediaTheme.Deployer/Program.cs b/Lombiq.Hosting.MediaTheme.Deployer/Program.cs index 2cffd6b..6a15f49 100644 --- a/Lombiq.Hosting.MediaTheme.Deployer/Program.cs +++ b/Lombiq.Hosting.MediaTheme.Deployer/Program.cs @@ -27,21 +27,21 @@ public class CommandLineOptions "remote-deployment-url", Required = false, HelpText = "The URL to use for Remote Deployment, as indicated on the Orchard Core admin.")] - public string? RemoteDeploymenUrl { get; set; } + public string? RemoteDeploymentUrl { get; set; } [Option( 'n', "remote-deployment-client-name", Required = false, HelpText = "The \"Client Name\" part of the Remote Deployment client's credentials.")] - public string? RemoteDeploymenClientName { get; set; } + public string? RemoteDeploymentClientName { get; set; } [Option( 'k', "remote-deployment-client-api-key", Required = false, HelpText = "The \"Client API Key\" part of the Remote Deployment client's credentials.")] - public string? RemoteDeploymenClientApiKey { get; set; } + public string? RemoteDeploymentClientApiKey { get; set; } } internal static class Program @@ -170,7 +170,7 @@ private static async Task RunOptionsInnerAsync(CommandLineOptions options) WriteLine("{0} was created successfully. ", zipFilePath); - if (string.IsNullOrEmpty(options.RemoteDeploymenUrl)) + if (string.IsNullOrEmpty(options.RemoteDeploymentUrl)) { return; } diff --git a/Lombiq.Hosting.MediaTheme.Deployer/RemoteDeploymentHelper.cs b/Lombiq.Hosting.MediaTheme.Deployer/RemoteDeploymentHelper.cs index 271aff8..f335faa 100644 --- a/Lombiq.Hosting.MediaTheme.Deployer/RemoteDeploymentHelper.cs +++ b/Lombiq.Hosting.MediaTheme.Deployer/RemoteDeploymentHelper.cs @@ -6,7 +6,7 @@ internal static class RemoteDeploymentHelper public static async Task DeployAsync(CommandLineOptions options, string deploymentPackagePath) { - if (string.IsNullOrEmpty(options.RemoteDeploymenClientName) || string.IsNullOrEmpty(options.RemoteDeploymenClientApiKey)) + if (string.IsNullOrEmpty(options.RemoteDeploymentClientName) || string.IsNullOrEmpty(options.RemoteDeploymentClientApiKey)) { throw new InvalidOperationException( "When doing a Remote Deployment, both the Client Name and Client API Key should be provided."); @@ -34,21 +34,21 @@ public static async Task DeployAsync(CommandLineOptions options, string deployme "Content", Path.GetFileName(deploymentPackagePath) }, - { new StringContent(options.RemoteDeploymenClientName), "ClientName" }, - { new StringContent(options.RemoteDeploymenClientApiKey), "ApiKey" }, + { new StringContent(options.RemoteDeploymentClientName), "ClientName" }, + { new StringContent(options.RemoteDeploymentClientApiKey), "ApiKey" }, }; #pragma warning restore CA2000 // Dispose objects before losing scope - response = await _httpClient.PostAsync(options.RemoteDeploymenUrl, requestContent); + response = await _httpClient.PostAsync(options.RemoteDeploymentUrl, requestContent); if (response.StatusCode == System.Net.HttpStatusCode.OK) { - Console.WriteLine("Remote deployment to {0} succeeded.", options.RemoteDeploymenUrl); + Console.WriteLine("Remote deployment to {0} succeeded.", options.RemoteDeploymentUrl); } else { throw new HttpRequestException( - $"Remote deployment to {options.RemoteDeploymenUrl} failed with the HTTP code " + + $"Remote deployment to {options.RemoteDeploymentUrl} failed with the HTTP code " + $"{response.StatusCode} and message \"{response.RequestMessage}\"."); } } From 8d5939ac198e87b06ca7eaab5ddc7237cd648ced Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zolt=C3=A1n=20Leh=C3=B3czky?= Date: Wed, 28 Dec 2022 18:28:04 +0100 Subject: [PATCH 33/54] Getting base theme configuration from the theme manifest if available --- Lombiq.Hosting.MediaTheme.Deployer/Program.cs | 69 +++++++++++++++---- Readme.md | 6 +- 2 files changed, 59 insertions(+), 16 deletions(-) diff --git a/Lombiq.Hosting.MediaTheme.Deployer/Program.cs b/Lombiq.Hosting.MediaTheme.Deployer/Program.cs index 6a15f49..a6a80d2 100644 --- a/Lombiq.Hosting.MediaTheme.Deployer/Program.cs +++ b/Lombiq.Hosting.MediaTheme.Deployer/Program.cs @@ -1,8 +1,10 @@ using CommandLine; using Newtonsoft.Json; using Newtonsoft.Json.Linq; +using System.Diagnostics.CodeAnalysis; using System.Globalization; using System.IO.Compression; +using System.Text.RegularExpressions; using static Lombiq.Hosting.MediaTheme.Deployer.Constants.PathConstants; using static System.Console; @@ -11,15 +13,27 @@ namespace Lombiq.Hosting.MediaTheme.Deployer; public class CommandLineOptions { [Option('p', "path", Required = true, HelpText = "Path of your theme project.")] - public string? PathOfTheTheme { get; set; } + public string? ThemePath { get; set; } - [Option('i', "base-id", Required = false, HelpText = "ID of the base theme, if any.")] + [Option( + 'i', + "base-id", + Required = false, + HelpText = "ID of the base theme, if any. If left empty, will attempt to get the value from the theme's Manifest.")] public string? BaseThemeId { get; set; } - [Option('c', "clear", Required = false, HelpText = "Whether or not to clear the Media Theme media folder of all files before deployment.")] + [Option( + 'c', + "clear", + Required = false, + HelpText = "Whether or not to clear the Media Theme media folder of all files before deployment.")] public bool ClearMediaHostingFolder { get; set; } = true; - [Option('d', "deployment-path", Required = false, HelpText = "The path where you want the deployment package to be written to.")] + [Option( + 'd', + "deployment-path", + Required = false, + HelpText = "The path where you want the deployment package to be written to.")] public string? DeploymentPackagePath { get; set; } [Option( @@ -79,6 +93,10 @@ private static async Task RunOptionsAsync(CommandLineOptions options) } } + [SuppressMessage( + "Major Code Smell", + "S4457:Parameter validation in \"sync\"/\"await\" methods should be wrapped", + Justification = "RunOptionsAsync() needs to use await as well to be able to set the exit code on exception.")] private static async Task RunOptionsInnerAsync(CommandLineOptions options) { // Creating directory for the deployment. @@ -98,28 +116,49 @@ private static async Task RunOptionsInnerAsync(CommandLineOptions options) throw; } - var pathToTheme = options.PathOfTheTheme; + var themePath = options.ThemePath; + + if (string.IsNullOrEmpty(themePath)) + { + throw new ArgumentException("The theme's path should be provided."); + } // Creating media theme step. dynamic mediaThemeStep = new JObject(); mediaThemeStep.name = "mediatheme"; - mediaThemeStep.BaseThemeId = string.IsNullOrEmpty(options.BaseThemeId) ? null : options.BaseThemeId; mediaThemeStep.ClearMediaThemeFolder = options.ClearMediaHostingFolder; + var baseThemeId = string.IsNullOrEmpty(options.BaseThemeId) ? null : options.BaseThemeId; + + if (baseThemeId == null) + { + var manifestPath = Path.Combine(themePath, "Manifest.cs"); + var manifestContent = await File.ReadAllTextAsync(manifestPath); + var basteThemeMatch = Regex.Match( + manifestContent, @"BaseTheme\s*=\s*""(?.*)""", RegexOptions.ExplicitCapture, TimeSpan.FromSeconds(1)); + + if (basteThemeMatch.Success) + { + baseThemeId = basteThemeMatch.Groups["baseThemeId"].Value; + } + } + + mediaThemeStep.BaseThemeId = baseThemeId; + // Creating media step. var files = new JArray(); // Getting assets. - var pathToAssets = Path.Join(pathToTheme, LocalThemeWwwRootDirectory); + var assetsPath = Path.Join(themePath, LocalThemeWwwRootDirectory); - var allAssetsPaths = Directory.EnumerateFiles(pathToAssets, "*", SearchOption.AllDirectories); + var allAssetsPaths = Directory.EnumerateFiles(assetsPath, "*", SearchOption.AllDirectories); foreach (var assetPath in allAssetsPaths) { dynamic assetJObject = new JObject(); assetJObject.SourcePath = Path.Join( MediaThemeAssetsWebPath, - assetPath[pathToAssets.Length..].Replace("\\", "/")); + assetPath[assetsPath.Length..].Replace("\\", "/")); assetJObject.TargetPath = assetJObject.SourcePath; files.Add(assetJObject); @@ -127,22 +166,22 @@ private static async Task RunOptionsInnerAsync(CommandLineOptions options) // Copying assets to deployment directory. CopyDirectory( - pathToAssets, + assetsPath, Path.Join(newDirectoryPath, MediaThemeAssetsCopyDirectoryPath), areLiquidFiles: false); // Getting templates. - var pathToTemplates = Path.Join(pathToTheme, LocalThemeViewsDirectory); + var templatesPath = Path.Join(themePath, LocalThemeViewsDirectory); var allTemplatesPaths = Directory - .EnumerateFiles(pathToTemplates, "*" + LiquidFileExtension, SearchOption.TopDirectoryOnly); + .EnumerateFiles(templatesPath, "*" + LiquidFileExtension, SearchOption.TopDirectoryOnly); foreach (var templatePath in allTemplatesPaths) { dynamic templateJObject = new JObject(); templateJObject.SourcePath = Path.Join( MediaThemeTemplatesWebPath, - templatePath[pathToTemplates.Length..].Replace("\\", "/")); + templatePath[templatesPath.Length..].Replace("\\", "/")); templateJObject.TargetPath = templateJObject.SourcePath; files.Add(templateJObject); @@ -150,7 +189,7 @@ private static async Task RunOptionsInnerAsync(CommandLineOptions options) // Copying templates to deployment directory. CopyDirectory( - pathToTemplates, + templatesPath, Path.Join(newDirectoryPath, MediaThemeTemplatesCopyDirectoryPath), areLiquidFiles: true, recursive: false); @@ -190,7 +229,9 @@ private static void CopyDirectory( // Check if the source directory exists. if (!directory.Exists) + { throw new DirectoryNotFoundException($"Source directory not found: {directory.FullName}"); + } // Cache directories before we start copying. var directories = directory.GetDirectories(); diff --git a/Readme.md b/Readme.md index bc60fb2..f704cb8 100644 --- a/Readme.md +++ b/Readme.md @@ -87,7 +87,8 @@ A specific example when run in the folder of your theme project: media-theme-deploy --path . --base-id TheTheme --clear true --deployment-path .\Deployment ``` -`--deployment-path` is not required. Without it, the package will be exported to your directory root, for example _C:\MediaThemeDeployment_04Aug2022230500.zip_. The parameters also have shorthand versions, `-p`, `-i`, `-c`, `-d`, respectively. +- `--base-id` is optional. If not provided, the tool will try to get it from the Manifest file, and if it's not defined there either, no base theme will be used. +- `--deployment-path` is optional. Without it, the package will be exported to your directory root, for example _C:\MediaThemeDeployment_04Aug2022230500.zip_. The parameters also have shorthand versions, `-p`, `-i`, `-c`, `-d`, respectively. You can then take the resulting ZIP file and import it on your site from the Admin UI → Configuration → Import/Export → Package Import. @@ -120,7 +121,8 @@ jobs: CLIENT_API_KEY: ${{ secrets.MY_THEME_DEPLOYMENT_CLIENT_API_KEY }} with: theme-path: "src/Themes/My.Theme" - base-theme-id: "TheBlogTheme" + # You can leave out base-theme-id to get it from the Manifest, or to not use a base theme at all. + #base-theme-id: "TheBlogTheme" ``` ## Contributing and support From 7b0033461d629a7df3c17d55fee4392343a70e47 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zolt=C3=A1n=20Leh=C3=B3czky?= Date: Wed, 28 Dec 2022 18:30:44 +0100 Subject: [PATCH 34/54] Updating alpha version number --- .github/actions/deploy-media-theme/action.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/actions/deploy-media-theme/action.yml b/.github/actions/deploy-media-theme/action.yml index 648401d..be39c78 100644 --- a/.github/actions/deploy-media-theme/action.yml +++ b/.github/actions/deploy-media-theme/action.yml @@ -20,7 +20,7 @@ runs: - name: Install Lombiq.Hosting.MediaTheme.Deployer shell: pwsh run: | - dotnet tool install --global Lombiq.Hosting.MediaTheme.Deployer --version 2.0.1-alpha.6.osoe-514 + dotnet tool install --global Lombiq.Hosting.MediaTheme.Deployer --version 2.0.1-alpha.7.osoe-514 - name: Deploy Media Theme shell: pwsh From 3ac055a5c6fa1feedb2646c489f5eb990f9ead75 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zolt=C3=A1n=20Leh=C3=B3czky?= Date: Wed, 28 Dec 2022 18:50:58 +0100 Subject: [PATCH 35/54] Fixing empty --base-id handling in GHA --- .github/actions/deploy-media-theme/action.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/actions/deploy-media-theme/action.yml b/.github/actions/deploy-media-theme/action.yml index be39c78..6ae0b6b 100644 --- a/.github/actions/deploy-media-theme/action.yml +++ b/.github/actions/deploy-media-theme/action.yml @@ -25,14 +25,15 @@ runs: - name: Deploy Media Theme shell: pwsh run: | + # Putting --base-id as last, so if it's empty, then the other parameters will still be parsed correct. $switches = @( '--path', '${{ inputs.theme-path }}' - '--base-id', '${{ inputs.base-theme-id }}' '--clear', '${{ inputs.clear-media-folder }}' '--deployment-path', '${{ inputs.theme-path }}/Deployment' '--remote-deployment-url', '${{ env.URL }}' '--remote-deployment-client-name', '${{ env.CLIENT_NAME }}' '--remote-deployment-client-api-key', '${{ env.CLIENT_API_KEY }}' + '--base-id', '${{ inputs.base-theme-id }}' ) media-theme-deploy @switches From 56d64e2071549a342fb8e4e07f3138c443d9399e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zolt=C3=A1n=20Leh=C3=B3czky?= Date: Wed, 28 Dec 2022 19:14:51 +0100 Subject: [PATCH 36/54] Automatically enabling everything necessary in the deployment package --- Lombiq.Hosting.MediaTheme.Deployer/Program.cs | 22 ++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/Lombiq.Hosting.MediaTheme.Deployer/Program.cs b/Lombiq.Hosting.MediaTheme.Deployer/Program.cs index a6a80d2..f67e315 100644 --- a/Lombiq.Hosting.MediaTheme.Deployer/Program.cs +++ b/Lombiq.Hosting.MediaTheme.Deployer/Program.cs @@ -123,10 +123,25 @@ private static async Task RunOptionsInnerAsync(CommandLineOptions options) throw new ArgumentException("The theme's path should be provided."); } + var recipeSteps = new JArray(); + + // Creating Feature step to enable the Media Theme theme and Bridge module. + dynamic featureStep = new JObject(); + featureStep.name = "Feature"; + featureStep.enable = new JArray("Lombiq.Hosting.MediaTheme.Bridge", "Lombiq.Hosting.MediaTheme"); + recipeSteps.Add(featureStep); + + // Creating Themes step to set Media Theme as the site theme. + dynamic themesStep = new JObject(); + themesStep.name = "Themes"; + themesStep.Site = "Lombiq.Hosting.MediaTheme"; + recipeSteps.Add(themesStep); + // Creating media theme step. dynamic mediaThemeStep = new JObject(); mediaThemeStep.name = "mediatheme"; mediaThemeStep.ClearMediaThemeFolder = options.ClearMediaHostingFolder; + recipeSteps.Add(mediaThemeStep); var baseThemeId = string.IsNullOrEmpty(options.BaseThemeId) ? null : options.BaseThemeId; @@ -197,8 +212,9 @@ private static async Task RunOptionsInnerAsync(CommandLineOptions options) dynamic mediaStep = new JObject(); mediaStep.name = "media"; mediaStep.Files = files; + recipeSteps.Add(mediaStep); - CreateRecipeAndWriteIt(mediaThemeStep, mediaStep, newDirectoryPath); + CreateRecipeAndWriteIt(recipeSteps, newDirectoryPath); // Zipping the directory. var zipFilePath = newDirectoryPath + ".zip"; @@ -287,7 +303,7 @@ private static string CreateNewDirectoryPath(CommandLineOptions values) + DateTime.Now.ToString("ddMMMyyyyHHmmss", CultureInfo.CurrentCulture); // #spell-check-ignore-line } - private static void CreateRecipeAndWriteIt(JObject mediaThemeStep, JObject mediaStep, string newDirectoryPath) + private static void CreateRecipeAndWriteIt(JArray steps, string newDirectoryPath) { // Creating the recipe itself. dynamic recipe = new JObject(); @@ -300,7 +316,7 @@ private static void CreateRecipeAndWriteIt(JObject mediaThemeStep, JObject media recipe.issetuprecipe = false; recipe.categories = new JArray(); recipe.tags = new JArray(); - recipe.steps = new JArray(mediaThemeStep, mediaStep); + recipe.steps = steps; // Creating JSON file. using var file = File.CreateText(Path.Join(newDirectoryPath, RecipeFile)); From 675fcfe0292e81f1bbf2b99475e4ea699f0f356e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zolt=C3=A1n=20Leh=C3=B3czky?= Date: Wed, 28 Dec 2022 19:15:17 +0100 Subject: [PATCH 37/54] Extending docs, removing not recommended manual deployment process --- Readme.md | 32 +++++++++++++++++++------------- 1 file changed, 19 insertions(+), 13 deletions(-) diff --git a/Readme.md b/Readme.md index f704cb8..50d6b9b 100644 --- a/Readme.md +++ b/Readme.md @@ -60,16 +60,9 @@ If you are developing a theme for your [DotNest](https://dotnest.com) site you c ### Deployment (import/export) -#### Manual deployment +#### Importing a deployment package created by the Deployer tool -If you want to export your Media Theme, go to the Admin UI → Configuration → Import/Export → Deployment Plans page and create a Deployment Plan with the following steps: - -- Add the "Media Theme" step. Here you can tick the "Clear Media Theme folder" checkbox; if ticked, it will delete all the files in the __MediaTheme_ folder in the Media Library during import. This can be helpful if you have a "Media" step along with this step bringing in all the Media Theme files, but be conscious of the order within the recipe: put the "Media Theme" step first. Leave it disabled if you only want to control the base theme. -- Optionally, add a "Media" step where you select the whole __MediaTheme_ folder. - -#### Deployment with the Deployer tool - -Instead of manual deployment you can [install](https://learn.microsoft.com/en-us/dotnet/core/tools/global-tools-how-to-use) the `Lombiq.Hosting.MediaTheme.Deployer` dotnet tool: +Instead of manually uploading files to the Media Library, [install](https://learn.microsoft.com/en-us/dotnet/core/tools/global-tools-how-to-use) the `Lombiq.Hosting.MediaTheme.Deployer` dotnet tool: ```pwsh dotnet tool install --global Lombiq.Hosting.MediaTheme.Deployer @@ -90,15 +83,15 @@ media-theme-deploy --path . --base-id TheTheme --clear true --deployment-path .\ - `--base-id` is optional. If not provided, the tool will try to get it from the Manifest file, and if it's not defined there either, no base theme will be used. - `--deployment-path` is optional. Without it, the package will be exported to your directory root, for example _C:\MediaThemeDeployment_04Aug2022230500.zip_. The parameters also have shorthand versions, `-p`, `-i`, `-c`, `-d`, respectively. -You can then take the resulting ZIP file and import it on your site from the Admin UI → Configuration → Import/Export → Package Import. +You can then take the resulting ZIP file and import it on your site from the Admin UI → Configuration → Import/Export → Package Import. Everything necessary will be configured by the package. If you don't see this menu item then first enable the "Deployment" feature under Configuration → Features. #### Remote deployment with the Deployer tool -You can use [Remote Deployment](https://docs.orchardcore.net/en/latest/docs/reference/modules/Deployment.Remote/) to accept packages created with the above-explained Deployer too via the internet. You can use this to deploy your theme remotely from your local development environment or CI workflow too. +You can use [Remote Deployment](https://docs.orchardcore.net/en/latest/docs/reference/modules/Deployment.Remote/) to accept packages created with the above-explained Deployer too via the internet, without manually uploading the ZIP file. You can use this to deploy your theme remotely from your local development environment or CI workflow too, for which we provide a ready to use [GitHub Actions workflow](https://github.com/features/actions). -For this, do the following: +Do the following to set up automated GitHub Actions deployments: -1. Create a Remote Client on the Orchard admin UI → Configuration → Import/Export → Remote Clients. Use a suitable name and a strong, unique API key. +1. Create a Remote Client on the Orchard admin UI → Configuration → Import/Export → Remote Clients. Use a suitable name and a strong, unique API key. If you don't see this menu item then first enable the "Remote Deployment" feature under Configuration → Features. 2. Configure the Client API Key as a [repository secret](https://docs.github.com/en/actions/security-guides/encrypted-secrets#creating-encrypted-secrets-for-a-repository). While not strictly necessary, we recommend also storing the Client Name and Remote Deployment URL as secrets too. 3. Add a workflow to the _.github/workflows_ folder of your repository that executes the `deploy-media-theme` reusable workflow with some suitable configuration: @@ -125,6 +118,19 @@ jobs: #base-theme-id: "TheBlogTheme" ``` +If you want to use a different CI system or would like to run remote deployment from the command line otherwise, use the `--remote-deployment-url`, `--remote-deployment-client-name`, and `--remote-deployment-client-api-key` parameters. See this PowerShell script for an example: + +```pwsh +$switches = @( + '--path', '.' + '--remote-deployment-url', 'https://localhost:44335/OrchardCore.Deployment.Remote/ImportRemoteInstance/Import' + '--remote-deployment-client-name', 'demo' + '--remote-deployment-client-api-key', 'Password1!' +) + +media-theme-deploy @switches +``` + ## Contributing and support Bug reports, feature requests, comments, questions, code contributions and love letters are warmly welcome. You can send them to us via GitHub issues and pull requests. Please adhere to our [open-source guidelines](https://lombiq.com/open-source-guidelines) while doing so. From 97ef87aebdd040f29c55adbbf182ce225b3cfbb9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zolt=C3=A1n=20Leh=C3=B3czky?= Date: Wed, 28 Dec 2022 20:07:47 +0100 Subject: [PATCH 38/54] Stronger validation message --- Lombiq.Hosting.MediaTheme.Deployer/Program.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Lombiq.Hosting.MediaTheme.Deployer/Program.cs b/Lombiq.Hosting.MediaTheme.Deployer/Program.cs index f67e315..5a3beae 100644 --- a/Lombiq.Hosting.MediaTheme.Deployer/Program.cs +++ b/Lombiq.Hosting.MediaTheme.Deployer/Program.cs @@ -120,7 +120,7 @@ private static async Task RunOptionsInnerAsync(CommandLineOptions options) if (string.IsNullOrEmpty(themePath)) { - throw new ArgumentException("The theme's path should be provided."); + throw new ArgumentException("The theme's path must be provided."); } var recipeSteps = new JArray(); From 8fad8f8e0ec3f72532ad720e2e0a3ffe37d4bef5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zolt=C3=A1n=20Leh=C3=B3czky?= Date: Thu, 29 Dec 2022 00:11:41 +0100 Subject: [PATCH 39/54] Code styling --- .../Middlewares/MediaThemeAssetUrlRedirectMiddleware.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Lombiq.Hosting.MediaTheme.Bridge/Middlewares/MediaThemeAssetUrlRedirectMiddleware.cs b/Lombiq.Hosting.MediaTheme.Bridge/Middlewares/MediaThemeAssetUrlRedirectMiddleware.cs index 662bb0c..bd6810e 100644 --- a/Lombiq.Hosting.MediaTheme.Bridge/Middlewares/MediaThemeAssetUrlRedirectMiddleware.cs +++ b/Lombiq.Hosting.MediaTheme.Bridge/Middlewares/MediaThemeAssetUrlRedirectMiddleware.cs @@ -12,8 +12,7 @@ public class MediaThemeAssetUrlRedirectMiddleware { private readonly RequestDelegate _next; - public MediaThemeAssetUrlRedirectMiddleware(RequestDelegate next) => - _next = next; + public MediaThemeAssetUrlRedirectMiddleware(RequestDelegate next) => _next = next; public async Task InvokeAsync( HttpContext context, From dcf2d99d0ed85d9f0399bd7c71d26960c831eba8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zolt=C3=A1n=20Leh=C3=B3czky?= Date: Thu, 29 Dec 2022 00:36:54 +0100 Subject: [PATCH 40/54] Cache busting for static resources --- .../Services/FileVersionProviderDecorator.cs | 59 +++++++++++++++++++ Lombiq.Hosting.MediaTheme.Bridge/Startup.cs | 2 + Readme.md | 13 ++-- 3 files changed, 67 insertions(+), 7 deletions(-) create mode 100644 Lombiq.Hosting.MediaTheme.Bridge/Services/FileVersionProviderDecorator.cs diff --git a/Lombiq.Hosting.MediaTheme.Bridge/Services/FileVersionProviderDecorator.cs b/Lombiq.Hosting.MediaTheme.Bridge/Services/FileVersionProviderDecorator.cs new file mode 100644 index 0000000..2c0acb0 --- /dev/null +++ b/Lombiq.Hosting.MediaTheme.Bridge/Services/FileVersionProviderDecorator.cs @@ -0,0 +1,59 @@ +using Lombiq.Hosting.MediaTheme.Bridge.Constants; +using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Mvc.ViewFeatures; +using Microsoft.Extensions.Options; +using OrchardCore.FileStorage; +using OrchardCore.Media; +using OrchardCore.Mvc; +using System; + +namespace Lombiq.Hosting.MediaTheme.Bridge.Services; + +/// +/// Service to add a cache busting version key to the URL of static resources references from Media Theme, like it +/// happens for standard resources. +/// +/// +/// +/// The default , , caches the version keys +/// until tenant restart (and in a second level, until app restart). While that's fine for local files that are part of +/// the app's source code, like CSS files in themes, it won't work for Media Theme files that can be updated any time +/// without app restart. +/// +/// +internal class FileVersionProviderDecorator : IFileVersionProvider +{ + private readonly IFileVersionProvider _decorated; + private readonly IMediaFileStore _mediaFileStore; + private readonly IOptions _mediaOption; + + public FileVersionProviderDecorator( + IFileVersionProvider decorated, + IMediaFileStore mediaFileStore, + IOptions mediaOptions) + { + _decorated = decorated; + _mediaFileStore = mediaFileStore; + _mediaOption = mediaOptions; + } + + public string AddFileVersionToPath(PathString requestPathBase, string path) + { + var isMediaThemePath = path.StartsWithOrdinalIgnoreCase(Routes.MediaThemeAssets) || + path.ContainsOrdinalIgnoreCase(Routes.MediaThemeAssets + "/"); + + if (isMediaThemePath) + { + var assetsSubPath = _mediaFileStore.Combine( + _mediaOption.Value.AssetsRequestPath, Paths.MediaThemeRootFolder, Paths.MediaThemeAssetsFolder); + path = path.Replace(Routes.MediaThemeAssets, assetsSubPath); + } + + // Note that if this will work all the time for local files. When a remote storage implementation is used to + // store Media files though (like Azure Blob Storage) then Media Cache will mirror the files locally. Since this + // only happens on the first request to the file, until then in the HTML output you'll see a URL without the + // cache busting parameter. + // This isn't an issue for real-life scenarios, just be mindful during development. + return _decorated.AddFileVersionToPath(requestPathBase, path); + } +} diff --git a/Lombiq.Hosting.MediaTheme.Bridge/Startup.cs b/Lombiq.Hosting.MediaTheme.Bridge/Startup.cs index a74cbb3..fbc9f21 100644 --- a/Lombiq.Hosting.MediaTheme.Bridge/Startup.cs +++ b/Lombiq.Hosting.MediaTheme.Bridge/Startup.cs @@ -6,6 +6,7 @@ using Lombiq.Hosting.MediaTheme.Bridge.Services; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Builder; +using Microsoft.AspNetCore.Mvc.ViewFeatures; using Microsoft.AspNetCore.Routing; using Microsoft.Extensions.DependencyInjection; using OrchardCore.Deployment; @@ -40,6 +41,7 @@ public override void ConfigureServices(IServiceCollection services) services.AddScoped(); services.AddScoped(); services.AddOrchardServices(); + services.Decorate(); } public override void Configure(IApplicationBuilder app, IEndpointRouteBuilder routes, IServiceProvider serviceProvider) diff --git a/Readme.md b/Readme.md index 50d6b9b..577ef80 100644 --- a/Readme.md +++ b/Readme.md @@ -43,18 +43,17 @@ You can proceed with developing your theme as you'd typically do: put the templa If you want to reference assets in your templates, you can use the `/mediatheme/` prefix in URLs, like below: -```html - -``` - -Be sure to use Orchard's resource manager for scripts and stylesheets: - ```liquid +{% assign 32pxIconUrl = "~/mediatheme/images/favicon-32x32.png" | href %} +{% link type:"image/png", rel:"icon", sizes:"32x32", href:32pxIconUrl, append_version:"true" %} + {% assign stylesPath = "~/mediatheme/styles/site.css" | href %} {% style src:stylesPath %} ``` -Media Theme will translate this path to either your local theme asset path or Media Library if the file exists. This way, you don't need to update your asset URLs in your templates one-by-one when deploying them. The `~` notation of virtual paths also comes in handy if you want to work with multiple tenants using URL prefixes locally, i.e. develop multiple Media Themes for multiple sites from the same solution. +These use Orchard's resource manager and thus will also include a browser/proxy cache busting `v` parameter that updates when the you deploy a new version of your theme. This will ensure that everybody sees the current version of your site's styling. + +Media Theme will translate this special path to either your local theme asset path or Media Library if the file exists. This way, you don't need to update your asset URLs in your templates one-by-one when deploying them. The `~` notation of virtual paths also comes in handy if you want to work with multiple tenants using URL prefixes locally, i.e. develop multiple Media Themes for multiple sites from the same solution. If you are developing a theme for your [DotNest](https://dotnest.com) site you can use the [DotNest Core SDK](https://github.com/Lombiq/DotNest-Core-SDK) that has everything prepared for you right away. From 362cc501550d4358f6e570095bd66e32fb62526d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zolt=C3=A1n=20Leh=C3=B3czky?= Date: Thu, 29 Dec 2022 00:40:10 +0100 Subject: [PATCH 41/54] Updating alpha version number --- .github/actions/deploy-media-theme/action.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/actions/deploy-media-theme/action.yml b/.github/actions/deploy-media-theme/action.yml index 6ae0b6b..b10d57e 100644 --- a/.github/actions/deploy-media-theme/action.yml +++ b/.github/actions/deploy-media-theme/action.yml @@ -20,7 +20,7 @@ runs: - name: Install Lombiq.Hosting.MediaTheme.Deployer shell: pwsh run: | - dotnet tool install --global Lombiq.Hosting.MediaTheme.Deployer --version 2.0.1-alpha.7.osoe-514 + dotnet tool install --global Lombiq.Hosting.MediaTheme.Deployer --version 2.0.1-alpha.8.osoe-514 - name: Deploy Media Theme shell: pwsh From 713d53ccf3cf21b420fbb3008a9f3f64056db57a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zolt=C3=A1n=20Leh=C3=B3czky?= Date: Thu, 29 Dec 2022 00:41:37 +0100 Subject: [PATCH 42/54] Docs --- Readme.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Readme.md b/Readme.md index 577ef80..2a5250f 100644 --- a/Readme.md +++ b/Readme.md @@ -51,7 +51,7 @@ If you want to reference assets in your templates, you can use the `/mediatheme/ {% style src:stylesPath %} ``` -These use Orchard's resource manager and thus will also include a browser/proxy cache busting `v` parameter that updates when the you deploy a new version of your theme. This will ensure that everybody sees the current version of your site's styling. +These use Orchard's resource manager and thus will also include a browser/proxy cache busting `v` parameter that updates when the you deploy a new version of your theme. This will ensure that everybody sees the current version of your site's styling. Note that while the Liquid `style` and `script` tags do this by default, for `link` you have to add `append_version` like above too. Media Theme will translate this special path to either your local theme asset path or Media Library if the file exists. This way, you don't need to update your asset URLs in your templates one-by-one when deploying them. The `~` notation of virtual paths also comes in handy if you want to work with multiple tenants using URL prefixes locally, i.e. develop multiple Media Themes for multiple sites from the same solution. From f54c1606ff73d6c1469db833905cab856c521918 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zolt=C3=A1n=20Leh=C3=B3czky?= Date: Mon, 2 Jan 2023 21:25:14 +0100 Subject: [PATCH 43/54] Grammar --- .github/actions/deploy-media-theme/action.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/actions/deploy-media-theme/action.yml b/.github/actions/deploy-media-theme/action.yml index b10d57e..892757b 100644 --- a/.github/actions/deploy-media-theme/action.yml +++ b/.github/actions/deploy-media-theme/action.yml @@ -25,7 +25,7 @@ runs: - name: Deploy Media Theme shell: pwsh run: | - # Putting --base-id as last, so if it's empty, then the other parameters will still be parsed correct. + # Putting --base-id as last, so if it's empty, then the other parameters will still be parsed correctly. $switches = @( '--path', '${{ inputs.theme-path }}' '--clear', '${{ inputs.clear-media-folder }}' From 69c3b94b7b59336d6b7889be5689177b4de41a95 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zolt=C3=A1n=20Leh=C3=B3czky?= Date: Mon, 2 Jan 2023 21:32:39 +0100 Subject: [PATCH 44/54] Docs --- .../Services/FileVersionProviderDecorator.cs | 6 ++---- .../Constants/PathConstants.cs | 2 +- Lombiq.Hosting.MediaTheme.Deployer/GlobalSuppressions.cs | 2 +- Lombiq.Hosting.MediaTheme.Deployer/Program.cs | 2 ++ Readme.md | 6 +++--- 5 files changed, 9 insertions(+), 9 deletions(-) diff --git a/Lombiq.Hosting.MediaTheme.Bridge/Services/FileVersionProviderDecorator.cs b/Lombiq.Hosting.MediaTheme.Bridge/Services/FileVersionProviderDecorator.cs index 2c0acb0..b972218 100644 --- a/Lombiq.Hosting.MediaTheme.Bridge/Services/FileVersionProviderDecorator.cs +++ b/Lombiq.Hosting.MediaTheme.Bridge/Services/FileVersionProviderDecorator.cs @@ -15,10 +15,8 @@ namespace Lombiq.Hosting.MediaTheme.Bridge.Services; /// /// /// -/// The default , , caches the version keys -/// until tenant restart (and in a second level, until app restart). While that's fine for local files that are part of -/// the app's source code, like CSS files in themes, it won't work for Media Theme files that can be updated any time -/// without app restart. +/// The default , , works just fine, but we need +/// to translate /mediatheme URLs. /// /// internal class FileVersionProviderDecorator : IFileVersionProvider diff --git a/Lombiq.Hosting.MediaTheme.Deployer/Constants/PathConstants.cs b/Lombiq.Hosting.MediaTheme.Deployer/Constants/PathConstants.cs index cf2800f..c56c37f 100644 --- a/Lombiq.Hosting.MediaTheme.Deployer/Constants/PathConstants.cs +++ b/Lombiq.Hosting.MediaTheme.Deployer/Constants/PathConstants.cs @@ -9,7 +9,7 @@ public static class PathConstants public const string MediaThemeTemplatesDirectory = "Templates"; public const string MediaThemeAssetsDirectory = "Assets"; - // These need to use slashes on every platform. + // These need to use forward slashes on every platform. public const string MediaThemeAssetsWebPath = MediaThemeRootDirectory + "/" + MediaThemeAssetsDirectory; public const string MediaThemeTemplatesWebPath = MediaThemeRootDirectory + "/" + MediaThemeTemplatesDirectory; diff --git a/Lombiq.Hosting.MediaTheme.Deployer/GlobalSuppressions.cs b/Lombiq.Hosting.MediaTheme.Deployer/GlobalSuppressions.cs index 8c9b7f6..c5331d8 100644 --- a/Lombiq.Hosting.MediaTheme.Deployer/GlobalSuppressions.cs +++ b/Lombiq.Hosting.MediaTheme.Deployer/GlobalSuppressions.cs @@ -3,5 +3,5 @@ [assembly: SuppressMessage( "Globalization", "CA1303:Do not pass literals as localized parameters", - Justification = "It's a console application, it doesn't need localization.", + Justification = "It's a developer console application, it doesn't need localization.", Scope = "module")] diff --git a/Lombiq.Hosting.MediaTheme.Deployer/Program.cs b/Lombiq.Hosting.MediaTheme.Deployer/Program.cs index 5a3beae..8a001ac 100644 --- a/Lombiq.Hosting.MediaTheme.Deployer/Program.cs +++ b/Lombiq.Hosting.MediaTheme.Deployer/Program.cs @@ -15,6 +15,8 @@ public class CommandLineOptions [Option('p', "path", Required = true, HelpText = "Path of your theme project.")] public string? ThemePath { get; set; } + // This parameter can still be useful if the base theme can't be parsed out of the Manifest easily, like if it uses + // consts for the ID instead of string literals. [Option( 'i', "base-id", diff --git a/Readme.md b/Readme.md index 2a5250f..c5e2250 100644 --- a/Readme.md +++ b/Readme.md @@ -51,9 +51,9 @@ If you want to reference assets in your templates, you can use the `/mediatheme/ {% style src:stylesPath %} ``` -These use Orchard's resource manager and thus will also include a browser/proxy cache busting `v` parameter that updates when the you deploy a new version of your theme. This will ensure that everybody sees the current version of your site's styling. Note that while the Liquid `style` and `script` tags do this by default, for `link` you have to add `append_version` like above too. +These use Orchard's resource manager and thus will also include a browser/proxy cache busting `v` parameter that updates when you deploy a new version of your theme. This will ensure that everybody sees the current version of your site's styling. Note that while the Liquid `style` and `script` tags do this by default, for `link` you have to add `append_version` like above too. -Media Theme will translate this special path to either your local theme asset path or Media Library if the file exists. This way, you don't need to update your asset URLs in your templates one-by-one when deploying them. The `~` notation of virtual paths also comes in handy if you want to work with multiple tenants using URL prefixes locally, i.e. develop multiple Media Themes for multiple sites from the same solution. +Media Theme will translate this special _~/mediatheme_ path to either your local theme asset path or Media Library if the file exists. This way, you don't need to update your asset URLs in your templates one-by-one when deploying them. The `~` notation of virtual paths also comes in handy if you want to work with multiple tenants using URL prefixes locally, i.e. develop multiple Media Themes for multiple sites from the same solution. If you are developing a theme for your [DotNest](https://dotnest.com) site you can use the [DotNest Core SDK](https://github.com/Lombiq/DotNest-Core-SDK) that has everything prepared for you right away. @@ -86,7 +86,7 @@ You can then take the resulting ZIP file and import it on your site from the Adm #### Remote deployment with the Deployer tool -You can use [Remote Deployment](https://docs.orchardcore.net/en/latest/docs/reference/modules/Deployment.Remote/) to accept packages created with the above-explained Deployer too via the internet, without manually uploading the ZIP file. You can use this to deploy your theme remotely from your local development environment or CI workflow too, for which we provide a ready to use [GitHub Actions workflow](https://github.com/features/actions). +You can use [Remote Deployment](https://docs.orchardcore.net/en/latest/docs/reference/modules/Deployment.Remote/) to accept packages created with the above-explained Deployer too via the internet, without manually uploading the ZIP file. You can use this to deploy your theme remotely from your local development environment or CI workflow too, for which we provide a ready-to-use [GitHub Actions workflow](https://github.com/features/actions). Do the following to set up automated GitHub Actions deployments: From d59f8842662cd936346be2139183ad9541ad1109 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zolt=C3=A1n=20Leh=C3=B3czky?= Date: Mon, 2 Jan 2023 21:37:13 +0100 Subject: [PATCH 45/54] Removing abbreviation --- Lombiq.Hosting.MediaTheme.Deployer/Program.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Lombiq.Hosting.MediaTheme.Deployer/Program.cs b/Lombiq.Hosting.MediaTheme.Deployer/Program.cs index 8a001ac..fc1845e 100644 --- a/Lombiq.Hosting.MediaTheme.Deployer/Program.cs +++ b/Lombiq.Hosting.MediaTheme.Deployer/Program.cs @@ -16,7 +16,7 @@ public class CommandLineOptions public string? ThemePath { get; set; } // This parameter can still be useful if the base theme can't be parsed out of the Manifest easily, like if it uses - // consts for the ID instead of string literals. + // constants for the ID instead of string literals. [Option( 'i', "base-id", From 0c40ad8759250a29bc88c2a7a3aa7023292d26da Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zolt=C3=A1n=20Leh=C3=B3czky?= Date: Tue, 3 Jan 2023 01:39:14 +0100 Subject: [PATCH 46/54] Typo --- .../Services/FileVersionProviderDecorator.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Lombiq.Hosting.MediaTheme.Bridge/Services/FileVersionProviderDecorator.cs b/Lombiq.Hosting.MediaTheme.Bridge/Services/FileVersionProviderDecorator.cs index b972218..1dec886 100644 --- a/Lombiq.Hosting.MediaTheme.Bridge/Services/FileVersionProviderDecorator.cs +++ b/Lombiq.Hosting.MediaTheme.Bridge/Services/FileVersionProviderDecorator.cs @@ -47,10 +47,10 @@ public string AddFileVersionToPath(PathString requestPathBase, string path) path = path.Replace(Routes.MediaThemeAssets, assetsSubPath); } - // Note that if this will work all the time for local files. When a remote storage implementation is used to - // store Media files though (like Azure Blob Storage) then Media Cache will mirror the files locally. Since this - // only happens on the first request to the file, until then in the HTML output you'll see a URL without the - // cache busting parameter. + // Note that this will work all the time for local files. When a remote storage implementation is used to store + // Media files though (like Azure Blob Storage) then Media Cache will mirror the files locally. Since this only + // happens on the first request to the file, until then in the HTML output you'll see a URL without the cache + // busting parameter. // This isn't an issue for real-life scenarios, just be mindful during development. return _decorated.AddFileVersionToPath(requestPathBase, path); } From 2d39c149da1ea396f453c2655df00379d1c9dc9e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zolt=C3=A1n=20Leh=C3=B3czky?= Date: Tue, 3 Jan 2023 02:11:22 +0100 Subject: [PATCH 47/54] Using Path.Combine() insteasd of Join() --- .../Constants/PathConstants.cs | 4 ---- Lombiq.Hosting.MediaTheme.Deployer/Program.cs | 18 ++++++++++-------- 2 files changed, 10 insertions(+), 12 deletions(-) diff --git a/Lombiq.Hosting.MediaTheme.Deployer/Constants/PathConstants.cs b/Lombiq.Hosting.MediaTheme.Deployer/Constants/PathConstants.cs index c56c37f..aaa5d8a 100644 --- a/Lombiq.Hosting.MediaTheme.Deployer/Constants/PathConstants.cs +++ b/Lombiq.Hosting.MediaTheme.Deployer/Constants/PathConstants.cs @@ -9,10 +9,6 @@ public static class PathConstants public const string MediaThemeTemplatesDirectory = "Templates"; public const string MediaThemeAssetsDirectory = "Assets"; - // These need to use forward slashes on every platform. - public const string MediaThemeAssetsWebPath = MediaThemeRootDirectory + "/" + MediaThemeAssetsDirectory; - public const string MediaThemeTemplatesWebPath = MediaThemeRootDirectory + "/" + MediaThemeTemplatesDirectory; - public const string RecipeFile = "Recipe.json"; public const string LiquidFileExtension = ".liquid"; diff --git a/Lombiq.Hosting.MediaTheme.Deployer/Program.cs b/Lombiq.Hosting.MediaTheme.Deployer/Program.cs index fc1845e..4ed5253 100644 --- a/Lombiq.Hosting.MediaTheme.Deployer/Program.cs +++ b/Lombiq.Hosting.MediaTheme.Deployer/Program.cs @@ -166,16 +166,17 @@ private static async Task RunOptionsInnerAsync(CommandLineOptions options) var files = new JArray(); // Getting assets. - var assetsPath = Path.Join(themePath, LocalThemeWwwRootDirectory); + var assetsPath = Path.Combine(themePath, LocalThemeWwwRootDirectory); var allAssetsPaths = Directory.EnumerateFiles(assetsPath, "*", SearchOption.AllDirectories); foreach (var assetPath in allAssetsPaths) { dynamic assetJObject = new JObject(); - assetJObject.SourcePath = Path.Join( - MediaThemeAssetsWebPath, - assetPath[assetsPath.Length..].Replace("\\", "/")); + // These need to use forward slashes on every platform due to Orchard's import logic. + assetJObject.SourcePath = + Path.Combine(MediaThemeAssetsCopyDirectoryPath, assetPath[(assetsPath.Length + 1)..]) + .Replace("\\", "/"); assetJObject.TargetPath = assetJObject.SourcePath; files.Add(assetJObject); @@ -188,7 +189,7 @@ private static async Task RunOptionsInnerAsync(CommandLineOptions options) areLiquidFiles: false); // Getting templates. - var templatesPath = Path.Join(themePath, LocalThemeViewsDirectory); + var templatesPath = Path.Combine(themePath, LocalThemeViewsDirectory); var allTemplatesPaths = Directory .EnumerateFiles(templatesPath, "*" + LiquidFileExtension, SearchOption.TopDirectoryOnly); @@ -196,9 +197,10 @@ private static async Task RunOptionsInnerAsync(CommandLineOptions options) foreach (var templatePath in allTemplatesPaths) { dynamic templateJObject = new JObject(); - templateJObject.SourcePath = Path.Join( - MediaThemeTemplatesWebPath, - templatePath[templatesPath.Length..].Replace("\\", "/")); + // These need to use forward slashes on every platform due to Orchard's import logic. + templateJObject.SourcePath = + Path.Combine(MediaThemeTemplatesCopyDirectoryPath, templatePath[(templatesPath.Length + 1)..]) + .Replace("\\", "/"); templateJObject.TargetPath = templateJObject.SourcePath; files.Add(templateJObject); From eba6e74ddb33d43477655901ab40aa7543b7b171 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zolt=C3=A1n=20Leh=C3=B3czky?= Date: Tue, 3 Jan 2023 02:12:09 +0100 Subject: [PATCH 48/54] Unneeded ToString() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Dávid El-Saig --- Lombiq.Hosting.MediaTheme.Deployer/Program.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Lombiq.Hosting.MediaTheme.Deployer/Program.cs b/Lombiq.Hosting.MediaTheme.Deployer/Program.cs index 4ed5253..ea0684b 100644 --- a/Lombiq.Hosting.MediaTheme.Deployer/Program.cs +++ b/Lombiq.Hosting.MediaTheme.Deployer/Program.cs @@ -90,7 +90,7 @@ private static async Task RunOptionsAsync(CommandLineOptions options) } catch (Exception ex) { - WriteLine("Deployment failed with the following exception: {0}", ex.ToString()); + WriteLine("Deployment failed with the following exception: {0}", ex); Environment.ExitCode = 1; } } From 02510ffa2da44d695489a61dd94f1d7ec0ef9b8e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zolt=C3=A1n=20Leh=C3=B3czky?= Date: Tue, 3 Jan 2023 02:25:30 +0100 Subject: [PATCH 49/54] Getting rid of dynamic --- Lombiq.Hosting.MediaTheme.Deployer/Program.cs | 82 +++++++++++-------- 1 file changed, 48 insertions(+), 34 deletions(-) diff --git a/Lombiq.Hosting.MediaTheme.Deployer/Program.cs b/Lombiq.Hosting.MediaTheme.Deployer/Program.cs index ea0684b..32beb45 100644 --- a/Lombiq.Hosting.MediaTheme.Deployer/Program.cs +++ b/Lombiq.Hosting.MediaTheme.Deployer/Program.cs @@ -128,23 +128,21 @@ private static async Task RunOptionsInnerAsync(CommandLineOptions options) var recipeSteps = new JArray(); // Creating Feature step to enable the Media Theme theme and Bridge module. - dynamic featureStep = new JObject(); - featureStep.name = "Feature"; - featureStep.enable = new JArray("Lombiq.Hosting.MediaTheme.Bridge", "Lombiq.Hosting.MediaTheme"); + var featureStep = JObject.FromObject(new + { + name = "Feature", + enable = new[] { "Lombiq.Hosting.MediaTheme.Bridge", "Lombiq.Hosting.MediaTheme" }, + }); recipeSteps.Add(featureStep); // Creating Themes step to set Media Theme as the site theme. - dynamic themesStep = new JObject(); - themesStep.name = "Themes"; - themesStep.Site = "Lombiq.Hosting.MediaTheme"; + var themesStep = JObject.FromObject(new + { + name = "Themes", + Site = "Lombiq.Hosting.MediaTheme", + }); recipeSteps.Add(themesStep); - // Creating media theme step. - dynamic mediaThemeStep = new JObject(); - mediaThemeStep.name = "mediatheme"; - mediaThemeStep.ClearMediaThemeFolder = options.ClearMediaHostingFolder; - recipeSteps.Add(mediaThemeStep); - var baseThemeId = string.IsNullOrEmpty(options.BaseThemeId) ? null : options.BaseThemeId; if (baseThemeId == null) @@ -160,7 +158,14 @@ private static async Task RunOptionsInnerAsync(CommandLineOptions options) } } - mediaThemeStep.BaseThemeId = baseThemeId; + // Creating media theme step. + var mediaThemeStep = JObject.FromObject(new + { + name = "mediatheme", + ClearMediaThemeFolder = options.ClearMediaHostingFolder, + BaseThemeId = baseThemeId, + }); + recipeSteps.Add(mediaThemeStep); // Creating media step. var files = new JArray(); @@ -172,12 +177,14 @@ private static async Task RunOptionsInnerAsync(CommandLineOptions options) foreach (var assetPath in allAssetsPaths) { - dynamic assetJObject = new JObject(); // These need to use forward slashes on every platform due to Orchard's import logic. - assetJObject.SourcePath = - Path.Combine(MediaThemeAssetsCopyDirectoryPath, assetPath[(assetsPath.Length + 1)..]) + var importPath = Path.Combine(MediaThemeAssetsCopyDirectoryPath, assetPath[(assetsPath.Length + 1)..]) .Replace("\\", "/"); - assetJObject.TargetPath = assetJObject.SourcePath; + var assetJObject = JObject.FromObject(new + { + SourcePath = importPath, + TargetPath = importPath, + }); files.Add(assetJObject); } @@ -196,12 +203,15 @@ private static async Task RunOptionsInnerAsync(CommandLineOptions options) foreach (var templatePath in allTemplatesPaths) { - dynamic templateJObject = new JObject(); // These need to use forward slashes on every platform due to Orchard's import logic. - templateJObject.SourcePath = + var importPath = Path.Combine(MediaThemeTemplatesCopyDirectoryPath, templatePath[(templatesPath.Length + 1)..]) .Replace("\\", "/"); - templateJObject.TargetPath = templateJObject.SourcePath; + var templateJObject = JObject.FromObject(new + { + SourcePath = importPath, + TargetPath = importPath, + }); files.Add(templateJObject); } @@ -213,9 +223,11 @@ private static async Task RunOptionsInnerAsync(CommandLineOptions options) areLiquidFiles: true, recursive: false); - dynamic mediaStep = new JObject(); - mediaStep.name = "media"; - mediaStep.Files = files; + var mediaStep = JObject.FromObject(new + { + name = "media", + Files = files, + }); recipeSteps.Add(mediaStep); CreateRecipeAndWriteIt(recipeSteps, newDirectoryPath); @@ -310,17 +322,19 @@ private static string CreateNewDirectoryPath(CommandLineOptions values) private static void CreateRecipeAndWriteIt(JArray steps, string newDirectoryPath) { // Creating the recipe itself. - dynamic recipe = new JObject(); - recipe.name = "MediaTheme"; - recipe.displayName = "Media Theme"; - recipe.description = "A recipe created with the media-theme-deployment tool."; - recipe.author = string.Empty; - recipe.website = string.Empty; - recipe.version = string.Empty; - recipe.issetuprecipe = false; - recipe.categories = new JArray(); - recipe.tags = new JArray(); - recipe.steps = steps; + var recipe = JObject.FromObject(new + { + name = "MediaTheme", + displayName = "Media Theme", + description = "A recipe created with the media-theme-deployment tool.", + author = string.Empty, + website = string.Empty, + version = string.Empty, + issetuprecipe = false, + categories = new JArray(), + tags = new JArray(), + steps = steps, + }); // Creating JSON file. using var file = File.CreateText(Path.Join(newDirectoryPath, RecipeFile)); From 2f67392fc9788c79a8c52c8a639e696054c267ce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zolt=C3=A1n=20Leh=C3=B3czky?= Date: Tue, 3 Jan 2023 02:28:51 +0100 Subject: [PATCH 50/54] DRY --- Lombiq.Hosting.MediaTheme.Deployer/Program.cs | 36 ++++++++----------- 1 file changed, 14 insertions(+), 22 deletions(-) diff --git a/Lombiq.Hosting.MediaTheme.Deployer/Program.cs b/Lombiq.Hosting.MediaTheme.Deployer/Program.cs index 32beb45..ca3a528 100644 --- a/Lombiq.Hosting.MediaTheme.Deployer/Program.cs +++ b/Lombiq.Hosting.MediaTheme.Deployer/Program.cs @@ -170,23 +170,26 @@ private static async Task RunOptionsInnerAsync(CommandLineOptions options) // Creating media step. var files = new JArray(); - // Getting assets. - var assetsPath = Path.Combine(themePath, LocalThemeWwwRootDirectory); - - var allAssetsPaths = Directory.EnumerateFiles(assetsPath, "*", SearchOption.AllDirectories); - - foreach (var assetPath in allAssetsPaths) + void AddFile(string rootPath, string filePath) { // These need to use forward slashes on every platform due to Orchard's import logic. - var importPath = Path.Combine(MediaThemeAssetsCopyDirectoryPath, assetPath[(assetsPath.Length + 1)..]) - .Replace("\\", "/"); - var assetJObject = JObject.FromObject(new + var importPath = Path.Combine(rootPath, filePath).Replace("\\", "/"); + var templateJObject = JObject.FromObject(new { SourcePath = importPath, TargetPath = importPath, }); - files.Add(assetJObject); + files.Add(templateJObject); + } + + // Getting assets. + var assetsPath = Path.Combine(themePath, LocalThemeWwwRootDirectory); + var allAssetsPaths = Directory.EnumerateFiles(assetsPath, "*", SearchOption.AllDirectories); + + foreach (var assetPath in allAssetsPaths) + { + AddFile(MediaThemeAssetsCopyDirectoryPath, assetPath[(assetsPath.Length + 1)..]); } // Copying assets to deployment directory. @@ -197,23 +200,12 @@ private static async Task RunOptionsInnerAsync(CommandLineOptions options) // Getting templates. var templatesPath = Path.Combine(themePath, LocalThemeViewsDirectory); - var allTemplatesPaths = Directory .EnumerateFiles(templatesPath, "*" + LiquidFileExtension, SearchOption.TopDirectoryOnly); foreach (var templatePath in allTemplatesPaths) { - // These need to use forward slashes on every platform due to Orchard's import logic. - var importPath = - Path.Combine(MediaThemeTemplatesCopyDirectoryPath, templatePath[(templatesPath.Length + 1)..]) - .Replace("\\", "/"); - var templateJObject = JObject.FromObject(new - { - SourcePath = importPath, - TargetPath = importPath, - }); - - files.Add(templateJObject); + AddFile(MediaThemeTemplatesCopyDirectoryPath, templatePath[(templatesPath.Length + 1)..]); } // Copying templates to deployment directory. From ad784080496231bba677b02621f183d2a63db994 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zolt=C3=A1n=20Leh=C3=B3czky?= Date: Tue, 3 Jan 2023 02:31:48 +0100 Subject: [PATCH 51/54] Simplifying if --- Lombiq.Hosting.MediaTheme.Deployer/Program.cs | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/Lombiq.Hosting.MediaTheme.Deployer/Program.cs b/Lombiq.Hosting.MediaTheme.Deployer/Program.cs index ca3a528..e362c5c 100644 --- a/Lombiq.Hosting.MediaTheme.Deployer/Program.cs +++ b/Lombiq.Hosting.MediaTheme.Deployer/Program.cs @@ -233,13 +233,10 @@ void AddFile(string rootPath, string filePath) WriteLine("{0} was created successfully. ", zipFilePath); - if (string.IsNullOrEmpty(options.RemoteDeploymentUrl)) + if (!string.IsNullOrEmpty(options.RemoteDeploymentUrl)) { - return; + await RemoteDeploymentHelper.DeployAsync(options, zipFilePath); } - - // This is a remote deployment. - await RemoteDeploymentHelper.DeployAsync(options, zipFilePath); } private static void CopyDirectory( From 3e1af07ab73ebbe4f13f24df4b8ef72bfa89efaa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zolt=C3=A1n=20Leh=C3=B3czky?= Date: Tue, 3 Jan 2023 02:40:44 +0100 Subject: [PATCH 52/54] Updating alpha version number in action --- .github/actions/deploy-media-theme/action.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/actions/deploy-media-theme/action.yml b/.github/actions/deploy-media-theme/action.yml index 892757b..2831ab6 100644 --- a/.github/actions/deploy-media-theme/action.yml +++ b/.github/actions/deploy-media-theme/action.yml @@ -20,7 +20,7 @@ runs: - name: Install Lombiq.Hosting.MediaTheme.Deployer shell: pwsh run: | - dotnet tool install --global Lombiq.Hosting.MediaTheme.Deployer --version 2.0.1-alpha.8.osoe-514 + dotnet tool install --global Lombiq.Hosting.MediaTheme.Deployer --version 2.0.2-alpha.0.osoe-514 - name: Deploy Media Theme shell: pwsh From 29245fc3838a283d81ad001ab38f8a6a53db79a2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zolt=C3=A1n=20Leh=C3=B3czky?= Date: Tue, 3 Jan 2023 03:00:47 +0100 Subject: [PATCH 53/54] Code styling --- Lombiq.Hosting.MediaTheme.Deployer/Program.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Lombiq.Hosting.MediaTheme.Deployer/Program.cs b/Lombiq.Hosting.MediaTheme.Deployer/Program.cs index e362c5c..e8961d9 100644 --- a/Lombiq.Hosting.MediaTheme.Deployer/Program.cs +++ b/Lombiq.Hosting.MediaTheme.Deployer/Program.cs @@ -322,7 +322,7 @@ private static void CreateRecipeAndWriteIt(JArray steps, string newDirectoryPath issetuprecipe = false, categories = new JArray(), tags = new JArray(), - steps = steps, + steps, }); // Creating JSON file. From 8746da23b0935804b25e9d359d4069b11c4396e1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?D=C3=A1vid=20El-Saig?= Date: Thu, 5 Jan 2023 15:24:35 +0100 Subject: [PATCH 54/54] reset branch selector --- .github/workflows/deploy-media-theme.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/deploy-media-theme.yml b/.github/workflows/deploy-media-theme.yml index 7631f7c..2ded367 100644 --- a/.github/workflows/deploy-media-theme.yml +++ b/.github/workflows/deploy-media-theme.yml @@ -43,7 +43,7 @@ jobs: token: ${{ secrets.CHECKOUT_TOKEN }} - name: Deploy Media Theme - uses: Lombiq/Hosting-Media-Theme/.github/actions/deploy-media-theme@issue/OSOE-514 + uses: Lombiq/Hosting-Media-Theme/.github/actions/deploy-media-theme@dev env: URL: ${{ secrets.URL }} CLIENT_NAME: ${{ secrets.CLIENT_NAME }}