fix(ui): write generated i18n resources atomically - #352
Conversation
CI typecheck and build both regenerate resources.generated.ts in parallel. writeFileSync truncates the file first, so tsc can read an empty module and fail with TS2305. Co-authored-by: Cursor <cursoragent@cursor.com>
🦋 Changeset detectedLatest commit: cedb864 The changes in this PR will be included in the next version bump. This PR includes changesets to release 0 packagesWhen changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
cameronapak
left a comment
There was a problem hiding this comment.
Spec
No YPE ticket. Spec is the PR body: UI typecheck and UI build both regenerate resources.generated.ts. writeFileSync can empty that file under tsc (TS2305 on #351).
typecheck ──┐
├─ generate-i18n-resources
build ──────┘
skip if unchanged
else dest.${pid}.tmp → renameSync dest
All five asked items are present. Skip-if-unchanged plus same-dir pid temp plus POSIX rename closes the truncate race on Linux CI. Type Check is green on this PR.
nitpick: Node renameSync on Windows can fail with EPERM if the dest file is open. Linux CI is the stated environment.
Standards
No documented-standard break. Empty changeset matches Decision 4 (internal generator, no release).
suggestion (worth): The first empty catch around readFileSync swallows every failure. This file logs watch errors with console.error. The unlink catch after a failed rename is fine: cleanup must not hide the rename error.
Summary
- Standards: 0 must-fix, 1 worth. Worst: empty
catcharoundreadFileSync. - Spec: 0 must-fix, 0 worth, 1 nit. Worst: none.
Code Reviewer bot, sent on behalf of Cam.
|
Thanks for this! |
Summary
TS2305: Module "./resources.generated" has no exported member 'resources').resources.generated.tsin parallel.writeFileSynctruncates that file first, sotsccan read an empty module and report missing exports.Test plan
pnpm --filter @youversion/platform-react-ui typechecklocally still passesMade with Cursor
Greptile Summary
This PR prevents concurrent i18n generation from exposing a truncated TypeScript module by skipping unchanged output and replacing changed output through a same-directory temporary file.
Confidence Score: 5/5
The PR appears safe to merge, with the generated resource now replaced atomically instead of being transiently truncated.
The changed writer preserves a complete destination for concurrent readers, avoids no-op write races, surfaces replacement errors, and does not introduce a reachable build, runtime, or security failure.
Important Files Changed
Reviews (1): Last reviewed commit: "fix(ui): write generated i18n resources ..." | Re-trigger Greptile
Context used: