ci: add ja-JP publish workflow

This commit is contained in:
Peter Steinberger 2026-04-05 11:32:36 +01:00
parent a2fe84c9e1
commit 3d8c6c5a4e
No known key found for this signature in database
3 changed files with 190 additions and 5 deletions

183
.github/workflows/translate-ja-jp.yml vendored Normal file
View File

@ -0,0 +1,183 @@
name: Translate ja-JP
on:
repository_dispatch:
types:
- translate-ja-jp-release
schedule:
- cron: "47 3 * * *"
workflow_dispatch:
permissions:
contents: write
concurrency:
group: translate-ja-jp
cancel-in-progress: false
jobs:
translate-ja-jp:
runs-on: ubuntu-latest
steps:
- name: Checkout publish repo
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Read source metadata
id: meta
run: |
node - <<'NODE'
const fs = require("node:fs");
const path = ".openclaw-sync/source.json";
const data = JSON.parse(fs.readFileSync(path, "utf8"));
if (!data.repository || !data.sha) {
throw new Error(`invalid source metadata in ${path}`);
}
fs.appendFileSync(process.env.GITHUB_OUTPUT, `repository=${data.repository}\n`);
fs.appendFileSync(process.env.GITHUB_OUTPUT, `sha=${data.sha}\n`);
NODE
- name: Checkout source repo
uses: actions/checkout@v4
with:
repository: ${{ steps.meta.outputs.repository }}
ref: ${{ steps.meta.outputs.sha }}
path: source
fetch-depth: 1
- name: Setup Node
uses: actions/setup-node@v4
with:
node-version: 22
- name: Setup Go
uses: actions/setup-go@v5
with:
go-version: "1.23"
- name: Prune stale ja-JP pages
run: |
python - <<'PY'
from pathlib import Path
root = Path("docs")
locale_root = root / "ja-JP"
if not locale_root.exists():
raise SystemExit(0)
for path in sorted(locale_root.rglob("*"), reverse=True):
if path.is_dir():
if not any(path.iterdir()):
path.rmdir()
continue
rel = path.relative_to(locale_root)
source = root / rel
if not source.exists():
path.unlink()
for path in sorted(locale_root.rglob("*"), reverse=True):
if path.is_dir() and not any(path.iterdir()):
path.rmdir()
PY
- name: Build pending docs file list
id: pending
run: |
python - <<'PY'
import hashlib
import os
import re
from pathlib import Path
source_hash_re = re.compile(r'^x-i18n:\n(?: .*\n)*? source_hash: ([0-9a-f]{64})$', re.M)
def stored_source_hash(path: Path) -> str:
if not path.exists():
return ""
text = path.read_text(encoding="utf-8", errors="ignore")
match = source_hash_re.search(text)
if not match:
return ""
return match.group(1).strip()
all_files = []
pending_files = []
for path in Path("docs").rglob("*"):
if not path.is_file():
continue
if path.suffix.lower() not in {".md", ".mdx"}:
continue
rel = path.as_posix()
if rel.startswith("docs/zh-CN/"):
continue
if rel.startswith("docs/ja-JP/"):
continue
if rel.startswith("docs/.generated/"):
continue
all_files.append(str(path.resolve()))
rel_doc = path.relative_to("docs")
locale_path = Path("docs") / "ja-JP" / rel_doc
source_hash = hashlib.sha256(path.read_bytes()).hexdigest()
if stored_source_hash(locale_path) != source_hash:
pending_files.append(str(path.resolve()))
Path(".openclaw-sync").mkdir(exist_ok=True)
Path(".openclaw-sync/docs-i18n-ja-files.txt").write_text("\n".join(pending_files) + ("\n" if pending_files else ""))
print(f"all_docs={len(all_files)} pending_docs={len(pending_files)}")
with open(os.environ["GITHUB_OUTPUT"], "a", encoding="utf-8") as fh:
fh.write(f"all_count={len(all_files)}\n")
fh.write(f"pending_count={len(pending_files)}\n")
PY
- name: Translate changed docs into ja-JP
if: steps.pending.outputs.pending_count != '0'
env:
OPENAI_API_KEY: ${{ secrets.OPENCLAW_DOCS_I18N_OPENAI_API_KEY }}
OPENCLAW_DOCS_I18N_PROVIDER: openai
OPENCLAW_DOCS_I18N_MODEL: gpt-5.4
OPENCLAW_DOCS_I18N_PROMPT_TIMEOUT: 10m
run: |
if [ ! -s .openclaw-sync/docs-i18n-ja-files.txt ]; then
echo "No docs files found."
exit 0
fi
mapfile -t DOC_FILES < .openclaw-sync/docs-i18n-ja-files.txt
attempt=1
max_attempts=5
while [ "$attempt" -le "$max_attempts" ]; do
echo "docs-i18n attempt $attempt/$max_attempts"
if (
cd source/scripts/docs-i18n
go run . \
--docs "$GITHUB_WORKSPACE/docs" \
--lang ja-JP \
--src en \
--mode doc \
--thinking low \
--parallel 8 \
"${DOC_FILES[@]}"
); then
exit 0
fi
if [ "$attempt" -eq "$max_attempts" ]; then
echo "docs-i18n failed after $max_attempts attempts"
exit 1
fi
attempt=$((attempt + 1))
sleep 5
done
- name: Commit ja-JP refresh
run: |
if git diff --quiet -- docs/ja-JP docs/.i18n/ja-JP.tm.jsonl; then
echo "No ja-JP translation changes."
exit 0
fi
git config user.name "openclaw-docs-i18n[bot]"
git config user.email "openclaw-docs-i18n[bot]@users.noreply.github.com"
git add docs/ja-JP docs/.i18n/ja-JP.tm.jsonl
git commit -m "chore(i18n): refresh ja-JP translations"
git push origin HEAD:main

View File

@ -8,27 +8,28 @@ Source of truth lives in [`openclaw/openclaw`](https://github.com/openclaw/openc
1. English docs are authored in `openclaw/openclaw`.
2. `openclaw/openclaw/.github/workflows/docs-sync-publish.yml` mirrors the docs tree into this repo.
3. This repo stores the published docs tree plus generated zh-CN output.
3. This repo stores the published docs tree plus generated locale output.
4. `openclaw/docs/.github/workflows/translate-zh-cn.yml` runs once a day, on manual dispatch, and after release dispatches from `openclaw/openclaw` to refresh `docs/zh-CN/**`.
5. `openclaw/docs/.github/workflows/translate-ja-jp.yml` does the same for `docs/ja-JP/**`.
## Translation behavior
- zh-CN pages are generated output.
- zh-CN and ja-JP pages are generated output.
- Each translated page stores `x-i18n.source_hash`.
- The translate workflow computes a pending file list before calling the model.
- If no English source hashes changed, the workflow skips the expensive translation step entirely.
- If files changed, only the pending files are translated.
- The workflow retries transient model-format failures.
- Published releases in `openclaw/openclaw` dispatch an extra zh-CN refresh so release-adjacent docs updates do not wait for the daily cron.
- Published releases in `openclaw/openclaw` dispatch extra zh-CN and ja-JP refreshes so release-adjacent docs updates do not wait for the daily cron.
## Editing rules
- Do not treat this repo as the primary place for English doc edits.
- Make English doc changes in `openclaw/openclaw`, then let sync copy them here.
- zh-CN pages in `docs/zh-CN/**` are generated output.
- Generated locale pages in `docs/zh-CN/**` and `docs/ja-JP/**` are generated output.
- `.openclaw-sync/source.json` records which `openclaw/openclaw` commit this mirror was synced from.
## Secrets
- `OPENCLAW_DOCS_SYNC_TOKEN` lives in `openclaw/openclaw` and lets the source repo push into this repo.
- `OPENCLAW_DOCS_I18N_OPENAI_API_KEY` lives in this repo and powers zh-CN translation refreshes.
- `OPENCLAW_DOCS_I18N_OPENAI_API_KEY` lives in this repo and powers locale translation refreshes.

View File

@ -0,0 +1 @@