Skip to content

fix(ui): write generated i18n resources atomically - #352

Merged
Dustin-Kelley merged 1 commit into
mainfrom
fix/i18n-generate-atomic-write
Aug 20, 2026
Merged

fix(ui): write generated i18n resources atomically#352
Dustin-Kelley merged 1 commit into
mainfrom
fix/i18n-generate-atomic-write

Conversation

@Dustin-Kelley

@Dustin-Kelley Dustin-Kelley commented Aug 20, 2026

Copy link
Copy Markdown
Collaborator

Summary

  • Fixes the Type Check failure on chore: version packages #351 (TS2305: Module "./resources.generated" has no exported member 'resources').
  • UI typecheck and UI build both regenerate resources.generated.ts in parallel. writeFileSync truncates that file first, so tsc can read an empty module and report missing exports.
  • The generator now skips the write when content is unchanged and otherwise replaces the file via temp + rename so readers never see a truncated copy.

Test plan

  • Confirm Type Check is green on this PR
  • Confirm Type Check is green on chore: version packages #351 after this lands on main (re-run or wait for the changeset action to rebase)
  • Optional: pnpm --filter @youversion/platform-react-ui typecheck locally still passes

Made 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.

  • Adds an intentional empty changeset for the internal tooling fix.
  • Reads the existing generated file before writing to avoid unnecessary replacements.
  • Writes changed resources to a process-specific temporary path and renames it over the destination.
  • Cleans up the temporary file when replacement fails.

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

Filename Overview
packages/ui/scripts/generate-i18n-resources.mjs Replaces truncate-in-place generation with unchanged-content detection and atomic temporary-file replacement; no actionable changed-code defect was established.
.changeset/small-rules-exist.md Adds the required empty changeset documenting this internal generator fix without triggering a package release.

Reviews (1): Last reviewed commit: "fix(ui): write generated i18n resources ..." | Re-trigger Greptile

Context used:

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-bot

changeset-bot Bot commented Aug 20, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: cedb864

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 0 packages

When 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 cameronapak left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

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 catch around readFileSync.
  • Spec: 0 must-fix, 0 worth, 1 nit. Worst: none.

Code Reviewer bot, sent on behalf of Cam.

Comment thread packages/ui/scripts/generate-i18n-resources.mjs
@cameronapak

Copy link
Copy Markdown
Collaborator

Thanks for this!

@Dustin-Kelley
Dustin-Kelley merged commit 30102cb into main Aug 20, 2026
14 checks passed
@Dustin-Kelley
Dustin-Kelley deleted the fix/i18n-generate-atomic-write branch August 20, 2026 18:44
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.

2 participants