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
2 changes: 1 addition & 1 deletion .claude/skills/fix-issue/references/verification-linux.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ Cargo prints one "test result:" line per test binary and never adds them up, thr

## Translations and data

- **`l10n` checks the file list and the catalog**, not the template. Extracting the template needs gettext 0.24 or later, which reads Rust; an older `xgettext` reads it with the C lexer and produces a template that must not be committed. CI's Translations job is the gate for it.
- **`l10n` checks the file list and the catalog**, not the template. Extracting the template needs gettext 1.0 or later: 0.24 to 0.26 read Rust but skip path-qualified calls such as `crate::i18n::gettext(...)`, and an older `xgettext` reads it with the C lexer. Neither template may be committed. CI's Translations job is the gate for it.
- **`i18n_catalog` needs the `en_US.UTF-8` locale and `msgfmt`**: `localedef -i en_US -f UTF-8 en_US.UTF-8` when the locale is missing.
- **`data` skips a validator whose tool is not installed** (`desktop-file-validate`, `appstreamcli`, `glib-compile-schemas`) and reports it.

Expand Down
26 changes: 15 additions & 11 deletions .github/workflows/build-linux.yml
Original file line number Diff line number Diff line change
Expand Up @@ -369,11 +369,14 @@ jobs:
if: needs.detect.outputs.linux == 'true'
runs-on: ubuntu-24.04
timeout-minutes: 30
# fedora:44 ships gettext 0.26; 0.24 is the first release whose
# xgettext reads Rust. An older one falls back to its C lexer and
# misreads lifetimes.
# ubuntu:26.10 ships gettext 1.0, the first release whose xgettext
# reads a call through a path such as crate::i18n::gettext. 0.24 to
# 0.26 read Rust but skip those calls, and an older one falls back to
# its C lexer.
container:
image: fedora:44
image: ubuntu:26.10
env:
DEBIAN_FRONTEND: noninteractive
defaults:
run:
working-directory: linux
Expand All @@ -383,19 +386,20 @@ jobs:
# read.
- name: Install git
run: |
dnf install -y --setopt=install_weak_deps=False git
apt-get update
apt-get install -y --no-install-recommends ca-certificates git
git config --global --add safe.directory "$GITHUB_WORKSPACE"
working-directory: /
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: false
- name: Install system dependencies
run: |
dnf install -y --setopt=install_weak_deps=False \
gcc pkgconf meson ninja-build gettext \
desktop-file-utils appstream glib2-devel \
gtk4-devel libadwaita-devel gtksourceview5-devel \
sqlite-devel krb5-devel clang-devel cargo rust
apt-get install -y --no-install-recommends \
build-essential pkgconf meson ninja-build gettext \
desktop-file-utils appstream libglib2.0-bin libglib2.0-dev libxml2-utils \
libgtk-4-dev libadwaita-1-dev libgtksourceview-5-dev \
libsqlite3-dev libkrb5-dev clang libclang-dev cargo rustc
- name: POTFILES.in is current
run: |
git ls-files 'crates/app/src/*.rs' 'data/resources/*.ui' 'data/*.desktop.in.in' \
Expand All @@ -410,7 +414,7 @@ jobs:
run: |
meson compile -C _build tablepro-pot
if ! git diff --exit-code --ignore-matching-lines='^"POT-Creation-Date: ' -- po/tablepro.pot; then
echo "::error::po/tablepro.pot does not match the strings in the code: run meson compile -C _build tablepro-pot with gettext 0.24 or newer, or take the tablepro-pot artifact of this run, and commit it"
echo "::error::po/tablepro.pot does not match the strings in the code: run meson compile -C _build tablepro-pot with gettext 1.0 or newer, or take the tablepro-pot artifact of this run, and commit it"
exit 1
fi
- name: Keep the regenerated template
Expand Down
2 changes: 1 addition & 1 deletion linux/docs/testing.md
Original file line number Diff line number Diff line change
Expand Up @@ -361,7 +361,7 @@ GitHub Actions (`.github/workflows/build-linux.yml`), Ubuntu runners. It runs on
1. **Fast checks**: `meson setup`, `cargo fmt --all -- --check`, the source greps (no `thread_local!` in services, no blocking file I/O under `ui`, no action group inserted as `win`, no `set_qdata`, no em dash in user-facing text), `scripts/check-doc-symbols.sh` over the docs that name code, clippy with and without default features, `meson compile`, `xvfb-run -a dbus-run-session -- meson test --print-errorlogs`, a Secret Service step under `gnome-keyring-daemon`, then `meson dist`. Runs in an `ubuntu:26.04` container, which ships GLib 2.88 plus the meson, appstream and desktop-file-utils packages. A failed run keeps `_build/meson-logs/testlog.txt` as the `meson-testlog` artifact. [CONTRIBUTING.md](../CONTRIBUTING.md#fast-job-commands) lists the same commands.
2. **Docker tests** (`integration`, `integration-session`, `integration-app`): runs after fast checks pass, and keeps each package's JUnit report as a `junit-<package>` artifact. One matrix entry per package with docker tests (the PostgreSQL driver with PgBouncer, the MySQL driver with MariaDB, the SQL Server and ClickHouse drivers, all four with their TLS suites, `tablepro-ssh` against an OpenSSH server container, and `tablepro-test-fixtures` for the fixtures themselves) runs that package's ignored docker tests through cargo-nextest on the host runner's Docker, one test at a time per package. `tablepro-session` builds storage, which needs GLib 2.88, so its job runs in the fast job's `ubuntu:26.04` image with the host's Docker socket mounted. The app's docker tests (`crates/app/tests/tracker_save_postgres.rs`) run the same way, since the app links GTK; that job names its test targets, because the app's `startup` test needs Meson. The SQLite driver needs no container: its suites run in the fast job.
3. **Supply chain**: `cargo deny check` against `deny.toml` (advisories, bans, licenses and sources, with every feature, both Linux targets and the dev-dependencies), `cargo shear` for unused or misplaced dependencies, and `build-aux/update-third-party-licenses.sh`, failing when `data/licenses`, `build-aux/debian/copyright` or the spec's `License` tag differ from what it writes. Then `zizmor` over the three Linux workflows.
4. **Translations**: in `fedora:44`, whose gettext reads Rust. `po/POTFILES.in` must match `git ls-files`, `meson setup --fatal-meson-warnings` must pass, and `po/tablepro.pot` must match a fresh `meson compile -C _build tablepro-pot` in everything but its creation date. Regenerating it locally needs gettext 0.24 or newer. A failed run keeps the template it wrote as the `tablepro-pot` artifact.
4. **Translations**: in `ubuntu:26.10`, whose gettext 1.0 reads path-qualified Rust calls such as `crate::i18n::gettext(...)`. `po/POTFILES.in` must match `git ls-files`, `meson setup --fatal-meson-warnings` must pass, and `po/tablepro.pot` must match a fresh `meson compile -C _build tablepro-pot` in everything but its creation date. Regenerating it locally needs gettext 1.0 or newer (`po/README.md`). A failed run keeps the template it wrote as the `tablepro-pot` artifact.
5. **Documentation links**: lychee, offline, over every Markdown file under `linux/`, with heading anchors checked.
6. **Flatpak Devel**: the Devel manifest built in the `gnome-51` Flatpak image for x86_64 and aarch64, with every Meson suite run inside the build sandbox from a tree with no `.git`. The x86_64 job lints the manifest with `flatpak-builder-lint` and `build-aux/flatpak/lint-exceptions.json`. The repository holds no Flathub manifest ([ADR 0018](decisions/0018-ppa-copr-and-flathub-later.md)).
7. **Minimum Rust version**: in `ubuntu:26.04`, `build-aux/packaging/add-rust-toolchain-ppa.sh` adds `ppa:rust-toolchain/staging`, `apt-get build-dep -P nocheck` installs the .deb's build dependencies without the test-only ones, and `cargo-1.97 check --workspace --all-targets --locked` runs with and without default features: the compiler the PPA builds with, at the workspace `rust-version`.
Expand Down
13 changes: 8 additions & 5 deletions linux/po/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -76,11 +76,14 @@ the committed file differs in anything but its creation date. It then
uploads the template it wrote as the `tablepro-pot` artifact, which can be
committed as it is.

This needs **gettext 0.24 or newer**, which is the first release whose
xgettext reads Rust. Fedora 44 ships 0.26; Ubuntu 26.04 ships 0.23.2. An
older xgettext falls back to its C lexer, which misreads lifetimes such as
`'static` as character constants and produces a template you should not
commit. `meson setup` warns when the xgettext it found is too old.
This needs **gettext 1.0 or newer**, the first release whose xgettext
reads a call through a path such as `crate::i18n::gettext(...)`, the way
most of the app calls it. Ubuntu 26.10 ships 1.0; Fedora 44 ships 0.26 and
Ubuntu 26.04 0.23.2. gettext 0.24 to 0.26 read Rust but skip every
path-qualified call, and anything older falls back to its C lexer, which
misreads lifetimes such as `'static` as character constants. Neither
template should be committed. `meson setup` warns when the xgettext it
found is too old.

Use `msgmerge` to fold new strings into existing translations:

Expand Down
4 changes: 2 additions & 2 deletions linux/po/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ xgettext = find_program('xgettext', required: false)

if xgettext.found()
xgettext_version = run_command(xgettext, '--version', check: false).stdout().split('\n')[0].split(' ')[-1]
if xgettext_version.version_compare('< 0.24')
if xgettext_version.version_compare('< 1.0')
warning(
'xgettext @0@ predates 0.24, which taught xgettext to read Rust. Regenerating the POT needs 0.24 or newer.'.format(
'xgettext @0@ predates 1.0, the first that reads a call through a path such as crate::i18n::gettext. Regenerating the POT needs 1.0 or newer.'.format(
xgettext_version,
),
)
Expand Down
Loading