Skip to content

Translate ticket and branch notices and input errors - #644

Open
ryanwelcher wants to merge 3 commits into
trunkfrom
fix/629-ticket-and-branch-strings
Open

ryanwelcher wants to merge 3 commits into
trunkfrom
fix/629-ticket-and-branch-strings

Conversation

@ryanwelcher

@ryanwelcher ryanwelcher commented Oct 6, 2026 •

Copy link
Copy Markdown
Collaborator

Why

The ticket card's questions and notices, the merge-in-progress and legacy-site notices, the deep-link banners, the folder-open failures, and the input errors for a ticket or issue number were plain English in a translated window. This is the #629 batch of #622, and needed the catalog in main from #634.

What changes

  • Whole sentences, per kind. Every sentence that spliced in a noun (ticket/issue), an English article, or a count is now one string per kind of work item, with _n for counts. This covers the dirty-trunk question (ticket-actions.cjs), the trunk-moved notice and the move's refusals (ticket-trunk-notice.cjs), the changes note (changes-note.cjs), and the carried-work notice in index.jsx.
  • The changes note used to be lead / link / middle / link / end. It is now one sentence per case with <review> and <discard> marked in it, filled in by createInterpolateElement. DiscardChangesLink takes its words as children for that.
  • Constants became functions: LEGACY_SITE_ERROR → legacySiteError(), DISCARD_CONFIRM_MESSAGE → discardConfirmMessage(), and the merge kinds table → kindWords(kind). Git commands go in as %s; the "resolve the files, then git add them and run %s" frame and the <every file the patch touched…> placeholder are wrapped.
  • Main process: the ticket and issue parsers' refusals (main returns them), the ticket-branches.js errors that reach res.error, the rebase handler's three refusals and the dirty-trunk error in main.js, and the editor's exit-code error in editor-launch.js.
  • @wordpress/element becomes a direct dependency, the same line Translate the Review & submit dialog #635 and Translate the pull request destination and GitHub sign-in #643 add.

Not wrapped, per #622: the WIP commit message, which leaves the app.

How to test this

The new journeys in tests/e2e/journeys/i18n.spec.js walk every state #629 lists, in the pseudo-locale. Run them from the repository root on either platform:

npx playwright test --project=journeys tests/e2e/journeys/i18n.spec.js -g "ticket card's questions|ticket from a link|merge left open|folder will not open"

All five fail without this change (checked by putting trunk's src/ back and rebuilding). They cover: a refused ticket number; loose edits on trunk and the question about them; both discard confirmations (read from window.confirm, since Electron's are not Playwright dialogs); the carried notice and the changes note with its two links; a parked ticket whose trunk moved; edits saved before a clean start; a deep link with no site, on a Core site and on a Gutenberg site; a merge left open by a terminal; a legacy site; and editor:open and dir:show stubbed to return each reason.

What the journeys cannot reach: the main-process refusals that need a real Git failure (the move's conflict, "No such branch", a second branch for the same issue) and the editor's exit code. Unit tests add the pseudo-locale filter and check those: ticket-branches.integration, editor-launch, trac-ticket, github-issue, merge-in-progress, legacy-site and ticket-trunk-notice.

To see the card by hand (either platform, current head):

  1. From the repository root, run npx electron . --lang=en-XA.
  2. Open a Core site on trunk, edit src/wp-login.php, type a ticket number in the ticket field and click Link ticket.
    • Expected: the question and its four buttons are accented and in brackets.
  3. Click the button that takes the edits into the ticket.
    • Expected: the carried notice and the changes note under the ticket are accented and in brackets. The note's two links are accented words inside its sentence.

What must not have happened: no English an English speaker sees has changed. The full journey suite (129, including ticket-branches, ticket-rebase, merge-in-progress, legacy-site, gutenberg-site, site-header, review-changes and trunk-update) passes with its exact English strings, and the unit tests that pin whole English sentences pass unchanged.

Risks and limitations

Related

Fixes #629. Part of #622.


Design decisions and alternatives considered
  • The changes note returns one marked-up string rather than the five parts. The parts fixed English word order around the two links; one sentence with <review> and <discard> lets a translator move them.
  • The Trac and GitHub hosts and the repository go in as %s, as Wrap the rest of the app's strings for translation #622 asks for product names and keys.
  • The merge restore placeholder keeps its angle brackets outside the translated words (<%s>), so the pseudo-locale accents the words and a translator does not have to keep the brackets.
  • The journeys use their own require lines at the end of the file rather than editing the shared one at the top, so they do not conflict with the other batches' edits to it.
Review outcome (required — see AGENTS.md)

1 [fix here] · 1 [follow-up]. The [fix here] is fixed; the follow-up is deferred (see Risks).

  • 🔵 Tests: the issue variants of the dirty-trunk question had no test that pinned them whole. Fixed: tests/unit/ticket-actions.test.cjs now pins each one with an exact assert.equal.

  • 🔵 Architecture, [follow-up]: the carried-work notice's plural is decided in index.jsx. It was decided there before this PR too. Deferred.

  • The reviewer compared old and new output by hand for every module in the diff and found no reachable English change. It noted that the unreachable no-ticket wording of rebaseRefusal changed, which is listed in Risks.

  • Review: completed. Fresh read-only agent context, head 126b51e / base 9fd167e, all 27 files. Before it: npm run lint clean, npm test 2039 pass / 0 fail / 2 skipped, npm run i18n:pot clean with every translator comment in the .pot, full journey suite 129 pass.

  • Since review: 126b51e → 0bb2fa3 added the test for the [fix here] finding. Then 0bb2fa3 → 149ff18, rebased onto trunk at e94f507 (base e94f507) after Translate the Review & submit dialog #635 merged. The rebase resolved two conflicts: changes-note.cjs's @wordpress/i18n import now takes _n alongside Translate the Review & submit dialog #635's __ and sprintf, and the journeys appended to i18n.spec.js now follow Translate the Review & submit dialog #635's, using trunk's gitOk import. The scanner hunk and the @wordpress/element line were already on trunk, so the branch's copies dropped out. Checked by the authoring session, not re-reviewed by a fresh context: npm run lint clean, npm test 2041 pass / 0 fail / 2 skipped, npm run i18n:pot clean, full journey suite 135 pass.

Screenshots or recording

None. Nothing changes on screen in English, and the pseudo-locale journeys are the check for the translated state.

🤖 Generated with Claude Code

@coderabbitai

coderabbitai Bot commented Oct 6, 2026 •

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration
  • Configuration used: Repository: WordPress/contributor-toolkit/.coderabbit.yaml
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 50847494-6091-4016-b362-75d50efefdea

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
  • Autopilot · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

Wraps the ticket card's questions and notices, the changes note, the
merge-in-progress and legacy-site notices, the deep-link banners, the
folder-open failures, the ticket and issue parsers' refusals, and the
ticket-branch errors main returns. Sentences that spliced a noun or a
count are now whole strings per kind, with _n for counts; the changes
note is one createInterpolateElement sentence per case.

Fixes #629.
@ryanwelcher
ryanwelcher force-pushed the fix/629-ticket-and-branch-strings branch from 0bb2fa3 to 149ff18 Compare October 6, 2026 19:03
ryanwelcher added a commit that referenced this pull request Oct 6, 2026
## Why

The Open a pull request card, its GitHub sign-in, and the errors main
sends it were plain English in a translated window. This is the #625
batch of #622, which needed the catalog in main from #634.

## What changes

- **The card** (`pull-request-destination.jsx`) wraps every string.
Sentences with a link or code in them use `createInterpolateElement`,
with logins, branches and repository names passed in as elements so they
are never read as markup. The failure messages are a function instead of
a module-level constant.
- **Per-project text** in `project-type.cjs` (`cards.*`) is getters,
read when the card renders. Main's refusal with nothing linked used to
splice the work item's label into a sentence; it is now
`cards.prNeedsWorkItem`, one sentence per project type.
- **Main process:** the sign-in errors in `github-auth.cjs` and the pull
request errors in `github-pr.cjs` are wrapped, including the step labels
passed to `failure()`, which the issue did not list. The "Trunk has
moved" message uses `_n`, and a GitHub failure is composed with `%1$s:
%2$s%3$s` so a translator can change the punctuation. GitHub's own
reason and the bracketed diagnostic for GitHub support stay as they are.

Not wrapped, per #622: the pull request body and the default pull
request title, because they leave the app.

## How to test this

The new journeys cover the card in the pseudo-locale on both projects.
Run them from the repository root on either platform:

```
npx playwright test --project=journeys tests/e2e/journeys/i18n.spec.js -g "pull request card"
```

Both fail without this change. The Core journey walks every state #625
lists: signed out, "Not now" and "Show this again", the device code,
signed in with the form and its fold, a `rate-limited` failure, a dry
run, and a pull request opened from a checkout behind trunk. The
Gutenberg one walks signed out, signed in with the fold open, and the
opened pull request, checking the words that are Gutenberg's own.

What the journeys cannot reach is a real GitHub. They stub every
`github:*` handler, so the main-process errors never reach the screen in
them. Unit tests in `github-auth`, `github-pr` and `pr-stage` cover
those strings in the pseudo-locale instead. To see one on screen by hand
(either platform, current head):

1. From the repository root, run `npx electron . --lang=en-XA`.
2. Open a Core site with a linked ticket and an edit, and click **Review
& submit changes**.
3. In **Open a pull request**, click **Sign in with GitHub** and finish
in the browser.
- Expected: every line of the card is accented and in brackets, apart
from your login, your fork's name, the code and the branch.

**What must not have happened:** no English an English speaker sees has
changed. The English journeys in `open-pull-request.spec.js`,
`review-changes.spec.js` and `pr-checkout.spec.js` still pass with their
exact strings.

## Risks and limitations

- The other open batches (#636, #644, #645, #646) also append tests to
the end of `i18n.spec.js`, so whichever merges later resolves that by
keeping both.
- One finding is deferred: `prFailureMessage` decides between five
user-facing strings inside a `.jsx` file the suite cannot load. It
predates this PR (it was the old constant map), so moving it to a `.cjs`
module with a test is a follow-up.

## Related

Fixes #625. Part of #622. Follows #634.

---

<details>
<summary>Design decisions and alternatives considered</summary>

- **Not stacked on #635.** #622 asks for batches that review on their
own. Now that #635 has merged, its `unwrapped()` scanner change and the
`@wordpress/element` dependency, which this PR also needed, come from
trunk.
- **The textarea placeholder** is three strings joined with a newline. A
single `__()` with `\n` in it is refused by
`@wordpress/i18n-no-collapsible-whitespace`.
- **"Signed in as …"** is wrapped in its own `<span>`, so the sentence
and the **Sign out** button beside it are separate elements, as in #635.

</details>

<details>
<summary>Review outcome (required — see AGENTS.md)</summary>

2 [fix here] · 1 [follow-up]. Both [fix here] findings are fixed; the
follow-up is deferred (see Risks).

- 🟡 The Gutenberg journey linked no issue, so it never showed the form,
the fold or the loop-back. Fixed: it links one in the record and walks
those states.
- 🔵 No test showed the main-process strings or the stage labels come out
translated. Fixed: pseudo-locale unit tests for the scope refusal, a
composed `failure()`, the plural stale message and `prStageLabel`.
- Style: three dead entries in the journey's `THEIRS` filter were
removed.

- **Review:** completed. Fresh agent context, head `11ef362` / base
`c34aa45`. `npm run lint` clean, `npm test` 2002 pass / 0 fail, i18n and
PR journeys 25 pass.
- **Since review:** `11ef362 → ef457fd`. The only change is the test
fixes above, checked by the authoring session, not re-reviewed by a
fresh context. `src` and `tests` lint clean, unit suite 2005 pass / 0
fail, i18n journeys 12 pass. The review did not run the journeys itself;
it was read-only.
- **After #635 merged:** `ef457fd → 9559a1f` (trunk merged from GitHub)
→ `012fca8` (trunk at `e94f507` merged; `i18n.spec.js` resolved as
trunk's file plus this PR's two tests, nothing else changed). Checked by
the authoring session, not re-reviewed: `src` and `tests` lint clean,
unit suite 2036 pass / 0 fail, i18n, open-pull-request, review-changes
and pr-checkout journeys 31 pass.

</details>

<details>
<summary>Screenshots or recording</summary>

None. Nothing changes on screen in English, and the pseudo-locale
journeys are the check for the translated state.

</details>

🤖 Generated with [Claude Code](https://claude.com/claude-code)
…ranch-strings

# Conflicts:
#	tests/e2e/journeys/i18n.spec.js

This branch has not been deployed

No deployments
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.

Translate ticket and branch notices and input errors

1 participant