Fork PRs run the pull_request workflow with a read-only token, so
'gh label create' and the retry 'gh pr edit --add-label' fail when the
translations-only label does not exist yet, failing the whole validate
job even though locale validation passed (seen on #5716). Labeling is
best-effort: add continue-on-error and tolerate the final edit failure.
The ask was to decouple translations from the release cycle so
community translators don't have to wait on a maintainer to merge
strings. Loading translations from a CDN was offered, but pulling
untrusted JSON into the UI at runtime adds attack surface and breaks
the offline-friendly self-hosted story.
Instead, automate the merge path that already exists:
- New scripts/validate-locales.js checks every public/locales/*.json
for JSON validity, _meta fields, and shape compatibility with
en.json (same key paths, same value types). Missing keys are
warnings (partial translations are OK, English is the fallback).
Also runnable locally with 'npm run validate-locales'.
- New .github/workflows/translations-autovalidate.yml runs that
validator on every PR that touches public/locales/**. If the PR is
translations-only (no en.json, no code) and validation passes,
it labels the PR 'translations-only' and turns on GitHub's
auto-merge so it goes in as soon as required checks are green.
- Workflow runs on pull_request (not pull_request_target) so it
cannot read secrets from fork PRs.
QEMU emulation of arm64 for npm ci + better-sqlite3 native
compilation was intermittently hitting SIGILL (exit 132) due
to emulator resource exhaustion on shared runners.
Restructured to use a build matrix with ubuntu-latest (amd64)
and ubuntu-24.04-arm (arm64) native runners, push each arch
as a digest, then merge into a combined manifest in a final job.
Per-platform builds were tagged as build-amd64/build-arm64 with no version,
so every release overwrote the same intermediate tags. Now uses
github.ref_name (e.g. v2.2.1-amd64) so each release is properly versioned.
Also fixed the merge loop to iterate newline-delimited metadata output
instead of splitting on commas.
Co-authored-by: USBAkimbo <71508071+USBAkimbo@users.noreply.github.com>
- Docker CI: lowercase IMAGE_NAME so tags are valid (#47)
- Roles: refresh detail panel after save so auto-assign reflects server state (#14)
- Roles: broadcast roles-updated after update-role so other admins stay in sync
- Screen share: constrain resolution/framerate via getDisplayMedia (#50)
- Screen share: cap bitrate per resolution via setParameters
- Screen share: quality picker in voice settings (720p/1080p/1440p/source, 15/30/60fps)
- Screen share: persist quality preferences in localStorage
- Reverted PiP to native browser system (draggable across screens)
- YouTube playlist controls now work (list= param preserved in embed URL)
- YouTube auto-advance on video end for playlists
- Bot Updated toast fixed from red/error to green/success
- Toast z-index raised above modals
- Bot channel dropdown ordered with sub-channel indentation
- Uncategorized DMs now collapsible with localStorage persistence
- HTTPS redirect uses actual host instead of hardcoded localhost
- Removed duplicate /api/upload-avatar route, added 2MB size check
- Guarded global get-webhooks handler to not conflict with per-channel
- E2E safety number now full 60 digits (SHA-512 instead of SHA-256)
- Reset YouTube playlist flag on Spotify URLs
- GitHub Actions workflow attaches haven.tar.gz with fixed dir name (closes#22)