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.
Files changed (457) hide show
  1. {openhound_github-0.21.3 → openhound_github-0.22.1}/PKG-INFO +22 -1
  2. {openhound_github-0.21.3 → openhound_github-0.22.1}/README.md +21 -0
  3. openhound_github-0.22.1/descriptions/edges/GH_Owns.md +29 -0
  4. {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/nodes/GH_App.md +8 -0
  5. {openhound_github-0.21.3 → openhound_github-0.22.1}/extension/schema.json +1 -1
  6. openhound_github-0.22.1/src/openhound_github/github_rest_client.py +90 -0
  7. {openhound_github-0.21.3 → openhound_github-0.22.1}/src/openhound_github/helpers.py +15 -8
  8. {openhound_github-0.21.3 → openhound_github-0.22.1}/src/openhound_github/lookup.py +32 -0
  9. {openhound_github-0.21.3 → openhound_github-0.22.1}/src/openhound_github/models/app_installation.py +90 -5
  10. {openhound_github-0.21.3 → openhound_github-0.22.1}/src/openhound_github/resources/organization.py +28 -5
  11. {openhound_github-0.21.3 → openhound_github-0.22.1}/src/openhound_github/source.py +2 -5
  12. openhound_github-0.22.1/tests/test_app_model.py +121 -0
  13. openhound_github-0.22.1/tests/test_collection_continuation.py +153 -0
  14. {openhound_github-0.21.3 → openhound_github-0.22.1}/tests/test_github_app_retry.py +36 -0
  15. openhound_github-0.22.1/tests/test_github_rest_client.py +161 -0
  16. openhound_github-0.22.1/tests/test_graphql_retry_budget.py +100 -0
  17. {openhound_github-0.21.3 → openhound_github-0.22.1}/tests/test_lookup.py +38 -0
  18. {openhound_github-0.21.3 → openhound_github-0.22.1}/tests/test_workflow_resources.py +61 -2
  19. openhound_github-0.21.3/descriptions/edges/GH_Owns.md +0 -20
  20. openhound_github-0.21.3/src/openhound_github/github_rest_client.py +0 -3
  21. openhound_github-0.21.3/tests/test_github_rest_client.py +0 -52
  22. {openhound_github-0.21.3 → openhound_github-0.22.1}/.dockerignore +0 -0
  23. {openhound_github-0.21.3 → openhound_github-0.22.1}/.github/CODE_OF_CONDUCT.md +0 -0
  24. {openhound_github-0.21.3 → openhound_github-0.22.1}/.github/CONTRIBUTING.md +0 -0
  25. {openhound_github-0.21.3 → openhound_github-0.22.1}/.github/GOVERNANCE.md +0 -0
  26. {openhound_github-0.21.3 → openhound_github-0.22.1}/.github/SECURITY.md +0 -0
  27. {openhound_github-0.21.3 → openhound_github-0.22.1}/.github/SO-Dark.svg +0 -0
  28. {openhound_github-0.21.3 → openhound_github-0.22.1}/.github/SO-FOSS-Dark.svg +0 -0
  29. {openhound_github-0.21.3 → openhound_github-0.22.1}/.github/SO-FOSS-Light.svg +0 -0
  30. {openhound_github-0.21.3 → openhound_github-0.22.1}/.github/SO-Light.svg +0 -0
  31. {openhound_github-0.21.3 → openhound_github-0.22.1}/.github/workflows/publish-container.yml +0 -0
  32. {openhound_github-0.21.3 → openhound_github-0.22.1}/.github/workflows/publish.yml +0 -0
  33. {openhound_github-0.21.3 → openhound_github-0.22.1}/.github/workflows/release-on-merge.yml +0 -0
  34. {openhound_github-0.21.3 → openhound_github-0.22.1}/.github/workflows/validate-branch.yml +0 -0
  35. {openhound_github-0.21.3 → openhound_github-0.22.1}/.gitignore +0 -0
  36. {openhound_github-0.21.3 → openhound_github-0.22.1}/.pre-commit-config.yaml +0 -0
  37. {openhound_github-0.21.3 → openhound_github-0.22.1}/Dockerfile +0 -0
  38. {openhound_github-0.21.3 → openhound_github-0.22.1}/LICENSE.md +0 -0
  39. {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_AddAssignee.md +0 -0
  40. {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_AddCollaborator.md +0 -0
  41. {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_AddLabel.md +0 -0
  42. {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_AddMember.md +0 -0
  43. {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_AddedDeployKey.md +0 -0
  44. {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_AdminTo.md +0 -0
  45. {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_ApprovesDeploymentTo.md +0 -0
  46. {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_AssignedTo.md +0 -0
  47. {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_AuthorizedForOrganization.md +0 -0
  48. {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_BypassBranchProtection.md +0 -0
  49. {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_BypassPullRequestAllowances.md +0 -0
  50. {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_CallsWorkflow.md +0 -0
  51. {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_CanAccess.md +0 -0
  52. {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_CanAccessSecret.md +0 -0
  53. {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_CanAssumeIdentity.md +0 -0
  54. {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_CanCreateBranch.md +0 -0
  55. {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_CanCreateEnvironment.md +0 -0
  56. {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_CanCreateInternalRepositories.md +0 -0
  57. {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_CanCreatePrivateRepositories.md +0 -0
  58. {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_CanCreatePublicRepositories.md +0 -0
  59. {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_CanCreateRepositories.md +0 -0
  60. {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_CanCreateRepositoryWithRunnerAccess.md +0 -0
  61. {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_CanDeployToEnvironment.md +0 -0
  62. {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_CanEditEnvironment.md +0 -0
  63. {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_CanEditProtection.md +0 -0
  64. {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_CanInterceptJob.md +0 -0
  65. {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_CanPwnRequest.md +0 -0
  66. {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_CanReadSecret.md +0 -0
  67. {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_CanReadSecretScanningAlert.md +0 -0
  68. {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_CanRequestOIDCTokenFor.md +0 -0
  69. {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_CanUseRunner.md +0 -0
  70. {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_CanWriteBranch.md +0 -0
  71. {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_CloseDiscussion.md +0 -0
  72. {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_CloseIssue.md +0 -0
  73. {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_ClosePullRequest.md +0 -0
  74. {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_Contains.md +0 -0
  75. {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_ConvertIssuesToDiscussions.md +0 -0
  76. {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_CreateDiscussionCategory.md +0 -0
  77. {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_CreateEnterpriseOrganizations.md +0 -0
  78. {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_CreateRepository.md +0 -0
  79. {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_CreateSoloMergeQueueEntry.md +0 -0
  80. {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_CreateTag.md +0 -0
  81. {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_CreateTeam.md +0 -0
  82. {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_DeleteAlertsCodeScanning.md +0 -0
  83. {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_DeleteDiscussion.md +0 -0
  84. {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_DeleteDiscussionComment.md +0 -0
  85. {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_DeleteIssue.md +0 -0
  86. {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_DeleteTag.md +0 -0
  87. {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_DependsOn.md +0 -0
  88. {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_DeploysTo.md +0 -0
  89. {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_EditCategoryOnDiscussion.md +0 -0
  90. {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_EditDiscussionCategory.md +0 -0
  91. {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_EditDiscussionComment.md +0 -0
  92. {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_EditEnterpriseCustomPropertiesForOrganizations.md +0 -0
  93. {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_EditRepoAnnouncementBanners.md +0 -0
  94. {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_EditRepoCustomPropertiesValues.md +0 -0
  95. {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_EditRepoMetadata.md +0 -0
  96. {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_EditRepoProtections.md +0 -0
  97. {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_HasBaseRole.md +0 -0
  98. {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_HasExternalIdentity.md +0 -0
  99. {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_HasMember.md +0 -0
  100. {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_HasPersonalAccessToken.md +0 -0
  101. {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_HasPersonalAccessTokenRequest.md +0 -0
  102. {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_HasRole.md +0 -0
  103. {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_HasRunner.md +0 -0
  104. {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_HasSamlIdentityProvider.md +0 -0
  105. {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_HasSecret.md +0 -0
  106. {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_HasVariable.md +0 -0
  107. {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_InheritedFrom.md +0 -0
  108. {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_InstalledAs.md +0 -0
  109. {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_InviteMember.md +0 -0
  110. {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_IsEligibleFor.md +0 -0
  111. {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_JumpMergeQueue.md +0 -0
  112. {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_ManageDeployKeys.md +0 -0
  113. {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_ManageDiscussionBadges.md +0 -0
  114. {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_ManageEnterpriseAdmins.md +0 -0
  115. {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_ManageEnterpriseIdentityProvider.md +0 -0
  116. {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_ManageEnterpriseMembers.md +0 -0
  117. {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_ManageEnterpriseOrganizationAdmins.md +0 -0
  118. {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_ManageEnterpriseOrganizations.md +0 -0
  119. {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_ManageEnterpriseReferrals.md +0 -0
  120. {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_ManageEnterpriseTeams.md +0 -0
  121. {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_ManageOrganizationWebhooks.md +0 -0
  122. {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_ManageRepoSecurityProducts.md +0 -0
  123. {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_ManageSecurityProducts.md +0 -0
  124. {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_ManageSettingsMergeTypes.md +0 -0
  125. {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_ManageSettingsPages.md +0 -0
  126. {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_ManageSettingsProjects.md +0 -0
  127. {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_ManageSettingsWiki.md +0 -0
  128. {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_ManageTopics.md +0 -0
  129. {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_ManageWebhooks.md +0 -0
  130. {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_MapsToUser.md +0 -0
  131. {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_MarkAsDuplicate.md +0 -0
  132. {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_MatchesEnvironmentPolicy.md +0 -0
  133. {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_MemberOf.md +0 -0
  134. {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_OrgBypassCodeScanningDismissalRequests.md +0 -0
  135. {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_OrgBypassSecretScanningClosureRequests.md +0 -0
  136. {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_OrgReviewAndManageSecretScanningBypassRequests.md +0 -0
  137. {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_OrgReviewAndManageSecretScanningClosureRequests.md +0 -0
  138. {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_ProtectedBy.md +0 -0
  139. {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_PushProtectedBranch.md +0 -0
  140. {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_ReadCodeScanning.md +0 -0
  141. {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_ReadEnterpriseAuditLog.md +0 -0
  142. {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_ReadEnterpriseDomainVerification.md +0 -0
  143. {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_ReadEnterpriseMembers.md +0 -0
  144. {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_ReadEnterpriseOrgProjects.md +0 -0
  145. {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_ReadEnterpriseOrganizationAdmin.md +0 -0
  146. {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_ReadOrganizationActionsUsageMetrics.md +0 -0
  147. {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_ReadOrganizationCustomOrgRole.md +0 -0
  148. {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_ReadOrganizationCustomRepoRole.md +0 -0
  149. {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_ReadRepoContents.md +0 -0
  150. {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_RemoveAssignee.md +0 -0
  151. {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_RemoveLabel.md +0 -0
  152. {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_ReopenDiscussion.md +0 -0
  153. {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_ReopenIssue.md +0 -0
  154. {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_ReopenPullRequest.md +0 -0
  155. {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_RequestPrReview.md +0 -0
  156. {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_RequestsAccessTo.md +0 -0
  157. {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_ResolveDependabotAlerts.md +0 -0
  158. {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_ResolveSecretScanningAlerts.md +0 -0
  159. {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_RestrictionsCanPush.md +0 -0
  160. {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_RunOrgMigration.md +0 -0
  161. {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_RunsOn.md +0 -0
  162. {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_ScopedTo.md +0 -0
  163. {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_SetEnterpriseInteractionLimits.md +0 -0
  164. {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_SetInteractionLimits.md +0 -0
  165. {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_SetIssueType.md +0 -0
  166. {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_SetMilestone.md +0 -0
  167. {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_SetSocialPreview.md +0 -0
  168. {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_SyncedTo.md +0 -0
  169. {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_ToggleDiscussionAnswer.md +0 -0
  170. {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_ToggleDiscussionCommentMinimize.md +0 -0
  171. {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_TransferRepository.md +0 -0
  172. {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_UsesSecret.md +0 -0
  173. {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_UsesVariable.md +0 -0
  174. {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_ValidToken.md +0 -0
  175. {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_ViewDependabotAlerts.md +0 -0
  176. {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_ViewEnterpriseActionsUsageMetrics.md +0 -0
  177. {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_ViewEnterpriseBilling.md +0 -0
  178. {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_ViewEnterpriseSecretScanningAlerts.md +0 -0
  179. {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_ViewSecretScanningAlerts.md +0 -0
  180. {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_WriteCodeScanning.md +0 -0
  181. {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_WriteEnterpriseActionsPolicies.md +0 -0
  182. {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_WriteEnterpriseBilling.md +0 -0
  183. {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_WriteEnterprisePersonalAccessTokenPolicies.md +0 -0
  184. {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_WriteEnterpriseSso.md +0 -0
  185. {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_WriteEnterpriseTeamMembers.md +0 -0
  186. {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_WriteOrganizationActionsSecrets.md +0 -0
  187. {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_WriteOrganizationActionsSettings.md +0 -0
  188. {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_WriteOrganizationActionsVariables.md +0 -0
  189. {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_WriteOrganizationCustomOrgRole.md +0 -0
  190. {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_WriteOrganizationCustomRepoRole.md +0 -0
  191. {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_WriteOrganizationNetworkConfigurations.md +0 -0
  192. {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_WriteRepoContents.md +0 -0
  193. {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/edges/GH_WriteRepoPullRequests.md +0 -0
  194. {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/nodes/GH_AppInstallation.md +0 -0
  195. {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/nodes/GH_Branch.md +0 -0
  196. {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/nodes/GH_BranchProtectionRule.md +0 -0
  197. {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/nodes/GH_ClassicPersonalAccessToken.md +0 -0
  198. {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/nodes/GH_DeployKey.md +0 -0
  199. {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/nodes/GH_Enterprise.md +0 -0
  200. {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/nodes/GH_EnterpriseManagedUser.md +0 -0
  201. {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/nodes/GH_EnterpriseRole.md +0 -0
  202. {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/nodes/GH_EnterpriseRunner.md +0 -0
  203. {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/nodes/GH_EnterpriseRunnerGroup.md +0 -0
  204. {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/nodes/GH_EnterpriseTeam.md +0 -0
  205. {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/nodes/GH_Environment.md +0 -0
  206. {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/nodes/GH_EnvironmentBranchPolicy.md +0 -0
  207. {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/nodes/GH_EnvironmentSecret.md +0 -0
  208. {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/nodes/GH_EnvironmentVariable.md +0 -0
  209. {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/nodes/GH_ExternalIdentity.md +0 -0
  210. {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/nodes/GH_OrgRole.md +0 -0
  211. {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/nodes/GH_OrgRunner.md +0 -0
  212. {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/nodes/GH_OrgRunnerGroup.md +0 -0
  213. {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/nodes/GH_OrgSecret.md +0 -0
  214. {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/nodes/GH_OrgVariable.md +0 -0
  215. {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/nodes/GH_Organization.md +0 -0
  216. {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/nodes/GH_PersonalAccessToken.md +0 -0
  217. {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/nodes/GH_PersonalAccessTokenRequest.md +0 -0
  218. {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/nodes/GH_RepoRole.md +0 -0
  219. {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/nodes/GH_RepoRunner.md +0 -0
  220. {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/nodes/GH_RepoSecret.md +0 -0
  221. {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/nodes/GH_RepoVariable.md +0 -0
  222. {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/nodes/GH_Repository.md +0 -0
  223. {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/nodes/GH_Runner.md +0 -0
  224. {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/nodes/GH_RunnerGroup.md +0 -0
  225. {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/nodes/GH_SamlIdentityProvider.md +0 -0
  226. {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/nodes/GH_Scope.md +0 -0
  227. {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/nodes/GH_Secret.md +0 -0
  228. {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/nodes/GH_SecretScanningAlert.md +0 -0
  229. {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/nodes/GH_Team.md +0 -0
  230. {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/nodes/GH_TeamRole.md +0 -0
  231. {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/nodes/GH_User.md +0 -0
  232. {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/nodes/GH_Variable.md +0 -0
  233. {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/nodes/GH_Workflow.md +0 -0
  234. {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/nodes/GH_WorkflowJob.md +0 -0
  235. {openhound_github-0.21.3 → openhound_github-0.22.1}/descriptions/nodes/GH_WorkflowStep.md +0 -0
  236. {openhound_github-0.21.3 → openhound_github-0.22.1}/docker-compose/.dlt/config.toml.example +0 -0
  237. {openhound_github-0.21.3 → openhound_github-0.22.1}/docker-compose/.dlt/secrets.toml.example +0 -0
  238. {openhound_github-0.21.3 → openhound_github-0.22.1}/docker-compose/.env.example +0 -0
  239. {openhound_github-0.21.3 → openhound_github-0.22.1}/docker-compose/README.md +0 -0
  240. {openhound_github-0.21.3 → openhound_github-0.22.1}/docker-compose/check_config.py +0 -0
  241. {openhound_github-0.21.3 → openhound_github-0.22.1}/docker-compose/compose.yaml +0 -0
  242. {openhound_github-0.21.3 → openhound_github-0.22.1}/extension/privilege_zone_rules/t0-all-repo-admin-role.json +0 -0
  243. {openhound_github-0.21.3 → openhound_github-0.22.1}/extension/privilege_zone_rules/t0-app-installations-all-repos.json +0 -0
  244. {openhound_github-0.21.3 → openhound_github-0.22.1}/extension/privilege_zone_rules/t0-apps-all-repos.json +0 -0
  245. {openhound_github-0.21.3 → openhound_github-0.22.1}/extension/privilege_zone_rules/t0-enterprise-owners-role.json +0 -0
  246. {openhound_github-0.21.3 → openhound_github-0.22.1}/extension/privilege_zone_rules/t0-external-identities-owners.json +0 -0
  247. {openhound_github-0.21.3 → openhound_github-0.22.1}/extension/privilege_zone_rules/t0-organizations.json +0 -0
  248. {openhound_github-0.21.3 → openhound_github-0.22.1}/extension/privilege_zone_rules/t0-owner-users.json +0 -0
  249. {openhound_github-0.21.3 → openhound_github-0.22.1}/extension/privilege_zone_rules/t0-owners-role.json +0 -0
  250. {openhound_github-0.21.3 → openhound_github-0.22.1}/extension/privilege_zone_rules/t0-pats-all-repos.json +0 -0
  251. {openhound_github-0.21.3 → openhound_github-0.22.1}/extension/privilege_zone_rules/t0-privilege-escalation-roles.json +0 -0
  252. {openhound_github-0.21.3 → openhound_github-0.22.1}/extension/privilege_zone_rules/t0-privilege-escalation-users.json +0 -0
  253. {openhound_github-0.21.3 → openhound_github-0.22.1}/extension/privilege_zone_rules/t0-saml-identity-providers.json +0 -0
  254. {openhound_github-0.21.3 → openhound_github-0.22.1}/extension/saved_searches/README.md +0 -0
  255. {openhound_github-0.21.3 → openhound_github-0.22.1}/extension/saved_searches/actions-sha-pinning-not-required.json +0 -0
  256. {openhound_github-0.21.3 → openhound_github-0.22.1}/extension/saved_searches/active-leaked-secrets.json +0 -0
  257. {openhound_github-0.21.3 → openhound_github-0.22.1}/extension/saved_searches/advanced-security-disabled-new-repos.json +0 -0
  258. {openhound_github-0.21.3 → openhound_github-0.22.1}/extension/saved_searches/all-actions-allowed.json +0 -0
  259. {openhound_github-0.21.3 → openhound_github-0.22.1}/extension/saved_searches/app-installations-all-repos.json +0 -0
  260. {openhound_github-0.21.3 → openhound_github-0.22.1}/extension/saved_searches/branch-protection-admins-not-enforced.json +0 -0
  261. {openhound_github-0.21.3 → openhound_github-0.22.1}/extension/saved_searches/branch-protection-deletions-allowed.json +0 -0
  262. {openhound_github-0.21.3 → openhound_github-0.22.1}/extension/saved_searches/branch-protection-force-pushes.json +0 -0
  263. {openhound_github-0.21.3 → openhound_github-0.22.1}/extension/saved_searches/branch-protection-no-code-owner-reviews.json +0 -0
  264. {openhound_github-0.21.3 → openhound_github-0.22.1}/extension/saved_searches/branch-protection-no-pr-reviews.json +0 -0
  265. {openhound_github-0.21.3 → openhound_github-0.22.1}/extension/saved_searches/branch-protection-no-status-checks.json +0 -0
  266. {openhound_github-0.21.3 → openhound_github-0.22.1}/extension/saved_searches/branch-protection-self-approval.json +0 -0
  267. {openhound_github-0.21.3 → openhound_github-0.22.1}/extension/saved_searches/branch-protection-stale-reviews.json +0 -0
  268. {openhound_github-0.21.3 → openhound_github-0.22.1}/extension/saved_searches/bypass-pr-requirements.json +0 -0
  269. {openhound_github-0.21.3 → openhound_github-0.22.1}/extension/saved_searches/dangerous-branch-perms.json +0 -0
  270. {openhound_github-0.21.3 → openhound_github-0.22.1}/extension/saved_searches/default-repository-permissions.json +0 -0
  271. {openhound_github-0.21.3 → openhound_github-0.22.1}/extension/saved_searches/demo-sso-to-cloud-round-trip.json +0 -0
  272. {openhound_github-0.21.3 → openhound_github-0.22.1}/extension/saved_searches/dependabot-alerts-disabled-new-repos.json +0 -0
  273. {openhound_github-0.21.3 → openhound_github-0.22.1}/extension/saved_searches/dependabot-updates-disabled-new-repos.json +0 -0
  274. {openhound_github-0.21.3 → openhound_github-0.22.1}/extension/saved_searches/dependency-graph-disabled-new-repos.json +0 -0
  275. {openhound_github-0.21.3 → openhound_github-0.22.1}/extension/saved_searches/environments-admin-bypass.json +0 -0
  276. {openhound_github-0.21.3 → openhound_github-0.22.1}/extension/saved_searches/expired-pats.json +0 -0
  277. {openhound_github-0.21.3 → openhound_github-0.22.1}/extension/saved_searches/external-identities-without-scim.json +0 -0
  278. {openhound_github-0.21.3 → openhound_github-0.22.1}/extension/saved_searches/github-to-azure-identity.json +0 -0
  279. {openhound_github-0.21.3 → openhound_github-0.22.1}/extension/saved_searches/global-repo-perms.json +0 -0
  280. {openhound_github-0.21.3 → openhound_github-0.22.1}/extension/saved_searches/hybrid-identities.json +0 -0
  281. {openhound_github-0.21.3 → openhound_github-0.22.1}/extension/saved_searches/members-can-change-repo-visibility.json +0 -0
  282. {openhound_github-0.21.3 → openhound_github-0.22.1}/extension/saved_searches/members-can-create-pages.json +0 -0
  283. {openhound_github-0.21.3 → openhound_github-0.22.1}/extension/saved_searches/members-can-create-public-repos.json +0 -0
  284. {openhound_github-0.21.3 → openhound_github-0.22.1}/extension/saved_searches/members-can-delete-repos.json +0 -0
  285. {openhound_github-0.21.3 → openhound_github-0.22.1}/extension/saved_searches/members-can-fork-private-repos.json +0 -0
  286. {openhound_github-0.21.3 → openhound_github-0.22.1}/extension/saved_searches/members-can-invite-outside-collaborators.json +0 -0
  287. {openhound_github-0.21.3 → openhound_github-0.22.1}/extension/saved_searches/org-owners.json +0 -0
  288. {openhound_github-0.21.3 → openhound_github-0.22.1}/extension/saved_searches/orgs-without-2fa.json +0 -0
  289. {openhound_github-0.21.3 → openhound_github-0.22.1}/extension/saved_searches/pats-all-repo-access.json +0 -0
  290. {openhound_github-0.21.3 → openhound_github-0.22.1}/extension/saved_searches/pending-pat-requests.json +0 -0
  291. {openhound_github-0.21.3 → openhound_github-0.22.1}/extension/saved_searches/private-repos-forking-allowed.json +0 -0
  292. {openhound_github-0.21.3 → openhound_github-0.22.1}/extension/saved_searches/privileged-custom-org-roles.json +0 -0
  293. {openhound_github-0.21.3 → openhound_github-0.22.1}/extension/saved_searches/privileged-hybrid-identities.json +0 -0
  294. {openhound_github-0.21.3 → openhound_github-0.22.1}/extension/saved_searches/public-repos.json +0 -0
  295. {openhound_github-0.21.3 → openhound_github-0.22.1}/extension/saved_searches/push-protection-disabled-new-repos.json +0 -0
  296. {openhound_github-0.21.3 → openhound_github-0.22.1}/extension/saved_searches/push-to-protected-branches.json +0 -0
  297. {openhound_github-0.21.3 → openhound_github-0.22.1}/extension/saved_searches/repos-secret-scanning-disabled.json +0 -0
  298. {openhound_github-0.21.3 → openhound_github-0.22.1}/extension/saved_searches/repos-vulnerable-to-workflow-secret-exfil.json +0 -0
  299. {openhound_github-0.21.3 → openhound_github-0.22.1}/extension/saved_searches/repository-workflows.json +0 -0
  300. {openhound_github-0.21.3 → openhound_github-0.22.1}/extension/saved_searches/saml-configuration.json +0 -0
  301. {openhound_github-0.21.3 → openhound_github-0.22.1}/extension/saved_searches/secret-scanning-alerts.json +0 -0
  302. {openhound_github-0.21.3 → openhound_github-0.22.1}/extension/saved_searches/secret-scanning-disabled-new-repos.json +0 -0
  303. {openhound_github-0.21.3 → openhound_github-0.22.1}/extension/saved_searches/secrets-reachable-by-user.json +0 -0
  304. {openhound_github-0.21.3 → openhound_github-0.22.1}/extension/saved_searches/self-hosted-runners-can-intercept-broad-token-jobs.json +0 -0
  305. {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
  306. {openhound_github-0.21.3 → openhound_github-0.22.1}/extension/saved_searches/team-membership-admin.json +0 -0
  307. {openhound_github-0.21.3 → openhound_github-0.22.1}/extension/saved_searches/team-structure.json +0 -0
  308. {openhound_github-0.21.3 → openhound_github-0.22.1}/extension/saved_searches/unprotected-branches.json +0 -0
  309. {openhound_github-0.21.3 → openhound_github-0.22.1}/extension/saved_searches/unprotected-default-branch-with-workflow.json +0 -0
  310. {openhound_github-0.21.3 → openhound_github-0.22.1}/extension/saved_searches/unprotected-default-branches.json +0 -0
  311. {openhound_github-0.21.3 → openhound_github-0.22.1}/extension/saved_searches/web-commit-signoff-not-required.json +0 -0
  312. {openhound_github-0.21.3 → openhound_github-0.22.1}/extension/saved_searches/workflow-jobs-interceptable-by-self-hosted-runners.json +0 -0
  313. {openhound_github-0.21.3 → openhound_github-0.22.1}/extension/saved_searches/workflow-jobs-with-broad-token-write-permissions.json +0 -0
  314. {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
  315. {openhound_github-0.21.3 → openhound_github-0.22.1}/extension/saved_searches/workflow-jobs-with-id-token-write.json +0 -0
  316. {openhound_github-0.21.3 → openhound_github-0.22.1}/extension/saved_searches/workflow-jobs-with-observed-oidc-auth-steps.json +0 -0
  317. {openhound_github-0.21.3 → openhound_github-0.22.1}/justfile +0 -0
  318. {openhound_github-0.21.3 → openhound_github-0.22.1}/pyproject.toml +0 -0
  319. {openhound_github-0.21.3 → openhound_github-0.22.1}/scripts/generate_gh_description_docs.py +0 -0
  320. {openhound_github-0.21.3 → openhound_github-0.22.1}/src/main.py +0 -0
  321. {openhound_github-0.21.3 → openhound_github-0.22.1}/src/openhound_github/__init__.py +0 -0
  322. {openhound_github-0.21.3 → openhound_github-0.22.1}/src/openhound_github/auth.py +0 -0
  323. {openhound_github-0.21.3 → openhound_github-0.22.1}/src/openhound_github/extension.yaml +0 -0
  324. {openhound_github-0.21.3 → openhound_github-0.22.1}/src/openhound_github/github_retry.py +0 -0
  325. {openhound_github-0.21.3 → openhound_github-0.22.1}/src/openhound_github/graph.py +0 -0
  326. {openhound_github-0.21.3 → openhound_github-0.22.1}/src/openhound_github/graphql.py +0 -0
  327. {openhound_github-0.21.3 → openhound_github-0.22.1}/src/openhound_github/kinds/edges.py +0 -0
  328. {openhound_github-0.21.3 → openhound_github-0.22.1}/src/openhound_github/kinds/nodes.py +0 -0
  329. {openhound_github-0.21.3 → openhound_github-0.22.1}/src/openhound_github/main.py +0 -0
  330. {openhound_github-0.21.3 → openhound_github-0.22.1}/src/openhound_github/models/__init__.py +0 -0
  331. {openhound_github-0.21.3 → openhound_github-0.22.1}/src/openhound_github/models/actions_permission.py +0 -0
  332. {openhound_github-0.21.3 → openhound_github-0.22.1}/src/openhound_github/models/branch.py +0 -0
  333. {openhound_github-0.21.3 → openhound_github-0.22.1}/src/openhound_github/models/branch_pr_bypass_allowance.py +0 -0
  334. {openhound_github-0.21.3 → openhound_github-0.22.1}/src/openhound_github/models/branch_protection_rule.py +0 -0
  335. {openhound_github-0.21.3 → openhound_github-0.22.1}/src/openhound_github/models/branch_push_allowance.py +0 -0
  336. {openhound_github-0.21.3 → openhound_github-0.22.1}/src/openhound_github/models/classic_personal_access_token.py +0 -0
  337. {openhound_github-0.21.3 → openhound_github-0.22.1}/src/openhound_github/models/deploy_key.py +0 -0
  338. {openhound_github-0.21.3 → openhound_github-0.22.1}/src/openhound_github/models/enterprise.py +0 -0
  339. {openhound_github-0.21.3 → openhound_github-0.22.1}/src/openhound_github/models/enterprise_admin.py +0 -0
  340. {openhound_github-0.21.3 → openhound_github-0.22.1}/src/openhound_github/models/enterprise_credential_inventory.py +0 -0
  341. {openhound_github-0.21.3 → openhound_github-0.22.1}/src/openhound_github/models/enterprise_helpers.py +0 -0
  342. {openhound_github-0.21.3 → openhound_github-0.22.1}/src/openhound_github/models/enterprise_managed_user.py +0 -0
  343. {openhound_github-0.21.3 → openhound_github-0.22.1}/src/openhound_github/models/enterprise_member.py +0 -0
  344. {openhound_github-0.21.3 → openhound_github-0.22.1}/src/openhound_github/models/enterprise_organization.py +0 -0
  345. {openhound_github-0.21.3 → openhound_github-0.22.1}/src/openhound_github/models/enterprise_role.py +0 -0
  346. {openhound_github-0.21.3 → openhound_github-0.22.1}/src/openhound_github/models/enterprise_role_team.py +0 -0
  347. {openhound_github-0.21.3 → openhound_github-0.22.1}/src/openhound_github/models/enterprise_role_user.py +0 -0
  348. {openhound_github-0.21.3 → openhound_github-0.22.1}/src/openhound_github/models/enterprise_team.py +0 -0
  349. {openhound_github-0.21.3 → openhound_github-0.22.1}/src/openhound_github/models/enterprise_team_member.py +0 -0
  350. {openhound_github-0.21.3 → openhound_github-0.22.1}/src/openhound_github/models/enterprise_team_organization.py +0 -0
  351. {openhound_github-0.21.3 → openhound_github-0.22.1}/src/openhound_github/models/enterprise_team_role.py +0 -0
  352. {openhound_github-0.21.3 → openhound_github-0.22.1}/src/openhound_github/models/enterprise_user.py +0 -0
  353. {openhound_github-0.21.3 → openhound_github-0.22.1}/src/openhound_github/models/env_secret.py +0 -0
  354. {openhound_github-0.21.3 → openhound_github-0.22.1}/src/openhound_github/models/env_variable.py +0 -0
  355. {openhound_github-0.21.3 → openhound_github-0.22.1}/src/openhound_github/models/environment.py +0 -0
  356. {openhound_github-0.21.3 → openhound_github-0.22.1}/src/openhound_github/models/environment_branch_policy.py +0 -0
  357. {openhound_github-0.21.3 → openhound_github-0.22.1}/src/openhound_github/models/external_identity.py +0 -0
  358. {openhound_github-0.21.3 → openhound_github-0.22.1}/src/openhound_github/models/org.py +0 -0
  359. {openhound_github-0.21.3 → openhound_github-0.22.1}/src/openhound_github/models/org_role.py +0 -0
  360. {openhound_github-0.21.3 → openhound_github-0.22.1}/src/openhound_github/models/org_role_member.py +0 -0
  361. {openhound_github-0.21.3 → openhound_github-0.22.1}/src/openhound_github/models/org_role_team.py +0 -0
  362. {openhound_github-0.21.3 → openhound_github-0.22.1}/src/openhound_github/models/org_secret.py +0 -0
  363. {openhound_github-0.21.3 → openhound_github-0.22.1}/src/openhound_github/models/org_variable.py +0 -0
  364. {openhound_github-0.21.3 → openhound_github-0.22.1}/src/openhound_github/models/permissions.py +0 -0
  365. {openhound_github-0.21.3 → openhound_github-0.22.1}/src/openhound_github/models/personal_access_token.py +0 -0
  366. {openhound_github-0.21.3 → openhound_github-0.22.1}/src/openhound_github/models/personal_access_token_access.py +0 -0
  367. {openhound_github-0.21.3 → openhound_github-0.22.1}/src/openhound_github/models/personal_access_token_request.py +0 -0
  368. {openhound_github-0.21.3 → openhound_github-0.22.1}/src/openhound_github/models/projected_enterprise_team.py +0 -0
  369. {openhound_github-0.21.3 → openhound_github-0.22.1}/src/openhound_github/models/repo_role_assignment.py +0 -0
  370. {openhound_github-0.21.3 → openhound_github-0.22.1}/src/openhound_github/models/repository.py +0 -0
  371. {openhound_github-0.21.3 → openhound_github-0.22.1}/src/openhound_github/models/repository_role.py +0 -0
  372. {openhound_github-0.21.3 → openhound_github-0.22.1}/src/openhound_github/models/repository_secret.py +0 -0
  373. {openhound_github-0.21.3 → openhound_github-0.22.1}/src/openhound_github/models/repository_variable.py +0 -0
  374. {openhound_github-0.21.3 → openhound_github-0.22.1}/src/openhound_github/models/runner.py +0 -0
  375. {openhound_github-0.21.3 → openhound_github-0.22.1}/src/openhound_github/models/saml_assertion_consumer_service.py +0 -0
  376. {openhound_github-0.21.3 → openhound_github-0.22.1}/src/openhound_github/models/saml_helpers.py +0 -0
  377. {openhound_github-0.21.3 → openhound_github-0.22.1}/src/openhound_github/models/saml_issuer.py +0 -0
  378. {openhound_github-0.21.3 → openhound_github-0.22.1}/src/openhound_github/models/saml_provider.py +0 -0
  379. {openhound_github-0.21.3 → openhound_github-0.22.1}/src/openhound_github/models/saml_service_provider.py +0 -0
  380. {openhound_github-0.21.3 → openhound_github-0.22.1}/src/openhound_github/models/scim_user.py +0 -0
  381. {openhound_github-0.21.3 → openhound_github-0.22.1}/src/openhound_github/models/scope.py +0 -0
  382. {openhound_github-0.21.3 → openhound_github-0.22.1}/src/openhound_github/models/secret_scanning_alert.py +0 -0
  383. {openhound_github-0.21.3 → openhound_github-0.22.1}/src/openhound_github/models/team.py +0 -0
  384. {openhound_github-0.21.3 → openhound_github-0.22.1}/src/openhound_github/models/team_member.py +0 -0
  385. {openhound_github-0.21.3 → openhound_github-0.22.1}/src/openhound_github/models/team_role.py +0 -0
  386. {openhound_github-0.21.3 → openhound_github-0.22.1}/src/openhound_github/models/user.py +0 -0
  387. {openhound_github-0.21.3 → openhound_github-0.22.1}/src/openhound_github/models/workflow.py +0 -0
  388. {openhound_github-0.21.3 → openhound_github-0.22.1}/src/openhound_github/models/workflow_job.py +0 -0
  389. {openhound_github-0.21.3 → openhound_github-0.22.1}/src/openhound_github/models/workflow_reference.py +0 -0
  390. {openhound_github-0.21.3 → openhound_github-0.22.1}/src/openhound_github/models/workflow_step.py +0 -0
  391. {openhound_github-0.21.3 → openhound_github-0.22.1}/src/openhound_github/resources/__init__.py +0 -0
  392. {openhound_github-0.21.3 → openhound_github-0.22.1}/src/openhound_github/resources/enterprise.py +0 -0
  393. {openhound_github-0.21.3 → openhound_github-0.22.1}/src/openhound_github/runner_ids.py +0 -0
  394. {openhound_github-0.21.3 → openhound_github-0.22.1}/src/openhound_github/transforms.py +0 -0
  395. {openhound_github-0.21.3 → openhound_github-0.22.1}/src/scheduler.py +0 -0
  396. {openhound_github-0.21.3 → openhound_github-0.22.1}/tests/test_app_auth.py +0 -0
  397. {openhound_github-0.21.3 → openhound_github-0.22.1}/tests/test_app_installation_repo_access.py +0 -0
  398. {openhound_github-0.21.3 → openhound_github-0.22.1}/tests/test_branch_collection_gate.py +0 -0
  399. {openhound_github-0.21.3 → openhound_github-0.22.1}/tests/test_branch_protection_traversability.py +0 -0
  400. {openhound_github-0.21.3 → openhound_github-0.22.1}/tests/test_classic_personal_access_tokens.py +0 -0
  401. {openhound_github-0.21.3 → openhound_github-0.22.1}/tests/test_credential_permission_models.py +0 -0
  402. {openhound_github-0.21.3 → openhound_github-0.22.1}/tests/test_data/api/actions-permissions.json +0 -0
  403. {openhound_github-0.21.3 → openhound_github-0.22.1}/tests/test_data/api/actionsecrets.json +0 -0
  404. {openhound_github-0.21.3 → openhound_github-0.22.1}/tests/test_data/api/app.json +0 -0
  405. {openhound_github-0.21.3 → openhound_github-0.22.1}/tests/test_data/api/appinstalls.json +0 -0
  406. {openhound_github-0.21.3 → openhound_github-0.22.1}/tests/test_data/api/branch-policies.json +0 -0
  407. {openhound_github-0.21.3 → openhound_github-0.22.1}/tests/test_data/api/branch-prot-rules.json +0 -0
  408. {openhound_github-0.21.3 → openhound_github-0.22.1}/tests/test_data/api/branches.json +0 -0
  409. {openhound_github-0.21.3 → openhound_github-0.22.1}/tests/test_data/api/custom-roles.json +0 -0
  410. {openhound_github-0.21.3 → openhound_github-0.22.1}/tests/test_data/api/environments.json +0 -0
  411. {openhound_github-0.21.3 → openhound_github-0.22.1}/tests/test_data/api/org-pat-request.json +0 -0
  412. {openhound_github-0.21.3 → openhound_github-0.22.1}/tests/test_data/api/org-pat.json +0 -0
  413. {openhound_github-0.21.3 → openhound_github-0.22.1}/tests/test_data/api/org-role-teams.json +0 -0
  414. {openhound_github-0.21.3 → openhound_github-0.22.1}/tests/test_data/api/org-role-users.json +0 -0
  415. {openhound_github-0.21.3 → openhound_github-0.22.1}/tests/test_data/api/org-roles.json +0 -0
  416. {openhound_github-0.21.3 → openhound_github-0.22.1}/tests/test_data/api/org.json +0 -0
  417. {openhound_github-0.21.3 → openhound_github-0.22.1}/tests/test_data/api/pat-repositories.json +0 -0
  418. {openhound_github-0.21.3 → openhound_github-0.22.1}/tests/test_data/api/repo-collaborators.json +0 -0
  419. {openhound_github-0.21.3 → openhound_github-0.22.1}/tests/test_data/api/repo-teams.json +0 -0
  420. {openhound_github-0.21.3 → openhound_github-0.22.1}/tests/test_data/api/repositories.json +0 -0
  421. {openhound_github-0.21.3 → openhound_github-0.22.1}/tests/test_data/api/scimusers.json +0 -0
  422. {openhound_github-0.21.3 → openhound_github-0.22.1}/tests/test_data/api/secrets.json +0 -0
  423. {openhound_github-0.21.3 → openhound_github-0.22.1}/tests/test_data/api/secretscanningalert.json +0 -0
  424. {openhound_github-0.21.3 → openhound_github-0.22.1}/tests/test_data/api/selected-org-secrets.json +0 -0
  425. {openhound_github-0.21.3 → openhound_github-0.22.1}/tests/test_data/api/variables.json +0 -0
  426. {openhound_github-0.21.3 → openhound_github-0.22.1}/tests/test_data/api/workflows.json +0 -0
  427. {openhound_github-0.21.3 → openhound_github-0.22.1}/tests/test_deploy_key_models.py +0 -0
  428. {openhound_github-0.21.3 → openhound_github-0.22.1}/tests/test_deploy_key_resources.py +0 -0
  429. {openhound_github-0.21.3 → openhound_github-0.22.1}/tests/test_description_docs.py +0 -0
  430. {openhound_github-0.21.3 → openhound_github-0.22.1}/tests/test_enterprise_capabilities.py +0 -0
  431. {openhound_github-0.21.3 → openhound_github-0.22.1}/tests/test_enterprise_organization.py +0 -0
  432. {openhound_github-0.21.3 → openhound_github-0.22.1}/tests/test_enterprise_resources.py +0 -0
  433. {openhound_github-0.21.3 → openhound_github-0.22.1}/tests/test_environment_model.py +0 -0
  434. {openhound_github-0.21.3 → openhound_github-0.22.1}/tests/test_environment_resources.py +0 -0
  435. {openhound_github-0.21.3 → openhound_github-0.22.1}/tests/test_environment_reviewer_lookup.py +0 -0
  436. {openhound_github-0.21.3 → openhound_github-0.22.1}/tests/test_error_resilience.py +0 -0
  437. {openhound_github-0.21.3 → openhound_github-0.22.1}/tests/test_github_retry.py +0 -0
  438. {openhound_github-0.21.3 → openhound_github-0.22.1}/tests/test_helpers.py +0 -0
  439. {openhound_github-0.21.3 → openhound_github-0.22.1}/tests/test_org_role_model.py +0 -0
  440. {openhound_github-0.21.3 → openhound_github-0.22.1}/tests/test_org_scim_resources.py +0 -0
  441. {openhound_github-0.21.3 → openhound_github-0.22.1}/tests/test_org_secret_models.py +0 -0
  442. {openhound_github-0.21.3 → openhound_github-0.22.1}/tests/test_preproc.py +0 -0
  443. {openhound_github-0.21.3 → openhound_github-0.22.1}/tests/test_repository_rulesets.py +0 -0
  444. {openhound_github-0.21.3 → openhound_github-0.22.1}/tests/test_repository_scopes.py +0 -0
  445. {openhound_github-0.21.3 → openhound_github-0.22.1}/tests/test_runner_ids.py +0 -0
  446. {openhound_github-0.21.3 → openhound_github-0.22.1}/tests/test_runner_models.py +0 -0
  447. {openhound_github-0.21.3 → openhound_github-0.22.1}/tests/test_runner_resources.py +0 -0
  448. {openhound_github-0.21.3 → openhound_github-0.22.1}/tests/test_saml_helpers.py +0 -0
  449. {openhound_github-0.21.3 → openhound_github-0.22.1}/tests/test_saml_models.py +0 -0
  450. {openhound_github-0.21.3 → openhound_github-0.22.1}/tests/test_scim_models.py +0 -0
  451. {openhound_github-0.21.3 → openhound_github-0.22.1}/tests/test_source_endpoints.py +0 -0
  452. {openhound_github-0.21.3 → openhound_github-0.22.1}/tests/test_source_org_canonicalization.py +0 -0
  453. {openhound_github-0.21.3 → openhound_github-0.22.1}/tests/test_team_external_groups.py +0 -0
  454. {openhound_github-0.21.3 → openhound_github-0.22.1}/tests/test_variable_models.py +0 -0
  455. {openhound_github-0.21.3 → openhound_github-0.22.1}/tests/test_workflow_interception_path.py +0 -0
  456. {openhound_github-0.21.3 → openhound_github-0.22.1}/tests/test_workflow_model.py +0 -0
  457. {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.21.3
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
  ```
@@ -2121,7 +2121,7 @@
2121
2121
  },
2122
2122
  {
2123
2123
  "name": "GH_Owns",
2124
- "description": "Organization owns a repository",
2124
+ "description": "GitHub account owns an application or repository",
2125
2125
  "is_traversable": true
2126
2126
  },
2127
2127
  {
@@ -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
- The underlying HTTP session still owns ordinary request retries. This helper
234
- handles the remaining terminal 502/504 case by retrying the same cursor with
235
- progressively smaller connection sizes.
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
- response = client.post(
282
- graphql_path,
283
- json={"query": query, "variables": request_variables},
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 status_code is not None and index + 1 < len(candidate_sizes)
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
@@ -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
- # owner_login=self.owner_login,
302
- # owner_node_id=self.owner_node_id,
303
- # owner_type=self.owner_type,
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
- return []
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(
@@ -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
- @app.defer
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
- response = client.get(
1491
- f"/repos/{repo.full_name}/contents/{path}", params=params
1492
- ).json()
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=requests.Client(
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]: