feat: Add group field to modelSpecs for flexible grouping #2771
Workflow file for this run
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |