openhound-github 0.21.3__tar.gz → 0.22.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {openhound_github-0.21.3 → openhound_github-0.22.1}/PKG-INFO +22 -1
- {openhound_github-0.21.3 → openhound_github-0.22.1}/README.md +21 -0
- openhound_github-0.22.1/descriptions/edges/GH_Owns.md +29 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/nodes/GH_App.md +8 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/extension/schema.json +1 -1
- openhound_github-0.22.1/src/openhound_github/github_rest_client.py +90 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/src/openhound_github/helpers.py +15 -8
- {openhound_github-0.21.3 → openhound_github-0.22.1}/src/openhound_github/lookup.py +32 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/src/openhound_github/models/app_installation.py +90 -5
- {openhound_github-0.21.3 → openhound_github-0.22.1}/src/openhound_github/resources/organization.py +28 -5
- {openhound_github-0.21.3 → openhound_github-0.22.1}/src/openhound_github/source.py +2 -5
- openhound_github-0.22.1/tests/test_app_model.py +121 -0
- openhound_github-0.22.1/tests/test_collection_continuation.py +153 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/tests/test_github_app_retry.py +36 -0
- openhound_github-0.22.1/tests/test_github_rest_client.py +161 -0
- openhound_github-0.22.1/tests/test_graphql_retry_budget.py +100 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/tests/test_lookup.py +38 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/tests/test_workflow_resources.py +61 -2
- openhound_github-0.21.3/descriptions/edges/GH_Owns.md +0 -20
- openhound_github-0.21.3/src/openhound_github/github_rest_client.py +0 -3
- openhound_github-0.21.3/tests/test_github_rest_client.py +0 -52
- {openhound_github-0.21.3 → openhound_github-0.22.1}/.dockerignore +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/.github/CODE_OF_CONDUCT.md +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/.github/CONTRIBUTING.md +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/.github/GOVERNANCE.md +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/.github/SECURITY.md +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/.github/SO-Dark.svg +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/.github/SO-FOSS-Dark.svg +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/.github/SO-FOSS-Light.svg +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/.github/SO-Light.svg +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/.github/workflows/publish-container.yml +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/.github/workflows/publish.yml +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/.github/workflows/release-on-merge.yml +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/.github/workflows/validate-branch.yml +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/.gitignore +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/.pre-commit-config.yaml +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/Dockerfile +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/LICENSE.md +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_AddAssignee.md +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_AddCollaborator.md +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_AddLabel.md +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_AddMember.md +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_AddedDeployKey.md +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_AdminTo.md +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_ApprovesDeploymentTo.md +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_AssignedTo.md +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_AuthorizedForOrganization.md +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_BypassBranchProtection.md +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_BypassPullRequestAllowances.md +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_CallsWorkflow.md +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_CanAccess.md +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_CanAccessSecret.md +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_CanAssumeIdentity.md +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_CanCreateBranch.md +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_CanCreateEnvironment.md +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_CanCreateInternalRepositories.md +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_CanCreatePrivateRepositories.md +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_CanCreatePublicRepositories.md +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_CanCreateRepositories.md +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_CanCreateRepositoryWithRunnerAccess.md +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_CanDeployToEnvironment.md +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_CanEditEnvironment.md +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_CanEditProtection.md +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_CanInterceptJob.md +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_CanPwnRequest.md +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_CanReadSecret.md +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_CanReadSecretScanningAlert.md +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_CanRequestOIDCTokenFor.md +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_CanUseRunner.md +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_CanWriteBranch.md +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_CloseDiscussion.md +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_CloseIssue.md +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_ClosePullRequest.md +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_Contains.md +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_ConvertIssuesToDiscussions.md +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_CreateDiscussionCategory.md +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_CreateEnterpriseOrganizations.md +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_CreateRepository.md +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_CreateSoloMergeQueueEntry.md +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_CreateTag.md +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_CreateTeam.md +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_DeleteAlertsCodeScanning.md +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_DeleteDiscussion.md +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_DeleteDiscussionComment.md +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_DeleteIssue.md +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_DeleteTag.md +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_DependsOn.md +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_DeploysTo.md +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_EditCategoryOnDiscussion.md +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_EditDiscussionCategory.md +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_EditDiscussionComment.md +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_EditEnterpriseCustomPropertiesForOrganizations.md +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_EditRepoAnnouncementBanners.md +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_EditRepoCustomPropertiesValues.md +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_EditRepoMetadata.md +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_EditRepoProtections.md +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_HasBaseRole.md +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_HasExternalIdentity.md +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_HasMember.md +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_HasPersonalAccessToken.md +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_HasPersonalAccessTokenRequest.md +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_HasRole.md +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_HasRunner.md +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_HasSamlIdentityProvider.md +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_HasSecret.md +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_HasVariable.md +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_InheritedFrom.md +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_InstalledAs.md +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_InviteMember.md +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_IsEligibleFor.md +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_JumpMergeQueue.md +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_ManageDeployKeys.md +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_ManageDiscussionBadges.md +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_ManageEnterpriseAdmins.md +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_ManageEnterpriseIdentityProvider.md +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_ManageEnterpriseMembers.md +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_ManageEnterpriseOrganizationAdmins.md +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_ManageEnterpriseOrganizations.md +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_ManageEnterpriseReferrals.md +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_ManageEnterpriseTeams.md +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_ManageOrganizationWebhooks.md +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_ManageRepoSecurityProducts.md +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_ManageSecurityProducts.md +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_ManageSettingsMergeTypes.md +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_ManageSettingsPages.md +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_ManageSettingsProjects.md +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_ManageSettingsWiki.md +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_ManageTopics.md +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_ManageWebhooks.md +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_MapsToUser.md +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_MarkAsDuplicate.md +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_MatchesEnvironmentPolicy.md +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_MemberOf.md +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_OrgBypassCodeScanningDismissalRequests.md +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_OrgBypassSecretScanningClosureRequests.md +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_OrgReviewAndManageSecretScanningBypassRequests.md +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_OrgReviewAndManageSecretScanningClosureRequests.md +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_ProtectedBy.md +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_PushProtectedBranch.md +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_ReadCodeScanning.md +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_ReadEnterpriseAuditLog.md +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_ReadEnterpriseDomainVerification.md +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_ReadEnterpriseMembers.md +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_ReadEnterpriseOrgProjects.md +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_ReadEnterpriseOrganizationAdmin.md +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_ReadOrganizationActionsUsageMetrics.md +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_ReadOrganizationCustomOrgRole.md +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_ReadOrganizationCustomRepoRole.md +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_ReadRepoContents.md +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_RemoveAssignee.md +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_RemoveLabel.md +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_ReopenDiscussion.md +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_ReopenIssue.md +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_ReopenPullRequest.md +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_RequestPrReview.md +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_RequestsAccessTo.md +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_ResolveDependabotAlerts.md +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_ResolveSecretScanningAlerts.md +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_RestrictionsCanPush.md +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_RunOrgMigration.md +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_RunsOn.md +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_ScopedTo.md +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_SetEnterpriseInteractionLimits.md +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_SetInteractionLimits.md +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_SetIssueType.md +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_SetMilestone.md +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_SetSocialPreview.md +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_SyncedTo.md +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_ToggleDiscussionAnswer.md +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_ToggleDiscussionCommentMinimize.md +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_TransferRepository.md +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_UsesSecret.md +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_UsesVariable.md +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_ValidToken.md +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_ViewDependabotAlerts.md +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_ViewEnterpriseActionsUsageMetrics.md +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_ViewEnterpriseBilling.md +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_ViewEnterpriseSecretScanningAlerts.md +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_ViewSecretScanningAlerts.md +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_WriteCodeScanning.md +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_WriteEnterpriseActionsPolicies.md +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_WriteEnterpriseBilling.md +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_WriteEnterprisePersonalAccessTokenPolicies.md +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_WriteEnterpriseSso.md +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_WriteEnterpriseTeamMembers.md +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_WriteOrganizationActionsSecrets.md +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_WriteOrganizationActionsSettings.md +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_WriteOrganizationActionsVariables.md +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_WriteOrganizationCustomOrgRole.md +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_WriteOrganizationCustomRepoRole.md +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_WriteOrganizationNetworkConfigurations.md +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_WriteRepoContents.md +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_WriteRepoPullRequests.md +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/nodes/GH_AppInstallation.md +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/nodes/GH_Branch.md +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/nodes/GH_BranchProtectionRule.md +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/nodes/GH_ClassicPersonalAccessToken.md +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/nodes/GH_DeployKey.md +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/nodes/GH_Enterprise.md +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/nodes/GH_EnterpriseManagedUser.md +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/nodes/GH_EnterpriseRole.md +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/nodes/GH_EnterpriseRunner.md +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/nodes/GH_EnterpriseRunnerGroup.md +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/nodes/GH_EnterpriseTeam.md +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/nodes/GH_Environment.md +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/nodes/GH_EnvironmentBranchPolicy.md +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/nodes/GH_EnvironmentSecret.md +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/nodes/GH_EnvironmentVariable.md +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/nodes/GH_ExternalIdentity.md +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/nodes/GH_OrgRole.md +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/nodes/GH_OrgRunner.md +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/nodes/GH_OrgRunnerGroup.md +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/nodes/GH_OrgSecret.md +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/nodes/GH_OrgVariable.md +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/nodes/GH_Organization.md +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/nodes/GH_PersonalAccessToken.md +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/nodes/GH_PersonalAccessTokenRequest.md +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/nodes/GH_RepoRole.md +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/nodes/GH_RepoRunner.md +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/nodes/GH_RepoSecret.md +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/nodes/GH_RepoVariable.md +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/nodes/GH_Repository.md +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/nodes/GH_Runner.md +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/nodes/GH_RunnerGroup.md +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/nodes/GH_SamlIdentityProvider.md +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/nodes/GH_Scope.md +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/nodes/GH_Secret.md +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/nodes/GH_SecretScanningAlert.md +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/nodes/GH_Team.md +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/nodes/GH_TeamRole.md +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/nodes/GH_User.md +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/nodes/GH_Variable.md +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/nodes/GH_Workflow.md +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/nodes/GH_WorkflowJob.md +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/nodes/GH_WorkflowStep.md +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/docker-compose/.dlt/config.toml.example +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/docker-compose/.dlt/secrets.toml.example +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/docker-compose/.env.example +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/docker-compose/README.md +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/docker-compose/check_config.py +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/docker-compose/compose.yaml +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/extension/privilege_zone_rules/t0-all-repo-admin-role.json +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/extension/privilege_zone_rules/t0-app-installations-all-repos.json +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/extension/privilege_zone_rules/t0-apps-all-repos.json +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/extension/privilege_zone_rules/t0-enterprise-owners-role.json +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/extension/privilege_zone_rules/t0-external-identities-owners.json +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/extension/privilege_zone_rules/t0-organizations.json +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/extension/privilege_zone_rules/t0-owner-users.json +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/extension/privilege_zone_rules/t0-owners-role.json +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/extension/privilege_zone_rules/t0-pats-all-repos.json +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/extension/privilege_zone_rules/t0-privilege-escalation-roles.json +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/extension/privilege_zone_rules/t0-privilege-escalation-users.json +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/extension/privilege_zone_rules/t0-saml-identity-providers.json +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/extension/saved_searches/README.md +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/extension/saved_searches/actions-sha-pinning-not-required.json +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/extension/saved_searches/active-leaked-secrets.json +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/extension/saved_searches/advanced-security-disabled-new-repos.json +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/extension/saved_searches/all-actions-allowed.json +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/extension/saved_searches/app-installations-all-repos.json +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/extension/saved_searches/branch-protection-admins-not-enforced.json +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/extension/saved_searches/branch-protection-deletions-allowed.json +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/extension/saved_searches/branch-protection-force-pushes.json +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/extension/saved_searches/branch-protection-no-code-owner-reviews.json +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/extension/saved_searches/branch-protection-no-pr-reviews.json +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/extension/saved_searches/branch-protection-no-status-checks.json +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/extension/saved_searches/branch-protection-self-approval.json +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/extension/saved_searches/branch-protection-stale-reviews.json +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/extension/saved_searches/bypass-pr-requirements.json +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/extension/saved_searches/dangerous-branch-perms.json +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/extension/saved_searches/default-repository-permissions.json +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/extension/saved_searches/demo-sso-to-cloud-round-trip.json +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/extension/saved_searches/dependabot-alerts-disabled-new-repos.json +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/extension/saved_searches/dependabot-updates-disabled-new-repos.json +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/extension/saved_searches/dependency-graph-disabled-new-repos.json +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/extension/saved_searches/environments-admin-bypass.json +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/extension/saved_searches/expired-pats.json +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/extension/saved_searches/external-identities-without-scim.json +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/extension/saved_searches/github-to-azure-identity.json +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/extension/saved_searches/global-repo-perms.json +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/extension/saved_searches/hybrid-identities.json +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/extension/saved_searches/members-can-change-repo-visibility.json +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/extension/saved_searches/members-can-create-pages.json +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/extension/saved_searches/members-can-create-public-repos.json +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/extension/saved_searches/members-can-delete-repos.json +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/extension/saved_searches/members-can-fork-private-repos.json +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/extension/saved_searches/members-can-invite-outside-collaborators.json +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/extension/saved_searches/org-owners.json +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/extension/saved_searches/orgs-without-2fa.json +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/extension/saved_searches/pats-all-repo-access.json +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/extension/saved_searches/pending-pat-requests.json +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/extension/saved_searches/private-repos-forking-allowed.json +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/extension/saved_searches/privileged-custom-org-roles.json +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/extension/saved_searches/privileged-hybrid-identities.json +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/extension/saved_searches/public-repos.json +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/extension/saved_searches/push-protection-disabled-new-repos.json +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/extension/saved_searches/push-to-protected-branches.json +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/extension/saved_searches/repos-secret-scanning-disabled.json +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/extension/saved_searches/repos-vulnerable-to-workflow-secret-exfil.json +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/extension/saved_searches/repository-workflows.json +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/extension/saved_searches/saml-configuration.json +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/extension/saved_searches/secret-scanning-alerts.json +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/extension/saved_searches/secret-scanning-disabled-new-repos.json +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/extension/saved_searches/secrets-reachable-by-user.json +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/extension/saved_searches/self-hosted-runners-can-intercept-broad-token-jobs.json +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/extension/saved_searches/shared-self-hosted-runners-can-intercept-secret-bearing-jobs.json +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/extension/saved_searches/team-membership-admin.json +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/extension/saved_searches/team-structure.json +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/extension/saved_searches/unprotected-branches.json +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/extension/saved_searches/unprotected-default-branch-with-workflow.json +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/extension/saved_searches/unprotected-default-branches.json +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/extension/saved_searches/web-commit-signoff-not-required.json +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/extension/saved_searches/workflow-jobs-interceptable-by-self-hosted-runners.json +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/extension/saved_searches/workflow-jobs-with-broad-token-write-permissions.json +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/extension/saved_searches/workflow-jobs-with-id-token-write-on-self-hosted-runners.json +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/extension/saved_searches/workflow-jobs-with-id-token-write.json +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/extension/saved_searches/workflow-jobs-with-observed-oidc-auth-steps.json +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/justfile +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/pyproject.toml +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/scripts/generate_gh_description_docs.py +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/src/main.py +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/src/openhound_github/__init__.py +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/src/openhound_github/auth.py +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/src/openhound_github/extension.yaml +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/src/openhound_github/github_retry.py +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/src/openhound_github/graph.py +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/src/openhound_github/graphql.py +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/src/openhound_github/kinds/edges.py +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/src/openhound_github/kinds/nodes.py +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/src/openhound_github/main.py +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/src/openhound_github/models/__init__.py +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/src/openhound_github/models/actions_permission.py +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/src/openhound_github/models/branch.py +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/src/openhound_github/models/branch_pr_bypass_allowance.py +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/src/openhound_github/models/branch_protection_rule.py +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/src/openhound_github/models/branch_push_allowance.py +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/src/openhound_github/models/classic_personal_access_token.py +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/src/openhound_github/models/deploy_key.py +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/src/openhound_github/models/enterprise.py +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/src/openhound_github/models/enterprise_admin.py +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/src/openhound_github/models/enterprise_credential_inventory.py +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/src/openhound_github/models/enterprise_helpers.py +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/src/openhound_github/models/enterprise_managed_user.py +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/src/openhound_github/models/enterprise_member.py +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/src/openhound_github/models/enterprise_organization.py +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/src/openhound_github/models/enterprise_role.py +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/src/openhound_github/models/enterprise_role_team.py +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/src/openhound_github/models/enterprise_role_user.py +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/src/openhound_github/models/enterprise_team.py +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/src/openhound_github/models/enterprise_team_member.py +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/src/openhound_github/models/enterprise_team_organization.py +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/src/openhound_github/models/enterprise_team_role.py +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/src/openhound_github/models/enterprise_user.py +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/src/openhound_github/models/env_secret.py +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/src/openhound_github/models/env_variable.py +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/src/openhound_github/models/environment.py +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/src/openhound_github/models/environment_branch_policy.py +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/src/openhound_github/models/external_identity.py +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/src/openhound_github/models/org.py +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/src/openhound_github/models/org_role.py +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/src/openhound_github/models/org_role_member.py +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/src/openhound_github/models/org_role_team.py +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/src/openhound_github/models/org_secret.py +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/src/openhound_github/models/org_variable.py +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/src/openhound_github/models/permissions.py +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/src/openhound_github/models/personal_access_token.py +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/src/openhound_github/models/personal_access_token_access.py +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/src/openhound_github/models/personal_access_token_request.py +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/src/openhound_github/models/projected_enterprise_team.py +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/src/openhound_github/models/repo_role_assignment.py +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/src/openhound_github/models/repository.py +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/src/openhound_github/models/repository_role.py +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/src/openhound_github/models/repository_secret.py +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/src/openhound_github/models/repository_variable.py +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/src/openhound_github/models/runner.py +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/src/openhound_github/models/saml_assertion_consumer_service.py +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/src/openhound_github/models/saml_helpers.py +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/src/openhound_github/models/saml_issuer.py +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/src/openhound_github/models/saml_provider.py +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/src/openhound_github/models/saml_service_provider.py +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/src/openhound_github/models/scim_user.py +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/src/openhound_github/models/scope.py +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/src/openhound_github/models/secret_scanning_alert.py +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/src/openhound_github/models/team.py +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/src/openhound_github/models/team_member.py +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/src/openhound_github/models/team_role.py +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/src/openhound_github/models/user.py +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/src/openhound_github/models/workflow.py +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/src/openhound_github/models/workflow_job.py +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/src/openhound_github/models/workflow_reference.py +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/src/openhound_github/models/workflow_step.py +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/src/openhound_github/resources/__init__.py +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/src/openhound_github/resources/enterprise.py +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/src/openhound_github/runner_ids.py +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/src/openhound_github/transforms.py +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/src/scheduler.py +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/tests/test_app_auth.py +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/tests/test_app_installation_repo_access.py +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/tests/test_branch_collection_gate.py +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/tests/test_branch_protection_traversability.py +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/tests/test_classic_personal_access_tokens.py +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/tests/test_credential_permission_models.py +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/tests/test_data/api/actions-permissions.json +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/tests/test_data/api/actionsecrets.json +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/tests/test_data/api/app.json +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/tests/test_data/api/appinstalls.json +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/tests/test_data/api/branch-policies.json +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/tests/test_data/api/branch-prot-rules.json +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/tests/test_data/api/branches.json +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/tests/test_data/api/custom-roles.json +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/tests/test_data/api/environments.json +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/tests/test_data/api/org-pat-request.json +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/tests/test_data/api/org-pat.json +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/tests/test_data/api/org-role-teams.json +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/tests/test_data/api/org-role-users.json +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/tests/test_data/api/org-roles.json +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/tests/test_data/api/org.json +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/tests/test_data/api/pat-repositories.json +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/tests/test_data/api/repo-collaborators.json +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/tests/test_data/api/repo-teams.json +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/tests/test_data/api/repositories.json +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/tests/test_data/api/scimusers.json +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/tests/test_data/api/secrets.json +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/tests/test_data/api/secretscanningalert.json +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/tests/test_data/api/selected-org-secrets.json +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/tests/test_data/api/variables.json +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/tests/test_data/api/workflows.json +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/tests/test_deploy_key_models.py +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/tests/test_deploy_key_resources.py +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/tests/test_description_docs.py +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/tests/test_enterprise_capabilities.py +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/tests/test_enterprise_organization.py +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/tests/test_enterprise_resources.py +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/tests/test_environment_model.py +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/tests/test_environment_resources.py +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/tests/test_environment_reviewer_lookup.py +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/tests/test_error_resilience.py +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/tests/test_github_retry.py +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/tests/test_helpers.py +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/tests/test_org_role_model.py +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/tests/test_org_scim_resources.py +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/tests/test_org_secret_models.py +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/tests/test_preproc.py +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/tests/test_repository_rulesets.py +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/tests/test_repository_scopes.py +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/tests/test_runner_ids.py +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/tests/test_runner_models.py +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/tests/test_runner_resources.py +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/tests/test_saml_helpers.py +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/tests/test_saml_models.py +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/tests/test_scim_models.py +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/tests/test_source_endpoints.py +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/tests/test_source_org_canonicalization.py +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/tests/test_team_external_groups.py +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/tests/test_variable_models.py +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/tests/test_workflow_interception_path.py +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/tests/test_workflow_model.py +0 -0
- {openhound_github-0.21.3 → openhound_github-0.22.1}/uv.lock +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: openhound-github
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.22.1
|
|
4
4
|
Summary: Github collector for OpenHound
|
|
5
5
|
Author-email: "jdreijer@specterops.io" <jdreijer@specterops.io>, Jared Atkinson <jatkinson@specterops.io>
|
|
6
6
|
License-File: LICENSE.md
|
|
@@ -66,6 +66,27 @@ Both values must be provided together when overriding the GitHub.com defaults.
|
|
|
66
66
|
Endpoint URLs must use HTTPS and share the same origin. GitHub App
|
|
67
67
|
`credentials.api_uri` may override only the path on that same origin.
|
|
68
68
|
|
|
69
|
+
### Request timeouts and retries
|
|
70
|
+
|
|
71
|
+
REST and GraphQL collection requests use a 10-second connection timeout and a
|
|
72
|
+
30-second read timeout. Transient HTTP 5xx errors, connection failures, and
|
|
73
|
+
timeouts share a limit of three attempts (the initial attempt plus two retries).
|
|
74
|
+
Adaptive GraphQL pagination shares that limit across page sizes: HTTP 502/504
|
|
75
|
+
responses trigger smaller-page attempts instead of a new retry budget.
|
|
76
|
+
|
|
77
|
+
After retries are exhausted, existing resource handlers log the failure and
|
|
78
|
+
continue with unaffected scopes. Already emitted records are retained, but the
|
|
79
|
+
affected scope may be incomplete. Resources that require all pages before
|
|
80
|
+
emitting records retain that behavior.
|
|
81
|
+
|
|
82
|
+
Workflow collection skips `dynamic/` paths. Missing workflow files are logged
|
|
83
|
+
and skipped without passing failed items to job or step parsing.
|
|
84
|
+
|
|
85
|
+
Rate-limit responses and GitHub App token refresh retain their existing retry
|
|
86
|
+
handling and do not consume the transient-failure budget. These timeouts are
|
|
87
|
+
not an overall request deadline. App authentication requests and credential
|
|
88
|
+
inventory CSV downloads retain their separate timeout settings.
|
|
89
|
+
|
|
69
90
|
### Enterprise SCIM and hybrid correlations
|
|
70
91
|
|
|
71
92
|
A token with enterprise SCIM access is used to collect both `/scim/v2/enterprises/{enterprise}/Users` and `/scim/v2/enterprises/{enterprise}/Groups`. The collector emits normalized `SCIM_Organization`, `SCIM_User`, and `SCIM_Group` nodes plus `SCIM_Contains`, `SCIM_MemberOf`, and `SCIM_Provisioned` relationships. Install the BloodHound SCIM extension alongside this extension to register the shared SCIM kinds.
|
|
@@ -55,6 +55,27 @@ Both values must be provided together when overriding the GitHub.com defaults.
|
|
|
55
55
|
Endpoint URLs must use HTTPS and share the same origin. GitHub App
|
|
56
56
|
`credentials.api_uri` may override only the path on that same origin.
|
|
57
57
|
|
|
58
|
+
### Request timeouts and retries
|
|
59
|
+
|
|
60
|
+
REST and GraphQL collection requests use a 10-second connection timeout and a
|
|
61
|
+
30-second read timeout. Transient HTTP 5xx errors, connection failures, and
|
|
62
|
+
timeouts share a limit of three attempts (the initial attempt plus two retries).
|
|
63
|
+
Adaptive GraphQL pagination shares that limit across page sizes: HTTP 502/504
|
|
64
|
+
responses trigger smaller-page attempts instead of a new retry budget.
|
|
65
|
+
|
|
66
|
+
After retries are exhausted, existing resource handlers log the failure and
|
|
67
|
+
continue with unaffected scopes. Already emitted records are retained, but the
|
|
68
|
+
affected scope may be incomplete. Resources that require all pages before
|
|
69
|
+
emitting records retain that behavior.
|
|
70
|
+
|
|
71
|
+
Workflow collection skips `dynamic/` paths. Missing workflow files are logged
|
|
72
|
+
and skipped without passing failed items to job or step parsing.
|
|
73
|
+
|
|
74
|
+
Rate-limit responses and GitHub App token refresh retain their existing retry
|
|
75
|
+
handling and do not consume the transient-failure budget. These timeouts are
|
|
76
|
+
not an overall request deadline. App authentication requests and credential
|
|
77
|
+
inventory CSV downloads retain their separate timeout settings.
|
|
78
|
+
|
|
58
79
|
### Enterprise SCIM and hybrid correlations
|
|
59
80
|
|
|
60
81
|
A token with enterprise SCIM access is used to collect both `/scim/v2/enterprises/{enterprise}/Users` and `/scim/v2/enterprises/{enterprise}/Groups`. The collector emits normalized `SCIM_Organization`, `SCIM_User`, and `SCIM_Group` nodes plus `SCIM_Contains`, `SCIM_MemberOf`, and `SCIM_Provisioned` relationships. Install the BloodHound SCIM extension alongside this extension to register the shared SCIM kinds.
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# GH_Owns
|
|
2
|
+
|
|
3
|
+
## General Information
|
|
4
|
+
|
|
5
|
+
The traversable GH_Owns edge represents that a GitHub account owns an application or repository. For GitHub Apps, ownership identifies the account whose authorized administrators can manage the App registration and credentials. For repositories, ownership links the repository to its organization. These control relationships are traversable for attack-path analysis.
|
|
6
|
+
|
|
7
|
+
## Edge Schema
|
|
8
|
+
|
|
9
|
+
| Source | Destination | Traversable |
|
|
10
|
+
| --- | --- | --- |
|
|
11
|
+
| `GH_Enterprise` | `GH_App` | `true` |
|
|
12
|
+
| `GH_Organization` | `GH_App` | `true` |
|
|
13
|
+
| `GH_Organization` | `GH_Repository` | `true` |
|
|
14
|
+
| `GH_User` | `GH_App` | `true` |
|
|
15
|
+
|
|
16
|
+
## Diagram
|
|
17
|
+
|
|
18
|
+
```mermaid
|
|
19
|
+
graph LR
|
|
20
|
+
n0["GH_Enterprise"]
|
|
21
|
+
n1["GH_App"]
|
|
22
|
+
n2["GH_Organization"]
|
|
23
|
+
n3["GH_Repository"]
|
|
24
|
+
n4["GH_User"]
|
|
25
|
+
n0 -->|GH_Owns| n1
|
|
26
|
+
n2 -->|GH_Owns| n1
|
|
27
|
+
n2 -->|GH_Owns| n3
|
|
28
|
+
n4 -->|GH_Owns| n1
|
|
29
|
+
```
|
|
@@ -24,10 +24,12 @@ App definitions are retrieved via the public `GET /apps/{app_slug}` endpoint (no
|
|
|
24
24
|
| `owner_login` | `string` | The login of the user or organization that owns the app. |
|
|
25
25
|
| `owner_node_id` | `string` | The node_id of the user or organization that owns the app. |
|
|
26
26
|
| `owner_type` | `string` | The type of the owner (e.g., `User`, `Organization`). |
|
|
27
|
+
| `registration_origin` | `string` | Whether the app is tenant-owned, third-party, or unknown. |
|
|
27
28
|
| `events` | `list[string]` | JSON string of the default webhook events the app subscribes to. |
|
|
28
29
|
| `installations_count` | `integer` | The total number of installations of this app across all organizations. |
|
|
29
30
|
| `created_at` | `datetime` | When the app was created. |
|
|
30
31
|
| `updated_at` | `datetime` | When the app was last updated. |
|
|
32
|
+
| `query_owner` | `string` | Query for the account that registered the app. |
|
|
31
33
|
| `query_installations` | `string` | Query for installations. |
|
|
32
34
|
|
|
33
35
|
## Diagram
|
|
@@ -36,5 +38,11 @@ App definitions are retrieved via the public `GET /apps/{app_slug}` endpoint (no
|
|
|
36
38
|
graph LR
|
|
37
39
|
n0["GH_App"]
|
|
38
40
|
n1["GH_AppInstallation"]
|
|
41
|
+
n2["GH_Enterprise"]
|
|
42
|
+
n3["GH_Organization"]
|
|
43
|
+
n4["GH_User"]
|
|
39
44
|
n0 -->|GH_InstalledAs| n1
|
|
45
|
+
n2 -->|GH_Owns| n0
|
|
46
|
+
n3 -->|GH_Owns| n0
|
|
47
|
+
n4 -->|GH_Owns| n0
|
|
40
48
|
```
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
from contextlib import contextmanager
|
|
2
|
+
from contextvars import ContextVar
|
|
3
|
+
from dataclasses import dataclass
|
|
4
|
+
from functools import wraps
|
|
5
|
+
|
|
6
|
+
from dlt.sources.helpers import requests
|
|
7
|
+
from requests.exceptions import ChunkedEncodingError, ConnectionError, Timeout
|
|
8
|
+
from tenacity import RetryCallState
|
|
9
|
+
from tenacity.stop import stop_base
|
|
10
|
+
|
|
11
|
+
from openhound_github.github_retry import should_retry_github_response
|
|
12
|
+
|
|
13
|
+
__all__ = ["github_http_session", "should_retry_github_response"]
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
@dataclass
|
|
17
|
+
class GraphQLPageRetryBudget:
|
|
18
|
+
"""Share transient failures across page sizes without changing other requests."""
|
|
19
|
+
|
|
20
|
+
failures: int = 0
|
|
21
|
+
|
|
22
|
+
@property
|
|
23
|
+
def exhausted(self) -> bool:
|
|
24
|
+
return self.failures >= 3
|
|
25
|
+
|
|
26
|
+
@contextmanager
|
|
27
|
+
def activate(self):
|
|
28
|
+
token = _graphql_page_budget.set(self)
|
|
29
|
+
try:
|
|
30
|
+
yield
|
|
31
|
+
finally:
|
|
32
|
+
_graphql_page_budget.reset(token)
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
_graphql_page_budget: ContextVar[GraphQLPageRetryBudget | None] = ContextVar(
|
|
36
|
+
"github_graphql_page_budget", default=None
|
|
37
|
+
)
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
class _StopAfterTransientFailures(stop_base):
|
|
41
|
+
"""Count transient failures per send, independently of other retry reasons."""
|
|
42
|
+
|
|
43
|
+
def __call__(self, retry_state: RetryCallState) -> bool:
|
|
44
|
+
outcome = retry_state.outcome
|
|
45
|
+
if outcome is None:
|
|
46
|
+
return False
|
|
47
|
+
exception = outcome.exception()
|
|
48
|
+
response = None
|
|
49
|
+
if isinstance(exception, requests.HTTPError):
|
|
50
|
+
response = exception.response
|
|
51
|
+
elif exception is None:
|
|
52
|
+
response = outcome.result()
|
|
53
|
+
transient = isinstance(exception, (ConnectionError, Timeout, ChunkedEncodingError)) or (
|
|
54
|
+
response is not None and 500 <= response.status_code < 600
|
|
55
|
+
)
|
|
56
|
+
page_budget = _graphql_page_budget.get()
|
|
57
|
+
if page_budget is not None:
|
|
58
|
+
page_budget.failures += int(transient)
|
|
59
|
+
# Return gateway errors immediately so pagination can shrink the page.
|
|
60
|
+
return page_budget.exhausted or (
|
|
61
|
+
response is not None and response.status_code in (502, 504)
|
|
62
|
+
)
|
|
63
|
+
failures = getattr(retry_state, "_github_transient_failures", 0) + int(transient)
|
|
64
|
+
setattr(retry_state, "_github_transient_failures", failures)
|
|
65
|
+
return failures >= 3
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
def github_http_session(retry_condition):
|
|
69
|
+
"""Bound transient failures while retaining DLT's existing retry policy."""
|
|
70
|
+
session = requests.Client(
|
|
71
|
+
request_timeout=(10, 30),
|
|
72
|
+
status_codes=tuple(range(500, 600)),
|
|
73
|
+
retry_condition=retry_condition,
|
|
74
|
+
).session
|
|
75
|
+
# Keep the configured overall limit for rate limits and credential refresh.
|
|
76
|
+
# RetryCallState is new for every send, including concurrent requests.
|
|
77
|
+
retry = session.send.retry
|
|
78
|
+
retry.stop = _StopAfterTransientFailures() | retry.stop
|
|
79
|
+
send = session.send
|
|
80
|
+
|
|
81
|
+
@wraps(send)
|
|
82
|
+
def send_with_status_check(request, **kwargs):
|
|
83
|
+
response = send(request, **kwargs)
|
|
84
|
+
# RESTClient calls send directly, bypassing Session.request's status check.
|
|
85
|
+
# Raise only after the retry loop finishes so scope handlers can skip it.
|
|
86
|
+
response.raise_for_status()
|
|
87
|
+
return response
|
|
88
|
+
|
|
89
|
+
session.send = send_with_status_check
|
|
90
|
+
return session
|
|
@@ -14,6 +14,7 @@ from dlt.sources.helpers.rest_client.paginators import (
|
|
|
14
14
|
from requests import Request
|
|
15
15
|
|
|
16
16
|
from openhound_github.auth import GitHubAppInstallationAuth
|
|
17
|
+
from openhound_github.github_rest_client import GraphQLPageRetryBudget
|
|
17
18
|
from openhound_github.github_retry import (
|
|
18
19
|
is_primary_rate_limit_response,
|
|
19
20
|
is_secondary_rate_limit_response,
|
|
@@ -230,9 +231,9 @@ def adaptive_graphql_paginate(
|
|
|
230
231
|
) -> Iterator[dict[str, Any]]:
|
|
231
232
|
"""Yield GraphQL pages while adapting connection size after gateway failures.
|
|
232
233
|
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
234
|
+
HTTP retries and smaller-page recovery share three transient attempts per
|
|
235
|
+
page. Gateway errors return immediately so the next attempt can shrink the
|
|
236
|
+
page; rate-limit and credential-refresh retries retain their existing policy.
|
|
236
237
|
"""
|
|
237
238
|
if not page_sizes or any(page_size <= 0 for page_size in page_sizes):
|
|
238
239
|
raise ValueError("page_sizes must contain positive integers")
|
|
@@ -270,6 +271,7 @@ def adaptive_graphql_paginate(
|
|
|
270
271
|
page_data: dict[str, Any] | None = None
|
|
271
272
|
paginator: GraphQLCursorPaginator | None = None
|
|
272
273
|
successful_page_size: int | None = None
|
|
274
|
+
retry_budget = GraphQLPageRetryBudget()
|
|
273
275
|
|
|
274
276
|
for index, page_size in enumerate(candidate_sizes):
|
|
275
277
|
request_variables = {
|
|
@@ -278,10 +280,11 @@ def adaptive_graphql_paginate(
|
|
|
278
280
|
page_size_variable: page_size,
|
|
279
281
|
}
|
|
280
282
|
try:
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
283
|
+
with retry_budget.activate():
|
|
284
|
+
response = client.post(
|
|
285
|
+
graphql_path,
|
|
286
|
+
json={"query": query, "variables": request_variables},
|
|
287
|
+
)
|
|
285
288
|
response.raise_for_status()
|
|
286
289
|
response_json = response.json()
|
|
287
290
|
paginator = GraphQLCursorPaginator(
|
|
@@ -303,7 +306,11 @@ def adaptive_graphql_paginate(
|
|
|
303
306
|
status_code = _graphql_gateway_status(error)
|
|
304
307
|
next_page_size = (
|
|
305
308
|
candidate_sizes[index + 1]
|
|
306
|
-
if
|
|
309
|
+
if (
|
|
310
|
+
status_code is not None
|
|
311
|
+
and index + 1 < len(candidate_sizes)
|
|
312
|
+
and not retry_budget.exhausted
|
|
313
|
+
)
|
|
307
314
|
else None
|
|
308
315
|
)
|
|
309
316
|
if next_page_size is not None:
|
|
@@ -118,6 +118,38 @@ class GithubLookup(LookupManager):
|
|
|
118
118
|
[enterprise_node_id],
|
|
119
119
|
)
|
|
120
120
|
|
|
121
|
+
@lru_cache
|
|
122
|
+
def is_tenant_organization_node_id(self, node_id: str) -> bool:
|
|
123
|
+
"""Return whether an organization belongs to the collected tenant."""
|
|
124
|
+
collected_org_id = self._find_single_object(
|
|
125
|
+
f"""SELECT node_id FROM {self.schema}.organizations WHERE node_id = ?""",
|
|
126
|
+
[node_id],
|
|
127
|
+
)
|
|
128
|
+
if collected_org_id is not None:
|
|
129
|
+
return True
|
|
130
|
+
|
|
131
|
+
enterprise_org_id = self._find_single_object(
|
|
132
|
+
f"""SELECT id FROM {self.schema}.enterprise_organizations WHERE id = ?""",
|
|
133
|
+
[node_id],
|
|
134
|
+
)
|
|
135
|
+
return enterprise_org_id is not None
|
|
136
|
+
|
|
137
|
+
@lru_cache
|
|
138
|
+
def is_collected_user_node_id(self, node_id: str) -> bool:
|
|
139
|
+
"""Return whether a user node exists in collected organization or enterprise data."""
|
|
140
|
+
organization_user_id = self._find_single_object(
|
|
141
|
+
f"""SELECT id FROM {self.schema}.users WHERE id = ?""",
|
|
142
|
+
[node_id],
|
|
143
|
+
)
|
|
144
|
+
if organization_user_id is not None:
|
|
145
|
+
return True
|
|
146
|
+
|
|
147
|
+
enterprise_user_id = self._find_single_object(
|
|
148
|
+
f"""SELECT id FROM {self.schema}.enterprise_users WHERE id = ?""",
|
|
149
|
+
[node_id],
|
|
150
|
+
)
|
|
151
|
+
return enterprise_user_id is not None
|
|
152
|
+
|
|
121
153
|
@lru_cache
|
|
122
154
|
def _enterprise_runner_group_identity_for_inherited_org_group(
|
|
123
155
|
self, org_node_id: str, group_name: str
|
{openhound_github-0.21.3 → openhound_github-0.22.1}/src/openhound_github/models/app_installation.py
RENAMED
|
@@ -215,10 +215,12 @@ class GHAppProperties(GHNodeProperties):
|
|
|
215
215
|
owner_login: The login of the user or organization that owns the app.
|
|
216
216
|
owner_node_id: The node_id of the user or organization that owns the app.
|
|
217
217
|
owner_type: The type of the owner (e.g., `User`, `Organization`).
|
|
218
|
+
registration_origin: Whether the app is tenant-owned, third-party, or unknown.
|
|
218
219
|
events: JSON string of the default webhook events the app subscribes to.
|
|
219
220
|
installations_count: The total number of installations of this app across all organizations.
|
|
220
221
|
created_at: When the app was created.
|
|
221
222
|
updated_at: When the app was last updated.
|
|
223
|
+
query_owner: Query for the account that registered the app.
|
|
222
224
|
query_installations: Query for installations.
|
|
223
225
|
"""
|
|
224
226
|
|
|
@@ -231,10 +233,12 @@ class GHAppProperties(GHNodeProperties):
|
|
|
231
233
|
owner_login: str | None = None
|
|
232
234
|
owner_node_id: str | None = None
|
|
233
235
|
owner_type: str | None = None
|
|
236
|
+
registration_origin: str | None = None
|
|
234
237
|
events: list[str] | None = None
|
|
235
238
|
installations_count: int | None = None
|
|
236
239
|
created_at: datetime | None = None
|
|
237
240
|
updated_at: datetime | None = None
|
|
241
|
+
query_owner: str | None = None
|
|
238
242
|
query_installations: str | None = None
|
|
239
243
|
|
|
240
244
|
|
|
@@ -252,6 +256,29 @@ class Owner(BaseModel):
|
|
|
252
256
|
icon="cube",
|
|
253
257
|
properties=GHAppProperties,
|
|
254
258
|
),
|
|
259
|
+
edges=[
|
|
260
|
+
EdgeDef(
|
|
261
|
+
start=nk.ENTERPRISE,
|
|
262
|
+
end=nk.APP,
|
|
263
|
+
kind=ek.OWNS,
|
|
264
|
+
description="Enterprise owns GitHub App",
|
|
265
|
+
traversable=True,
|
|
266
|
+
),
|
|
267
|
+
EdgeDef(
|
|
268
|
+
start=nk.ORGANIZATION,
|
|
269
|
+
end=nk.APP,
|
|
270
|
+
kind=ek.OWNS,
|
|
271
|
+
description="Organization owns GitHub App",
|
|
272
|
+
traversable=True,
|
|
273
|
+
),
|
|
274
|
+
EdgeDef(
|
|
275
|
+
start=nk.USER,
|
|
276
|
+
end=nk.APP,
|
|
277
|
+
kind=ek.OWNS,
|
|
278
|
+
description="User owns GitHub App",
|
|
279
|
+
traversable=True,
|
|
280
|
+
),
|
|
281
|
+
],
|
|
255
282
|
)
|
|
256
283
|
class App(BaseAsset):
|
|
257
284
|
"""One record from `apps` → one GH_App node. Edges (GH_InstalledAs) are emitted by AppInstallationAsset."""
|
|
@@ -262,7 +289,7 @@ class App(BaseAsset):
|
|
|
262
289
|
slug: str
|
|
263
290
|
client_id: str | None = None
|
|
264
291
|
node_id: str
|
|
265
|
-
owner: Owner
|
|
292
|
+
owner: Owner | None = None
|
|
266
293
|
name: str
|
|
267
294
|
description: str | None = None
|
|
268
295
|
permissions: dict
|
|
@@ -282,6 +309,51 @@ class App(BaseAsset):
|
|
|
282
309
|
return self.collected_org_node_id
|
|
283
310
|
return self._lookup.org_id_for_login(self.org_login)
|
|
284
311
|
|
|
312
|
+
@property
|
|
313
|
+
def registration_origin(self) -> str:
|
|
314
|
+
if self.owner is None:
|
|
315
|
+
return "unknown"
|
|
316
|
+
|
|
317
|
+
owner_type = self.owner.type.casefold()
|
|
318
|
+
if owner_type == "user":
|
|
319
|
+
return "third_party"
|
|
320
|
+
|
|
321
|
+
if owner_type == "organization":
|
|
322
|
+
if self._lookup.is_tenant_organization_node_id(self.owner.node_id):
|
|
323
|
+
return "tenant_owned"
|
|
324
|
+
return "third_party" if self._lookup.enterprise_id() else "unknown"
|
|
325
|
+
|
|
326
|
+
if owner_type == "enterprise":
|
|
327
|
+
enterprise_id = self._lookup.enterprise_id()
|
|
328
|
+
if enterprise_id is None:
|
|
329
|
+
return "unknown"
|
|
330
|
+
return (
|
|
331
|
+
"tenant_owned"
|
|
332
|
+
if self.owner.node_id == enterprise_id
|
|
333
|
+
else "third_party"
|
|
334
|
+
)
|
|
335
|
+
|
|
336
|
+
return "unknown"
|
|
337
|
+
|
|
338
|
+
@property
|
|
339
|
+
def registration_owner_node_id(self) -> str | None:
|
|
340
|
+
if self.owner is None:
|
|
341
|
+
return None
|
|
342
|
+
|
|
343
|
+
owner_type = self.owner.type.casefold()
|
|
344
|
+
if owner_type == "organization":
|
|
345
|
+
owner_exists = self._lookup.is_tenant_organization_node_id(
|
|
346
|
+
self.owner.node_id
|
|
347
|
+
)
|
|
348
|
+
elif owner_type == "enterprise":
|
|
349
|
+
owner_exists = self._lookup.enterprise_id() == self.owner.node_id
|
|
350
|
+
elif owner_type == "user":
|
|
351
|
+
owner_exists = self._lookup.is_collected_user_node_id(self.owner.node_id)
|
|
352
|
+
else:
|
|
353
|
+
owner_exists = False
|
|
354
|
+
|
|
355
|
+
return self.owner.node_id if owner_exists else None
|
|
356
|
+
|
|
285
357
|
@property
|
|
286
358
|
def as_node(self):
|
|
287
359
|
aid = self.node_id
|
|
@@ -298,21 +370,34 @@ class App(BaseAsset):
|
|
|
298
370
|
description=self.description,
|
|
299
371
|
external_url=self.external_url,
|
|
300
372
|
html_url=self.html_url,
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
373
|
+
owner_login=self.owner.login if self.owner else None,
|
|
374
|
+
owner_node_id=self.owner.node_id if self.owner else None,
|
|
375
|
+
owner_type=self.owner.type if self.owner else None,
|
|
376
|
+
registration_origin=self.registration_origin,
|
|
304
377
|
# permissions=self.permissions,
|
|
305
378
|
# installations_count=self.installations_count,
|
|
306
379
|
events=self.events,
|
|
307
380
|
created_at=self.created_at,
|
|
308
381
|
updated_at=self.updated_at,
|
|
382
|
+
query_owner=f"MATCH p=(owner)-[:GH_Owns]->(:GH_App {{node_id:'{aid}'}}) RETURN p",
|
|
309
383
|
query_installations=f"MATCH p=(:GH_App {{node_id:'{aid}'}})-[:GH_InstalledAs]->(:GH_AppInstallation) RETURN p",
|
|
310
384
|
),
|
|
311
385
|
)
|
|
312
386
|
|
|
313
387
|
@property
|
|
314
388
|
def edges(self) -> list[Edge]:
|
|
315
|
-
|
|
389
|
+
owner_node_id = self.registration_owner_node_id
|
|
390
|
+
if owner_node_id is None:
|
|
391
|
+
return []
|
|
392
|
+
|
|
393
|
+
return [
|
|
394
|
+
Edge(
|
|
395
|
+
kind=ek.OWNS,
|
|
396
|
+
start=EdgePath(value=owner_node_id, match_by="id"),
|
|
397
|
+
end=EdgePath(value=self.node_id, match_by="id"),
|
|
398
|
+
properties=EdgeProperties(traversable=True),
|
|
399
|
+
)
|
|
400
|
+
]
|
|
316
401
|
|
|
317
402
|
|
|
318
403
|
@app.asset(
|
{openhound_github-0.21.3 → openhound_github-0.22.1}/src/openhound_github/resources/organization.py
RENAMED
|
@@ -6,6 +6,7 @@ from threading import Lock
|
|
|
6
6
|
from typing import Any, Iterator
|
|
7
7
|
from urllib.parse import quote
|
|
8
8
|
|
|
9
|
+
import dlt
|
|
9
10
|
from dlt.sources.helpers import requests
|
|
10
11
|
from dlt.sources.helpers.rest_client.client import RESTClient
|
|
11
12
|
from dlt.sources.helpers.rest_client.paginators import (
|
|
@@ -1475,7 +1476,7 @@ def workflows(repo: Repository, ctx: SourceContext):
|
|
|
1475
1476
|
Workflow (Workflow): An active workflow record.
|
|
1476
1477
|
"""
|
|
1477
1478
|
|
|
1478
|
-
@
|
|
1479
|
+
@dlt.defer
|
|
1479
1480
|
def _workflow_file_contents(
|
|
1480
1481
|
client: RESTClient,
|
|
1481
1482
|
repo: Repository,
|
|
@@ -1487,11 +1488,30 @@ def workflows(repo: Repository, ctx: SourceContext):
|
|
|
1487
1488
|
return None
|
|
1488
1489
|
|
|
1489
1490
|
params = {"ref": repo.default_branch} if repo.default_branch else None
|
|
1490
|
-
|
|
1491
|
-
|
|
1492
|
-
|
|
1491
|
+
try:
|
|
1492
|
+
response = client.get(
|
|
1493
|
+
f"/repos/{repo.full_name}/contents/{path}", params=params
|
|
1494
|
+
).json()
|
|
1495
|
+
content = response.get("content")
|
|
1496
|
+
except Exception as exc:
|
|
1497
|
+
# Return None so DLT drops the failed item. app.defer returns [],
|
|
1498
|
+
# which can reach the job/step transformers as an invalid Workflow.
|
|
1499
|
+
if (
|
|
1500
|
+
isinstance(exc, requests.HTTPError)
|
|
1501
|
+
and exc.response is not None
|
|
1502
|
+
and exc.response.status_code == 404
|
|
1503
|
+
):
|
|
1504
|
+
logger.warning(
|
|
1505
|
+
"Skipping workflow '%s' in repository '%s': file unavailable at ref '%s' (HTTP 404)",
|
|
1506
|
+
path, repo.full_name, repo.default_branch,
|
|
1507
|
+
)
|
|
1508
|
+
else:
|
|
1509
|
+
logger.error(
|
|
1510
|
+
"Unable to collect workflow '%s' in repository '%s': %s",
|
|
1511
|
+
path, repo.full_name, exc,
|
|
1512
|
+
)
|
|
1513
|
+
return None
|
|
1493
1514
|
|
|
1494
|
-
content = response.get("content")
|
|
1495
1515
|
if not content:
|
|
1496
1516
|
return None
|
|
1497
1517
|
|
|
@@ -1517,6 +1537,9 @@ def workflows(repo: Repository, ctx: SourceContext):
|
|
|
1517
1537
|
):
|
|
1518
1538
|
for workflow in page:
|
|
1519
1539
|
if workflow.get("state") == "active":
|
|
1540
|
+
path = workflow.get("path")
|
|
1541
|
+
if not path or path.startswith("dynamic/"):
|
|
1542
|
+
continue
|
|
1520
1543
|
if workflow_permissions is None:
|
|
1521
1544
|
workflow_permissions = _repository_workflow_permissions(
|
|
1522
1545
|
ctx, client, repo.full_name
|
|
@@ -8,7 +8,6 @@ from urllib.parse import urlparse
|
|
|
8
8
|
import dlt
|
|
9
9
|
from dlt.common.configuration import configspec
|
|
10
10
|
from dlt.common.configuration.specs import CredentialsConfiguration
|
|
11
|
-
from dlt.sources.helpers import requests
|
|
12
11
|
from dlt.sources.helpers.rest_client.auth import AuthConfigBase
|
|
13
12
|
from dlt.sources.helpers.rest_client.auth import BearerTokenAuth
|
|
14
13
|
from dlt.sources.helpers.rest_client.client import RESTClient
|
|
@@ -27,6 +26,7 @@ from openhound_github.helpers import (
|
|
|
27
26
|
DEFAULT_GITHUB_REST_API_URL,
|
|
28
27
|
github_retry_policy,
|
|
29
28
|
)
|
|
29
|
+
from openhound_github.github_rest_client import github_http_session
|
|
30
30
|
from openhound_github.main import app
|
|
31
31
|
from openhound_github.models.saml_helpers import (
|
|
32
32
|
DEFAULT_GITHUB_DEPLOYMENT_ID,
|
|
@@ -352,10 +352,7 @@ def source(
|
|
|
352
352
|
},
|
|
353
353
|
auth=auth,
|
|
354
354
|
paginator=HeaderLinkPaginator(),
|
|
355
|
-
session=
|
|
356
|
-
status_codes=tuple(range(500, 600)),
|
|
357
|
-
retry_condition=github_retry_policy(auth),
|
|
358
|
-
).session,
|
|
355
|
+
session=github_http_session(github_retry_policy(auth)),
|
|
359
356
|
)
|
|
360
357
|
|
|
361
358
|
def clients(auth: AuthConfigBase) -> tuple[RESTClient, RESTClient]:
|