2021-08-25 12:40:32 -04:00
// 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 ;
2021-12-10 15:36:47 -05:00
using System.Threading.Tasks ;
2021-08-25 12:40:32 -04:00
using System.Xml ;
using UnrealBuildBase ;
2023-03-07 21:23:47 -05:00
using Microsoft.Extensions.Logging ;
2021-08-25 12:40:32 -04:00
2021-12-10 16:56:09 -05:00
namespace AutomationTool.Tasks
2021-08-25 12:40:32 -04:00
{
/// <summary>
/// Parameters for a AWS ECS deploy task
/// </summary>
public class AwsEcsDeployTaskParameters
{
/// <summary>
/// Task definition file to use
/// </summary>
[TaskParameter(Optional = false)]
public string TaskDefinitionFile ;
/// <summary>
2021-09-02 05:15:26 -04:00
/// Docker image to set in new task definition (will replace %%DOCKER_PATTERN%% with this value)
2021-08-25 12:40:32 -04:00
/// </summary>
[TaskParameter(Optional = false)]
public string DockerImage ;
2021-09-02 05:15:26 -04:00
/// <summary>
/// App version to set in new task definition (will replace %%VERSION%% with this value)
/// </summary>
[TaskParameter(Optional = true)]
public string Version ;
2021-08-25 12:40:32 -04:00
/// <summary>
/// Cluster ARN representing AWS ECS cluster to operate on
/// </summary>
[TaskParameter(Optional = false)]
public string Cluster ;
/// <summary>
/// Service name to update and deploy to
/// </summary>
[TaskParameter(Optional = false)]
public string Service ;
/// <summary>
/// Environment variables
/// </summary>
[TaskParameter(Optional = true)]
public string Environment ;
/// <summary>
/// File to read environment from
/// </summary>
[TaskParameter(Optional = true)]
public string EnvironmentFile ;
/// <summary>
/// Write output to the log
/// </summary>
[TaskParameter(Optional = true)]
public bool LogOutput = false ;
}
/// <summary>
/// Creates a new AWS ECS task definition and updates the ECS service to use this new revision of the task def
/// </summary>
[TaskElement("Aws-EcsDeploy", typeof(AwsEcsDeployTaskParameters))]
public class AwsEcsDeployTask : SpawnTaskBase
{
/// <summary>
/// Parameters for this task
/// </summary>
AwsEcsDeployTaskParameters Parameters ;
/// <summary>
/// Construct an AWS ECS deploy task
/// </summary>
/// <param name="InParameters">Parameters for the task</param>
public AwsEcsDeployTask ( AwsEcsDeployTaskParameters InParameters )
{
Parameters = InParameters ;
}
/// <summary>
/// Execute the task.
/// </summary>
/// <param name="Job">Information about the current job</param>
/// <param name="BuildProducts">Set of build products produced by this node.</param>
/// <param name="TagNameToFileSet">Mapping from tag names to the set of files they include</param>
2021-12-10 15:36:47 -05:00
public override async Task ExecuteAsync ( JobContext Job , HashSet < FileReference > BuildProducts , Dictionary < string , HashSet < FileReference > > TagNameToFileSet )
2021-08-25 12:40:32 -04:00
{
2021-09-02 05:15:26 -04:00
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 ) ;
}
2021-08-25 12:40:32 -04:00
FileReference TempTaskDefFile = FileReference . Combine ( Unreal . RootDirectory , "Engine" , "Intermediate" , "Build" , "AwsEcsDeployTaskTemp.json" ) ;
DirectoryReference . CreateDirectory ( TempTaskDefFile . Directory ) ;
2021-09-02 05:15:26 -04:00
File . WriteAllText ( TempTaskDefFile . FullName , TaskDefRendered , new UTF8Encoding ( encoderShouldEmitUTF8Identifier : false ) ) ;
2021-08-25 12:40:32 -04:00
2021-12-10 15:36:47 -05:00
IProcessResult CreateTaskDefResult = await SpawnTaskBase . ExecuteAsync ( "aws" , $"ecs register-task-definition --cli-input-json \" file : //{TempTaskDefFile.FullName}\"", EnvVars: ParseEnvVars(Parameters.Environment, Parameters.EnvironmentFile), LogOutput: Parameters.LogOutput);
2021-08-25 12:40:32 -04:00
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}" ;
2021-12-10 15:36:47 -05:00
await SpawnTaskBase . ExecuteAsync ( "aws" , Params , EnvVars : ParseEnvVars ( Parameters . Environment , Parameters . EnvironmentFile ) , LogOutput : Parameters . LogOutput ) ;
2021-08-25 12:40:32 -04:00
2023-03-08 12:43:35 -05:00
Logger . LogInformation ( "Service {Service} updated to use new task def {TaskDefFamily}:{TaskDefRevision}" , Parameters . Service , TaskDefFamily , TaskDefRevision ) ;
2021-08-25 12:40:32 -04:00
}
/// <summary>
/// Output this task out to an XML writer.
/// </summary>
public override void Write ( XmlWriter Writer )
{
Write ( Writer , Parameters ) ;
}
/// <summary>
/// Find all the tags which are used as inputs to this task
/// </summary>
/// <returns>The tag names which are read by this task</returns>
public override IEnumerable < string > FindConsumedTagNames ( )
{
yield break ;
}
/// <summary>
/// Find all the tags which are modified by this task
/// </summary>
/// <returns>The tag names which are modified by this task</returns>
public override IEnumerable < string > FindProducedTagNames ( )
{
yield break ;
}
}
}