diff --git a/cli/classes/generated/definitions.py b/cli/classes/generated/definitions.py index a6bf00ba..072b9713 100644 --- a/cli/classes/generated/definitions.py +++ b/cli/classes/generated/definitions.py @@ -116,23 +116,23 @@ class Author(RootModel): root: Union[str, ContactData] = Field(..., description='The author of the windfile.', title='Author') -class ExternalAction(BaseModel): +class FileAction(BaseModel): """ - External action that can be executed with or without parameters. + Action that is defined in a file. """ model_config = ConfigDict( extra='forbid', ) name: str = Field(..., description='The name of the action.', examples=['rust-exercise-jobs']) - use: str = Field(..., description='The name of the external action.', title='Name of the external action.') + file: str = Field(..., description='The file that contains the action.') parameters: Optional[Parameters] = None excludeDuring: Optional[List[Lifecycle]] = Field( None, description='Exclude this action during the specified parts of the lifetime of an exercise.', title='Exclude during', ) - environment: Optional[Environment] = Field(None, description='Environment variables for this external action.') + environment: Optional[Environment] = Field(None, description='Environment variables for this file action.') platform: Optional[Target] = Field( None, description="The platform that this action is defined for. If it's not set, the action is defined for all platforms.", @@ -141,67 +141,67 @@ class ExternalAction(BaseModel): runAlways: Optional[bool] = Field( False, description='If this is set to true, the action is always executed, even if other actions fail.' ) - workdir: Optional[str] = Field( - None, description='The working directory of the external action.', examples=['tests'] - ) + workdir: Optional[str] = Field(None, description='The working directory of the file action.', examples=['tests']) results: Optional[List[Result]] = Field( None, description='The results of the action. For the CI system to keep/publish.' ) -class FileAction(BaseModel): +class PlatformAction(BaseModel): """ - Action that is defined in a file. + Action that is defined for a specific platform. """ model_config = ConfigDict( extra='forbid', ) name: str = Field(..., description='The name of the action.', examples=['rust-exercise-jobs']) - file: str = Field(..., description='The file that contains the action.') + file: Optional[str] = Field(None, description='The file of the platform action. Written in Python') parameters: Optional[Parameters] = None + function: Optional[constr(pattern=r'^[a-zA-Z0-9._-]+$')] = Field( + 'run', description='The function of the platform action.', examples=['run'] + ) excludeDuring: Optional[List[Lifecycle]] = Field( None, description='Exclude this action during the specified parts of the lifetime of an exercise.', title='Exclude during', ) - environment: Optional[Environment] = Field(None, description='Environment variables for this file action.') - platform: Optional[Target] = Field( - None, - description="The platform that this action is defined for. If it's not set, the action is defined for all platforms.", - ) + environment: Optional[Environment] = Field(None, description='Environment variables for this platform action.') + platform: Optional[Target] = Field(None, description='Ignored for this action.') + kind: Optional[str] = Field(None, description='The kind of the platform action.', examples=['junit']) docker: Optional[Docker] = Field(None, description='The docker configuration that is used to execute the action') runAlways: Optional[bool] = Field( False, description='If this is set to true, the action is always executed, even if other actions fail.' ) - workdir: Optional[str] = Field(None, description='The working directory of the file action.', examples=['tests']) + workdir: Optional[str] = Field( + None, description='The working directory of the platform action.', examples=['tests'] + ) results: Optional[List[Result]] = Field( None, description='The results of the action. For the CI system to keep/publish.' ) -class PlatformAction(BaseModel): +class ScriptAction(BaseModel): """ - Action that is defined for a specific platform. + Internally defined action that can be executed. """ model_config = ConfigDict( extra='forbid', ) name: str = Field(..., description='The name of the action.', examples=['rust-exercise-jobs']) - file: Optional[str] = Field(None, description='The file of the platform action. Written in Python') - parameters: Optional[Parameters] = None - function: Optional[constr(pattern=r'^[a-zA-Z0-9._-]+$')] = Field( - 'run', description='The function of the platform action.', examples=['run'] - ) + script: str = Field(..., description='The script of the internal action. Written in aeolus DSL') excludeDuring: Optional[List[Lifecycle]] = Field( None, description='Exclude this action during the specified parts of the lifetime of an exercise.', title='Exclude during', ) - environment: Optional[Environment] = Field(None, description='Environment variables for this platform action.') - platform: Optional[Target] = Field(None, description='Ignored for this action.') - kind: Optional[str] = Field(None, description='The kind of the platform action.', examples=['junit']) + parameters: Optional[Parameters] = None + environment: Optional[Environment] = Field(None, description='Environment variables for this internal action.') + platform: Optional[Target] = Field( + None, + description="The platform that this action is defined for. If it's not set, the action is defined for all platforms.", + ) docker: Optional[Docker] = Field(None, description='The docker configuration that is used to execute the action') runAlways: Optional[bool] = Field( False, description='If this is set to true, the action is always executed, even if other actions fail.' @@ -214,23 +214,23 @@ class PlatformAction(BaseModel): ) -class ScriptAction(BaseModel): +class TemplateAction(BaseModel): """ - Internally defined action that can be executed. + Template action that can be executed with or without parameters. """ model_config = ConfigDict( extra='forbid', ) name: str = Field(..., description='The name of the action.', examples=['rust-exercise-jobs']) - script: str = Field(..., description='The script of the internal action. Written in aeolus DSL') + use: str = Field(..., description='The name of the template action.', title='Name of the template action.') + parameters: Optional[Parameters] = None excludeDuring: Optional[List[Lifecycle]] = Field( None, description='Exclude this action during the specified parts of the lifetime of an exercise.', title='Exclude during', ) - parameters: Optional[Parameters] = None - environment: Optional[Environment] = Field(None, description='Environment variables for this internal action.') + environment: Optional[Environment] = Field(None, description='Environment variables for this template action.') platform: Optional[Target] = Field( None, description="The platform that this action is defined for. If it's not set, the action is defined for all platforms.", @@ -240,7 +240,7 @@ class ScriptAction(BaseModel): False, description='If this is set to true, the action is always executed, even if other actions fail.' ) workdir: Optional[str] = Field( - None, description='The working directory of the platform action.', examples=['tests'] + None, description='The working directory of the template action.', examples=['tests'] ) results: Optional[List[Result]] = Field( None, description='The results of the action. For the CI system to keep/publish.' @@ -285,7 +285,7 @@ class WindfileMetadata(BaseModel): class Action(RootModel): - root: Union[FileAction, ScriptAction, PlatformAction, ExternalAction] = Field( + root: Union[FileAction, ScriptAction, PlatformAction, TemplateAction] = Field( ..., description='Action that can be executed.', title='Action' ) diff --git a/cli/classes/merger.py b/cli/classes/merger.py index 600d3ac9..662cba56 100644 --- a/cli/classes/merger.py +++ b/cli/classes/merger.py @@ -18,7 +18,7 @@ Environment, PlatformAction, FileAction, - ExternalAction, + TemplateAction, ScriptAction, Docker, ) @@ -33,7 +33,7 @@ get_external_actions, get_file_actions, Validator, - get_internal_actions_with_names, + get_script_actions_with_names, ) from cli_utils import logger, utils from cli_utils.utils import get_content_of, get_path_to_file, file_exists @@ -124,8 +124,8 @@ def merge_script_actions(self) -> bool: """ if self.windfile is None: return False - logger.info("🏠 ", "Merging internal actions", self.output_settings.emoji) - actions: List[tuple[str, Action]] = get_internal_actions_with_names(self.windfile) + logger.info("🏠 ", "Merging script actions", self.output_settings.emoji) + actions: List[tuple[str, Action]] = get_script_actions_with_names(self.windfile) for action in actions: index: int = [i for i, item in enumerate(self.windfile.actions) if action[0] == item.root.name][0] merge_docker(self.windfile.metadata.docker, self.windfile.actions[index]) @@ -178,7 +178,7 @@ def set_original_types(self, names: List[str], key: str) -> None: ) def pull_external_action( - self, action: ExternalAction + self, action: TemplateAction ) -> Optional[typing.Tuple[typing.List[str], typing.List[Action]]]: """ Pulls the given external action from GitHub/or other GIT hostings and converts it to internal actions. @@ -283,14 +283,14 @@ def traverse_external_actions( if isinstance(action, PlatformAction): if path is None: converted = ([name], [Action(root=action)]) - elif isinstance(action, ExternalAction): + elif isinstance(action, TemplateAction): path = action.use if path: converted = self.convert_external_action_to_internal( external_file=path, action=action, ) - if not converted and isinstance(action, ExternalAction): + if not converted and isinstance(action, TemplateAction): # try to pull the action from GitHub converted = self.pull_external_action(action=action) if not converted: @@ -393,7 +393,7 @@ def convert_actionfile_to_script_actions( for internals in actionfile.steps: internal: Optional[Action] = None content: Optional[str] = None - if isinstance(internals.root, ExternalAction): + if isinstance(internals.root, TemplateAction): logger.error( "❌ ", "external actions in an external action are not supported yet", @@ -473,7 +473,7 @@ def convert_actionfile_to_script_actions( def convert_external_action_to_internal( self, external_file: str, - action: ExternalAction | FileAction | PlatformAction | Action, + action: TemplateAction | FileAction | PlatformAction | Action, ) -> Optional[typing.Tuple[typing.List[str], typing.List[Action]]]: """ Converts the given external action to an internal action. For @@ -511,7 +511,7 @@ def convert_external_action_to_internal( ) original_types.append("file") actions.append(internal_action) - if isinstance(action, ExternalAction): + if isinstance(action, TemplateAction): logger.info( "📄 ", f"reading external action {absolute_path}", diff --git a/cli/classes/validator.py b/cli/classes/validator.py index f5d1b00a..f3cdce87 100644 --- a/cli/classes/validator.py +++ b/cli/classes/validator.py @@ -10,7 +10,7 @@ from classes.generated.actionfile import ActionFile from classes.generated.definitions import ( Action, - ExternalAction, + TemplateAction, FileAction, ScriptAction, PlatformAction, @@ -30,7 +30,7 @@ def has_external_actions(windfile: WindFile) -> bool: :return: True if the windfile contains external actions, False otherwise """ for action in windfile.actions: - if isinstance(action.root, ExternalAction): + if isinstance(action.root, TemplateAction): return True return False @@ -43,7 +43,7 @@ def get_external_actions( :param windfile: WindFile to analyze :return: List of external actions in the given windfile """ - return get_actions_of_type(action_type=ExternalAction, windfile=windfile) + return get_actions_of_type(action_type=TemplateAction, windfile=windfile) def get_platform_actions( @@ -90,11 +90,11 @@ def get_file_actions( return get_actions_of_type(action_type=FileAction, windfile=windfile) -def get_internal_actions_with_names( +def get_script_actions_with_names( windfile: typing.Optional[WindFile], ) -> typing.List[typing.Tuple[str, Action]]: """ - Returns a list of all internal actions in the given windfile with their names. + Returns a list of all script actions in the given windfile with their names. :param windfile: Windfile to analyze :return: List of actions in the given windfile """ @@ -103,17 +103,17 @@ def get_internal_actions_with_names( def get_actions( windfile: WindFile, -) -> typing.List[ScriptAction | ExternalAction | FileAction | PlatformAction]: +) -> typing.List[ScriptAction | TemplateAction | FileAction | PlatformAction]: """ Returns a list of all actions in the given windfile. :param windfile: Windfile to analyze :return: List of actions """ - actions: typing.List[ScriptAction | ExternalAction | FileAction | PlatformAction] = [] + actions: typing.List[ScriptAction | TemplateAction | FileAction | PlatformAction] = [] for action in windfile.actions: if isinstance(action.root, ScriptAction): actions.append(action.root) - elif isinstance(action.root, ExternalAction): + elif isinstance(action.root, TemplateAction): actions.append(action.root) elif isinstance(action.root, FileAction): actions.append(action.root) diff --git a/cli/cli_utils/utils.py b/cli/cli_utils/utils.py index e38b7bb6..8949cda9 100644 --- a/cli/cli_utils/utils.py +++ b/cli/cli_utils/utils.py @@ -18,7 +18,7 @@ ScriptAction, FileAction, PlatformAction, - ExternalAction, + TemplateAction, ) from classes.generated.environment import EnvironmentSchema from classes.generated.windfile import WindFile @@ -339,7 +339,7 @@ def clean_up(windfile: WindFile, output_settings: OutputSettings) -> None: """ combine_docker_config(windfile=windfile, output_settings=output_settings) for index, _ in enumerate(windfile.actions): - root_action: FileAction | ScriptAction | PlatformAction | ExternalAction = windfile.actions[index].root + root_action: FileAction | ScriptAction | PlatformAction | TemplateAction = windfile.actions[index].root if root_action.environment is not None and len(root_action.environment.root.root) == 0: root_action.environment = None if root_action.parameters is not None and len(root_action.parameters.root.root) == 0: diff --git a/cli/templates/Jenkinsfile.j2 b/cli/templates/Jenkinsfile.j2 index 3b3f6d11..a5a509e8 100644 --- a/cli/templates/Jenkinsfile.j2 +++ b/cli/templates/Jenkinsfile.j2 @@ -99,12 +99,12 @@ pipeline { {%- if step.workdir %} dir('{{ step.workdir }}') { sh ''' - {{ step.script }} + {{ step.script | indent(12, false) }} ''' } {%- else %} sh ''' - {{ step.script }} + {{ step.script | indent(12, false) }} ''' {%- endif %} } @@ -120,12 +120,12 @@ pipeline { {%- if action.workdir %} dir('{{ action.workdir }}') { sh ''' - {{ action.script }} + {{ action.script | indent(8, false) }} ''' } {%- else %} sh ''' - {{ action.script }} + {{ action.script | indent(6, false) }} ''' {%- endif %} } diff --git a/cli/templates/cli.sh.j2 b/cli/templates/cli.sh.j2 index 8737b5e0..1d05369b 100644 --- a/cli/templates/cli.sh.j2 +++ b/cli/templates/cli.sh.j2 @@ -48,7 +48,7 @@ export {{ env_var }}="{{ environment[env_var] }}" cp -a ${_sources} {{ metadata.moveResultsTo }}/${_directory} {%- endfor -%} {%- endif -%} - {{ step.script }} + {{ step.script | indent(2, false) }} {%- if metadata.moveResultsTo %} cd {{ initial_directory }} mkdir -p {{ metadata.moveResultsTo }} diff --git a/cli/test/test_merge.py b/cli/test/test_merge.py index 4cfc9947..1f3768c0 100644 --- a/cli/test/test_merge.py +++ b/cli/test/test_merge.py @@ -11,7 +11,7 @@ VALID_WINDFILE_WITH_NON_EXISTING_ACTIONFILE, VALID_WINDFILE_WITH_FILEACTION, ) -from classes.generated.definitions import FileAction, PlatformAction, ExternalAction, ScriptAction +from classes.generated.definitions import FileAction, PlatformAction, TemplateAction, ScriptAction from classes.generated.windfile import WindFile from classes.input_settings import InputSettings from classes.merger import Merger @@ -47,7 +47,7 @@ def test_merge_no_external_actions(self) -> None: self.assertEqual(len(index), 1) self.assertTrue(isinstance(windfile.actions[index[0]].root, ScriptAction)) if isinstance(windfile.actions[index[0]].root, ScriptAction): - action: FileAction | ScriptAction | PlatformAction | ExternalAction = windfile.actions[index[0]].root + action: FileAction | ScriptAction | PlatformAction | TemplateAction = windfile.actions[index[0]].root self.assertTrue(isinstance(action, ScriptAction)) if isinstance(action, ScriptAction): self.assertEqual(action.script, 'echo "This is an internal action"') @@ -111,7 +111,7 @@ def test_merge_with_external_actions(self) -> None: index: list[int] = [i for i, item in enumerate(windfile.actions) if name == item.root.name] self.assertEqual(len(index), 1) actual_index: int = index[0] - action: FileAction | ScriptAction | PlatformAction | ExternalAction = windfile.actions[ + action: FileAction | ScriptAction | PlatformAction | TemplateAction = windfile.actions[ actual_index ].root self.assertTrue(isinstance(action, ScriptAction)) @@ -151,7 +151,7 @@ def test_merge_with_file_action(self) -> None: index: list[int] = [i for i, item in enumerate(windfile.actions) if "file-action_0" == item.root.name] self.assertEqual(len(index), 1) self.assertTrue(isinstance(windfile.actions[index[0]].root, ScriptAction)) - action: FileAction | ScriptAction | PlatformAction | ExternalAction = windfile.actions[index[0]].root + action: FileAction | ScriptAction | PlatformAction | TemplateAction = windfile.actions[index[0]].root if isinstance(action, ScriptAction): self.assertEqual(action.script, content) if action.excludeDuring is None: diff --git a/schemas/v0.0.1/schemas/definitions.json b/schemas/v0.0.1/schemas/definitions.json index 689972b1..e4faf71b 100644 --- a/schemas/v0.0.1/schemas/definitions.json +++ b/schemas/v0.0.1/schemas/definitions.json @@ -184,7 +184,7 @@ "$ref": "#/platform-action" }, { - "$ref": "#/external-action" + "$ref": "#/template-action" } ] }, @@ -406,9 +406,9 @@ "script" ] }, - "external-action": { - "title": "External Action", - "description": "External action that can be executed with or without parameters.", + "template-action": { + "title": "Template Action", + "description": "Template action that can be executed with or without parameters.", "type": "object", "additionalProperties": false, "properties": { @@ -420,8 +420,8 @@ ] }, "use": { - "description": "The name of the external action.", - "title": "Name of the external action.", + "description": "The name of the template action.", + "title": "Name of the template action.", "type": "string" }, "parameters": { @@ -436,7 +436,7 @@ } }, "environment": { - "description": "Environment variables for this external action.", + "description": "Environment variables for this template action.", "$ref": "#/environment" }, "platform": { @@ -453,7 +453,7 @@ "default": false }, "workdir": { - "description": "The working directory of the external action.", + "description": "The working directory of the template action.", "type": "string", "examples": [ "tests"