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
12 changes: 12 additions & 0 deletions .cargo/config.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@
# one disposable build tree. Cargo resolves this relative path to <repo>/target.
[build]
target-dir = "target"
# Compiling Slint's generated library and test harness together can exhaust
# memory on a 16 GiB development host, including editor background checks.
# Larger builders can opt into more parallelism with Cargo's -j option.
jobs = 1

# Slint's desktop guide recommends matching Linux's larger main-thread stack on
# Windows. This prevents stack overflows in debug builds with deep UI trees.
Expand All @@ -10,3 +14,11 @@ rustflags = ["-C", "link-arg=/STACK:8000000"]

[target.aarch64-pc-windows-msvc]
rustflags = ["-C", "link-arg=/STACK:8000000"]

# NDK r27 and newer devices must agree on 16 KiB ELF load alignment. This also
# remains compatible with 4 KiB Android devices and matches bundled PDFium.
[target.aarch64-linux-android]
rustflags = ["-C", "link-arg=-Wl,-z,max-page-size=16384"]

[target.x86_64-linux-android]
rustflags = ["-C", "link-arg=-Wl,-z,max-page-size=16384"]
186 changes: 177 additions & 9 deletions .github/workflows/native-platforms.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,15 @@ on:
description: Also build an experimental unsigned iOS archive
type: boolean
default: false
pull_request:
paths:
- ".github/workflows/native-platforms.yml"
- "Cargo.lock"
- "Cargo.toml"
- "build.rs"
- "packaging/**"
- "resources/**"
- "scripts/**"
push:
tags:
- "v*.*.*"
Expand All @@ -36,7 +45,7 @@ permissions:

concurrency:
group: native-${{ github.ref }}
cancel-in-progress: false
cancel-in-progress: ${{ github.event_name == 'pull_request' }}

env:
CARGO_TERM_COLOR: always
Expand Down Expand Up @@ -84,7 +93,7 @@ jobs:

linux:
needs: metadata
if: github.event_name == 'push' || inputs.include_linux
if: github.event_name == 'push' || github.event_name == 'pull_request' || inputs.include_linux
name: Linux packages (x64)
runs-on: ubuntu-22.04
env:
Expand Down Expand Up @@ -133,19 +142,22 @@ jobs:
# broken URLs. Flathub performs its own online validation on submit.
appstreamcli validate --no-net resources/com.flectar.mail.metainfo.xml

- name: Build AppImage
- name: Build release executable
env:
APPIMAGE_EXTRACT_AND_RUN: "1"
FLECTAR_GOOGLE_DESKTOP_CLIENT_ID: ${{ secrets.FLECTAR_GOOGLE_DESKTOP_CLIENT_ID }}
FLECTAR_GOOGLE_DESKTOP_CLIENT_SECRET: ${{ secrets.FLECTAR_GOOGLE_DESKTOP_CLIENT_SECRET }}
FLECTAR_MICROSOFT_DESKTOP_CLIENT_ID: ${{ secrets.FLECTAR_MICROSOFT_DESKTOP_CLIENT_ID }}
run: cargo build --locked --release --no-default-features --features remote-content --bin flectar-mail

- name: Build AppImage
env:
APPIMAGE_EXTRACT_AND_RUN: "1"
FLECTAR_SKIP_BUILD: "1"
run: ./scripts/build-appimage.sh

- name: Build Debian package
env:
FLECTAR_GOOGLE_DESKTOP_CLIENT_ID: ${{ secrets.FLECTAR_GOOGLE_DESKTOP_CLIENT_ID }}
FLECTAR_GOOGLE_DESKTOP_CLIENT_SECRET: ${{ secrets.FLECTAR_GOOGLE_DESKTOP_CLIENT_SECRET }}
FLECTAR_MICROSOFT_DESKTOP_CLIENT_ID: ${{ secrets.FLECTAR_MICROSOFT_DESKTOP_CLIENT_ID }}
FLECTAR_SKIP_BUILD: "1"
run: ./scripts/build-deb.sh

- name: Benchmark startup and idle resources
Expand All @@ -165,6 +177,137 @@ jobs:
target/startup-benchmark/*.json
if-no-files-found: error

rpm:
needs: metadata
if: github.event_name == 'push' || github.event_name == 'pull_request' || inputs.include_linux
name: Fedora RPM preview (x64)
runs-on: ubuntu-24.04
container: fedora:44
env:
SOURCE_DATE_EPOCH: ${{ needs.metadata.outputs.source_date_epoch }}
steps:
- name: Install Fedora build dependencies
run: |
dnf install -y \
appstream \
dbus-daemon \
dbus-devel \
desktop-file-utils \
findutils \
fontconfig-devel \
gcc \
gcc-c++ \
git \
libX11-devel \
libXcursor-devel \
libxcb-devel \
libxkbcommon-devel \
libxkbcommon-x11-devel \
make \
pkgconf-pkg-config \
python3 \
rpm-build \
tar \
wayland-devel \
xorg-x11-server-Xvfb
- uses: actions/checkout@fbc6f3992d24b796d5a048ff273f7fcc4a7b6c09 # v5
- uses: dtolnay/rust-toolchain@4360b52568e2003a75bf9bc1d59f33a8e3fc893c # stable
with:
toolchain: stable
- uses: Swatinem/rust-cache@6323deb102c322ba6fcbdcafc7e3dddab59af2b6 # v2
with:
cache-on-failure: true
key: native-fedora-rpm-x64
- name: Build Fedora release executable
env:
FLECTAR_GOOGLE_DESKTOP_CLIENT_ID: ${{ secrets.FLECTAR_GOOGLE_DESKTOP_CLIENT_ID }}
FLECTAR_GOOGLE_DESKTOP_CLIENT_SECRET: ${{ secrets.FLECTAR_GOOGLE_DESKTOP_CLIENT_SECRET }}
FLECTAR_MICROSOFT_DESKTOP_CLIENT_ID: ${{ secrets.FLECTAR_MICROSOFT_DESKTOP_CLIENT_ID }}
run: cargo build --locked --release --no-default-features --features remote-content --bin flectar-mail
- name: Build and inspect RPM
env:
FLECTAR_SKIP_BUILD: "1"
run: |
./scripts/build-rpm.sh
rpm -qip target/rpm/flectar-mail.rpm
rpm -qlp target/rpm/flectar-mail.rpm
- name: Test RPM installation and removal
run: |
dnf install -y target/rpm/flectar-mail.rpm
test -x /usr/bin/flectar-mail
test -f "$(rpm --eval '%{_libdir}')/flectar-mail/libpdfium.so"
desktop-file-validate /usr/share/applications/com.flectar.mail.desktop
appstreamcli validate --no-net /usr/share/metainfo/com.flectar.mail.metainfo.xml
set +e
timeout 15s dbus-run-session -- xvfb-run -a /usr/bin/flectar-mail \
> target/rpm/launch.log 2>&1
status=$?
set -e
if [[ "$status" -ne 124 ]]; then
cat target/rpm/launch.log
echo "Installed RPM launch smoke test exited unexpectedly with status $status" >&2
exit 1
fi
dnf remove -y flectar-mail
test ! -e /usr/bin/flectar-mail
- uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
with:
name: flectar-mail-rpm-x64
path: target/rpm/flectar-mail.rpm
if-no-files-found: error

flatpak:
needs: metadata
if: github.event_name == 'push' || github.event_name == 'pull_request' || inputs.include_linux
name: Flatpak preview bundle (x64)
runs-on: ubuntu-24.04
env:
SOURCE_DATE_EPOCH: ${{ needs.metadata.outputs.source_date_epoch }}
steps:
- uses: actions/checkout@fbc6f3992d24b796d5a048ff273f7fcc4a7b6c09 # v5
- name: Install Flatpak build tools
run: |
sudo apt-get update
sudo apt-get install -y appstream dbus-x11 desktop-file-utils flatpak flatpak-builder xvfb
flatpak remote-add --user --if-not-exists flathub https://flathub.org/repo/flathub.flatpakrepo
flatpak install --user --noninteractive -y flathub \
org.freedesktop.Platform//25.08 \
org.freedesktop.Sdk//25.08 \
org.freedesktop.Sdk.Extension.rust-stable//25.08
- name: Build Flatpak bundle from locked sources
run: ./scripts/build-flatpak.sh
- name: Test Flatpak installation and packaged runtime
env:
EXPECTED_VERSION: ${{ needs.metadata.outputs.version }}
run: |
flatpak install --user --noninteractive -y target/flatpak/flectar-mail.flatpak
flatpak run --command=sh --env=EXPECTED_VERSION="$EXPECTED_VERSION" com.flectar.mail -c '
test -x /app/bin/flectar-mail
test -f /app/lib/flectar-mail/libpdfium.so
test -x /usr/bin/gpg
test -f /app/share/applications/com.flectar.mail.desktop
test -f /app/share/metainfo/com.flectar.mail.metainfo.xml
! grep -q X-AppImage /app/share/applications/com.flectar.mail.desktop
grep -q "version=\"$EXPECTED_VERSION\"" /app/share/metainfo/com.flectar.mail.metainfo.xml
'
flatpak info --user --show-permissions com.flectar.mail
set +e
timeout 15s dbus-run-session -- xvfb-run -a flatpak run com.flectar.mail \
> target/flatpak/launch.log 2>&1
status=$?
set -e
if [[ "$status" -ne 124 ]]; then
cat target/flatpak/launch.log
echo "Flatpak launch smoke test exited unexpectedly with status $status" >&2
exit 1
fi
flatpak uninstall --user --noninteractive -y com.flectar.mail
- uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
with:
name: flectar-mail-flatpak-x64
path: target/flatpak/flectar-mail.flatpak
if-no-files-found: error

windows:
needs: metadata
if: github.event_name == 'push' || inputs.include_windows
Expand Down Expand Up @@ -210,6 +353,8 @@ jobs:
New-Item -ItemType Directory -Force target/package/windows | Out-Null
New-Item -ItemType Directory -Force "target/package/windows/Licenses/Google Sans Flex" | Out-Null
New-Item -ItemType Directory -Force "target/package/windows/Licenses/Noto Emoji" | Out-Null
python scripts/stage-pdfium.py win-x64 target/package/windows
if ($LASTEXITCODE -ne 0) { throw "PDFium staging failed" }
Copy-Item target/release/flectar-mail.exe target/package/windows/
Copy-Item README.md target/package/windows/
Copy-Item LICENSE target/package/windows/
Expand All @@ -219,6 +364,8 @@ jobs:
Copy-Item resources/fonts/google-sans-flex/README.md "target/package/windows/Licenses/Google Sans Flex/"
Copy-Item resources/fonts/noto-emoji/OFL.txt "target/package/windows/Licenses/Noto Emoji/"
Copy-Item resources/fonts/noto-emoji/README.md "target/package/windows/Licenses/Noto Emoji/"
python scripts/test-pdf-preview.py target/package/windows/flectar-mail.exe
if ($LASTEXITCODE -ne 0) { throw "Packaged PDF preview test failed" }
Compress-Archive -Path target/package/windows/* -DestinationPath target/flectar-mail-windows-x64.zip -Force

- name: Install pinned Inno Setup compiler
Expand Down Expand Up @@ -431,15 +578,19 @@ jobs:
if: >-
!cancelled() && github.event_name == 'push' && github.ref_type == 'tag' &&
needs.metadata.result == 'success' && needs.quality.result == 'success' &&
needs.linux.result == 'success' && needs.windows.result == 'success' &&
needs.linux.result == 'success' && needs.rpm.result == 'success' &&
needs.flatpak.result == 'success' && needs.windows.result == 'success' &&
needs.macos.result == 'success' &&
(needs.android.result == 'success' ||
(needs.metadata.outputs.prerelease == 'false' && needs.android.result == 'skipped'))
needs: [metadata, quality, linux, windows, macos, android]
needs: [metadata, quality, linux, rpm, flatpak, windows, macos, android]
runs-on: ubuntu-24.04
permissions:
actions: read
artifact-metadata: write
attestations: write
contents: write
id-token: write
steps:
- uses: actions/checkout@fbc6f3992d24b796d5a048ff273f7fcc4a7b6c09 # v5

Expand All @@ -455,6 +606,18 @@ jobs:
name: flectar-mail-windows-x64
path: release-assets/windows

- name: Download RPM package
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4
with:
name: flectar-mail-rpm-x64
path: release-assets/rpm

- name: Download Flatpak bundle
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4
with:
name: flectar-mail-flatpak-x64
path: release-assets/flatpak

- name: Download macOS package
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4
with:
Expand All @@ -473,6 +636,11 @@ jobs:
RELEASE_VERSION: ${{ needs.metadata.outputs.version }}
run: python3 scripts/prepare-release.py

- name: Attest release downloads
uses: actions/attest@1e69f48acb82d1966a394da916b4c1698aa569d6 # v4
with:
subject-path: dist/*

- name: Publish tagged release
env:
GH_TOKEN: ${{ github.token }}
Expand Down
36 changes: 28 additions & 8 deletions .github/workflows/quality.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,9 @@ concurrency:

env:
CARGO_TERM_COLOR: always
CARGO_BUILD_JOBS: "2"
# Slint's generated application is large; simultaneous lib/test rustc jobs
# can exhaust runner memory before any tests start.
CARGO_BUILD_JOBS: "1"

jobs:
quality:
Expand All @@ -34,6 +36,7 @@ jobs:
sudo apt-get install -y \
build-essential \
gettext \
gnupg \
libdbus-1-dev \
libfontconfig1-dev \
libx11-dev \
Expand Down Expand Up @@ -77,7 +80,9 @@ jobs:
- name: Verify the Blitz patch queue
run: bash scripts/blitz-patches.sh verify
- name: Test release validation and publication
run: python3 scripts/test-release.py
run: |
python3 scripts/test-release.py
python3 scripts/test-pdf-packaging.py
- name: Reject unused direct dependencies
run: |
cargo install cargo-machete --locked --version 0.9.2
Expand All @@ -86,6 +91,8 @@ jobs:
run: cargo check --workspace --all-targets --locked
- name: Check the capability-minimal application
run: cargo check -p flectar-mail --no-default-features --locked
- name: Check the Flatpak application profile
run: cargo check -p flectar-mail --no-default-features --features remote-content,flatpak --locked
- name: Check the opt-in GPU renderer
run: cargo check -p flectar-mail --no-default-features --features remote-content,gpu-renderer --locked
- name: Lint without warnings
Expand All @@ -103,6 +110,13 @@ jobs:
test -z "$(msgattrib --only-obsolete lang/es/LC_MESSAGES/flectar-mail.po)"
- name: Run the default test suite
run: cargo test --workspace --all-targets --locked
- name: Exercise the mobile PDF renderer with bundled PDFium on the host
run: |
python3 scripts/stage-pdfium.py linux-x64 target/pdfium-mobile-test
python3 scripts/test-pdf-preview.py --fixture "$RUNNER_TEMP/mobile-preview.pdf"
FLECTAR_TEST_PDFIUM="$PWD/target/pdfium-mobile-test/libpdfium.so" \
FLECTAR_TEST_PDF="$RUNNER_TEMP/mobile-preview.pdf" \
cargo test -p flectar-mail --lib --locked mobile_native_pages_and_rejection -- --ignored

optional-embeddings:
if: github.event_name != 'schedule'
Expand All @@ -113,7 +127,7 @@ jobs:
- name: Install native core dependencies
run: |
sudo apt-get update
sudo apt-get install -y build-essential libdbus-1-dev pkg-config
sudo apt-get install -y build-essential libdbus-1-dev pkg-config gnupg
- uses: dtolnay/rust-toolchain@4360b52568e2003a75bf9bc1d59f33a8e3fc893c # stable
with:
toolchain: stable
Expand All @@ -134,15 +148,21 @@ jobs:
- uses: dtolnay/rust-toolchain@4360b52568e2003a75bf9bc1d59f33a8e3fc893c # stable
with:
toolchain: stable
- uses: Swatinem/rust-cache@6323deb102c322ba6fcbdcafc7e3dddab59af2b6 # v2
with:
cache-targets: false
key: quality-rustsec
- name: Install pinned cargo-audit
run: cargo install cargo-audit --locked --version 0.22.2
- name: Audit the locked dependency graph
# These four advisories are unmaintained notices in optional/build or
# Slint/Blitz typography dependencies. Deny every new warning while the
# upstream replacements are tracked explicitly here.
run: |
cargo audit --file Cargo.lock --deny warnings \
--ignore RUSTSEC-2025-0141 \
--ignore RUSTSEC-2024-0436 \
--ignore RUSTSEC-2026-0206 \
--ignore RUSTSEC-2026-0192
for lockfile in Cargo.lock platform/android/Cargo.lock; do
cargo audit --file "$lockfile" --deny warnings \
--ignore RUSTSEC-2025-0141 \
--ignore RUSTSEC-2024-0436 \
--ignore RUSTSEC-2026-0206 \
--ignore RUSTSEC-2026-0192
done
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
# Rust build output and locally packaged artifacts
/target/
/.flatpak-builder/
/libs/
/.artifacts/
/tmp/
/.devcontainer/
*.AppImage
/platform/android/gradle/.gradle/
/platform/android/gradle/app/build/
/platform/android/gradle/build/
/platform/ios/*.xcodeproj/

# Local OAuth application registrations (see .env.example)
Expand Down
Loading
Loading