openhound-github 0.5.2__tar.gz → 0.5.3__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.5.2 → openhound_github-0.5.3}/PKG-INFO +1 -1
- {openhound_github-0.5.2 → openhound_github-0.5.3}/descriptions/edges/GH_ApprovesDeploymentTo.md +1 -1
- openhound_github-0.5.3/descriptions/edges/GH_CanDeployToEnvironment.md +9 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/extension/schema.json +1 -1
- {openhound_github-0.5.2 → openhound_github-0.5.3}/src/openhound_github/lookup.py +260 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/src/openhound_github/main.py +6 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/src/openhound_github/models/environment.py +168 -9
- {openhound_github-0.5.2 → openhound_github-0.5.3}/src/openhound_github/models/environment_branch_policy.py +9 -4
- {openhound_github-0.5.2 → openhound_github-0.5.3}/src/openhound_github/transforms.py +118 -3
- {openhound_github-0.5.2 → openhound_github-0.5.3}/tests/test_environment_model.py +152 -0
- openhound_github-0.5.3/tests/test_environment_reviewer_lookup.py +193 -0
- openhound_github-0.5.2/descriptions/edges/GH_CanDeployToEnvironment.md +0 -7
- {openhound_github-0.5.2 → openhound_github-0.5.3}/.github/CODE_OF_CONDUCT.md +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/.github/CONTRIBUTING.md +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/.github/GOVERNANCE.md +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/.github/GitHub-COC-Header.png +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/.github/GitHub-CONTRIB-Header.png +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/.github/GitHub-GOV-Header.png +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/.github/GitHub-Header.png +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/.github/GitHub-LIC-Header.png +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/.github/GitHub-SEC-Header.png +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/.github/SECURITY.md +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/.github/SO-Dark.svg +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/.github/SO-FOSS-Dark.svg +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/.github/SO-FOSS-Light.svg +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/.github/SO-Light.svg +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/.github/workflows/publish.yml +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/.github/workflows/release-on-merge.yml +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/.github/workflows/validate-branch.yml +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/.gitignore +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/.gitmodules +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/.pre-commit-config.yaml +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/LICENSE.md +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/README.md +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/descriptions/edges/GH_AddAssignee.md +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/descriptions/edges/GH_AddCollaborator.md +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/descriptions/edges/GH_AddLabel.md +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/descriptions/edges/GH_AddMember.md +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/descriptions/edges/GH_AdminTo.md +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/descriptions/edges/GH_AssignedTo.md +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/descriptions/edges/GH_BypassBranchProtection.md +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/descriptions/edges/GH_BypassPullRequestAllowances.md +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/descriptions/edges/GH_CallsWorkflow.md +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/descriptions/edges/GH_CanAccess.md +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/descriptions/edges/GH_CanAssumeIdentity.md +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/descriptions/edges/GH_CanCreateBranch.md +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/descriptions/edges/GH_CanCreateEnvironment.md +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/descriptions/edges/GH_CanCreateRepositoryWithRunnerAccess.md +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/descriptions/edges/GH_CanEditEnvironment.md +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/descriptions/edges/GH_CanEditProtection.md +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/descriptions/edges/GH_CanPwnRequest.md +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/descriptions/edges/GH_CanReadSecretScanningAlert.md +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/descriptions/edges/GH_CanUseRunner.md +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/descriptions/edges/GH_CanWriteBranch.md +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/descriptions/edges/GH_CloseDiscussion.md +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/descriptions/edges/GH_CloseIssue.md +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/descriptions/edges/GH_ClosePullRequest.md +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/descriptions/edges/GH_Contains.md +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/descriptions/edges/GH_ConvertIssuesToDiscussions.md +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/descriptions/edges/GH_CreateDiscussionCategory.md +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/descriptions/edges/GH_CreateRepository.md +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/descriptions/edges/GH_CreateSoloMergeQueueEntry.md +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/descriptions/edges/GH_CreateTag.md +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/descriptions/edges/GH_CreateTeam.md +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/descriptions/edges/GH_DeleteAlertsCodeScanning.md +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/descriptions/edges/GH_DeleteDiscussion.md +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/descriptions/edges/GH_DeleteDiscussionComment.md +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/descriptions/edges/GH_DeleteIssue.md +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/descriptions/edges/GH_DeleteTag.md +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/descriptions/edges/GH_DependsOn.md +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/descriptions/edges/GH_DeploysTo.md +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/descriptions/edges/GH_EditCategoryOnDiscussion.md +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/descriptions/edges/GH_EditDiscussionCategory.md +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/descriptions/edges/GH_EditDiscussionComment.md +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/descriptions/edges/GH_EditRepoAnnouncementBanners.md +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/descriptions/edges/GH_EditRepoCustomPropertiesValues.md +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/descriptions/edges/GH_EditRepoMetadata.md +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/descriptions/edges/GH_EditRepoProtections.md +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/descriptions/edges/GH_GrantsAccessTo.md +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/descriptions/edges/GH_HasBaseRole.md +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/descriptions/edges/GH_HasBranch.md +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/descriptions/edges/GH_HasEnvironment.md +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/descriptions/edges/GH_HasExternalIdentity.md +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/descriptions/edges/GH_HasJob.md +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/descriptions/edges/GH_HasMember.md +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/descriptions/edges/GH_HasPersonalAccessToken.md +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/descriptions/edges/GH_HasPersonalAccessTokenRequest.md +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/descriptions/edges/GH_HasRole.md +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/descriptions/edges/GH_HasSamlIdentityProvider.md +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/descriptions/edges/GH_HasSecret.md +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/descriptions/edges/GH_HasStep.md +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/descriptions/edges/GH_HasVariable.md +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/descriptions/edges/GH_HasWorkflow.md +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/descriptions/edges/GH_InheritedFrom.md +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/descriptions/edges/GH_InstalledAs.md +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/descriptions/edges/GH_InviteMember.md +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/descriptions/edges/GH_JumpMergeQueue.md +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/descriptions/edges/GH_ManageDeployKeys.md +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/descriptions/edges/GH_ManageDiscussionBadges.md +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/descriptions/edges/GH_ManageOrganizationWebhooks.md +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/descriptions/edges/GH_ManageRepoSecurityProducts.md +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/descriptions/edges/GH_ManageSecurityProducts.md +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/descriptions/edges/GH_ManageSettingsMergeTypes.md +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/descriptions/edges/GH_ManageSettingsPages.md +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/descriptions/edges/GH_ManageSettingsProjects.md +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/descriptions/edges/GH_ManageSettingsWiki.md +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/descriptions/edges/GH_ManageTopics.md +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/descriptions/edges/GH_ManageWebhooks.md +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/descriptions/edges/GH_MapsToUser.md +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/descriptions/edges/GH_MarkAsDuplicate.md +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/descriptions/edges/GH_MatchesEnvironmentPolicy.md +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/descriptions/edges/GH_MemberOf.md +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/descriptions/edges/GH_OrgBypassCodeScanningDismissalRequests.md +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/descriptions/edges/GH_OrgBypassSecretScanningClosureRequests.md +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/descriptions/edges/GH_OrgReviewAndManageSecretScanningBypassRequests.md +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/descriptions/edges/GH_OrgReviewAndManageSecretScanningClosureRequests.md +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/descriptions/edges/GH_Owns.md +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/descriptions/edges/GH_ProtectedBy.md +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/descriptions/edges/GH_PushProtectedBranch.md +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/descriptions/edges/GH_ReadCodeScanning.md +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/descriptions/edges/GH_ReadOrganizationActionsUsageMetrics.md +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/descriptions/edges/GH_ReadOrganizationCustomOrgRole.md +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/descriptions/edges/GH_ReadOrganizationCustomRepoRole.md +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/descriptions/edges/GH_ReadRepoContents.md +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/descriptions/edges/GH_RemoveAssignee.md +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/descriptions/edges/GH_RemoveLabel.md +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/descriptions/edges/GH_ReopenDiscussion.md +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/descriptions/edges/GH_ReopenIssue.md +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/descriptions/edges/GH_ReopenPullRequest.md +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/descriptions/edges/GH_RequestPrReview.md +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/descriptions/edges/GH_ResolveDependabotAlerts.md +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/descriptions/edges/GH_ResolveSecretScanningAlerts.md +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/descriptions/edges/GH_RestrictionsCanPush.md +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/descriptions/edges/GH_RunOrgMigration.md +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/descriptions/edges/GH_SetInteractionLimits.md +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/descriptions/edges/GH_SetIssueType.md +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/descriptions/edges/GH_SetMilestone.md +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/descriptions/edges/GH_SetSocialPreview.md +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/descriptions/edges/GH_SyncedTo.md +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/descriptions/edges/GH_ToggleDiscussionAnswer.md +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/descriptions/edges/GH_ToggleDiscussionCommentMinimize.md +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/descriptions/edges/GH_TransferRepository.md +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/descriptions/edges/GH_UsesSecret.md +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/descriptions/edges/GH_UsesVariable.md +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/descriptions/edges/GH_ValidToken.md +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/descriptions/edges/GH_ViewDependabotAlerts.md +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/descriptions/edges/GH_ViewSecretScanningAlerts.md +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/descriptions/edges/GH_WriteCodeScanning.md +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/descriptions/edges/GH_WriteOrganizationActionsSecrets.md +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/descriptions/edges/GH_WriteOrganizationActionsSettings.md +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/descriptions/edges/GH_WriteOrganizationActionsVariables.md +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/descriptions/edges/GH_WriteOrganizationCustomOrgRole.md +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/descriptions/edges/GH_WriteOrganizationCustomRepoRole.md +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/descriptions/edges/GH_WriteOrganizationNetworkConfigurations.md +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/descriptions/edges/GH_WriteRepoContents.md +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/descriptions/edges/GH_WriteRepoPullRequests.md +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/descriptions/nodes/GH_App.md +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/descriptions/nodes/GH_AppInstallation.md +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/descriptions/nodes/GH_Branch.md +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/descriptions/nodes/GH_BranchProtectionRule.md +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/descriptions/nodes/GH_EnterpriseRunner.md +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/descriptions/nodes/GH_EnterpriseRunnerGroup.md +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/descriptions/nodes/GH_Environment.md +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/descriptions/nodes/GH_EnvironmentBranchPolicy.md +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/descriptions/nodes/GH_EnvironmentSecret.md +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/descriptions/nodes/GH_EnvironmentVariable.md +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/descriptions/nodes/GH_ExternalIdentity.md +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/descriptions/nodes/GH_OrgRole.md +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/descriptions/nodes/GH_OrgRunner.md +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/descriptions/nodes/GH_OrgRunnerGroup.md +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/descriptions/nodes/GH_OrgSecret.md +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/descriptions/nodes/GH_OrgVariable.md +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/descriptions/nodes/GH_Organization.md +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/descriptions/nodes/GH_PersonalAccessToken.md +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/descriptions/nodes/GH_PersonalAccessTokenRequest.md +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/descriptions/nodes/GH_RepoRole.md +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/descriptions/nodes/GH_RepoRunner.md +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/descriptions/nodes/GH_RepoSecret.md +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/descriptions/nodes/GH_RepoVariable.md +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/descriptions/nodes/GH_Repository.md +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/descriptions/nodes/GH_SamlIdentityProvider.md +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/descriptions/nodes/GH_SecretScanningAlert.md +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/descriptions/nodes/GH_Team.md +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/descriptions/nodes/GH_TeamRole.md +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/descriptions/nodes/GH_User.md +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/descriptions/nodes/GH_Workflow.md +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/descriptions/nodes/GH_WorkflowJob.md +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/descriptions/nodes/GH_WorkflowStep.md +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/docs/og-docs.json +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/extension/privilege_zone_rules/t0-all-repo-admin-role.json +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/extension/privilege_zone_rules/t0-app-installations-all-repos.json +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/extension/privilege_zone_rules/t0-apps-all-repos.json +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/extension/privilege_zone_rules/t0-external-identities-owners.json +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/extension/privilege_zone_rules/t0-organizations.json +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/extension/privilege_zone_rules/t0-owner-users.json +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/extension/privilege_zone_rules/t0-owners-role.json +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/extension/privilege_zone_rules/t0-pats-all-repos.json +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/extension/privilege_zone_rules/t0-privilege-escalation-roles.json +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/extension/privilege_zone_rules/t0-privilege-escalation-users.json +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/extension/privilege_zone_rules/t0-saml-identity-providers.json +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/extension/saved_searches/README.md +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/extension/saved_searches/actions-sha-pinning-not-required.json +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/extension/saved_searches/active-leaked-secrets.json +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/extension/saved_searches/advanced-security-disabled-new-repos.json +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/extension/saved_searches/all-actions-allowed.json +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/extension/saved_searches/app-installations-all-repos.json +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/extension/saved_searches/branch-protection-admins-not-enforced.json +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/extension/saved_searches/branch-protection-deletions-allowed.json +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/extension/saved_searches/branch-protection-force-pushes.json +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/extension/saved_searches/branch-protection-no-code-owner-reviews.json +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/extension/saved_searches/branch-protection-no-pr-reviews.json +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/extension/saved_searches/branch-protection-no-status-checks.json +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/extension/saved_searches/branch-protection-self-approval.json +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/extension/saved_searches/branch-protection-stale-reviews.json +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/extension/saved_searches/bypass-pr-requirements.json +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/extension/saved_searches/dangerous-branch-perms.json +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/extension/saved_searches/default-repository-permissions.json +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/extension/saved_searches/demo-sso-to-cloud-round-trip.json +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/extension/saved_searches/dependabot-alerts-disabled-new-repos.json +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/extension/saved_searches/dependabot-updates-disabled-new-repos.json +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/extension/saved_searches/dependency-graph-disabled-new-repos.json +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/extension/saved_searches/environments-admin-bypass.json +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/extension/saved_searches/expired-pats.json +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/extension/saved_searches/external-identities-without-scim.json +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/extension/saved_searches/github-to-azure-identity.json +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/extension/saved_searches/global-repo-perms.json +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/extension/saved_searches/hybrid-identities.json +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/extension/saved_searches/members-can-change-repo-visibility.json +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/extension/saved_searches/members-can-create-pages.json +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/extension/saved_searches/members-can-create-public-repos.json +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/extension/saved_searches/members-can-delete-repos.json +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/extension/saved_searches/members-can-fork-private-repos.json +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/extension/saved_searches/members-can-invite-outside-collaborators.json +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/extension/saved_searches/org-owners.json +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/extension/saved_searches/orgs-without-2fa.json +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/extension/saved_searches/pats-all-repo-access.json +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/extension/saved_searches/pending-pat-requests.json +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/extension/saved_searches/private-repos-forking-allowed.json +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/extension/saved_searches/privileged-custom-org-roles.json +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/extension/saved_searches/privileged-hybrid-identities.json +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/extension/saved_searches/public-repos.json +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/extension/saved_searches/push-protection-disabled-new-repos.json +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/extension/saved_searches/push-to-protected-branches.json +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/extension/saved_searches/repos-secret-scanning-disabled.json +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/extension/saved_searches/repos-vulnerable-to-workflow-secret-exfil.json +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/extension/saved_searches/repository-workflows.json +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/extension/saved_searches/saml-configuration.json +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/extension/saved_searches/secret-scanning-alerts.json +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/extension/saved_searches/secret-scanning-disabled-new-repos.json +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/extension/saved_searches/secrets-reachable-by-user.json +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/extension/saved_searches/team-membership-admin.json +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/extension/saved_searches/team-structure.json +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/extension/saved_searches/unprotected-branches.json +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/extension/saved_searches/unprotected-default-branch-with-workflow.json +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/extension/saved_searches/unprotected-default-branches.json +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/extension/saved_searches/web-commit-signoff-not-required.json +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/justfile +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/pyproject.toml +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/src/main.py +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/src/openhound_github/__init__.py +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/src/openhound_github/auth.py +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/src/openhound_github/extension.yaml +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/src/openhound_github/graph.py +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/src/openhound_github/graphql.py +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/src/openhound_github/helpers.py +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/src/openhound_github/kinds/edges.py +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/src/openhound_github/kinds/nodes.py +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/src/openhound_github/models/__init__.py +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/src/openhound_github/models/actions_permission.py +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/src/openhound_github/models/app_installation.py +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/src/openhound_github/models/branch.py +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/src/openhound_github/models/branch_pr_bypass_allowance.py +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/src/openhound_github/models/branch_protection_rule.py +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/src/openhound_github/models/branch_push_allowance.py +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/src/openhound_github/models/enterprise.py +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/src/openhound_github/models/enterprise_admin.py +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/src/openhound_github/models/enterprise_helpers.py +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/src/openhound_github/models/enterprise_managed_user.py +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/src/openhound_github/models/enterprise_member.py +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/src/openhound_github/models/enterprise_organization.py +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/src/openhound_github/models/enterprise_role.py +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/src/openhound_github/models/enterprise_role_team.py +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/src/openhound_github/models/enterprise_role_user.py +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/src/openhound_github/models/enterprise_team.py +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/src/openhound_github/models/enterprise_team_member.py +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/src/openhound_github/models/enterprise_team_organization.py +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/src/openhound_github/models/enterprise_team_role.py +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/src/openhound_github/models/enterprise_user.py +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/src/openhound_github/models/env_secret.py +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/src/openhound_github/models/env_variable.py +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/src/openhound_github/models/external_identity.py +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/src/openhound_github/models/org.py +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/src/openhound_github/models/org_role.py +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/src/openhound_github/models/org_role_member.py +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/src/openhound_github/models/org_role_team.py +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/src/openhound_github/models/org_secret.py +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/src/openhound_github/models/org_variable.py +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/src/openhound_github/models/personal_access_token.py +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/src/openhound_github/models/personal_access_token_access.py +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/src/openhound_github/models/personal_access_token_request.py +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/src/openhound_github/models/projected_enterprise_team.py +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/src/openhound_github/models/repo_role_assignment.py +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/src/openhound_github/models/repository.py +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/src/openhound_github/models/repository_role.py +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/src/openhound_github/models/repository_secret.py +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/src/openhound_github/models/repository_variable.py +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/src/openhound_github/models/runner.py +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/src/openhound_github/models/saml_assertion_consumer_service.py +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/src/openhound_github/models/saml_helpers.py +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/src/openhound_github/models/saml_issuer.py +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/src/openhound_github/models/saml_provider.py +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/src/openhound_github/models/saml_service_provider.py +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/src/openhound_github/models/scim_user.py +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/src/openhound_github/models/secret_scanning_alert.py +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/src/openhound_github/models/team.py +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/src/openhound_github/models/team_member.py +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/src/openhound_github/models/team_role.py +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/src/openhound_github/models/user.py +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/src/openhound_github/models/workflow.py +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/src/openhound_github/models/workflow_job.py +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/src/openhound_github/models/workflow_step.py +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/src/openhound_github/resources/__init__.py +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/src/openhound_github/resources/enterprise.py +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/src/openhound_github/resources/organization.py +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/src/openhound_github/runner_ids.py +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/src/openhound_github/source.py +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/tests/test_app_auth.py +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/tests/test_branch_collection_gate.py +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/tests/test_branch_protection_traversability.py +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/tests/test_data/api/actions-permissions.json +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/tests/test_data/api/actionsecrets.json +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/tests/test_data/api/app.json +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/tests/test_data/api/appinstalls.json +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/tests/test_data/api/branch-policies.json +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/tests/test_data/api/branch-prot-rules.json +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/tests/test_data/api/branches.json +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/tests/test_data/api/custom-roles.json +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/tests/test_data/api/environments.json +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/tests/test_data/api/org-pat-request.json +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/tests/test_data/api/org-pat.json +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/tests/test_data/api/org-role-teams.json +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/tests/test_data/api/org-role-users.json +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/tests/test_data/api/org-roles.json +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/tests/test_data/api/org.json +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/tests/test_data/api/pat-repositories.json +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/tests/test_data/api/repo-collaborators.json +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/tests/test_data/api/repo-teams.json +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/tests/test_data/api/repositories.json +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/tests/test_data/api/scimusers.json +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/tests/test_data/api/secrets.json +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/tests/test_data/api/secretscanningalert.json +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/tests/test_data/api/selected-org-secrets.json +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/tests/test_data/api/variables.json +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/tests/test_data/api/workflows.json +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/tests/test_enterprise_capabilities.py +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/tests/test_enterprise_organization.py +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/tests/test_enterprise_resources.py +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/tests/test_environment_resources.py +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/tests/test_error_resilience.py +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/tests/test_external_identity_tenant_matching.py +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/tests/test_github_rest_client.py +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/tests/test_github_retry.py +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/tests/test_org_secret_models.py +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/tests/test_repository_rulesets.py +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/tests/test_runner_ids.py +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/tests/test_runner_models.py +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/tests/test_runner_resources.py +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/tests/test_saml_helpers.py +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/tests/test_saml_models.py +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/tests/test_scim_models.py +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/tests/test_variable_models.py +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/tests/test_workflow_model.py +0 -0
- {openhound_github-0.5.2 → openhound_github-0.5.3}/uv.lock +0 -0
{openhound_github-0.5.2 → openhound_github-0.5.3}/descriptions/edges/GH_ApprovesDeploymentTo.md
RENAMED
|
@@ -4,4 +4,4 @@ The non-traversable GH_ApprovesDeploymentTo edge represents that a user or team
|
|
|
4
4
|
|
|
5
5
|
This edge is emitted from GH_User or GH_Team nodes to GH_Environment nodes when the environment includes a required reviewer protection rule. Required reviewers act as an approval gate before jobs referencing the environment can continue.
|
|
6
6
|
|
|
7
|
-
The edge is non-traversable because it records reviewer configuration rather than direct deployment access. When self-review is allowed, the same reviewer may also receive a traversable GH_CanDeployToEnvironment edge
|
|
7
|
+
The edge is non-traversable because it records reviewer configuration rather than direct deployment access. When self-review is allowed, the same reviewer may also receive a traversable GH_CanDeployToEnvironment edge only if they can also supply deployable code through GH_CanCreateBranch or GH_CanWriteBranch under the environment's branch policy. When prevent_self_review is enabled, GH_ApprovesDeploymentTo remains context only because the split-principal approval flow is not currently modeled.
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
## General Information
|
|
2
|
+
|
|
3
|
+
The traversable GH_CanDeployToEnvironment edge represents the ability for a repository, branch, repository role, or reviewer to satisfy the modeled deployment constraints for a GitHub Environment.
|
|
4
|
+
|
|
5
|
+
This edge is computed from environment deployment branch policy, branch protection state, required reviewer behavior, and administrator bypass behavior. For environments without required reviewers, unrestricted environments emit repository and branch edges, protected-branch-only environments emit edges only for protected branches unless no branch protection rules exist, and custom branch policies emit edges only for matching branches.
|
|
6
|
+
|
|
7
|
+
When required reviewers are configured and self-review is allowed, a configured GH_User or GH_Team reviewer receives GH_CanDeployToEnvironment only when the same actor can also supply deployable code. For unrestricted environments this means the actor can create a branch in the repository. For protected-branch-only or custom branch policy environments this means the actor can write to an eligible branch under the existing GH_CanWriteBranch rules.
|
|
8
|
+
|
|
9
|
+
Self-review alone is not sufficient for this edge. GH_ApprovesDeploymentTo remains the non-traversable representation of reviewer authority, while GH_CanDeployToEnvironment represents the combined ability to satisfy both the approval gate and the code-supply path. When prevent_self_review is enabled, no direct deploy edge is emitted for the reviewer because the required split-principal flow is not currently modeled.
|
|
@@ -1042,7 +1042,7 @@
|
|
|
1042
1042
|
},
|
|
1043
1043
|
{
|
|
1044
1044
|
"name": "GH_CanDeployToEnvironment",
|
|
1045
|
-
"description": "[Computed] Repository, branch, repo role, or
|
|
1045
|
+
"description": "[Computed] Repository, branch, repo role, or reviewer can deploy to this GitHub environment after evaluating deployment branch policy, reviewer gates, and admin bypass behavior; reviewer edges require both self-approval and a deployable code path",
|
|
1046
1046
|
"is_traversable": true
|
|
1047
1047
|
},
|
|
1048
1048
|
{
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import json
|
|
1
2
|
from functools import lru_cache
|
|
2
3
|
|
|
3
4
|
import duckdb
|
|
@@ -584,6 +585,265 @@ class GithubLookup(LookupManager):
|
|
|
584
585
|
[repository_node_id],
|
|
585
586
|
)
|
|
586
587
|
|
|
588
|
+
@lru_cache
|
|
589
|
+
def environment_branch_policy_names(self, environment_node_id: str):
|
|
590
|
+
return self._find_all_objects(
|
|
591
|
+
f"""
|
|
592
|
+
SELECT name
|
|
593
|
+
FROM {self.schema}.environment_branch_policies
|
|
594
|
+
WHERE environment_node_id = ?
|
|
595
|
+
""",
|
|
596
|
+
[environment_node_id],
|
|
597
|
+
)
|
|
598
|
+
|
|
599
|
+
@lru_cache
|
|
600
|
+
def reviewer_repo_role_assignments(
|
|
601
|
+
self, reviewer_node_id: str, reviewer_kind: str, repository_node_id: str
|
|
602
|
+
):
|
|
603
|
+
reviewer_kind = reviewer_kind.lower()
|
|
604
|
+
return self._find_all_objects(
|
|
605
|
+
f"""
|
|
606
|
+
WITH RECURSIVE
|
|
607
|
+
repository_org(org_login) AS (
|
|
608
|
+
SELECT org_login
|
|
609
|
+
FROM {self.schema}.repositories
|
|
610
|
+
WHERE node_id = ?
|
|
611
|
+
),
|
|
612
|
+
seed_teams(team_id) AS (
|
|
613
|
+
SELECT ? WHERE ? = 'team'
|
|
614
|
+
|
|
615
|
+
UNION
|
|
616
|
+
|
|
617
|
+
SELECT tm.team_id
|
|
618
|
+
FROM {self.schema}.team_members tm
|
|
619
|
+
WHERE ? = 'user'
|
|
620
|
+
AND tm.id = ?
|
|
621
|
+
),
|
|
622
|
+
actor_teams(team_id) AS (
|
|
623
|
+
SELECT team_id
|
|
624
|
+
FROM seed_teams
|
|
625
|
+
|
|
626
|
+
UNION
|
|
627
|
+
|
|
628
|
+
SELECT json_extract_string(t.parent_team, '$.id')
|
|
629
|
+
FROM {self.schema}.teams t
|
|
630
|
+
JOIN actor_teams actor_team ON t.id = actor_team.team_id
|
|
631
|
+
WHERE t.parent_team IS NOT NULL
|
|
632
|
+
AND json_extract_string(t.parent_team, '$.id') IS NOT NULL
|
|
633
|
+
),
|
|
634
|
+
direct_repo_roles(
|
|
635
|
+
assignment_actor_id,
|
|
636
|
+
role_id,
|
|
637
|
+
role_name,
|
|
638
|
+
base_role,
|
|
639
|
+
role_permissions
|
|
640
|
+
) AS (
|
|
641
|
+
SELECT DISTINCT
|
|
642
|
+
rra.node_id,
|
|
643
|
+
rr.id,
|
|
644
|
+
rra.role_name,
|
|
645
|
+
coalesce(rra.base_role, rr.base_role),
|
|
646
|
+
rra.role_permissions
|
|
647
|
+
FROM {self.schema}.repo_role_assignments rra
|
|
648
|
+
LEFT JOIN {self.schema}.repo_roles rr
|
|
649
|
+
ON rr.repository_node_id = rra.repo_node_id
|
|
650
|
+
AND rr.name = rra.role_name
|
|
651
|
+
WHERE rra.repo_node_id = ?
|
|
652
|
+
AND (
|
|
653
|
+
(lower(rra.assignee_type) = ? AND rra.node_id = ?)
|
|
654
|
+
OR (
|
|
655
|
+
lower(rra.assignee_type) = 'team'
|
|
656
|
+
AND rra.node_id IN (SELECT team_id FROM actor_teams)
|
|
657
|
+
)
|
|
658
|
+
)
|
|
659
|
+
),
|
|
660
|
+
actor_org_roles(assignment_actor_id, org_role_name, base_role) AS (
|
|
661
|
+
SELECT
|
|
662
|
+
u.id,
|
|
663
|
+
CASE WHEN u.role = 'ADMIN' THEN 'owners' ELSE 'members' END,
|
|
664
|
+
org_role.base_role
|
|
665
|
+
FROM {self.schema}.users u
|
|
666
|
+
JOIN repository_org repo_org ON repo_org.org_login = u.org_login
|
|
667
|
+
JOIN {self.schema}.org_roles org_role
|
|
668
|
+
ON org_role.org_login = u.org_login
|
|
669
|
+
AND org_role.name = CASE
|
|
670
|
+
WHEN u.role = 'ADMIN' THEN 'owners'
|
|
671
|
+
ELSE 'members'
|
|
672
|
+
END
|
|
673
|
+
WHERE ? = 'user'
|
|
674
|
+
AND u.id = ?
|
|
675
|
+
|
|
676
|
+
UNION
|
|
677
|
+
|
|
678
|
+
SELECT
|
|
679
|
+
orm.node_id,
|
|
680
|
+
orm.org_role_name,
|
|
681
|
+
org_role.base_role
|
|
682
|
+
FROM {self.schema}.org_role_members orm
|
|
683
|
+
JOIN repository_org repo_org ON repo_org.org_login = orm.org_login
|
|
684
|
+
JOIN {self.schema}.org_roles org_role
|
|
685
|
+
ON org_role.org_login = orm.org_login
|
|
686
|
+
AND org_role.name = orm.org_role_name
|
|
687
|
+
WHERE ? = 'user'
|
|
688
|
+
AND orm.node_id = ?
|
|
689
|
+
|
|
690
|
+
UNION
|
|
691
|
+
|
|
692
|
+
SELECT
|
|
693
|
+
ort.node_id,
|
|
694
|
+
ort.org_role_name,
|
|
695
|
+
org_role.base_role
|
|
696
|
+
FROM {self.schema}.org_role_teams ort
|
|
697
|
+
JOIN repository_org repo_org ON repo_org.org_login = ort.org_login
|
|
698
|
+
JOIN {self.schema}.org_roles org_role
|
|
699
|
+
ON org_role.org_login = ort.org_login
|
|
700
|
+
AND org_role.name = ort.org_role_name
|
|
701
|
+
WHERE ort.node_id IN (SELECT team_id FROM actor_teams)
|
|
702
|
+
),
|
|
703
|
+
org_repo_roles(
|
|
704
|
+
assignment_actor_id,
|
|
705
|
+
role_id,
|
|
706
|
+
role_name,
|
|
707
|
+
base_role,
|
|
708
|
+
role_permissions
|
|
709
|
+
) AS (
|
|
710
|
+
SELECT DISTINCT
|
|
711
|
+
actor_org_role.assignment_actor_id,
|
|
712
|
+
rr.id,
|
|
713
|
+
rr.name,
|
|
714
|
+
rr.base_role,
|
|
715
|
+
rr.permissions
|
|
716
|
+
FROM actor_org_roles actor_org_role
|
|
717
|
+
JOIN {self.schema}.repo_roles rr
|
|
718
|
+
ON rr.repository_node_id = ?
|
|
719
|
+
AND rr.name = actor_org_role.base_role
|
|
720
|
+
)
|
|
721
|
+
SELECT * FROM direct_repo_roles
|
|
722
|
+
UNION
|
|
723
|
+
SELECT * FROM org_repo_roles
|
|
724
|
+
""",
|
|
725
|
+
[
|
|
726
|
+
repository_node_id,
|
|
727
|
+
reviewer_node_id,
|
|
728
|
+
reviewer_kind,
|
|
729
|
+
reviewer_kind,
|
|
730
|
+
reviewer_node_id,
|
|
731
|
+
repository_node_id,
|
|
732
|
+
reviewer_kind,
|
|
733
|
+
reviewer_node_id,
|
|
734
|
+
reviewer_kind,
|
|
735
|
+
reviewer_node_id,
|
|
736
|
+
reviewer_kind,
|
|
737
|
+
reviewer_node_id,
|
|
738
|
+
repository_node_id,
|
|
739
|
+
],
|
|
740
|
+
)
|
|
741
|
+
|
|
742
|
+
@staticmethod
|
|
743
|
+
def _role_permissions(raw_permissions) -> set[str]:
|
|
744
|
+
if raw_permissions is None:
|
|
745
|
+
return set()
|
|
746
|
+
if isinstance(raw_permissions, str):
|
|
747
|
+
try:
|
|
748
|
+
raw_permissions = json.loads(raw_permissions)
|
|
749
|
+
except json.JSONDecodeError:
|
|
750
|
+
return set()
|
|
751
|
+
if not isinstance(raw_permissions, list):
|
|
752
|
+
return set()
|
|
753
|
+
return {str(permission) for permission in raw_permissions}
|
|
754
|
+
|
|
755
|
+
@lru_cache
|
|
756
|
+
def reviewer_deployment_path(
|
|
757
|
+
self,
|
|
758
|
+
reviewer_node_id: str,
|
|
759
|
+
reviewer_kind: str,
|
|
760
|
+
repository_node_id: str,
|
|
761
|
+
eligible_branch_ids: tuple[str, ...],
|
|
762
|
+
allow_create_branch: bool,
|
|
763
|
+
) -> tuple[str, str | None] | None:
|
|
764
|
+
if not self.repository_default_branch_collected(repository_node_id):
|
|
765
|
+
return None
|
|
766
|
+
|
|
767
|
+
eligible_branches = set(eligible_branch_ids)
|
|
768
|
+
write_roles = {"write", "maintain", "admin"}
|
|
769
|
+
bypass_roles = {"maintain"}
|
|
770
|
+
|
|
771
|
+
for (
|
|
772
|
+
assignment_actor_id,
|
|
773
|
+
role_id,
|
|
774
|
+
role_name,
|
|
775
|
+
base_role,
|
|
776
|
+
raw_permissions,
|
|
777
|
+
) in self.reviewer_repo_role_assignments(
|
|
778
|
+
reviewer_node_id, reviewer_kind, repository_node_id
|
|
779
|
+
):
|
|
780
|
+
permissions = self._role_permissions(raw_permissions)
|
|
781
|
+
has_write_access = role_name in write_roles or base_role in write_roles
|
|
782
|
+
if not has_write_access:
|
|
783
|
+
continue
|
|
784
|
+
|
|
785
|
+
if (
|
|
786
|
+
allow_create_branch
|
|
787
|
+
and role_id is not None
|
|
788
|
+
and self.role_can_create_branch(role_id, repository_node_id)
|
|
789
|
+
):
|
|
790
|
+
return ("create_branch", None)
|
|
791
|
+
|
|
792
|
+
writable_branches = {
|
|
793
|
+
branch_id
|
|
794
|
+
for (branch_id,) in self.unprotected_branches(repository_node_id)
|
|
795
|
+
}
|
|
796
|
+
|
|
797
|
+
has_push_protected_branch = (
|
|
798
|
+
("push_protected_branch" in permissions and base_role in write_roles)
|
|
799
|
+
or role_name in bypass_roles
|
|
800
|
+
or base_role in bypass_roles
|
|
801
|
+
)
|
|
802
|
+
has_bypass_branch_protection = (
|
|
803
|
+
"bypass_branch_protection" in permissions and base_role in write_roles
|
|
804
|
+
)
|
|
805
|
+
|
|
806
|
+
if role_name == "admin" or base_role == "admin":
|
|
807
|
+
writable_branches.update(
|
|
808
|
+
branch_id
|
|
809
|
+
for (branch_id,) in self._write_admin_bypass(repository_node_id)
|
|
810
|
+
)
|
|
811
|
+
if has_push_protected_branch:
|
|
812
|
+
writable_branches.update(
|
|
813
|
+
branch_id
|
|
814
|
+
for (branch_id,) in self._write_push_restricted_branch_bypass(
|
|
815
|
+
repository_node_id
|
|
816
|
+
)
|
|
817
|
+
)
|
|
818
|
+
if has_bypass_branch_protection:
|
|
819
|
+
writable_branches.update(
|
|
820
|
+
branch_id
|
|
821
|
+
for (branch_id,) in self._write_branch_protection_bypass(
|
|
822
|
+
repository_node_id
|
|
823
|
+
)
|
|
824
|
+
)
|
|
825
|
+
if has_push_protected_branch and has_bypass_branch_protection:
|
|
826
|
+
writable_branches.update(
|
|
827
|
+
branch_id
|
|
828
|
+
for (branch_id,) in self._write_combined_bypass(repository_node_id)
|
|
829
|
+
)
|
|
830
|
+
|
|
831
|
+
writable_branches.update(
|
|
832
|
+
branch_id
|
|
833
|
+
for (branch_id,) in self.actor_gate_bypass(
|
|
834
|
+
assignment_actor_id,
|
|
835
|
+
repository_node_id,
|
|
836
|
+
has_bypass_branch_protection,
|
|
837
|
+
has_push_protected_branch,
|
|
838
|
+
)
|
|
839
|
+
)
|
|
840
|
+
|
|
841
|
+
for branch_id in eligible_branch_ids:
|
|
842
|
+
if branch_id in writable_branches and branch_id in eligible_branches:
|
|
843
|
+
return ("write_branch", branch_id)
|
|
844
|
+
|
|
845
|
+
return None
|
|
846
|
+
|
|
587
847
|
@lru_cache
|
|
588
848
|
def members_can_fork_private_repositories(self, org_login: str):
|
|
589
849
|
return self._find_all_objects(
|
|
@@ -59,6 +59,9 @@ def preproc(ctx: PreProcContext):
|
|
|
59
59
|
"repo_role_assignments": "repo_role_assignments",
|
|
60
60
|
"branches": "branches",
|
|
61
61
|
"repo_roles": "repo_roles",
|
|
62
|
+
"users": "users",
|
|
63
|
+
"teams": "teams",
|
|
64
|
+
"team_members": "team_members",
|
|
62
65
|
"saml_provider": "saml_provider",
|
|
63
66
|
"applications": "applications",
|
|
64
67
|
"enterprise": "enterprise",
|
|
@@ -67,8 +70,11 @@ def preproc(ctx: PreProcContext):
|
|
|
67
70
|
"enterprise_runner_group_organizations": "enterprise_runner_group_organizations",
|
|
68
71
|
"enterprise_runner_group_memberships": "enterprise_runner_group_memberships",
|
|
69
72
|
"org_roles": "org_roles",
|
|
73
|
+
"org_role_members": "org_role_members",
|
|
74
|
+
"org_role_teams": "org_role_teams",
|
|
70
75
|
"projected_enterprise_teams": "projected_enterprise_teams",
|
|
71
76
|
"environments": "environments",
|
|
77
|
+
"environment_branch_policies": "environment_branch_policies",
|
|
72
78
|
"environment_secrets": "environment_secrets",
|
|
73
79
|
"environment_variables": "environment_variables",
|
|
74
80
|
"organization_secrets": "organization_secrets",
|
{openhound_github-0.5.2 → openhound_github-0.5.3}/src/openhound_github/models/environment.py
RENAMED
|
@@ -10,6 +10,9 @@ from openhound_github.graph import GHEdgeProperties, GHNode, GHNodeProperties
|
|
|
10
10
|
from openhound_github.kinds import edges as ek
|
|
11
11
|
from openhound_github.kinds import nodes as nk
|
|
12
12
|
from openhound_github.main import app
|
|
13
|
+
from openhound_github.models.environment_branch_policy import (
|
|
14
|
+
matches_environment_branch_policy,
|
|
15
|
+
)
|
|
13
16
|
|
|
14
17
|
|
|
15
18
|
class DeploymentBranchPolicy(BaseModel):
|
|
@@ -142,14 +145,14 @@ class GHEnvironmentProperties(GHNodeProperties):
|
|
|
142
145
|
start=nk.USER,
|
|
143
146
|
end=nk.ENVIRONMENT,
|
|
144
147
|
kind=ek.CAN_DEPLOY_TO_ENVIRONMENT,
|
|
145
|
-
description="Reviewer user can self-approve
|
|
148
|
+
description="Reviewer user can self-approve and supply deployable code under current branch policy",
|
|
146
149
|
traversable=True,
|
|
147
150
|
),
|
|
148
151
|
EdgeDef(
|
|
149
152
|
start=nk.TEAM,
|
|
150
153
|
end=nk.ENVIRONMENT,
|
|
151
154
|
kind=ek.CAN_DEPLOY_TO_ENVIRONMENT,
|
|
152
|
-
description="Reviewer team can self-approve
|
|
155
|
+
description="Reviewer team can self-approve and supply deployable code under current branch policy",
|
|
153
156
|
traversable=True,
|
|
154
157
|
),
|
|
155
158
|
EdgeDef(
|
|
@@ -240,6 +243,53 @@ class Environment(BaseAsset):
|
|
|
240
243
|
def reviewer_self_deployment_edges_allowed(self) -> bool:
|
|
241
244
|
return self.required_reviewers and not self.prevent_self_review
|
|
242
245
|
|
|
246
|
+
@property
|
|
247
|
+
def _reviewer_eligible_branch_ids(self) -> tuple[str, ...]:
|
|
248
|
+
branches = self._lookup.branches_for_repository(self.repository_node_id)
|
|
249
|
+
|
|
250
|
+
if self.has_custom_branch_policies:
|
|
251
|
+
protected_branches_only = bool(
|
|
252
|
+
self.deployment_branch_policy
|
|
253
|
+
and self.deployment_branch_policy.protected_branches
|
|
254
|
+
)
|
|
255
|
+
policy_names = {
|
|
256
|
+
policy_name
|
|
257
|
+
for (policy_name,) in self._lookup.environment_branch_policy_names(
|
|
258
|
+
self.node_id
|
|
259
|
+
)
|
|
260
|
+
}
|
|
261
|
+
return tuple(
|
|
262
|
+
branch_id
|
|
263
|
+
for branch_id, branch_name, protected in branches
|
|
264
|
+
if any(
|
|
265
|
+
matches_environment_branch_policy(branch_name, policy_name)
|
|
266
|
+
for policy_name in policy_names
|
|
267
|
+
)
|
|
268
|
+
and (not protected_branches_only or protected)
|
|
269
|
+
)
|
|
270
|
+
|
|
271
|
+
if (
|
|
272
|
+
self.deployment_branch_policy
|
|
273
|
+
and self.deployment_branch_policy.protected_branches
|
|
274
|
+
):
|
|
275
|
+
protected_branch_ids = tuple(
|
|
276
|
+
branch_id
|
|
277
|
+
for (branch_id,) in self._lookup.branches_with_bpr(
|
|
278
|
+
self.repository_node_id
|
|
279
|
+
)
|
|
280
|
+
)
|
|
281
|
+
if protected_branch_ids:
|
|
282
|
+
return protected_branch_ids
|
|
283
|
+
|
|
284
|
+
return tuple(branch_id for branch_id, _branch_name, _protected in branches)
|
|
285
|
+
|
|
286
|
+
@property
|
|
287
|
+
def _reviewer_can_create_branch_for_deployment(self) -> bool:
|
|
288
|
+
return not self.has_custom_branch_policies and not (
|
|
289
|
+
self.deployment_branch_policy
|
|
290
|
+
and self.deployment_branch_policy.protected_branches
|
|
291
|
+
)
|
|
292
|
+
|
|
243
293
|
@property
|
|
244
294
|
def as_node(self) -> GHNode:
|
|
245
295
|
eid = self.node_id
|
|
@@ -313,16 +363,107 @@ class Environment(BaseAsset):
|
|
|
313
363
|
f"RETURN p"
|
|
314
364
|
)
|
|
315
365
|
|
|
316
|
-
def
|
|
366
|
+
def _reviewer_can_create_branch_query(
|
|
317
367
|
self, reviewer_node_id: str, reviewer_kind: str
|
|
318
368
|
) -> str:
|
|
319
369
|
return (
|
|
320
|
-
f"MATCH p=(:{reviewer_kind} {{node_id:'{reviewer_node_id}'}})"
|
|
321
|
-
f"-[:
|
|
370
|
+
f"MATCH p=(actor:{reviewer_kind} {{node_id:'{reviewer_node_id}'}})"
|
|
371
|
+
f"-[:GH_HasRole|GH_HasBaseRole|GH_MemberOf*1..]->"
|
|
372
|
+
f"(:GH_RepoRole)-[:GH_CanCreateBranch]->"
|
|
373
|
+
f"(repo:GH_Repository {{node_id:'{self.repository_node_id}'}}) "
|
|
374
|
+
f"MATCH p1=(actor)-[:GH_ApprovesDeploymentTo]->"
|
|
322
375
|
f"(env:GH_Environment {{node_id:'{self.node_id}'}}) "
|
|
376
|
+
f"MATCH p2=(repo)-[:GH_Contains]->(env) "
|
|
323
377
|
f"WHERE env.required_reviewers = true "
|
|
324
378
|
f"AND coalesce(env.prevent_self_review, false) = false "
|
|
325
|
-
f"
|
|
379
|
+
f"AND coalesce(env.custom_branch_policies, false) = false "
|
|
380
|
+
f"AND coalesce(env.protected_branches, false) = false "
|
|
381
|
+
f"RETURN p, p1, p2"
|
|
382
|
+
)
|
|
383
|
+
|
|
384
|
+
def _reviewer_can_write_branch_query(
|
|
385
|
+
self, reviewer_node_id: str, reviewer_kind: str, branch_id: str
|
|
386
|
+
) -> str:
|
|
387
|
+
actor_path = (
|
|
388
|
+
f"MATCH p=(actor:{reviewer_kind} {{node_id:'{reviewer_node_id}'}})"
|
|
389
|
+
f"-[:GH_HasRole|GH_HasBaseRole|GH_MemberOf|GH_CanWriteBranch*1..]->"
|
|
390
|
+
f"(branch:GH_Branch {{node_id:'{branch_id}'}}) "
|
|
391
|
+
f"MATCH p1=(actor)-[:GH_ApprovesDeploymentTo]->"
|
|
392
|
+
f"(env:GH_Environment {{node_id:'{self.node_id}'}}) "
|
|
393
|
+
)
|
|
394
|
+
reviewer_policy = (
|
|
395
|
+
"WHERE env.required_reviewers = true "
|
|
396
|
+
"AND coalesce(env.prevent_self_review, false) = false "
|
|
397
|
+
)
|
|
398
|
+
|
|
399
|
+
if self.has_custom_branch_policies:
|
|
400
|
+
custom_policy_path = (
|
|
401
|
+
"MATCH p2=(branch)-[:GH_MatchesEnvironmentPolicy]->"
|
|
402
|
+
"(:GH_EnvironmentBranchPolicy)<-[:GH_Contains]-(env) "
|
|
403
|
+
)
|
|
404
|
+
if (
|
|
405
|
+
self.deployment_branch_policy
|
|
406
|
+
and self.deployment_branch_policy.protected_branches
|
|
407
|
+
):
|
|
408
|
+
return (
|
|
409
|
+
actor_path
|
|
410
|
+
+ custom_policy_path
|
|
411
|
+
+ "MATCH p3=(branch)<-[:GH_ProtectedBy]-(:GH_BranchProtectionRule) "
|
|
412
|
+
+ reviewer_policy
|
|
413
|
+
+ "AND env.custom_branch_policies = true "
|
|
414
|
+
+ "AND env.protected_branches = true "
|
|
415
|
+
+ "RETURN p, p1, p2, p3"
|
|
416
|
+
)
|
|
417
|
+
|
|
418
|
+
return (
|
|
419
|
+
actor_path
|
|
420
|
+
+ custom_policy_path
|
|
421
|
+
+ reviewer_policy
|
|
422
|
+
+ "AND env.custom_branch_policies = true "
|
|
423
|
+
+ "AND coalesce(env.protected_branches, false) = false "
|
|
424
|
+
+ "RETURN p, p1, p2"
|
|
425
|
+
)
|
|
426
|
+
|
|
427
|
+
if (
|
|
428
|
+
self.deployment_branch_policy
|
|
429
|
+
and self.deployment_branch_policy.protected_branches
|
|
430
|
+
):
|
|
431
|
+
if self._lookup.branches_with_bpr(self.repository_node_id):
|
|
432
|
+
return (
|
|
433
|
+
actor_path
|
|
434
|
+
+ f"MATCH p2=(repo:GH_Repository {{node_id:'{self.repository_node_id}'}})"
|
|
435
|
+
f"-[:GH_Contains]->(branch)<-[:GH_ProtectedBy]-(:GH_BranchProtectionRule) "
|
|
436
|
+
f"MATCH p3=(repo)-[:GH_Contains]->(env) "
|
|
437
|
+
+ reviewer_policy
|
|
438
|
+
+ "AND env.protected_branches = true "
|
|
439
|
+
+ "AND coalesce(env.custom_branch_policies, false) = false "
|
|
440
|
+
+ "RETURN p, p1, p2, p3"
|
|
441
|
+
)
|
|
442
|
+
|
|
443
|
+
return (
|
|
444
|
+
actor_path
|
|
445
|
+
+ f"MATCH p2=(repo:GH_Repository {{node_id:'{self.repository_node_id}'}})"
|
|
446
|
+
f"-[:GH_Contains]->(branch) "
|
|
447
|
+
f"MATCH p3=(repo)-[:GH_Contains]->(env) "
|
|
448
|
+
+ reviewer_policy
|
|
449
|
+
+ "AND env.protected_branches = true "
|
|
450
|
+
+ "AND coalesce(env.custom_branch_policies, false) = false "
|
|
451
|
+
+ "AND NOT EXISTS { "
|
|
452
|
+
+ "MATCH (repo)-[:GH_Contains]->(:GH_Branch)"
|
|
453
|
+
+ "<-[:GH_ProtectedBy]-(:GH_BranchProtectionRule) "
|
|
454
|
+
+ "} "
|
|
455
|
+
+ "RETURN p, p1, p2, p3"
|
|
456
|
+
)
|
|
457
|
+
|
|
458
|
+
return (
|
|
459
|
+
actor_path
|
|
460
|
+
+ f"MATCH p2=(repo:GH_Repository {{node_id:'{self.repository_node_id}'}})"
|
|
461
|
+
f"-[:GH_Contains]->(branch) "
|
|
462
|
+
f"MATCH p3=(repo)-[:GH_Contains]->(env) "
|
|
463
|
+
+ reviewer_policy
|
|
464
|
+
+ "AND coalesce(env.custom_branch_policies, false) = false "
|
|
465
|
+
+ "AND coalesce(env.protected_branches, false) = false "
|
|
466
|
+
+ "RETURN p, p1, p2, p3"
|
|
326
467
|
)
|
|
327
468
|
|
|
328
469
|
def _protected_branches_fallback_repo_query(self) -> str:
|
|
@@ -480,6 +621,26 @@ class Environment(BaseAsset):
|
|
|
480
621
|
|
|
481
622
|
if self.reviewer_self_deployment_edges_allowed:
|
|
482
623
|
reviewer_kind = nk.USER if reviewer_type == "user" else nk.TEAM
|
|
624
|
+
deployment_path = self._lookup.reviewer_deployment_path(
|
|
625
|
+
reviewer_node_id,
|
|
626
|
+
reviewer_type,
|
|
627
|
+
self.repository_node_id,
|
|
628
|
+
self._reviewer_eligible_branch_ids,
|
|
629
|
+
self._reviewer_can_create_branch_for_deployment,
|
|
630
|
+
)
|
|
631
|
+
if deployment_path is None:
|
|
632
|
+
continue
|
|
633
|
+
|
|
634
|
+
path_type, branch_id = deployment_path
|
|
635
|
+
query_composition = (
|
|
636
|
+
self._reviewer_can_create_branch_query(
|
|
637
|
+
reviewer_node_id, reviewer_kind
|
|
638
|
+
)
|
|
639
|
+
if path_type == "create_branch"
|
|
640
|
+
else self._reviewer_can_write_branch_query(
|
|
641
|
+
reviewer_node_id, reviewer_kind, branch_id or ""
|
|
642
|
+
)
|
|
643
|
+
)
|
|
483
644
|
yield Edge(
|
|
484
645
|
kind=ek.CAN_DEPLOY_TO_ENVIRONMENT,
|
|
485
646
|
start=EdgePath(value=reviewer_node_id, match_by="id"),
|
|
@@ -487,8 +648,6 @@ class Environment(BaseAsset):
|
|
|
487
648
|
properties=GHEdgeProperties(
|
|
488
649
|
traversable=True,
|
|
489
650
|
composed=True,
|
|
490
|
-
query_composition=
|
|
491
|
-
reviewer_node_id, reviewer_kind
|
|
492
|
-
),
|
|
651
|
+
query_composition=query_composition,
|
|
493
652
|
),
|
|
494
653
|
)
|
|
@@ -11,6 +11,14 @@ from openhound_github.main import app
|
|
|
11
11
|
|
|
12
12
|
# from openhound_github.helpers import _b64
|
|
13
13
|
|
|
14
|
+
|
|
15
|
+
def matches_environment_branch_policy(branch_name: str, policy_name: str) -> bool:
|
|
16
|
+
return PurePosixPath(f"/{branch_name}").full_match(
|
|
17
|
+
f"/{policy_name}",
|
|
18
|
+
case_sensitive=True,
|
|
19
|
+
)
|
|
20
|
+
|
|
21
|
+
|
|
14
22
|
@dataclass
|
|
15
23
|
class GHEnvironmentBranchPolicyProperties(GHNodeProperties):
|
|
16
24
|
environment_name: str | None = None
|
|
@@ -88,10 +96,7 @@ class EnvironmentBranchPolicy(BaseAsset):
|
|
|
88
96
|
return required_reviewers
|
|
89
97
|
|
|
90
98
|
def matches_branch(self, branch_name: str) -> bool:
|
|
91
|
-
return
|
|
92
|
-
f"/{self.name}",
|
|
93
|
-
case_sensitive=True,
|
|
94
|
-
)
|
|
99
|
+
return matches_environment_branch_policy(branch_name, self.name)
|
|
95
100
|
|
|
96
101
|
@property
|
|
97
102
|
def as_node(self) -> GHNode:
|