diff --git a/.github/scripts/test-validate-registry-translations.sh b/.github/scripts/test-validate-registry-translations.sh new file mode 100755 index 0000000..d320bb0 --- /dev/null +++ b/.github/scripts/test-validate-registry-translations.sh @@ -0,0 +1,66 @@ +#!/usr/bin/env bash +set -euo pipefail + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +VALIDATE="$SCRIPT_DIR/validate-registry-translations.sh" + +PASS=0 +FAIL=0 +TMPDIR_ROOT="$(mktemp -d)" +trap 'rm -rf "$TMPDIR_ROOT"' EXIT + +assert_passes() { + local desc="$1" + shift + local translations_dir + translations_dir="$(mktemp -d "$TMPDIR_ROOT/translations.XXXXXX")" + for locale in "$@"; do + printf '{}\n' > "$translations_dir/$locale.json" + done + + local output + if output="$(bash "$VALIDATE" "$translations_dir" 2>&1)"; then + echo " PASS: $desc" + PASS=$((PASS + 1)) + else + echo " FAIL: $desc" + echo " output: $output" + FAIL=$((FAIL + 1)) + fi +} + +assert_rejects() { + local desc="$1" + local expect_substr="$2" + shift 2 + local translations_dir + translations_dir="$(mktemp -d "$TMPDIR_ROOT/translations.XXXXXX")" + for locale in "$@"; do + printf '{}\n' > "$translations_dir/$locale.json" + done + + local output rc=0 + output="$(bash "$VALIDATE" "$translations_dir" 2>&1)" || rc=$? + if [[ "$rc" -eq 1 && "$output" == *"$expect_substr"* ]]; then + echo " PASS: $desc" + PASS=$((PASS + 1)) + else + echo " FAIL: $desc (expected exit 1 containing '$expect_substr', got exit $rc)" + echo " output: $output" + FAIL=$((FAIL + 1)) + fi +} + +echo "=== registry translations validator tests ===" + +assert_passes "empty directory is valid" +assert_passes "all supported locale filenames are valid" \ + ar-MA de en-US es fr it ja ko nl pl pt zh-CN zh-TW +assert_rejects "underscore region separator is rejected" \ + "use BCP-47 dash form" en-US zh_CN +assert_rejects "unknown locale is rejected" \ + "Unsupported registry translation locale file(s): xx-YY" en-US xx-YY + +echo "" +echo "=== Results: $PASS passed, $FAIL failed ===" +[[ "$FAIL" -eq 0 ]] diff --git a/.github/scripts/test-validate-translations.sh b/.github/scripts/test-validate-translations.sh index ddf5b97..63dde6b 100755 --- a/.github/scripts/test-validate-translations.sh +++ b/.github/scripts/test-validate-translations.sh @@ -145,6 +145,11 @@ assert_rejects "unsupported locale filename is rejected" \ "tasks:en-US.json:$EN_BASIC" \ "tasks:xx-YY.json:$EN_BASIC" +assert_rejects "underscore locale filename is rejected" \ + "Unsupported locale file" \ + "tasks:en-US.json:$EN_BASIC" \ + "tasks:zh_CN.json:$EN_BASIC" + assert_rejects "tasksList taskKey missing from en-US is rejected" \ "not present in translations/en-US.json" \ "tasks:en-US.json:$EN_BASIC" \ diff --git a/.github/scripts/validate-registry-translations.sh b/.github/scripts/validate-registry-translations.sh new file mode 100755 index 0000000..a8bd491 --- /dev/null +++ b/.github/scripts/validate-registry-translations.sh @@ -0,0 +1,47 @@ +#!/usr/bin/env bash +# Validate locale filenames in commerce-apps-manifest/translations/. +# +# Usage: validate-registry-translations.sh +# +# Exit codes: +# 0 - locale filenames are valid +# 1 - one or more locale filenames are unsupported +# 2 - usage error (bad args or missing directory) + +set -euo pipefail + +if [[ $# -ne 1 ]]; then + echo "Usage: $(basename "$0") " >&2 + exit 2 +fi + +translations_dir="$1" + +if [[ ! -d "$translations_dir" ]]; then + echo "Registry translations directory not found: $translations_dir" >&2 + exit 2 +fi + +# Set of supported manifest locales. Region separators use BCP-47 dash form. +SUPPORTED_LOCALES=("ar-MA" "de" "en-US" "es" "fr" "it" "ja" "ko" "nl" "pl" "pt" "zh-CN" "zh-TW") + +unsupported_locales=() +while IFS= read -r locale_file; do + locale="$(basename "$locale_file" .json)" + supported_locale=false + for supported in "${SUPPORTED_LOCALES[@]}"; do + if [[ "$locale" == "$supported" ]]; then + supported_locale=true + break + fi + done + [[ "$supported_locale" == "false" ]] && unsupported_locales+=("$locale") +done < <(find "$translations_dir" -mindepth 1 -maxdepth 1 -type f -name '*.json' | sort) + +if [[ ${#unsupported_locales[@]} -gt 0 ]]; then + echo "Unsupported registry translation locale file(s): ${unsupported_locales[*]} (supported: ${SUPPORTED_LOCALES[*]}; use BCP-47 dash form for region separators)" >&2 + exit 1 +fi + +locale_count="$(find "$translations_dir" -mindepth 1 -maxdepth 1 -type f -name '*.json' | wc -l | tr -d ' ')" +echo "Registry translation locale filenames are valid ($locale_count file(s))" diff --git a/.github/workflows/verify-zip.yml b/.github/workflows/verify-zip.yml index 5f2dad1..7532b21 100644 --- a/.github/workflows/verify-zip.yml +++ b/.github/workflows/verify-zip.yml @@ -5,6 +5,7 @@ on: types: [opened, reopened, synchronize, edited, ready_for_review] paths: - '**/*.zip' + - 'commerce-apps-manifest/translations/**' jobs: verify-zips: @@ -569,3 +570,9 @@ jobs: rm -rf "$tmpdir" done < changed_zips.txt + + - name: Step 10 - Validate registry translation locale filenames + shell: bash + run: | + bash ".github/scripts/validate-registry-translations.sh" \ + "commerce-apps-manifest/translations" diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 3cb042c..99adf36 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -513,7 +513,9 @@ Locale filenames are validated against the set of locales supported by Business | Chinese (Simplified) | `zh-CN.json` | | Chinese (Traditional) | `zh-TW.json` | -CI will reject locale files whose filenames are outside this set. +CI enforces this filename set for both registry-level files under +`commerce-apps-manifest/translations/` and locale files packaged under +`app-configuration/translations/`. ---