GitHub App от Lingo.dev настраивает непрерывную локализацию репозитория с помощью .lingo/config.json.
Что понадобится#
Перед установкой приложения убедитесь, что у вас есть:
- Организация в Lingo.dev с включённой интеграцией с GitHub
- Движок локализации в этой организации
- Права администратора в организации GitHub или в репозитории, который вы хотите подключить
Если вы не администратор организации GitHub, вместо установки можно отправить запрос. Администратор организации GitHub должен одобрить его, прежде чем Lingo.dev получит доступ к выбранным репозиториям.
Подключение GitHub App#
- В Lingo.dev откройте свою организацию.
- Перейдите в Settings.
- В разделе интеграций найдите GitHub (App).
- В строке GitHub (App) нажмите Connect.
- В GitHub выберите аккаунт или организацию, в которую нужно установить приложение.
- Выберите All repositories или Only select repositories.
- Нажмите Install.
После установки Lingo.dev покажет подключённый GitHub-аккаунт и репозитории в разделе Settings > GitHub (App). Если позже понадобится добавить или удалить репозитории, используйте Manage repositories on GitHub в той же карточке настроек.
Если ваш запрос на установку ожидает одобрения, администратор GitHub может проверить его в GitHub в разделе организации Settings > GitHub Apps. GitHub также показывает ожидающие запросы на приложения владельцам организации в её настройках.
Добавьте конфигурацию репозитория#
Создайте .lingo/config.json в репозитории, где установлено приложение:
{
"engineId": "eng_abc123",
"sourceLocale": "en",
"targetLocales": ["es", "fr", "de"],
"files": [
{ "pattern": "docs/en/**/*.md" },
{ "pattern": "docs/en/**/*.mdx" },
{ "pattern": "locales/en.json" }
],
"github": {
"workflows": {
"onPushToDefaultBranch": { "enabled": true },
"onPullRequest": { "enabled": true }
},
"safety": {
"requireApproval": false
}
}
}| Поле | Обязательно | Описание |
|---|---|---|
engineId | Да | Движок Lingo.dev, который должен переводить этот репозиторий. |
sourceLocale | Да | Исходная локаль, которая используется в путях к исходным файлам, например en или en-US. |
targetLocales | Да | Коды локалей, на которые нужно переводить. Поддерживается до 50 уникальных локалей. |
files | Да | Шаблоны путей к исходным файлам относительно репозитория. Поддерживается до 100 шаблонов. |
github.workflows.onPushToDefaultBranch.enabled | Нет | Запускается, когда исходные файлы меняются в ветке по умолчанию. Включено по умолчанию. |
github.workflows.onPullRequest.enabled | Нет | Запускается, когда исходные файлы меняются в pull request. Отключено по умолчанию. |
github.safety.requireApproval | Нет | Требует одобрения перед тем, как автоматические рабочие процессы для push или PR запустят перевод. Отключено по умолчанию. |
Шаблоны файлов#
Шаблоны files указывают на исходные файлы, то есть файлы локали по умолчанию. Приложение сверяет изменённые файлы с этими шаблонами и обрабатывает только поддерживаемые исходные файлы, которые им соответствуют.
Шаблоны задаются относительно репозитория, чувствительны к регистру и могут использовать:
*— для совпадения внутри одного сегмента пути**/— для совпадения на любой глубине директорий
Шаблоны не могут начинаться с / и не могут содержать ...
{
"files": [
{ "pattern": "docs/en/**/*.md" },
{ "pattern": "src/content/en/**/*.mdx" },
{ "pattern": "messages/en.jsonc" }
]
}Параметры файлов#
Каждая запись в files может включать дополнительные параметры помимо своего pattern. Все они необязательны, и каждый применяется только к определённым форматам.
| Параметр | Применяется к | Описание |
|---|---|---|
format | Все | Переопределяет формат, определённый по расширению файла. Обязателен для OpenAPI YAML ("yaml-openapi"). |
include / exclude | Все | Списки glob-шаблонов, которые уточняют, какие файлы охватывает запись; используются вместе с pattern или вместо него. |
translateFrontmatterFields | Markdown, MDX, Markdoc | Ключи frontmatter, которые нужно переводить. По умолчанию используются title и description. |
translateComponentProps | MDX, Markdoc | Свойства компонентов MDX и атрибуты тегов Markdoc, которые нужно переводить. |
lockedKeys | JSON, JSONC | Пути ключей, для которых сохраняется исходное значение без перевода. |
preservedKeys | JSON, JSONC | Пути ключей, для которых сохраняется текущее целевое значение без повторного перевода. |
injectLocale | JSON, JSONC | Записывает код целевой локали в выходной файл по указанному ключу (по умолчанию language). |
Записи translateComponentProps — это либо имя свойства, которое применяется к этому свойству в любом компоненте или теге, либо объект, который ограничивает свойства указанными компонентами или тегами:
{
"files": [
{
"pattern": "src/content/en/**/*.mdx",
"translateFrontmatterFields": ["title", "description"],
"translateComponentProps": [
"alt",
{ "component": ["Callout", "Hero"], "props": ["title", "subtitle"] }
]
},
{
"pattern": "locales/en.json",
"lockedKeys": ["app.version"],
"injectLocale": { "enabled": true, "key": "language" }
}
]
}Куда записываются локализованные файлы#
Приложение формирует каждый целевой путь на основе исходного пути и кодов локалей из вашей конфигурации:
| Исходный путь | Целевая локаль | Выходной путь |
|---|---|---|
docs/en/guide.md | es | docs/es/guide.md |
docs/en-US/guide.md | fr-FR | docs/fr-FR/guide.md |
locales/en.json | de | locales/de.json |
README.md | es | es/README.md |
Используйте полное имя директории или файла как код локали. Например, если исходные файлы находятся в docs/en-US/, укажите "sourceLocale": "en-US", а не "en". Если исходные строки находятся в messages/en.json, укажите "sourceLocale": "en".
Если исходный путь содержит директорию локали, приложение заменяет эту директорию. Если исходный путь — это файл с именем локали, приложение заменяет имя файла. Если ни один из этих вариантов не подходит, приложение поместит переведённый файл в новую директорию целевой локали рядом с исходным файлом.
Рабочие процессы#
Push в ветку по умолчанию#
Когда подходящий исходный файл добавляется или изменяется в ветке по умолчанию, приложение переводит его и коммитит локализованные файлы в:
lingo/translations/<default-branch>Затем приложение открывает или обновляет pull request из этой ветки переводов обратно в ветку по умолчанию. Если ветка переводов уже существует, новые коммиты добавляются в неё.
Если в том же push целевой файл был добавлен или изменён, приложение считает его уже обработанным и переносит его в translation PR вместо перезаписи.
Pull request#
Если github.workflows.onPullRequest.enabled имеет значение true, приложение проверяет изменения в pull request на наличие подходящих исходных файлов. Переведённые файлы коммитятся напрямую в ветку PR.
Приложение не записывает изменения в ветки PR из форков и не записывает изменения в ветку по умолчанию из комментария в PR. Чтобы приложение могло коммитить переводы, pull request должен оставаться открытым.
В PR Lingo.dev обновляет комментарий, добавляя переведённые файлы и информацию о возможных ошибках.
Инкрементальные обновления и восстановление#
Для существующих целевых файлов приложение переводит только те изменения в исходниках, которые может обнаружить, вместо полной перегенерации файла. Для новых целевых файлов оно создаёт локализованную версию для каждой настроенной целевой локали.
Если при предыдущей локализации PR было пропущено изменение в исходнике или произошёл сбой до обновления целевого файла, следующая синхронизация PR сможет восстановить состояние: приложение сравнит исходник в PR с исходником в базовой ветке и переведёт пропущенное изменение.
Если исходный файл больше не существует в коммите, который обрабатывается, приложение пропускает его.
Режим одобрения#
Установите github.safety.requireApproval в значение true, если хотите добавить этап одобрения человеком перед запуском автоматических переводов.
При push в ветку по умолчанию проверка Lingo.dev показывает действия Approve и Deny. В pull request приложение публикует комментарий с предложением перевода; ответьте с помощью:
/lingo approveКоманды /lingo translate с ограниченной областью действия не требуют этого этапа одобрения.
Ручная команда для PR#
Используйте /lingo в комментарии к pull request, чтобы добавить недостающие переводы или принудительно запустить перевод для конкретных файлов.
/lingo translate docs/en/**/*.md/lingo translate docs/en/**/*.mdx --locales fr,es/lingo translate docs/en/**/*.md --forceСправочник команд:
| Команда | Описание |
|---|---|
/lingo | Показывает справку. |
/lingo help | Показывает справку. |
/lingo translate <glob>... | Переводит отсутствующие целевые файлы для подходящих исходных файлов. |
/lingo translate <glob>... --locales fr,es | Ограничивает запуск настроенными целевыми локалями. Значения локалей парсер команд приводит к нижнему регистру. |
/lingo translate <glob>... --force | Переводит каждый подходящий исходник и каждую локаль в текущей области, перезаписывая существующие целевые файлы. |
/lingo approve | Одобряет ожидающее предложение перевода в PR. |
Команда должна быть на отдельной строке. Glob-шаблоны сопоставляются только с файлами, которые также соответствуют настроенным исходным шаблонам files. Как и шаблоны в конфигурации, glob-шаблоны команды не могут начинаться с / и не могут содержать ...
По умолчанию /lingo translate работает в режиме дозаполнения: команда создаёт только те целевые файлы, которых нет в ветке PR. Добавьте --force, если хотите заново сгенерировать существующие целевые файлы.
Поддерживаемые форматы#
GitHub App определяет эти форматы по расширению файла:
- JSON (
.json) - JSONC (
.jsonc) - Markdown (
.md) - MDX (
.mdx) - Markdoc
Документы OpenAPI в YAML тоже поддерживаются, но автоматически не распознаются. Укажите "format": "yaml-openapi" в шаблоне файла:
{
"files": [
{ "pattern": "openapi/en.yaml", "format": "yaml-openapi" }
]
}Крупные обновления#
Приложение может разбивать результаты перевода на несколько коммитов. Это происходит, если за один запуск нужно записать более 100 файлов в одном коммите или более 5 МБ содержимого переведённых файлов в одном коммите.
В этом случае в сообщениях коммитов будет указан номер пакета, например:
feat: Lingo.dev translations (1/3)
feat: Lingo.dev translations (2/3)
feat: Lingo.dev translations (3/3)Что происходит, если ничего не совпало#
Если .lingo/config.json отсутствует, приложение молча пропускает репозиторий. Когда конфигурация появляется, некорректная конфигурация приводит к ошибке в проверке, а в PR — к комментарию с ошибкой валидации.
Если ни один изменённый файл не соответствует вашим исходным шаблонам, приложение завершит работу без записи переводов. Для /lingo translate бот ответит коротким объяснением, например: нет подходящих файлов, нет подходящих локалей или все целевые файлы уже существуют.
