Skip to content

Conversation

emekanwaoma
Copy link
Contributor

@emekanwaoma emekanwaoma commented Oct 10, 2025

User description

Description

What - Added comprehensive multi-organization support to the GitHub Ocean integration

Why - The current GitHub integration only supports a single organization, limiting its scalability and requiring separate integrations for each organization. This change enables users to manage multiple GitHub organizations through a single integration instance.

How -

  • Updated all resync functions to iterate through multiple organizations using organization-specific clients
  • Modified webhook processors to include organization context in payloads
  • Enhanced client factory to create organization-specific GitHub clients
  • Added custom OrganizationRequiredException for better error handling
  • Updated configuration schema to support githubOrganizations field
  • Refactored all resource exporters to work with organization-specific clients

Type of change

  • Breaking change (fix or feature that would cause existing functionality to not work as expected)

Core testing checklist

  • Integration able to create all default resources from scratch
  • Resync finishes successfully
  • Resync able to create entities
  • Resync able to update entities
  • Resync able to detect and delete entities
  • Scheduled resync able to abort existing resync and start a new one
  • Tested with at least 2 integrations from scratch
  • Tested with Kafka and Polling event listeners
  • Tested deletion of entities that don't pass the selector

Integration testing checklist

  • Integration able to create all default resources from scratch
  • Completed a full resync from a freshly installed integration and it completed successfully
  • Resync able to create entities
  • Resync able to update entities
  • Resync able to detect and delete entities
  • Resync finishes successfully
  • If new resource kind is added or updated in the integration, add example raw data, mapping and expected result to the examples folder in the integration directory.
  • If resource kind is updated, run the integration with the example data and check if the expected result is achieved
  • If new resource kind is added or updated, validate that live-events for that resource are working as expected
  • Docs PR link here

Preflight checklist

  • Handled rate limiting
  • Handled pagination
  • Implemented the code in async
  • Support Multi account

Screenshots

Include screenshots from your environment showing how the resources of the integration will look.

API Documentation

Provide links to the API documentation used for this integration.


PR Type

Enhancement, Tests


Description

• Added comprehensive multi-organization support to the GitHub Ocean integration, enabling management of multiple GitHub organizations through a single integration instance
• Updated all resync functions and resource exporters to iterate through multiple organizations using organization-specific clients
• Enhanced webhook processors to include organization context in payloads and processing logic
• Modified configuration schema to support githubOrganizations field while making githubOrganization optional
• Added new OrganizationRequiredException for better error handling and organization validation
• Updated all core option types to inherit from organization-aware base classes
• Refactored utility functions to use parse_github_options instead of extract_repo_params for organization support
• Enhanced file processing, folder mapping, and team management to work with organization-specific contexts
• Updated all test suites to include organization parameters and validate multi-organization functionality
• Added organization as a new resource kind in the integration specification


Diagram Walkthrough

flowchart LR
  A["Single Org Config"] --> B["Multi-Org Config"]
  B --> C["Organization-Specific Clients"]
  C --> D["Enhanced Resync Functions"]
  C --> E["Updated Webhook Processors"]
  C --> F["Modified Resource Exporters"]
  D --> G["Multi-Org Resource Management"]
  E --> G
  F --> G
Loading

File Walkthrough

Relevant files
Enhancement
41 files
main.py
Multi-organization support for GitHub integration               

integrations/github/main.py

• Added comprehensive multi-organization support to all resync
functions
• Modified webhook subscription to iterate through multiple
organizations
• Updated all resource exporters to work with
organization-specific clients
• Added new resync_organizations
function for organization management

+468/-194
core.py
Organization support in file exporter core                             

integrations/github/github/core/exporters/file_exporter/core.py

• Added organization parameter to all file-related methods
• Updated
API endpoints to use organization-specific URLs
• Enhanced logging to
include organization context
• Modified file processing to handle
organization information

+67/-32 
file_validation.py
Organization support in file validation service                   

integrations/github/github/webhook/webhook_processors/check_runs/file_validation.py

• Added organization parameter to FileValidationService constructor

Updated check run creation and update methods to use
organization-specific endpoints
• Enhanced error logging to include
organization context

+25/-16 
file_processor.py
Organization support in file processor                                     

integrations/github/github/core/exporters/file_exporter/file_processor.py

• Added organization parameter to all file processing methods

Updated FileObject creation to include organization information

Modified file reference resolution to handle organization context

+33/-8   
file_webhook_processor.py
Organization support in file webhook processor                     

integrations/github/github/webhook/webhook_processors/file_webhook_processor.py

• Added organization extraction from webhook payload
• Updated file
processing methods to include organization parameter
• Enhanced
logging to include organization context throughout

+23/-10 
pull_request_exporter.py
Organization support in pull request exporter                       

integrations/github/github/core/exporters/pull_request_exporter.py

• Updated to use parse_github_options instead of extract_repo_params

Modified API endpoints to use organization-specific URLs
• Enhanced
logging to include organization context

+28/-22 
folder_exporter.py
Organization support in folder exporter                                   

integrations/github/github/core/exporters/folder_exporter.py

• Updated create_path_mapping to handle organization-based repository
mapping
• Modified folder retrieval to work with organization-specific
repositories
• Added organization parameter to folder enrichment
methods

+59/-38 
repository_exporter.py
Organization support in repository exporter                           

integrations/github/github/core/exporters/repository_exporter.py

• Added organization parameter to repository fetching methods

Updated API endpoints to use organization-specific URLs
• Modified
repository enrichment methods to include organization context

+20/-13 
branch_exporter.py
Organization support in branch exporter                                   

integrations/github/github/core/exporters/branch_exporter.py

• Added organization parameter to branch fetching methods
• Updated
API endpoints to use organization-specific URLs
• Modified branch
hydration and protection rule methods to include organization

+27/-16 
team_member_and_repository_exporter.py
Organization support in team member repository exporter   

integrations/github/github/core/exporters/team_exporter/team_member_and_repository_exporter.py

• Added organization parameter to team fetching methods
• Updated
GraphQL variables to use organization-specific queries
• Modified team
data retrieval to include organization context

+9/-5     
utils.py
Enhance file exporter utilities with organization support

integrations/github/github/core/exporters/file_exporter/utils.py

• Added organization field to FileObject TypedDict structure
• Updated
file pattern grouping functions to handle organization-specific
repository fetching
• Enhanced logging to include organization context
throughout file processing
• Added deep_dict utility function for
converting defaultdict structures

+26/-6   
folder_webhook_processor.py
Add organization support to folder webhook processor         

integrations/github/github/webhook/webhook_processors/folder_webhook_processor.py

• Added organization extraction from webhook payload
• Updated folder
fetching logic to include organization parameter in repository options

• Enhanced logging messages to include organization context
• Modified
repository mapping structure to include organization hierarchy

+22/-8   
team_with_members_exporter.py
Update team with members exporter for organization support

integrations/github/github/core/exporters/team_exporter/team_with_members_exporter.py

• Updated GraphQL team queries to use organization from options
instead of client
• Added organization parameter to all team member
fetching operations
• Modified paginated resources method to accept
ListTeamOptions with organization

+12/-7   
check_runs_validator_webhook_processor.py
Add organization support to check runs validator                 

integrations/github/github/webhook/webhook_processors/check_runs/check_runs_validator_webhook_processor.py

• Added organization extraction from webhook payload
• Updated file
validation service initialization with organization parameter

Modified commit diff fetching to include organization parameter

Enhanced logging to include organization context

+16/-9   
utils.py
Enhance utility functions with organization support           

integrations/github/github/helpers/utils.py

• Added ORGANIZATION enum value to ObjectKind
• Renamed
extract_repo_params to parse_github_options with organization support

• Updated fetch_commit_diff function to accept organization parameter

• Enhanced repository search functions with organization context

+21/-8   
user_exporter.py
Update user exporter for organization support                       

integrations/github/github/core/exporters/user_exporter.py

• Updated user fetching methods to use organization from options
instead of client
• Added organization parameter to external identity
fetching operations
• Modified paginated resources method to accept
ListUserOptions

+14/-8   
collaborator_exporter.py
Update collaborator exporter for organization support       

integrations/github/github/core/exporters/collaborator_exporter.py

• Updated to use parse_github_options instead of extract_repo_params

Modified API endpoints to use organization from options
• Enhanced
logging to include organization context
• Added type casting for
repository name parameter

+11/-10 
options.py
Add organization support to core options types                     

integrations/github/github/core/options.py

• Added new organization-related option types:
ListOrganizationOptions, SingleOrganizationOptions
• Updated existing
option types to inherit from SingleOrganizationOptions
• Modified
RepositoryIdentifier to include organization parameter
• Updated
folder options to support organization hierarchy in repository mapping

+32/-15 
dependabot_exporter.py
Update dependabot exporter for organization support           

integrations/github/github/core/exporters/dependabot_exporter.py

• Updated to use parse_github_options instead of extract_repo_params

Modified API endpoints to use organization from options
• Enhanced
logging to include organization context
• Added type casting for
repository name parameter

+12/-9   
secret_scanning_alert_exporter.py
Update secret scanning alert exporter for organization support

integrations/github/github/core/exporters/secret_scanning_alert_exporter.py

• Updated to use parse_github_options instead of extract_repo_params

Modified API endpoints to use organization from options
• Enhanced
logging to include organization context
• Added type casting for
repository name parameter

+12/-9   
release_exporter.py
Update release exporter for organization support                 

integrations/github/github/core/exporters/release_exporter.py

• Updated to use parse_github_options instead of extract_repo_params

Modified API endpoints to use organization from options
• Enhanced
logging to include organization context
• Added type casting for
repository name parameter

+13/-9   
team_exporter.py
Update team exporter for organization support                       

integrations/github/github/core/exporters/team_exporter/team_exporter.py

• Updated team fetching methods to use organization from options
instead of client
• Added organization parameter to team repository
fetching operations
• Modified paginated resources method to accept
ListTeamOptions
• Enhanced logging to include organization context

+16/-8   
deployment_exporter.py
Update deployment exporter for organization support           

integrations/github/github/core/exporters/deployment_exporter.py

• Updated to use parse_github_options instead of extract_repo_params

Modified API endpoints to use organization from options
• Enhanced
logging to include organization context
• Added type casting for
repository name parameter

+11/-10 
environment_exporter.py
Update environment exporter for organization support         

integrations/github/github/core/exporters/environment_exporter.py

• Updated to use parse_github_options instead of extract_repo_params

Modified API endpoints to use organization from options
• Enhanced
logging to include organization context
• Added type casting for
repository name parameter

+9/-9     
tag_exporter.py
Update tag exporter for organization support                         

integrations/github/github/core/exporters/tag_exporter.py

• Updated to use parse_github_options instead of extract_repo_params

Modified API endpoints to use organization from options
• Enhanced
logging to include organization context
• Added type casting for
repository name parameter

+14/-10 
code_scanning_alert_exporter.py
Update code scanning alert exporter for organization support

integrations/github/github/core/exporters/code_scanning_alert_exporter.py

• Updated to use parse_github_options instead of extract_repo_params

Modified API endpoints to use organization from options
• Enhanced
logging to include organization context
• Added type casting for
repository name parameter

+12/-9   
membership_webhook_processor.py
Add organization support to membership webhook processor 

integrations/github/github/webhook/webhook_processors/collaborator_webhook_processor/membership_webhook_processor.py

• Added organization extraction from webhook payload
• Updated team
repository fetching to include organization parameter
• Enhanced
logging messages to include organization context
• Modified
collaborator processing to use organization-specific operations

+5/-4     
dependabot_webhook_processor.py
Add organization support to Dependabot webhook processor 

integrations/github/github/webhook/webhook_processors/dependabot_webhook_processor.py

• Added organization extraction from webhook payload
• Updated logging
to include organization information
• Modified
SingleDependabotAlertOptions to include organization parameter

+7/-2     
workflow_run_webhook_processor.py
Add organization support to workflow run webhook processor

integrations/github/github/webhook/webhook_processors/workflow_run_webhook_processor.py

• Added organization extraction from webhook payload
• Enhanced
logging messages to include organization context
• Updated
SingleWorkflowRunOptions to include organization parameter

+12/-4   
team_webhook_processor.py
Add organization support to team webhook processor             

integrations/github/github/webhook/webhook_processors/team_webhook_processor.py

• Added organization extraction from webhook payload
• Updated logging
messages to include organization information
• Modified
SingleTeamOptions to include organization parameter

+5/-4     
release_webhook_processor.py
Add organization support to release webhook processor       

integrations/github/github/webhook/webhook_processors/release_webhook_processor.py

• Added organization extraction from webhook payload
• Enhanced
logging to include organization context
• Updated SingleReleaseOptions
to include organization parameter

+5/-2     
issue_webhook_processor.py
Add organization support to issue webhook processor           

integrations/github/github/webhook/webhook_processors/issue_webhook_processor.py

• Added organization extraction from webhook payload
• Enhanced
logging messages with organization information
• Updated
SingleIssueOptions to include organization parameter

+9/-2     
user_webhook_processor.py
Add organization support to user webhook processor             

integrations/github/github/webhook/webhook_processors/user_webhook_processor.py

• Added organization extraction from webhook payload
• Updated logging
messages to include organization context
• Modified SingleUserOptions
to include organization parameter

+9/-4     
branch_webhook_processor.py
Add organization support to branch webhook processor         

integrations/github/github/webhook/webhook_processors/branch_webhook_processor.py

• Added organization extraction from webhook payload
• Enhanced
logging to include organization information
• Updated
SingleBranchOptions to include organization parameter

+3/-1     
repository_webhook_processor.py
Add organization support to repository webhook processor 

integrations/github/github/webhook/webhook_processors/repository_webhook_processor.py

• Added organization extraction from webhook payload
• Enhanced
logging messages with organization context
• Updated
SingleRepositoryOptions to include organization parameter

+5/-1     
webhook_client.py
Add organization parameter to GitHub webhook client           

integrations/github/github/webhook/webhook_client.py

• Added organization parameter to GithubWebhookClient constructor

Added organization instance variable to store organization context

+4/-1     
integration.py
Add multi-organization configuration support to integration

integrations/github/integration.py

• Added organization field to FolderSelector and GithubFilePattern
models
• Added organizations field to GithubPortAppConfig for
multi-org support
• Updated configuration to make githubOrganization
optional

+10/-0   
tag_webhook_processor.py
Add organization support to tag webhook processor               

integrations/github/github/webhook/webhook_processors/tag_webhook_processor.py

• Added organization extraction from webhook payload
• Enhanced
logging messages with organization information
• Updated
SingleTagOptions to include organization parameter

+5/-2     
deployment_webhook_processor.py
Add organization support to deployment webhook processor 

integrations/github/github/webhook/webhook_processors/deployment_webhook_processor.py

• Added organization extraction from webhook payload
• Enhanced
logging to include organization context
• Updated
SingleDeploymentOptions to include organization parameter

+3/-1     
base_repository_webhook_processor.py
Enhance base repository webhook processor validation chain

integrations/github/github/webhook/webhook_processors/base_repository_webhook_processor.py

• Updated validate_payload method to call parent class validation
first
• Improved validation chain to include organization validation

+5/-3     
environment_webhook_processor.py
Add organization support to environment webhook processor

integrations/github/github/webhook/webhook_processors/environment_webhook_processor.py

• Added organization extraction from webhook payload
• Enhanced
logging messages with organization information
• Updated
SingleEnvironmentOptions to include organization parameter

+3/-1     
Tests
27 files
test_team_exporter.py
Team exporter tests updated for multi-org                               

integrations/github/tests/github/core/exporters/test_team_exporter.py

• Updated test cases to include organization parameter in
SingleTeamOptions
• Modified API endpoint assertions to use
organization-specific URLs
• Added organization context to all
team-related test scenarios

+48/-24 
test_file_exporter.py
File exporter tests updated for multi-org                               

integrations/github/tests/github/core/exporters/test_file_exporter.py

• Added organization parameter to FileContentOptions and
FileSearchOptions
• Updated test assertions to verify
organization-specific API calls
• Modified file processing tests to
include organization context

+73/-20 
test_file_entity_processor.py
File entity processor tests updated for multi-org               

integrations/github/tests/github/entity_processors/test_file_entity_processor.py

• Added owner field with login property to repository test data

Updated test assertions to include organization parameter in API calls

• Modified all test scenarios to handle organization context

+27/-3   
test_folder_exporter.py
Folder exporter tests updated for multi-org                           

integrations/github/tests/github/core/exporters/test_folder_exporter.py

• Updated folder pattern creation tests to include organization
parameter
• Modified repository mapping structure to support
organization-based grouping
• Updated test assertions for new
multi-organization folder structure

+57/-17 
test_branch_exporter.py
Branch exporter tests updated for multi-org                           

integrations/github/tests/github/core/exporters/test_branch_exporter.py

• Added organization parameter to SingleBranchOptions and
ListBranchOptions
• Updated API endpoint assertions to use
organization-specific URLs
• Modified branch fetching and enrichment
method signatures

+38/-12 
test_utils.py
Utils tests updated for multi-org parsing                               

integrations/github/tests/github/helpers/test_utils.py

• Updated tests from extract_repo_params to parse_github_options

Added organization parameter handling in all test scenarios
• Modified
test assertions to verify organization extraction

+35/-16 
test_dependabot_exporter.py
Dependabot exporter tests updated for multi-org                   

integrations/github/tests/github/core/exporters/test_dependabot_exporter.py

• Added organization parameter to SingleDependabotAlertOptions and
ListDependabotAlertOptions
• Updated API endpoint assertions to use
organization-specific URLs
• Modified all test scenarios to include
organization context

+20/-10 
test_code_scanning_alert_exporter.py
Update code scanning alert tests for multi-organization support

integrations/github/tests/github/core/exporters/test_code_scanning_alert_exporter.py

• Updated test methods to include organization parameter in
SingleCodeScanningAlertOptions and ListCodeScanningAlertOptions

Modified API endpoint assertions to use organization from options
instead of client organization
• Added organization parameter to all
test cases for code scanning alert operations

+20/-10 
test_file_validation.py
Update file validation tests for organization support       

integrations/github/tests/github/webhook/webhook_processors/check_runs/test_file_validation.py

• Added organization parameter to FileValidationService initialization

• Updated FileObject creation to include organization field
• Modified
test assertions to include organization in API calls
• Updated file
pattern configurations with organization parameter

+13/-9   
test_pull_request_exporter.py
Update pull request exporter tests for organization support

integrations/github/tests/github/core/exporters/test_pull_request_exporter.py

• Added organization parameter to SinglePullRequestOptions and
ListPullRequestOptions in tests
• Updated API endpoint assertions to
use organization from options
• Modified all test cases to include
organization context

+30/-8   
test_user_exporter.py
Update user exporter tests for organization support           

integrations/github/tests/github/core/exporters/test_user_exporter.py

• Added organization parameter to SingleUserOptions and
ListUserOptions in tests
• Updated GraphQL query assertions to use
organization from options
• Modified external identity fetching tests
to include organization parameter

+15/-9   
test_folder_webhook_processor.py
Update folder webhook processor tests for organization support

integrations/github/tests/github/webhook/webhook_processors/test_folder_webhook_processor.py

• Added organization parameter to folder selector configurations

Updated webhook payload assertions to include organization
• Modified
repository mapping structure to include organization hierarchy

Updated API call assertions with organization parameter

+9/-4     
test_secret_scanning_alert_exporter.py
Update secret scanning alert tests for organization support

integrations/github/tests/github/core/exporters/test_secret_scanning_alert_exporter.py

• Added organization parameter to alert options in all test methods

Updated API endpoint assertions to use organization from options

Modified test cases to include organization context throughout

+15/-6   
test_repository_exporter.py
Update repository exporter tests for organization support

integrations/github/tests/github/core/exporters/test_repository_exporter.py

• Added organization parameter to repository options in tests

Updated API endpoint assertions to use organization from options

Modified collaborator request assertions to include organization

+10/-7   
test_base_repository_webhook_processor.py
Update base repository webhook processor tests for organization
support

integrations/github/tests/github/webhook/webhook_processors/test_base_repository_webhook_processor.py

• Updated test payloads to include organization field
• Added
organization data to test cases for proper validation

+17/-4   
test_file_webhook_processor.py
Update file webhook processor tests for organization support

integrations/github/tests/github/webhook/webhook_processors/test_file_webhook_processor.py

• Added organization field to GithubFilePattern test configurations

Updated test payload to include organization data
• Modified test
assertions to include organization parameter in method calls

+5/-1     
test_pull_request_webhook_processor.py
Update pull request webhook processor tests for organization support

integrations/github/tests/github/webhook/webhook_processors/test_pull_request_webhook_processor.py

• Added organization field to test payloads
• Updated test assertions
to include organization parameter in SinglePullRequestOptions

+9/-2     
test_issue_webhook_processor.py
Update issue webhook processor tests for organization support

integrations/github/tests/github/webhook/webhook_processors/test_issue_webhook_processor.py

• Added organization field to test payloads
• Updated test assertions
to include organization parameter in SingleIssueOptions

+9/-2     
test_team_webhook_processor.py
Update team webhook processor tests for organization support

integrations/github/tests/github/webhook/webhook_processors/test_team_webhook_processor.py

• Added organization field to test payloads
• Updated test assertions
to include organization parameter in SingleTeamOptions

+6/-2     
test_member_webhook_processor.py
Update member webhook processor tests for organization support

integrations/github/tests/github/webhook/webhook_processors/test_collaborator_webhook_processor/test_member_webhook_processor.py

• Added organization field to test payloads
• Updated test assertions
to include organization parameter in SingleCollaboratorOptions

+4/-1     
test_tag_webhook_processor.py
Update tag webhook processor tests for organization support

integrations/github/tests/github/webhook/webhook_processors/test_tag_webhook_processor.py

• Added organization field to test payloads
• Updated test assertions
to include organization parameter in SingleTagOptions

+4/-1     
test_release_webhook_processor.py
Update release webhook processor tests for organization support

integrations/github/tests/github/webhook/webhook_processors/test_release_webhook_processor.py

• Added organization field to test payloads
• Updated test assertions
to include organization parameter in SingleReleaseOptions

+4/-1     
test_deployment_webhook_processor.py
Update deployment webhook processor tests for organization support

integrations/github/tests/github/webhook/webhook_processors/test_deployment_webhook_processor.py

• Added organization field to test payloads
• Updated test assertions
to include organization parameter in SingleDeploymentOptions

+4/-1     
test_environment_webhook_processor.py
Update environment webhook processor tests for organization support

integrations/github/tests/github/webhook/webhook_processors/test_environment_webhook_processor.py

• Added organization field to test payloads
• Updated test assertions
to include organization parameter in SingleEnvironmentOptions

+4/-1     
test_workflow_webhook_processor.py
Update workflow webhook processor tests for organization support

integrations/github/tests/github/webhook/webhook_processors/test_workflow_webhook_processor.py

• Added organization field to test payloads
• Updated test assertions
to include organization parameter in SingleWorkflowOptions

+2/-0     
test_branch_webhook_processor.py
Update branch webhook processor tests for organization support

integrations/github/tests/github/webhook/webhook_processors/test_branch_webhook_processor.py

• Added organization field to test payloads
• Updated test assertions
to include organization parameter in SingleBranchOptions

+2/-0     
test_team_webhook_processor.py
Update team collaborator webhook processor tests for organization
support

integrations/github/tests/github/webhook/webhook_processors/test_collaborator_webhook_processor/test_team_webhook_processor.py

• Updated test assertions to include organization parameter in team
exporter calls

+1/-1     
Configuration changes
1 files
spec.yaml
Update integration specification for multi-organization support

integrations/github/.port/spec.yaml

• Added organization as a new resource kind
• Made githubOrganization
configuration optional
• Updated description to reflect
multi-organization support

+3/-2     
Documentation
1 files
CHANGELOG.md
Add changelog entry for multi-organization support             

integrations/github/CHANGELOG.md

• Added changelog entry for version 1.5.11-beta
• Documented
multi-organization support features

+11/-0   
Miscellaneous
1 files
pyproject.toml
Bump version to 1.5.11-beta                                                           

integrations/github/pyproject.toml

• Updated version from 1.5.10-beta to 1.5.11-beta

+1/-1     
Additional files
33 files
base_client.py +0/-2     
utils.py +0/-1     
issue_exporter.py +14/-9   
organization_exporter.py +37/-0   
workflow_runs_exporter.py +11/-6   
workflows_exporter.py +10/-5   
file_entity_processor.py +13/-3   
code_scanning_alert_webhook_processor.py +7/-4     
member_webhook_processor.py +11/-4   
team_webhook_processor.py +14/-5   
github_abstract_webhook_processor.py +12/-5   
pull_request_webhook_processor.py +8/-3     
secret_scanning_alert_webhook_processor.py +6/-4     
team_member_webhook_processor.py +7/-4     
workflow_webhook_processor.py +7/-4     
test_collaborator_exporter.py +8/-4     
test_deployment_exporter.py +8/-4     
test_environment_exporter.py +8/-4     
test_issue_exporter.py +12/-6   
test_release_exporter.py +6/-4     
test_tag_exporter.py +6/-4     
test_workflow_exporter.py +8/-4     
test_workflow_run_exporter.py +8/-3     
test_check_run_validator_webhook_processor.py +5/-1     
test_code_scanning_alert_webhook_processor.py +7/-0     
test_membership_webhook_processor.py +1/-1     
test_dependabot_webhook_processor.py +7/-0     
test_github_abstract_webhook_processor.py +12/-4   
test_repository_webhook_processor.py +14/-3   
test_secret_scanning_alert_webhook_processor.py +8/-0     
test_team_member_webhook_processor.py +13/-3   
test_user_webhook_processor.py +9/-2     
test_workflow_run_webhook_processor.py +8/-2     

Copy link
Contributor

qodo-merge-pro bot commented Oct 10, 2025

PR Compliance Guide 🔍

Below is a summary of compliance checks for this PR:

Security Compliance
🟢
No security concerns identified No security vulnerabilities detected by AI analysis. Human verification advised for critical code.
Ticket Compliance
🎫 No ticket provided
  • Create ticket/issue
Codebase Duplication Compliance
Codebase context is not defined

Follow the guide to enable codebase context checks.

Custom Compliance
No custom compliance provided

Follow the guide to enable custom compliance check.

  • Update
Compliance status legend 🟢 - Fully Compliant
🟡 - Partial Compliant
🔴 - Not Compliant
⚪ - Requires Further Human Verification
🏷️ - Compliance label

Copy link
Contributor

qodo-merge-pro bot commented Oct 10, 2025

PR Code Suggestions ✨

Explore these optional code suggestions:

CategorySuggestion                                                                                                                                    Impact
High-level
Abstract the multi-organization iteration logic

The logic for iterating over organizations is duplicated in each resync
function. This should be abstracted into a reusable decorator or higher-order
function to reduce duplication and improve maintainability.

Examples:

integrations/github/main.py [154-180]
integrations/github/main.py [184-204]

Solution Walkthrough:

Before:

@ocean.on_resync(ObjectKind.REPOSITORY)
async def resync_repositories(kind: str):
    org_exporter = RestOrganizationExporter(...)
    port_app_config = cast(GithubPortAppConfig, event.port_app_config)
    org_options = ListOrganizationOptions(organizations=port_app_config.organizations)

    async for organizations in org_exporter.get_paginated_resources(org_options):
        tasks = (
            RestRepositoryExporter(...).get_paginated_resources(...)
            for org in organizations
        )
        async for repositories in stream_async_iterators_tasks(*tasks):
            yield repositories

@ocean.on_resync(ObjectKind.USER)
async def resync_users(kind: str):
    org_exporter = RestOrganizationExporter(...)
    port_app_config = cast(GithubPortAppConfig, event.port_app_config)
    org_options = ListOrganizationOptions(organizations=port_app_config.organizations)

    async for organizations in org_exporter.get_paginated_resources(org_options):
        tasks = (
            GraphQLUserExporter(...).get_paginated_resources(...)
            for org in organizations
        )
        async for users in stream_async_iterators_tasks(*tasks):
            yield users

After:

def for_each_organization(func):
    async def wrapper(kind: str):
        org_exporter = RestOrganizationExporter(...)
        port_app_config = cast(GithubPortAppConfig, event.port_app_config)
        org_options = ListOrganizationOptions(organizations=port_app_config.organizations)

        async for organizations in org_exporter.get_paginated_resources(org_options):
            async for results in func(kind, organizations):
                yield results
    return wrapper

@ocean.on_resync(ObjectKind.REPOSITORY)
@for_each_organization
async def resync_repositories(kind: str, organizations: list):
    tasks = (
        RestRepositoryExporter(...).get_paginated_resources(...)
        for org in organizations
    )
    async for repositories in stream_async_iterators_tasks(*tasks):
        yield repositories

@ocean.on_resync(ObjectKind.USER)
@for_each_organization
async def resync_users(kind: str, organizations: list):
    tasks = (
        GraphQLUserExporter(...).get_paginated_resources(...)
        for org in organizations
    )
    async for users in stream_async_iterators_tasks(*tasks):
        yield users
Suggestion importance[1-10]: 9

__

Why: The suggestion correctly identifies a significant code duplication pattern across all new resync functions in main.py, and proposing an abstraction would greatly improve code maintainability and readability.

High
Possible issue
Fix incorrect organization assignment bug

Fix a bug in the list comprehension by correctly sourcing the organization from
the files list for each repository, instead of using a stale value from the
previous loop.

integrations/github/github/core/exporters/file_exporter/utils.py [176-183]

 logger.info(
     f"Repository path map built for {len(repo_map)} repositories from {len(files)} file patterns."
 )
 
 return [
-    ListFileSearchOptions(organization=organization, repo_name=repo, files=files)
+    ListFileSearchOptions(
+        organization=files[0]["organization"], repo_name=repo, files=files
+    )
     for repo, files in repo_map.items()
 ]
  • Apply / Chat
Suggestion importance[1-10]: 9

__

Why: The suggestion correctly identifies a critical bug where a variable from an outer loop's scope is incorrectly used, leading to the wrong organization being assigned to all but the last group of repositories.

High
Prevent crashes from missing payload keys

Use safe dictionary access with .get() for payload["organization"]["login"] to
prevent potential KeyError exceptions if the organization key is missing from
the webhook payload.

integrations/github/github/webhook/webhook_processors/dependabot_webhook_processor.py [35-38]

 repo = payload["repository"]
 alert_number = alert["number"]
 repo_name = repo["name"]
-organization = payload["organization"]["login"]
+organization = payload.get("organization", {}).get("login")
 
+if not organization:
+    logger.debug("Skipping event as it is not related to an organization")
+    return WebhookEventRawResults()
+
  • Apply / Chat
Suggestion importance[1-10]: 8

__

Why: The suggestion correctly identifies a potential KeyError due to unsafe dictionary access and provides a robust solution using .get() to prevent crashes, which is a critical improvement for error handling.

Medium
General
Update tests for new function behavior

Update tests for parse_github_options to align with its new behavior of handling
a missing repo_name and requiring an organization.

integrations/github/tests/github/helpers/test_utils.py [136-151]

 def test_extract_missing_repo_name(self) -> None:
-    """Test that missing repo_name raises KeyError."""
-    params = {"other_param": "value"}
+    """Test that missing repo_name returns None for repo_name."""
+    params = {"organization": "test-org", "other_param": "value"}
 
-    with pytest.raises(KeyError, match="repo_name"):
-        extract_repo_params(params)
+    repo_name, organization, remaining_params = parse_github_options(params)
+
+    assert repo_name is None
+    assert organization == "test-org"
+    assert remaining_params == {"other_param": "value"}
 
 def test_extract_empty_dict(self) -> None:
-    """Test that empty dict raises KeyError."""
+    """Test that empty dict raises KeyError for organization."""
     params: Dict[str, Any] = {}
 
-    with pytest.raises(KeyError, match="repo_name"):
-        extract_repo_params(params)
+    with pytest.raises(KeyError, match="organization"):
+        parse_github_options(params)

[To ensure code accuracy, apply this suggestion manually]

Suggestion importance[1-10]: 8

__

Why: The suggestion correctly identifies that the tests are outdated due to a function signature and behavior change in the PR, and it provides the correct updated test logic.

Medium
Avoid nested async loops for concurrency

Refactor the nested async for loops to fetch repositories concurrently across
all organizations, improving performance.

integrations/github/main.py [255-279]

-async for organizations in org_exporter.get_paginated_resources(org_options):
-    tasks = []
-    for org in organizations:
-        org_name = org["login"]
-        repo_exporter = RestRepositoryExporter(rest_client)
-        workflow_exporter = RestWorkflowExporter(rest_client)
-
-        repo_options = ListRepositoryOptions(
-            organization=org_name, type=port_app_config.repository_type
-        )
-
-        async for repositories in repo_exporter.get_paginated_resources(
-            options=repo_options
-        ):
-            for repo in repositories:
-                tasks.append(
-                    workflow_exporter.get_paginated_resources(
-                        options=ListWorkflowOptions(
-                            organization=org_name, repo_name=repo["name"]
-                        )
+async def fetch_workflows_for_org(org: dict[str, Any]) -> list:
+    org_name = org["login"]
+    repo_exporter = RestRepositoryExporter(rest_client)
+    workflow_exporter = RestWorkflowExporter(rest_client)
+    repo_options = ListRepositoryOptions(
+        organization=org_name, type=port_app_config.repository_type
+    )
+    org_tasks = []
+    async for repositories in repo_exporter.get_paginated_resources(
+        options=repo_options
+    ):
+        for repo in repositories:
+            org_tasks.append(
+                workflow_exporter.get_paginated_resources(
+                    options=ListWorkflowOptions(
+                        organization=org_name, repo_name=repo["name"]
                     )
                 )
+            )
+    return org_tasks
 
-    async for workflows in stream_async_iterators_tasks(*tasks):
+async for organizations in org_exporter.get_paginated_resources(org_options):
+    all_tasks = []
+    org_tasks_results = await asyncio.gather(
+        *(fetch_workflows_for_org(org) for org in organizations)
+    )
+    for org_tasks in org_tasks_results:
+        all_tasks.extend(org_tasks)
+
+    async for workflows in stream_async_iterators_tasks(*all_tasks):
         yield workflows

[To ensure code accuracy, apply this suggestion manually]

Suggestion importance[1-10]: 7

__

Why: The suggestion correctly identifies a performance bottleneck from nested async loops and proposes a valid concurrent approach, which would significantly improve efficiency.

Medium
Optimize organization fetching with direct API calls
Suggestion Impact:The commit added logic to directly fetch a single specified organization via /orgs/{org} when only one org is provided, while still paginating and filtering when multiple orgs are specified or fetching all when none are specified.

code diff:

+        if len(organizations_set) > 1:
+            async for orgs in self.client.send_paginated_request(
+                f"{self.client.base_url}/user/orgs", {}
+            ):
                 filtered_orgs = [
                     org for org in orgs if org.get("login") in organizations_set
                 ]
@@ -30,8 +37,14 @@
                     f"Filtered to {len(filtered_orgs)} organizations from {len(orgs)} total"
                 )
                 yield filtered_orgs
-            else:
-                yield orgs
+
+        else:
+            org = next(iter(organizations_set))
+            logger.info(f"Fetching organization {org}")
+            org_data = await self.client.send_api_request(
+                f"{self.client.base_url}/orgs/{org}"
+            )
+            yield [org_data]

Optimize organization fetching by using the direct /orgs/{org} API endpoint for
specified organizations instead of fetching all and filtering them.

integrations/github/github/core/exporters/organization_exporter.py [19-34]

 organizations = options.get("organizations")
-organizations_set = set(organizations) if organizations else None
 
-async for orgs in self.client.send_paginated_request(
-    f"{self.client.base_url}/user/orgs", {}
-):
-    if organizations_set:
-        filtered_orgs = [
-            org for org in orgs if org.get("login") in organizations_set
-        ]
-        logger.info(
-            f"Filtered to {len(filtered_orgs)} organizations from {len(orgs)} total"
+if organizations:
+    logger.info(f"Fetching {len(organizations)} specified organizations")
+    for org_name in organizations:
+        org_data = await self.client.send_request(
+            "GET", f"{self.client.base_url}/orgs/{org_name}"
         )
-        yield filtered_orgs
-    else:
+        yield [org_data]
+else:
+    logger.info("Fetching all organizations for the user")
+    async for orgs in self.client.send_paginated_request(
+        f"{self.client.base_url}/user/orgs", {}
+    ):
         yield orgs

[Suggestion processed]

Suggestion importance[1-10]: 7

__

Why: The suggestion correctly identifies an inefficient data fetching pattern and proposes a more optimal solution by using a direct API endpoint, which reduces API usage and processing time.

Medium
  • Update

Copy link
Member

@mk-armah mk-armah left a comment

Choose a reason for hiding this comment

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

LGTM

Copy link
Member

@matan84 matan84 left a comment

Choose a reason for hiding this comment

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

Left small comments

Copy link
Member

@matan84 matan84 left a comment

Choose a reason for hiding this comment

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

LGTM

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants