Skip to content

Commit 7bf29b8

Browse files
Add automation to detect missing locale translations from dependent packages (GH-110)
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
2 parents 3da9b8b + e63a075 commit 7bf29b8

File tree

2 files changed

+169
-0
lines changed

2 files changed

+169
-0
lines changed

.github/workflows/locales.yml

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
name: locales
2+
3+
on:
4+
push:
5+
branches: [ master ]
6+
pull_request:
7+
branches: [ master ]
8+
9+
jobs:
10+
update:
11+
runs-on: ubuntu-latest
12+
permissions:
13+
contents: read
14+
issues: write
15+
16+
steps:
17+
- name: Checkout code
18+
uses: actions/checkout@v2
19+
20+
- name: Setup Python
21+
uses: actions/setup-python@v3
22+
23+
- name: Check locales
24+
id: check
25+
continue-on-error: true
26+
run: python scripts/check-locales
27+
28+
- name: Read issue body
29+
if: steps.check.outcome == 'failure'
30+
id: issue_body
31+
run: |
32+
if [ -f /tmp/missing_locales_issue.md ]; then
33+
echo "issue_body<<EOF" >> $GITHUB_OUTPUT
34+
cat /tmp/missing_locales_issue.md >> $GITHUB_OUTPUT
35+
echo "EOF" >> $GITHUB_OUTPUT
36+
fi
37+
38+
- name: Check existing issue
39+
if: steps.check.outcome == 'failure'
40+
id: check_issue
41+
env:
42+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
43+
run: |
44+
ISSUE_COUNT=$(gh issue list --label "missing-locales" --state open --json number --jq 'length')
45+
echo "existing_issues=$ISSUE_COUNT" >> $GITHUB_OUTPUT
46+
47+
- name: Create issue
48+
if: steps.check.outcome == 'failure' && steps.check_issue.outputs.existing_issues == '0'
49+
env:
50+
ISSUE_BODY: ${{ steps.issue_body.outputs.issue_body }}
51+
uses: actions/github-script@v7
52+
with:
53+
github-token: ${{ secrets.GITHUB_TOKEN }}
54+
script: |
55+
const issueBody = process.env.ISSUE_BODY;
56+
await github.rest.issues.create({
57+
owner: context.repo.owner,
58+
repo: context.repo.repo,
59+
title: 'Missing locale translations detected',
60+
body: issueBody,
61+
labels: ['missing-locales', 'translation', 'enhancement']
62+
});
63+
64+
- name: Update issue
65+
if: steps.check.outcome == 'failure' && steps.check_issue.outputs.existing_issues != '0'
66+
env:
67+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
68+
run: |
69+
ISSUE_NUMBER=$(gh issue list --label "missing-locales" --state open --json number --jq '.[0].number')
70+
gh issue comment $ISSUE_NUMBER --body "The automated locale check has been run again."

scripts/check-locales/__main__.py

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
import json
2+
import os
3+
import re
4+
import subprocess
5+
import sys
6+
from pathlib import Path
7+
8+
9+
project_root = Path(__file__).parent.parent.parent
10+
locale_file = project_root / "src" / "locale.ts"
11+
12+
with open(locale_file, 'r') as f:
13+
content = f.read()
14+
15+
locale_pattern = r'^export const (\w+) = \{'
16+
existing_locales = set(re.findall(locale_pattern, content, re.MULTILINE))
17+
18+
locale_name_pattern = re.compile(r'^[a-z]{2,3}[A-Z][A-Za-z]{1,3}$')
19+
20+
try:
21+
result = subprocess.run(
22+
['curl', '-s', '-H', 'User-Agent: react-phone-hooks',
23+
'https://api.github.com/repos/ant-design/ant-design/contents/components/locale'],
24+
capture_output=True,
25+
text=True,
26+
timeout=30
27+
)
28+
if result.returncode == 0 and result.stdout.strip():
29+
files = json.loads(result.stdout)
30+
antd_locales = set()
31+
for file in files:
32+
name = file['name']
33+
if name.endswith('.ts') and name != 'index.ts':
34+
locale_name = name.replace('.ts', '').replace('_', '')
35+
if locale_name_pattern.match(locale_name):
36+
antd_locales.add(locale_name)
37+
else:
38+
antd_locales = set()
39+
except:
40+
antd_locales = set()
41+
42+
try:
43+
result = subprocess.run(
44+
['curl', '-s', '-H', 'User-Agent: react-phone-hooks',
45+
'https://api.github.com/repos/mui/material-ui/contents/packages/mui-material/src/locale'],
46+
capture_output=True,
47+
text=True,
48+
timeout=30
49+
)
50+
if result.returncode == 0 and result.stdout.strip():
51+
files = json.loads(result.stdout)
52+
mui_locales = set()
53+
for file in files:
54+
name = file['name']
55+
if name.endswith('.ts') and name != 'index.ts':
56+
locale_name = name.replace('.ts', '')
57+
if locale_name_pattern.match(locale_name):
58+
mui_locales.add(locale_name)
59+
else:
60+
mui_locales = set()
61+
except:
62+
mui_locales = set()
63+
64+
missing_from_antd = antd_locales - existing_locales
65+
missing_from_mui = mui_locales - existing_locales
66+
all_missing = missing_from_antd | missing_from_mui
67+
68+
if all_missing:
69+
locale_sources = {}
70+
for locale in all_missing:
71+
sources = []
72+
if locale in missing_from_antd:
73+
sources.append('antd')
74+
if locale in missing_from_mui:
75+
sources.append('mui')
76+
locale_sources[locale] = sources
77+
78+
issue_body = "Update the translations, adding the following language keys:\n\n"
79+
for locale in sorted(locale_sources.keys()):
80+
sources_str = ', '.join(f'`{s}`' for s in locale_sources[locale])
81+
issue_body += f" - `{locale}` ({sources_str})\n"
82+
83+
output_file = Path("/tmp/missing_locales_issue.md")
84+
with open(output_file, 'w') as f:
85+
f.write(issue_body)
86+
87+
if os.getenv('GITHUB_OUTPUT'):
88+
with open(os.getenv('GITHUB_OUTPUT'), 'a') as f:
89+
f.write(f"has_missing=true\n")
90+
f.write(f"count={len(all_missing)}\n")
91+
92+
sys.exit(1)
93+
else:
94+
if os.getenv('GITHUB_OUTPUT'):
95+
with open(os.getenv('GITHUB_OUTPUT'), 'a') as f:
96+
f.write(f"has_missing=false\n")
97+
f.write(f"count=0\n")
98+
99+
sys.exit(0)

0 commit comments

Comments
 (0)