mirror of
https://github.com/danny-avila/LibreChat.git
synced 2025-09-21 21:50:49 +02:00

* fix: error when updating bookmarks if no query data * feat: localize bookmark dialog, form labels and validation messages, also improve validation * feat: add localization for EmptyPromptPreview component and update translation.json * chore: add missing localizations for static UI text * chore: update AgentPanelContextType and useGetAgentsConfig to support null configurations * refactor: update agent categories to support localization and custom properties, improve related typing * ci: add localization for 'All' category and update tab names in accessibility tests * chore: remove unused AgentCategoryDisplay component and its tests * chore: add localization handling for agent category selector * chore: enhance AgentCard to support localized category labels and add related tests * chore: enhance i18n unused keys detection to include additional source directories and improve handling for agent category keys
149 lines
5.6 KiB
YAML
149 lines
5.6 KiB
YAML
name: Detect Unused i18next Strings
|
|
|
|
# This workflow checks for unused i18n keys in translation files.
|
|
# It has special handling for:
|
|
# - com_ui_special_var_* keys that are dynamically constructed
|
|
# - com_agents_category_* keys that are stored in the database and used dynamically
|
|
|
|
on:
|
|
pull_request:
|
|
paths:
|
|
- "client/src/**"
|
|
- "api/**"
|
|
- "packages/data-provider/src/**"
|
|
- "packages/client/**"
|
|
- "packages/data-schemas/src/**"
|
|
|
|
jobs:
|
|
detect-unused-i18n-keys:
|
|
runs-on: ubuntu-latest
|
|
permissions:
|
|
pull-requests: write
|
|
steps:
|
|
- name: Checkout repository
|
|
uses: actions/checkout@v3
|
|
|
|
- name: Find unused i18next keys
|
|
id: find-unused
|
|
run: |
|
|
echo "🔍 Scanning for unused i18next keys..."
|
|
|
|
# Define paths
|
|
I18N_FILE="client/src/locales/en/translation.json"
|
|
SOURCE_DIRS=("client/src" "api" "packages/data-provider/src" "packages/client" "packages/data-schemas/src")
|
|
|
|
# Check if translation file exists
|
|
if [[ ! -f "$I18N_FILE" ]]; then
|
|
echo "::error title=Missing i18n File::Translation file not found: $I18N_FILE"
|
|
exit 1
|
|
fi
|
|
|
|
# Extract all keys from the JSON file
|
|
KEYS=$(jq -r 'keys[]' "$I18N_FILE")
|
|
|
|
# Track unused keys
|
|
UNUSED_KEYS=()
|
|
|
|
# Check if each key is used in the source code
|
|
for KEY in $KEYS; do
|
|
FOUND=false
|
|
|
|
# Special case for dynamically constructed special variable keys
|
|
if [[ "$KEY" == com_ui_special_var_* ]]; then
|
|
# Check if TSpecialVarLabel is used in the codebase
|
|
for DIR in "${SOURCE_DIRS[@]}"; do
|
|
if grep -r --include=\*.{js,jsx,ts,tsx} -q "TSpecialVarLabel" "$DIR"; then
|
|
FOUND=true
|
|
break
|
|
fi
|
|
done
|
|
|
|
# Also check if the key is directly used somewhere
|
|
if [[ "$FOUND" == false ]]; then
|
|
for DIR in "${SOURCE_DIRS[@]}"; do
|
|
if grep -r --include=\*.{js,jsx,ts,tsx} -q "$KEY" "$DIR"; then
|
|
FOUND=true
|
|
break
|
|
fi
|
|
done
|
|
fi
|
|
# Special case for agent category keys that are dynamically used from database
|
|
elif [[ "$KEY" == com_agents_category_* ]]; then
|
|
# Check if agent category localization is being used
|
|
for DIR in "${SOURCE_DIRS[@]}"; do
|
|
# Check for dynamic category label/description usage
|
|
if grep -r --include=\*.{js,jsx,ts,tsx} -E "category\.(label|description).*startsWith.*['\"]com_" "$DIR" > /dev/null 2>&1 || \
|
|
# Check for the method that defines these keys
|
|
grep -r --include=\*.{js,jsx,ts,tsx} "ensureDefaultCategories" "$DIR" > /dev/null 2>&1 || \
|
|
# Check for direct usage in agentCategory.ts
|
|
grep -r --include=\*.ts -E "label:.*['\"]$KEY['\"]" "$DIR" > /dev/null 2>&1 || \
|
|
grep -r --include=\*.ts -E "description:.*['\"]$KEY['\"]" "$DIR" > /dev/null 2>&1; then
|
|
FOUND=true
|
|
break
|
|
fi
|
|
done
|
|
|
|
# Also check if the key is directly used somewhere
|
|
if [[ "$FOUND" == false ]]; then
|
|
for DIR in "${SOURCE_DIRS[@]}"; do
|
|
if grep -r --include=\*.{js,jsx,ts,tsx} -q "$KEY" "$DIR"; then
|
|
FOUND=true
|
|
break
|
|
fi
|
|
done
|
|
fi
|
|
else
|
|
# Regular check for other keys
|
|
for DIR in "${SOURCE_DIRS[@]}"; do
|
|
if grep -r --include=\*.{js,jsx,ts,tsx} -q "$KEY" "$DIR"; then
|
|
FOUND=true
|
|
break
|
|
fi
|
|
done
|
|
fi
|
|
|
|
if [[ "$FOUND" == false ]]; then
|
|
UNUSED_KEYS+=("$KEY")
|
|
fi
|
|
done
|
|
|
|
# Output results
|
|
if [[ ${#UNUSED_KEYS[@]} -gt 0 ]]; then
|
|
echo "🛑 Found ${#UNUSED_KEYS[@]} unused i18n keys:"
|
|
echo "unused_keys=$(echo "${UNUSED_KEYS[@]}" | jq -R -s -c 'split(" ")')" >> $GITHUB_ENV
|
|
for KEY in "${UNUSED_KEYS[@]}"; do
|
|
echo "::warning title=Unused i18n Key::'$KEY' is defined but not used in the codebase."
|
|
done
|
|
else
|
|
echo "✅ No unused i18n keys detected!"
|
|
echo "unused_keys=[]" >> $GITHUB_ENV
|
|
fi
|
|
|
|
- name: Post verified comment on PR
|
|
if: env.unused_keys != '[]'
|
|
run: |
|
|
PR_NUMBER=$(jq --raw-output .pull_request.number "$GITHUB_EVENT_PATH")
|
|
|
|
# Format the unused keys list as checkboxes for easy manual checking.
|
|
FILTERED_KEYS=$(echo "$unused_keys" | jq -r '.[]' | grep -v '^\s*$' | sed 's/^/- [ ] `/;s/$/`/' )
|
|
|
|
COMMENT_BODY=$(cat <<EOF
|
|
### 🚨 Unused i18next Keys Detected
|
|
|
|
The following translation keys are defined in \`translation.json\` but are **not used** in the codebase:
|
|
|
|
$FILTERED_KEYS
|
|
|
|
⚠️ **Please remove these unused keys to keep the translation files clean.**
|
|
EOF
|
|
)
|
|
|
|
gh api "repos/${{ github.repository }}/issues/${PR_NUMBER}/comments" \
|
|
-f body="$COMMENT_BODY" \
|
|
-H "Authorization: token ${{ secrets.GITHUB_TOKEN }}"
|
|
env:
|
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
|
|
- name: Fail workflow if unused keys found
|
|
if: env.unused_keys != '[]'
|
|
run: exit 1
|