Translations: hold a development build to en-GB, fr-FR and pt-PT and a release to its selected languages, with every language scaffolded #347

Closed
opened 2026-10-01 10:06:12 +00:00 by tiagoagueda · 1 comment
Owner

This is the work the maintainer's final decision on translations (2026-10-01) implies for the core. The decision is recorded on #269 and #72; this issue is where it is built. Which languages 0.5.0 adds is #269's subject; the spelling of their codes is #337's.

The decision

  1. Every language is scaffolded: each has its catalogue, with a slot for every string.
  2. A development build requires every string to be present in en-GB, fr-FR and pt-PT. A draft counts.
  3. A release requires every string to be present in the languages selected for that release. A draft counts.
  4. 0.4.0 requires no additional languages.
  5. 0.5.0 additionally requires fr-CA and en-CA; then, eventually, any language of the European continent still missing (Russian excepted); and, eventually, Chinese and Arabic, which may move to 0.6.0 if the load on 0.5.0 becomes too great.

Settled the same day:

  • Chinese is both: simplified and traditional, two catalogues (zh-Hans, zh-Hant).
  • "European" means the continent, not the European Union. Turkish and Icelandic count, and are already carried: the 39 started catalogues are the Union's 23 beside the source, the 15 from the rest of the continent that came with 0.3.0, and pt-BR.
  • Every component moves with the core. The plugins and the extensions are held to the same languages as the core release they ship beside. Each has its own issue, listed at the end.

What the code does today

  • No test holds fr-FR and pt-PT complete on a commit. It is a convention.
  • pt-BR is held complete on every commit, by tests/test_language_variants.py::test_every_string_came_across. The decision does not ask that of a development build.
  • The release gate is a fixed list. tests/test_translations.py::test_every_european_union_language_stays_complete (marked release) holds the 24 languages of the European Union, the tuple EUROPEAN_UNION in the test. The 15 other European catalogues and pt-BR are not held by anything at a release, which is the "just the European Union" the maintainer ruled out.
  • 68 catalogues exist: 39 started and 29 scaffolded and empty (the African set of #70). Nothing exists for Russian, Chinese, Hindi, Japanese and the rest, for fr-CA or en-CA, or for the PALOP languages #101 lists as missing.
  • Offering is separate and stays so: accounts/forms.py::language_choices offers a language only once somebody has started it, so a scaffolded catalogue is invisible.

What to build

  1. One list of the languages each release selects, kept in one place and readable by the plugin repositories through postulo.core.messages_tool, which they already depend on. 0.4.0 selects the European set carried today (the 39), nothing added; 0.5.0 adds what the decision names, as #269 fills it in.
  2. The development gate: a test on every commit that every string, in every catalogue set (Postulo's own and each bundled plugin's), is present in fr-FR and pt-PT. en-GB is the source. Drafts count.
  3. The release gate reads the list from point 1 instead of EUROPEAN_UNION, and pt-BR's completeness moves from every commit to the release it is selected for. CONTRIBUTING.md § Making a release and scripts/release_tools.py name the same list.
  4. Scaffold every language: a catalogue and a name in core/languages.py for each language Postulo means to carry, with the right plural rule (nplurals=1 for Chinese, six forms for Arabic), written by scripts/messages.py extract like the others. Variants are seeded from their sibling and flagged draft, as pt-BR was from pt-PT (#110): fr-CA from fr-FR, en-CA from en-GB.
  5. docs/TRANSLATING.md states the five points in place of its table of phases by release.

Done when

  • A commit that adds a string without its fr-FR and pt-PT translation fails the suite; one that leaves pt-BR or any other language without it does not.
  • uv run pytest -m release fails when a language selected for the version being released lacks a string, in any catalogue set, and passes however empty a language that is not selected may be.
  • The selected languages of a release are written once, and the gate, the release tool, the handbook and the plugin repositories all read that one list.
  • Every language Postulo means to carry has a catalogue; none is offered until it is started.

The other components

Language-wise they move with the core, each under its own issue:
postulo/postulo-apprise#7, postulo/postulo-dav#16, postulo/postulo-imap#5, postulo/postulo-paperless#7, postulo/postulo-helloworld#6, postulo/postulo-firefox#5, and the issues that already covered it: postulo/postulo-chromium#10, postulo/postulo-thunderbird#7, postulo/postulo-templates#7. postulo-mcp is English only by decision and carries no catalogues, so nothing changes there.

This is the work the maintainer's final decision on translations (2026-10-01) implies for the core. The decision is recorded on #269 and #72; this issue is where it is built. Which languages 0.5.0 adds is #269's subject; the spelling of their codes is #337's. ## The decision 1. **Every language is scaffolded**: each has its catalogue, with a slot for every string. 2. **A development build** requires every string to be present in **en-GB, fr-FR and pt-PT**. A draft counts. 3. **A release** requires every string to be present in **the languages selected for that release**. A draft counts. 4. **0.4.0** requires no additional languages. 5. **0.5.0** additionally requires **fr-CA** and **en-CA**; then, eventually, any language of the **European continent** still missing (Russian excepted); and, eventually, **Chinese** and **Arabic**, which may move to 0.6.0 if the load on 0.5.0 becomes too great. Settled the same day: - **Chinese is both**: simplified and traditional, two catalogues (`zh-Hans`, `zh-Hant`). - **"European" means the continent, not the European Union.** Turkish and Icelandic count, and are already carried: the 39 started catalogues are the Union's 23 beside the source, the 15 from the rest of the continent that came with 0.3.0, and pt-BR. - **Every component moves with the core.** The plugins and the extensions are held to the same languages as the core release they ship beside. Each has its own issue, listed at the end. ## What the code does today - **No test holds fr-FR and pt-PT complete on a commit.** It is a convention. - **pt-BR is held complete on every commit**, by `tests/test_language_variants.py::test_every_string_came_across`. The decision does not ask that of a development build. - **The release gate is a fixed list.** `tests/test_translations.py::test_every_european_union_language_stays_complete` (marked `release`) holds the 24 languages of the European Union, the tuple `EUROPEAN_UNION` in the test. The 15 other European catalogues and pt-BR are not held by anything at a release, which is the "just the European Union" the maintainer ruled out. - **68 catalogues exist**: 39 started and 29 scaffolded and empty (the African set of #70). Nothing exists for Russian, Chinese, Hindi, Japanese and the rest, for fr-CA or en-CA, or for the PALOP languages #101 lists as missing. - **Offering is separate and stays so**: `accounts/forms.py::language_choices` offers a language only once somebody has started it, so a scaffolded catalogue is invisible. ## What to build 1. **One list of the languages each release selects**, kept in one place and readable by the plugin repositories through `postulo.core.messages_tool`, which they already depend on. 0.4.0 selects the European set carried today (the 39), nothing added; 0.5.0 adds what the decision names, as #269 fills it in. 2. **The development gate**: a test on every commit that every string, in every catalogue set (Postulo's own and each bundled plugin's), is present in fr-FR and pt-PT. en-GB is the source. Drafts count. 3. **The release gate** reads the list from point 1 instead of `EUROPEAN_UNION`, and pt-BR's completeness moves from every commit to the release it is selected for. `CONTRIBUTING.md` § *Making a release* and `scripts/release_tools.py` name the same list. 4. **Scaffold every language**: a catalogue and a name in `core/languages.py` for each language Postulo means to carry, with the right plural rule (`nplurals=1` for Chinese, six forms for Arabic), written by `scripts/messages.py extract` like the others. Variants are seeded from their sibling and flagged `draft`, as pt-BR was from pt-PT (#110): fr-CA from fr-FR, en-CA from en-GB. 5. **`docs/TRANSLATING.md`** states the five points in place of its table of phases by release. ## Done when - A commit that adds a string without its fr-FR and pt-PT translation fails the suite; one that leaves pt-BR or any other language without it does not. - `uv run pytest -m release` fails when a language selected for the version being released lacks a string, in any catalogue set, and passes however empty a language that is not selected may be. - The selected languages of a release are written once, and the gate, the release tool, the handbook and the plugin repositories all read that one list. - Every language Postulo means to carry has a catalogue; none is offered until it is started. ## The other components Language-wise they move with the core, each under its own issue: postulo/postulo-apprise#7, postulo/postulo-dav#16, postulo/postulo-imap#5, postulo/postulo-paperless#7, postulo/postulo-helloworld#6, postulo/postulo-firefox#5, and the issues that already covered it: postulo/postulo-chromium#10, postulo/postulo-thunderbird#7, postulo/postulo-templates#7. postulo-mcp is English only by decision and carries no catalogues, so nothing changes there.
tiagoagueda added this to the 0.5.0 milestone 2026-10-01 10:06:12 +00:00
Author
Owner

The development gate follows #706's rule, decided 2026-10-10: translations are made in Weblate only, so a commit adds a string with its slots empty and cannot carry fr-FR and pt-PT itself. Weblate drafts the new string by machine (LibreTranslate, needs editing) and brings it in with its pull request from the weblate branch; the gate is held there, in CI: scripts/messages.py gate fr-FR pt-PT on a pull request whose head is weblate (e014152fc), a draft counting. Between the commit and that pull request a development build shows the new string in English. The release gate (pytest -m release) is unchanged. docs/TRANSLATING.md states the five points of this issue in place of the table of phases (925e3e9cd).

The development gate follows #706's rule, decided 2026-10-10: translations are made in Weblate only, so a commit adds a string with its slots empty and cannot carry fr-FR and pt-PT itself. Weblate drafts the new string by machine (LibreTranslate, *needs editing*) and brings it in with its pull request from the `weblate` branch; the gate is held there, in CI: `scripts/messages.py gate fr-FR pt-PT` on a pull request whose head is `weblate` (e014152fc), a draft counting. Between the commit and that pull request a development build shows the new string in English. The release gate (`pytest -m release`) is unchanged. docs/TRANSLATING.md states the five points of this issue in place of the table of phases (925e3e9cd).
tiagoagueda referenced this issue from a commit 2026-11-01 00:33:52 +00:00
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
Postulo/postulo#347
No description provided.