From b647017c435068911082d500d187f67d9d434f77 Mon Sep 17 00:00:00 2001 From: Phantom <59059173+EurFelux@users.noreply.github.com> Date: Thu, 4 Sep 2025 19:51:15 +0800 Subject: [PATCH] ci: auto i18n (#9889) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * refactor(i18n): 将日语和俄语迁移到translate目录 * refactor(i18n): 将日语和俄语翻译文件移动到机器翻译目录 * docs(i18n): 更新翻译目录的README说明 * ci: 添加自动国际化翻译的 GitHub Actions 工作流 * Potential fix for code scanning alert no. 48: Workflow does not contain permissions Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com> * fix(i18n): 修复国际化文件末尾缺少换行符的问题 * ci(workflow): 修改自动i18n工作流触发条件为pull_request 将触发条件从push到main分支改为在pull_request的opened、synchronize和reopened事件时触发 * ci(workflow): 更新自动i18n工作流的权限和推送配置 添加pull-requests写入权限以支持PR操作 将推送动作更新为github-push-action并改为推送至PR分支 * ci(github): 更新自动i18n工作流以支持PR分支 修改自动i18n工作流,在检出步骤中添加ref参数以支持PR分支 更新提交消息格式以包含PR编号 * ci(workflows): 更新自动i18n工作流以使用yarn 将依赖管理从npm切换到yarn,并添加corepack启用步骤 * ci(workflow): 优化自动翻译工作流的依赖安装步骤 修改依赖安装命令,使用更精确的参数避免不必要的锁定文件生成,并确保安装开发依赖 * ci(workflow): 更新i18n翻译脚本的执行方式 * ci(workflow): 移除不必要的生产环境标志以简化依赖安装 移除 yarn add 命令中的 --production=false 标志,因为在此上下文中不需要区分生产环境依赖 * ci(workflow): 更新依赖安装命令以跳过构建步骤 * fix(i18n): Auto update translations for PR #9889 * ci(workflow): 优化依赖安装步骤以减少构建时间 将直接使用yarn安装依赖改为在临时目录中通过npm安装,避免全局安装影响 * ci(i18n): 在自动翻译工作流中忽略 package.json 和 yarn.lock 的更改 重置 package.json 和 yarn.lock 的更改,避免在自动更新翻译时提交这些文件 * ci(workflow): 简化自动i18n工作流的依赖安装步骤 移除不必要的corepack启用步骤,直接使用npm安装所需依赖 * Revert "fix(i18n): Auto update translations for PR #9889" This reverts commit 23a4a366e16035bb15f3373e90bbfd7c152d6149. * ci(workflow): 将 npm 安装改为 yarn 全局安装依赖以简化命令 * ci(workflow): 将依赖安装从yarn改为npm * ci(workflow): 修改i18n工作流以隔离依赖安装 将全局依赖安装改为在临时目录中安装,避免污染全局环境 使用npx运行tsx以确保使用正确版本的依赖 * fix(i18n): Auto update translations for PR #9889 * ci(workflow): 更新自动翻译工作流配置 移除 yarn 相关配置并更新翻译脚本文件名 * fix(i18n): Auto update translations for PR #9889 * ci(workflow): 在自动翻译工作流中添加prettier格式化步骤 添加prettier及其json排序插件用于自动格式化翻译后的i18n文件,确保代码风格一致 * Revert "fix(i18n): Auto update translations for PR #9889" This reverts commit 423ca8fb03c8c51c74323ea5c31f560c3d4fd836. * ci(workflow): 修复自动翻译工作流中prettier路径问题 * fix(i18n): Auto update translations for PR #9889 * fix(i18n): 修正西班牙语翻译中的字幕文件字段 * ci(i18n): 添加无变更时的检查逻辑 避免在没有翻译变更时生成空提交 --------- Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com> Co-authored-by: GitHub Action --- .github/workflows/auto-i18n.yml | 65 +++++++++++++++++++ src/main/utils/locales.ts | 4 +- src/renderer/src/i18n/index.ts | 4 +- src/renderer/src/i18n/locales/en-us.json | 2 +- src/renderer/src/i18n/locales/zh-cn.json | 2 +- src/renderer/src/i18n/locales/zh-tw.json | 2 +- src/renderer/src/i18n/translate/README.md | 4 +- src/renderer/src/i18n/translate/el-gr.json | 4 +- src/renderer/src/i18n/translate/es-es.json | 4 +- src/renderer/src/i18n/translate/fr-fr.json | 4 +- .../i18n/{locales => translate}/ja-jp.json | 2 +- src/renderer/src/i18n/translate/pt-pt.json | 4 +- .../i18n/{locales => translate}/ru-ru.json | 2 +- 13 files changed, 84 insertions(+), 19 deletions(-) create mode 100644 .github/workflows/auto-i18n.yml rename src/renderer/src/i18n/{locales => translate}/ja-jp.json (99%) rename src/renderer/src/i18n/{locales => translate}/ru-ru.json (99%) diff --git a/.github/workflows/auto-i18n.yml b/.github/workflows/auto-i18n.yml new file mode 100644 index 0000000000..5797675347 --- /dev/null +++ b/.github/workflows/auto-i18n.yml @@ -0,0 +1,65 @@ +name: Auto I18N + +env: + API_KEY: ${{ secrets.TRANSLATE_API_KEY}} + MODEL: ${{ vars.MODEL || 'deepseek/deepseek-v3.1'}} + BASE_URL: ${{ vars.BASE_URL || 'https://api.ppinfra.com/openai'}} + +on: + pull_request: + types: [opened, synchronize, reopened] + workflow_dispatch: + +jobs: + auto-i18n: + runs-on: ubuntu-latest + name: Auto I18N + permissions: + contents: write + pull-requests: write + + steps: + - name: 🐈‍⬛ Checkout + uses: actions/checkout@v5 + with: + ref: ${{ github.event.pull_request.head.ref }} + + - name: 📦 Setting Node.js + uses: actions/setup-node@v4 + with: + node-version: 20 + + - name: 📦 Install dependencies in isolated directory + run: | + # 在临时目录安装依赖 + mkdir -p /tmp/translation-deps + cd /tmp/translation-deps + echo '{"dependencies": {"openai": "^5.12.2", "cli-progress": "^3.12.0", "tsx": "^4.20.3", "prettier": "^3.5.3", "prettier-plugin-sort-json": "^4.1.1"}}' > package.json + npm install --no-package-lock + + # 设置 NODE_PATH 让项目能找到这些依赖 + echo "NODE_PATH=/tmp/translation-deps/node_modules" >> $GITHUB_ENV + + - name: 🏃‍♀️ Translate + run: npx tsx scripts/auto-translate-i18n.ts + + - name: 🔍 Format + run: cd /tmp/translation-deps && npx prettier --write --config /home/runner/work/cherry-studio/cherry-studio/.prettierrc /home/runner/work/cherry-studio/cherry-studio/src/renderer/src/i18n/ + + - name: 🔄 Commit changes + run: | + git config --local user.email "action@github.com" + git config --local user.name "GitHub Action" + git add . + git reset -- package.json yarn.lock # 不提交 package.json 和 yarn.lock 的更改 + if git diff --cached --quiet; then + echo "No changes to commit" + else + git commit -m "fix(i18n): Auto update translations for PR #${{ github.event.pull_request.number }}" + fi + + - name: 🚀 Push changes + uses: ad-m/github-push-action@master + with: + github_token: ${{ secrets.GITHUB_TOKEN }} + branch: ${{ github.event.pull_request.head.ref }} diff --git a/src/main/utils/locales.ts b/src/main/utils/locales.ts index 9e8d9be839..397e69fd96 100644 --- a/src/main/utils/locales.ts +++ b/src/main/utils/locales.ts @@ -1,13 +1,13 @@ import EnUs from '../../renderer/src/i18n/locales/en-us.json' -import JaJP from '../../renderer/src/i18n/locales/ja-jp.json' -import RuRu from '../../renderer/src/i18n/locales/ru-ru.json' import ZhCn from '../../renderer/src/i18n/locales/zh-cn.json' import ZhTw from '../../renderer/src/i18n/locales/zh-tw.json' // Machine translation import elGR from '../../renderer/src/i18n/translate/el-gr.json' import esES from '../../renderer/src/i18n/translate/es-es.json' import frFR from '../../renderer/src/i18n/translate/fr-fr.json' +import JaJP from '../../renderer/src/i18n/translate/ja-jp.json' import ptPT from '../../renderer/src/i18n/translate/pt-pt.json' +import RuRu from '../../renderer/src/i18n/translate/ru-ru.json' const locales = Object.fromEntries( [ diff --git a/src/renderer/src/i18n/index.ts b/src/renderer/src/i18n/index.ts index da6b924af9..8257f36ad9 100644 --- a/src/renderer/src/i18n/index.ts +++ b/src/renderer/src/i18n/index.ts @@ -5,15 +5,15 @@ import { initReactI18next } from 'react-i18next' // Original translation import enUS from './locales/en-us.json' -import jaJP from './locales/ja-jp.json' -import ruRU from './locales/ru-ru.json' import zhCN from './locales/zh-cn.json' import zhTW from './locales/zh-tw.json' // Machine translation import elGR from './translate/el-gr.json' import esES from './translate/es-es.json' import frFR from './translate/fr-fr.json' +import jaJP from './translate/ja-jp.json' import ptPT from './translate/pt-pt.json' +import ruRU from './translate/ru-ru.json' const logger = loggerService.withContext('I18N') diff --git a/src/renderer/src/i18n/locales/en-us.json b/src/renderer/src/i18n/locales/en-us.json index bfaa971abd..627f57d9cc 100644 --- a/src/renderer/src/i18n/locales/en-us.json +++ b/src/renderer/src/i18n/locales/en-us.json @@ -4268,4 +4268,4 @@ "show_window": "Show Window", "visualization": "Visualization" } -} \ No newline at end of file +} diff --git a/src/renderer/src/i18n/locales/zh-cn.json b/src/renderer/src/i18n/locales/zh-cn.json index 2bf63b81bd..b460ca1ae3 100644 --- a/src/renderer/src/i18n/locales/zh-cn.json +++ b/src/renderer/src/i18n/locales/zh-cn.json @@ -3925,7 +3925,7 @@ "aistudio_access_token": "星河社区访问令牌", "aistudio_url_label": "星河社区", "api_url": "API URL", - "serving_doc_url_label": "PaddleOCR 服务化部署文档", + "serving_doc_url_label": "PaddleOCR 服务化部署文档", "tip": "您可以参考 PaddleOCR 官方文档部署本地服务,或者在飞桨星河社区部署云服务。对于后一种情况,请填写星河社区访问令牌。" }, "system": { diff --git a/src/renderer/src/i18n/locales/zh-tw.json b/src/renderer/src/i18n/locales/zh-tw.json index ff61d5e29c..3075f4e44b 100644 --- a/src/renderer/src/i18n/locales/zh-tw.json +++ b/src/renderer/src/i18n/locales/zh-tw.json @@ -4268,4 +4268,4 @@ "show_window": "顯示視窗", "visualization": "視覺化" } -} \ No newline at end of file +} diff --git a/src/renderer/src/i18n/translate/README.md b/src/renderer/src/i18n/translate/README.md index 60e516f5c9..3e507e6360 100644 --- a/src/renderer/src/i18n/translate/README.md +++ b/src/renderer/src/i18n/translate/README.md @@ -1,2 +1,2 @@ -本目录文件使用`yarn update:i18n`机器翻译生成,请勿手动编辑。 -This directory contains machine translated files generated by `yarn update:i18n`. Please do not edit manually. +本目录文件使用 GitHub Workflow 自动翻译,无需人工维护 +Files in this directory are automatically translated using GitHub Workflow and require no manual maintenance diff --git a/src/renderer/src/i18n/translate/el-gr.json b/src/renderer/src/i18n/translate/el-gr.json index 63e84d7cc8..4513d00461 100644 --- a/src/renderer/src/i18n/translate/el-gr.json +++ b/src/renderer/src/i18n/translate/el-gr.json @@ -1085,7 +1085,7 @@ "status_preprocess_completed": "Η προεπεξεργασία ολοκληρώθηκε", "status_preprocess_failed": "Η προεπεξεργασία απέτυχε", "status_processing": "Επεξεργασία", - "subtitle_file": "[to be translated]:字幕文件", + "subtitle_file": "Υποτίτλων", "threshold": "Περιθώριο συνάφειας", "threshold_placeholder": "Δεν έχει ρυθμιστεί", "threshold_too_large_or_small": "Το περιθώριο δεν μπορεί να είναι μεγαλύτερο από 1 ή μικρότερο από 0", @@ -1099,7 +1099,7 @@ "url_placeholder": "Εισάγετε τη διεύθυνση, χωρίστε πολλαπλές διευθύνσεις με επιστροφή", "urls": "Διευθύνσεις", "videos": "βίντεο", - "videos_file": "[to be translated]:视频文件" + "videos_file": "Αρχείο βίντεο" }, "languages": { "arabic": "Αραβικά", diff --git a/src/renderer/src/i18n/translate/es-es.json b/src/renderer/src/i18n/translate/es-es.json index 031e0a3575..f4f37f4bf1 100644 --- a/src/renderer/src/i18n/translate/es-es.json +++ b/src/renderer/src/i18n/translate/es-es.json @@ -1085,7 +1085,7 @@ "status_preprocess_completed": "Preprocesamiento completado", "status_preprocess_failed": "Error en el preprocesamiento", "status_processing": "Procesando", - "subtitle_file": "[to be translated]:字幕文件", + "subtitle_file": "Archivo de subtítulos", "threshold": "Umbral de coincidencia", "threshold_placeholder": "No configurado", "threshold_too_large_or_small": "El umbral no puede ser mayor que 1 o menor que 0", @@ -1099,7 +1099,7 @@ "url_placeholder": "Ingrese la URL, múltiples URLs separadas por enter", "urls": "URLs", "videos": "vídeo", - "videos_file": "[to be translated]:视频文件" + "videos_file": "video file" }, "languages": { "arabic": "Árabe", diff --git a/src/renderer/src/i18n/translate/fr-fr.json b/src/renderer/src/i18n/translate/fr-fr.json index 6c0a6e5272..6e0e785db7 100644 --- a/src/renderer/src/i18n/translate/fr-fr.json +++ b/src/renderer/src/i18n/translate/fr-fr.json @@ -1085,7 +1085,7 @@ "status_preprocess_completed": "Prétraitement terminé", "status_preprocess_failed": "Échec du prétraitement", "status_processing": "En cours de traitement", - "subtitle_file": "[to be translated]:字幕文件", + "subtitle_file": "Fichier de sous-titres", "threshold": "Seuil de similarité", "threshold_placeholder": "Non défini", "threshold_too_large_or_small": "Le seuil ne peut pas être supérieur à 1 ou inférieur à 0", @@ -1099,7 +1099,7 @@ "url_placeholder": "Entrez l'URL, plusieurs URLs séparées par des sauts de ligne", "urls": "URLs", "videos": "vidéo", - "videos_file": "[to be translated]:视频文件" + "videos_file": "Fichier vidéo" }, "languages": { "arabic": "Arabe", diff --git a/src/renderer/src/i18n/locales/ja-jp.json b/src/renderer/src/i18n/translate/ja-jp.json similarity index 99% rename from src/renderer/src/i18n/locales/ja-jp.json rename to src/renderer/src/i18n/translate/ja-jp.json index 0d5577467a..052077ab9b 100644 --- a/src/renderer/src/i18n/locales/ja-jp.json +++ b/src/renderer/src/i18n/translate/ja-jp.json @@ -4268,4 +4268,4 @@ "show_window": "ウィンドウを表示", "visualization": "可視化" } -} \ No newline at end of file +} diff --git a/src/renderer/src/i18n/translate/pt-pt.json b/src/renderer/src/i18n/translate/pt-pt.json index d6a2e84d9e..835a26cc51 100644 --- a/src/renderer/src/i18n/translate/pt-pt.json +++ b/src/renderer/src/i18n/translate/pt-pt.json @@ -1085,7 +1085,7 @@ "status_preprocess_completed": "Pré-processamento concluído", "status_preprocess_failed": "Falha no pré-processamento", "status_processing": "Processando", - "subtitle_file": "[to be translated]:字幕文件", + "subtitle_file": "arquivo de legenda", "threshold": "Limite de correspondência", "threshold_placeholder": "Não definido", "threshold_too_large_or_small": "O limite não pode ser maior que 1 ou menor que 0", @@ -1099,7 +1099,7 @@ "url_placeholder": "Digite a URL, várias URLs separadas por enter", "urls": "URLs", "videos": "vídeo", - "videos_file": "[to be translated]:视频文件" + "videos_file": "Arquivo de vídeo" }, "languages": { "arabic": "Árabe", diff --git a/src/renderer/src/i18n/locales/ru-ru.json b/src/renderer/src/i18n/translate/ru-ru.json similarity index 99% rename from src/renderer/src/i18n/locales/ru-ru.json rename to src/renderer/src/i18n/translate/ru-ru.json index e8c61dd971..de8305320b 100644 --- a/src/renderer/src/i18n/locales/ru-ru.json +++ b/src/renderer/src/i18n/translate/ru-ru.json @@ -4268,4 +4268,4 @@ "show_window": "Показать окно", "visualization": "Визуализация" } -} \ No newline at end of file +}