Skip to content

Fix deleted files persisting in published realm on republish#4221

Merged
jurgenwerk merged 4 commits intomainfrom
cs-10189-deleted-files-should-be-removed-from-published-realm-upon
Mar 24, 2026
Merged

Fix deleted files persisting in published realm on republish#4221
jurgenwerk merged 4 commits intomainfrom
cs-10189-deleted-files-should-be-removed-from-published-realm-upon

Conversation

@jurgenwerk
Copy link
Copy Markdown
Contributor

Summary

  • Clear the published realm directory before copying from source on republish, so files deleted from the source realm don't persist in the published realm
  • Previously, copySync would only add/overwrite files but never remove files that existed in the destination but not in the source
  • The existing fullIndex() call already handles DB-level cleanup by tombstoning index entries for files no longer on disk

Closes CS-10189

Test plan

  • Added test: "republishing removes files that were deleted from the source realm"
  • All 14 existing publish/unpublish tests pass
  • Manual verification: delete a card from source realm, republish, confirm it's gone from published realm

🤖 Generated with Claude Code

Clear the published realm directory before copying from source so that
files deleted from the source realm don't linger in the published realm.
The existing fullIndex() call already handles DB-level cleanup by
tombstoning index entries for files no longer on disk.

Closes CS-10189

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@jurgenwerk jurgenwerk force-pushed the cs-10189-deleted-files-should-be-removed-from-published-realm-upon branch from 63a6b51 to e3ccf23 Compare March 20, 2026 11:03
@github-actions
Copy link
Copy Markdown

github-actions bot commented Mar 20, 2026

Host Test Results

    1 files  ±    0      1 suites  ±0   3h 47m 46s ⏱️ + 1h 27m 14s
2 031 tests +    1  2 015 ✅ ±    0  15 💤 ± 0  0 ❌ ±0  1 🔥 +1 
4 003 runs  +1 958  3 972 ✅ +1 942  29 💤 +14  1 ❌ +1  1 🔥 +1 

For more details on these errors, see this check.

Results for commit af7990c. ± Comparison against base commit c459617.

♻️ This comment has been updated with latest results.

@jurgenwerk jurgenwerk marked this pull request as ready for review March 20, 2026 11:33
@jurgenwerk jurgenwerk requested a review from a team March 20, 2026 11:33
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: e3ccf23075

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines 338 to 339
removeSync(publishedRealmPath);
copySync(sourceRealmPath, publishedRealmPath);
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Preserve old published realm until new copy succeeds

Deleting publishedRealmPath before copying makes republish non-atomic for existing published realms: if copySync (or any subsequent read/write in this block) fails due to I/O conditions like disk-full or permission errors, the request returns 500 after the old on-disk realm has already been removed, and there is no rollback path to restore it. In that failure mode, the currently mounted published realm is left serving from a deleted/partially rebuilt directory, causing user-visible outages until another successful publish.

Useful? React with 👍 / 👎.

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.

This does seem worth thinking through, we don’t have much in the way of error-handling here

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Fixed

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR fixes republish behavior for published realms by ensuring files deleted from a source realm do not persist in the published realm after republishing (CS-10189).

Changes:

  • Clear the published realm directory before copying files from the source realm during publish/republish.
  • Add a regression test verifying deleted source files are removed from the published realm on republish.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.

File Description
packages/realm-server/handlers/handle-publish-realm.ts Removes existing published realm directory prior to copying from the source realm to prevent stale files on republish.
packages/realm-server/tests/publish-unpublish-realm-test.ts Adds a test that publishes, deletes a source file, republishes, and asserts the file is removed from the published realm on disk.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines 333 to 339
let sourceRealmPath = sourceRealm.dir;
let publishedDir = join(realmsRootPath, PUBLISHED_DIRECTORY_NAME);
let publishedRealmPath = join(publishedDir, publishedRealmId);
// Remove existing published files so that files deleted from the source
// realm don't persist in the published realm on republish
removeSync(publishedRealmPath);
copySync(sourceRealmPath, publishedRealmPath);
Copy link

Copilot AI Mar 20, 2026

Choose a reason for hiding this comment

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

removeSync(publishedRealmPath) runs before unmounting existingPublishedRealm (the unmount happens later), which means a republish can delete/partially overwrite the on-disk directory while the realm is still mounted and potentially serving requests. This can cause transient 5xxs or inconsistent reads during republish and leaves the published realm in a broken state if copySync or subsequent steps fail. Consider unmounting the existing published realm before touching the filesystem, or publishing into a fresh temp directory and then swapping/renaming it into place atomically once the copy and config rewrite succeed.

Copilot uses AI. Check for mistakes.
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.

I agree with this, I don’t know that we’ve defined behaviour around requests for published realms when (re)publishing is in progress

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Fixed

Copy link
Copy Markdown
Contributor

@backspace backspace left a comment

Choose a reason for hiding this comment

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

The test looks good to me, the bot comments do seem relevant but could be addressed in followup issues

jurgenwerk and others added 3 commits March 24, 2026 08:53
Copy source realm to a temp directory first, then swap it into place,
so that a failed copy (e.g. disk-full, permission error) doesn't
destroy the existing published realm with no rollback path.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Move the unmount of the existing published realm to happen before the
directory swap, so it can't serve requests from a partially replaced
filesystem during republish.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@jurgenwerk jurgenwerk merged commit 05d39d2 into main Mar 24, 2026
128 of 130 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants