Skip to content

Gitsync 1p#655

Open
gnishant-gupta wants to merge 9 commits intomainfrom
gitsync_1p
Open

Gitsync 1p#655
gnishant-gupta wants to merge 9 commits intomainfrom
gitsync_1p

Conversation

@gnishant-gupta
Copy link
Copy Markdown
Contributor

@gnishant-gupta gnishant-gupta commented Mar 31, 2026

Checklist:

Please ensure you have completed the following items before submitting your PR.
This helps us review your contribution faster and more efficiently.

General Checks:

  • I have read and followed the project's contributing.md guide.
  • My code follows the project's coding style guidelines.
  • I have performed a self-review of my own code.
  • My changes do not introduce any new warnings.
  • My changes pass all existing tests.
  • I have added new tests where appropriate to cover my changes. (If applicable)
  • I have updated the documentation where necessary (e.g., README, API docs). (If applicable)

Open-Source Specific Checks:

  • My changes do not introduce any Personally Identifiable Information (PII) or sensitive customer data.
  • My changes do not expose any internal-only code examples, configurations, or URLs.
  • All code examples, comments, and messages are generic and suitable for a public repository.
  • I understand that any internal context or sensitive details related to this work are handled separately in internal systems (Buganizer for Google team members).

For Google Team Members and Reviewers Only:

  • I have included the Buganizer ID in the PR title or description (e.g., "Internal Buganizer ID: 123456789" or "Related Buganizer: go/buganizer/123456789").
  • I have ensured that all internal discussions and PII related to this work remain in Buganizer.
  • I have tagged the PR with one or more labels that reflect the pull request purpose.

Note

Medium Risk
Broad refactor of GitSync’s platform API interactions (moving many calls to TIPCommon.rest.soar_api and new data-model conversions), which can affect multiple content types during push/pull. Also changes workflow export/import behavior by introducing dedicated block handling, so regressions may surface in sync/install flows across environments.

Overview
GitSync is migrated toward TIPCommon 1P API usage by refactoring SiemplifyApiClient to delegate most operations (integrations, workflows, environments, ontology, settings, jobs, connectors, simulated cases) to TIPCommon.rest.soar_api, and updating jobs/managers to pass chronicle_soar / normalize payloads via TIPCommon.data_models.

Workflow syncing is expanded to support blocks: blocks are stored under a new Blocks/ path, GitContentManager can read/write blocks, and PushContent/PushPlaybook now detect WorkflowTypes.BLOCK and optionally export involved blocks when pushing playbooks.

Compatibility and robustness fixes include handling alternative integration package formats (.def vs .json), more tolerant README templating for renamed fields, safer parsing of denylist payload shapes, and updated integration/version metadata (plus dependency bumps in pyproject.toml).

Reviewed by Cursor Bugbot for commit 8aec20e. Bugbot is set up for automated code reviews on this repo. Configure here.

@gnishant-gupta gnishant-gupta requested review from a team as code owners March 31, 2026 12:13
@gemini-code-assist
Copy link
Copy Markdown
Contributor

Summary of Changes

Hello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request focuses on migrating the GitSync tool to utilize the 1P (First Party) API for interactions with the Chronicle SOAR platform. It introduces support for 'Blocks' as a distinct content type, updates internal dependencies, and refactors several core managers to improve stability and maintainability. These changes ensure better compatibility with modern platform APIs and expand the content types managed by the tool.

Highlights

  • 1P API Migration: Migrated various API calls to the 1P (First Party) API structure, enhancing integration with the Chronicle SOAR platform.
  • Block Support: Added support for 'Blocks' as a new content type, including logic for pushing and pulling blocks alongside playbooks.
  • Refactored GitManager: Removed redundant push failure logic and simplified the push process by relying on standard porcelain commands.
  • Dependency Updates: Updated internal dependencies (TIPCommon, integration-testing) to version 2.3.6 and bumped GitSync version to 45.0.

🧠 New Feature in Public Preview: You can now enable Memory to help Gemini Code Assist learn from your team's feedback. This makes future code reviews more consistent and personalized to your project's style. Click here to enable Memory in your admin console.

Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for GitHub and other Google products, sign up here.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request migrates the GitSync integration to a 1P API pattern, primarily by refactoring the SiemplifyApiClient to utilize shared functions from TIPCommon. It also introduces support for 'Blocks' as a workflow type and updates various job scripts to handle new data models and pass the SOAR SDK object to API calls. Feedback identifies several critical issues, including a logically incorrect boolean expression in job lookup, the use of an incorrect variable when pushing mappings which could lead to data being overwritten, and a missing f-string prefix in a warning log. Additionally, a cryptic comment was flagged for removal to maintain code readability.

(
x
for x in self.api.get_jobs(chronicle_soar=self._siemplify)
if x.get("name") or x.get("displayName") == job.name
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

The boolean expression x.get("name") or x.get("displayName") == job.name is logically incorrect. Due to operator precedence, it evaluates as (x.get("name")) or (x.get("displayName") == job.name). This means the condition will be true for any job that has a non-empty "name" field, regardless of whether it matches job.name. It should be updated to compare both fields against the target name.

Suggested change
if x.get("name") or x.get("displayName") == job.name
if x.get("name") == job.name or x.get("displayName") == job.name

if source and source.lower() == integration.lower():
rules.append(rule)
break
gitsync.content.push_mapping(Mapping(source, records, rules))
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

The Mapping constructor is using the source variable instead of the loop variable integration. Furthermore, source was redefined on line 75 inside the inner loop. This will cause all pushed mappings to be incorrectly named in the repository, leading to data being overwritten or saved under the wrong identifier.

Suggested change
gitsync.content.push_mapping(Mapping(source, records, rules))
gitsync.content.push_mapping(Mapping(integration, records, rules))

Comment on lines +246 to +247
"Unexpected response format from get_ide_cards "
"for integration '{integration.identifier}'. "
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The string literal on line 247 contains a placeholder {integration.identifier} but is missing the f prefix required for interpolation. This will result in the literal text being logged instead of the actual integration identifier.

Suggested change
"Unexpected response format from get_ide_cards "
"for integration '{integration.identifier}'. "
f"Unexpected response format from get_ide_cards "
f"for integration '{integration.identifier}'. "

break
all_records = gitsync.api.get_ontology_records(chronicle_soar=siemplify)
records_integrations = set([x["source"] for x in all_records])
for integration in records_integrations:
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

This loop iterates over all integrations found in the ontology records, effectively pushing all mappings. However, the job's log message (line 37) and the source variable suggest it is intended to push mappings for a specific source. This change in behavior ignores the source filter and might lead to unintended data being pushed to the repository.

record["source"],
record["product"],
record["eventName"],
rule = gitsync.api.get_mapping_rules(# ng
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The comment # ng is cryptic and does not provide helpful context for other developers. Please use a descriptive comment or remove it if it was a temporary note.

Suggested change
rule = gitsync.api.get_mapping_rules(# ng
rule = gitsync.api.get_mapping_rules(
References
  1. Code must prioritize readability and maintainability, using clear and descriptive naming and logic. (link)

@gnishant-gupta gnishant-gupta added Dependencies Pull requests that update a dependency file New tipcommon Google Release labels Mar 31, 2026
@gnishant-gupta gnishant-gupta self-assigned this Mar 31, 2026
Copy link
Copy Markdown

@cursor cursor bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 5 potential issues.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 8aec20e. Configure here.

self._define_workflow_as_new(workflow)
self._process_steps(workflow)
self.api.save_playbook(workflow.raw_data)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing chronicle_soar argument in get_playbook call

High Severity

self.api.get_playbook(playbook_id) passes the playbook_id string as the chronicle_soar parameter, since get_playbook was refactored to take chronicle_soar as its first positional argument and identifier as the second. This will cause a runtime error whenever _adjust_workflow_ids is called (i.e., when updating an existing workflow). Every other call site in the codebase was updated to pass chronicle_soar explicitly, but this one was missed.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 8aec20e. Configure here.

(
x
for x in self.api.get_jobs(chronicle_soar=self._siemplify)
if x.get("name") or x.get("displayName") == job.name
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Operator precedence causes incorrect job matching condition

High Severity

The expression x.get("name") or x.get("displayName") == job.name evaluates as (x.get("name")) or (x.get("displayName") == job.name) due to operator precedence. If x.get("name") returns any truthy string, the condition is true regardless of whether it matches job.name. This causes the next() call to return the first job in the list rather than the one matching by name, leading to incorrect job ID assignment.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 8aec20e. Configure here.

if source and source.lower() == integration.lower():
rules.append(rule)
break
gitsync.content.push_mapping(Mapping(source, records, rules))
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Job parameter source overwritten inside loop body

High Severity

The source variable (the user-provided job parameter from extract_job_param) is overwritten at line 75 by source = mapping_rule.get("source"). Additionally, the refactored code iterates over all records_integrations instead of filtering by the original source parameter, completely ignoring the user's input. The Mapping constructor and the later set_readme_addon call both use the now-corrupted source variable.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 8aec20e. Configure here.

self.logger.warning(
"Unexpected response format from get_ide_cards "
"for integration '{integration.identifier}'. "
f"Expected dict or list, but got {type(response).__name__}."
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing f-string prefix hides integration identifier in warning

Low Severity

The string "for integration '{integration.identifier}'." on line 247 is a plain string literal, not an f-string, so {integration.identifier} will appear literally in the log output instead of being interpolated. Only the third string segment has the f prefix.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 8aec20e. Configure here.


from io import BytesIO
import time
import threading
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unused time and threading imports

Low Severity

time and threading are imported in both PushContent.py and PushIntegration.py but are never used anywhere in either file. These appear to be accidentally committed debug/development imports.

Additional Locations (1)
Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 8aec20e. Configure here.

@cursor
Copy link
Copy Markdown

cursor bot commented Apr 10, 2026

You have used all of your free Bugbot PR reviews.

To receive reviews on all of your PRs, visit the Cursor dashboard to activate Pro and start your 14-day free trial.

@cursor
Copy link
Copy Markdown

cursor bot commented Apr 16, 2026

You have used all of your free Bugbot PR reviews.

To receive reviews on all of your PRs, visit the Cursor dashboard to activate Pro and start your 14-day free trial.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants