1+ name : Validate JSON Files
2+
3+ on :
4+ push :
5+ paths :
6+ - ' **/*.json'
7+ pull_request :
8+ paths :
9+ - ' **/*.json'
10+ workflow_dispatch : # Allows manual triggering
11+
12+ jobs :
13+ validate-json :
14+ runs-on : ubuntu-latest
15+
16+ steps :
17+ - name : Checkout repository
18+ uses : actions/checkout@v4
19+
20+ - name : Setup Node.js
21+ uses : actions/setup-node@v4
22+ with :
23+ node-version : ' 18'
24+
25+ - name : Install dependencies
26+ run : npm install -g ajv-cli ajv-formats
27+
28+ - name : Create JSON schema for validation
29+ run : |
30+ cat > schema.json << 'EOL'
31+ {
32+ "$schema": "http://json-schema.org/draft-07/schema#",
33+ "type": "array",
34+ "items": {
35+ "type": "object",
36+ "required": ["version", "new"],
37+ "properties": {
38+ "version": {
39+ "type": "string",
40+ "pattern": "^\\d+\\.\\d+$|^\\d+\\.\\d+\\.\\d+$"
41+ },
42+ "subVersion": {
43+ "type": "string",
44+ "pattern": "^\\d+\\.\\d+\\.\\d+$"
45+ },
46+ "new": {
47+ "type": "array",
48+ "items": {
49+ "type": "object",
50+ "required": ["icon", "title", "subtitle", "body"],
51+ "properties": {
52+ "icon": { "type": "string" },
53+ "title": { "type": "string" },
54+ "subtitle": { "type": "string" },
55+ "body": { "type": "string" }
56+ }
57+ },
58+ "minItems": 1
59+ }
60+ }
61+ },
62+ "minItems": 1
63+ }
64+ EOL
65+
66+ - name : Scan for JSON files
67+ id : scan
68+ run : |
69+ echo "Scanning for JSON files..."
70+ # Create a temporary file to store the list of JSON files
71+ touch json_files.txt
72+
73+ # Find all data.json files and group them by language
74+ find Demo -name "data.json" -print0 | while IFS= read -r -d '' FILE; do
75+ # Extract the language from the directory path
76+ LANG_DIR=$(dirname "$FILE")
77+ LANG=$(basename "$LANG_DIR")
78+ echo "$LANG:$FILE" >> json_files.txt
79+ done
80+
81+ echo "Found the following JSON files for validation:"
82+ cat json_files.txt
83+
84+ echo "Scan completed."
85+
86+ - name : Validate JSON syntax per language
87+ run : |
88+ echo "Validating JSON syntax for each language..."
89+ ERROR=0
90+
91+ # Process each file by language
92+ while IFS=':' read -r LANG_DIR FILE || [ -n "$FILE" ]; do
93+ echo "Checking syntax for language: $LANG_DIR - $FILE"
94+
95+ # Check JSON syntax
96+ if ! jq empty "$FILE" 2>/dev/null; then
97+ echo "❌ Invalid JSON syntax in $LANG_DIR ($FILE)"
98+ ERROR=1
99+ else
100+ echo "✅ JSON syntax is valid for $LANG_DIR"
101+ fi
102+ done < json_files.txt
103+
104+ if [ $ERROR -ne 0 ]; then
105+ echo "JSON syntax validation failed"
106+ exit 1
107+ fi
108+
109+ - name : Validate schema per language
110+ run : |
111+ echo "Validating JSON schema for each language..."
112+ ERROR=0
113+
114+ # Process each file by language
115+ while IFS=':' read -r LANG_DIR FILE || [ -n "$FILE" ]; do
116+ echo "Validating schema for language: $LANG_DIR - $FILE"
117+
118+ # Validate against schema
119+ if ! npx ajv -s schema.json -d "$FILE" --strict=false; then
120+ echo "❌ $LANG_DIR ($FILE) does not match the required schema"
121+ ERROR=1
122+ else
123+ echo "✅ Schema is valid for $LANG_DIR"
124+ fi
125+ done < json_files.txt
126+
127+ if [ $ERROR -ne 0 ]; then
128+ echo "JSON schema validation failed"
129+ exit 1
130+ fi
131+
132+ echo "All JSON files are valid! 🎉"
133+
134+ check-localization-completeness :
135+ runs-on : ubuntu-latest
136+ needs : validate-json
137+
138+ steps :
139+ - name : Checkout repository
140+ uses : actions/checkout@v4
141+
142+ - name : Find JSON files
143+ id : find-json
144+ run : |
145+ # Create a directory to store extracted language files
146+ mkdir -p extracted_langs
147+
148+ # Find the base (en) language JSON file
149+ BASE_FILE=$(find Demo -path "*/en.lproj/data.json" -print -quit)
150+ if [ ! -f "$BASE_FILE" ]; then
151+ echo "❌ Base language file (en.lproj/data.json) not found!"
152+ exit 1
153+ fi
154+
155+ # Find all localized JSON files
156+ find Demo -name "data.json" | grep -v "$BASE_FILE" > localized_files.txt
157+
158+ echo "Base file: $BASE_FILE"
159+ echo "Found $(wc -l < localized_files.txt) localized files"
160+
161+ - name : Check for missing versions
162+ run : |
163+ BASE_FILE=$(find Demo -path "*/en.lproj/data.json" -print -quit)
164+
165+ # Extract version numbers from base file
166+ jq -r '.[].version' "$BASE_FILE" | sort -V > base_versions.txt
167+
168+ # Create a report file
169+ touch localization_report.md
170+ echo "# Localization Completeness Report" >> localization_report.md
171+ echo "Generated on $(date)" >> localization_report.md
172+ echo "" >> localization_report.md
173+
174+ # Check each localized file
175+ while read -r LOC_FILE; do
176+ LANG_DIR=$(dirname "$LOC_FILE")
177+ LANG=$(basename "$LANG_DIR" | sed 's/\.lproj//')
178+
179+ echo "## Checking $LANG" >> localization_report.md
180+
181+ # Extract version numbers from localized file
182+ jq -r '.[].version' "$LOC_FILE" | sort -V > "${LANG}_versions.txt"
183+
184+ # Find missing versions
185+ MISSING_VERSIONS=$(comm -23 base_versions.txt "${LANG}_versions.txt")
186+
187+ if [ -n "$MISSING_VERSIONS" ]; then
188+ echo "❌ $LANG is missing versions: $MISSING_VERSIONS"
189+ echo "### Missing versions:" >> localization_report.md
190+ echo '```' >> localization_report.md
191+ echo "$MISSING_VERSIONS" >> localization_report.md
192+ echo '```' >> localization_report.md
193+ echo "" >> localization_report.md
194+ EXIT_CODE=1
195+ else
196+ echo "✅ $LANG has all versions from base language"
197+ echo "✅ All versions present" >> localization_report.md
198+ echo "" >> localization_report.md
199+ fi
200+
201+ # Check content for each version
202+ echo "### Content comparison:" >> localization_report.md
203+
204+ while read -r VERSION; do
205+ # Extract base data for this version
206+ jq -r --arg v "$VERSION" '.[] | select(.version == $v)' "$BASE_FILE" > "base_${VERSION}.json"
207+ jq -r --arg v "$VERSION" '.[] | select(.version == $v)' "$LOC_FILE" > "${LANG}_${VERSION}.json"
208+
209+ if [ -s "${LANG}_${VERSION}.json" ]; then
210+ # Count items in the "new" array for base and localized
211+ BASE_ITEMS=$(jq -r '.new | length' "base_${VERSION}.json")
212+ LOC_ITEMS=$(jq -r '.new | length' "${LANG}_${VERSION}.json")
213+
214+ if [ "$BASE_ITEMS" -ne "$LOC_ITEMS" ]; then
215+ echo "❌ $LANG version $VERSION has $LOC_ITEMS items (base has $BASE_ITEMS)"
216+ echo "- Version $VERSION: $LOC_ITEMS/$BASE_ITEMS items ❌" >> localization_report.md
217+ EXIT_CODE=1
218+ else
219+ echo "✅ $LANG version $VERSION has all $BASE_ITEMS items"
220+ echo "- Version $VERSION: $LOC_ITEMS/$BASE_ITEMS items ✅" >> localization_report.md
221+ fi
222+ fi
223+ done < base_versions.txt
224+
225+ echo "" >> localization_report.md
226+ done < localized_files.txt
227+
228+ cat localization_report.md
229+
230+ # Exit with the accumulated status
231+ if [ "$EXIT_CODE" -eq 1 ]; then
232+ echo "❌ Localization check failed - some languages are missing versions or items"
233+ exit 1
234+ else
235+ echo "✅ All languages have complete translations"
236+ fi
237+
238+ - name : Upload Localization Report
239+ if : always()
240+ uses : actions/upload-artifact@v4
241+ with :
242+ name : localization-report
243+ path : localization_report.md
0 commit comments