20个项目,20种语言,截止日期为昨天。 第三部分

关于Serge + Smartcat集成的最终文章。 在本文中,我将向您介绍我们如何将Serge扩展到整个公司,考虑4种非标准集成,并作为奖励,讨论2种可以简化您生活的功能。

以前的文章:

20个项目,20种语言,昨天截止
20个项目,20种语言,截止日期为昨天。 第二部分

可扩展性


在上一篇文章中,我讨论了如何为单个存储库配置Serge。 在我们公司中,我们有几十个需要翻译的存储库,因此分配了一个单独的本地化服务器。 文件结构和环境与上一篇文章中描述的完全相同。 每个存储库都使用自己的Serge实例。 为了不手动执行命令,每个实例都有一个表冠,该表冠依次运行Serge命令:从存储库接收新行,接收新翻译,解析,向Smartcat发送新行以及向Gitlab发送新翻译。

整合选项


在一个存储库中使用两组语言


让我们从最简单的情况开始。 想象一下,您的存储库有几组资源文件。 例如,客户端字符串和应用程序API存储在同一存储库中,但存储在不同目录中。 客户端被翻译成20种语言,API被翻译成6种语言。

目标 :在每个目录中组织独立的翻译。
解决方案

  1. 用Smartcat设置2个项目:6种语言和20种语言。
  2. 在本地化服务器上​​设置2个项目。
  3. 在第一个项目中,在project1.cfg文件中添加$ $ unmerged_branch_mask ='^(translateAPI-)'行; #处理与该掩码匹配的未合并分支 ,其中“ translateAPI- ”是分支名称前缀。 前缀将向Serge指示此分支需要在API目录中进行翻译。
  4. project1.serge.tmpl文件中,在source_dir参数的API目录中指定资源文件的路径。
  5. 同样,对于project2.cfg文件中的第二个项目,添加以下行: $ unmerged_branch_mask ='^(translateCLIENT-)'; #处理与该掩码匹配的未合并分支 ,其中“ translateCLIENT ”是该项目分支的前缀。 前缀将向Serge指示此分支需要Client目录中的翻译。
  6. project2.serge.tmpl文件中,在source_dir参数的CLIENT目录中指定资源文件的路径。

请注意,在为一个存储库配置的所有项目中,前缀必须唯一。

总共,我们在Smartcat中有2个项目,在本地化服务器上​​有2个相应的项目。 这两个项目都在Gitlab中查看相同的存储库,但是在不同的目录中。 Serge使用分支前缀来了解他需要发送哪些行进行翻译。 要计算差异,请使用相同的base-translate分支。

本地化昂首阔步


在我们公司中,所有产品(包括文档)均已本地化。 现在,我们将介绍由swagger自动生成的文档,并且我们面临着对其进行本地化的需求。
任务 :毫不费力地本地化招摇。

解决方案 :在myproject.tmpl.serge文件中,将数据对象添加到解析器对象中,并在其中列出必须提取其值并发送以进行转换的那些字段:

parser { plugin parse_json data { path_matches \/(summary|description)$ } } 

一个类似的任务 :有必要翻译文件中的文本,但不是全部,而是合法的。 其他文本由营销团队提供。 为了不使结构复杂化并且不为法律文本创建附加文件,所有法律行的键都使用前缀“ legal”:

 parser { plugin parse_json data { path_matches ^\/legal\..* } } 

法律翻译的精妙之处


另一个有趣的情况。 我们有一份法律文件,其条款因国家/地区而异。 但是,尽管如此,这是一个应用程序,资源文件位于同一目录中。

目标 :在一个项目的框架中翻译多个文档,每个文档必须翻译成一种特定的语言。

已经做了什么

  1. 为每个国家/地区创建了一个适当的目录,其中包含与该国家/地区有关的英语源文件。
  2. source_dir变量的路径指定到带有资源文件的共享目录。
  3. 我们允许在所有子目录中搜索资源文件: source_process_subdirs是
  4. 我们将一个新的插件添加到被调用的插件列表中,它允许您将每个特定的资源文件发送给所需的语言。 作为指导,请使用其所在目录的名称:

 callback_plugins { :feature_branch { plugin feature_branch data { master_job job.base-translate } } :limit_languages { plugin limit_languages data { # all rules are processed top to bottom; each rule can add or remove languages # so the most priority rules are placed at the bottom if { # by default, don't localize file_matches . then { exclude_all_languages YES } } if { file_matches de-au\/ then { include_languages de-AT } } if { file_matches li-LI\/ then { include_languages li } } if { file_matches pt\/ then { include_languages pt-BR } } if { file_matches zh-Hans\/ then { include_languages zh-Hans } } # and so on.. } } 

在数据库中存储行时的本地化


我们的系统有一部分代码将翻译存储在数据库中,由于多种原因,它无法移至存储库中的资源文件。 但是,我们需要能够快速,自动地交付翻译。

任务 :如果行未存储在存储库中,而是存储在数据库中,则组织连续本地化的过程。

解决方案

  1. 根据我们方便的原则(根据翻译语言或产品的数量)创建一个存储库,从数据库中收集所有行并将其分组。
  2. 在Smartcat中创建一个项目。
  3. 开始连续本地化的标准周期。
  4. 将翻译分支合并到base-translate分支中。
  5. 按王冠,检查base-translate中最后一次提交的哈希值。 如果哈希已更改,即解析了新的转换,则解析了旧哈希与当前哈希之间的差异,并将新的/已更改的行发送到数据库。

奖励功能


警报


基本的Smartcat警报不适合我们,因为每个团队都希望仅接收有关其分支机构的通知,以及仅接收有关产品所有资源文件中翻译的完整准备情况的通知。

决定基于存储库中所有翻译的可用性,如果翻译已经完全准备就绪,则将通知发送给企业信使(在我们的例子中为Google Chat)。

任务 :在存储库中组织警报,其中8个团队可以提交警报,并在技术文档部门的渠道中复制所有警报。

解决方案

  1. 与每个团队同意分支机构的名称应包含团队的名称。 仍使用前缀translation-表示需要翻译的分支。
  2. 创建仅对以translate-为前缀的分支运行的管道。
  3. 在管道中,确定分支所属的命令,检查是否存在空值的行,如果没有,则将就绪通知发送到适当的通道。 由于代码量很大,因此将其放入脚本中。

CI


 check-translations: stage: check-translations image: node:8.14.0 tags: - devops script: - chmod +x ./notification.sh - ./notification.sh only: - base-translate - /^translate.*$/ when: always 

警报脚本


 #!/bin/bash hangouts(){ curl -X POST --max-time 180 -H "Content-Type: application/json; charset=UTF-8" --data "{ \"cards\": [{\"header\": {\"title\": \"LOCALIZATION IS READY\",\"subtitle\": \"REPOSITORY NAME\",\"imageUrl\": \"https://avatanplus.com/files/resources/mid/5775880ee27f8155a31b7a50.png\"},\"sections\": [{\"widgets\": [{\"keyValue\": {\"topLabel\": \"Translation is finished in the branch\",\"content\": \"$1\"}}]},{\"widgets\": [{\"buttons\": [{\"textButton\": {\"text\": \"SEE COMMIT\",\"onClick\": {\"openLink\": {\"url\": \"https://gitlab.loc/common/publisher-client/commit/$2\"}}}}]}]}]}]}" "$3" || true } cd app/translations if echo "$CI_COMMIT_REF_NAME" | grep "commandname1"; then grep -rl '\:\s\"\"' *.json >> result.file if [ -s network.file ]; then echo "Translations are not ready"; cat result.file else hangouts $CI_COMMIT_REF_NAME $CI_COMMIT_SHA $HANGOUTS_NOTIFICATIONS_COMMAND_NAME_1 hangouts $CI_COMMIT_REF_NAME $CI_COMMIT_SHA $HANGOUTS_NOTIFICATIONS_DOC fi fi if echo "$CI_COMMIT_REF_NAME" | grep "commandname2"; then grep -rl '\:\s\"\"' *.json >> result.file if [ -s result.file ]; then echo "Translations are not ready"; cat result.file else hangouts $CI_COMMIT_REF_NAME $CI_COMMIT_SHA $HANGOUTS_NOTIFICATIONS_COMMAND_NAME_2 hangouts $CI_COMMIT_REF_NAME $CI_COMMIT_SHA $HANGOUTS_NOTIFICATIONS_DOC fi fi ... if echo "$CI_COMMIT_REF_NAME" | grep "commandname8"; then grep -rl '\:\s\"\"' *.json >> result.file if [ -s result.file ]; then echo "Translations are not ready"; cat result.file else hangouts $CI_COMMIT_REF_NAME $CI_COMMIT_SHA $HANGOUTS_NOTIFICATIONS_COMMAND_NAME_8 hangouts $CI_COMMIT_REF_NAME $CI_COMMIT_SHA $HANGOUTS_NOTIFICATIONS_DOC fi fi 

通过Smartcat API进行翻译分配




这是我们的本地化经理在分配所有分支进行翻译时的样子。

平均而言,我们每天有10个以上的分支机构在工作。 在Smartcat中,每个语言对都是一个单独的文档,并且必须为每个此类文档分配翻译。 手动。 想象一下:每天40-60个约会。 为了简化此过程,我们通过API进行了约会,并将其放入管道中。 通过按钮启动该作业。 一个合理的问题:为什么在发送转移时不自动执行分配,为什么不在Smartcat插件中而不是在管道中放置方法调用?

做出此决定的原因有很多:

  1. 人为因素。 尽管我们建立了流程并尝试遵守这些流程,但未读的行或没有上下文的行仍会定期进入Smartcat。 在这种情况下,自动分配对我们来说意味着额外的费用,因为在编辑之前和之后,有些行将被翻译两次。
  2. 角色分布。 项目是由项目的本地化工程师或技术作者在本地化服务器级别配置和管理的。 任命和与翻译的沟通由本地化经理处理。 因此,分配必须是可管理的,透明的并且可以通过GUI访问。

解决方案:当本地化经理认为该分支中的行已准备好进行翻译时,她按下Gitlab中的按钮。 整个翻译团队都被分配到这个分支。 该任务由首先做出响应的翻译承担。

CI


 assignee: stage: assignee image: node:8.14.0 tags: - devops script: - chmod +x ./assignee.sh - ./assignee.sh only: - base-translate - /^translate.*$/ - assignee when: manual 

作业脚本


 #!/bin/bash if echo "$CI_COMMIT_REF_NAME" | grep "translate-"; then node -pe "JSON.parse(process.argv[1]).documents.forEach(function(elem){ if(elem.name.indexOf(\"$CI_COMMIT_REF_NAME\") !== -1) { console.log(elem.id) } });" "$(curl -XGET -H "Authorization: Basic $SMARTCAT_API_KEY" -H "Content-type: application/json" "https://smartcat.ai/api/integration/v1/project/$SMARTCAT_PROJECT_ID")" >> documents fi sed '$d' documents > documents.list while read LINE; do bash -c "curl -XPOST -H 'Authorization: Basic $SMARTCAT_API_KEY' -H "Content-type:application/json" -d '{"documentIds":[\""$LINE"\"],"stageNumber": 1}' 'https://smartcat.ai/api/integration/v1/document/assignFromMyTeam'";done < documents.list 

总结了我有关集成和配置连续本地化的系列文章。 我很高兴回答您的任何问题。

Source: https://habr.com/ru/post/zh-CN452580/


All Articles