in src/Amazon.Lambda.Tools/Commands/PackageCommand.cs [148:266]
protected override async Task<bool> PerformActionAsync()
{
EnsureInProjectDirectory();
// Disable interactive since this command is intended to be run as part of a pipeline.
this.DisableInteractive = true;
string projectLocation = Utilities.DetermineProjectLocation(this.WorkingDirectory, this.GetStringValueOrDefault(this.ProjectLocation, CommonDefinedCommandOptions.ARGUMENT_PROJECT_LOCATION, false));
Lambda.PackageType packageType = LambdaUtilities.DeterminePackageType(this.GetStringValueOrDefault(this.PackageType, LambdaDefinedCommandOptions.ARGUMENT_PACKAGE_TYPE, false));
if(packageType == Lambda.PackageType.Image)
{
var pushResults = await PushLambdaImageAsync();
if (!pushResults.Success)
{
if (pushResults.LastException != null)
throw pushResults.LastException;
throw new LambdaToolsException("Failed to push container image to ECR.", LambdaToolsException.LambdaErrorCode.FailedToPushImage);
}
}
else
{
var layerVersionArns = this.GetStringValuesOrDefault(this.LayerVersionArns, LambdaDefinedCommandOptions.ARGUMENT_FUNCTION_LAYERS, false);
LayerPackageInfo layerPackageInfo = null;
if (layerVersionArns != null)
{
if (!this.DisableRegionAndCredentialsCheck)
{
// Region and credentials are only required if using layers. This is new behavior so do a preemptive check when there are layers to
// see if region and credentials are set. If they are not set give a specific error message about region and credentials required
// when using layers.
try
{
base.DetermineAWSRegion();
}
catch (Exception)
{
throw new ToolsException("Region is required for the package command when layers are specified. The layers must be inspected to see how they affect packaging.", ToolsException.CommonErrorCode.RegionNotConfigured);
}
try
{
base.DetermineAWSCredentials();
}
catch (Exception)
{
throw new ToolsException("AWS credentials are required for the package command when layers are specified. The layers must be inspected to see how they affect packaging.", ToolsException.CommonErrorCode.InvalidCredentialConfiguration);
}
}
layerPackageInfo = await LambdaUtilities.LoadLayerPackageInfos(this.Logger, this.LambdaClient, this.S3Client, layerVersionArns);
}
else
{
layerPackageInfo = new LayerPackageInfo();
}
// Release will be the default configuration if nothing set.
var configuration = this.GetStringValueOrDefault(this.Configuration, CommonDefinedCommandOptions.ARGUMENT_CONFIGURATION, false);
var msbuildParameters = this.GetStringValueOrDefault(this.MSBuildParameters, CommonDefinedCommandOptions.ARGUMENT_MSBUILD_PARAMETERS, false);
var targetFramework = this.GetStringValueOrDefault(this.TargetFramework, CommonDefinedCommandOptions.ARGUMENT_FRAMEWORK, false);
if (string.IsNullOrEmpty(targetFramework))
{
targetFramework = Utilities.LookupTargetFrameworkFromProjectFile(projectLocation, msbuildParameters);
// If we still don't know what the target framework is ask the user what targetframework to use.
// This is common when a project is using multi targeting.
if (string.IsNullOrEmpty(targetFramework))
{
targetFramework = this.GetStringValueOrDefault(this.TargetFramework, CommonDefinedCommandOptions.ARGUMENT_FRAMEWORK, true);
}
}
bool isNativeAot = Utilities.LookPublishAotFlag(projectLocation, msbuildParameters);
var architecture = this.GetStringValueOrDefault(this.Architecture, LambdaDefinedCommandOptions.ARGUMENT_FUNCTION_ARCHITECTURE, false);
var disableVersionCheck = this.GetBoolValueOrDefault(this.DisableVersionCheck, LambdaDefinedCommandOptions.ARGUMENT_DISABLE_VERSION_CHECK, false).GetValueOrDefault();
var zipArchivePath = GetStringValueOrDefault(this.OutputPackageFileName, LambdaDefinedCommandOptions.ARGUMENT_OUTPUT_PACKAGE, false);
string publishLocation;
var success = LambdaPackager.CreateApplicationBundle(defaults: this.DefaultConfig,
logger: this.Logger,
workingDirectory: this.WorkingDirectory,
projectLocation: projectLocation,
configuration: configuration,
targetFramework: targetFramework,
msbuildParameters: msbuildParameters,
architecture: architecture,
disableVersionCheck: disableVersionCheck,
layerPackageInfo: layerPackageInfo,
isNativeAot: isNativeAot,
useContainerForBuild: GetBoolValueOrDefault(this.UseContainerForBuild, LambdaDefinedCommandOptions.ARGUMENT_USE_CONTAINER_FOR_BUILD, false),
containerImageForBuild: GetStringValueOrDefault(this.ContainerImageForBuild, LambdaDefinedCommandOptions.ARGUMENT_CONTAINER_IMAGE_FOR_BUILD, false),
codeMountDirectory: GetStringValueOrDefault(this.CodeMountDirectory, LambdaDefinedCommandOptions.ARGUMENT_CODE_MOUNT_DIRECTORY, false),
publishLocation: out publishLocation,
zipArchivePath: ref zipArchivePath);
if (!success)
{
throw new LambdaToolsException("Failed to create Lambda deployment bundle.", ToolsException.CommonErrorCode.DotnetPublishFailed);
}
this.Logger.WriteLine("Lambda project successfully packaged: " + zipArchivePath);
var dotnetSharedStoreValue = layerPackageInfo.GenerateDotnetSharedStoreValue();
if (!string.IsNullOrEmpty(dotnetSharedStoreValue))
{
this.NewDotnetSharedStoreValue = dotnetSharedStoreValue;
this.Logger.WriteLine($"\nWarning: You must set the {LambdaConstants.ENV_DOTNET_SHARED_STORE} environment variable when deploying the package. " +
"If not set the layers specified will not be located by the .NET Core runtime. The trailing '/' is required.");
this.Logger.WriteLine($"{LambdaConstants.ENV_DOTNET_SHARED_STORE}: {dotnetSharedStoreValue}");
}
}
return true;
}