Localization: stage regular-string translations into Localizable.xcstrings (manual)#25713
Draft
jkmassel wants to merge 6 commits into
Draft
Localization: stage regular-string translations into Localizable.xcstrings (manual)#25713jkmassel wants to merge 6 commits into
jkmassel wants to merge 6 commits into
Conversation
…lane) Adds a regular-string reverse fold — the catalog analogue of the plural fold — that populates Localizable.xcstrings (the future regular-string backing store) with GlotPress human translations plus AI machine translations, as human ?? existing-machine ?? AI ?? English (human => translated; machine / English => needs_review). - CatalogStrings.fold_translations! (pure, 12 tests): reuse-aware — a valid existing needs_review machine cell is kept, so the catalog's needs_review state is the persistence (no side-store) and re-runs only translate genuinely-new gaps. Humans supersede machine cells on the next fold. - download_localized_catalog lane: generate the English catalog, fold the downloaded .strings humans + AI-fill (translate_all), commit. Gated on ANTHROPIC_API_KEY. STAGED, NOT SHIPPED: the catalog isn't the runtime store yet, so this changes nothing users see. MANUAL ONLY: deliberately not wired into download_localized_strings or CI — it runs xcstringstool extraction, calls the API, and commits a large catalog, so it's run on demand.
Collaborator
Generated by 🚫 Danger |
… -> AI-fill Make the lane mirror the pipeline order: (1) generate_strings_catalog scans the code, (2) it now downloads the current GlotPress translations itself (ios_download_strings_files_from_glotpress) and folds them in, (3) CatalogStrings AI-fills the rest. Adds a locales:fr,de scope (and skip_download:true) so a run can be kept cheap. Uploading the AI drafts back to GlotPress (the eventual step 4) stays out — it builds on the existing GlotPress import integration (gp_update_metadata_source), not done here.
Run a download then a localize as separate fastlane invocations: - download_catalog_strings — pull GlotPress translations into the *.lproj dirs (scoped by locales:) - localize_catalog — scan + fold the downloaded strings + AI-fill into Localizable.xcstrings Replaces the single download_localized_catalog lane (and its skip_download flag): download once, re-localize as many times as you like without re-downloading.
localize_catalog no longer re-runs generate_strings_catalog — scanning the code is its own lane (generate_strings_catalog), so you can refresh the English catalog without ever invoking the AI. The three stages are now independent fastlane invocations: generate_strings_catalog (scan) -> download_catalog_strings (download) -> localize_catalog (fold + AI-fill) localize_catalog errors if the catalog hasn't been generated yet.
The extract/sync sh calls echo enormous commands (up to 400 file paths per extract batch; a --stringsdata <path> pair per file on sync), burying the output. Pass log: false and emit concise progress lines instead. No fastlane/release-toolkit action wraps xcstringstool, so sh is the invocation; log: false is its clean-output option.
fastlane's sh treats each call as an action: even with log: false it prints a '--- Step: shell command ---' banner per call and lists it in the run summary. extract is chunked into ~7 calls and sync runs twice, so that wrapped the real progress in a wall of banners. Run xcstringstool through Open3.capture2e instead (argv — safe for paths with spaces; captured output surfaced only on failure), via a run_xcstringstool helper. The scan now prints just its own progress lines.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Stages regular-string translations into
Localizable.xcstrings— a regular-string reverse fold (the catalog analogue of the plural fold), populating the future backing store with GlotPress human translations plus AI machine translations ashuman ?? existing-machine ?? AI ?? English.Stacked on #25705 (its
AITranslatorprimitives aren't ontrunkyet); base retargets totrunkonce #25705 merges. Sibling of #25710 (which does the same for plurals intoPlurals.xcstrings). Draft — the live fold wants a real run to validate.Staged, not shipped — and manual, not CI
Two deliberate constraints:
Localizable.xcstringsis generated (Localization: String Catalog pipeline (plurals + catalog generation) #25688) but isn't the runtime store yet — the app still ships the legacyLocalizable.stringsfor regular strings. This fold only pre-populates the catalog for the eventual cutover; it changes nothing users see. (This is why regular-string MT belongs in the catalog, not the live.strings: the catalog'sneeds_reviewstate lets a machine translation be staged rather than shipped.)download_localized_catalogis not wired intodownload_localized_stringsor any pipeline step — it runsxcstringstoolextraction, calls the translation API (cost), and commits a large catalog, so it's run on demand, not on every release. The pure unit suite still runs in CI (it's free).So this PR makes the catalog fold possible to run, without putting it in CI's path. First manual run generates + commits the
Localizable.xcstrings; later runs maintain it.What's here
CatalogStrings.fold_translations!(pure, 12 tests) — per (key, locale):human ?? existing-machine ?? AI ?? English; human ⇒translated, machine / English ⇒needs_review. Reuse-aware: a valid existingneeds_reviewmachine cell is kept and not re-translated — the catalog'sneeds_reviewstate is the persistence, so re-runs only translate genuinely-new gaps (no side-store), and a GlotPress human translation supersedes a machine cell automatically on the next fold. Handles key-as-source strings andshouldTranslate:false.locales:fr,de):generate_strings_catalogscans the code into the English catalog (existing lane, no AI),download_catalog_stringspulls the current GlotPress translations into the*.lprojdirs, thenlocalize_catalogfolds those human translations in (→translated) and AI-fills the rest (CatalogStrings, →needs_review) → commit. Scanning the code is therefore separate from the AI fill;localize_catalogneither scans nor downloads. Gated onANTHROPIC_API_KEY(absent ⇒ human + English only); a per-locale API failure degrades to English.Uploading the AI drafts back to GlotPress as
needs-review(the eventual "step 4") is intentionally out of this PR. It's not blocked on tooling — it builds on the existing GlotPress import integration the project already uses for metadata source (gp_update_metadata_source) — it's just a separate step.Test plan
ruby fastlane/lanes/catalog_strings_helper_test.rb— 12 (provenance, reuse vs. retry, human-supersedes-machine, key-as-source,shouldTranslate, batched per-locale call)fastlane/lanes/*_test.rbsuite green — 62 runsrubocopclean on all changed filesdownload_localized_catalogrun (needsANTHROPIC_API_KEY+bundle install) on real downloaded strings — eyeball the staged catalog + measure costRelated
Plurals.xcstrings); itsdocs/localization-pipeline.mddescribes the floor and will get a follow-up note that regular strings now have a staged catalog path