diff --git a/.github/workflows/modern-checks.yml b/.github/workflows/modern-checks.yml new file mode 100644 index 00000000..1e591b74 --- /dev/null +++ b/.github/workflows/modern-checks.yml @@ -0,0 +1,56 @@ +# Builds the modern ViewTouch and runs all its tests on every pull request +# and every push to main, on Debian 13: the Qt (6.8) the Raspberry Pi store +# computers run. No secrets: it works for pull requests from forks. +name: Modern checks + +on: + pull_request: + push: + branches: [main] + workflow_dispatch: + +concurrency: + group: modern-checks-${{ github.ref }} + cancel-in-progress: true + +permissions: + contents: read + +jobs: + test: + name: Build and test (Debian 13, Qt 6.8) + runs-on: ubuntu-24.04 + container: debian:trixie + timeout-minutes: 60 + steps: + - name: Install build tools + run: | + apt-get update -qq + DEBIAN_FRONTEND=noninteractive apt-get install -y -qq --no-install-recommends \ + ca-certificates git python3 g++ cmake ninja-build \ + qt6-base-dev qt6-declarative-dev qt6-declarative-dev-tools libgl-dev libssl-dev \ + qml6-module-qtquick qml6-module-qtquick-controls qml6-module-qtquick-templates \ + qml6-module-qtquick-layouts qml6-module-qtquick-shapes qml6-module-qtquick-dialogs \ + qml6-module-qtquick-window qml6-module-qtqml-workerscript qml6-module-qttest \ + libqt6sql6-sqlite qt6-qpa-plugins fonts-dejavu-core fonts-noto-cjk fonts-noto-color-emoji + + - uses: actions/checkout@v4 + with: + fetch-depth: 0 # every commit: the build number and version history come from them + + - name: Build + run: | + git config --global --add safe.directory "$GITHUB_WORKSPACE" + cmake -S modern -B build -G Ninja -DCMAKE_BUILD_TYPE=Release + cmake --build build + + - name: Tests + env: + QT_QPA_PLATFORM: offscreen + run: timeout 2400 ./build/tests/vtm_tests + + - name: Translations + run: | + for lang in es fr pt zh; do + python3 modern/tools/i18n.py check "$lang" + done diff --git a/modern/tools/i18n.py b/modern/tools/i18n.py index cf5d7d14..78459d6f 100644 --- a/modern/tools/i18n.py +++ b/modern/tools/i18n.py @@ -126,10 +126,14 @@ def main(): if cmd == "check": bad = [p for p in all_ if p not in have] for key, value in have.items(): - forms = value.values() if isinstance(value, dict) else [value] + forms = value.items() if isinstance(value, dict) else [("", value)] want = sorted(re.findall(r"%(?:\d+|n)", key)) - for f in forms: - if sorted(re.findall(r"%(?:\d+|n)", f)) != want: + for form, f in forms: + got = sorted(re.findall(r"%(?:\d+|n)", f)) + # The singular may say "its item" instead of "its 1 item(s)". + if form == "one" and "%n" in want and "%n" not in got: + got = sorted(got + ["%n"]) + if got != want: bad.append(f"placeholders differ: {key!r} -> {f!r}") for b in bad: print(b if b.startswith("placeholders") else f"missing: {b!r}")