// Copyright Epic Games, Inc. All Rights Reserved. using AutomationTool; using EpicGames.Core; using System; using System.Collections.Generic; using System.IO; using System.Text; using System.Text.Json; using System.Xml; using UnrealBuildBase; namespace BuildGraph.Tasks { /// /// Parameters for a AWS ECS deploy task /// public class AwsEcsDeployTaskParameters { /// /// Task definition file to use /// [TaskParameter(Optional = false)] public string TaskDefinitionFile; /// /// Docker image to set in new task definition (will replace %%DOCKER_PATTERN%% with this value) /// [TaskParameter(Optional = false)] public string DockerImage; /// /// App version to set in new task definition (will replace %%VERSION%% with this value) /// [TaskParameter(Optional = true)] public string Version; /// /// Cluster ARN representing AWS ECS cluster to operate on /// [TaskParameter(Optional = false)] public string Cluster; /// /// Service name to update and deploy to /// [TaskParameter(Optional = false)] public string Service; /// /// Environment variables /// [TaskParameter(Optional = true)] public string Environment; /// /// File to read environment from /// [TaskParameter(Optional = true)] public string EnvironmentFile; /// /// Write output to the log /// [TaskParameter(Optional = true)] public bool LogOutput = false; } /// /// Creates a new AWS ECS task definition and updates the ECS service to use this new revision of the task def /// [TaskElement("Aws-EcsDeploy", typeof(AwsEcsDeployTaskParameters))] public class AwsEcsDeployTask : SpawnTaskBase { /// /// Parameters for this task /// AwsEcsDeployTaskParameters Parameters; /// /// Construct an AWS ECS deploy task /// /// Parameters for the task public AwsEcsDeployTask(AwsEcsDeployTaskParameters InParameters) { Parameters = InParameters; } /// /// Execute the task. /// /// Information about the current job /// Set of build products produced by this node. /// Mapping from tag names to the set of files they include public override void Execute(JobContext Job, HashSet BuildProducts, Dictionary> TagNameToFileSet) { string TaskDefTemplate = File.ReadAllText(ResolveFile(Parameters.TaskDefinitionFile).FullName); string TaskDefRendered = TaskDefTemplate.Replace("%%DOCKER_IMAGE%%", Parameters.DockerImage); if (Parameters.Version != null) { TaskDefRendered = TaskDefRendered.Replace("%%VERSION%%", Parameters.Version); } FileReference TempTaskDefFile = FileReference.Combine(Unreal.RootDirectory, "Engine", "Intermediate", "Build", "AwsEcsDeployTaskTemp.json"); DirectoryReference.CreateDirectory(TempTaskDefFile.Directory); File.WriteAllText(TempTaskDefFile.FullName, TaskDefRendered, new UTF8Encoding(encoderShouldEmitUTF8Identifier: false)); IProcessResult CreateTaskDefResult = SpawnTaskBase.Execute("aws", $"ecs register-task-definition --cli-input-json \"file://{TempTaskDefFile.FullName}\"", EnvVars: ParseEnvVars(Parameters.Environment, Parameters.EnvironmentFile), LogOutput: Parameters.LogOutput); JsonDocument TaskDefJson = JsonDocument.Parse(CreateTaskDefResult.Output); string TaskDefFamily = TaskDefJson.RootElement.GetProperty("taskDefinition").GetProperty("family").GetString(); string TaskDefRevision = TaskDefJson.RootElement.GetProperty("taskDefinition").GetProperty("revision").ToString(); string Params = $"ecs update-service --cluster {Parameters.Cluster} --service {Parameters.Service} --task-definition {TaskDefFamily}:{TaskDefRevision}"; SpawnTaskBase.Execute("aws", Params, EnvVars: ParseEnvVars(Parameters.Environment, Parameters.EnvironmentFile), LogOutput: Parameters.LogOutput); Log.TraceInformation($"Service {Parameters.Service} updated to use new task def {TaskDefFamily}:{TaskDefRevision}"); } /// /// Output this task out to an XML writer. /// public override void Write(XmlWriter Writer) { Write(Writer, Parameters); } /// /// Find all the tags which are used as inputs to this task /// /// The tag names which are read by this task public override IEnumerable FindConsumedTagNames() { yield break; } /// /// Find all the tags which are modified by this task /// /// The tag names which are modified by this task public override IEnumerable FindProducedTagNames() { yield break; } } }