name: Frontend Checks on: push: branches: [main] paths: - "frontend/**" - ".github/workflows/frontend-checks.yml" pull_request: branches: [main] paths: - "frontend/**" - ".github/workflows/frontend-checks.yml" workflow_call: jobs: build: name: Build & typecheck runs-on: ubuntu-latest defaults: run: working-directory: frontend steps: - uses: actions/checkout@v4 - uses: actions/setup-node@v4 with: node-version: "22" cache: npm cache-dependency-path: frontend/package-lock.json # npm install (not ci), same as the Dockerfile: the lockfile is produced on # Windows and lacks some Linux-only optional deps, which makes `npm ci` fail. - name: Install dependencies run: npm install --no-audit --no-fund # Russian sessions do not load en.json as a fallback (lib/i18n.ts), so a # key present only in en.json would show up raw in the Russian UI. - name: Locale keys parity (ru covers en) run: | node -e ' const flat = (o, p = "") => Object.entries(o).flatMap(([k, v]) => v && typeof v === "object" ? flat(v, p + k + ".") : [p + k]); const ru = new Set(flat(require("./src/locales/ru.json"))); const missing = flat(require("./src/locales/en.json")).filter((k) => !ru.has(k)); if (missing.length) { console.error("Missing in ru.json:\n" + missing.join("\n")); process.exit(1); } ' # The production image only runs `vite build`, so this is the gate that # must stay green. - name: Production build run: npm run build # Reported, not yet enforced: flip to blocking once the existing # type and lint findings are cleared. - name: Typecheck run: npx tsc -b continue-on-error: true - name: Lint run: npm run lint continue-on-error: true