diff --git a/apps/studio/data/storage/versioning/archived-object-purge-mutation.test.tsx b/apps/studio/data/storage/versioning/archived-object-purge-mutation.test.tsx index 2a6b6eea2a8..3c8b4522484 100644 --- a/apps/studio/data/storage/versioning/archived-object-purge-mutation.test.tsx +++ b/apps/studio/data/storage/versioning/archived-object-purge-mutation.test.tsx @@ -79,6 +79,14 @@ describe('useArchivedObjectPurgeMutation', () => { expect(deleted).toEqual([]) }) + it('stops rather than delete a version that went live mid-purge', async () => { + // The first round clears the history; by the second, the path has been written again. + mockListPages([[marker(), row('v2')], [row('v-new', { archived_at: null })]]) + + await expect(purge()).rejects.toThrow(/restored or replaced/) + expect(deleted).toEqual([[MARKER, 'v2']]) + }) + it('gives up rather than spin when a round deletes nothing', async () => { mockListPages([[marker(), row('v1')]]) diff --git a/apps/studio/data/storage/versioning/archived-object-purge-mutation.ts b/apps/studio/data/storage/versioning/archived-object-purge-mutation.ts index 381c51a09aa..277bc43c107 100644 --- a/apps/studio/data/storage/versioning/archived-object-purge-mutation.ts +++ b/apps/studio/data/storage/versioning/archived-object-purge-mutation.ts @@ -69,6 +69,13 @@ export const useArchivedObjectPurgeMutation = ({ await deleteVersions(versions) const remaining = await listVersions() + // Deleting the marker promotes nothing, so nothing here should be live. One that is + // arrived while the purge was running — a restore, or a new upload to the same path — + // and belongs to the user, not to the archive the next round would hand to `del`. + const live = remaining.find((version) => version.isCurrent) + if (live !== undefined && live.versionId !== archivedObjectId) { + throw new Error(`${path} was restored or replaced while it was being deleted`) + } // Nothing went away, so another round would spin rather than make progress. if (remaining.length >= versions.length) { throw new Error(`Some versions of ${path} could not be deleted`)