Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 7 additions & 2 deletions .github/workflows/backend-selective.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,10 @@ concurrency:
group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
cancel-in-progress: true

defaults:
run:
shell: bash -euo pipefail {0}

# hack for https://github.com/actions/cache/issues/810#issuecomment-1222550359
env:
SEGMENT_DOWNLOAD_TIMEOUT_MINS: 3
Expand Down Expand Up @@ -62,6 +66,7 @@ jobs:
env:
GH_TOKEN: ${{ github.token }}
run: |

CHANGED_FILES=$(gh api repos/${{ github.repository }}/pulls/${{ github.event.pull_request.number }}/files --paginate --jq '.[].filename' | tr '\n' ' ')
echo "Changed files: $CHANGED_FILES"
echo "files=$CHANGED_FILES" >> "$GITHUB_OUTPUT"
Expand All @@ -83,7 +88,7 @@ jobs:
- name: Download coverage database
id: download-coverage
run: |
set -euo pipefail

mkdir -p .artifacts/coverage

GCS_PATH="gs://getsentry-coverage-data/latest/.coverage.combined"
Expand All @@ -106,7 +111,7 @@ jobs:
COVERAGE_DB: ${{ steps.download-coverage.outputs.coverage-file }}
CHANGED_FILES: ${{ steps.changed.outputs.files }}
run: |
set -euo pipefail


python3 .github/workflows/scripts/compute-sentry-selected-tests.py \
--coverage-db "$COVERAGE_DB" \
Expand Down
1 change: 1 addition & 0 deletions .github/workflows/getsentry-dispatch-selective.yml
Original file line number Diff line number Diff line change
Expand Up @@ -96,4 +96,5 @@ jobs:
mergeCommitSha: '${{ steps.mergecommit.outputs.mergeCommitSha }}',
fileChanges: ${{ toJson(steps.changes.outputs) }},
sentryChangedFiles: process.env.SENTRY_CHANGED_FILES,
targetWorkflow: 'backend-selective.yml',
});
8 changes: 7 additions & 1 deletion .github/workflows/scripts/getsentry-dispatch.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,17 @@ export async function dispatch({
fileChanges,
mergeCommitSha,
sentryChangedFiles,
targetWorkflow,
}) {
core.startGroup('Dispatching request to getsentry.');

const dispatches =
targetWorkflow !== undefined
? [{workflow: targetWorkflow, pathFilterName: 'backend_all'}]
: DISPATCHES;

await Promise.all(
DISPATCHES.map(({workflow, pathFilterName}) => {
dispatches.map(({workflow, pathFilterName}) => {
const inputs = {
pull_request_number: `${context.payload.pull_request.number}`, // needs to be string
skip: `${fileChanges[pathFilterName] !== 'true'}`, // even though this is a boolean, it must be cast to a string
Expand Down
7 changes: 4 additions & 3 deletions src/sentry/issues/endpoints/group_details.py
Original file line number Diff line number Diff line change
Expand Up @@ -199,8 +199,6 @@ def get(self, request: Request, group: Group) -> Response:
)
)

hourly_stats, daily_stats = self.__group_hourly_daily_stats(group, environment_ids)

if "inbox" in expand:
inbox_map = get_inbox_details([group])
inbox_reason = inbox_map.get(group.id)
Expand Down Expand Up @@ -277,11 +275,14 @@ def get(self, request: Request, group: Group) -> Response:
"pluginIssues": get_available_issue_plugins(group),
"pluginContexts": self._get_context_plugins(request, group),
"userReportCount": user_reports.count(),
"stats": {"24h": hourly_stats, "30d": daily_stats},
"count": get_group_global_count(group),
}
)

if "stats" not in collapse:
hourly_stats, daily_stats = self.__group_hourly_daily_stats(group, environment_ids)
data["stats"] = {"24h": hourly_stats, "30d": daily_stats}

participants = user_service.serialize_many(
filter={"user_ids": GroupSubscriptionManager.get_participating_user_ids(group)},
as_user=request.user,
Expand Down
2 changes: 0 additions & 2 deletions src/sentry/seer/endpoints/seer_rpc.py
Original file line number Diff line number Diff line change
Expand Up @@ -252,8 +252,6 @@ def post(self, request: Request, method_name: str) -> Response:
sentry_sdk.capture_exception()
raise ParseError from e
except ObjectDoesNotExist as e:
# Let this fall through, this is normal.
sentry_sdk.capture_exception()
raise NotFound from e
except SnubaRPCRateLimitExceeded as e:
sentry_sdk.capture_exception()
Expand Down
17 changes: 16 additions & 1 deletion src/sentry/seer/explorer/client_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -205,7 +205,22 @@ def collect_user_org_context(
"all_org_projects": all_org_projects,
}

member = OrganizationMember.objects.get(organization=organization, user_id=user.id)
try:
member = OrganizationMember.objects.get(organization=organization, user_id=user.id)
except OrganizationMember.DoesNotExist:
# User is not a member of this organization (e.g., superuser accessing foreign org)
logger.warning(
"User attempted to access Seer Explorer for organization they are not a member of",
extra={
"user_id": user.id,
"organization_id": organization.id,
"organization_slug": organization.slug,
},
)
return {
"org_slug": organization.slug,
"all_org_projects": all_org_projects,
}
user_teams = [{"id": t.id, "slug": t.slug} for t in member.get_teams()]
my_projects = (
Project.objects.filter(
Expand Down
1 change: 0 additions & 1 deletion src/sentry/tasks/post_process.py
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,6 @@ def _capture_event_stats(event: Event) -> None:
platform = format_event_platform(event)
tags = {"platform": platform}
metrics.incr("events.processed", tags={"platform": platform}, skip_internal=False)
metrics.incr(f"events.processed.{platform}", skip_internal=False)
metrics.distribution("events.size.data", event.size, tags=tags, unit="byte")


Expand Down
16 changes: 14 additions & 2 deletions static/app/components/footer.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import {Fragment} from 'react';
import {Fragment, useContext} from 'react';
import styled from '@emotion/styled';

import {Button} from '@sentry/scraps/button';
Expand All @@ -14,6 +14,8 @@ import {ConfigStore} from 'sentry/stores/configStore';
import {useLegacyStore} from 'sentry/stores/useLegacyStore';
import {pulsingIndicatorStyles} from 'sentry/styles/pulsingIndicator';
import {useOrganization} from 'sentry/utils/useOrganization';
import {SecondaryNavigationContext} from 'sentry/views/navigation/secondaryNavigationContext';
import {useHasPageFrameFeature} from 'sentry/views/navigation/useHasPageFrameFeature';

type SentryLogoProps = SVGIconProps & {
/**
Expand Down Expand Up @@ -41,8 +43,18 @@ function BaseFooter({className}: Props) {
const {state: appState} = useFrontendVersion();
const organization = useOrganization({allowNull: true});

const secondaryNavigation = useContext(SecondaryNavigationContext);
const hasPageFrame = useHasPageFrameFeature();

return (
<Container as="footer" background="primary" className={className}>
<Container
as="footer"
background="primary"
className={className}
borderLeft={
hasPageFrame && secondaryNavigation?.view === 'expanded' ? 'secondary' : undefined
}
>
<LeftLinks>
{isSelfHosted && (
<Fragment>
Expand Down
42 changes: 35 additions & 7 deletions static/app/components/layouts/thirds.tsx
Original file line number Diff line number Diff line change
@@ -1,18 +1,46 @@
import type {HTMLAttributes} from 'react';
import {useContext, type HTMLAttributes} from 'react';
import {css} from '@emotion/react';
import styled from '@emotion/styled';

import {Container} from '@sentry/scraps/layout';
import {Container, Stack, type FlexProps} from '@sentry/scraps/layout';
import {Tabs} from '@sentry/scraps/tabs';

import {SecondaryNavigationContext} from 'sentry/views/navigation/secondaryNavigationContext';
import {useHasPageFrameFeature} from 'sentry/views/navigation/useHasPageFrameFeature';

/**
* Main container for a page.
*/
export const Page = styled('main')<{withPadding?: boolean}>`
display: flex;
flex-direction: column;
flex: 1;
${p => p.withPadding && `padding: ${p.theme.space['2xl']} ${p.theme.space['3xl']}`};
export function Page(props: FlexProps<'main'> & {withPadding?: boolean}) {
const hasPageFrame = useHasPageFrameFeature();
const secondaryNavigation = useContext(SecondaryNavigationContext);

const {withPadding, ...rest} = props;

if (hasPageFrame) {
return (
<StyledPageFrameStack
flex="1"
as="main"
padding={props.withPadding ? '2xl 3xl' : undefined}
radius={secondaryNavigation?.view === 'expanded' ? 'lg 0 0 0' : undefined}
borderTop={secondaryNavigation?.view === 'expanded' ? 'primary' : undefined}
borderLeft={secondaryNavigation?.view === 'expanded' ? 'primary' : undefined}
background="secondary"
{...rest}
/>
);
}

return (
<Stack flex="1" padding={withPadding ? '2xl 3xl' : undefined} as="main" {...rest} />
);
}

const StyledPageFrameStack = styled(Stack)`
> :first-child {
border-top-left-radius: ${p => p.theme.radius.lg};
}
`;

/**
Expand Down
10 changes: 7 additions & 3 deletions static/app/components/repositories/scmRepoTreeModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,20 @@ import type {ModalRenderProps} from 'sentry/actionCreators/modal';
import {ScmIntegrationTree} from 'sentry/components/repositories/scmIntegrationTree/scmIntegrationTree';
import {ScmTreeFilters} from 'sentry/components/repositories/scmIntegrationTree/scmTreeFilters';
import type {RepoFilter} from 'sentry/components/repositories/scmIntegrationTree/types';
import {t, tct} from 'sentry/locale';
import {tct} from 'sentry/locale';

export function ScmRepoTreeModal({Header, Body}: ModalRenderProps) {
interface Props extends ModalRenderProps {
title: string;
}

export function ScmRepoTreeModal({Header, Body, title}: Props) {
const [search, setSearch] = useState('');
const [repoFilter, setRepoFilter] = useState<RepoFilter>('all');

return (
<Fragment>
<Header closeButton>
<Heading as="h4">{t('Add Repository')}</Heading>
<Heading as="h4">{title}</Heading>
</Header>
<Body>
<Stack gap="2xl">
Expand Down
Loading
Loading