Lingo.dev GitHub App은 .lingo/config.json을 사용해 저장소에 지속적인 로컬라이제이션을 설정합니다.
사전 준비 사항#
앱을 설치하기 전에 다음을 준비해 주세요:
- GitHub 통합 기능이 활성화된 Lingo.dev 조직
- 해당 조직에 있는 로컬라이제이션 엔진
- 연결하려는 GitHub 조직 또는 저장소에 대한 관리자 권한
GitHub 조직 관리자가 아니라면 GitHub에서 설치를 요청할 수 있습니다. Lingo.dev가 선택한 저장소에 액세스하려면 GitHub 조직 관리자가 해당 요청을 먼저 승인해야 합니다.
GitHub App 연결#
- Lingo.dev에서 조직을 엽니다.
- Settings로 이동합니다.
- Integrations 섹션에서 **GitHub (App)**을 찾습니다.
- GitHub (App) 행에서 Connect를 클릭합니다.
- GitHub에서 앱을 설치할 계정 또는 조직을 선택합니다.
- All repositories 또는 Only select repositories 중 하나를 선택합니다.
- Install를 클릭합니다.
설치가 완료되면 Lingo.dev의 **Settings > GitHub (App)**에서 연결된 GitHub 계정과 저장소를 확인할 수 있습니다. 나중에 저장소를 추가하거나 제거해야 할 때는 같은 설정 카드의 Manage repositories on GitHub를 사용하세요.
설치 요청이 승인 대기 중이라면 GitHub 관리자는 GitHub의 조직 Settings > GitHub Apps 영역에서 이를 검토할 수 있습니다. GitHub는 조직 설정에서 조직 소유자에게 대기 중인 앱 요청도 표시합니다.
저장소 config 추가#
앱을 설치한 저장소에 .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 컴포넌트 prop과 Markdoc 태그 속성입니다. |
lockedKeys | JSON, JSONC | 항상 소스 값으로 유지되어 절대 번역되지 않는 키 경로입니다. |
preservedKeys | JSON, JSONC | 기존 대상 값으로 유지되며 다시 번역되지 않는 키 경로입니다. |
injectLocale | JSON, JSONC | 지정한 키에 대상 로캘 코드를 출력으로 기록합니다(기본값은 language). |
translateComponentProps 항목은 prop 이름일 수도 있고, 이 경우 모든 컴포넌트 또는 태그의 해당 prop에 적용됩니다. 또는 prop의 적용 범위를 이름이 지정된 컴포넌트나 태그로 한정하는 객체일 수도 있습니다:
{
"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" }
}
]
}로컬라이즈된 파일이 저장되는 위치#
앱은 소스 경로와 config에 지정한 로캘 코드를 바탕으로 각 대상 경로를 결정합니다:
| 소스 경로 | 대상 로캘 | 출력 경로 |
|---|---|---|
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에서 대상 파일이 추가되거나 변경된 경우 앱은 해당 파일이 이미 처리된 것으로 간주하고, 덮어쓰는 대신 번역 PR에 그대로 반영합니다.
Pull request#
github.workflows.onPullRequest.enabled이 true이면 앱은 pull request의 변경 사항에서 일치하는 소스 파일을 확인합니다. 번역된 파일은 PR 브랜치에 직접 커밋됩니다.
앱은 포크된 PR 브랜치에는 기록하지 않으며, PR 댓글만으로 기본 브랜치에 기록하지도 않습니다. 앱이 번역을 커밋하려면 pull request가 열린 상태여야 합니다.
PR에서는 Lingo.dev가 번역된 파일과 실패 항목을 포함한 PR 댓글을 업데이트합니다.
증분 업데이트 및 복구#
기존 대상 파일의 경우 앱은 전체 파일을 다시 생성하지 않고, 감지할 수 있는 소스 변경분만 번역합니다. 새 대상 파일의 경우 설정된 각 대상 로캘에 맞는 로컬라이즈된 파일을 생성합니다.
이전 PR 로컬라이제이션에서 소스 변경이 누락되었거나 대상 파일을 업데이트하기 전에 실패했다면, 다음 PR 동기화에서 PR 소스를 기본 브랜치 소스와 비교해 누락된 변경 사항을 번역함으로써 복구할 수 있습니다.
처리 중인 커밋에 소스 파일이 더 이상 존재하지 않으면 앱은 해당 파일을 건너뜁니다.
승인 모드#
자동 번역을 실행하기 전에 사람의 승인 단계를 두고 싶다면 github.safety.requireApproval을 true로 설정하세요.
기본 브랜치에 push되면 Lingo.dev check run에 Approve와 Deny 작업이 표시됩니다. pull request에서는 앱이 번역 제안 댓글을 게시하므로, 다음과 같이 답글을 남기면 됩니다:
/lingo approve범위가 지정된 /lingo translate 명령에는 이 승인 게이트가 적용되지 않습니다.
수동 PR 명령#
pull request 댓글에서 /lingo을 사용해 특정 파일의 번역을 보완하거나 강제로 실행할 수 있습니다.
/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 | 실행 범위를 config에 설정된 대상 로캘로 제한합니다. 로캘 값은 명령 파서에 의해 소문자로 변환됩니다. |
/lingo translate <glob>... --force | 범위 내의 모든 일치하는 소스와 로캘을 번역하며, 기존 대상 파일을 덮어씁니다. |
/lingo approve | PR에서 대기 중인 번역 제안을 승인합니다. |
명령은 반드시 단독 줄에 있어야 합니다. glob은 config에 설정한 files 소스 패턴과도 일치하는 파일을 대상으로 매칭됩니다. config 패턴과 마찬가지로 명령 glob도 /로 시작할 수 없고 ..를 포함할 수 없습니다.
기본적으로 /lingo translate은 backfill 모드로 실행됩니다. 즉, PR 브랜치에 없는 대상 파일만 생성합니다. 기존 대상 파일을 다시 생성하려면 --force를 추가하세요.
지원 형식#
GitHub App은 파일 확장자를 기준으로 다음 형식을 감지합니다:
- JSON (
.json) - JSONC (
.jsonc) - Markdown (
.md) - MDX (
.mdx) - Markdoc
YAML로 작성된 OpenAPI 문서도 지원하지만 자동으로 감지되지는 않습니다. 파일 패턴에 "format": "yaml-openapi"을 설정하세요:
{
"files": [
{ "pattern": "openapi/en.yaml", "format": "yaml-openapi" }
]
}대규모 업데이트#
한 번의 실행에서 단일 커밋에 100개를 초과하는 파일을 기록하거나, 번역된 파일 콘텐츠가 단일 커밋에서 5MB를 넘는 경우 앱은 번역 결과를 여러 커밋으로 나눌 수 있습니다.
이 경우 커밋 메시지에는 다음과 같이 배치 번호가 포함됩니다:
feat: Lingo.dev translations (1/3)
feat: Lingo.dev translations (2/3)
feat: Lingo.dev translations (3/3)일치하는 항목이 없을 때#
.lingo/config.json이 없으면 앱은 해당 저장소를 조용히 건너뜁니다. config가 생긴 뒤 config가 유효하지 않으면 check run이 실패하고, PR에서는 유효성 검사 오류가 담긴 댓글이 남습니다.
변경된 파일 중 소스 패턴과 일치하는 파일이 없으면 앱은 번역을 기록하지 않고 종료합니다. /lingo translate의 경우 봇이 일치하는 파일 없음, 일치하는 로캘 없음, 또는 모든 대상 파일이 이미 존재함과 같은 짧은 설명으로 답글을 남깁니다.
