From 703165fc7fedf56f455a03bdf19162b895a6a48d Mon Sep 17 00:00:00 2001 From: Andrei Irimia Date: Wed, 7 Jan 2026 15:23:55 +0000 Subject: [PATCH 01/15] feat: add 'git checkout' action --- git.json | 105 +++++++++++++++++++++++++++++++++++- git_connector.py | 45 +++++++++++++++- release_notes/unreleased.md | 1 + 3 files changed, 148 insertions(+), 3 deletions(-) diff --git a/git.json b/git.json index d8342c8..37e6dae 100644 --- a/git.json +++ b/git.json @@ -12,13 +12,16 @@ }, { "name": "Chris Hutto" + }, + { + "name": "Andrei Irimia" } ], "package_name": "phantom_git", - "license": "Copyright (c) 2017-2025 Splunk Inc.", + "license": "Copyright (c) 2017-2026 Splunk Inc.", "main_module": "git_connector.py", "type": "devops", - "app_version": "4.1.6", + "app_version": "4.2.0", "utctime_updated": "2025-09-24T19:16:06.075267Z", "product_vendor": "Generic", "product_name": "Git", @@ -489,6 +492,104 @@ ], "versions": "EQ(*)" }, + { + "action": "git checkout", + "description": "Checks out the provided branch in the local repository. Creates branch if it does not exist.", + "type": "generic", + "identifier": "git_checkout", + "read_only": false, + "parameters": { + "branch_name": { + "description": "Branch name to checkout (default is 'master')", + "data_type": "string", + "required": true, + "default": "master", + "order": 0 + } + }, + "render": { + "width": 12, + "height": 5, + "type": "table", + "title": "Git Checkout" + }, + "output": [ + { + "data_path": "action_result.status", + "data_type": "string", + "example_values": [ + "success", + "failed" + ], + "column_order": 3, + "column_name": "Status" + }, + { + "data_path": "action_result.parameter.branch_name", + "data_type": "string", + "example_values": [ + "master", + "my-feature-branch" + ], + "column_order": 2, + "column_name": "Parameter Branch Name" + }, + { + "data_path": "action_result.data.*.branch_name", + "data_type": "string", + "example_values": [ + "master" + ], + "column_order": 1, + "column_name": "Branch Name" + }, + { + "data_path": "action_result.data.*.repo_dir", + "data_type": "string", + "example_values": [ + "/opt/phantom/local_data/app_states/ff116964-86f7-4e29-8763-4462ce0d39a7/test_repo" + ], + "contains": [ + "file path" + ] + }, + { + "data_path": "action_result.data.*.repo_name", + "data_type": "string", + "example_values": [ + "repo2" + ], + "column_order": 0, + "column_name": "Repo Name" + }, + { + "data_path": "action_result.summary", + "data_type": "string" + }, + { + "data_path": "action_result.message", + "data_type": "string", + "example_values": [ + "Successfully checked out branch: test-branch" + ] + }, + { + "data_path": "summary.total_objects", + "data_type": "numeric", + "example_values": [ + 1 + ] + }, + { + "data_path": "summary.total_objects_successful", + "data_type": "numeric", + "example_values": [ + 1 + ] + } + ], + "versions": "EQ(*)" + }, { "action": "delete file", "description": "Delete a file from the local working directory", diff --git a/git_connector.py b/git_connector.py index a0e4c5b..f642d08 100644 --- a/git_connector.py +++ b/git_connector.py @@ -1,6 +1,6 @@ # File: git_connector.py # -# Copyright (c) 2017-2025 Splunk Inc. +# Copyright (c) 2017-2026 Splunk Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -450,6 +450,48 @@ def _git_push(self, param): return action_result.set_status(phantom.APP_SUCCESS, status_message=message) + def _git_checkout(self, param): + """Creates new branch in local repository and checks out the branch. If it already exists, checks out the existing branch. + + :param param: dictionary on input parameters + + :return: status success/failure + """ + self.save_progress(f"In action handler for: {self.get_action_identifier()}") + action_result = self.add_action_result(ActionResult(dict(param))) + self._set_repo_attributes(param=param) + new_branch_name = param["branch_name"] + + # Verify that directory for given repo exists and it is valid git repo + resp_status, repo = self.verify_repo(self.repo_name, action_result) + + if phantom.is_fail(resp_status): + return action_result.get_status() + + try: + repo.git.checkout("-b", new_branch_name) + except Exception as e: + # Check if the failure is because the branch exists + if "already exists" in str(e): + try: + # Checkout the existing branch + repo.git.checkout(new_branch_name) + except Exception as inner_e: + # Checkout failed + message = f"Error switching to existing branch: {inner_e!s}" + self.debug_print(inner_e) + return action_result.set_status(phantom.APP_ERROR, message) + else: + # Catch original exception if branch creation failed for other reasons + message = f"Error while creating branch: {e!s}" + self.debug_print(e) + return action_result.set_status(phantom.APP_ERROR, message) + + repo_dir = self.app_state_dir / self.repo_name + message = f"Successfully checked out branch: {new_branch_name}" + action_result.add_data({"repo_name": self.repo_name, "repo_dir": str(repo_dir), "branch_name": new_branch_name}) + return action_result.set_status(phantom.APP_SUCCESS, message) + def __git_pull(self, action_result, param): self._set_repo_attributes(param=param) @@ -848,6 +890,7 @@ def handle_action(self, param): "update_file": self._update_file, "configure_ssh": self._configure_ssh, "git_status": self._git_status, + "git_checkout": self._git_checkout, "on_poll": self._on_poll, "test_asset_connectivity": self._test_asset_connectivity, } diff --git a/release_notes/unreleased.md b/release_notes/unreleased.md index fbcb2fd..bf8d646 100644 --- a/release_notes/unreleased.md +++ b/release_notes/unreleased.md @@ -1 +1,2 @@ **Unreleased** +* Added 'git checkout' action From dced17b462f3dbd088f9a9277e45722e51cff646 Mon Sep 17 00:00:00 2001 From: Andrei Irimia Date: Wed, 7 Jan 2026 15:41:57 +0000 Subject: [PATCH 02/15] feat: add 'git checkout' action --- LICENSE | 2 +- NOTICE | 2 +- README.md | 32 ++++++++++++++++++++++++++++++-- __init__.py | 2 +- git_consts.py | 2 +- git_git_status.html | 2 +- git_list_repos.html | 2 +- git_view.py | 2 +- 8 files changed, 37 insertions(+), 9 deletions(-) diff --git a/LICENSE b/LICENSE index 01f84e5..86185fe 100644 --- a/LICENSE +++ b/LICENSE @@ -186,7 +186,7 @@ same "printed page" as the copyright notice for easier identification within third-party archives. - Copyright (c) 2017-2025 Splunk Inc. + Copyright (c) 2017-2026 Splunk Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/NOTICE b/NOTICE index 418fb3b..f158626 100644 --- a/NOTICE +++ b/NOTICE @@ -1,5 +1,5 @@ Splunk SOAR App: Git -Copyright (c) 2017-2025 Splunk Inc. +Copyright (c) 2017-2026 Splunk Inc. Third Party Software Attributions: @@@@============================================================================ diff --git a/README.md b/README.md index ac1c059..6035784 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ # Git Publisher: Splunk
-Connector Version: 4.1.6
+Connector Version: 4.2.0
Product Vendor: Generic
Product Name: Git
Minimum Product Version: 6.3.0 @@ -117,6 +117,7 @@ VARIABLE | REQUIRED | TYPE | DESCRIPTION [list repos](#action-list-repos) - List repos configured/pulled
[update file](#action-update-file) - Update (overwrite) contents of a file in the working directory
[git status](#action-git-status) - Get the result of git status
+[git checkout](#action-git-checkout) - Checks out the provided branch in the local repository. Creates branch if it does not exist.
[delete file](#action-delete-file) - Delete a file from the local working directory
[add file](#action-add-file) - Create a file in the local working directory
[git commit](#action-git-commit) - Commit changes
@@ -253,6 +254,33 @@ action_result.message | string | | Status: Your branch is up-to-date with 'origi summary.total_objects | numeric | | 1 | summary.total_objects_successful | numeric | | 1 | +## action: 'git checkout' + +Checks out the provided branch in the local repository. Creates branch if it does not exist. + +Type: **generic**
+Read only: **False** + +#### Action Parameters + +PARAMETER | REQUIRED | DESCRIPTION | TYPE | CONTAINS +--------- | -------- | ----------- | ---- | -------- +**branch_name** | required | Branch name to checkout (default is 'master') | string | | + +#### Action Output + +DATA PATH | TYPE | CONTAINS | EXAMPLE VALUES +--------- | ---- | -------- | -------------- +action_result.status | string | | success failed | +action_result.parameter.branch_name | string | | master my-feature-branch | +action_result.data.\*.branch_name | string | | master | +action_result.data.\*.repo_dir | string | `file path` | /opt/phantom/local_data/app_states/ff116964-86f7-4e29-8763-4462ce0d39a7/test_repo | +action_result.data.\*.repo_name | string | | repo2 | +action_result.summary | string | | | +action_result.message | string | | Successfully checked out branch: test-branch | +summary.total_objects | numeric | | 1 | +summary.total_objects_successful | numeric | | 1 | + ## action: 'delete file' Delete a file from the local working directory @@ -472,7 +500,7 @@ ______________________________________________________________________ Auto-generated Splunk SOAR Connector documentation. -Copyright 2025 Splunk Inc. +Copyright 2026 Splunk Inc. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/__init__.py b/__init__.py index c8a2c5b..c6ac30e 100644 --- a/__init__.py +++ b/__init__.py @@ -1,6 +1,6 @@ # File: __init__.py # -# Copyright (c) 2017-2025 Splunk Inc. +# Copyright (c) 2017-2026 Splunk Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/git_consts.py b/git_consts.py index 9fa1935..e2cbf50 100644 --- a/git_consts.py +++ b/git_consts.py @@ -1,6 +1,6 @@ # File: git_consts.py # -# Copyright (c) 2017-2025 Splunk Inc. +# Copyright (c) 2017-2026 Splunk Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/git_git_status.html b/git_git_status.html index 9b654c0..aa440f9 100644 --- a/git_git_status.html +++ b/git_git_status.html @@ -11,7 +11,7 @@ {% block widget_content %}