Спросите свой вопрос и получите сводку документа, используя эту страницу и выбранного вами поставщика AI
Содержимое этой страницы было переведено с помощью ИИ.
Смотреть последнюю версию оригинального контента на английскомЕсли у вас есть идея по улучшению этой документации, не стесняйтесь внести свой вклад, подав запрос на вытягивание на GitHub.
Ссылка на документацию GitHubКопировать Markdown документа в буфер обмена
Автоматизация переводов в CI/CD без отправки некорректных текстов
Ручной перевод не выдерживает темпов современной разработки. Разработчик добавляет строку в пятницу, экспорт происходит только в следующем спринте, и к этому моменту еще три языка отстают от актуальной версии. Автоматизировать этот процесс просто. Сложнее сделать это так, чтобы случайно не выкатить сырой машинный перевод клиентам.
Содержание
Для автоматизации не нужно мигрировать
Приведенные ниже схемы пайплайнов не зависят от используемой библиотеки, как и инструменты. Если ваши переводы хранятся в JSON-каталогах для i18next, next-intl, react-intl, vue-i18n или next-translate, плагин Sync JSON читает и обновляет эти файлы прямо на месте:
Копировать код в буфер обмена
Ваше приложение продолжает импортировать то, что импортировало раньше. CI-задачи затем заполняют и проверяют существующие каталоги, а в ревью будет виден обычный diff в locales/fr/checkout.json, а не глобальная миграция кодовой базы. Также есть плагин Sync PO для gettext и адаптеры совместимости для сохранения runtime API без изменений.
Разделяйте блокировку (gate) и заполнение (fill)
Две совершенно разные задачи постоянно путают между собой.
Gate (барьер) — это проверка, которая падает с ошибкой. Она указывает, что сборка не должна попасть в релиз из-за отсутствия обязательных переводов. Gate ничего не записывает.
Fill (заполнение) — это мутация данных. Команда генерирует недостающие переводы и коммитит их. Fill никогда не роняет сборку.
Запуск только fill означает, что ничто никогда не блокируется, и непроверенный машинный текст попадает напрямую в продакшен. Запуск только gate означает, что билд становится красным и человеку приходится вмешиваться каждый раз. Большинству команд нужны оба механизма, привязанные к разным триггерам: fill на этапе pull request, gate при слиянии в релизную ветку.
Где размещать автоматизацию
Открыть таблицу в модальном окне для четкого просмотра всех данных
| Этап | Триггер | Для чего подходит | Затраты |
|---|---|---|---|
| Pre-push хук | Git local | Быстрая обратная связь, не тратит минут CI | Работает на машине разработчика с его API-ключом |
| Pull request | CI job | Ревью до слияния, единое место для секретов | Минуты CI плюс запросы к модели на каждый PR |
| Release ветка | CI job | Жесткая блокировка по покрытию | Дешево, без вызовов нейросетей |
| Runtime | CMS | Правки контента без пересборки приложения | Зависимость от внешнего сервиса |
Pre-push: самый быстрый цикл
Husky запускает заполнение до того, как код покинет рабочую станцию, поэтому переводы отправляются в том же пуше, что и новые строки.
Копировать код в буфер обмена
Флаг --unpushed ограничивает работу только тем контентом, который еще не был отправлен в удаленный репозиторий, поэтому пуш не зависает на минуту. --mode complete заполняет только пропущенные ключи и не перезаписывает уже существующие переводы, гарантируя сохранность вычитанного текста.
В монорепозитории изолируйте приложения:
Копировать код в буфер обмена
Минус очевиден: каждому разработчику нужен API-ключ, и расходы ложатся на того, кто делает пуш. Поэтому команды обычно переносят этот этап в CI по мере роста.
Pull request: автозаполнение на этапе ревью
Тот же процесс в GitHub Actions с ограничением по diff:
Копировать код в буфер обмена
Четыре детали здесь имеют решающее значение:
fetch-depth: 0необходим для работы--git-diff. У поверхностного клона нет базовой ветки для построения diff, и заполнение молча ничего не сделает.[skip ci]в сообщении коммита предотвращает зацикливание воркфлоу. Без него коммит инициирует новый запуск, который коммитит снова, сжигая баланс CI за ночь.concurrencyсcancel-in-progressзащищает от гонки двух одновременных пушей при записи файлов.--git-diffограничивает обработку только тем, что изменилось в PR. Без него весь каталог будет переводиться заново при каждом запуске.
Переводы фиксируются коммитом прямо в ветку PR, что дает возможность ревьюеру проверить их в diff. В этом и заключается смысл выполнения шага на этапе PR, а не после слияния.
Релизная ветка: блокирующий барьер (gate)
Барьер не требует доступа к моделям и должен выполняться быстро.
Копировать код в буфер обмена
С проверкой через тест, проверяющий покрытие ассертами:
Копировать код в буфер обмена
Команда npx intlayer content test выводит отчет в консоль, но завершается с кодом 0, поэтому она только информирует, но не блокирует сборку. Используйте ее локально, а в CI запускайте тест с ассертом. Подробнее в статье как находить недостающие переводы.
requiredLocales делает барьер жизнеспособным
Барьер, требующий полноты всех восемнадцати языков, блокирует релиз до тех пор, пока не будет готов самый медленный перевод, и в итоге отключается командой через месяц.
Копировать код в буфер обмена
Объявляйте все поддерживаемые языки, но обязательными делайте только те, которые действительно критичны для релиза. Остальные локали наполняются асинхронно и не задерживают выпуск версий.
Вынос переводов за пределы репозитория
Второй подход заключается в объявлении одного базового языка в коде и управлении остальными через CMS с Live Sync. Правки контента в таком случае не требуют пересборки проекта, отделяя работу редакторов от цикла релизов кода.
Копировать код в буфер обмена
Это удобно командам, где текстами занимаются не-разработчики. Это осознанный компромисс: вы получаете независимость редакторов, но теряете гарантию того, что git-checkout полностью описывает состояние интерфейса. Подробнее в документации по CMS.
Помните, что clientSecret является серверным секретом. Он должен храниться в переменных окружения сервера и CI, и ни при каких условиях не попадать в клиентский бандл.
Реальные ограничения
Все описанное выше автоматизирует покрытие, а не качество. Автозаполнение превращает заметный пробел в незаметный: проверки проходят успешно, потому что у ключа есть значение, но текст никто не вычитывал.
Это допустимо для внутренних инструментов, списков изменений или бета-локалей. Это категорически недопустимо для тарифов, юридических документов, сообщений об ошибках оплаты и любых конверсионных экранов. Для таких разделов привлекайте людей и используйте --mode complete, чтобы нейросеть не перетерла проверенный текст.
Передавайте контекст модели для получения стабильных формулировок:
Копировать код в буфер обмена
Распространенные ошибки
- Отсутствие
[skip ci]в автокоммите. Пайплайн запускается по кругу до исчерпания лимитов. - Поверхностный клон при использовании
--git-diff. Нет базы для сравнения, ничего не заполняется и ошибок не возникает. - Перевод всего каталога при каждом прогоне. Ограничивайте запуск флагами
--git-diffили--unpushed. - Использование отчета CLI в качестве барьера. Он завершается с кодом 0.
- Требование обязательности всех локалей сразу. Барьер отключают после первой же сорванной доставки релиза.
- Пайплайн с автозаполнением, но без проверочного барьера. Ничего не падает, и сырой машинный текст уходит клиентам.
- API-ключи моделей в репозитории. Они должны храниться только в секретах CI.
Полезные материалы
- CI/CD: автогенерация переводов с Husky, GitHub Actions и CMS
- Тестирование контента и блокировка сборки по покрытию
- autoFill: создание файлов деклараций для каждой локали
- Справочник конфигурации:
locales,requiredLocales,editor - Отчеты производительности фреймворков
- Адаптер совместимости с i18next
- Как находить недостающие переводы
- Как тестировать переводы без хрупких тестов
Комментарии
Пока нет комментариев. Будьте первым, кто поделится своими мыслями.
