Skip to content

chore: upgrade templating engine to net8 #927

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
May 8, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ public override async Task<int> ExecuteAsync(CommandContext context, GenerateDep
}
}

cdkProjectHandler.CreateCdkProject(selectedRecommendation, session, saveDirectory);
await cdkProjectHandler.CreateCdkProject(selectedRecommendation, session, saveDirectory);
await GenerateDeploymentRecipeSnapShot(selectedRecommendation, saveDirectory, projectDisplayName, targetApplicationFullPath);

var saveCdkDirectoryFullPath = directoryManager.GetDirectoryInfo(saveDirectory).FullName;
Expand Down
6 changes: 3 additions & 3 deletions src/AWS.Deploy.Orchestration/AWS.Deploy.Orchestration.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,9 @@
<PackageReference Include="AWSSDK.S3" Version="4.0.0.1" />
<PackageReference Include="AWSSDK.AppRunner" Version="4.0.0.1" />
<PackageReference Include="AWSSDK.SimpleSystemsManagement" Version="4.0.1.1" />
<PackageReference Include="Microsoft.Bcl.AsyncInterfaces" Version="6.0.0" />
<PackageReference Include="Microsoft.TemplateEngine.IDE" Version="5.0.1" />
<PackageReference Include="Microsoft.TemplateEngine.Orchestrator.RunnableProjects" Version="5.0.1" />
<PackageReference Include="Microsoft.Bcl.AsyncInterfaces" Version="8.0.0" />
<PackageReference Include="Microsoft.TemplateEngine.IDE" Version="8.0.408" />
<PackageReference Include="Microsoft.TemplateEngine.Orchestrator.RunnableProjects" Version="8.0.408" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
<PackageReference Include="System.Linq.Async" Version="6.0.1" />
<PackageReference Include="YamlDotNet" Version="13.4.0" />
Expand Down
8 changes: 4 additions & 4 deletions src/AWS.Deploy.Orchestration/CdkProjectHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ namespace AWS.Deploy.Orchestration
public interface ICdkProjectHandler
{
Task<string> ConfigureCdkProject(OrchestratorSession session, CloudApplication cloudApplication, Recommendation recommendation);
string CreateCdkProject(Recommendation recommendation, OrchestratorSession session, string? saveDirectoryPath = null);
Task<string> CreateCdkProject(Recommendation recommendation, OrchestratorSession session, string? saveDirectoryPath = null);
Task DeployCdkProject(OrchestratorSession session, CloudApplication cloudApplication, string cdkProjectPath, Recommendation recommendation);
void DeleteTemporaryCdkProject(string cdkProjectPath);
Task<string> PerformCdkDiff(string cdkProjectPath, CloudApplication cloudApplication);
Expand Down Expand Up @@ -71,7 +71,7 @@ public async Task<string> ConfigureCdkProject(OrchestratorSession session, Cloud
{
// Create a new temporary CDK project for a new deployment
_interactiveService.LogInfoMessage("Generating AWS Cloud Development Kit (AWS CDK) deployment project");
cdkProjectPath = CreateCdkProject(recommendation, session);
cdkProjectPath = await CreateCdkProject(recommendation, session);
}

// Write required configuration in appsettings.json
Expand Down Expand Up @@ -255,7 +255,7 @@ private async Task CheckCdkDeploymentFailure(string stackId, DateTime deployment
}
}

public string CreateCdkProject(Recommendation recommendation, OrchestratorSession session, string? saveCdkDirectoryPath = null)
public async Task<string> CreateCdkProject(Recommendation recommendation, OrchestratorSession session, string? saveCdkDirectoryPath = null)
{
string? assemblyName;
if (string.IsNullOrEmpty(saveCdkDirectoryPath))
Expand All @@ -278,7 +278,7 @@ public string CreateCdkProject(Recommendation recommendation, OrchestratorSessio
_directoryManager.CreateDirectory(saveCdkDirectoryPath);

var templateEngine = new TemplateEngine();
templateEngine.GenerateCDKProjectFromTemplate(recommendation, session, saveCdkDirectoryPath, assemblyName);
await templateEngine.GenerateCdkProjectFromTemplateAsync(recommendation, session, saveCdkDirectoryPath, assemblyName);

_interactiveService.LogDebugMessage($"Saving AWS CDK deployment project to: {saveCdkDirectoryPath}");
return saveCdkDirectoryPath;
Expand Down
68 changes: 30 additions & 38 deletions src/AWS.Deploy.Orchestration/TemplateEngine.cs
Original file line number Diff line number Diff line change
@@ -1,37 +1,30 @@
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Threading.Tasks;
using AWS.Deploy.Common;
using Microsoft.TemplateEngine.Abstractions;
using Microsoft.TemplateEngine.Edge;
using Microsoft.TemplateEngine.Edge.Template;
using Microsoft.TemplateEngine.Abstractions.Installer;
using Microsoft.TemplateEngine.Edge.Installers.Folder;
using Microsoft.TemplateEngine.IDE;
using Microsoft.TemplateEngine.Orchestrator.RunnableProjects;
using Microsoft.TemplateEngine.Utils;
using DefaultTemplateEngineHost = Microsoft.TemplateEngine.Edge.DefaultTemplateEngineHost;
using WellKnownSearchFilters = Microsoft.TemplateEngine.Utils.WellKnownSearchFilters;

namespace AWS.Deploy.Orchestration
{
public class TemplateEngine
{
private const string HostIdentifier = "aws-net-deploy-template-generator";
private const string HostVersion = "v1.0.0";
private const string HOST_IDENTIFIER = "aws-net-deploy-template-generator";
private const string HOST_VERSION = "v2.0.0";
private readonly Bootstrapper _bootstrapper;
private static readonly object s_locker = new();

public TemplateEngine()
{
_bootstrapper = new Bootstrapper(CreateHost(), null, virtualizeConfiguration: true);
_bootstrapper = new Bootstrapper(CreateHost(), true);
}

public void GenerateCDKProjectFromTemplate(Recommendation recommendation, OrchestratorSession session, string outputDirectory, string assemblyName)
public async Task GenerateCdkProjectFromTemplateAsync(Recommendation recommendation, OrchestratorSession session, string outputDirectory, string assemblyName)
{
if (string.IsNullOrEmpty(recommendation.Recipe.CdkProjectTemplate))
{
Expand All @@ -49,50 +42,49 @@
recommendation.Recipe.CdkProjectTemplate);

//Installing the base template into the templating engine to make it available for generation
InstallTemplates(cdkProjectTemplateDirectory);
await InstallTemplates(cdkProjectTemplateDirectory);

//Looking up the installed template in the templating engine
var template =
var templates = await
_bootstrapper
.ListTemplates(
true,
WellKnownSearchFilters.NameFilter(recommendation.Recipe.CdkProjectTemplateId))
.FirstOrDefault()
?.Info;
.GetTemplatesAsync(
new[] { WellKnownSearchFilters.NameFilter(recommendation.Recipe.CdkProjectTemplateId) });
var template = templates.FirstOrDefault()?.Info;

//If the template is not found, throw an exception
if (template == null)
throw new Exception($"Failed to find a Template for [{recommendation.Recipe.CdkProjectTemplateId}]");

var templateParameters = new Dictionary<string, string> {
// CDK Template projects can parameterize the version number of the AWS.Deploy.Recipes.CDK.Common package. This avoid
var templateParameters = new Dictionary<string, string?> {
// CDK Template projects can parameterize the version number of the AWS.Deploy.Recipes.CDK.Common package. This avoids
// projects having to be modified every time the package version is bumped.
{ "AWSDeployRecipesCDKCommonVersion", FileVersionInfo.GetVersionInfo(typeof(AWS.Deploy.Recipes.CDK.Common.CDKRecipeSetup).Assembly.Location).ProductVersion
?? throw new InvalidAWSDeployRecipesCDKCommonVersionException(DeployToolErrorCode.InvalidAWSDeployRecipesCDKCommonVersion, "The version number of the AWS.Deploy.Recipes.CDK.Common package is invalid.") }
};

try
{
lock (s_locker)
{
//Generate the CDK project using the installed template into the output directory
_bootstrapper.CreateAsync(template, assemblyName, outputDirectory, templateParameters, false, "").GetAwaiter().GetResult();
}
//Generate the CDK project using the installed template into the output directory
await _bootstrapper.CreateAsync(template, assemblyName, outputDirectory, templateParameters);
}
catch
{
throw new TemplateGenerationFailedException(DeployToolErrorCode.FailedToGenerateCDKProjectFromTemplate, "Failed to generate CDK project from template");
}
}

private void InstallTemplates(string folderLocation)
private async Task InstallTemplates(string folderLocation)
{
try
{
lock (s_locker)
var installRequests = new[]
{
_bootstrapper.Install(folderLocation);
}
new InstallRequest(folderLocation, folderLocation, force: true)
};

var result = await _bootstrapper.InstallTemplatePackagesAsync(installRequests);
if (result.Any(x => x.Success == false))
throw new Exception("Failed to install the default template that is required to the generate the CDK project");

Check warning on line 87 in src/AWS.Deploy.Orchestration/TemplateEngine.cs

View check run for this annotation

Codecov / codecov/patch

src/AWS.Deploy.Orchestration/TemplateEngine.cs#L87

Added line #L87 was not covered by tests
}
catch(Exception e)
{
Expand All @@ -107,13 +99,13 @@
{ "prefs:language", "C#" }
};

var builtIns = new AssemblyComponentCatalog(new[]
var builtIns = new List<(Type, IIdentifiedComponent)>
{
typeof(RunnableProjectGenerator).GetTypeInfo().Assembly, // for assembly: Microsoft.TemplateEngine.Orchestrator.RunnableProjects
typeof(AssemblyComponentCatalog).GetTypeInfo().Assembly, // for assembly: Microsoft.TemplateEngine.Edge
});
(typeof(IGenerator), new RunnableProjectGenerator()),
(typeof(IInstallerFactory), new FolderInstallerFactory())
};

ITemplateEngineHost host = new DefaultTemplateEngineHost(HostIdentifier, HostVersion, CultureInfo.CurrentCulture.Name, preferences, builtIns, null);
ITemplateEngineHost host = new DefaultTemplateEngineHost(HOST_IDENTIFIER, HOST_VERSION, preferences, builtIns);

return host;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
{
"$schema": "http://json.schemastore.org/template",
"author": "AWS",
"classifications": [
"AWS",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
{
"$schema": "http://json.schemastore.org/template",
"author": "AWS",
"classifications": [
"AWS",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
{
"$schema": "http://json.schemastore.org/template",
"author": "AWS",
"classifications": [
"AWS",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
{
"$schema": "http://json.schemastore.org/template",
"author": "AWS",
"classifications": [
"AWS",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
{
"$schema": "http://json.schemastore.org/template",
"author": "AWS",
"classifications": [
"AWS",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
{
"$schema": "http://json.schemastore.org/template",
"author": "AWS",
"classifications": [
"AWS",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
{
"$schema": "http://json.schemastore.org/template",
"author": "AWS",
"classifications": [
"AWS",
Expand Down
Loading