返回博客
A git diff view showing a locale file with three changed keys highlighted, and only those three keys being sent to the translation API below.

您无需重新翻译所有内容:CI 中的增量翻译如何工作

By Robert M

你不需要重新翻译所有内容:CI 中的增量翻译工作原理

一旦你将自动翻译接入到 CI 流水线中,一个自然的问题很快就会出现:每次有人推送更改时,是否会重新翻译整个本地化文件?

如果没有增量模式,是的。每次推送涉及你的源本地化文件时,都会将整个文件发送到 API,每个键、每个字符串,无论是否更改。对于早期的小项目来说,这没问题。对于一个成熟的项目,拥有数百个翻译键,覆盖 10 到 20 种语言,你会在自上次运行以来未更改的字符串上浪费令牌,并且得到相同的输出作为代价。

增量翻译解决了这个问题。它不是发送完整文件,而是将当前源文件与存储的基线进行比较,只识别新增或修改的键,并仅将这些键发送到 API。未更改键的输出则取自现有的翻译文件。令牌使用量下降,匹配实际完成的工作量。


基线的工作原理

当增量模式首次运行,或你强制完全刷新时,Action 会翻译完整的源文件,并将其扁平化的 JSON 表示存储为基线文件在你的仓库中。后续运行时,Action 会加载该基线,与当前源文件进行差异比较,并构建只包含更改键的负载。

对于 JSON 本地化文件,基线存储在消息目录下的 .polylingo-baseline.json。对于 YAML 本地化文件,基线存储在本地化目录下的 .polylingo-yaml-baseline.json。对于 Laravel PHP 语言文件,基线存储在 lang 目录下的 .polylingo-laravel-php-baseline.json

基线与翻译文件一起提交,因此它随仓库一起传递。任何克隆仓库的开发者都会获得流水线正在使用的相同基线。


什么算作更改

差异比较基于源文件的扁平化键表示。嵌套结构在比较前被扁平化为点符号键:

{
  "nav.home": "首页",
  "nav.about": "关于我们",
  "hero.title": "欢迎来到我们的平台",
  "hero.cta": "开始使用"
}

如果满足以下条件,键会被包含在增量负载中:

  • 它存在于当前源文件中但不在基线中(新键)
  • 它存在于两者中但值已更改(修改键)

存在于基线但不在当前源文件中的键(已删除键)会自动从翻译输出文件中移除。两者相同的键则完全跳过,保留现有翻译。


实际应用示例

假设你有一个 Next.js 项目,messages/en.json 中有 200 个翻译键,已经翻译成 12 种语言。一位开发者更新了 hero 部分的文案,并为功能公告添加了两个新键。共计 4 个键发生了变化。

没有增量模式时,流水线每次推送都会发送所有 200 个键,乘以 12 种语言。启用增量模式后,只发送 4 个键。该次运行的令牌使用量大约是完整翻译的 2%。流水线也更快,因为发送和等待的内容更少。

经过一个月的常规开发,节省效果显著。大多数推送只涉及少量字符串。只有在添加新语言或显式重置基线时,才会进行完整重新翻译。


三个 PolyLingo GitHub Actions

增量模式适用于所有三个 PolyLingo 翻译 Actions。每个针对特定内容类型和项目结构构建。

translateAction — JSON 和 Markdown

原始 Action。处理 next-intl 和 i18next 风格的扁平 JSON 本地化文件,支持通过异步作业 API 对较大文件进行可选的 Markdown 文档处理。

- uses: UsePolyLingo/translate-action@v1
  with:
    api_key: ${{ secrets.POLYLINGO_API_KEY }}
    source_file: messages/en.json
    locales: fr,de,es,ja,zh
    delta: true
    commit: true
    commit_message: "chore(i18n): sync translations"

增量基线:messages/.polylingo-baseline.json

github.com/UsePolyLingo/translateAction在 Marketplace 查看


translate-action-yaml — YAML 本地化文件

适用于使用嵌套 YAML 本地化文件的项目:Rails i18n、Vue i18n 及其他使用 YAML 格式的框架。Action 自动处理 Rails 的根本地化键约定——en.yml 有一个 en: 根键,每个输出文件获得正确的目标本地化键(如 fr:de: 等)。

由于 PolyLingo API 原生支持 JSON,Action 会先将嵌套 YAML 扁平化为点符号 JSON,发送翻译后再重建嵌套结构并写出有效的 YAML 输出。v1 版本有一个注意点:包含点的键不支持,因为与点符号扁平化冲突。

- uses: UsePolyLingo/translate-action-yaml@v1
  with:
    api_key: ${{ secrets.POLYLINGO_API_KEY }}
    locales_dir: config/locales
    source_file: config/locales/en.yml
    locales: fr,de,es,ja
    delta: true
    commit: true

增量基线:config/locales/.polylingo-yaml-baseline.json

github.com/UsePolyLingo/translate-action-yaml在 Marketplace 查看


translate-action-laravel — Laravel 语言文件

适用于 Laravel 项目,支持 JSON 翻译文件(lang/en.json,支持 Laravel 9+ 风格的嵌套和平面结构)或 PHP 数组语言文件(lang/en/*.php)。Action 通过 php_format: auto 自动检测项目使用的格式——优先检查 lang/en.json,找不到则回退到 PHP 数组文件。

对于 PHP 文件,Action 调用 PHP CLI 读取源文件,并将翻译输出序列化回有效的 PHP 数组语法,无需额外依赖。GitHub 托管的 ubuntu-latest 运行器默认包含 PHP 8.x,无需额外设置。要求 PHP 7.4 或更高版本。

v1 版本注意:PHP 模式下不支持包含点的键,因点符号扁平化策略。

- uses: UsePolyLingo/translate-action-laravel@v1
  with:
    api_key: ${{ secrets.POLYLINGO_API_KEY }}
    lang_dir: lang
    source_locale: en
    locales: fr,de,es,pt,nl
    php_format: auto
    delta: true
    open_pr: true

增量基线:根据格式不同,存储为 lang/.polylingo-laravel-json-baseline.jsonlang/.polylingo-laravel-php-baseline.json

github.com/UsePolyLingo/translate-action-laravel在 Marketplace 查看


PR 模式与提交模式

所有三个 Actions 支持两种输出模式。

提交模式commit: true)直接写入翻译文件并提交到当前分支。设置简单,适合将翻译视为无需审核的自动化流程的团队。

PR 模式open_pr: true)创建新分支(如 polylingo/yaml-<sha>polylingo/laravel-<sha> 等),写入翻译文件,并针对基础分支打开拉取请求。适合希望在合并翻译内容前进行人工审核的团队,或翻译质量直接影响用户体验的项目。

两者同时设置时,PR 模式优先。

PR 模式需要在工作流权限中启用 pull-requests: write

permissions:
  contents: write
  pull-requests: write

强制完全刷新

增量模式基于存储的基线进行比较。如果你想无视基线,重新翻译所有内容,设置 delta: false。这也会更新基线以匹配当前源文件,后续增量运行从新状态开始。

完全刷新适用于添加新目标语言、想要采用新模型版本的翻译质量改进,或基线因任何原因偏离实际情况时。

- uses: UsePolyLingo/translate-action-yaml@v1
  with:
    api_key: ${{ secrets.POLYLINGO_API_KEY }}
    locales_dir: config/locales
    locales: fr,de,es,ja,zh,ko,ar
    delta: false  # 完全刷新,更新基线
    commit: true

下游步骤的输出

所有三个 Actions 都暴露相同的输出,方便在后续工作流步骤中使用:

- uses: UsePolyLingo/translate-action@v1
  id: translate
  with:
    api_key: ${{ secrets.POLYLINGO_API_KEY }}
    source_file: messages/en.json
    locales: fr,de,es
    delta: true
    commit: true

- name: Log translation stats
  run: |
    echo "Locales translated: ${{ steps.translate.outputs.locales_translated }}"
    echo "Files changed: ${{ steps.translate.outputs.files_changed }}"
    echo "Tokens used: ${{ steps.translate.outputs.tokens_used }}"

每次运行还会将摘要表写入 GitHub Actions 步骤摘要,方便查看令牌使用和翻译结果,无需翻阅日志。


入门指南

所有三个 Actions 都可在 GitHub Marketplace 获取。你需要一个 PolyLingo API 密钥,可在 usepolylingo.com 免费获取。免费套餐每月包含 50,000 个令牌。启用增量模式后,大多数项目在常规开发推送中都能轻松控制在此范围内。

将你的 API 密钥添加为仓库密钥(POLYLINGO_API_KEY),并将相应的 Action 添加到工作流中。首次运行会进行完整翻译并设置基线。之后每次运行只翻译发生变化的内容。