openhound-github 0.6.0__tar.gz → 0.6.2__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.6.0 → openhound_github-0.6.2}/PKG-INFO +1 -1
- {openhound_github-0.6.0 → openhound_github-0.6.2}/src/openhound_github/auth.py +108 -7
- {openhound_github-0.6.0 → openhound_github-0.6.2}/src/openhound_github/helpers.py +47 -2
- {openhound_github-0.6.0 → openhound_github-0.6.2}/src/openhound_github/models/repository.py +4 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/src/openhound_github/resources/organization.py +23 -2
- {openhound_github-0.6.0 → openhound_github-0.6.2}/src/openhound_github/source.py +18 -3
- {openhound_github-0.6.0 → openhound_github-0.6.2}/tests/test_app_auth.py +47 -1
- openhound_github-0.6.2/tests/test_github_app_retry.py +233 -0
- openhound_github-0.6.2/tests/test_helpers.py +102 -0
- openhound_github-0.6.2/tests/test_repository_rulesets.py +241 -0
- openhound_github-0.6.0/tests/test_repository_rulesets.py +0 -137
- {openhound_github-0.6.0 → openhound_github-0.6.2}/.github/CODE_OF_CONDUCT.md +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/.github/CONTRIBUTING.md +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/.github/GOVERNANCE.md +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/.github/GitHub-COC-Header.png +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/.github/GitHub-CONTRIB-Header.png +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/.github/GitHub-GOV-Header.png +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/.github/GitHub-Header.png +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/.github/GitHub-LIC-Header.png +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/.github/GitHub-SEC-Header.png +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/.github/SECURITY.md +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/.github/SO-Dark.svg +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/.github/SO-FOSS-Dark.svg +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/.github/SO-FOSS-Light.svg +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/.github/SO-Light.svg +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/.github/workflows/publish.yml +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/.github/workflows/release-on-merge.yml +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/.github/workflows/validate-branch.yml +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/.gitignore +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/.gitmodules +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/.pre-commit-config.yaml +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/LICENSE.md +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/README.md +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/descriptions/edges/GH_AddAssignee.md +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/descriptions/edges/GH_AddCollaborator.md +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/descriptions/edges/GH_AddLabel.md +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/descriptions/edges/GH_AddMember.md +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/descriptions/edges/GH_AdminTo.md +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/descriptions/edges/GH_ApprovesDeploymentTo.md +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/descriptions/edges/GH_AssignedTo.md +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/descriptions/edges/GH_BypassBranchProtection.md +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/descriptions/edges/GH_BypassPullRequestAllowances.md +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/descriptions/edges/GH_CallsWorkflow.md +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/descriptions/edges/GH_CanAccess.md +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/descriptions/edges/GH_CanAssumeIdentity.md +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/descriptions/edges/GH_CanCreateBranch.md +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/descriptions/edges/GH_CanCreateEnvironment.md +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/descriptions/edges/GH_CanCreateRepositoryWithRunnerAccess.md +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/descriptions/edges/GH_CanDeployToEnvironment.md +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/descriptions/edges/GH_CanEditEnvironment.md +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/descriptions/edges/GH_CanEditProtection.md +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/descriptions/edges/GH_CanPwnRequest.md +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/descriptions/edges/GH_CanReadSecretScanningAlert.md +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/descriptions/edges/GH_CanUseRunner.md +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/descriptions/edges/GH_CanWriteBranch.md +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/descriptions/edges/GH_CloseDiscussion.md +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/descriptions/edges/GH_CloseIssue.md +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/descriptions/edges/GH_ClosePullRequest.md +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/descriptions/edges/GH_Contains.md +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/descriptions/edges/GH_ConvertIssuesToDiscussions.md +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/descriptions/edges/GH_CreateDiscussionCategory.md +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/descriptions/edges/GH_CreateRepository.md +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/descriptions/edges/GH_CreateSoloMergeQueueEntry.md +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/descriptions/edges/GH_CreateTag.md +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/descriptions/edges/GH_CreateTeam.md +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/descriptions/edges/GH_DeleteAlertsCodeScanning.md +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/descriptions/edges/GH_DeleteDiscussion.md +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/descriptions/edges/GH_DeleteDiscussionComment.md +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/descriptions/edges/GH_DeleteIssue.md +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/descriptions/edges/GH_DeleteTag.md +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/descriptions/edges/GH_DependsOn.md +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/descriptions/edges/GH_DeploysTo.md +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/descriptions/edges/GH_EditCategoryOnDiscussion.md +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/descriptions/edges/GH_EditDiscussionCategory.md +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/descriptions/edges/GH_EditDiscussionComment.md +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/descriptions/edges/GH_EditRepoAnnouncementBanners.md +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/descriptions/edges/GH_EditRepoCustomPropertiesValues.md +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/descriptions/edges/GH_EditRepoMetadata.md +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/descriptions/edges/GH_EditRepoProtections.md +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/descriptions/edges/GH_HasBaseRole.md +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/descriptions/edges/GH_HasBranch.md +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/descriptions/edges/GH_HasEnvironment.md +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/descriptions/edges/GH_HasExternalIdentity.md +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/descriptions/edges/GH_HasJob.md +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/descriptions/edges/GH_HasMember.md +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/descriptions/edges/GH_HasPersonalAccessToken.md +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/descriptions/edges/GH_HasPersonalAccessTokenRequest.md +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/descriptions/edges/GH_HasRole.md +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/descriptions/edges/GH_HasRunner.md +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/descriptions/edges/GH_HasSamlIdentityProvider.md +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/descriptions/edges/GH_HasSecret.md +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/descriptions/edges/GH_HasStep.md +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/descriptions/edges/GH_HasVariable.md +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/descriptions/edges/GH_HasWorkflow.md +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/descriptions/edges/GH_InheritedFrom.md +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/descriptions/edges/GH_InstalledAs.md +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/descriptions/edges/GH_InviteMember.md +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/descriptions/edges/GH_IsEligibleFor.md +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/descriptions/edges/GH_JumpMergeQueue.md +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/descriptions/edges/GH_ManageDeployKeys.md +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/descriptions/edges/GH_ManageDiscussionBadges.md +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/descriptions/edges/GH_ManageOrganizationWebhooks.md +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/descriptions/edges/GH_ManageRepoSecurityProducts.md +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/descriptions/edges/GH_ManageSecurityProducts.md +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/descriptions/edges/GH_ManageSettingsMergeTypes.md +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/descriptions/edges/GH_ManageSettingsPages.md +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/descriptions/edges/GH_ManageSettingsProjects.md +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/descriptions/edges/GH_ManageSettingsWiki.md +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/descriptions/edges/GH_ManageTopics.md +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/descriptions/edges/GH_ManageWebhooks.md +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/descriptions/edges/GH_MapsToUser.md +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/descriptions/edges/GH_MarkAsDuplicate.md +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/descriptions/edges/GH_MatchesEnvironmentPolicy.md +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/descriptions/edges/GH_MemberOf.md +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/descriptions/edges/GH_OrgBypassCodeScanningDismissalRequests.md +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/descriptions/edges/GH_OrgBypassSecretScanningClosureRequests.md +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/descriptions/edges/GH_OrgReviewAndManageSecretScanningBypassRequests.md +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/descriptions/edges/GH_OrgReviewAndManageSecretScanningClosureRequests.md +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/descriptions/edges/GH_Owns.md +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/descriptions/edges/GH_ProtectedBy.md +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/descriptions/edges/GH_PushProtectedBranch.md +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/descriptions/edges/GH_ReadCodeScanning.md +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/descriptions/edges/GH_ReadOrganizationActionsUsageMetrics.md +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/descriptions/edges/GH_ReadOrganizationCustomOrgRole.md +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/descriptions/edges/GH_ReadOrganizationCustomRepoRole.md +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/descriptions/edges/GH_ReadRepoContents.md +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/descriptions/edges/GH_RemoveAssignee.md +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/descriptions/edges/GH_RemoveLabel.md +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/descriptions/edges/GH_ReopenDiscussion.md +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/descriptions/edges/GH_ReopenIssue.md +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/descriptions/edges/GH_ReopenPullRequest.md +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/descriptions/edges/GH_RequestPrReview.md +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/descriptions/edges/GH_ResolveDependabotAlerts.md +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/descriptions/edges/GH_ResolveSecretScanningAlerts.md +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/descriptions/edges/GH_RestrictionsCanPush.md +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/descriptions/edges/GH_RunOrgMigration.md +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/descriptions/edges/GH_SetInteractionLimits.md +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/descriptions/edges/GH_SetIssueType.md +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/descriptions/edges/GH_SetMilestone.md +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/descriptions/edges/GH_SetSocialPreview.md +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/descriptions/edges/GH_SyncedTo.md +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/descriptions/edges/GH_ToggleDiscussionAnswer.md +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/descriptions/edges/GH_ToggleDiscussionCommentMinimize.md +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/descriptions/edges/GH_TransferRepository.md +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/descriptions/edges/GH_UsesSecret.md +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/descriptions/edges/GH_UsesVariable.md +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/descriptions/edges/GH_ValidToken.md +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/descriptions/edges/GH_ViewDependabotAlerts.md +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/descriptions/edges/GH_ViewSecretScanningAlerts.md +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/descriptions/edges/GH_WriteCodeScanning.md +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/descriptions/edges/GH_WriteOrganizationActionsSecrets.md +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/descriptions/edges/GH_WriteOrganizationActionsSettings.md +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/descriptions/edges/GH_WriteOrganizationActionsVariables.md +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/descriptions/edges/GH_WriteOrganizationCustomOrgRole.md +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/descriptions/edges/GH_WriteOrganizationCustomRepoRole.md +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/descriptions/edges/GH_WriteOrganizationNetworkConfigurations.md +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/descriptions/edges/GH_WriteRepoContents.md +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/descriptions/edges/GH_WriteRepoPullRequests.md +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/descriptions/nodes/GH_App.md +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/descriptions/nodes/GH_AppInstallation.md +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/descriptions/nodes/GH_Branch.md +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/descriptions/nodes/GH_BranchProtectionRule.md +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/descriptions/nodes/GH_EnterpriseRunner.md +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/descriptions/nodes/GH_EnterpriseRunnerGroup.md +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/descriptions/nodes/GH_Environment.md +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/descriptions/nodes/GH_EnvironmentBranchPolicy.md +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/descriptions/nodes/GH_EnvironmentSecret.md +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/descriptions/nodes/GH_EnvironmentVariable.md +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/descriptions/nodes/GH_ExternalIdentity.md +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/descriptions/nodes/GH_OrgRole.md +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/descriptions/nodes/GH_OrgRunner.md +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/descriptions/nodes/GH_OrgRunnerGroup.md +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/descriptions/nodes/GH_OrgSecret.md +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/descriptions/nodes/GH_OrgVariable.md +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/descriptions/nodes/GH_Organization.md +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/descriptions/nodes/GH_PersonalAccessToken.md +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/descriptions/nodes/GH_PersonalAccessTokenRequest.md +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/descriptions/nodes/GH_RepoRole.md +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/descriptions/nodes/GH_RepoRunner.md +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/descriptions/nodes/GH_RepoSecret.md +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/descriptions/nodes/GH_RepoVariable.md +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/descriptions/nodes/GH_Repository.md +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/descriptions/nodes/GH_SamlIdentityProvider.md +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/descriptions/nodes/GH_SecretScanningAlert.md +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/descriptions/nodes/GH_Team.md +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/descriptions/nodes/GH_TeamRole.md +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/descriptions/nodes/GH_User.md +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/descriptions/nodes/GH_Workflow.md +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/descriptions/nodes/GH_WorkflowJob.md +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/descriptions/nodes/GH_WorkflowStep.md +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/docs/og-docs.json +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/extension/privilege_zone_rules/t0-all-repo-admin-role.json +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/extension/privilege_zone_rules/t0-app-installations-all-repos.json +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/extension/privilege_zone_rules/t0-apps-all-repos.json +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/extension/privilege_zone_rules/t0-external-identities-owners.json +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/extension/privilege_zone_rules/t0-organizations.json +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/extension/privilege_zone_rules/t0-owner-users.json +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/extension/privilege_zone_rules/t0-owners-role.json +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/extension/privilege_zone_rules/t0-pats-all-repos.json +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/extension/privilege_zone_rules/t0-privilege-escalation-roles.json +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/extension/privilege_zone_rules/t0-privilege-escalation-users.json +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/extension/privilege_zone_rules/t0-saml-identity-providers.json +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/extension/saved_searches/README.md +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/extension/saved_searches/actions-sha-pinning-not-required.json +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/extension/saved_searches/active-leaked-secrets.json +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/extension/saved_searches/advanced-security-disabled-new-repos.json +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/extension/saved_searches/all-actions-allowed.json +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/extension/saved_searches/app-installations-all-repos.json +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/extension/saved_searches/branch-protection-admins-not-enforced.json +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/extension/saved_searches/branch-protection-deletions-allowed.json +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/extension/saved_searches/branch-protection-force-pushes.json +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/extension/saved_searches/branch-protection-no-code-owner-reviews.json +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/extension/saved_searches/branch-protection-no-pr-reviews.json +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/extension/saved_searches/branch-protection-no-status-checks.json +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/extension/saved_searches/branch-protection-self-approval.json +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/extension/saved_searches/branch-protection-stale-reviews.json +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/extension/saved_searches/bypass-pr-requirements.json +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/extension/saved_searches/dangerous-branch-perms.json +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/extension/saved_searches/default-repository-permissions.json +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/extension/saved_searches/demo-sso-to-cloud-round-trip.json +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/extension/saved_searches/dependabot-alerts-disabled-new-repos.json +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/extension/saved_searches/dependabot-updates-disabled-new-repos.json +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/extension/saved_searches/dependency-graph-disabled-new-repos.json +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/extension/saved_searches/environments-admin-bypass.json +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/extension/saved_searches/expired-pats.json +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/extension/saved_searches/external-identities-without-scim.json +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/extension/saved_searches/github-to-azure-identity.json +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/extension/saved_searches/global-repo-perms.json +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/extension/saved_searches/hybrid-identities.json +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/extension/saved_searches/members-can-change-repo-visibility.json +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/extension/saved_searches/members-can-create-pages.json +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/extension/saved_searches/members-can-create-public-repos.json +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/extension/saved_searches/members-can-delete-repos.json +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/extension/saved_searches/members-can-fork-private-repos.json +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/extension/saved_searches/members-can-invite-outside-collaborators.json +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/extension/saved_searches/org-owners.json +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/extension/saved_searches/orgs-without-2fa.json +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/extension/saved_searches/pats-all-repo-access.json +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/extension/saved_searches/pending-pat-requests.json +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/extension/saved_searches/private-repos-forking-allowed.json +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/extension/saved_searches/privileged-custom-org-roles.json +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/extension/saved_searches/privileged-hybrid-identities.json +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/extension/saved_searches/public-repos.json +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/extension/saved_searches/push-protection-disabled-new-repos.json +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/extension/saved_searches/push-to-protected-branches.json +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/extension/saved_searches/repos-secret-scanning-disabled.json +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/extension/saved_searches/repos-vulnerable-to-workflow-secret-exfil.json +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/extension/saved_searches/repository-workflows.json +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/extension/saved_searches/saml-configuration.json +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/extension/saved_searches/secret-scanning-alerts.json +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/extension/saved_searches/secret-scanning-disabled-new-repos.json +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/extension/saved_searches/secrets-reachable-by-user.json +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/extension/saved_searches/team-membership-admin.json +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/extension/saved_searches/team-structure.json +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/extension/saved_searches/unprotected-branches.json +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/extension/saved_searches/unprotected-default-branch-with-workflow.json +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/extension/saved_searches/unprotected-default-branches.json +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/extension/saved_searches/web-commit-signoff-not-required.json +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/extension/schema.json +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/justfile +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/pyproject.toml +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/src/main.py +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/src/openhound_github/__init__.py +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/src/openhound_github/extension.yaml +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/src/openhound_github/graph.py +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/src/openhound_github/graphql.py +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/src/openhound_github/kinds/edges.py +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/src/openhound_github/kinds/nodes.py +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/src/openhound_github/lookup.py +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/src/openhound_github/main.py +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/src/openhound_github/models/__init__.py +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/src/openhound_github/models/actions_permission.py +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/src/openhound_github/models/app_installation.py +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/src/openhound_github/models/branch.py +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/src/openhound_github/models/branch_pr_bypass_allowance.py +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/src/openhound_github/models/branch_protection_rule.py +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/src/openhound_github/models/branch_push_allowance.py +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/src/openhound_github/models/enterprise.py +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/src/openhound_github/models/enterprise_admin.py +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/src/openhound_github/models/enterprise_helpers.py +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/src/openhound_github/models/enterprise_managed_user.py +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/src/openhound_github/models/enterprise_member.py +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/src/openhound_github/models/enterprise_organization.py +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/src/openhound_github/models/enterprise_role.py +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/src/openhound_github/models/enterprise_role_team.py +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/src/openhound_github/models/enterprise_role_user.py +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/src/openhound_github/models/enterprise_team.py +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/src/openhound_github/models/enterprise_team_member.py +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/src/openhound_github/models/enterprise_team_organization.py +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/src/openhound_github/models/enterprise_team_role.py +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/src/openhound_github/models/enterprise_user.py +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/src/openhound_github/models/env_secret.py +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/src/openhound_github/models/env_variable.py +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/src/openhound_github/models/environment.py +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/src/openhound_github/models/environment_branch_policy.py +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/src/openhound_github/models/external_identity.py +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/src/openhound_github/models/org.py +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/src/openhound_github/models/org_role.py +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/src/openhound_github/models/org_role_member.py +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/src/openhound_github/models/org_role_team.py +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/src/openhound_github/models/org_secret.py +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/src/openhound_github/models/org_variable.py +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/src/openhound_github/models/personal_access_token.py +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/src/openhound_github/models/personal_access_token_access.py +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/src/openhound_github/models/personal_access_token_request.py +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/src/openhound_github/models/projected_enterprise_team.py +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/src/openhound_github/models/repo_role_assignment.py +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/src/openhound_github/models/repository_role.py +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/src/openhound_github/models/repository_secret.py +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/src/openhound_github/models/repository_variable.py +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/src/openhound_github/models/runner.py +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/src/openhound_github/models/saml_assertion_consumer_service.py +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/src/openhound_github/models/saml_helpers.py +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/src/openhound_github/models/saml_issuer.py +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/src/openhound_github/models/saml_provider.py +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/src/openhound_github/models/saml_service_provider.py +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/src/openhound_github/models/scim_user.py +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/src/openhound_github/models/secret_scanning_alert.py +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/src/openhound_github/models/team.py +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/src/openhound_github/models/team_member.py +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/src/openhound_github/models/team_role.py +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/src/openhound_github/models/user.py +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/src/openhound_github/models/workflow.py +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/src/openhound_github/models/workflow_job.py +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/src/openhound_github/models/workflow_step.py +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/src/openhound_github/resources/__init__.py +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/src/openhound_github/resources/enterprise.py +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/src/openhound_github/runner_ids.py +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/src/openhound_github/transforms.py +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/tests/test_branch_collection_gate.py +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/tests/test_branch_protection_traversability.py +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/tests/test_data/api/actions-permissions.json +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/tests/test_data/api/actionsecrets.json +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/tests/test_data/api/app.json +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/tests/test_data/api/appinstalls.json +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/tests/test_data/api/branch-policies.json +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/tests/test_data/api/branch-prot-rules.json +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/tests/test_data/api/branches.json +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/tests/test_data/api/custom-roles.json +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/tests/test_data/api/environments.json +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/tests/test_data/api/org-pat-request.json +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/tests/test_data/api/org-pat.json +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/tests/test_data/api/org-role-teams.json +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/tests/test_data/api/org-role-users.json +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/tests/test_data/api/org-roles.json +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/tests/test_data/api/org.json +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/tests/test_data/api/pat-repositories.json +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/tests/test_data/api/repo-collaborators.json +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/tests/test_data/api/repo-teams.json +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/tests/test_data/api/repositories.json +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/tests/test_data/api/scimusers.json +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/tests/test_data/api/secrets.json +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/tests/test_data/api/secretscanningalert.json +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/tests/test_data/api/selected-org-secrets.json +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/tests/test_data/api/variables.json +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/tests/test_data/api/workflows.json +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/tests/test_enterprise_capabilities.py +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/tests/test_enterprise_organization.py +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/tests/test_enterprise_resources.py +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/tests/test_environment_model.py +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/tests/test_environment_resources.py +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/tests/test_environment_reviewer_lookup.py +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/tests/test_error_resilience.py +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/tests/test_external_identity_tenant_matching.py +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/tests/test_github_rest_client.py +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/tests/test_github_retry.py +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/tests/test_org_secret_models.py +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/tests/test_runner_ids.py +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/tests/test_runner_models.py +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/tests/test_runner_resources.py +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/tests/test_saml_helpers.py +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/tests/test_saml_models.py +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/tests/test_scim_models.py +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/tests/test_variable_models.py +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/tests/test_workflow_model.py +0 -0
- {openhound_github-0.6.0 → openhound_github-0.6.2}/uv.lock +0 -0
|
@@ -2,6 +2,8 @@ import logging
|
|
|
2
2
|
from datetime import datetime, timedelta, timezone
|
|
3
3
|
from threading import Lock
|
|
4
4
|
from typing import Iterator
|
|
5
|
+
from urllib.parse import urlparse
|
|
6
|
+
from weakref import WeakKeyDictionary
|
|
5
7
|
|
|
6
8
|
import requests
|
|
7
9
|
from dlt.common.configuration import configspec
|
|
@@ -17,6 +19,30 @@ from pydantic import BaseModel
|
|
|
17
19
|
logger = logging.getLogger(__name__)
|
|
18
20
|
|
|
19
21
|
|
|
22
|
+
def _normalized_http_origin(
|
|
23
|
+
url: str, *, allow_query: bool = False
|
|
24
|
+
) -> tuple[str, str, int | None]:
|
|
25
|
+
parsed = urlparse(url)
|
|
26
|
+
scheme = parsed.scheme.lower()
|
|
27
|
+
if scheme != "https" or not parsed.hostname:
|
|
28
|
+
raise ValueError("GitHub API URI must be an absolute HTTPS URL")
|
|
29
|
+
if (
|
|
30
|
+
parsed.username is not None
|
|
31
|
+
or parsed.password is not None
|
|
32
|
+
or (parsed.query and not allow_query)
|
|
33
|
+
or parsed.fragment
|
|
34
|
+
):
|
|
35
|
+
raise ValueError(
|
|
36
|
+
"GitHub API URI must not contain user-info, query strings, or fragments"
|
|
37
|
+
)
|
|
38
|
+
|
|
39
|
+
port = parsed.port
|
|
40
|
+
if scheme == "https" and port == 443:
|
|
41
|
+
port = None
|
|
42
|
+
|
|
43
|
+
return scheme, parsed.hostname.lower(), port
|
|
44
|
+
|
|
45
|
+
|
|
20
46
|
class AccountConfig(BaseModel):
|
|
21
47
|
id: int
|
|
22
48
|
login: str | None = None
|
|
@@ -63,7 +89,8 @@ class GithubSession:
|
|
|
63
89
|
private_key_path: str,
|
|
64
90
|
api_uri: str = "https://api.github.com/",
|
|
65
91
|
):
|
|
66
|
-
|
|
92
|
+
_normalized_http_origin(api_uri)
|
|
93
|
+
self.api_uri = f"{api_uri.rstrip('/')}/"
|
|
67
94
|
self.jwt_issuer = jwt_issuer
|
|
68
95
|
self.private_key_path = private_key_path
|
|
69
96
|
self.client = RESTClient(
|
|
@@ -158,11 +185,28 @@ class GitHubAppInstallationAuth(AuthConfigBase):
|
|
|
158
185
|
self,
|
|
159
186
|
installation: GithubInstallation,
|
|
160
187
|
refresh_margin_seconds: int = 300,
|
|
188
|
+
api_uri: str | None = None,
|
|
161
189
|
):
|
|
162
190
|
self.installation = installation
|
|
163
191
|
self.refresh_margin_seconds = refresh_margin_seconds
|
|
192
|
+
installation_api_uri = getattr(
|
|
193
|
+
installation, "api_uri", "https://api.github.com/"
|
|
194
|
+
)
|
|
195
|
+
selected_api_uri = api_uri or installation_api_uri
|
|
196
|
+
installation_api_origin = _normalized_http_origin(installation_api_uri)
|
|
197
|
+
selected_api_origin = _normalized_http_origin(selected_api_uri)
|
|
198
|
+
if selected_api_origin != installation_api_origin:
|
|
199
|
+
raise ValueError(
|
|
200
|
+
"GitHub App auth API URI origin must match installation API URI origin"
|
|
201
|
+
)
|
|
202
|
+
|
|
203
|
+
self.api_uri = selected_api_uri
|
|
204
|
+
self._api_origin = selected_api_origin
|
|
164
205
|
self.access_token: str | None = None
|
|
165
206
|
self.expires_at: datetime | None = None
|
|
207
|
+
self._response_refreshed_requests: WeakKeyDictionary[
|
|
208
|
+
requests.PreparedRequest, str
|
|
209
|
+
] = WeakKeyDictionary()
|
|
166
210
|
self._token_lock = Lock()
|
|
167
211
|
|
|
168
212
|
def _should_refresh(self) -> bool:
|
|
@@ -172,6 +216,14 @@ class GitHubAppInstallationAuth(AuthConfigBase):
|
|
|
172
216
|
refresh_at = self.expires_at - timedelta(seconds=self.refresh_margin_seconds)
|
|
173
217
|
return datetime.now(timezone.utc) >= refresh_at
|
|
174
218
|
|
|
219
|
+
def _refresh_token(self) -> None:
|
|
220
|
+
logger.info(
|
|
221
|
+
f"Refreshing access token for {self.installation.installation_id}"
|
|
222
|
+
)
|
|
223
|
+
get_token = self.installation.token
|
|
224
|
+
self.access_token = get_token.token
|
|
225
|
+
self.expires_at = get_token.expires_at
|
|
226
|
+
|
|
175
227
|
def token(self, force_refresh: bool = False) -> str | None:
|
|
176
228
|
if (
|
|
177
229
|
not force_refresh
|
|
@@ -182,15 +234,64 @@ class GitHubAppInstallationAuth(AuthConfigBase):
|
|
|
182
234
|
|
|
183
235
|
with self._token_lock:
|
|
184
236
|
if (force_refresh or self._should_refresh()) or self.access_token is None:
|
|
185
|
-
|
|
186
|
-
f"Refreshing access token for {self.installation.installation_id}"
|
|
187
|
-
)
|
|
188
|
-
get_token = self.installation.token
|
|
189
|
-
self.access_token = get_token.token
|
|
190
|
-
self.expires_at = get_token.expires_at
|
|
237
|
+
self._refresh_token()
|
|
191
238
|
|
|
192
239
|
return self.access_token
|
|
193
240
|
|
|
241
|
+
def refresh_request(self, request: requests.PreparedRequest) -> bool:
|
|
242
|
+
"""Repair a rejected same-origin request without stampeding token issuance."""
|
|
243
|
+
try:
|
|
244
|
+
request_origin = _normalized_http_origin(
|
|
245
|
+
request.url or "", allow_query=True
|
|
246
|
+
)
|
|
247
|
+
except ValueError:
|
|
248
|
+
return False
|
|
249
|
+
|
|
250
|
+
if request_origin != self._api_origin:
|
|
251
|
+
return False
|
|
252
|
+
|
|
253
|
+
request_authorization = request.headers.get("Authorization")
|
|
254
|
+
if (
|
|
255
|
+
not request_authorization
|
|
256
|
+
or not request_authorization.startswith("Bearer ")
|
|
257
|
+
or not request_authorization.removeprefix("Bearer ").strip()
|
|
258
|
+
):
|
|
259
|
+
return False
|
|
260
|
+
|
|
261
|
+
with self._token_lock:
|
|
262
|
+
current_authorization = (
|
|
263
|
+
f"Bearer {self.access_token}" if self.access_token is not None else None
|
|
264
|
+
)
|
|
265
|
+
should_refresh = self._should_refresh()
|
|
266
|
+
repaired_authorization = self._response_refreshed_requests.get(request)
|
|
267
|
+
if (
|
|
268
|
+
not should_refresh
|
|
269
|
+
and request_authorization == current_authorization
|
|
270
|
+
and request_authorization == repaired_authorization
|
|
271
|
+
):
|
|
272
|
+
return False
|
|
273
|
+
|
|
274
|
+
if (
|
|
275
|
+
self.access_token is None
|
|
276
|
+
or should_refresh
|
|
277
|
+
or request_authorization == current_authorization
|
|
278
|
+
):
|
|
279
|
+
try:
|
|
280
|
+
self._refresh_token()
|
|
281
|
+
except Exception:
|
|
282
|
+
logger.warning(
|
|
283
|
+
"Failed to refresh GitHub App installation token for "
|
|
284
|
+
"installation %s during request retry",
|
|
285
|
+
self.installation.installation_id,
|
|
286
|
+
)
|
|
287
|
+
return False
|
|
288
|
+
|
|
289
|
+
replacement_authorization = f"Bearer {self.access_token}"
|
|
290
|
+
request.headers["Authorization"] = replacement_authorization
|
|
291
|
+
self._response_refreshed_requests[request] = replacement_authorization
|
|
292
|
+
|
|
293
|
+
return True
|
|
294
|
+
|
|
194
295
|
def __call__(self, request: requests.PreparedRequest) -> requests.PreparedRequest:
|
|
195
296
|
request.headers["Authorization"] = f"Bearer {self.token()}"
|
|
196
297
|
return request
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import logging
|
|
2
2
|
import time
|
|
3
3
|
from typing import Optional
|
|
4
|
+
from urllib.parse import urlparse
|
|
4
5
|
|
|
5
6
|
from dlt.common import jsonpath
|
|
6
7
|
from dlt.sources.helpers import requests
|
|
@@ -10,6 +11,8 @@ from dlt.sources.helpers.rest_client.paginators import (
|
|
|
10
11
|
)
|
|
11
12
|
from requests import Request
|
|
12
13
|
|
|
14
|
+
from openhound_github.auth import GitHubAppInstallationAuth
|
|
15
|
+
|
|
13
16
|
logger = logging.getLogger(__name__)
|
|
14
17
|
|
|
15
18
|
|
|
@@ -151,6 +154,25 @@ def _has_graphql_errors(response: requests.Response) -> bool:
|
|
|
151
154
|
return isinstance(response_data, dict) and bool(response_data.get("errors"))
|
|
152
155
|
|
|
153
156
|
|
|
157
|
+
def _has_invalid_json_body(response: requests.Response) -> bool:
|
|
158
|
+
try:
|
|
159
|
+
response.json()
|
|
160
|
+
except ValueError:
|
|
161
|
+
return True
|
|
162
|
+
return False
|
|
163
|
+
|
|
164
|
+
|
|
165
|
+
def _is_graphql_response(response: requests.Response) -> bool:
|
|
166
|
+
if response.headers.get("x-ratelimit-resource") == "graphql":
|
|
167
|
+
return True
|
|
168
|
+
|
|
169
|
+
request = response.request
|
|
170
|
+
if request is None or not request.url:
|
|
171
|
+
return False
|
|
172
|
+
|
|
173
|
+
return urlparse(request.url).path.rstrip("/").endswith("/graphql")
|
|
174
|
+
|
|
175
|
+
|
|
154
176
|
def github_retry_policy(auth: AuthConfigBase):
|
|
155
177
|
def retry_policy(
|
|
156
178
|
response: Optional[requests.Response], exception: Optional[BaseException]
|
|
@@ -160,9 +182,32 @@ def github_retry_policy(auth: AuthConfigBase):
|
|
|
160
182
|
|
|
161
183
|
headers = response.headers
|
|
162
184
|
now = int(time.time())
|
|
185
|
+
|
|
186
|
+
# DLT retries the same prepared request after long Retry-After sleeps.
|
|
187
|
+
if (
|
|
188
|
+
response.status_code == 401
|
|
189
|
+
and "bad credentials" in _response_message(response).lower()
|
|
190
|
+
and isinstance(auth, GitHubAppInstallationAuth)
|
|
191
|
+
and response.request is not None
|
|
192
|
+
):
|
|
193
|
+
if not auth.refresh_request(response.request):
|
|
194
|
+
return False
|
|
195
|
+
logger.warning(
|
|
196
|
+
"GitHub App installation token rejected, retrying request with refreshed token"
|
|
197
|
+
)
|
|
198
|
+
return True
|
|
199
|
+
|
|
163
200
|
if (
|
|
164
201
|
response.status_code == 200
|
|
165
|
-
and
|
|
202
|
+
and _is_graphql_response(response)
|
|
203
|
+
and _has_invalid_json_body(response)
|
|
204
|
+
):
|
|
205
|
+
logger.warning("GraphQL response body was not valid JSON, retrying request")
|
|
206
|
+
return True
|
|
207
|
+
|
|
208
|
+
if (
|
|
209
|
+
response.status_code == 200
|
|
210
|
+
and _is_graphql_response(response)
|
|
166
211
|
and _has_graphql_errors(response)
|
|
167
212
|
):
|
|
168
213
|
if headers.get("Retry-After"):
|
|
@@ -178,10 +223,10 @@ def github_retry_policy(auth: AuthConfigBase):
|
|
|
178
223
|
return True
|
|
179
224
|
return False
|
|
180
225
|
|
|
181
|
-
message = _response_message(response).lower()
|
|
182
226
|
if response.status_code not in (403, 429):
|
|
183
227
|
return False
|
|
184
228
|
|
|
229
|
+
message = _response_message(response).lower()
|
|
185
230
|
if (
|
|
186
231
|
headers.get("x-ratelimit-remaining") == "0"
|
|
187
232
|
or "api rate limit exceeded" in message
|
|
@@ -29,6 +29,7 @@ class GHRepositoryProperties(GHNodeProperties):
|
|
|
29
29
|
disabled: Whether the repository is disabled.
|
|
30
30
|
visibility: The visibility level: `public`, `private`, or `internal`.
|
|
31
31
|
default_branch: The name of the default branch (e.g., `main`).
|
|
32
|
+
size: Repository size in kilobytes as reported by GitHub.
|
|
32
33
|
open_issues_count: Number of open issues.
|
|
33
34
|
allow_forking: Whether forking is allowed.
|
|
34
35
|
web_commit_signoff_required: Whether web-based commits require sign-off.
|
|
@@ -74,6 +75,7 @@ class GHRepositoryProperties(GHNodeProperties):
|
|
|
74
75
|
disabled: bool | None = None
|
|
75
76
|
visibility: str | None = None
|
|
76
77
|
default_branch: str | None = None
|
|
78
|
+
size: int | None = None
|
|
77
79
|
open_issues_count: int | None = None
|
|
78
80
|
allow_forking: bool | None = None
|
|
79
81
|
web_commit_signoff_required: bool | None = None
|
|
@@ -195,6 +197,7 @@ class Repository(BaseAsset):
|
|
|
195
197
|
disabled: bool | None = None
|
|
196
198
|
visibility: str | None = None
|
|
197
199
|
default_branch: str | None = None
|
|
200
|
+
size: int | None = None
|
|
198
201
|
open_issues_count: int | None = None
|
|
199
202
|
allow_forking: bool | None = None
|
|
200
203
|
web_commit_signoff_required: bool | None = None
|
|
@@ -240,6 +243,7 @@ class Repository(BaseAsset):
|
|
|
240
243
|
disabled=self.disabled,
|
|
241
244
|
visibility=self.visibility,
|
|
242
245
|
default_branch=self.default_branch,
|
|
246
|
+
size=self.size,
|
|
243
247
|
open_issues_count=self.open_issues_count,
|
|
244
248
|
allow_forking=self.allow_forking,
|
|
245
249
|
web_commit_signoff_required=self.web_commit_signoff_required,
|
{openhound_github-0.6.0 → openhound_github-0.6.2}/src/openhound_github/resources/organization.py
RENAMED
|
@@ -916,6 +916,8 @@ def repositories_graphql(ctx: SourceContext):
|
|
|
916
916
|
for org in ctx.organizations:
|
|
917
917
|
org_name = org.org_name
|
|
918
918
|
client = org.client
|
|
919
|
+
repository_cursor: str | None = None
|
|
920
|
+
emitted_repositories = 0
|
|
919
921
|
try:
|
|
920
922
|
paginator = GraphQLCursorPaginator(
|
|
921
923
|
page_info_path="data.organization.repositories.pageInfo",
|
|
@@ -939,15 +941,34 @@ def repositories_graphql(ctx: SourceContext):
|
|
|
939
941
|
for repo in repos_page["nodes"]:
|
|
940
942
|
repo_record = {**repo}
|
|
941
943
|
branch_rulesets = repo_record.pop("branchRulesets", None) or {}
|
|
944
|
+
emitted_repositories += 1
|
|
942
945
|
yield {
|
|
943
946
|
**repo_record,
|
|
944
947
|
"branch_ruleset_count": branch_rulesets.get("totalCount"),
|
|
945
948
|
"org_login": org_name,
|
|
946
949
|
}
|
|
950
|
+
|
|
951
|
+
page_info = repos_page.get("pageInfo") or {}
|
|
952
|
+
if isinstance(page_info, dict):
|
|
953
|
+
repository_cursor = page_info.get("endCursor")
|
|
947
954
|
except Exception as e:
|
|
948
955
|
logger.error(
|
|
949
|
-
|
|
950
|
-
|
|
956
|
+
"Error in resource 'repositories_graphql' processing organization '%s' "
|
|
957
|
+
"at repository cursor %r after emitting %d repositories "
|
|
958
|
+
"(%s): %s",
|
|
959
|
+
org_name,
|
|
960
|
+
repository_cursor,
|
|
961
|
+
emitted_repositories,
|
|
962
|
+
type(e).__name__,
|
|
963
|
+
e,
|
|
964
|
+
extra={
|
|
965
|
+
"resource": "repositories_graphql",
|
|
966
|
+
"phase": "resource_iteration",
|
|
967
|
+
"org_name": org_name,
|
|
968
|
+
"repository_cursor": repository_cursor,
|
|
969
|
+
"emitted_repositories": emitted_repositories,
|
|
970
|
+
"error_type": type(e).__name__,
|
|
971
|
+
},
|
|
951
972
|
)
|
|
952
973
|
continue
|
|
953
974
|
|
|
@@ -172,6 +172,7 @@ def source(
|
|
|
172
172
|
github_app_session = GithubApp(
|
|
173
173
|
jwt_issuer=jwt_issuer,
|
|
174
174
|
private_key_path=credentials.key_path,
|
|
175
|
+
api_uri=host,
|
|
175
176
|
)
|
|
176
177
|
for installation in github_app_session.installations:
|
|
177
178
|
if installation.target_type == "Organization":
|
|
@@ -179,12 +180,16 @@ def source(
|
|
|
179
180
|
installation_id=installation.id,
|
|
180
181
|
jwt_issuer=jwt_issuer,
|
|
181
182
|
private_key_path=credentials.key_path,
|
|
183
|
+
api_uri=host,
|
|
182
184
|
)
|
|
183
185
|
ctx.organizations.append(
|
|
184
186
|
OrgContext(
|
|
185
187
|
org_name=installation.account.login,
|
|
186
188
|
client=client(
|
|
187
|
-
GitHubAppInstallationAuth(
|
|
189
|
+
GitHubAppInstallationAuth(
|
|
190
|
+
installation=org_installation,
|
|
191
|
+
api_uri=host,
|
|
192
|
+
)
|
|
188
193
|
),
|
|
189
194
|
enterprise_name=credentials.enterprise_name,
|
|
190
195
|
github_deployment_id=github_deployment_id,
|
|
@@ -196,9 +201,13 @@ def source(
|
|
|
196
201
|
installation_id=installation.id,
|
|
197
202
|
jwt_issuer=jwt_issuer,
|
|
198
203
|
private_key_path=credentials.key_path,
|
|
204
|
+
api_uri=host,
|
|
199
205
|
)
|
|
200
206
|
ctx.client = client(
|
|
201
|
-
GitHubAppInstallationAuth(
|
|
207
|
+
GitHubAppInstallationAuth(
|
|
208
|
+
installation=es_installation,
|
|
209
|
+
api_uri=host,
|
|
210
|
+
)
|
|
202
211
|
)
|
|
203
212
|
|
|
204
213
|
return (*enterprise_resources(ctx), *organization_resources(ctx))
|
|
@@ -213,11 +222,17 @@ def source(
|
|
|
213
222
|
installation_id=credentials.install_id,
|
|
214
223
|
jwt_issuer=credentials.client_id,
|
|
215
224
|
private_key_path=credentials.key_path,
|
|
225
|
+
api_uri=host,
|
|
216
226
|
)
|
|
217
227
|
ctx.organizations.append(
|
|
218
228
|
OrgContext(
|
|
219
229
|
org_name=credentials.org_name,
|
|
220
|
-
client=client(
|
|
230
|
+
client=client(
|
|
231
|
+
GitHubAppInstallationAuth(
|
|
232
|
+
installation=org_installation,
|
|
233
|
+
api_uri=host,
|
|
234
|
+
)
|
|
235
|
+
),
|
|
221
236
|
github_deployment_id=github_deployment_id,
|
|
222
237
|
github_web_origin=github_web_origin,
|
|
223
238
|
)
|
|
@@ -9,6 +9,7 @@ from dlt.common.configuration.resolve import resolve_configuration
|
|
|
9
9
|
from openhound_github import auth
|
|
10
10
|
from openhound_github.auth import (
|
|
11
11
|
AccountConfig,
|
|
12
|
+
GitHubAppInstallationAuth,
|
|
12
13
|
GithubSession,
|
|
13
14
|
InstallationResponse,
|
|
14
15
|
resolve_github_app_jwt_issuer,
|
|
@@ -97,6 +98,48 @@ def test_legacy_installation_response_does_not_require_client_id() -> None:
|
|
|
97
98
|
assert installation.app_id == 123456
|
|
98
99
|
|
|
99
100
|
|
|
101
|
+
def test_github_app_installation_auth_rejects_mismatched_api_origins() -> None:
|
|
102
|
+
installation = SimpleNamespace(
|
|
103
|
+
installation_id="12345",
|
|
104
|
+
api_uri="https://ghe.example/api/v3/",
|
|
105
|
+
)
|
|
106
|
+
|
|
107
|
+
with pytest.raises(ValueError, match="must match installation API URI origin"):
|
|
108
|
+
GitHubAppInstallationAuth(
|
|
109
|
+
installation=installation,
|
|
110
|
+
api_uri="https://api.github.com/",
|
|
111
|
+
)
|
|
112
|
+
|
|
113
|
+
|
|
114
|
+
def test_github_session_rejects_plaintext_api_uri() -> None:
|
|
115
|
+
with pytest.raises(ValueError, match="absolute HTTPS URL"):
|
|
116
|
+
GithubSession(
|
|
117
|
+
jwt_issuer="123456",
|
|
118
|
+
private_key_path="/tmp/github-app.pem",
|
|
119
|
+
api_uri="http://ghe.example/api/v3/",
|
|
120
|
+
)
|
|
121
|
+
|
|
122
|
+
|
|
123
|
+
@pytest.mark.parametrize(
|
|
124
|
+
"api_uri",
|
|
125
|
+
(
|
|
126
|
+
"https://user:password@ghe.example/api/v3/",
|
|
127
|
+
"https://ghe.example/api/v3/?token=secret",
|
|
128
|
+
"https://ghe.example/api/v3/#fragment",
|
|
129
|
+
),
|
|
130
|
+
)
|
|
131
|
+
def test_github_session_rejects_api_uri_with_unsafe_components(api_uri: str) -> None:
|
|
132
|
+
with pytest.raises(
|
|
133
|
+
ValueError,
|
|
134
|
+
match="must not contain user-info, query strings, or fragments",
|
|
135
|
+
):
|
|
136
|
+
GithubSession(
|
|
137
|
+
jwt_issuer="123456",
|
|
138
|
+
private_key_path="/tmp/github-app.pem",
|
|
139
|
+
api_uri=api_uri,
|
|
140
|
+
)
|
|
141
|
+
|
|
142
|
+
|
|
100
143
|
def test_enterprise_source_reuses_selected_issuer_for_installation_tokens(
|
|
101
144
|
monkeypatch: pytest.MonkeyPatch,
|
|
102
145
|
) -> None:
|
|
@@ -104,7 +147,9 @@ def test_enterprise_source_reuses_selected_issuer_for_installation_tokens(
|
|
|
104
147
|
captured_issuers: list[str] = []
|
|
105
148
|
|
|
106
149
|
class FakeGithubApp:
|
|
107
|
-
def __init__(
|
|
150
|
+
def __init__(
|
|
151
|
+
self, jwt_issuer: str, private_key_path: str, api_uri: str
|
|
152
|
+
) -> None:
|
|
108
153
|
captured_issuers.append(jwt_issuer)
|
|
109
154
|
self.installations = (
|
|
110
155
|
SimpleNamespace(
|
|
@@ -125,6 +170,7 @@ def test_enterprise_source_reuses_selected_issuer_for_installation_tokens(
|
|
|
125
170
|
installation_id: int,
|
|
126
171
|
jwt_issuer: str,
|
|
127
172
|
private_key_path: str,
|
|
173
|
+
api_uri: str,
|
|
128
174
|
) -> None:
|
|
129
175
|
captured_issuers.append(jwt_issuer)
|
|
130
176
|
|