Write the store copy ahead of the release, and translate the app again - #162
Merged
Conversation
andiwand
force-pushed
the
fix-the-edit-workflow
branch
from
August 16, 2026 08:23
c608627 to
8cab066
Compare
The "What's New" text was typed into App Store Connect at submission and translated by hand. scripts/store-copy.py now writes it from the changelog, one agent per language and a second one reading each draft back, and the release run uploads it and refuses a version any locale is missing. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Xryx81PvamT674wzzQujjg
Every language but English showed English for the onboarding buttons, the privacy screen and the banner - nineteen of the forty-four strings. Danish, Catalan, Turkish and Czech showed it for most of the rest, and the Chinese introduction named a different app. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Xryx81PvamT674wzzQujjg
Every listing but the English one was a translation of an older, shorter listing: six of the nine features and the whole list of formats the app opens were missing, and so were the notes about ads and where to send feedback. The Swedish one called an office suite office supplies. The 1.41 notes say PDFs fit the screen and take a password like everything else, rather than which engine draws them. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Xryx81PvamT674wzzQujjg
Eight of the ten storefronts showed an English name and subtitle, both saying the app only reads. Every one showed the same English keywords, so nobody searching in their own language found it. Each listing now leads with LibreOffice, says somewhere that it edits, and spends its keywords on words people there actually type. The release run uploads all of it, not just the release notes, so the store says what is written here. Lite still takes the notes alone: a name has to be unique in the store, and only Pro's listing is checked in. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Xryx81PvamT674wzzQujjg
andiwand
force-pushed
the
fill-in-the-translations
branch
from
August 16, 2026 08:33
19fee95 to
5f0271a
Compare
fastlane/metadata is what Pro and Lite share. fastlane/metadata-pro and
-lite hold the rest, read over it. Two things differ: the name, because
the store wants a unique one, and the sentence about ads, which Pro has
been carrying for years without showing any. That one sentence is a
${ads} in the shared description rather than a second copy of it.
The name is no longer translated. OpenDocument is the format's own name,
and the App Store indexes the subtitle just as well, so the local words
and LibreOffice moved down there.
Nothing sells the app as an editor now. It edits text, but not well
enough to promise.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Xryx81PvamT674wzzQujjg
Both were counted up from what was on disk. A locale that lost its directory, or only its description, simply stopped being a locale: the check passed with ten, and that storefront kept whatever the console said. The eleven are written down now. Same for the listing itself. A field found nowhere was left out of what is staged, and App Store Connect reads a field it was not given as "leave this be" - so the run meant to replace the old words would have kept them instead. The name is the easiest to lose, since each app says it in one file for all eleven languages. Both come from the review of the Android half, opendocument-app/OpenDocument.droid#593. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Xryx81PvamT674wzzQujjg
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.
Two halves of the same problem: the app's text in other languages was either typed in by hand at submission time or missing altogether.
Rebased onto
mainnow that #159, #160 and #161 are in.The store copy
scripts/store-copy.py 1.41writes the "What's New" text for every locale before the release, instead of it being typed into App Store Connect and translated by hand during one.The English comes from the
CHANGELOG.mdsection of that version, or fromUnreleasedwhile the heading is still open. Every other locale is translated by an agent of its own, given that locale's store description and the release before it, so the notes keep the words the listing already uses. A second agent of the same language reads each draft back against the English before it is written. Output is checked mechanically - a line for every English line, every line a bullet, under the store's 4000 characters - and a language that comes back wrong is retried, then named so it can be redone on its own with--locales.It writes files and never uploads. The copy lives in
fastlane/metadata/<locale>/changelogs/1.41.txt, one file per version per locale, because App Store Connect keeps only the notes of the submission in flight.scripts/store-notes.pyowns that layout: it checks a version has copy everywhere and stages it into the one-release_notes.txt-per-locale shapedeliverreads. The release run checks before it builds, so a missing translation fails in seconds rather than after both apps are up, and a newnotesjob uploads it afterwards. That job is separate fromuploadbecause notes stay editable until the version is submitted, while a build cannot be uploaded twice.deliveris pointed at a throwaway directory holding nothing but release notes, so the descriptions checked in beside them are never pushed. The stalerelease_notes.txtfiles are gone - every one of them still said "Add search functionality for ODF documents".1.41's copy is written and reviewed in all eleven locales.
The app
Nineteen of the forty-four strings had no translation in any language: every onboarding button, the whole privacy screen, and all of the house ad. Danish, Catalan, Turkish and Czech showed English for most of the remaining twenty-five.
All fifteen languages are now complete, each gone over by a speaker of that language. Beyond the missing strings, that turned up:
超级文件管理大师intro_title_editheld the text belonging tointro_title_appsloadingwas Catalan, and misspelledokwas CyrillicОК, a homoglyph of the LatinOKiOS actually showsTerminology now follows Apple's own wording per language, and the German, Turkish and Russian apps agree with their 1.41 release notes on what "edit" is called. Irish and Slovenian name the iOS Settings panes in English, since iOS ships no UI in either language and a translated path is one the user cannot find.
The store descriptions
Every listing but the English one was a translation of an older English listing, in two generations:
de-DE,fr-FR,ruandhiwere one behind,es-ES,it,pl,pt-BR,svandtrtwo behind — those six were around 1400 characters against English's 3454.All ten are now translated from what the listing says today. What was missing from most of them:
Individual defects worth naming: Swedish said
kontorsvaror— office supplies — for office suite, along withbasisk redigeringand an untranslatedopen .odt, .ods och.odp; French called Apple's Numbers "Numéros" and listed Pladao Office twice; Italian had a sentence that stopped mid-air atapri .odt, .ods e .odp senza; Turkish advertised a small app size that the English dropped long ago; German hadlesen , welcheand translated Pages as "Seiten".The 1.41 release notes changed with them. Line one was
PDFs are drawn by the app's own engine, so they fit the screen— reviewers in four languages balked at the engine, and two dropped it rather than translate it. It now readsPDFs now fit the screen and behave like every other document, password protected ones included, which is both plainer and covers the password prompt the old line left out. Every locale's line one was updated to match. The rebase then added #160's line about flat XML documents to the English, so all ten translations were rewritten against the finished four-line text - by the script, which is what it is for.Name, subtitle and keywords
Eight of the ten storefronts showed the English
LibreOffice document viewer/View ODT, ODS, ODG, ODP & more; all ten shared one English keyword string. Every one of them also sold a viewer, so no storefront but the English one said the app edits.A speaker of each language proposed a localized name and subtitle, and a first
round of this branch shipped them. Apple's public lookup API then said what the
two apps are actually called today:
at.tomtasche.readerOpenDocument Reader Pro, andLibreOffice Dokumentbetrachter/Visionneuse LibreOfficein de and frat.tomtasche.reader.lite1OpenDocument Reader - view ODT, the same in all eleven storefrontsfastlane/metadata/en-US/name.txtmatched neither. The checked-in listing haddrifted, so uploading it would have renamed a live app to something nobody chose.
So the names were settled instead of guessed, and they are no longer translated:
OpenDocument Reader ProOpenDocument ReaderOpenDocumentis the format's own name and goes untranslated in every language;one name is one app that people can pass to each other. Nothing is lost to search
by it, because the App Store indexes name, subtitle and keywords alike — so
LibreOfficeand the local words moved into the subtitle, which is empty on bothapps in every storefront today. There is no
name.txtunderfastlane/metadataany more; the apps own their names.
Nothing sells the app as an editor. It edits text, but the capability is
young and does not reach every document, so no name, subtitle or keyword claims
it, and each description says it once, quietly, and calls itself a reader.
No keyword repeats a word from the name or from its own subtitle — Apple indexes
all three, so a repeat is a wasted slot. Hindi keeps two Devanagari keywords and
otherwise Latin script, because Hindi-locale App Store search skews heavily Latin.
The listing is uploaded now
scripts/store-notes.pybecamescripts/store-listing.py, and--stage --app pro|litestages the whole listing rather than the release notes alone. Thenotesjob is nowlisting, one per app.What goes up:
name,subtitle,description,keywords, the three URLs,copyright, and the version's release notes. What does not:review_information— the account's contact details and the note to the reviewer — and the category files. Those are named in a list in the script rather than globbed, so adding one is a decision.Both apps get the whole listing. They say almost the same thing, so
fastlane/metadataholds what they share andfastlane/metadata-pro/-litehold the rest, read over it —<app>/all/into every locale,<app>/<locale>/into that one.Two things differ. The name, which has to: an App Store name is unique, so one file each. And the sentence about advertising, which Pro has been carrying for years in every locale without showing an ad since it stopped linking the SDK. Rather than keep two descriptions per locale and let them drift, the shared one holds
${ads}and each app fills it in from its ownads.txt— Lite has eleven, Pro has none, and a fill-in nobody answers leaves nothing behind, the space in front of it included.FILL_INSlists the names one may have, so a misspelt${adds}is an error rather than a sentence that quietly vanishes from the store.The first run overwrites what is in App Store Connect for those fields, on both apps, in all eleven locales. That is the point — the checked-in copy is now the source of truth — but it is worth knowing before the run rather than after. Two things to look at first:
copyright.txtstill says 2019, and Lite's live name loses- view ODT.Checked
.stringsfile passesplutil -lint, has all 44 keys inen.lprojorder, no duplicates and no empty valuesFastfileandrelease.ymlparse; the lanes registername.txt, and one sentence ofdescription.txt${...}survives staging, and no double space is left where one was filled in emptyThe App Store Connect call itself needs the repository secrets, so the first real release run is its own proof.
🤖 Generated with Claude Code