wordpress-mobile / wordpress-mobile/WordPress-iOS
Enforce localization key immutability in CI
Nobody has claimed this yet.
- Dominant language
- Swift
- Stars
- 3.9k
- Forks
- 1.2k
- Avg merge
- 23h 51m
- Merged PRs (30d)
- 58
Description
Summary
The regular-string String Catalog fold treats each (key, locale) cell's stored English as the record of what its translation was made for. If an explicit-key string's English is reworded in place (the key stays, only value: changes), xcstringstool sync silently keeps the old translations — now stale for the new text — and the fold can't tell a translation of the old English from a current one.
We've decided localization keys are immutable: rewording requires a new key. generate_strings_catalog now hard-fails on a reworded key (CatalogHelper.reworded_keys → enforce_immutable_source_keys in fastlane/lanes/localization_catalog.rb).
The gap this issue tracks
That check compares freshly-extracted English against the persisted catalog, which works for the local manual lane but not in CI: Localizable.xcstrings is gitignored and generated transiently, so CI has no prior English to diff against. A reword can therefore merge without CI catching it.
Proposal
Add a CI lint on the committed English .strings — the one cross-run baseline we do keep (it's the GlotPress source of truth): fail when an existing key's value changes (same key, different English).
- A key-as-source reword shows up in the
.stringsdiff as a remove + add → passes (that key genuinely changed). - An explicit-key reword shows up as same-key / changed-value → fails, with a message to mint a new key.
This is what makes immutable keys enforced on every PR, not only where the catalog persists.
Escape hatch
Hard-fail everywhere for now, no exceptions. If the friction on cosmetic edits (typo fixes) proves burdensome, add an opt-in ack later — a Reword: commit trailer, or a PR-comment + review gate — that flips reconcile from fail to its keep-and-flag (needs_review) path. The placeholder-format gate runs regardless, so an ack could only ever let through prose drift, never a runtime crash.
References
- Enforcement today:
CatalogHelper.reworded_keys(fastlane/lanes/catalog_helper.rb),enforce_immutable_source_keys(fastlane/lanes/localization_catalog.rb). - Rationale + the
human ?? AI ?? Englishcontract and immutable-key note:docs/localization-pipeline.md.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with CatalogHelper.reworded_keys in fastlane/lanes/catalog_helper.rb, enforce_immutable_source_keys in fastlane/lanes/localization_catalog.rb, and the workflow that validates committed English .strings files. Trace how the existing source baseline is read, then ensure CI fails for same-key value changes while allowing remove-and-add key changes; verify the failure message requires minting a new key.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- swift
- Domain
- ci-cd, localization
- Issue type
- Feature
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 52/100