diff --git a/static/app/components/preprod/preprodBuildsTable.tsx b/static/app/components/preprod/preprodBuildsTable.tsx
index 59d7af5fbb3c6a..c7609d6e2b8e82 100644
--- a/static/app/components/preprod/preprodBuildsTable.tsx
+++ b/static/app/components/preprod/preprodBuildsTable.tsx
@@ -15,8 +15,8 @@ import {IconCheckmark, IconCommit} from 'sentry/icons';
import {t} from 'sentry/locale';
import type {BuildDetailsApiResponse} from 'sentry/views/preprod/types/buildDetailsTypes';
import {
- formattedDownloadSize,
- formattedInstallSize,
+ formattedPrimaryMetricDownloadSize,
+ formattedPrimaryMetricInstallSize,
getLabels,
getPlatformIconFromPlatform,
} from 'sentry/views/preprod/utils/labelUtils';
@@ -137,11 +137,11 @@ export function PreprodBuildsTable({
- {formattedInstallSize(build)}
+ {formattedPrimaryMetricInstallSize(build.size_info)}
- {formattedDownloadSize(build)}
+ {formattedPrimaryMetricDownloadSize(build.size_info)}
diff --git a/static/app/views/preprod/buildComparison/header/buildCompareHeaderContent.tsx b/static/app/views/preprod/buildComparison/header/buildCompareHeaderContent.tsx
index 2cdf444f03e0b2..16af33f26fca8f 100644
--- a/static/app/views/preprod/buildComparison/header/buildCompareHeaderContent.tsx
+++ b/static/app/views/preprod/buildComparison/header/buildCompareHeaderContent.tsx
@@ -18,8 +18,8 @@ import {
type BuildDetailsApiResponse,
} from 'sentry/views/preprod/types/buildDetailsTypes';
import {
- formattedDownloadSize,
- formattedInstallSize,
+ formattedPrimaryMetricDownloadSize,
+ formattedPrimaryMetricInstallSize,
getLabels,
getPlatformIconFromPlatform,
getReadablePlatformLabel,
@@ -100,7 +100,9 @@ export function BuildCompareHeaderContent(props: BuildCompareHeaderContentProps)
- {formattedInstallSize(buildDetails)}
+
+ {formattedPrimaryMetricInstallSize(buildDetails.size_info)}
+
)}
@@ -108,7 +110,9 @@ export function BuildCompareHeaderContent(props: BuildCompareHeaderContentProps)
- {formattedDownloadSize(buildDetails)}
+
+ {formattedPrimaryMetricDownloadSize(buildDetails.size_info)}
+
)}
diff --git a/static/app/views/preprod/buildComparison/main/sizeCompareSelectionContent.tsx b/static/app/views/preprod/buildComparison/main/sizeCompareSelectionContent.tsx
index 233c4ffc42775e..afcc6a8eed719a 100644
--- a/static/app/views/preprod/buildComparison/main/sizeCompareSelectionContent.tsx
+++ b/static/app/views/preprod/buildComparison/main/sizeCompareSelectionContent.tsx
@@ -23,7 +23,6 @@ import {
} from 'sentry/icons';
import {IconBranch} from 'sentry/icons/iconBranch';
import {t} from 'sentry/locale';
-import {formatBytesBase10} from 'sentry/utils/bytes/formatBytesBase10';
import parseLinkHeader from 'sentry/utils/parseLinkHeader';
import {useApiQuery, useMutation, type UseApiQueryResult} from 'sentry/utils/queryClient';
import {decodeScalar} from 'sentry/utils/queryString';
@@ -39,6 +38,10 @@ import {
type BuildDetailsApiResponse,
} from 'sentry/views/preprod/types/buildDetailsTypes';
import type {ListBuildsApiResponse} from 'sentry/views/preprod/types/listBuildsTypes';
+import {
+ formattedPrimaryMetricDownloadSize,
+ formattedPrimaryMetricInstallSize,
+} from 'sentry/views/preprod/utils/labelUtils';
import {SizeCompareSelectedBuilds} from './sizeCompareSelectedBuilds';
@@ -249,13 +252,13 @@ function BuildItem({build, isSelected, onSelect}: BuildItemProps) {
{isSizeInfoCompleted(sizeInfo) && (
- {formatBytesBase10(sizeInfo.install_size_bytes)}
+ {formattedPrimaryMetricInstallSize(sizeInfo)}
)}
{isSizeInfoCompleted(sizeInfo) && (
- {formatBytesBase10(sizeInfo.download_size_bytes)}
+ {formattedPrimaryMetricDownloadSize(sizeInfo)}
)}
diff --git a/static/app/views/preprod/buildDetails/buildDetails.spec.tsx b/static/app/views/preprod/buildDetails/buildDetails.spec.tsx
index b50f4258e449a3..d6746315ea1b8c 100644
--- a/static/app/views/preprod/buildDetails/buildDetails.spec.tsx
+++ b/static/app/views/preprod/buildDetails/buildDetails.spec.tsx
@@ -6,6 +6,7 @@ import {
import {render, screen, waitFor} from 'sentry-test/reactTestingLibrary';
+import {MetricsArtifactType} from 'sentry/views/preprod/types/appSizeTypes';
import {BuildDetailsSizeAnalysisState} from 'sentry/views/preprod/types/buildDetailsTypes';
import BuildDetails from './buildDetails';
@@ -98,8 +99,13 @@ describe('BuildDetails', () => {
body: PreprodBuildDetailsWithSizeInfoFixture(
{
state: BuildDetailsSizeAnalysisState.COMPLETED,
- install_size_bytes: 1024000,
- download_size_bytes: 512000,
+ size_metrics: [
+ {
+ metrics_artifact_type: MetricsArtifactType.MAIN_ARTIFACT,
+ install_size_bytes: 1024000,
+ download_size_bytes: 512000,
+ },
+ ],
},
{
vcs_info: PreprodVcsInfoFullFixture(),
@@ -168,8 +174,13 @@ describe('BuildDetails', () => {
}
return PreprodBuildDetailsWithSizeInfoFixture({
state: BuildDetailsSizeAnalysisState.COMPLETED,
- install_size_bytes: 1024000,
- download_size_bytes: 512000,
+ size_metrics: [
+ {
+ metrics_artifact_type: MetricsArtifactType.MAIN_ARTIFACT,
+ install_size_bytes: 1024000,
+ download_size_bytes: 512000,
+ },
+ ],
});
},
});
@@ -215,8 +226,13 @@ describe('BuildDetails', () => {
method: 'GET',
body: PreprodBuildDetailsWithSizeInfoFixture({
state: BuildDetailsSizeAnalysisState.COMPLETED,
- install_size_bytes: 1024000,
- download_size_bytes: 512000,
+ size_metrics: [
+ {
+ metrics_artifact_type: MetricsArtifactType.MAIN_ARTIFACT,
+ install_size_bytes: 1024000,
+ download_size_bytes: 512000,
+ },
+ ],
}),
});
diff --git a/static/app/views/preprod/buildDetails/sidebar/buildDetailsSidebarAppInfo.tsx b/static/app/views/preprod/buildDetails/sidebar/buildDetailsSidebarAppInfo.tsx
index 762b76b3177d76..aa3ff6e65e9c8d 100644
--- a/static/app/views/preprod/buildDetails/sidebar/buildDetailsSidebarAppInfo.tsx
+++ b/static/app/views/preprod/buildDetails/sidebar/buildDetailsSidebarAppInfo.tsx
@@ -2,7 +2,7 @@ import styled from '@emotion/styled';
import {PlatformIcon} from 'platformicons';
import {CodeBlock} from '@sentry/scraps/code';
-import {Flex} from '@sentry/scraps/layout';
+import {Flex, Stack} from '@sentry/scraps/layout';
import {Heading, Text} from '@sentry/scraps/text';
import {Tooltip} from '@sentry/scraps/tooltip';
@@ -12,12 +12,16 @@ import {t} from 'sentry/locale';
import {formatBytesBase10} from 'sentry/utils/bytes/formatBytesBase10';
import {getFormat, getFormattedDate, getUtcToSystem} from 'sentry/utils/dates';
import {openInstallModal} from 'sentry/views/preprod/components/installModal';
+import {MetricsArtifactType} from 'sentry/views/preprod/types/appSizeTypes';
import {
BuildDetailsSizeAnalysisState,
+ getMainArtifactSizeMetric,
type BuildDetailsAppInfo,
type BuildDetailsSizeInfo,
} from 'sentry/views/preprod/types/buildDetailsTypes';
import {
+ formattedPrimaryMetricDownloadSize,
+ formattedPrimaryMetricInstallSize,
getLabels,
getPlatformIconFromPlatform,
getReadableArtifactTypeLabel,
@@ -40,6 +44,101 @@ export function BuildDetailsSidebarAppInfo(props: BuildDetailsSidebarAppInfoProp
timeZone: true,
});
+ let sizeInfoGroup = null;
+ if (
+ props.sizeInfo &&
+ props.sizeInfo.state === BuildDetailsSizeAnalysisState.COMPLETED
+ ) {
+ const primarySizeMetric = getMainArtifactSizeMetric(props.sizeInfo);
+ const watchAppMetrics = props.sizeInfo.size_metrics.find(
+ metric => metric.metrics_artifact_type === MetricsArtifactType.WATCH_ARTIFACT
+ );
+
+ let installSizeContent = (
+ {formattedPrimaryMetricInstallSize(props.sizeInfo)}
+ );
+ let downloadSizeContent = (
+ {formattedPrimaryMetricDownloadSize(props.sizeInfo)}
+ );
+ if (watchAppMetrics) {
+ installSizeContent = (
+
+
+
+ {t('App')}:
+
+
+ {formatBytesBase10(primarySizeMetric?.install_size_bytes ?? 0)}
+
+
+
+
+ {t('Watch')}:
+
+
+ {formatBytesBase10(watchAppMetrics.install_size_bytes)}
+
+
+
+ }
+ position="left"
+ >
+
+ {formattedPrimaryMetricInstallSize(props.sizeInfo)}
+
+
+ );
+ downloadSizeContent = (
+
+
+
+ {t('App')}:
+
+
+ {formatBytesBase10(watchAppMetrics.download_size_bytes)}
+
+
+
+
+ {t('Watch')}:
+
+
+ {formatBytesBase10(watchAppMetrics.download_size_bytes)}
+
+
+
+ }
+ position="left"
+ >
+
+ {formattedPrimaryMetricDownloadSize(props.sizeInfo)}
+
+
+ );
+ }
+
+ sizeInfoGroup = (
+
+
+
+ {labels.installSizeLabel}
+
+ {installSizeContent}
+
+
+
+ {labels.downloadSizeLabel}
+
+ {downloadSizeContent}
+
+
+ );
+ }
+
return (
@@ -49,27 +148,7 @@ export function BuildDetailsSidebarAppInfo(props: BuildDetailsSidebarAppInfoProp
{props.appInfo.name && {props.appInfo.name}}
- {props.sizeInfo &&
- props.sizeInfo.state === BuildDetailsSizeAnalysisState.COMPLETED && (
-
-
-
- {labels.installSizeLabel}
-
-
- {formatBytesBase10(props.sizeInfo.install_size_bytes)}
-
-
-
-
- {labels.downloadSizeLabel}
-
-
- {formatBytesBase10(props.sizeInfo.download_size_bytes)}
-
-
-
- )}
+ {sizeInfoGroup}
diff --git a/static/app/views/preprod/types/buildDetailsTypes.ts b/static/app/views/preprod/types/buildDetailsTypes.ts
index 41cdccea695152..9ded2c20700f2e 100644
--- a/static/app/views/preprod/types/buildDetailsTypes.ts
+++ b/static/app/views/preprod/types/buildDetailsTypes.ts
@@ -1,3 +1,6 @@
+/* eslint-disable typescript-sort-keys/interface */
+import {MetricsArtifactType} from 'sentry/views/preprod/types/appSizeTypes';
+
import type {Platform} from './sharedTypes';
export interface BuildDetailsApiResponse {
@@ -42,6 +45,12 @@ export interface BuildDetailsVcsInfo {
provider?: string | null;
}
+interface BuildDetailsSizeInfoSizeMetric {
+ metrics_artifact_type: MetricsArtifactType;
+ install_size_bytes: number;
+ download_size_bytes: number;
+}
+
interface BuildDetailsSizeInfoPending {
state: BuildDetailsSizeAnalysisState.PENDING;
}
@@ -51,9 +60,8 @@ interface BuildDetailsSizeInfoProcessing {
}
interface BuildDetailsSizeInfoCompleted {
- download_size_bytes: number;
- install_size_bytes: number;
state: BuildDetailsSizeAnalysisState.COMPLETED;
+ size_metrics: BuildDetailsSizeInfoSizeMetric[];
}
interface BuildDetailsSizeInfoFailed {
@@ -83,6 +91,14 @@ export function isSizeInfoProcessing(
);
}
+export function getMainArtifactSizeMetric(
+ sizeInfo: BuildDetailsSizeInfoCompleted
+): BuildDetailsSizeInfoSizeMetric | undefined {
+ return sizeInfo.size_metrics.find(
+ metric => metric.metrics_artifact_type === MetricsArtifactType.MAIN_ARTIFACT
+ );
+}
+
export enum BuildDetailsState {
UPLOADING = 0,
UPLOADED = 1,
diff --git a/static/app/views/preprod/utils/labelUtils.tsx b/static/app/views/preprod/utils/labelUtils.tsx
index c6153e1a511bb0..0c9dbe3bc4b232 100644
--- a/static/app/views/preprod/utils/labelUtils.tsx
+++ b/static/app/views/preprod/utils/labelUtils.tsx
@@ -3,8 +3,9 @@ import {formatBytesBase10} from 'sentry/utils/bytes/formatBytesBase10';
import {unreachable} from 'sentry/utils/unreachable';
import {
BuildDetailsArtifactType,
+ getMainArtifactSizeMetric,
isSizeInfoCompleted,
- type BuildDetailsApiResponse,
+ type BuildDetailsSizeInfo,
} from 'sentry/views/preprod/types/buildDetailsTypes';
import type {Platform} from 'sentry/views/preprod/types/sharedTypes';
@@ -114,16 +115,30 @@ export function getReadablePlatformLabel(platform: Platform): string {
}
}
-export function formattedInstallSize(build: BuildDetailsApiResponse): string {
- if (isSizeInfoCompleted(build?.size_info)) {
- return formatBytesBase10(build.size_info.install_size_bytes);
+export function formattedPrimaryMetricInstallSize(
+ sizeInfo: BuildDetailsSizeInfo | undefined
+): string {
+ if (isSizeInfoCompleted(sizeInfo)) {
+ const primarySizeMetric = getMainArtifactSizeMetric(sizeInfo);
+ if (!primarySizeMetric) {
+ return '-';
+ }
+
+ return formatBytesBase10(primarySizeMetric.install_size_bytes);
}
return '-';
}
-export function formattedDownloadSize(build: BuildDetailsApiResponse): string {
- if (isSizeInfoCompleted(build?.size_info)) {
- return formatBytesBase10(build.size_info.download_size_bytes);
+export function formattedPrimaryMetricDownloadSize(
+ sizeInfo: BuildDetailsSizeInfo | undefined
+): string {
+ if (isSizeInfoCompleted(sizeInfo)) {
+ const primarySizeMetric = getMainArtifactSizeMetric(sizeInfo);
+ if (!primarySizeMetric) {
+ return '-';
+ }
+
+ return formatBytesBase10(primarySizeMetric.download_size_bytes);
}
return '-';
}