-
-
Notifications
You must be signed in to change notification settings - Fork 4.7k
feat(pr iteration): add github app permission nudge to autofix drawer #119059
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
b6f6bad
37af874
8ed4f7e
9011f00
9abc4a8
a217219
4db8baa
c6776ea
e88e2ca
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,52 @@ | ||
| import {OrganizationFixture} from 'sentry-fixture/organization'; | ||
|
|
||
| import {render, screen} from 'sentry-test/reactTestingLibrary'; | ||
|
|
||
| import {AutofixWarnings} from 'sentry/components/events/autofix/v3/drawer'; | ||
|
|
||
| describe('AutofixWarnings', () => { | ||
| const organization = OrganizationFixture(); | ||
|
|
||
| it('deduplicates repo names', () => { | ||
| render( | ||
| <AutofixWarnings | ||
| groupId="1" | ||
| warnings={[ | ||
| { | ||
| warning_type: 'github_app_permissions', | ||
| repo_name: 'getsentry/sentry', | ||
| }, | ||
| { | ||
| warning_type: 'github_app_permissions', | ||
| repo_name: 'getsentry/sentry', | ||
| }, | ||
| ]} | ||
| />, | ||
| {organization} | ||
| ); | ||
|
|
||
| expect(screen.getAllByText('getsentry/sentry')).toHaveLength(1); | ||
| expect(screen.getByText(/The configured GitHub App for/)).toBeInTheDocument(); | ||
| }); | ||
|
|
||
| it('renders fallback copy when repo names are missing', () => { | ||
| render( | ||
| <AutofixWarnings | ||
| groupId="1" | ||
| warnings={[ | ||
| { | ||
| warning_type: 'github_app_permissions', | ||
| }, | ||
| ]} | ||
| />, | ||
| {organization} | ||
| ); | ||
|
|
||
| expect( | ||
| screen.getByText( | ||
| 'The configured GitHub App is missing permissions. Update the app and ask Seer to retry.' | ||
| ) | ||
| ).toBeInTheDocument(); | ||
| expect(screen.queryByText(/The configured GitHub App for/)).not.toBeInTheDocument(); | ||
| }); | ||
| }); |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,7 +1,12 @@ | ||
| import {useCallback, useMemo, useRef} from 'react'; | ||
| import {Fragment, useCallback, useMemo, useRef} from 'react'; | ||
|
|
||
| import {Alert} from '@sentry/scraps/alert'; | ||
| import {Button, LinkButton} from '@sentry/scraps/button'; | ||
| import {Flex} from '@sentry/scraps/layout'; | ||
| import {ExternalLink} from '@sentry/scraps/link'; | ||
| import {useModal} from '@sentry/scraps/modal'; | ||
|
|
||
| import {AutofixGithubAppPermissionsModal} from 'sentry/components/events/autofix/autofixGithubAppPermissionsModal'; | ||
| import {getReferrerFromBlocks} from 'sentry/components/events/autofix/autofixReferrer'; | ||
| import { | ||
| getAutofixArtifactFromSection, | ||
|
|
@@ -13,12 +18,15 @@ import {SeerDrawerContent} from 'sentry/components/events/autofix/v3/content'; | |
| import {SeerDrawerHeader} from 'sentry/components/events/autofix/v3/header'; | ||
| import {artifactToMarkdown} from 'sentry/components/events/autofix/v3/utils'; | ||
| import {Placeholder} from 'sentry/components/placeholder'; | ||
| import {t} from 'sentry/locale'; | ||
| import {IconClose} from 'sentry/icons'; | ||
| import {t, tct} from 'sentry/locale'; | ||
| import type {Group} from 'sentry/types/group'; | ||
| import type {Project} from 'sentry/types/project'; | ||
| import {defined} from 'sentry/utils/defined'; | ||
| import {getGithubPermissionsUpdateUrl} from 'sentry/utils/integrationUtil'; | ||
| import {useAutoScroll} from 'sentry/utils/useAutoScroll'; | ||
| import {useCopyToClipboard} from 'sentry/utils/useCopyToClipboard'; | ||
| import {useDismissAlert} from 'sentry/utils/useDismissAlert'; | ||
| import {useOrganization} from 'sentry/utils/useOrganization'; | ||
| import {useAiConfig} from 'sentry/views/issueDetails/hooks/useAiConfig'; | ||
| import {useSeerExplorerDrawer} from 'sentry/views/seerExplorer/components/drawer/useSeerExplorerDrawer'; | ||
|
|
@@ -72,6 +80,7 @@ export function SeerDrawer({group, project}: SeerDrawerProps) { | |
| onReset={handleRestart} | ||
| referrer={referrer} | ||
| /> | ||
| <AutofixWarnings warnings={aiAutofix.warnings} groupId={group.id} /> | ||
| <SeerDrawerBody ref={containerRef} onScroll={onScrollHandler}> | ||
| {aiConfig.isAutofixSetupLoading ? ( | ||
| <Flex data-test-id="ai-setup-loading-indicator" direction="column" gap="xl"> | ||
|
|
@@ -138,3 +147,126 @@ function useHandleOpenSeerAgent({ | |
| return () => openSeerExplorerDrawer({runId}); | ||
| }, [openSeerExplorerDrawer, runId]); | ||
| } | ||
|
|
||
| type AutofixWarning = { | ||
| warning_type: string; | ||
| installation_id?: string; | ||
| repo_name?: string; | ||
| }; | ||
|
|
||
| function InstallationPermissionsButton({installationId}: {installationId: string}) { | ||
| const {openModal} = useModal(); | ||
| const installationUrl = getGithubPermissionsUpdateUrl(installationId); | ||
|
|
||
| return ( | ||
| <Button | ||
| variant="primary" | ||
| size="xs" | ||
| onClick={() => | ||
| openModal(deps => ( | ||
| <AutofixGithubAppPermissionsModal | ||
| {...deps} | ||
| installationUrl={installationUrl} | ||
| description={tct( | ||
| 'Seer had trouble talking to GitHub while running Autofix. Please update your [link:GitHub App installation settings] to grant the required permissions.', | ||
| {link: <ExternalLink href={installationUrl} />} | ||
| )} | ||
| /> | ||
| )) | ||
| } | ||
| > | ||
| {t('Update Permissions')} | ||
| </Button> | ||
| ); | ||
| } | ||
|
|
||
| function ConfigurationPermissionsButton() { | ||
| const organization = useOrganization(); | ||
| const configurationUrl = `/settings/${organization.slug}/integrations/github/?tab=configurations`; | ||
|
|
||
| return ( | ||
| <LinkButton to={configurationUrl} variant="primary" size="xs"> | ||
| {t('Update Permissions')} | ||
| </LinkButton> | ||
| ); | ||
| } | ||
|
|
||
| export function AutofixWarnings({ | ||
| warnings, | ||
| groupId, | ||
| }: { | ||
| groupId: string; | ||
| warnings: AutofixWarning[]; | ||
| }) { | ||
| const organization = useOrganization(); | ||
| const {dismiss, isDismissed} = useDismissAlert({ | ||
| key: `${organization.id}:${groupId}:autofix-github-permissions-warning`, | ||
| expirationDays: 7, | ||
| }); | ||
|
|
||
| if (!warnings.length || isDismissed) { | ||
| return null; | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Dismissal hides subsequent permission warningsMedium Severity
Reviewed by Cursor Bugbot for commit e88e2ca. Configure here. |
||
| } | ||
|
|
||
| const permissionWarnings = warnings.filter( | ||
| w => w.warning_type === 'github_app_permissions' | ||
| ); | ||
|
|
||
| if (!permissionWarnings.length) { | ||
| return null; | ||
| } | ||
|
|
||
| const installationIds = [ | ||
| ...new Set(permissionWarnings.map(w => w.installation_id).filter(defined)), | ||
| ]; | ||
| const [installationId] = installationIds; | ||
|
|
||
| const comp = | ||
| installationIds.length === 1 && defined(installationId) ? ( | ||
| <InstallationPermissionsButton installationId={installationId} /> | ||
| ) : ( | ||
| <ConfigurationPermissionsButton /> | ||
| ); | ||
|
cursor[bot] marked this conversation as resolved.
|
||
|
|
||
| const repoNames = [ | ||
| ...new Set(permissionWarnings.map(w => w.repo_name).filter(defined)), | ||
| ]; | ||
|
|
||
| const repoNamesNode = repoNames.map((repoName, index) => ( | ||
| <Fragment key={repoName}> | ||
| {index > 0 && ', '} | ||
| <code>{repoName}</code> | ||
| </Fragment> | ||
| )); | ||
|
sentry[bot] marked this conversation as resolved.
|
||
|
|
||
| return ( | ||
| <Flex direction="column" gap="md" padding="md 2xl 0"> | ||
| <Alert | ||
| variant="warning" | ||
| trailingItems={ | ||
| <Flex gap="sm" alignSelf="center"> | ||
| {comp} | ||
| <Button | ||
| icon={<IconClose />} | ||
| variant="transparent" | ||
| size="xs" | ||
| aria-label={t('Dismiss')} | ||
| onClick={dismiss} | ||
| /> | ||
| </Flex> | ||
| } | ||
| > | ||
| {repoNames.length | ||
| ? tct( | ||
| 'The configured GitHub App for [repoNames] is missing permissions. Update the app and ask Seer to retry.', | ||
| { | ||
| repoNames: repoNamesNode, | ||
| } | ||
| ) | ||
| : t( | ||
| 'The configured GitHub App is missing permissions. Update the app and ask Seer to retry.' | ||
| )} | ||
| </Alert> | ||
| </Flex> | ||
| ); | ||
| } | ||


Uh oh!
There was an error while loading. Please reload this page.