Skip to content

feat(releases): Add mobile tab to releases#104376

Merged
rbro112 merged 11 commits intomasterfrom
mtopo27/add-mobile-tab-to-releases-v1
Dec 11, 2025
Merged

feat(releases): Add mobile tab to releases#104376
rbro112 merged 11 commits intomasterfrom
mtopo27/add-mobile-tab-to-releases-v1

Conversation

@mtopo27
Copy link
Copy Markdown
Contributor

@mtopo27 mtopo27 commented Dec 4, 2025

context: https://www.notion.so/sentry/Integrating-with-releases-short-term-fix-2b08b10e4b5d80cbb28ccbdefe46f7f8#2b58b10e4b5d80acb810f8af7c651bac

When mobile project selected:
Screenshot 2025-12-10 at 2 09 50 PM
Screenshot 2025-12-10 at 2 09 44 PM

When non-mobile project is selected (also tested to confirm default releases page is handled when switching from mobile back to non-mobile):
Screenshot 2025-12-10 at 2 09 57 PM

@github-actions github-actions bot added the Scope: Frontend Automatically applied to PRs that change frontend components label Dec 4, 2025
@codecov
Copy link
Copy Markdown

codecov bot commented Dec 4, 2025

❌ 1 Tests Failed:

Tests completed Failed Passed Skipped
12840 1 12839 10
View the top 1 failed test(s) by shortest run time
ReleasesList allows searching within the mobile-builds tab
Stack Traces | 1.6s run time
Error: expect(jest.fn()).toHaveBeenLastCalledWith(...expected)

Expected: ".../mobile-project-2/preprodartifacts/list-builds/", ObjectContaining {"query": ObjectContaining {"per_page": 25, "query": "branch:main", "statsPeriod": "14d"}}
Received
       3: ".../mobile-project-2/preprodartifacts/list-builds/", {"data": undefined, "error": [Function error], "headers": undefined, "host": undefined, "method": "GET", "query": {"per_page": 25, "statsPeriod": "14d", "tab": "mobile-builds"}, "success": [Function success]}
->     4: ".../mobile-project-2/preprodartifacts/list-builds/", {"data": undefined, "error": [Function error], "headers": undefined, "host": undefined, "method": "GET", "query": {"per_page": 25, "query": "b", "statsPeriod": "14d", "tab": "mobile-builds"}, "success": [Function success]}

Number of calls: 4

Ignored nodes: comments, script, style
...
    at toHaveBeenLastCalledWith (.../releases/list/index.spec.tsx:633:26)
    at runWithExpensiveErrorDiagnosticsDisabled (.../sentry/node_modules/.pnpm/@testing-library+dom@10.4.0/node_modules/@.../dom/dist/config.js:47:12)
    at checkCallback (.../sentry/node_modules/.pnpm/@testing-library+dom@10.4.0/node_modules/@.../dom/dist/wait-for.js:124:77)
    at checkRealTimersCallback (.../sentry/node_modules/.pnpm/@testing-library+dom@10.4.0/node_modules/@.../dom/dist/wait-for.js:118:16)
    at Timeout.task [as _onTimeout] (.../sentry/node_modules/.pnpm/jsdom@26.1..../jsdom/browser/Window.js:579:19)
    at listOnTimeout (node:internal/timers:588:17)
    at processTimers (node:internal/timers:523:7)

To view more test analytics, go to the Test Analytics Dashboard
📋 Got 3 mins? Take this short survey to help us improve Test Analytics.

Copy link
Copy Markdown
Member

rbro112 commented Dec 10, 2025

This stack of pull requests is managed by Graphite. Learn more about stacking.

numberOfMobileBuilds === 0 ? (
<BadgeWrapper>
<FeatureBadge type="new" />
<FeatureBadge type="beta" />
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Unifying on "Beta" per Max and I's discussion

selection={selection}
/>
<ReleasesPageFilterBar condensed>
<Layout.Header noActionWrap>
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Inlines the header now and moves the project selector into it. This is intentional to give us the divider under the tabs.

Image

)}

{selectedTab === 'releases' && (
<Fragment>
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

All content here is the same, just gated behind the selectedTab being 'releases'

const ReleasesPageFilterBar = styled(PageFilterBar)`
margin-bottom: ${space(2)};
const ReleasesPageFilterBar = styled(PageFilterBar)<{shouldShowMobileBuildsTab: boolean}>`
${p => !p.shouldShowMobileBuildsTab && `margin-bottom: ${p.theme.space.xl};`}
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Conditional logic to add bottom padding before the divider when tabs are not present

Image

@rbro112 rbro112 changed the title (WIP) Mtopo27/add mobile tab to releases v1 feat(releases): Add mobile tab to releases Dec 10, 2025
@rbro112 rbro112 marked this pull request as ready for review December 10, 2025 22:42
@rbro112 rbro112 requested a review from a team as a code owner December 10, 2025 22:42
([...mobile, ...desktop] as string[]).includes(releaseProjectPlatform);
export const isMobileRelease = (
releaseProjectPlatform: PlatformKey,
includeDesktop = true
Copy link
Copy Markdown
Member

@ryan953 ryan953 Dec 10, 2025

Choose a reason for hiding this comment

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

that's a funny prop

isMobile .... or sometimes desktop. lol

Copy link
Copy Markdown
Member

@rbro112 rbro112 Dec 10, 2025

Choose a reason for hiding this comment

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

I agree but I admittedly don't have context here. Appears this change is just styling but will follow up and remove this weird includeDesktop behavior if I get the greenlight to from @mtopo27

Copy link
Copy Markdown
Member

@ryan953 ryan953 left a comment

Choose a reason for hiding this comment

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

works for me. some nits if that's your thing.

:shipit: when you're ready!

if (!shouldShowMobileBuildsTab) {
return 'releases';
}
return (decodeScalar(location.query.tab) as ReleaseTab | undefined) || 'releases';

This comment was marked as outdated.

@rbro112 rbro112 merged commit a1510a0 into master Dec 11, 2025
48 checks passed
@rbro112 rbro112 deleted the mtopo27/add-mobile-tab-to-releases-v1 branch December 11, 2025 00:43
@jshchnz
Copy link
Copy Markdown
Member

jshchnz commented Dec 20, 2025

@sentry review

@jshchnz
Copy link
Copy Markdown
Member

jshchnz commented Dec 20, 2025

cursor review

return 'releases';
}
return (decodeScalar(location.query.tab) as ReleaseTab | undefined) || 'releases';
}, [shouldShowMobileBuildsTab, location.query.tab]);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Invalid tab URL parameter causes empty page body

The selectedTab computation at line 230 casts the URL tab parameter directly to ReleaseTab without validation. If a user manually enters an invalid tab value like ?tab=invalid, decodeScalar returns "invalid" (truthy, so the || 'releases' fallback doesn't trigger). Since neither selectedTab === 'mobile-builds' nor selectedTab === 'releases' matches, the page body renders empty. Other similar patterns in the codebase (e.g., configureIntegration.tsx) properly validate against a list of valid tabs.

Additional Locations (1)

Fix in Cursor Fix in Web

'preprod.builds.release.build_row_clicked': BasePreprodBuildEvent;
'preprod.releases.mobile-builds.tab-clicked': {
organization: Organization;
};
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Analytics event defined but never tracked

The analytics event 'preprod.releases.mobile-builds.tab-clicked' is defined in preprodBuildAnalyticsEvents.tsx with its corresponding event map entry, but no trackAnalytics call is made when the Mobile Builds tab is clicked. The tab navigation uses the to prop for routing without an onClick handler to track the analytics event. This means tab click analytics will not be collected despite the event being set up.

Additional Locations (1)

Fix in Cursor Fix in Web

@github-actions github-actions bot locked and limited conversation to collaborators Jan 4, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

Scope: Frontend Automatically applied to PRs that change frontend components

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants