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 4f34d6b3219 fix(i18n): control translation generation through workflow
mode (#4338)
4f34d6b3219 is described below
commit 4f34d6b3219a13ad1bb82c044ae97feeed0f8310
Author: Mingyu Chen (Rayner) <[email protected]>
AuthorDate: Fri Oct 16 17:37:51 2026 +0100
fix(i18n): control translation generation through workflow mode (#4338)
Manual `generate` runs currently complete discovery but skip translation
and PR creation unless two repository variables are enabled. Remove both
variable gates so manual runs follow the selected mode and scheduled
runs generate pending batches automatically.
Use `I18N_MODE` consistently in the workflow, generator and local
simulator. Keep read-only `dry-run` behavior, the one-page `validate`
constraints, credential checks and existing batch limits. Update the
operating instructions and regression tests.
## Validation
- `node --test scripts/i18n/__tests__/*.test.cjs
scripts/i18n/poc/*.test.cjs`: 122 passed.
- JavaScript syntax checks and workflow YAML/mode wiring checks passed.
- `git diff --check` passed; removed switches have no remaining tracked
references.
- Live model calls and the master-only workflow were not run locally.
## Versions
- [ ] dev
- [ ] 4.x
- [ ] 3.x
- [ ] 2.1 or older (not covered by version/language sync gate)
This change affects shared CI and internal operating instructions.
Product documentation, page paths, anchors, navigation and
versioned/localized counterparts are unaffected.
## Languages
- [ ] Chinese
- [x] English
## Docs Checklist
- [x] Checked by AI
- [x] Test Cases Built
- [x] Updated required version and language counterparts, or explained
why not
- [x] If only one language changed, confirmed whether source/translation
counterparts need sync
Self-review found no additional issues. The diff is limited to mode
selection and related documentation/tests, preserves the existing
master-only manual/scheduled triggers and permissions, and does not
change frontend behavior.
Co-authored-by: morningman <[email protected]>
---
.github/workflows/japanese-translation.yml | 8 +++-----
scripts/i18n/__tests__/workflow.test.cjs | 18 ++++++++++++++----
scripts/i18n/simulate-workflow.cjs | 2 +-
scripts/i18n/workflow-generate.cjs | 12 ++++++------
translations/README.md | 22 +++++++++++-----------
5 files changed, 35 insertions(+), 27 deletions(-)
diff --git a/.github/workflows/japanese-translation.yml
b/.github/workflows/japanese-translation.yml
index 37c66792004..38190444727 100644
--- a/.github/workflows/japanese-translation.yml
+++ b/.github/workflows/japanese-translation.yml
@@ -4,7 +4,7 @@ on:
workflow_dispatch:
inputs:
mode:
- description: Read-only dry run, one-page live validation, or enabled
batch
+ description: Read-only dry run, one-page live validation, or batch
generation
type: choice
options: [dry-run, validate, generate]
default: generate
@@ -82,7 +82,7 @@ jobs:
needs: discover
env:
I18N_LOCALE: ${{ inputs.locale }}
- if: needs.discover.outputs.can_generate == 'true' && ((github.event_name
== 'workflow_dispatch' && inputs.mode == 'validate') ||
(vars.I18N_AUTO_TRANSLATE_ENABLED == 'true' && vars.I18N_LIVE_VERIFIED ==
'true'))
+ if: needs.discover.outputs.can_generate == 'true'
runs-on: ubuntu-latest
timeout-minutes: 45
steps:
@@ -184,9 +184,7 @@ jobs:
id: translation
env:
I18N_CODEX_MODEL: ${{ vars.I18N_CODEX_MODEL || 'gpt-6-sol' }}
- I18N_AUTO_TRANSLATE_ENABLED: ${{ vars.I18N_AUTO_TRANSLATE_ENABLED }}
- I18N_LIVE_VERIFIED: ${{ vars.I18N_LIVE_VERIFIED }}
- I18N_VALIDATION_RUN: ${{ github.event_name == 'workflow_dispatch' &&
inputs.mode == 'validate' }}
+ I18N_MODE: ${{ inputs.mode || 'generate' }}
I18N_PATH: ${{ inputs.path }}
I18N_MAX_PAGES: ${{ inputs.mode == 'validate' && '1' || '10' }}
GITHUB_REPOSITORY: ${{ github.repository }}
diff --git a/scripts/i18n/__tests__/workflow.test.cjs
b/scripts/i18n/__tests__/workflow.test.cjs
index 80f443034c3..4c8342064a4 100644
--- a/scripts/i18n/__tests__/workflow.test.cjs
+++ b/scripts/i18n/__tests__/workflow.test.cjs
@@ -130,15 +130,25 @@ test('human maintained pages are excluded from automatic
generation', () => {
assert.equal(machineOwned(task, {data: {pages: [{...task, ownership:
'human'}]}}), false);
});
-test('one-page validation can bootstrap without enabling ongoing automation',
() => {
- const request = {I18N_VALIDATION_RUN: 'true', GITHUB_EVENT_NAME:
'workflow_dispatch',
+test('one-page validation requires a manual run, exact source path and
one-page limit', () => {
+ const request = {I18N_MODE: 'validate', GITHUB_EVENT_NAME:
'workflow_dispatch',
I18N_PATH: 'docs/guide.md', I18N_MAX_PAGES: '1'};
assert.equal(allowGeneration(request), true);
assert.equal(allowGeneration({...request, I18N_MAX_PAGES: '4'}), false);
assert.equal(allowGeneration({...request, GITHUB_EVENT_NAME: 'push'}),
false);
assert.equal(allowGeneration({...request, I18N_PATH: ''}), false);
- assert.equal(allowGeneration({I18N_AUTO_TRANSLATE_ENABLED: 'true'}),
false);
- assert.equal(allowGeneration({I18N_AUTO_TRANSLATE_ENABLED: 'true',
I18N_LIVE_VERIFIED: 'true'}), true);
+});
+
+test('generate mode runs manually and on schedule without enablement
variables', () => {
+ for (const event of ['workflow_dispatch', 'schedule']) {
+ assert.equal(allowGeneration({I18N_MODE: 'generate',
GITHUB_EVENT_NAME: event}), true);
+ }
+});
+
+test('dry-run, unknown and missing modes cannot call the generator', () => {
+ for (const mode of ['dry-run', 'unknown', undefined]) {
+ assert.equal(allowGeneration({I18N_MODE: mode}), false);
+ }
});
test('push eligibility follows current native identities and relevant rules',
() => {
diff --git a/scripts/i18n/simulate-workflow.cjs
b/scripts/i18n/simulate-workflow.cjs
index 359e14c1092..849d1f35404 100644
--- a/scripts/i18n/simulate-workflow.cjs
+++ b/scripts/i18n/simulate-workflow.cjs
@@ -108,7 +108,7 @@ function main() {
const env = {...process.env, PATH: `${bin}:${process.env.PATH}`, GH_TOKEN:
'local-simulation',
GITHUB_REPOSITORY: 'apache/doris-website', GITHUB_EVENT_NAME:
'workflow_dispatch',
GITHUB_RUN_ID: runId, I18N_PR_AUTH_KIND: 'pat', I18N_MODE: 'validate',
- I18N_VALIDATION_RUN: 'true', I18N_PATH: sourcePath, I18N_MAX_PAGES:
'1',
+ I18N_PATH: sourcePath, I18N_MAX_PAGES: '1',
I18N_LIMIT: '20', DORIS_ENABLE_JA: 'true', CODEX_HOME: auth,
I18N_SIM_PR_RECORD: path.join(output, 'pull-request.json')};
runNode(repo, 'scripts/i18n/workflow-prs.cjs', [scan], env, logs);
diff --git a/scripts/i18n/workflow-generate.cjs
b/scripts/i18n/workflow-generate.cjs
index 7ccb6ec49d2..1b64d8cb684 100644
--- a/scripts/i18n/workflow-generate.cjs
+++ b/scripts/i18n/workflow-generate.cjs
@@ -1,4 +1,4 @@
-// Trusted-master automation only. A closed-by-default workflow supplies the
+// Trusted-master automation only. The workflow supplies the requested mode and
// model credential; this module writes only validated managed ja files/state.
const assert = require('node:assert/strict');
const fs = require('node:fs');
@@ -147,19 +147,19 @@ async function generate({plan, reconciliation, maxPages =
10, target,
}
function allowGeneration(env) {
- if (env.I18N_VALIDATION_RUN === 'true') {
+ if (env.I18N_MODE === 'validate') {
return env.GITHUB_EVENT_NAME === 'workflow_dispatch'
&& /\.mdx?$/.test(env.I18N_PATH || '') && env.I18N_MAX_PAGES ===
'1';
}
- return env.I18N_AUTO_TRANSLATE_ENABLED === 'true' &&
env.I18N_LIVE_VERIFIED === 'true';
+ return env.I18N_MODE === 'generate';
}
async function main() {
const output = process.argv[2];
assert(output && process.argv.length === 3, 'Usage: workflow-generate.cjs
<scan-directory>');
- assert(allowGeneration(process.env), 'Live automation is not enabled or
limited validation was not requested');
+ assert(allowGeneration(process.env), 'Generation requires generate mode or
valid one-page validation');
const plan = JSON.parse(fs.readFileSync(path.join(output, 'plan.json'),
'utf8'));
- if (process.env.I18N_VALIDATION_RUN === 'true') {
+ if (process.env.I18N_MODE === 'validate') {
assert(plan.selected.length === 1 && plan.tasks.find(task => task.id
=== plan.selected[0])?.sourcePath === process.env.I18N_PATH,
'Validation mode must select exactly one source file');
}
@@ -179,7 +179,7 @@ async function main() {
+ `${manifest.failures.length} failed or need manual handling. No
translation is merged yet.\n`);
process.stdout.write(JSON.stringify({candidates:
manifest.candidates.length,
failures: manifest.failures.length, usedTokens: manifest.usedTokens})
+ '\n');
- if (process.env.I18N_VALIDATION_RUN === 'true' &&
manifest.candidates.length === 0)
+ if (process.env.I18N_MODE === 'validate' && manifest.candidates.length ===
0)
process.exitCode = 1;
}
diff --git a/translations/README.md b/translations/README.md
index 252cc7f5517..b54056b6848 100644
--- a/translations/README.md
+++ b/translations/README.md
@@ -303,7 +303,7 @@ For offline tests, `--provider mock --mock-file <json>`
maps each masked unit
text to a replacement string and stages a fixture candidate. Mock output cannot
be applied to managed translation files. The offline fixture does not establish
live model quality, latency, cost or availability. A real limited call and
-review are required before T08 enables automatic generation.
+review are recommended before running batch generation.
## Asynchronous Japanese discovery and generation
@@ -323,10 +323,9 @@ appears in the exception report.
Manual dispatch defaults to `generate` and accepts optional plugin, version and
source path filters. `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
-page while ongoing automation remains disabled. It is the first live acceptance
-path after OSS model access is available. With OSS access but no GitHub write
-credential, `validate` still
-writes the candidate to the generation artifact and makes no GitHub write.
+page. It provides a single-page live check after OSS model access is available.
+With OSS access but no GitHub write credential, `validate` still writes the
+candidate to the generation artifact and makes no GitHub write.
`dry-run` remains available for read-only discovery. Full scans recover
pending work from new or changed source documents and earlier failed runs.
One workflow-level concurrency group covers every trigger, mode and locale.
@@ -339,9 +338,10 @@ Translation PR
merges do not trigger this workflow. It does not participate in website
builds or release deployment.
-Ongoing generation stays off unless both repository variables
-`I18N_AUTO_TRANSLATE_ENABLED=true` and `I18N_LIVE_VERIFIED=true` are set. The
-workflow uses the same verified Codex CLI package and numbered ChatGPT auth
+The mode controls generation directly: manual `generate` runs and scheduled
+runs generate batches when eligible documents are pending, while `dry-run`
+only scans. No repository enablement variables are required. The workflow
+uses the same verified Codex CLI package and numbered ChatGPT auth
snapshots in OSS as the Apache Doris code-review runner. The repository's
`OSS_AK` and `OSS_SK` secrets must be able to read those objects and update the
selected auth snapshot if Codex refreshes it. `I18N_CODEX_MODEL` is optional
@@ -357,12 +357,12 @@ write permissions, subject to organization token policy.
A repository admin
must store the secret. The resulting commits and PR use that person's identity.
When both credentials are present, the App takes precedence. The workflow
does not use `GITHUB_TOKEN` to create PRs because those PR checks can require
-manual approval. Set the enablement variables only after a one-page `validate`
-run and its App- or PAT-created PR have passed the required checks.
+manual approval. Use a one-page `validate` run to check model access and the
+App- or PAT-created PR before running a full batch.
Missing write credentials leave manual validation as an artifact-only run;
missing OSS credentials leave discovery available without model calls.
-When enabled, one run produces at most 10 target page candidates. The T08
planner
+In `generate` mode, one run produces at most 10 target page candidates. The
T08 planner
and Codex adapter do not reject work based on an estimated or accumulated
token allowance. The adapter still records actual usage for the run summary.
Document length, chunk size, call timeout and the model's own context limits
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]