Skip to content
Closed
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
15 changes: 2 additions & 13 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -447,19 +447,8 @@ jobs:
sed -i.bak '/apt.postgresql.org/s/^/# /' /etc/apt/sources.list
fi
apt-get update --allow-releaseinfo-change
apt-get install -y \
lld llvm binutils clang cmake ninja-build pkg-config \
libgtk-3-dev libasound2-dev libunwind-dev \
libsecret-1-0 libsecret-1-dev \
libmpv-dev mpv \
libgstreamer1.0-dev \
libgstreamer-plugins-base1.0-dev \
libgstreamer-plugins-bad1.0-dev \
gstreamer1.0-plugins-base gstreamer1.0-plugins-good \
gstreamer1.0-plugins-bad gstreamer1.0-plugins-ugly \
gstreamer1.0-libav gstreamer1.0-tools gstreamer1.0-x \
gstreamer1.0-alsa gstreamer1.0-gl gstreamer1.0-gtk3 \
gstreamer1.0-qt5 gstreamer1.0-pulseaudio
LINUX_DEPS="$(uv run --project sdk/python/packages/flet python -c 'import flet.utils; print(flet.utils.linux_client_dependencies_apt)')"
apt-get install -y $LINUX_DEPS

- name: Build Flutter Linux clients
shell: bash
Expand Down
152 changes: 123 additions & 29 deletions .github/workflows/flet-build-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,19 +10,24 @@ on:
- 'client/**'
- 'sdk/python/packages/**'
- 'packages/flet/**'
- 'sdk/python/examples/apps/flet_build_test'
- 'sdk/python/examples/apps/flet_build_test/**'
pull_request:
paths:
- '.github/workflows/flet-build-test.yml'
- '.fvmrc'
- 'client/**'
- 'sdk/python/packages/**'
- 'packages/flet/**'
- 'sdk/python/examples/apps/flet_build_test'
- 'sdk/python/examples/apps/flet_build_test/**'
workflow_dispatch:
inputs:
extra_args:
description: "Extra CLI args appended to `flet build ...` command (ex: --template-ref 0.1.0)"
extra_build_args:
description: "Extra CLI args appended to `flet build` command (ex: --template-ref 0.1.0)"
required: false
default: ""

extra_pack_args:
description: "Extra CLI args appended to `flet pack` command (ex: --icon path/to/icon)"
required: false
default: ""

Expand All @@ -31,6 +36,9 @@ concurrency:
cancel-in-progress: true

env:
ROOT: "${{ github.workspace }}"
SDK_PYTHON: "${{ github.workspace }}/sdk/python"
SCRIPTS: "${{ github.workspace }}/.github/scripts"
UV_PYTHON: 3.12
PYTHONUTF8: 1

Expand All @@ -39,6 +47,7 @@ env:

# Extra args passed via workflow_dispatch (empty for push/PR)
FLET_BUILD_EXTRA_ARGS: ${{ github.event_name == 'workflow_dispatch' && inputs.extra_args || '' }}
FLET_PACK_EXTRA_ARGS: ${{ github.event_name == 'workflow_dispatch' && inputs.extra_pack_args || '' }}

jobs:
build:
Expand Down Expand Up @@ -160,36 +169,20 @@ jobs:
- name: Setup uv
uses: astral-sh/setup-uv@v6

- name: Patch versions
shell: bash
run: |
source "${SCRIPTS}/update_build_version.sh"
source "${SCRIPTS}/common.sh"
patch_python_package_versions

- name: Install Linux dependencies
if: matrix.needs_linux_deps
shell: bash
run: |
sudo apt update --allow-releaseinfo-change
sudo apt-get install -y --no-install-recommends \
clang \
ninja-build \
libgtk-3-dev \
libasound2-dev \
libmpv-dev \
mpv \
libgstreamer1.0-dev \
libgstreamer-plugins-base1.0-dev \
libgstreamer-plugins-bad1.0-dev \
gstreamer1.0-plugins-base \
gstreamer1.0-plugins-good \
gstreamer1.0-plugins-bad \
gstreamer1.0-plugins-ugly \
gstreamer1.0-libav \
gstreamer1.0-tools \
gstreamer1.0-x \
gstreamer1.0-alsa \
gstreamer1.0-gl \
gstreamer1.0-gtk3 \
gstreamer1.0-qt5 \
gstreamer1.0-pulseaudio \
pkg-config \
libsecret-1-0 \
libsecret-1-dev
LINUX_DEPS="$(uv run --project sdk/python/packages/flet python -c 'import flet.utils; print(flet.utils.linux_build_dependencies_apt)')"
sudo apt-get install -y --no-install-recommends $LINUX_DEPS
sudo apt-get clean

- name: Setup Flutter
Expand All @@ -212,3 +205,104 @@ jobs:
path: sdk/python/examples/apps/flet_build_test/${{ matrix.artifact_path }}
if-no-files-found: error
overwrite: false

pack:
name: Pack (${{ matrix.name }})
runs-on: ${{ matrix.runner }}
env:
FLET_DESKTOP_FLAVOR: full
strategy:
fail-fast: false
matrix:
include:
- name: linux
runner: ubuntu-latest

- name: macos
runner: macos-latest

- name: windows
runner: windows-latest

steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
fetch-depth: 0
fetch-tags: true

- name: Setup uv
uses: astral-sh/setup-uv@v6

- name: Setup Flutter
uses: kuhnroyal/flutter-fvm-config-action/setup@v3
with:
path: '.fvmrc'
cache: true

- name: Patch versions
shell: bash
run: |
source "${SCRIPTS}/update_build_version.sh"
source "${SCRIPTS}/common.sh"
patch_python_package_versions

- name: Install Linux dependencies
if: matrix.name == 'linux'
shell: bash
run: |
sudo apt update --allow-releaseinfo-change
LINUX_DEPS="$(uv run --project sdk/python/packages/flet python -c 'import flet.utils; print(flet.utils.linux_client_dependencies_apt)')"
sudo apt-get install -y --no-install-recommends $LINUX_DEPS
sudo apt-get clean

- name: Prepare local desktop client archive
shell: bash
run: |
set -euo pipefail
APP_DIR="${SDK_PYTHON}/packages/flet-desktop/src/flet_desktop/app"
mkdir -p "${APP_DIR}"
rm -rf "${APP_DIR:?}"/*

pushd client
case "${{ matrix.name }}" in
linux)
flutter build linux --build-name="$PKG_VER" --build-number="$BUILD_NUM"
rm -rf build/linux/x64/release/flet
mv build/linux/x64/release/bundle build/linux/x64/release/flet
tar -czvf "${APP_DIR}/flet-linux-ubuntu24.04-amd64.tar.gz" -C build/linux/x64/release flet
;;
macos)
flutter build macos --build-name="$PKG_VER" --build-number="$BUILD_NUM"
tar -czvf "${APP_DIR}/flet-macos.tar.gz" -C build/macos/Build/Products/Release Flet.app
;;
windows)
flutter build windows --build-name="$PKG_VER" --build-number="$BUILD_NUM"
RUNNER_DIR="${ROOT}/client/build/windows/x64/runner"
RELEASE_DIR="${RUNNER_DIR}/Release"
cp "${WINDIR}/system32/msvcp140.dll" "$RELEASE_DIR"
cp "${WINDIR}/system32/vcruntime140.dll" "$RELEASE_DIR"
cp "${WINDIR}/system32/vcruntime140_1.dll" "$RELEASE_DIR"
rm -rf "${RUNNER_DIR}/flet"
mv "$RELEASE_DIR" "${RUNNER_DIR}/flet"
pushd "${RUNNER_DIR}"
7z a "${APP_DIR}/flet-windows.zip" "flet"
popd
;;
esac
popd

- name: Pack app
shell: bash
working-directory: sdk/python/examples/apps/flet_build_test
run: |
echo "FLET_PACK_EXTRA_ARGS='${FLET_PACK_EXTRA_ARGS}'"
uv run --with pyinstaller flet pack src/main.py --yes --name flet-pack-test --distpath dist $FLET_PACK_EXTRA_ARGS

- name: Upload Artifact
uses: actions/upload-artifact@v5.0.0
with:
name: ${{ matrix.name }}-pack-artifact
path: sdk/python/examples/apps/flet_build_test/dist
if-no-files-found: error
overwrite: false
8 changes: 2 additions & 6 deletions sdk/python/packages/flet/docs/publish/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -1484,12 +1484,8 @@ jobs:
shell: bash
run: |
sudo apt update --allow-releaseinfo-change
sudo apt-get install -y --no-install-recommends \
clang ninja-build libgtk-3-dev libasound2-dev libmpv-dev mpv \
libgstreamer1.0-dev libgstreamer-plugins-base1.0-dev libgstreamer-plugins-bad1.0-dev \
gstreamer1.0-plugins-base gstreamer1.0-plugins-good gstreamer1.0-plugins-bad gstreamer1.0-plugins-ugly \
gstreamer1.0-libav gstreamer1.0-tools gstreamer1.0-x gstreamer1.0-alsa gstreamer1.0-gl gstreamer1.0-gtk3 \
gstreamer1.0-qt5 gstreamer1.0-pulseaudio pkg-config libsecret-1-0 libsecret-1-dev
LINUX_DEPS="$(uv run python -c 'import flet.utils; print(flet.utils.linux_build_dependencies_apt)')"
sudo apt-get install -y --no-install-recommends $LINUX_DEPS
sudo apt-get clean

- name: Build app # (15)!
Expand Down
10 changes: 10 additions & 0 deletions sdk/python/packages/flet/src/flet/utils/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,12 @@
from flet.utils.from_dict import from_dict
from flet.utils.hashing import calculate_file_hash, sha1
from flet.utils.json_utils import to_json
from flet.utils.linux_deps import (
linux_build_dependencies,
linux_build_dependencies_apt,
linux_client_dependencies,
linux_client_dependencies_apt,
)
from flet.utils.network import get_free_tcp_port, get_local_ip
from flet.utils.object_model import get_param_count, patch_dataclass
from flet.utils.once import Once
Expand Down Expand Up @@ -66,6 +72,10 @@
"is_pyodide",
"is_windows",
"is_within_directory",
"linux_build_dependencies",
"linux_build_dependencies_apt",
"linux_client_dependencies",
"linux_client_dependencies_apt",
"open_in_browser",
"patch_dataclass",
"random_string",
Expand Down
71 changes: 71 additions & 0 deletions sdk/python/packages/flet/src/flet/utils/linux_deps.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
"""Canonical Linux apt dependency sets used by Flet workflows."""

from typing import Final

linux_build_dependencies: Final[tuple[str, ...]] = (
"clang",
"ninja-build",
"libgtk-3-dev",
"libasound2-dev",
"libmpv-dev",
"mpv",
"libgstreamer1.0-dev",
"libgstreamer-plugins-base1.0-dev",
"libgstreamer-plugins-bad1.0-dev",
"gstreamer1.0-plugins-base",
"gstreamer1.0-plugins-good",
"gstreamer1.0-plugins-bad",
"gstreamer1.0-plugins-ugly",
"gstreamer1.0-libav",
"gstreamer1.0-tools",
"gstreamer1.0-x",
"gstreamer1.0-alsa",
"gstreamer1.0-gl",
"gstreamer1.0-gtk3",
"gstreamer1.0-qt5",
"gstreamer1.0-pulseaudio",
"pkg-config",
"libsecret-1-0",
"libsecret-1-dev",
)
"""Linux apt packages required to build a Flet Linux app."""

linux_build_dependencies_apt: Final[str] = " ".join(linux_build_dependencies)
"""`linux_build_dependencies` as a shell-ready, space-separated string."""

linux_client_dependencies: Final[tuple[str, ...]] = (
"lld",
"llvm",
"binutils",
"clang",
"cmake",
"ninja-build",
"pkg-config",
"libgtk-3-dev",
"libasound2-dev",
"libunwind-dev",
"libsecret-1-0",
"libsecret-1-dev",
"libmpv-dev",
"mpv",
"libgstreamer1.0-dev",
"libgstreamer-plugins-base1.0-dev",
"libgstreamer-plugins-bad1.0-dev",
"gstreamer1.0-plugins-base",
"gstreamer1.0-plugins-good",
"gstreamer1.0-plugins-bad",
"gstreamer1.0-plugins-ugly",
"gstreamer1.0-libav",
"gstreamer1.0-tools",
"gstreamer1.0-x",
"gstreamer1.0-alsa",
"gstreamer1.0-gl",
"gstreamer1.0-gtk3",
"gstreamer1.0-qt5",
"gstreamer1.0-pulseaudio",
)
"""Linux apt packages used to build Flet Linux client binaries in CI."""


linux_client_dependencies_apt: Final[str] = " ".join(linux_client_dependencies)
"""`linux_client_dependencies` as a shell-ready, space-separated string."""
Comment on lines +67 to +71
Copy link

Copilot AI Mar 30, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same issue as above: this standalone triple-quoted string after the assignment is a no-op expression and is likely to trigger Ruff flake8-bugbear B018. Use a #/#: comment instead, or move this text into the module docstring.

Copilot uses AI. Check for mistakes.
Comment on lines +1 to +71
Copy link

Copilot AI Mar 30, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The triple-quoted strings after these assignments are standalone string expressions (variable “docstrings”). With the repo’s Ruff config selecting flake8-bugbear rules (B018), these are likely to be flagged as “useless expression” and fail lint. Prefer #/#: comments on the assignment line, or convert to module-level documentation instead of standalone string literals.

Suggested change
"""Canonical Linux apt dependency sets used by Flet workflows."""
from typing import Final
linux_build_dependencies: Final[tuple[str, ...]] = (
"clang",
"ninja-build",
"libgtk-3-dev",
"libasound2-dev",
"libmpv-dev",
"mpv",
"libgstreamer1.0-dev",
"libgstreamer-plugins-base1.0-dev",
"libgstreamer-plugins-bad1.0-dev",
"gstreamer1.0-plugins-base",
"gstreamer1.0-plugins-good",
"gstreamer1.0-plugins-bad",
"gstreamer1.0-plugins-ugly",
"gstreamer1.0-libav",
"gstreamer1.0-tools",
"gstreamer1.0-x",
"gstreamer1.0-alsa",
"gstreamer1.0-gl",
"gstreamer1.0-gtk3",
"gstreamer1.0-qt5",
"gstreamer1.0-pulseaudio",
"pkg-config",
"libsecret-1-0",
"libsecret-1-dev",
)
"""Linux apt packages required to build a Flet Linux app."""
linux_build_dependencies_apt: Final[str] = " ".join(linux_build_dependencies)
"""`linux_build_dependencies` as a shell-ready, space-separated string."""
linux_client_dependencies: Final[tuple[str, ...]] = (
"lld",
"llvm",
"binutils",
"clang",
"cmake",
"ninja-build",
"pkg-config",
"libgtk-3-dev",
"libasound2-dev",
"libunwind-dev",
"libsecret-1-0",
"libsecret-1-dev",
"libmpv-dev",
"mpv",
"libgstreamer1.0-dev",
"libgstreamer-plugins-base1.0-dev",
"libgstreamer-plugins-bad1.0-dev",
"gstreamer1.0-plugins-base",
"gstreamer1.0-plugins-good",
"gstreamer1.0-plugins-bad",
"gstreamer1.0-plugins-ugly",
"gstreamer1.0-libav",
"gstreamer1.0-tools",
"gstreamer1.0-x",
"gstreamer1.0-alsa",
"gstreamer1.0-gl",
"gstreamer1.0-gtk3",
"gstreamer1.0-qt5",
"gstreamer1.0-pulseaudio",
)
"""Linux apt packages used to build Flet Linux client binaries in CI."""
linux_client_dependencies_apt: Final[str] = " ".join(linux_client_dependencies)
"""`linux_client_dependencies` as a shell-ready, space-separated string."""
"""Canonical Linux apt dependency sets used by Flet workflows."""
from typing import Final
# Linux apt packages required to build a Flet Linux app.
linux_build_dependencies: Final[tuple[str, ...]] = (
"clang",
"ninja-build",
"libgtk-3-dev",
"libasound2-dev",
"libmpv-dev",
"mpv",
"libgstreamer1.0-dev",
"libgstreamer-plugins-base1.0-dev",
"libgstreamer-plugins-bad1.0-dev",
"gstreamer1.0-plugins-base",
"gstreamer1.0-plugins-good",
"gstreamer1.0-plugins-bad",
"gstreamer1.0-plugins-ugly",
"gstreamer1.0-libav",
"gstreamer1.0-tools",
"gstreamer1.0-x",
"gstreamer1.0-alsa",
"gstreamer1.0-gl",
"gstreamer1.0-gtk3",
"gstreamer1.0-qt5",
"gstreamer1.0-pulseaudio",
"pkg-config",
"libsecret-1-0",
"libsecret-1-dev",
)
# `linux_build_dependencies` as a shell-ready, space-separated string.
linux_build_dependencies_apt: Final[str] = " ".join(linux_build_dependencies)
# Linux apt packages used to build Flet Linux client binaries in CI.
linux_client_dependencies: Final[tuple[str, ...]] = (
"lld",
"llvm",
"binutils",
"clang",
"cmake",
"ninja-build",
"pkg-config",
"libgtk-3-dev",
"libasound2-dev",
"libunwind-dev",
"libsecret-1-0",
"libsecret-1-dev",
"libmpv-dev",
"mpv",
"libgstreamer1.0-dev",
"libgstreamer-plugins-base1.0-dev",
"libgstreamer-plugins-bad1.0-dev",
"gstreamer1.0-plugins-base",
"gstreamer1.0-plugins-good",
"gstreamer1.0-plugins-bad",
"gstreamer1.0-plugins-ugly",
"gstreamer1.0-libav",
"gstreamer1.0-tools",
"gstreamer1.0-x",
"gstreamer1.0-alsa",
"gstreamer1.0-gl",
"gstreamer1.0-gtk3",
"gstreamer1.0-qt5",
"gstreamer1.0-pulseaudio",
)
# `linux_client_dependencies` as a shell-ready, space-separated string.
linux_client_dependencies_apt: Final[str] = " ".join(linux_client_dependencies)

Copilot uses AI. Check for mistakes.
7 changes: 4 additions & 3 deletions sdk/python/packages/flet/src/flet/version.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import json
import subprocess as sp
import sys
from pathlib import Path
from typing import Optional

Expand Down Expand Up @@ -66,9 +67,9 @@ def from_git() -> Optional[str]:

except sp.CalledProcessError as e:
# Git is present but no tags / not a valid repo state
print(f"Error getting Git version: {e}")
print(f"Error getting Git version: {e}", file=sys.stderr)
except OSError as e:
print(f"Error running Git: {e}")
print(f"Error running Git: {e}", file=sys.stderr)

return None

Expand Down Expand Up @@ -127,7 +128,7 @@ def get_flutter_version() -> str:
raise ValueError("Empty or missing 'flutter' value")
return v
except Exception as e:
print(f"Error parsing {fvmrc_path!r}: {e}")
print(f"Error parsing {fvmrc_path!r}: {e}", file=sys.stderr)

# If 'flutter_version' is still empty after the above (e.g., in a built package
# where CI didn't replace it), fall back to the below default.
Expand Down
Loading