Imagine: você tem 7 equipes de desenvolvimento, totalizando mais de 100 pessoas. Eles viram simultaneamente 13 aplicações. O trabalho é realizado em 20 repositórios.
Todos os aplicativos precisam ser traduzidos. Alguns em 6 idiomas, outros em 20. E outros em 13, mas esse é um conjunto de idiomas completamente diferente, não incluído nos 20 anteriores.
Todo mundo tem uma pilha diferente, como resultado de diferentes formatos de linha: js, json, ts, yaml ou yml. E alguns ainda mantêm seus textos no banco de dados.
Você trabalha no Agile: entrega diária de valor, sprints de duas semanas. O DoR inclui todas as traduções necessárias. Bem, é claro, ontem foram necessárias traduções para ter tempo de testar.
Existe um departamento de escritores técnicos. Quem é um escritor técnico? É uma pessoa que escreve documentação externa, às vezes interna. Grava todos os tipos de textos que os usuários ou parceiros podem ver: textos de front-end, textos de mensagens, respostas de API, erros. Acompanha o processo de desenvolvimento a ser imerso em tecnologia e lógica de negócios. E fornece entrega oportuna de traduções para o aplicativo.
Há também a posição de redator-tradutor e gerente de localização. É uma pessoa que cria todos os textos em inglês e também monitora a consistência das traduções, nomeia tradutores e resolve todos os problemas relacionados.
Atenção, a pergunta é: quantas especificações técnicas, redatores e gerentes de localização são necessários para não prejudicar o desenvolvimento e não prejudicar todo o departamento técnico?
No nosso caso, gerenciamos 4 serviços técnicos e 1 gerente de localização de redatores. A entrega de transferências, em média, cabe dentro de um dia útil e nunca excede três dias úteis. Espero que você ache interessante.
Como chegamos a isso?
Há 6 anos, trabalhamos nas planilhas do Google e em um banco de dados. Ou seja, se durante o processo de desenvolvimento as linhas apareceram para tradução, as copiamos em um tablet e as enviamos por correio para a tradução. Quando a tradução estava pronta, ela foi derramada manualmente no banco de dados. A única vantagem dessa solução é que você não precisa re-instalar o aplicativo para ver novas linhas. Mas se houver um erro nas traduções, não funcionará para reverter. Sem memória de tradução, sem glossários. A consistência das traduções é alcançada pelo método do olhar.
Primeira tentativa
A primeira versão para automatizar esse processo era assim: quando um desenvolvedor tinha linhas, ele as adicionou a uma nova ramificação em um repositório especial para traduções. Em seguida, no mesmo ramo, foi lançado um pipeline, que, pela API, enviou todas as linhas de diferenças para conversão. É verdade que as traduções já deveriam voltar ao banco de dados, mas falharam ao carregar as linhas do recurso externo para o banco de dados interno por meio da API.
O que essa integração deu? Foi removida uma etapa em que o redator técnico precisa coletar tudo em uma tabela, enviar manualmente e depois dividir as traduções recebidas por aplicativo e pelo número de idiomas. Nesse caso, as linhas foram imediatamente enviadas para tradução como parte de um projeto com o mesmo nome e com o aplicativo a que se destinavam. Como resultado, o redator técnico recebeu um conjunto de arquivos para cada um dos aplicativos para os quais o trabalho foi realizado. Isso reduziu significativamente a parcela de trabalho manual. Além disso, a memória de tradução foi implementada no lado do provedor. Mas essa solução também retinha várias desvantagens: armazenar linhas no banco de dados não permitia o gerenciamento completo de linhas do nosso lado e, como antes, implicava uma grande parte do trabalho manual.
Dor e localização contínua
A integração a seguir trouxe muito sofrimento aos desenvolvedores. Parece-me que quem o pegou ainda tem os olhos tremendo com a palavra "localização". Esta foi a primeira integração com Serge e Smartcat.

Aqui é importante dizer o que Serge e Smartcat são.
Serge é um utilitário que suporta git. Ela sabe como obter as linhas necessárias da ramificação, enviá-las para tradução e, em seguida, retorne a tradução das mesmas linhas apenas para a mesma ramificação. Também precisamos de um plugin que chamará a API do sistema CAT no qual traduzimos. O plug-in deve receber novas linhas de Serge e retornar traduções prontas para Serge.
O Smartcat é um sistema CAT com suporte para glossário, memória de tradução, espaços reservados. Além disso, o Smartcat agrega e simplifica o processo de acordos com freelancers, suporta a conexão de fornecedores de tradução.
Nesta etapa, transferimos as linhas do banco de dados para o repositório do projeto. Agora as seqüências tinham que ser enviadas diretamente do repositório de aplicativos e retornadas para lá.
Supunha-se que isso funcionaria assim: o desenvolvedor sabe de qual ramificação ele criou sua ramificação de recursos, e a diferença nos arquivos de recursos entre essas duas ramificações é exatamente o que precisa ser traduzido. Quando um desenvolvedor tem um conjunto de linhas para tradução, ele inicia um trabalho em sua filial com a configuração de Serge. Serge calcula diff, extrai novas linhas, chama o plugin e envia as linhas para tradução. Quando as traduções estão prontas, o desenvolvedor chama o seguinte trabalho: ele implanta a instância Serge criada na etapa anterior, recebe as traduções concluídas e as confirma na ramificação de origem.
A solução acabou sendo instável: o Serge não deveria ser implantado do zero toda vez que o pipeline foi lançado, os desenvolvedores não queriam pensar em diferenças entre os ramos, e o plug-in Smartcat precisava urgentemente de atualização e aprimoramento. O processo de entrega de novas linhas pode levar horas. E, infelizmente, nem sempre foi bem sucedido.
Teoricamente, todas as etapas do processo foram automatizadas; de fato, a manutenção, o cálculo da diferença antes do início do pipeline e a solução de problemas demoraram mais do que a execução manual da mesma tarefa.
Luz no fim do túnel
Em agosto de 2018, lançamos a versão atual da integração. Temos um servidor de localização. No servidor para cada repositório, há uma instância separada do Serge. Serge varre todas as ramificações do repositório, envia novas linhas para tradução e confirma as traduções concluídas nas ramificações originais. Na integração atual, tudo é rápido e estável. Depois de criar uma ramificação para traduções, as linhas aparecem no Smartcat dentro de 5-6 minutos. Depois de confirmar as transferências, a confirmação ocorre da mesma forma, dentro dos mesmos 5-6 minutos. O tempo de entrega das traduções é limitado apenas pelo fator humano: a carga de trabalho dos tradutores, a diferença de fuso horário e assim por diante.
Nos artigos a seguir, mostrarei como configurar a integração Serge-Smartcat-Gitlab a partir do zero e como resolvemos várias tarefas não-padrão.
Continuação:
20 projetos, 20 idiomas, prazo de ontem. Parte 220 projetos, 20 idiomas, prazo de ontem. Parte 3