This is an automated email from the ASF dual-hosted git repository.
morningman pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/doris-website.git
The following commit(s) were added to refs/heads/master by this push:
new d0a4611beb5 [i18n] Default manual Korean runs to generate and name the
LLM in the translation notice (#4414)
d0a4611beb5 is described below
commit d0a4611beb51ee4fbbfd579c7782ef77fda65e15
Author: Mingyu Chen (Rayner) <[email protected]>
AuthorDate: Wed Oct 21 07:49:24 2026 +0100
[i18n] Default manual Korean runs to generate and name the LLM in the
translation notice (#4414)
## Why
Two small follow-ups to the translation work:
- Manual runs of the Korean translation workflow defaulted to `dry-run`,
while the Japanese workflow defaults to `generate`. The Korean default
dates from when Korean generation was manual-only. Korean runs have been
scheduled since #4409, so both workflows now use the same default: a
manual run started without changing the mode generates, like a scheduled
run.
- The notice on translated docs pages said the page was machine
translated. These pages are translated by a large language model, and
the notice now says so.
## What changed
### 1. Manual Korean runs generate by default
- `korean-translation.yml`: the manual `mode` input defaults to
`generate`. `dry-run` and `validate` can still be selected. Scheduled
runs are unchanged.
- `translation-workflows.test.cjs`: the contract test now requires both
workflows to default to `generate` and checks that the default passes
the generation gate. A run with `dry-run` selected still never reaches
the generator.
- `translations/README.md`: updated the two sentences that described the
Korean `dry-run` default.
### 2. The translated-page notice names the large language model
`docs.translation.machine` is the notice on Japanese and Korean docs
pages whose translation is current and has not been reviewed by a
person.
| Locale | Before | After |
| --- | --- | --- |
| English default | This page is machine translated. | This page was
translated by a large language model (LLM). |
| Japanese | このページは機械翻訳されています。 | このページは大規模言語モデル(LLM)によって翻訳されています。 |
| Korean | 이 페이지는 기계 번역되었습니다. | 이 페이지는 대규모 언어 모델(LLM)로 번역되었습니다. |
A locale without its own entry would show the English default; English
pages have no notice. The other notices (reviewed by a person, stale,
not translated, unverified) are unchanged.
## Effect
- A Korean run started from the Actions page without changing the mode
now generates a batch when pages are pending. It calls the model and
opens a labeled PR for review, as a Japanese manual run does. Nothing is
merged automatically. For a read-only check, select `dry-run` (or pass
`-f mode=dry-run`).
- After the next deployment, every machine-translated Japanese and
Korean docs page shows the new notice.
The lock and triggers are unchanged, and a run already in progress keeps
the workflow definition it started with, so this can be merged at any
time.
## Verification
- All 21 translation test suites in Build Check pass on Node 20.20.2
(193 tests), and so do the publish suite and `state.test.cjs`, which
reads both dictionaries.
- Restoring the `dry-run` default makes two contract tests fail.
- `check-configuration --all` passes. The Japanese and Korean
translation gates (`check-translations --base 82ccae8`) report no errors
or warnings.
- The longer default message is wrapped to stay within the 120-column
Prettier width.
- actionlint 1.7.12 reports nothing new. The two remaining findings, the
`queue` concurrency key and `actions/setup-python@v4`, also exist on
master.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
---------
Co-authored-by: morningman <[email protected]>
Co-authored-by: Claude Opus 5.5 (1M context) <[email protected]>
---
.github/workflows/korean-translation.yml | 5 ++---
i18n/ja/code.json | 2 +-
i18n/ko/code.json | 2 +-
scripts/i18n/__tests__/translation-workflows.test.cjs | 18 +++++++++++-------
src/theme/DocItem/Layout/TranslationStatus.tsx | 3 ++-
translations/README.md | 7 ++++---
6 files changed, 21 insertions(+), 16 deletions(-)
diff --git a/.github/workflows/korean-translation.yml
b/.github/workflows/korean-translation.yml
index ac0e425fc9d..2b764f57548 100644
--- a/.github/workflows/korean-translation.yml
+++ b/.github/workflows/korean-translation.yml
@@ -7,7 +7,7 @@ on:
description: Read-only dry run, one-page live validation, or batch
generation
type: choice
options: [dry-run, validate, generate]
- default: dry-run
+ default: generate
required: true
plugin:
description: Optional plugin filter (default or community)
@@ -44,8 +44,7 @@ jobs:
with:
locale: ko
workspace: korean-translation
- # Scheduled runs have no inputs and generate; manual runs keep the
- # dry-run default.
+ # Scheduled runs have no inputs and generate.
mode: ${{ inputs.mode || 'generate' }}
plugin: ${{ inputs.plugin }}
version: ${{ inputs.version }}
diff --git a/i18n/ja/code.json b/i18n/ja/code.json
index 7376ac3ee05..1aba74c3108 100644
--- a/i18n/ja/code.json
+++ b/i18n/ja/code.json
@@ -1064,7 +1064,7 @@
"message": "この日本語訳は人が校正しています。"
},
"docs.translation.machine": {
- "message": "このページは機械翻訳されています。"
+ "message": "このページは大規模言語モデル(LLM)によって翻訳されています。"
},
"docs.translation.translatedAt": {
"message": "翻訳日: "
diff --git a/i18n/ko/code.json b/i18n/ko/code.json
index dd23048f93a..21b758741ae 100644
--- a/i18n/ko/code.json
+++ b/i18n/ko/code.json
@@ -30,7 +30,7 @@
"message": "사람이 교정한 한국어 번역입니다."
},
"docs.translation.machine": {
- "message": "이 페이지는 기계 번역되었습니다."
+ "message": "이 페이지는 대규모 언어 모델(LLM)로 번역되었습니다."
},
"docs.translation.translatedAt": {
"message": "번역일: "
diff --git a/scripts/i18n/__tests__/translation-workflows.test.cjs
b/scripts/i18n/__tests__/translation-workflows.test.cjs
index cb5255a9cd7..06ef5e1d866 100644
--- a/scripts/i18n/__tests__/translation-workflows.test.cjs
+++ b/scripts/i18n/__tests__/translation-workflows.test.cjs
@@ -15,7 +15,8 @@ const russian = load('russian-translation.yml');
test('Russian discovery is manual only and uses the shared run, lock and
explicit secrets', () => {
assert.deepEqual(Object.keys(russian.on), ['workflow_dispatch']);
const inputs = russian.on.workflow_dispatch.inputs;
- assert.deepEqual(inputs, callers.ko.on.workflow_dispatch.inputs);
+ const koreanInputs = callers.ko.on.workflow_dispatch.inputs;
+ assert.deepEqual(inputs, {...koreanInputs, mode: {...koreanInputs.mode,
default: 'dry-run'}});
assert.deepEqual(russian.permissions, shared.permissions);
for (const workflow of Object.values(callers))
assert.deepEqual(russian.concurrency, workflow.concurrency);
assert.deepEqual(Object.keys(russian.jobs), ['translation']);
@@ -44,9 +45,9 @@ test('one-page validation rejects an exact batch list before
creating scan artif
test('each language workflow passes one fixed locale to the shared run under
one lock', () => {
const expected = {
- ja: {workspace: 'japanese-translation', mode: 'generate', cron: '23
4,16 * * *'},
+ ja: {workspace: 'japanese-translation', cron: '23 4,16 * * *'},
// Twenty minutes later; the shared lock queues it behind a Japanese
run.
- ko: {workspace: 'korean-translation', mode: 'dry-run', cron: '43 4,16
* * *'},
+ ko: {workspace: 'korean-translation', cron: '43 4,16 * * *'},
};
for (const [locale, workflow] of Object.entries(callers)) {
assert.deepEqual(Object.keys(workflow.on), ['workflow_dispatch',
'schedule']);
@@ -54,7 +55,8 @@ test('each language workflow passes one fixed locale to the
shared run under one
const inputs = workflow.on.workflow_dispatch.inputs;
// No locale input: each workflow runs only its own language.
assert.deepEqual(Object.keys(inputs), ['mode', 'plugin', 'version',
'path', 'paths']);
- assert.equal(inputs.mode.default, expected[locale].mode);
+ // Manual runs generate by default, like scheduled ones; dry-run stays
selectable.
+ assert.equal(inputs.mode.default, 'generate');
assert.deepEqual(inputs.mode.options, ['dry-run', 'validate',
'generate']);
assert.deepEqual(workflow.permissions, {'contents': 'read',
'pull-requests': 'read'});
assert.deepEqual(workflow.concurrency, {group: 'docs-translation',
'cancel-in-progress': false, queue: 'max'});
@@ -69,15 +71,17 @@ test('each language workflow passes one fixed locale to the
shared run under one
}
});
-test('a scheduled run resolves to a mode that the generation gate accepts', ()
=> {
+test('scheduled and default manual runs resolve to a mode that the generation
gate accepts', () => {
// Discovery marks every scheduled run eligible, so the input-less fallback
// must be a mode that workflow-generate.cjs will run, not a dry run.
for (const workflow of Object.values(callers)) {
const fallback = /\|\| '([a-z-]+)'
\}\}$/.exec(workflow.jobs.translation.with.mode)[1];
assert.equal(allowGeneration({I18N_MODE: fallback, GITHUB_EVENT_NAME:
'schedule', I18N_MAX_PAGES: '10'}), true);
+ assert.equal(allowGeneration({I18N_MODE:
workflow.on.workflow_dispatch.inputs.mode.default,
+ GITHUB_EVENT_NAME: 'workflow_dispatch', I18N_MAX_PAGES: '10'}),
true);
}
- assert.equal(allowGeneration({I18N_MODE:
callers.ko.on.workflow_dispatch.inputs.mode.default,
- GITHUB_EVENT_NAME: 'workflow_dispatch', I18N_MAX_PAGES: '10'}), false);
+ // Choosing dry-run by hand still never reaches the generator.
+ assert.equal(allowGeneration({I18N_MODE: 'dry-run', GITHUB_EVENT_NAME:
'workflow_dispatch', I18N_MAX_PAGES: '10'}), false);
});
test('the shared run names no language and sets mode and filters once', () => {
diff --git a/src/theme/DocItem/Layout/TranslationStatus.tsx
b/src/theme/DocItem/Layout/TranslationStatus.tsx
index 3f2e6ecfe69..f2cd8dff068 100644
--- a/src/theme/DocItem/Layout/TranslationStatus.tsx
+++ b/src/theme/DocItem/Layout/TranslationStatus.tsx
@@ -27,7 +27,8 @@ function description(state: TranslationState): string {
message: 'The translation does not reflect the latest changes to the
source.'});
return state.reviewStatus === 'human'
? translate({id: 'docs.translation.reviewedHuman', message: 'This
translation was reviewed by a person.'})
- : translate({id: 'docs.translation.machine', message: 'This page is
machine translated.'});
+ : translate({id: 'docs.translation.machine',
+ message: 'This page was translated by a large language model
(LLM).'});
}
export default function TranslationStatus({state}: {state: TranslationState}):
JSX.Element {
diff --git a/translations/README.md b/translations/README.md
index 8e05c7346de..c92e45a575a 100644
--- a/translations/README.md
+++ b/translations/README.md
@@ -192,8 +192,8 @@ batch when eligible Korean documents are pending, with the
same limits as a
manual `generate` run: the planner considers at most 20 targets and a batch has
at most 10 pages. It opens a normal labeled PR that maintainers review and
merge
like any other; nothing is merged automatically. With nothing pending, a
-scheduled run only scans and makes no model call. Manual dispatch defaults to a
-read-only dry run. To run discovery on master:
+scheduled run only scans and makes no model call. Manual dispatch also defaults
+to `generate`; choose `dry-run` for read-only discovery on master:
```bash
gh workflow run korean-translation.yml --repo apache/doris-website --ref
master -f mode=dry-run
@@ -571,7 +571,8 @@ attention and neither closes nor overwrites the existing
PR. A PR whose
candidate cannot be verified blocks that target from robot generation and
appears in the exception report.
-Japanese manual dispatch defaults to `generate` (Korean and Russian to
`dry-run`) and
+Japanese and Korean manual dispatch default to `generate`; Russian defaults to
+`dry-run`. Each workflow
accepts optional plugin, version and source path prefix filters, or an exact
`paths` list. `validate` mode requires one exact English source path
ending in `.md` or `.mdx`; it can call the model and create a regular PR for
one
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]