From 049548c2caf699f0baec1af4d57661bd261eea1b Mon Sep 17 00:00:00 2001 From: Mai Morag <81917647+maimorag@users.noreply.github.com> Date: Thu, 19 Dec 2024 17:59:34 +0200 Subject: [PATCH 1/6] adding another option for path check (#4717) * adding another option for path check * fix * fix * fix * fix * Update .changelog/4717.yml Co-authored-by: Adi Bamberger Edri <72088126+BEAdi@users.noreply.github.com> * Update demisto_sdk/commands/validate/validators/RM_validators/RM114_is_image_exists_in_readme.py Co-authored-by: Adi Bamberger Edri <72088126+BEAdi@users.noreply.github.com> * fix * fix * fix * fix * fix * adding unit test --------- Co-authored-by: Adi Bamberger Edri <72088126+BEAdi@users.noreply.github.com> --- .changelog/4717.yml | 4 +++ .../validate/tests/RM_validators_test.py | 36 +++++++++++++++++++ .../RM114_is_image_exists_in_readme.py | 6 +++- 3 files changed, 45 insertions(+), 1 deletion(-) create mode 100644 .changelog/4717.yml diff --git a/.changelog/4717.yml b/.changelog/4717.yml new file mode 100644 index 00000000000..a0ef5247a10 --- /dev/null +++ b/.changelog/4717.yml @@ -0,0 +1,4 @@ +changes: +- description: Fixed an issue where RM114 falsely failed when it concatenated "Packs/" twice to the file path. + type: fix +pr_number: 4717 diff --git a/demisto_sdk/commands/validate/tests/RM_validators_test.py b/demisto_sdk/commands/validate/tests/RM_validators_test.py index 2736b877a48..3554bb51ddc 100644 --- a/demisto_sdk/commands/validate/tests/RM_validators_test.py +++ b/demisto_sdk/commands/validate/tests/RM_validators_test.py @@ -2,6 +2,7 @@ import more_itertools import pytest +from click.exceptions import BadParameter from demisto_sdk.commands.common.tools import find_pack_folder from demisto_sdk.commands.validate.tests.test_tools import ( @@ -343,6 +344,41 @@ def test_IsImageExistsInReadmeValidator_obtain_invalid_content_items( ) +def test_IsImageExistsInReadmeValidator_invalid_image_paths(mocker): + """ + Given: + - A pack name and a list of image paths, some with a missing prefix and others already valid. + When: + - Running the `get_invalid_image_paths` function to validate image paths. + Then: + - Ensure that initially invalid paths are identified. + - Ensure that removing the prefix allows paths to be validated successfully. + """ + import click + + pack_name = "MyPack" + image_paths = [ + "../doc_files/valid_image.png", # Will be valid after adding prefix + ] + + # Mocking click.Path.convert to simulate file validation + def mock_first_convert(path, param, ctx): + # Simulate failed validation for all paths during second call + raise BadParameter + + def mock_second_convert(path, param, ctx): + # Simulate successful validation for all paths during second call + pass + + mocker.patch.object( + click.Path, "convert", side_effect=[mock_first_convert, mock_second_convert] + ) + invalid_paths = IsImageExistsInReadmeValidator.get_invalid_image_paths( + pack_name, image_paths + ) + assert not invalid_paths + + def test_IsPackReadmeNotEqualPackDescriptionValidator_not_valid(): """ Given: diff --git a/demisto_sdk/commands/validate/validators/RM_validators/RM114_is_image_exists_in_readme.py b/demisto_sdk/commands/validate/validators/RM_validators/RM114_is_image_exists_in_readme.py index 9610840b862..92b9ca3590e 100644 --- a/demisto_sdk/commands/validate/validators/RM_validators/RM114_is_image_exists_in_readme.py +++ b/demisto_sdk/commands/validate/validators/RM_validators/RM114_is_image_exists_in_readme.py @@ -76,6 +76,10 @@ def get_invalid_image_paths(pack_name: str, image_paths: List[str]) -> List[str] path_validate.convert(image_path, param=None, ctx=None) except click.exceptions.BadParameter: - invalid_image_paths.append(image_path) + try: + alternative_path = image_path.removeprefix("Packs/") + path_validate.convert(alternative_path, param=None, ctx=None) + except click.exceptions.BadParameter: + invalid_image_paths.append(image_path) return invalid_image_paths From fc297e2fab9e6525073973cc486cfd7e09a758a5 Mon Sep 17 00:00:00 2001 From: Moshe Galitzky <112559840+moishce@users.noreply.github.com> Date: Fri, 20 Dec 2024 00:52:44 +0200 Subject: [PATCH 2/6] Exclude silent items from release notes validation (#4720) * fixed pre-commit * added changelog * added unittest case --- .changelog/4720.yml | 4 ++++ demisto_sdk/commands/validate/tests/RN_validators_test.py | 8 ++++++-- demisto_sdk/commands/validate/tools.py | 3 +++ 3 files changed, 13 insertions(+), 2 deletions(-) create mode 100644 .changelog/4720.yml diff --git a/.changelog/4720.yml b/.changelog/4720.yml new file mode 100644 index 00000000000..49d2de2cf09 --- /dev/null +++ b/.changelog/4720.yml @@ -0,0 +1,4 @@ +changes: +- description: Exclude silent items from release notes validation. + type: feature +pr_number: 4720 diff --git a/demisto_sdk/commands/validate/tests/RN_validators_test.py b/demisto_sdk/commands/validate/tests/RN_validators_test.py index 3eeee229a56..3c80097ef2e 100644 --- a/demisto_sdk/commands/validate/tests/RN_validators_test.py +++ b/demisto_sdk/commands/validate/tests/RN_validators_test.py @@ -547,7 +547,7 @@ def mock_is_missing_rn_validator(mocker): ]: mocker.patch( f"demisto_sdk.commands.validate.validators.RN_validators.{rn_validator}.should_skip_rn_check", - side_effect=lambda c: isinstance(c, TestPlaybook), + side_effect=lambda c: isinstance(c, TestPlaybook) or c.is_silent, ) mocker.patch( f"demisto_sdk.commands.validate.validators.RN_validators.{rn_validator}.was_rn_added", @@ -691,7 +691,7 @@ def test_IsMissingReleaseNotes_for_api_module_dependents( def test_IsMissingReleaseNoteEntries(mock_is_missing_rn_validator): """ Given: - - pack1 with a modified integration, a RM entry exists + - pack1 with a modified integration and silent playbook, a RN entry exists only for the integration - pack2 with modified script, playbook and TPB, a RN entry exists only for the script - pack3 with a modified script, a RN file does not exist - pack4 with a new mapper, a RN exists @@ -709,6 +709,9 @@ def test_IsMissingReleaseNoteEntries(mock_is_missing_rn_validator): release_note_content=f"#### Integrations\n##### {integ.display_name}\n- Added x y z", ) integ.pack = pack1 + silent_playbook = create_playbook_object() + silent_playbook.is_silent = True + silent_playbook.pack = pack1 script1 = create_script_object() playbook = create_playbook_object() @@ -740,6 +743,7 @@ def test_IsMissingReleaseNoteEntries(mock_is_missing_rn_validator): content_items = [ pack1, integ, + silent_playbook, pack2, script1, playbook, diff --git a/demisto_sdk/commands/validate/tools.py b/demisto_sdk/commands/validate/tools.py index bdf0cdebb39..7a7a6ef6d52 100644 --- a/demisto_sdk/commands/validate/tools.py +++ b/demisto_sdk/commands/validate/tools.py @@ -270,6 +270,7 @@ def should_skip_rn_check(content_item: ContentItem) -> bool: - A modeling rule is considered modified if its XIF and schema files are modified - A movement between packs is considered a modification - Test content items shouldn't have RNs + - Silent content items shouldn't have RNs Args: content_item (ContentItem): A content item object @@ -279,6 +280,8 @@ def should_skip_rn_check(content_item: ContentItem) -> bool: """ if isinstance(content_item, (TestPlaybook, TestScript)): return True + if content_item.is_silent: + return True if isinstance(content_item, Integration): return ( not content_item.git_status and not content_item.description_file.git_status From 019501fa9721db790e0778d0fe6f332275110602 Mon Sep 17 00:00:00 2001 From: Moshe Galitzky <112559840+moishce@users.noreply.github.com> Date: Sun, 22 Dec 2024 10:38:02 +0200 Subject: [PATCH 3/6] Validate silent-Playbook and silent-trigger relationships (#4670) * added pb131 * added rn * fixed pre-commit * fixed cr comments * fixed pre-commit * fixed pre-commit * changed to use is_silent property * changed to use is_silent property * fixed test --- .changelog/4670.yml | 4 + .../validate/sdk_validation_config.toml | 2 + .../validate/tests/PB_validators_test.py | 159 ++++++++++++++++++ .../PB131_is_silent_playbook_relationships.py | 69 ++++++++ 4 files changed, 234 insertions(+) create mode 100644 .changelog/4670.yml create mode 100644 demisto_sdk/commands/validate/validators/PB_validators/PB131_is_silent_playbook_relationships.py diff --git a/.changelog/4670.yml b/.changelog/4670.yml new file mode 100644 index 00000000000..c1ca05a48be --- /dev/null +++ b/.changelog/4670.yml @@ -0,0 +1,4 @@ +changes: +- description: Added validation to ensure every silent trigger points to a silent playbook, and vice versa. + type: feature +pr_number: 4670 diff --git a/demisto_sdk/commands/validate/sdk_validation_config.toml b/demisto_sdk/commands/validate/sdk_validation_config.toml index 0eda35e9e2f..68fdf2e4b3e 100644 --- a/demisto_sdk/commands/validate/sdk_validation_config.toml +++ b/demisto_sdk/commands/validate/sdk_validation_config.toml @@ -146,6 +146,7 @@ select = [ "PB126", "PB127", "PB130", + "PB131", "PB114", "BA100", "BA101", @@ -334,6 +335,7 @@ select = [ "PB119", "PB127", "PB130", + "PB131", "BC100", "BC101", "BC102", diff --git a/demisto_sdk/commands/validate/tests/PB_validators_test.py b/demisto_sdk/commands/validate/tests/PB_validators_test.py index 8abe89cd109..78d227b4fe0 100644 --- a/demisto_sdk/commands/validate/tests/PB_validators_test.py +++ b/demisto_sdk/commands/validate/tests/PB_validators_test.py @@ -1,9 +1,13 @@ import pytest from demisto_sdk.commands.content_graph.objects.base_playbook import TaskConfig +from demisto_sdk.commands.content_graph.objects.pack_content_items import ( + PackContentItems, +) from demisto_sdk.commands.content_graph.objects.playbook import Playbook from demisto_sdk.commands.validate.tests.test_tools import ( create_playbook_object, + create_trigger_object, ) from demisto_sdk.commands.validate.validators.PB_validators.PB100_is_no_rolename import ( IsNoRolenameValidator, @@ -66,6 +70,9 @@ from demisto_sdk.commands.validate.validators.PB_validators.PB130_is_silent_playbook import ( IsSilentPlaybookValidator, ) +from demisto_sdk.commands.validate.validators.PB_validators.PB131_is_silent_playbook_relationships import ( + IsSilentPlaybookRelationshipsValidator, +) @pytest.mark.parametrize( @@ -1423,3 +1430,155 @@ def test_IsSilentPlaybookValidator(name, id, is_silent, result_len): [playbook] ) assert result_len == len(invalid_content_items) + + +class Pack: + content_items = PackContentItems() + + +@pytest.mark.parametrize( + "playbook_id, playbook_is_silent, trigger_playbook_id, trigger_is_silent, result_len", + [ + ( + "test", + True, + "test", + False, + 1, + ), + ( + "test", + True, + "test", + True, + 0, + ), + ( + "test1", + True, + "test2", + False, + 1, + ), + ( + "test1", + True, + "test2", + True, + 1, + ), + ( + "test1", + False, + "test1", + True, + 0, + ), + ], +) +def test_IsSilentPlaybookRelationshipsValidator( + playbook_id, playbook_is_silent, trigger_playbook_id, trigger_is_silent, result_len +): + """ + Given: + - case 1: A silent trigger that points on a non-silent playbook. + - case 2: A silent trigger that points on a silent playbook. + - case 3: A silent trigger that points on a non-silent playbook that is not found. + - case 4: A silent trigger that points on a silent playbook that is not found. + - case 5: A non-silent trigger that points on a silent playbook. + When: + - Calling IsSilentPlaybookRelationshipsValidator for playbooks. + Then: + - Validate that only invalid items are returned. + """ + playbook_item = create_playbook_object() + playbook_item.pack = Pack() + playbook_item.pack.content_items.trigger.extend([create_trigger_object()]) + + playbook_item.data["id"] = playbook_id + playbook_item.is_silent = playbook_is_silent + + playbook_item.pack.content_items.trigger[0].data["playbook_id"] = ( + trigger_playbook_id + ) + playbook_item.pack.content_items.trigger[0].is_silent = trigger_is_silent + + invalid_content_items = ( + IsSilentPlaybookRelationshipsValidator().obtain_invalid_content_items( + [playbook_item] + ) + ) + assert result_len == len(invalid_content_items) + + +@pytest.mark.parametrize( + "trigger_playbook_id, trigger_is_silent, playbook_id, playbook_is_silent, result_len", + [ + ( + "test", + True, + "test", + False, + 1, + ), + ( + "test", + True, + "test", + True, + 0, + ), + ( + "test1", + True, + "test2", + False, + 1, + ), + ( + "test1", + True, + "test2", + True, + 1, + ), + ( + "test1", + False, + "test1", + True, + 0, + ), + ], +) +def test_IsSilentTriggerRelationshipsValidator( + trigger_playbook_id, trigger_is_silent, playbook_id, playbook_is_silent, result_len +): + """ + Given: + - case 1: A silent playbook that corresponds to a non-silent trigger. + - case 2: A silent playbook that corresponds to a silent trigger. + - case 3: A silent playbook that corresponds to a non-silent trigger that is not found. + - case 4: A silent playbook that corresponds to a silent trigger that is not found. + - case 5: A non-silent playbook that corresponds to a silent trigger. + When: + - Calling IsSilentPlaybookRelationshipsValidator for playbooks. + Then: + - Validate that only invalid items are returned. + """ + trigger_item = create_trigger_object() + trigger_item.pack = Pack() + trigger_item.pack.content_items.playbook.extend([create_playbook_object()]) + + trigger_item.data["playbook_id"] = trigger_playbook_id + trigger_item.is_silent = trigger_is_silent + + trigger_item.pack.content_items.playbook[0].data["id"] = playbook_id + trigger_item.pack.content_items.playbook[0].is_silent = playbook_is_silent + + invalid_content_items = ( + IsSilentPlaybookRelationshipsValidator().obtain_invalid_content_items( + [trigger_item] + ) + ) + assert result_len == len(invalid_content_items) diff --git a/demisto_sdk/commands/validate/validators/PB_validators/PB131_is_silent_playbook_relationships.py b/demisto_sdk/commands/validate/validators/PB_validators/PB131_is_silent_playbook_relationships.py new file mode 100644 index 00000000000..d970c3809cc --- /dev/null +++ b/demisto_sdk/commands/validate/validators/PB_validators/PB131_is_silent_playbook_relationships.py @@ -0,0 +1,69 @@ +from __future__ import annotations + +from typing import Iterable, List, Union + +from demisto_sdk.commands.content_graph.common import ContentType +from demisto_sdk.commands.content_graph.objects.content_item import ContentItem +from demisto_sdk.commands.content_graph.objects.playbook import Playbook +from demisto_sdk.commands.content_graph.objects.trigger import Trigger +from demisto_sdk.commands.validate.validators.base_validator import ( + BaseValidator, + ValidationResult, +) + +ContentTypes = Union[Playbook, Trigger] + + +class IsSilentPlaybookRelationshipsValidator(BaseValidator[ContentTypes]): + error_code = "PB131" + description = "Every silent trigger must correspond to a silent playbook in the same pack, and vice versa." + rationale = "To ensure the effective operation of the silent playbook items." + error_message = ( + "The {} is silent, but does not correspond to a silent {} in the pack." + ) + related_field = "isSilent" + is_auto_fixable = False + + def obtain_invalid_content_items( + self, content_items: Iterable[ContentTypes] + ) -> List[ValidationResult]: + def get_types_for_err_msg(c: ContentItem) -> tuple[ContentType, ContentType]: + if isinstance(c, Trigger): + return ContentType.TRIGGER, ContentType.PLAYBOOK + return ContentType.PLAYBOOK, ContentType.TRIGGER + + return [ + ValidationResult( + validator=self, + message=self.error_message.format(*get_types_for_err_msg(content_item)), + content_object=content_item, + ) + for content_item in content_items + if not is_valid_relationship(content_item) + ] + + +def is_valid_relationship(content_item: ContentTypes) -> bool: + """ + Validates the relationship between a content item and its associated playbook/trigger. + """ + if not content_item.is_silent: + # If the content item is not marked as silent, it's automatically valid + return True + + if content_item.content_type == ContentType.PLAYBOOK: + return any( + trigger.data.get("playbook_id") == content_item.data.get("id") + and trigger.is_silent + for trigger in content_item.pack.content_items.trigger + ) + + if content_item.content_type == ContentType.TRIGGER: + return any( + playbook.data.get("id") == content_item.data.get("playbook_id") + and playbook.is_silent + for playbook in content_item.pack.content_items.playbook + ) + + # Default case if content type is not PLAYBOOK or TRIGGER + return True From 8b3429dc31abd00e442b926def118a4db7da2cb8 Mon Sep 17 00:00:00 2001 From: Moshe Galitzky <112559840+moishce@users.noreply.github.com> Date: Sun, 22 Dec 2024 16:31:00 +0200 Subject: [PATCH 4/6] Validate silent-Playbook do not have a README file (#4723) * added silent readme check * added silent readme check * added test and fixed rm109 rm116 * added changelog * Update .changelog/4723.yml Co-authored-by: Dan Tavori <38749041+dantavori@users.noreply.github.com> * Update demisto_sdk/commands/validate/validators/PB_validators/PB132_no_readme_for_silent_playbook.py Co-authored-by: Dan Tavori <38749041+dantavori@users.noreply.github.com> * Update demisto_sdk/commands/validate/validators/PB_validators/PB132_no_readme_for_silent_playbook.py Co-authored-by: Dan Tavori <38749041+dantavori@users.noreply.github.com> * added "good" case * pre-commit --------- Co-authored-by: Dan Tavori <38749041+dantavori@users.noreply.github.com> --- .changelog/4723.yml | 4 +++ .../validate/sdk_validation_config.toml | 2 ++ .../validate/tests/PB_validators_test.py | 29 ++++++++++++++++ .../PB132_no_readme_for_silent_playbook.py | 33 +++++++++++++++++++ .../RM_validators/RM109_is_readme_exists.py | 2 +- .../RM116_missing_playbook_image.py | 7 ++-- 6 files changed, 74 insertions(+), 3 deletions(-) create mode 100644 .changelog/4723.yml create mode 100644 demisto_sdk/commands/validate/validators/PB_validators/PB132_no_readme_for_silent_playbook.py diff --git a/.changelog/4723.yml b/.changelog/4723.yml new file mode 100644 index 00000000000..13cc9255353 --- /dev/null +++ b/.changelog/4723.yml @@ -0,0 +1,4 @@ +changes: +- description: Added the **PB132** validation to ensure that silent playbooks do not have a README file. + type: feature +pr_number: 4723 diff --git a/demisto_sdk/commands/validate/sdk_validation_config.toml b/demisto_sdk/commands/validate/sdk_validation_config.toml index 68fdf2e4b3e..f1c10cba7b2 100644 --- a/demisto_sdk/commands/validate/sdk_validation_config.toml +++ b/demisto_sdk/commands/validate/sdk_validation_config.toml @@ -147,6 +147,7 @@ select = [ "PB127", "PB130", "PB131", + "PB132", "PB114", "BA100", "BA101", @@ -336,6 +337,7 @@ select = [ "PB127", "PB130", "PB131", + "PB132", "BC100", "BC101", "BC102", diff --git a/demisto_sdk/commands/validate/tests/PB_validators_test.py b/demisto_sdk/commands/validate/tests/PB_validators_test.py index 78d227b4fe0..0122c57c721 100644 --- a/demisto_sdk/commands/validate/tests/PB_validators_test.py +++ b/demisto_sdk/commands/validate/tests/PB_validators_test.py @@ -73,6 +73,9 @@ from demisto_sdk.commands.validate.validators.PB_validators.PB131_is_silent_playbook_relationships import ( IsSilentPlaybookRelationshipsValidator, ) +from demisto_sdk.commands.validate.validators.PB_validators.PB132_no_readme_for_silent_playbook import ( + NoReadmeForSilentPlaybook, +) @pytest.mark.parametrize( @@ -1582,3 +1585,29 @@ def test_IsSilentTriggerRelationshipsValidator( ) ) assert result_len == len(invalid_content_items) + + +def test_NoReadmeForSilentPlaybook(): + """ + Given: + a silent playbook with/without a readme file. + + When: + - calling NoReadmeForSilentPlaybook.obtain_invalid_content_items. + + Then: + - Checks that it fails only when there is a readme. + """ + playbook = create_playbook_object() + playbook.is_silent = True + playbook.readme.exist = True + invalid_content_items = NoReadmeForSilentPlaybook().obtain_invalid_content_items( + [playbook] + ) + assert len(invalid_content_items) == 1 + + playbook.readme.exist = False + invalid_content_items = NoReadmeForSilentPlaybook().obtain_invalid_content_items( + [playbook] + ) + assert len(invalid_content_items) == 0 diff --git a/demisto_sdk/commands/validate/validators/PB_validators/PB132_no_readme_for_silent_playbook.py b/demisto_sdk/commands/validate/validators/PB_validators/PB132_no_readme_for_silent_playbook.py new file mode 100644 index 00000000000..d0ae78cf657 --- /dev/null +++ b/demisto_sdk/commands/validate/validators/PB_validators/PB132_no_readme_for_silent_playbook.py @@ -0,0 +1,33 @@ +from __future__ import annotations + +from typing import Iterable, List + +from demisto_sdk.commands.content_graph.objects.playbook import Playbook +from demisto_sdk.commands.validate.validators.base_validator import ( + BaseValidator, + ValidationResult, +) + +ContentTypes = Playbook + + +class NoReadmeForSilentPlaybook(BaseValidator[ContentTypes]): + error_code = "PB132" + description = "A silent playbook is not allowed to have a README file." + rationale = "To ensure that silent playbooks do not appears in the documentation." + error_message = "A silent playbook is not allowed to have a README file." + related_field = "isSilent" + is_auto_fixable = False + + def obtain_invalid_content_items( + self, content_items: Iterable[ContentTypes] + ) -> List[ValidationResult]: + return [ + ValidationResult( + validator=self, + message=self.error_message, + content_object=content_item, + ) + for content_item in content_items + if content_item.is_silent and content_item.readme.exist + ] diff --git a/demisto_sdk/commands/validate/validators/RM_validators/RM109_is_readme_exists.py b/demisto_sdk/commands/validate/validators/RM_validators/RM109_is_readme_exists.py index b38d3fb7758..57aaf473533 100644 --- a/demisto_sdk/commands/validate/validators/RM_validators/RM109_is_readme_exists.py +++ b/demisto_sdk/commands/validate/validators/RM_validators/RM109_is_readme_exists.py @@ -34,5 +34,5 @@ def obtain_invalid_content_items( content_object=content_item, ) for content_item in content_items - if (not content_item.readme.exist) + if (not content_item.readme.exist) and (not content_item.is_silent) ] diff --git a/demisto_sdk/commands/validate/validators/RM_validators/RM116_missing_playbook_image.py b/demisto_sdk/commands/validate/validators/RM_validators/RM116_missing_playbook_image.py index a501ae1ec24..a7413159a92 100644 --- a/demisto_sdk/commands/validate/validators/RM_validators/RM116_missing_playbook_image.py +++ b/demisto_sdk/commands/validate/validators/RM_validators/RM116_missing_playbook_image.py @@ -30,7 +30,10 @@ def obtain_invalid_content_items( ) for content_item in content_items if ( - not content_item.image.exist - or "doc_files" not in str(content_item.image.file_path) + ( + not content_item.image.exist + or "doc_files" not in str(content_item.image.file_path) + ) + and not content_item.is_silent ) ] From 2aaa5167db10d3c70cfe1caa8cd17e69f481725b Mon Sep 17 00:00:00 2001 From: Moshe Galitzky <112559840+moishce@users.noreply.github.com> Date: Mon, 23 Dec 2024 11:14:09 +0200 Subject: [PATCH 5/6] Support for silent-playbooks in the old-validate (#4726) * fixed for silent * added changelog --- .changelog/4726.yml | 4 ++++ .../common/hook_validations/content_entity_validator.py | 2 ++ .../commands/common/hook_validations/release_notes.py | 7 +++++++ 3 files changed, 13 insertions(+) create mode 100644 .changelog/4726.yml diff --git a/.changelog/4726.yml b/.changelog/4726.yml new file mode 100644 index 00000000000..1afbe33ee17 --- /dev/null +++ b/.changelog/4726.yml @@ -0,0 +1,4 @@ +changes: +- description: Added support for Silent-Playbooks in the old-validate. + type: feature +pr_number: 4726 diff --git a/demisto_sdk/commands/common/hook_validations/content_entity_validator.py b/demisto_sdk/commands/common/hook_validations/content_entity_validator.py index a4c02fb3e7b..5e8417d3f9b 100644 --- a/demisto_sdk/commands/common/hook_validations/content_entity_validator.py +++ b/demisto_sdk/commands/common/hook_validations/content_entity_validator.py @@ -699,6 +699,8 @@ def validate_readme_exists(self, validate_all: bool = False): path_split = file_path.split(os.sep) file_type = find_type(self.file_path, _dict=self.current_file, file_type="yml") if file_type == FileType.PLAYBOOK: + if self.current_file.get("isSilent"): + return True to_replace = os.path.splitext(path_split[-1])[-1] readme_path = file_path.replace(to_replace, "_README.md") elif file_type in {FileType.SCRIPT, FileType.INTEGRATION}: diff --git a/demisto_sdk/commands/common/hook_validations/release_notes.py b/demisto_sdk/commands/common/hook_validations/release_notes.py index e99f85e17b4..9d7e0c0575a 100644 --- a/demisto_sdk/commands/common/hook_validations/release_notes.py +++ b/demisto_sdk/commands/common/hook_validations/release_notes.py @@ -216,9 +216,16 @@ def are_release_notes_complete(self): if find_type(file) in SKIP_RELEASE_NOTES_FOR_TYPES: continue + elif ( checked_file_pack_name and checked_file_pack_name == self.pack_name ): + try: + _dict, file_type = get_dict_from_file(file) + if _dict.get("isSilent"): + continue + except Exception: + pass # Refer image and description file paths to the corresponding yml files file = UpdateRN.change_image_or_desc_file_path(file) update_rn_util = UpdateRN( From ff1f24492b8c3c34ccb4b1edeacec59af4e54b1d Mon Sep 17 00:00:00 2001 From: Moshe Galitzky <112559840+moishce@users.noreply.github.com> Date: Mon, 23 Dec 2024 16:43:27 +0200 Subject: [PATCH 6/6] Changed isSilent to lower case (#4728) * changed all isSilent to lower case * added changelog --- .changelog/4728.yml | 4 ++++ .../content_entity_validator.py | 2 +- .../common/hook_validations/release_notes.py | 2 +- .../commands/common/schemas/playbook.yml | 2 +- .../commands/common/schemas/trigger.yml | 2 +- .../content_graph/parsers/json_content_item.py | 2 +- .../content_graph/parsers/yaml_content_item.py | 2 +- .../content_graph/strict_objects/playbook.py | 2 +- .../validate/tests/PB_validators_test.py | 18 +++++++++--------- .../PB_validators/PB130_is_silent_playbook.py | 10 +++++----- .../PB131_is_silent_playbook_relationships.py | 2 +- .../PB132_no_readme_for_silent_playbook.py | 2 +- .../tests/validate_deleted_files_test.py | 2 +- demisto_sdk/scripts/validate_deleted_files.py | 2 +- 14 files changed, 29 insertions(+), 25 deletions(-) create mode 100644 .changelog/4728.yml diff --git a/.changelog/4728.yml b/.changelog/4728.yml new file mode 100644 index 00000000000..37340b33b28 --- /dev/null +++ b/.changelog/4728.yml @@ -0,0 +1,4 @@ +changes: +- description: Changed the isSilent key to be lower case. + type: fix +pr_number: 4728 diff --git a/demisto_sdk/commands/common/hook_validations/content_entity_validator.py b/demisto_sdk/commands/common/hook_validations/content_entity_validator.py index 5e8417d3f9b..b5221741fa6 100644 --- a/demisto_sdk/commands/common/hook_validations/content_entity_validator.py +++ b/demisto_sdk/commands/common/hook_validations/content_entity_validator.py @@ -699,7 +699,7 @@ def validate_readme_exists(self, validate_all: bool = False): path_split = file_path.split(os.sep) file_type = find_type(self.file_path, _dict=self.current_file, file_type="yml") if file_type == FileType.PLAYBOOK: - if self.current_file.get("isSilent"): + if self.current_file.get("issilent"): return True to_replace = os.path.splitext(path_split[-1])[-1] readme_path = file_path.replace(to_replace, "_README.md") diff --git a/demisto_sdk/commands/common/hook_validations/release_notes.py b/demisto_sdk/commands/common/hook_validations/release_notes.py index 9d7e0c0575a..32e909427cc 100644 --- a/demisto_sdk/commands/common/hook_validations/release_notes.py +++ b/demisto_sdk/commands/common/hook_validations/release_notes.py @@ -222,7 +222,7 @@ def are_release_notes_complete(self): ): try: _dict, file_type = get_dict_from_file(file) - if _dict.get("isSilent"): + if _dict.get("issilent"): continue except Exception: pass diff --git a/demisto_sdk/commands/common/schemas/playbook.yml b/demisto_sdk/commands/common/schemas/playbook.yml index 54c1566d04d..011ecc2993b 100644 --- a/demisto_sdk/commands/common/schemas/playbook.yml +++ b/demisto_sdk/commands/common/schemas/playbook.yml @@ -38,7 +38,7 @@ mapping: type: bool deprecated: type: bool - isSilent: + issilent: type: bool starttaskid: type: str diff --git a/demisto_sdk/commands/common/schemas/trigger.yml b/demisto_sdk/commands/common/schemas/trigger.yml index aa2af40b084..75b60f3685c 100644 --- a/demisto_sdk/commands/common/schemas/trigger.yml +++ b/demisto_sdk/commands/common/schemas/trigger.yml @@ -16,7 +16,7 @@ mapping: description: type: str required: true - isSilent: + issilent: type: bool suggestion_reason: type: str diff --git a/demisto_sdk/commands/content_graph/parsers/json_content_item.py b/demisto_sdk/commands/content_graph/parsers/json_content_item.py index 3fa1b4a0218..a06e98d0970 100644 --- a/demisto_sdk/commands/content_graph/parsers/json_content_item.py +++ b/demisto_sdk/commands/content_graph/parsers/json_content_item.py @@ -114,4 +114,4 @@ def version(self) -> int: @property def is_silent(self) -> bool: - return get_value(self.json_data, "isSilent", False) + return get_value(self.json_data, "issilent", False) diff --git a/demisto_sdk/commands/content_graph/parsers/yaml_content_item.py b/demisto_sdk/commands/content_graph/parsers/yaml_content_item.py index 171fc76c184..2623dd84144 100644 --- a/demisto_sdk/commands/content_graph/parsers/yaml_content_item.py +++ b/demisto_sdk/commands/content_graph/parsers/yaml_content_item.py @@ -78,7 +78,7 @@ def deprecated(self) -> bool: @property def is_silent(self) -> bool: - return get_value(self.yml_data, "isSilent", False) + return get_value(self.yml_data, "issilent", False) @property def description(self) -> Optional[str]: diff --git a/demisto_sdk/commands/content_graph/strict_objects/playbook.py b/demisto_sdk/commands/content_graph/strict_objects/playbook.py index 8d83d668b69..caf3674f3ca 100644 --- a/demisto_sdk/commands/content_graph/strict_objects/playbook.py +++ b/demisto_sdk/commands/content_graph/strict_objects/playbook.py @@ -291,4 +291,4 @@ class StrictPlaybook(BaseStrictModel): tests: Optional[List[str]] = None role_name: Optional[List[str]] = Field(None, alias="rolename") marketplaces: Optional[List[MarketplaceVersions]] = None - is_silent: Optional[bool] = Field(alias="isSilent") + is_silent: Optional[bool] = Field(alias="issilent") diff --git a/demisto_sdk/commands/validate/tests/PB_validators_test.py b/demisto_sdk/commands/validate/tests/PB_validators_test.py index 0122c57c721..95a40af3fb3 100644 --- a/demisto_sdk/commands/validate/tests/PB_validators_test.py +++ b/demisto_sdk/commands/validate/tests/PB_validators_test.py @@ -1409,14 +1409,14 @@ def test_MarketplaceKeysHaveDefaultValidator( def test_IsSilentPlaybookValidator(name, id, is_silent, result_len): """ Given: - case 1: isSilent = False, and name/id do not contain silent prefix. - case 2: isSilent = True, and name/id contain silent prefix. - case 3: isSilent = True, name contain and id do not contain silent prefix. - case 4: isSilent = True, id contain and name do not contain silent prefix. - case 5: isSilent = False, and name/id contain silent prefix. - case 6: isSilent = False, name contain and id do not contain silent prefix. - case 7: isSilent = False, id contain and name do not contain silent prefix. - case 8: isSilent = True, and name/id do not contain silent prefix. + case 1: issilent = False, and name/id do not contain silent prefix. + case 2: issilent = True, and name/id contain silent prefix. + case 3: issilent = True, name contain and id do not contain silent prefix. + case 4: issilent = True, id contain and name do not contain silent prefix. + case 5: issilent = False, and name/id contain silent prefix. + case 6: issilent = False, name contain and id do not contain silent prefix. + case 7: issilent = False, id contain and name do not contain silent prefix. + case 8: issilent = True, and name/id do not contain silent prefix. When: - calling IsSilentPlaybookValidator.obtain_invalid_content_items. @@ -1427,7 +1427,7 @@ def test_IsSilentPlaybookValidator(name, id, is_silent, result_len): playbook = create_playbook_object() playbook.data["id"] = id playbook.data["name"] = name - playbook.data["isSilent"] = is_silent + playbook.data["issilent"] = is_silent invalid_content_items = IsSilentPlaybookValidator().obtain_invalid_content_items( [playbook] diff --git a/demisto_sdk/commands/validate/validators/PB_validators/PB130_is_silent_playbook.py b/demisto_sdk/commands/validate/validators/PB_validators/PB130_is_silent_playbook.py index efff549a72c..12b451a6a1a 100644 --- a/demisto_sdk/commands/validate/validators/PB_validators/PB130_is_silent_playbook.py +++ b/demisto_sdk/commands/validate/validators/PB_validators/PB130_is_silent_playbook.py @@ -13,9 +13,9 @@ class IsSilentPlaybookValidator(BaseValidator[ContentTypes]): error_code = "PB130" - description = "Validate that the name and ID of a silent-Playbook contain the silent prefix and include the field isSilent: true" - rationale = "In silent-Playbook the name and ID prefix should be silent and also include the field isSilent: true" - error_message = "Silent-Playbook should have silent as a prefix in the name and ID, as well as the field isSilent: true, one of them is missing." + description = "Validate that the name and ID of a silent-Playbook contain the silent prefix and include the field issilent: true" + rationale = "In silent-Playbook the name and ID prefix should be silent and also include the field issilent: true" + error_message = "Silent-Playbook should have silent as a prefix in the name and ID, as well as the field issilent: true, one of them is missing." related_field = "" is_auto_fixable = False @@ -30,14 +30,14 @@ def obtain_invalid_content_items( ) for content_item in content_items if ( - content_item.data.get("isSilent") + content_item.data.get("issilent") or any( content_item.data.get(key, "").startswith("silent") for key in ["name", "id"] ) ) and not ( - content_item.data.get("isSilent") + content_item.data.get("issilent") and all( content_item.data.get(key, "").startswith("silent") for key in ["name", "id"] diff --git a/demisto_sdk/commands/validate/validators/PB_validators/PB131_is_silent_playbook_relationships.py b/demisto_sdk/commands/validate/validators/PB_validators/PB131_is_silent_playbook_relationships.py index d970c3809cc..cd748a9c058 100644 --- a/demisto_sdk/commands/validate/validators/PB_validators/PB131_is_silent_playbook_relationships.py +++ b/demisto_sdk/commands/validate/validators/PB_validators/PB131_is_silent_playbook_relationships.py @@ -21,7 +21,7 @@ class IsSilentPlaybookRelationshipsValidator(BaseValidator[ContentTypes]): error_message = ( "The {} is silent, but does not correspond to a silent {} in the pack." ) - related_field = "isSilent" + related_field = "issilent" is_auto_fixable = False def obtain_invalid_content_items( diff --git a/demisto_sdk/commands/validate/validators/PB_validators/PB132_no_readme_for_silent_playbook.py b/demisto_sdk/commands/validate/validators/PB_validators/PB132_no_readme_for_silent_playbook.py index d0ae78cf657..198d0e715cb 100644 --- a/demisto_sdk/commands/validate/validators/PB_validators/PB132_no_readme_for_silent_playbook.py +++ b/demisto_sdk/commands/validate/validators/PB_validators/PB132_no_readme_for_silent_playbook.py @@ -16,7 +16,7 @@ class NoReadmeForSilentPlaybook(BaseValidator[ContentTypes]): description = "A silent playbook is not allowed to have a README file." rationale = "To ensure that silent playbooks do not appears in the documentation." error_message = "A silent playbook is not allowed to have a README file." - related_field = "isSilent" + related_field = "issilent" is_auto_fixable = False def obtain_invalid_content_items( diff --git a/demisto_sdk/scripts/tests/validate_deleted_files_test.py b/demisto_sdk/scripts/tests/validate_deleted_files_test.py index dfefb9ee53b..c4376551d1e 100644 --- a/demisto_sdk/scripts/tests/validate_deleted_files_test.py +++ b/demisto_sdk/scripts/tests/validate_deleted_files_test.py @@ -122,7 +122,7 @@ def test_get_forbidden_deleted_files_deleting_silent_playbook(git_repo: Repo): pack = git_repo.create_pack("Test") silent_playbook = pack.create_playbook("name") - silent_playbook.yml.update({"isSilent": "true"}) + silent_playbook.yml.update({"issilent": "true"}) git_repo.git_util.commit_files("create pack and silent playbook") git_repo.git_util.repo.git.checkout("-b", "delete_playbook") diff --git a/demisto_sdk/scripts/validate_deleted_files.py b/demisto_sdk/scripts/validate_deleted_files.py index fcd701bfbe5..8e49d0991e1 100644 --- a/demisto_sdk/scripts/validate_deleted_files.py +++ b/demisto_sdk/scripts/validate_deleted_files.py @@ -57,7 +57,7 @@ def is_file_allowed_to_be_deleted_by_file_type(file_path: Path) -> bool: def check_if_content_item_is_silent(file_dict): if isinstance(file_dict, dict): - if file_dict.get("isSilent"): + if file_dict.get("issilent"): return True return False