ci: auto i18n (#9889)

* 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 23a4a366e1.

* 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 423ca8fb03.

* 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 <action@github.com>
This commit is contained in:
Phantom 2025-09-04 19:51:15 +08:00 committed by GitHub
parent 3a8a603527
commit b647017c43
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
13 changed files with 84 additions and 19 deletions

65
.github/workflows/auto-i18n.yml vendored Normal file
View File

@ -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 }}

View File

@ -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(
[

View File

@ -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')

View File

@ -4268,4 +4268,4 @@
"show_window": "Show Window",
"visualization": "Visualization"
}
}
}

View File

@ -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": {

View File

@ -4268,4 +4268,4 @@
"show_window": "顯示視窗",
"visualization": "視覺化"
}
}
}

View File

@ -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

View File

@ -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": "Αραβικά",

View File

@ -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",

View File

@ -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",

View File

@ -4268,4 +4268,4 @@
"show_window": "ウィンドウを表示",
"visualization": "可視化"
}
}
}

View File

@ -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",

View File

@ -4268,4 +4268,4 @@
"show_window": "Показать окно",
"visualization": "Визуализация"
}
}
}