diff --git a/src/sentry/preprod/api/endpoints/preprod_artifact_snapshot.py b/src/sentry/preprod/api/endpoints/preprod_artifact_snapshot.py
index 1dbc03c8ddf82f..898134a5c091ec 100644
--- a/src/sentry/preprod/api/endpoints/preprod_artifact_snapshot.py
+++ b/src/sentry/preprod/api/endpoints/preprod_artifact_snapshot.py
@@ -344,7 +344,12 @@ def get(self, request: Request, organization: Organization, snapshot_id: str) ->
if pending_or_failed_state is not None:
comparison_state = PreprodSnapshotComparison.State(pending_or_failed_state).name
- comparison_type = "diff" if comparison_manifest is not None else "solo"
+ if comparison_manifest is not None:
+ comparison_type = "diff"
+ elif commit_comparison and commit_comparison.base_sha and pending_or_failed_state is None:
+ comparison_type = "waiting_for_base"
+ else:
+ comparison_type = "solo"
run_info: SnapshotComparisonRunInfo | None = None
if comparison_state is not None:
diff --git a/src/sentry/preprod/api/models/project_preprod_build_details_models.py b/src/sentry/preprod/api/models/project_preprod_build_details_models.py
index ee936c16ca36ea..e56bccf27a3770 100644
--- a/src/sentry/preprod/api/models/project_preprod_build_details_models.py
+++ b/src/sentry/preprod/api/models/project_preprod_build_details_models.py
@@ -91,7 +91,9 @@ class PostedStatusChecks(BaseModel):
class SnapshotComparisonInfo(BaseModel):
image_count: int
- comparison_state: Literal["pending", "processing", "success", "failed"] | None = None
+ comparison_state: (
+ Literal["pending", "processing", "success", "failed", "waiting_for_base"] | None
+ ) = None
comparison_error_message: str | None = None
images_added: int = 0
images_removed: int = 0
@@ -299,7 +301,11 @@ def to_snapshot_comparison_info(head_artifact: PreprodArtifact) -> SnapshotCompa
reverse=True,
)
comparison = comparisons[0] if comparisons else None
- if comparison:
+ if not comparison:
+ cc = head_artifact.commit_comparison
+ if cc and cc.base_sha:
+ comparison_state = "waiting_for_base"
+ elif comparison:
comparison_state = PreprodSnapshotComparison.State(comparison.state).name.lower()
if comparison.state == PreprodSnapshotComparison.State.SUCCESS:
images_added = comparison.images_added
diff --git a/static/app/components/preprod/preprodBuildsSnapshotTable.tsx b/static/app/components/preprod/preprodBuildsSnapshotTable.tsx
index 2f82ccb2b9ff12..6977703f52eacf 100644
--- a/static/app/components/preprod/preprodBuildsSnapshotTable.tsx
+++ b/static/app/components/preprod/preprodBuildsSnapshotTable.tsx
@@ -65,6 +65,17 @@ function ChangeCounts({
if (!comparisonState) {
return {t('Base')};
}
+ if (comparisonState === 'waiting_for_base') {
+ return (
+
+ {t('Waiting for base')}
+
+ );
+ }
if (comparisonState === 'pending') {
return (
diff --git a/static/app/views/preprod/snapshots/main/snapshotMainContent.tsx b/static/app/views/preprod/snapshots/main/snapshotMainContent.tsx
index 52190ddc6742e2..848320cf331f39 100644
--- a/static/app/views/preprod/snapshots/main/snapshotMainContent.tsx
+++ b/static/app/views/preprod/snapshots/main/snapshotMainContent.tsx
@@ -54,7 +54,7 @@ export interface NavButtonRefs {
interface SnapshotMainContentProps {
canNavigateNext: boolean;
canNavigatePrev: boolean;
- comparisonType: 'diff' | 'solo' | undefined;
+ comparisonType: 'diff' | 'solo' | 'waiting_for_base' | undefined;
diffImageBaseUrl: string;
diffMode: DiffMode;
hasDiffComparison: boolean;
@@ -192,6 +192,16 @@ export function SnapshotMainContent({
);
} else if (comparisonType === 'solo') {
soloDiffToggle = {t('Base')};
+ } else if (comparisonType === 'waiting_for_base') {
+ soloDiffToggle = (
+
+ {t('Waiting for base')}
+
+ );
}
if (viewMode === 'list') {
diff --git a/static/app/views/preprod/snapshots/snapshots.tsx b/static/app/views/preprod/snapshots/snapshots.tsx
index 7aac75fd30b41e..1e773a8d9c9007 100644
--- a/static/app/views/preprod/snapshots/snapshots.tsx
+++ b/static/app/views/preprod/snapshots/snapshots.tsx
@@ -266,7 +266,7 @@ export default function SnapshotsPage() {
viewOverride === 'solo' ? 'solo' : (data?.comparison_type ?? 'solo');
const comparisonRunInfo = data?.comparison_run_info;
- const isSoloView = comparisonType === 'solo';
+ const isSoloView = comparisonType === 'solo' || comparisonType === 'waiting_for_base';
const handleToggleView = useCallback(() => {
const {view: _view, ...restQuery} = location.query;
if (isSoloView) {
diff --git a/static/app/views/preprod/types/buildDetailsTypes.ts b/static/app/views/preprod/types/buildDetailsTypes.ts
index 2b538cdcacf63c..92557d103ab9aa 100644
--- a/static/app/views/preprod/types/buildDetailsTypes.ts
+++ b/static/app/views/preprod/types/buildDetailsTypes.ts
@@ -194,7 +194,12 @@ export function isStatusCheckFailure(
return result?.success === false;
}
-export type SnapshotComparisonState = 'pending' | 'processing' | 'success' | 'failed';
+export type SnapshotComparisonState =
+ | 'pending'
+ | 'processing'
+ | 'success'
+ | 'failed'
+ | 'waiting_for_base';
export type SnapshotApprovalStatus = 'approved' | 'requires_approval';
interface SnapshotComparisonInfo {
diff --git a/static/app/views/preprod/types/snapshotTypes.ts b/static/app/views/preprod/types/snapshotTypes.ts
index 32b84062e3a3b3..60e6ebe42aa79f 100644
--- a/static/app/views/preprod/types/snapshotTypes.ts
+++ b/static/app/views/preprod/types/snapshotTypes.ts
@@ -40,7 +40,7 @@ interface SnapshotApprovalInfo {
}
export interface SnapshotDetailsApiResponse {
- comparison_type: 'solo' | 'diff';
+ comparison_type: 'solo' | 'diff' | 'waiting_for_base';
head_artifact_id: string;
image_count: number;
images: SnapshotImage[];