public static bool CreateApplicationBundle()

in src/Amazon.Lambda.Tools/LambdaPackager.cs [111:269]


        public static bool CreateApplicationBundle(LambdaToolsDefaults defaults, IToolLogger logger, string workingDirectory,
            string projectLocation, string configuration, string targetFramework, string msbuildParameters, string architecture,
            bool disableVersionCheck, LayerPackageInfo layerPackageInfo, bool isNativeAot,
            bool? useContainerForBuild, string containerImageForBuild, string codeMountDirectory,
            out string publishLocation, ref string zipArchivePath)
        {
            LambdaUtilities.ValidateTargetFramework(projectLocation, msbuildParameters, targetFramework, isNativeAot);

            LambdaUtilities.ValidateNativeAotArchitecture(architecture, isNativeAot);

            // If use container is set to false explicitly, then that overrides other values.
            if (useContainerForBuild.HasValue && !useContainerForBuild.Value)
            {
                containerImageForBuild = null;
            }
            // Else, if we haven't been given a build image, we need to figure out if we should use a default
            else if (string.IsNullOrWhiteSpace(containerImageForBuild))
            {
                // Use a default container image if Use Container is set to true, or if we need to build NativeAOT on non-AL2
                if ((useContainerForBuild.HasValue && useContainerForBuild.Value) || (isNativeAot && !IsAmazonLinux(logger)))
                {
                    containerImageForBuild = LambdaUtilities.GetDefaultBuildImage(targetFramework, architecture, logger);
                }
            }
            // Otherwise, we've been given a build image to use, so always use that.
            // Below, the code only considers whether containerImageForBuild is set or not

            LogDeprecationMessagesIfNecessary(logger, targetFramework);

            if (msbuildParameters != null && msbuildParameters.Contains("--self-contained true"))
            {
                if (string.Equals(architecture, LambdaConstants.ARCHITECTURE_ARM64) && IsAmazonLinux2(logger))
                {
                    logger.WriteLine("WARNING: There is an issue with self-contained ARM-based .NET Lambda functions using custom runtimes on Amazon Linux 2 that causes functions to fail to run.");
                    logger.WriteLine("For more information and workarounds, see: https://github.com/aws/aws-lambda-dotnet/issues/920");
                }
                else if (IsAmazonLinux2023(logger))
                {
                    logger.WriteLine("WARNING: There is an issue with self-contained .NET Lambda functions using custom runtimes on Amazon Linux 2023 that causes functions to fail to run.");
                    logger.WriteLine("This applies to both AMD and ARM architectures.");
                    logger.WriteLine("For more information and workarounds, see: https://github.com/aws/aws-lambda-dotnet/issues/920");
                }
            }

            if (string.IsNullOrEmpty(configuration))
                configuration = LambdaConstants.DEFAULT_BUILD_CONFIGURATION;

            var lambdaRuntimePackageStoreManifestContent = LambdaUtilities.LoadPackageStoreManifest(logger, targetFramework);

            var publishManifestPath = new List<string>();
            if (!string.IsNullOrEmpty(lambdaRuntimePackageStoreManifestContent))
            {
                var tempFile = Path.GetTempFileName();
                File.WriteAllText(tempFile, lambdaRuntimePackageStoreManifestContent);
                publishManifestPath.Add(tempFile);
            }

            if (layerPackageInfo != null)
            {
                foreach (var info in layerPackageInfo.Items)
                {
                    publishManifestPath.Add(info.ManifestPath);
                }
            }

            publishLocation = Utilities.DeterminePublishLocation(workingDirectory, projectLocation, configuration, targetFramework);

            logger?.WriteLine("Executing publish command");
            var cli = new LambdaDotNetCLIWrapper(logger, workingDirectory);

            if (!string.IsNullOrWhiteSpace(containerImageForBuild))
            {
                var containerBuildLogMessage = isNativeAot ? $"Starting container for native AOT build using build image: {containerImageForBuild}." : $"Starting container for build using build image: {containerImageForBuild}.";
                logger.WriteLine(containerBuildLogMessage);

                var directoryToMountToContainer = Utilities.GetSolutionDirectoryFullPath(workingDirectory, projectLocation, codeMountDirectory);

                var dockerCli = new DockerCLIWrapper(logger, directoryToMountToContainer);

                var containerName = $"tempLambdaBuildContainer-{Guid.NewGuid()}";

                string relativeContainerPathToProjectLocation = string.Concat(DockerCLIWrapper.WorkingDirectoryMountLocation, Utilities.RelativePathTo(directoryToMountToContainer, projectLocation));

                // This value is the path inside of the container that will map directly to the out parameter "publishLocation" on the host machine
                string relativeContainerPathToPublishLocation = Utilities.DeterminePublishLocation(null, relativeContainerPathToProjectLocation, configuration, targetFramework);

                var publishCommand = "dotnet " + cli.GetPublishArguments(projectLocation, relativeContainerPathToPublishLocation, targetFramework, configuration, msbuildParameters, architecture, publishManifestPath, isNativeAot, relativeContainerPathToProjectLocation);

                var runResult = dockerCli.Run(containerImageForBuild, containerName, publishCommand);
                if (runResult != 0)
                {
                    throw new LambdaToolsException($"ERROR: Container build returned {runResult}", LambdaToolsException.LambdaErrorCode.ContainerBuildFailed);
                }
            }
            else
            {
                if (cli.Publish(defaults: defaults,
                    projectLocation: projectLocation,
                    outputLocation: publishLocation,
                    targetFramework: targetFramework,
                    configuration: configuration,
                    msbuildParameters: msbuildParameters,
                    architecture: architecture,
                    publishManifests: publishManifestPath) != 0)
                {
                    throw new LambdaToolsException($"ERROR: The dotnet publish command return unsuccessful error code", LambdaToolsException.CommonErrorCode.ShellOutToDotnetPublishFailed);
                }
            }

            var buildLocation = Utilities.DetermineBuildLocation(workingDirectory, projectLocation, configuration, targetFramework);

            // This is here for legacy reasons. Some older versions of the dotnet CLI were not 
            // copying the deps.json file into the publish folder.
            foreach (var file in Directory.GetFiles(buildLocation, "*.deps.json", SearchOption.TopDirectoryOnly))
            {
                var destinationPath = Path.Combine(publishLocation, Path.GetFileName(file));
                if (!File.Exists(destinationPath))
                    File.Copy(file, destinationPath);
            }

            bool flattenRuntime = false;
            var depsJsonTargetNode = GetDepsJsonTargetNode(logger, publishLocation);
            // If there is no target node then this means the tool is being used on a future version of .NET Core
            // then was available when the this tool was written. Go ahead and continue the deployment with warnings so the
            // user can see if the future version will work.
            if (depsJsonTargetNode != null && string.Equals(targetFramework, "netcoreapp1.0", StringComparison.OrdinalIgnoreCase))
            {
                // Make sure the project is not pulling in dependencies requiring a later version of .NET Core then the declared target framework
                if (!ValidateDependencies(logger, targetFramework, depsJsonTargetNode, disableVersionCheck))
                    return false;

                // Flatten the runtime folder which reduces the package size by not including native dependencies
                // for other platforms.
                flattenRuntime = FlattenRuntimeFolder(logger, publishLocation, depsJsonTargetNode);
            }

            FlattenPowerShellRuntimeModules(logger, publishLocation, targetFramework);


            if (zipArchivePath == null)
                zipArchivePath = Path.Combine(Directory.GetParent(publishLocation).FullName, new DirectoryInfo(projectLocation).Name + ".zip");

            zipArchivePath = Path.GetFullPath(zipArchivePath);
            logger?.WriteLine($"Zipping publish folder {publishLocation} to {zipArchivePath}");
            if (File.Exists(zipArchivePath))
                File.Delete(zipArchivePath);

            var zipArchiveParentDirectory = Path.GetDirectoryName(zipArchivePath);
            if (!Directory.Exists(zipArchiveParentDirectory))
            {
                logger?.WriteLine($"Creating directory {zipArchiveParentDirectory}");
                new DirectoryInfo(zipArchiveParentDirectory).Create();
            }


            BundleDirectory(zipArchivePath, publishLocation, flattenRuntime, logger);

            return true;
        }