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
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ export function BuildDetailsHeaderContent(props: BuildDetailsHeaderContentProps)
platform: buildDetailsData.app_info?.platform ?? null,
build_id: buildDetailsData.id,
project_type: projectType,
project_slug: projectId,
project_slug: project?.slug,
});
router.push(
getCompareBuildPath({
Expand All @@ -153,7 +153,7 @@ export function BuildDetailsHeaderContent(props: BuildDetailsHeaderContentProps)
organization,
platform: buildDetailsData.app_info?.platform ?? null,
build_id: buildDetailsData.id,
project_slug: projectId,
project_slug: project?.slug,
project_type: projectType,
});
};
Expand Down Expand Up @@ -198,12 +198,14 @@ export function BuildDetailsHeaderContent(props: BuildDetailsHeaderContentProps)
{t('Compare Build')}
</Button>
<Feature features="organizations:preprod-frontend-routes">
<LinkButton
size="sm"
icon={<IconSettings />}
aria-label={t('Settings')}
to={`/settings/${organization.slug}/projects/${projectId}/mobile-builds/`}
/>
{project && (
<LinkButton
size="sm"
icon={<IconSettings />}
aria-label={t('Settings')}
to={`/settings/${organization.slug}/projects/${project?.slug}/mobile-builds/`}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Redundant optional chaining inside truthiness guard

Low Severity

project?.slug uses optional chaining inside a block that already guards with {project && (...)} on line 201. Since project is guaranteed to be truthy within this block, the ?. is redundant. Should be project.slug.

Fix in Cursor Fix in Web

/>
)}
</Feature>
<ConfirmDelete
message={t(
Expand Down
7 changes: 5 additions & 2 deletions static/app/views/preprod/buildList/buildList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import {PreprodBuildsTable} from 'sentry/components/preprod/preprodBuildsTable';
import SentryDocumentTitle from 'sentry/components/sentryDocumentTitle';
import {IconSettings} from 'sentry/icons';
import {t} from 'sentry/locale';
import ProjectsStore from 'sentry/stores/projectsStore';
import getApiUrl from 'sentry/utils/api/getApiUrl';
import {useApiQuery, type UseApiQueryResult} from 'sentry/utils/queryClient';
import {decodeList, decodeScalar} from 'sentry/utils/queryString';
Expand All @@ -28,6 +29,8 @@ export default function BuildList() {
});
const projects = Array.from(new Set(projectList.filter(Boolean)));
const projectId = projects[0];
const singleProject =
projectId === undefined ? undefined : ProjectsStore.getById(projectId);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bug: The code uses ProjectsStore.getById(projectId) to fetch project details, but the projectId variable contains a project slug, not a numeric ID, causing the lookup to fail.
Severity: MEDIUM

Suggested Fix

Replace the call to ProjectsStore.getById(projectId) with ProjectsStore.getBySlug(projectId). This will correctly look up the project using its slug, ensuring the project object is found and related UI components render as expected.

Prompt for AI Agent
Review the code at the location below. A potential bug has been identified by an AI
agent.
Verify if this is a real issue. If it is, propose a fix; if not, explain why it's not
valid.

Location: static/app/views/preprod/buildList/buildList.tsx#L33

Potential issue: The `projectId` variable is derived from the `project` URL query
parameter, which contains the project slug. The code incorrectly attempts to fetch the
project object using `ProjectsStore.getById(projectId)`. Since `getById` expects a
numeric ID, this lookup will always fail and return `undefined`. Consequently, UI
elements like the Settings button in the build list and a LinkButton in the build
details header will not be rendered. Additionally, analytics events will be missing the
`project_slug`.


const queryParams: Record<string, any> = {
per_page: 25,
Expand Down Expand Up @@ -77,13 +80,13 @@ export default function BuildList() {
<Layout.Header>
<Layout.Title>Builds</Layout.Title>
<Layout.HeaderActions>
{projects.length === 1 && (
{singleProject && (
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Settings button appears when multiple projects selected

Medium Severity

The condition controlling when the Settings button appears changed from projects.length === 1 to just singleProject. Since singleProject is derived from projects[0], it will be truthy whenever any project is selected and exists in the store—even when multiple projects are selected. This causes the Settings button to incorrectly appear and link to only the first project's settings when viewing multiple projects, which wasn't the original behavior.

Additional Locations (1)

Fix in Cursor Fix in Web

<Feature features="organizations:preprod-frontend-routes">
<LinkButton
size="sm"
icon={<IconSettings />}
aria-label={t('Settings')}
to={`/settings/${organization.slug}/projects/${projectId}/mobile-builds/`}
to={`/settings/${organization.slug}/projects/${singleProject.slug}/mobile-builds/`}
/>
</Feature>
)}
Expand Down
Loading