Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
115 changes: 115 additions & 0 deletions .github/workflows/audit-glossaries.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
# Weekly audit of translation glossaries against source-of-truth localization
# files in the platform and SDK repos.
#
# Compares scripts/glossaries/*.json against the actual UI translations in
# the Braze platform dashboard, Android SDK, Swift SDK, and GrapesJS editor
# to surface terminology drift.
#
# Creates a GitHub Issue when mismatches or missing terms are detected.
name: Audit glossaries

on:
schedule:
- cron: '0 6 * * 0' # Every Sunday at 06:00 UTC
workflow_dispatch:

permissions:
contents: read
issues: write

jobs:
audit:
runs-on: ubuntu-latest
timeout-minutes: 30

steps:
- name: Checkout braze-docs
uses: actions/checkout@v4

- name: Clone reference repos
env:
GH_TOKEN: ${{ secrets.REFERENCE_REPO_TOKEN }}
run: |
# Clone repos needed for localization comparison.
# Public repos use HTTPS; private repos use the PAT.
clone_repo() {
local org=$1 repo=$2
echo "Cloning $org/$repo..."
git clone --depth 1 --filter=blob:none --sparse \
"https://x-access-token:${GH_TOKEN}@github.com/${org}/${repo}.git" \
"../${repo}" 2>/dev/null || \
git clone --depth 1 \
"https://github.com/${org}/${repo}.git" \
"../${repo}" 2>/dev/null || \
echo " WARNING: Could not clone ${org}/${repo} — skipping"
}

clone_repo Appboy platform
clone_repo braze-inc braze-android-sdk
clone_repo braze-inc braze-swift-sdk
clone_repo braze-inc grapesjs

# Sparse-checkout only the locale directories we need
for repo in platform braze-android-sdk braze-swift-sdk grapesjs; do
if [ -d "../${repo}" ]; then
cd "../${repo}"
git sparse-checkout init --cone 2>/dev/null || true
case $repo in
platform)
git sparse-checkout set dashboard/config/locales 2>/dev/null || true ;;
braze-android-sdk)
git sparse-checkout set android-sdk-ui/src/main/res 2>/dev/null || true ;;
braze-swift-sdk)
git sparse-checkout set Sources/BrazeUI/Resources/Localization 2>/dev/null || true ;;
grapesjs)
git sparse-checkout set src/i18n/locale 2>/dev/null || true ;;
esac
cd "$GITHUB_WORKSPACE"
fi
done

- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.12'

- name: Run glossary audit
id: audit
run: |
python scripts/audit_glossaries.py \
--platform-repo ../platform \
--android-repo ../braze-android-sdk \
--swift-repo ../braze-swift-sdk \
--grapesjs-repo ../grapesjs \
--output glossary_audit_report.json || true

# Read stats for the issue
if [ -f glossary_audit_report.json ]; then
mismatches=$(python3 -c "import json; r=json.load(open('glossary_audit_report.json')); print(r['stats']['total_mismatches'])")
missing=$(python3 -c "import json; r=json.load(open('glossary_audit_report.json')); print(r['stats']['total_missing'])")
echo "mismatches=${mismatches}" >> "$GITHUB_OUTPUT"
echo "missing=${missing}" >> "$GITHUB_OUTPUT"
echo "has_findings=$([ $mismatches -gt 0 ] || [ $missing -gt 0 ] && echo true || echo false)" >> "$GITHUB_OUTPUT"
else
echo "has_findings=false" >> "$GITHUB_OUTPUT"
fi

- name: Create or update issue
if: steps.audit.outputs.has_findings == 'true'
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
DATE=$(date +%Y-%m-%d)
TITLE="Glossary audit: ${{ steps.audit.outputs.mismatches }} mismatches, ${{ steps.audit.outputs.missing }} missing terms ($DATE)"

BODY=$(cat glossary_audit_report.md)

# Close any previous open audit issues
gh issue list --label "glossary-audit" --state open --json number -q '.[].number' | while read num; do
gh issue close "$num" --comment "Superseded by new audit run on $DATE."
done

gh issue create \
--title "$TITLE" \
--body "$BODY" \
--label "glossary-audit"
16 changes: 13 additions & 3 deletions .github/workflows/auto-translate.yml
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,13 @@ jobs:
if: steps.changes.outputs.count != '0'
run: python scripts/auto_translate.py translate --changed-files changed_files.txt

# ------------------------------------------------------------------
# Quality checks
# ------------------------------------------------------------------
- name: Run translation QC checks
if: steps.changes.outputs.count != '0'
run: python scripts/auto_translate.py qc

# ------------------------------------------------------------------
# Build verification + auto-fix loop
# ------------------------------------------------------------------
Expand All @@ -104,9 +111,12 @@ jobs:
ruby-version: '3.3'
bundler-cache: true

- name: Clean up orphaned translations
if: steps.changes.outputs.count != '0'
run: python scripts/clean_orphaned_translations.py
# Orphaned translation cleanup is temporarily disabled while the
# clean_orphaned_translations.py script is validated to avoid
# accidental deletions. Re-enable once confirmed safe in production.
# - name: Clean up orphaned translations
# if: steps.changes.outputs.count != '0'
# run: python scripts/clean_orphaned_translations.py

- name: Verify builds and fix errors
if: steps.changes.outputs.count != '0'
Expand Down
6 changes: 6 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,9 @@ braze-docs.iml
# Braze scripts
scripts/temp
node_modules

# Generated translation/audit artifacts
translation_results.json
translation_pr_body.md
qc_results.json
glossary_audit_report.*
Loading