def execute(self): """ Runs the action. :raises lambda_builders.actions.ActionFailedError: when Make Build fails. """ # Check for manifest file try: self.manifest_check() except MakeFileNotFoundError as ex: raise ActionFailedError(str(ex)) # Create the Artifacts Directory if it doesnt exist. if not self.osutils.exists(self.artifacts_dir): self.osutils.makedirs(self.artifacts_dir) try: current_env = self.osutils.environ() LOG.info("Current Artifacts Directory : %s", self.artifact_dir_path) current_env.update({"ARTIFACTS_DIR": self.artifact_dir_path}) # Export environmental variables that might be needed by other binaries used # within the Makefile and also specify the makefile to be used as well. self.subprocess_make.run( [ "--makefile", "{}".format(self.manifest_path), "build-{logical_id}".format(logical_id=self.build_logical_id), ], env=current_env, cwd=self.scratch_dir, ) except MakeExecutionError as ex: raise ActionFailedError(str(ex))
def execute(self): os_utils = OSUtils() python_path = self.binaries[self.LANGUAGE].binary_path try: pip = SubprocessPip(osutils=os_utils, python_exe=python_path) except MissingPipError as ex: raise ActionFailedError(str(ex)) pip_runner = PipRunner(python_exe=python_path, pip=pip) dependency_builder = DependencyBuilder(osutils=os_utils, pip_runner=pip_runner, runtime=self.runtime, architecture=self.architecture) package_builder = PythonPipDependencyBuilder( osutils=os_utils, runtime=self.runtime, dependency_builder=dependency_builder) try: target_artifact_dir = self.artifacts_dir # if dependencies folder is provided, download the dependencies into dependencies folder if self.dependencies_dir: target_artifact_dir = self.dependencies_dir package_builder.build_dependencies( artifacts_dir_path=target_artifact_dir, scratch_dir_path=self.scratch_dir, requirements_path=self.manifest_path, ) except PackagerError as ex: raise ActionFailedError(str(ex))
def execute(self): """ Runs the action. :raises lambda_builders.actions.ActionFailedError: when esbuild version checking fails """ args = ["--version"] try: version = self.subprocess_esbuild.run(args, cwd=self.scratch_dir) except EsbuildExecutionError as ex: raise ActionFailedError(str(ex)) LOG.debug("Found esbuild with version: %s", version) try: check_version = EsbuildCheckVersionAction._get_version_tuple(self.MIN_VERSION) esbuild_version = EsbuildCheckVersionAction._get_version_tuple(version) if esbuild_version < check_version: raise ActionFailedError( f"Unsupported esbuild version. To use a dependency layer, the esbuild version must be at " f"least {self.MIN_VERSION}. Version found: {version}" ) except (TypeError, ValueError) as ex: raise ActionFailedError(f"Unable to parse esbuild version: {str(ex)}")
def _get_explicit_file_type(self, entry_point, entry_path): """ Get an entry point with an explicit .ts or .js suffix. :type entry_point: str :param entry_point: path to entry file from code uri :type entry_path: str :param entry_path: full path of entry file :rtype: str :return: entry point with appropriate file extension :raises lambda_builders.actions.ActionFailedError: when esbuild packaging fails """ if Path(entry_point).suffix: if self.osutils.file_exists(entry_path): return entry_point raise ActionFailedError("entry point {} does not exist".format(entry_path)) for ext in [".ts", ".js"]: entry_path_with_ext = entry_path + ext if self.osutils.file_exists(entry_path_with_ext): return entry_point + ext raise ActionFailedError("entry point {} does not exist".format(entry_path))
def execute(self): """ Runs the action. :raises lambda_builders.actions.ActionFailedError: when NPM packaging fails """ try: package_path = "file:{}".format( self.osutils.abspath(self.osutils.dirname(self.manifest_path))) LOG.debug("NODEJS packaging %s to %s", package_path, self.scratch_dir) tarfile_name = self.subprocess_npm.run( ["pack", "-q", package_path], cwd=self.scratch_dir).splitlines()[-1] LOG.debug("NODEJS packed to %s", tarfile_name) tarfile_path = self.osutils.joinpath(self.scratch_dir, tarfile_name) LOG.debug("NODEJS extracting to %s", self.artifacts_dir) self.osutils.extract_tarfile(tarfile_path, self.artifacts_dir) except NpmExecutionError as ex: raise ActionFailedError(str(ex))
def execute(self): # run Amazon.Lambda.Tools update in sync block in case build is triggered in parallel with GlobalToolInstallAction.__lock: LOG.debug("Entered synchronized block for updating Amazon.Lambda.Tools") # check if Amazon.Lambda.Tools updated recently if GlobalToolInstallAction.__tools_installed: LOG.info("Skipping to update Amazon.Lambda.Tools install/update, since it is updated recently") return try: LOG.debug("Installing Amazon.Lambda.Tools Global Tool") self.subprocess_dotnet.run(["tool", "install", "-g", "Amazon.Lambda.Tools", "--ignore-failed-sources"]) GlobalToolInstallAction.__tools_installed = True except DotnetCLIExecutionError as ex: LOG.debug("Error installing probably due to already installed. Attempt to update to latest version.") try: self.subprocess_dotnet.run( ["tool", "update", "-g", "Amazon.Lambda.Tools", "--ignore-failed-sources"] ) GlobalToolInstallAction.__tools_installed = True except DotnetCLIExecutionError as ex: raise ActionFailedError( "Error configuring the Amazon.Lambda.Tools .NET Core Global Tool: " + str(ex) )
def execute(self): try: LOG.debug("Running `dotnet lambda package` in %s", self.source_dir) zipfilename = os.path.basename(os.path.normpath( self.source_dir)) + ".zip" zipfullpath = os.path.join(self.artifacts_dir, zipfilename) arguments = ['lambda', 'package', '--output-package', zipfullpath] if self.mode and self.mode.lower() == BuildMode.DEBUG: LOG.debug( "Debug build requested: Setting configuration to Debug") arguments += ["--configuration", "Debug"] if self.options is not None: for key in self.options: if str.startswith(key, "-"): arguments.append(key) arguments.append(self.options[key]) self.subprocess_dotnet.run(arguments, cwd=self.source_dir) # The dotnet lambda package command outputs a zip file for the package. To make this compatible # with the workflow, unzip the zip file into the artifacts directory and then delete the zip archive. self.os_utils.expand_zip(zipfullpath, self.artifacts_dir) except DotnetCLIExecutionError as ex: raise ActionFailedError(str(ex))
def execute(self): try: self.builder.build( self.source_dir, self.output_path, ) except BuilderError as ex: raise ActionFailedError(str(ex))
def execute(self): try: LOG.debug("Running bundle install in %s", self.source_dir) self.subprocess_bundler.run( ['install', '--without', 'development', 'test'], cwd=self.source_dir) except BundlerExecutionError as ex: raise ActionFailedError(str(ex))
def _copy_init_script(self): try: src = os.path.join(os.path.dirname(__file__), "resources", self.INIT_SCRIPT) dst = os.path.join(self.scratch_dir, self.INIT_SCRIPT) return self.os_utils.copy(src, dst) except Exception as ex: raise ActionFailedError(str(ex))
def execute(self): try: self.package_builder.build_dependencies( self.artifacts_dir, self.manifest_path, self.scratch_dir ) except PackagerError as ex: raise ActionFailedError(str(ex))
def _copy_artifacts(self): lambda_build_output = os.path.join(self.scratch_dir, "target", "classes") dependency_output = os.path.join(self.scratch_dir, "target", "dependency") if not self.os_utils.exists(lambda_build_output): raise ActionFailedError( "Required target/classes directory was not produced from 'mvn package'" ) try: self.os_utils.copytree(lambda_build_output, self.artifacts_dir) if self.os_utils.exists(dependency_output): self.os_utils.copytree(dependency_output, os.path.join(self.artifacts_dir, "lib")) except Exception as ex: raise ActionFailedError(str(ex))
def _copy_artifacts(self): lambda_build_output = os.path.join(self.build_dir, "build", "distributions", "lambda-build") try: if not self.os_utils.exists(self.artifacts_dir): self.os_utils.makedirs(self.artifacts_dir) self.os_utils.copytree(lambda_build_output, self.artifacts_dir) except Exception as ex: raise ActionFailedError(str(ex))
def execute(self): try: LOG.debug("Running bundle install --deployment in %s", self.source_dir) self.subprocess_bundler.run([ "install", "--deployment", "--without", "development", "test" ], cwd=self.source_dir) except BundlerExecutionError as ex: raise ActionFailedError(str(ex))
def _build_project(self, init_script_file): try: if not self.os_utils.exists(self.scratch_dir): self.os_utils.makedirs(self.scratch_dir) self.subprocess_gradle.build( self.source_dir, self.build_file, self.gradle_cache_dir, init_script_file, {self.SCRATCH_DIR_PROPERTY: os.path.abspath(self.scratch_dir)}) except GradleExecutionError as ex: raise ActionFailedError(str(ex))
def _move_dependencies(self): """ Move the entire lib directory from artifact folder to dependencies folder """ try: dependencies_lib_dir = os.path.join(self.dependencies_dir, "lib") lib_folder = os.path.join(self.artifacts_dir, "lib") self.os_utils.move(lib_folder, dependencies_lib_dir) except Exception as ex: raise ActionFailedError(str(ex))
def test_must_raise_if_action_failed(self): action_mock = Mock() self.work.actions = [action_mock.action1, action_mock.action2, action_mock.action3] # Doesn't matter which action fails, but let's make the second one fail action_mock.action2.execute.side_effect = ActionFailedError("testfailure") with self.assertRaises(WorkflowFailedError) as ctx: self.work.run() self.assertIn("testfailure", str(ctx.exception))
def execute(self): env = self.env env.update({"GOOS": "linux", "GOARCH": "amd64"}) try: self.subprocess_go.run( ["build", "-o", self.output_path, self.source_path], cwd=self.source_path, env=env) except ExecutionError as ex: raise ActionFailedError(str(ex))
def _copy_dependencies(self): """ copy the entire lib directory from artifact folder to dependencies folder """ try: dependencies_lib_dir = os.path.join(self.dependencies_dir, "lib") if not self.os_utils.exists(dependencies_lib_dir): self.os_utils.makedirs(dependencies_lib_dir) lib_folder = os.path.join(self.artifacts_dir, "lib") self.os_utils.copytree(lib_folder, dependencies_lib_dir) except Exception as ex: raise ActionFailedError(str(ex))
def _copy_artifacts(self): lambda_build_output = os.path.join(self.scratch_dir, "target") dependency_output = os.path.join(self.scratch_dir, "target", "dependency") if not self.os_utils.exists(lambda_build_output): raise ActionFailedError( "Required target/classes directory was not produced from 'mvn package'" ) try: self.os_utils.copytree( lambda_build_output, os.path.join(self.artifacts_dir, "lib"), ignore=shutil.ignore_patterns(*self.IGNORED_FOLDERS), include=jar_file_filter, ) if self.os_utils.exists(dependency_output): self.os_utils.copytree(dependency_output, os.path.join(self.artifacts_dir, "lib")) except Exception as ex: raise ActionFailedError(str(ex))
def _construct_esbuild_entry_points(self): """ Construct the list of explicit entry points """ if self.ENTRY_POINTS not in self.bundler_config: raise ActionFailedError(f"{self.ENTRY_POINTS} not set ({self.bundler_config})") entry_points = self.bundler_config[self.ENTRY_POINTS] if not isinstance(entry_points, list): raise ActionFailedError(f"{self.ENTRY_POINTS} must be a list ({self.bundler_config})") if not entry_points: raise ActionFailedError(f"{self.ENTRY_POINTS} must not be empty ({self.bundler_config})") entry_paths = [self.osutils.joinpath(self.scratch_dir, entry_point) for entry_point in entry_points] LOG.debug("NODEJS building %s using esbuild to %s", entry_paths, self.artifacts_dir) explicit_entry_points = [] for entry_path, entry_point in zip(entry_paths, entry_points): explicit_entry_points.append(self._get_explicit_file_type(entry_point, entry_path)) return explicit_entry_points
def execute(self): """ Runs the action. :raises lambda_builders.actions.ActionFailedError: when NPM execution fails """ try: LOG.debug("NODEJS installing ci in: %s", self.artifacts_dir) self.subprocess_npm.run(["ci"], cwd=self.artifacts_dir) except NpmExecutionError as ex: raise ActionFailedError(str(ex))
def execute(self): """ Runs the action. :raises lambda_builders.actions.ActionFailedError: when deleting .npmrc fails """ try: npmrc_path = self.osutils.joinpath(self.artifacts_dir, ".npmrc") if self.osutils.file_exists(npmrc_path): LOG.debug(".npmrc cleanup in: %s", self.artifacts_dir) self.osutils.remove_file(npmrc_path) except OSError as ex: raise ActionFailedError(str(ex))
def execute(self): """ Runs the action. :raises lambda_builders.actions.ActionFailedError: when .npmrc copying fails """ try: npmrc_path = self.osutils.joinpath(self.source_dir, ".npmrc") if self.osutils.file_exists(npmrc_path): LOG.debug(".npmrc copying in: %s", self.artifacts_dir) self.osutils.copy_file(npmrc_path, self.artifacts_dir) except OSError as ex: raise ActionFailedError(str(ex))
def execute(self): try: LOG.debug("Installing Amazon.Lambda.Tools Global Tool") self.subprocess_dotnet.run( ['tool', 'install', '-g', 'Amazon.Lambda.Tools'], ) except DotnetCLIExecutionError as ex: LOG.debug( "Error installing probably due to already installed. Attempt to update to latest version." ) try: self.subprocess_dotnet.run( ['tool', 'update', '-g', 'Amazon.Lambda.Tools'], ) except DotnetCLIExecutionError as ex: raise ActionFailedError( "Error configuring the Amazon.Lambda.Tools .NET Core Global Tool: " + str(ex))
def _copy_artifacts(self): lambda_build_output = os.path.join(self.build_dir, "build", "libs") layer_dependencies = os.path.join(self.build_dir, "build", "distributions", "lambda-build", "lib") try: if not self.os_utils.exists(self.artifacts_dir): self.os_utils.makedirs(self.artifacts_dir) self.os_utils.copytree(lambda_build_output, os.path.join(self.artifacts_dir, "lib"), include=jar_file_filter) self.os_utils.copytree(layer_dependencies, os.path.join(self.artifacts_dir, "lib"), include=jar_file_filter) except Exception as ex: raise ActionFailedError(str(ex))
def execute(self): """ Runs the action. :raises lambda_builders.actions.ActionFailedError: when copying fails """ try: for filename in [".npmrc", "package-lock.json"]: file_path = self.osutils.joinpath(self.source_dir, filename) if self.osutils.file_exists(file_path): LOG.debug("%s copying in: %s", filename, self.artifacts_dir) self.osutils.copy_file(file_path, self.artifacts_dir) except OSError as ex: raise ActionFailedError(str(ex))
def _run_external_esbuild_in_nodejs(self, script): """ Run esbuild in a separate process through Node.js Workaround for https://github.com/evanw/esbuild/issues/1958 :type script: str :param script: Node.js script to execute :raises lambda_builders.actions.ActionFailedError: when esbuild packaging fails """ with NamedTemporaryFile(dir=self.scratch_dir, mode="w") as tmp: tmp.write(script) tmp.flush() try: self.subprocess_nodejs.run([tmp.name], cwd=self.scratch_dir) except EsbuildExecutionError as ex: raise ActionFailedError(str(ex))
def execute(self): """ Runs the action. :raises lambda_builders.actions.ActionFailedError: when NPM execution fails """ try: LOG.debug("NODEJS installing in: %s", self.artifacts_dir) self.subprocess_npm.run([ "install", "-q", "--no-audit", "--no-save", "--production", "--unsafe-perm" ], cwd=self.artifacts_dir) except NpmExecutionError as ex: raise ActionFailedError(str(ex))
def execute(self): os_utils = OSUtils() python_path = self.binaries[self.LANGUAGE].binary_path pip = SubprocessPip(osutils=os_utils, python_exe=python_path) pip_runner = PipRunner(python_exe=python_path, pip=pip) dependency_builder = DependencyBuilder(osutils=os_utils, pip_runner=pip_runner, runtime=self.runtime) package_builder = PythonPipDependencyBuilder(osutils=os_utils, runtime=self.runtime, dependency_builder=dependency_builder) try: package_builder.build_dependencies( self.artifacts_dir, self.manifest_path, self.scratch_dir ) except PackagerError as ex: raise ActionFailedError(str(ex))