Skip to content

fix: lazy-load auth deps in web/Pyodide startup and add regression tests #1786

fix: lazy-load auth deps in web/Pyodide startup and add regression tests

fix: lazy-load auth deps in web/Pyodide startup and add regression tests #1786

Workflow file for this run

name: Build & Publish
on:
push:
branches:
- '**'
tags:
- 'v[0-9]+.[0-9]+.[0-9]+'
paths:
- '.github/workflows/ci.yml'
- '.github/scripts/**'
- 'client/**'
- 'sdk/python/packages/**'
- 'packages/flet/**'
- '.fvmrc'
pull_request:
paths:
- '.github/workflows/ci.yml'
- '.github/scripts/**'
- 'client/**'
- 'sdk/python/packages/**'
- 'packages/flet/**'
- '.fvmrc'
workflow_dispatch:
permissions:
id-token: write
contents: write
concurrency:
group: ci-${{ github.workflow }}-${{ github.event.pull_request.head.ref || github.ref_name }}
cancel-in-progress: true
env:
ROOT: "${{ github.workspace }}"
SDK_PYTHON: "${{ github.workspace }}/sdk/python"
SCRIPTS: "${{ github.workspace }}/.github/scripts"
UV_PYTHON: "3.12.7"
jobs:
# ============
# Python tests
# ============
python_tests:
name: Python ${{ matrix.python-version }} tests
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
python-version: [ "3.10", "3.11", "3.12", "3.13", "3.14" ]
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Setup uv
uses: astral-sh/setup-uv@v6
with:
python-version: ${{ matrix.python-version }}
- name: Run tests
shell: bash
working-directory: ${{ env.SDK_PYTHON }}
run: |
uv run --no-dev --group test pytest packages/flet/tests
- name: Run docs-coverage
if: matrix.python-version == '3.12'
shell: bash
working-directory: ${{ env.SDK_PYTHON }}
run: |
exec > docstr_coverage.log 2>&1
status=0
for pkg in packages/*; do
if [ -f "$pkg/pyproject.toml" ] && [ -d "$pkg/src" ]; then
pkg_name=$(basename "$pkg")
echo "====== $pkg ======"
uv run --no-dev --group docs-coverage docstr-coverage -C .docstr.yaml "$pkg/src" --badge="packages/flet/docs/assets/badges/docs-coverage/${pkg_name}.svg" || status=$?
echo
fi
done
exit $status
- name: Upload docs-coverage logs
if: matrix.python-version == '3.12'
uses: actions/upload-artifact@v4
with:
name: docs-coverage
path: sdk/python/docstr_coverage.log
# ===========================
# Build Flet Flutter package
# ===========================
build_flet_package:
name: Build Flet Flutter package
runs-on: ubuntu-latest
permissions:
id-token: write # Required for authentication using OIDC
outputs:
PKG_VER: ${{ steps.versions.outputs.PKG_VER }}
BUILD_NUM: ${{ steps.versions.outputs.BUILD_NUM }}
PYPI_VER: ${{ steps.versions.outputs.PYPI_VER }}
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
fetch-depth: 0 # fetch all history
fetch-tags: true # ensure tags are available
- name: Setup uv
uses: astral-sh/setup-uv@v6
- name: Compute versions
id: versions
run: source "${SCRIPTS}/update_build_version.sh"
- name: Setup Dart (OIDC for pub.dev)
uses: dart-lang/setup-dart@e630b99d28a3b71860378cafdc2a067c71107f94
- name: Setup Flutter
uses: kuhnroyal/flutter-fvm-config-action/setup@v3
with:
path: '.fvmrc'
cache: true
- name: Run tests
shell: bash
working-directory: packages/flet
run: flutter test
- name: Publish to pub.dev (Dry Run)
shell: bash
working-directory: packages/flet
run: dart pub publish --dry-run
- name: Publish to pub.dev
if: ${{ github.ref_type == 'tag' }}
shell: bash
working-directory: packages/flet
run: dart pub publish -f
# =============================
# Build Flet Client for Windows
# =============================
build_windows:
name: Build Flet Client for Windows
runs-on: windows-latest
needs:
- python_tests
- build_flet_package
env:
PKG_VER: ${{ needs.build_flet_package.outputs.PKG_VER }}
BUILD_NUM: ${{ needs.build_flet_package.outputs.BUILD_NUM }}
PYPI_VER: ${{ needs.build_flet_package.outputs.PYPI_VER }}
steps:
- name: Checkout repository
uses: actions/checkout@v4
- 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: Prepare env and patch versions
shell: bash
working-directory: ${{ env.SDK_PYTHON }}
run: |
source "$SCRIPTS/common.sh"
patch_python_package_versions
patch_toml_versions "packages/flet-desktop/pyproject.toml" "$PYPI_VER"
- name: Build Flutter Windows client
env:
RUNNER_DIR: ${{ env.ROOT }}/client/build/windows/x64/runner
RELEASE_DIR: ${{ env.ROOT }}/client/build/windows/x64/runner/Release
shell: bash
working-directory: client
run: |
flutter build windows --build-name="$PKG_VER" --build-number="$BUILD_NUM"
# Copy needed runtime DLLs
cp "${WINDIR}/system32/msvcp140.dll" "$RELEASE_DIR"
cp "${WINDIR}/system32/vcruntime140.dll" "$RELEASE_DIR"
cp "${WINDIR}/system32/vcruntime140_1.dll" "$RELEASE_DIR"
# Rename Release folder to flet
mv "$RELEASE_DIR" "${RUNNER_DIR}/flet"
# Zip up the runner
cd "$RUNNER_DIR"
7z a "${ROOT}/client/flet-windows.zip" "flet"
# Stage app into flet-desktop package
FLET_DESKTOP_APP="${SDK_PYTHON}/packages/flet-desktop/src/flet_desktop/app"
mkdir -p "$FLET_DESKTOP_APP"
cp -r "flet" "${FLET_DESKTOP_APP}/flet"
- name: Build flet-desktop Python package
shell: bash
run: |
source "$SCRIPTS/common.sh"
cd "$SDK_PYTHON"
uv build --package flet-desktop --wheel
# Ensure glob expands
shopt -s nullglob
for wheel in dist/*-py3-none-any.whl; do
repackage_wheel_with_tag "$wheel" "py3-none-win_amd64"
rm -f "$wheel"
done
- name: Upload artifacts
uses: actions/upload-artifact@v4
with:
name: windows-artifacts
if-no-files-found: error
path: |
client/flet-windows.zip
sdk/python/dist/*.whl
# ===========================
# Build Flet Client for macOS
# ===========================
build_macos:
name: Build Flet Client for macOS
runs-on: macos-15
needs:
- python_tests
- build_flet_package
env:
PKG_VER: ${{ needs.build_flet_package.outputs.PKG_VER }}
BUILD_NUM: ${{ needs.build_flet_package.outputs.BUILD_NUM }}
PYPI_VER: ${{ needs.build_flet_package.outputs.PYPI_VER }}
steps:
- name: Checkout repository
uses: actions/checkout@v4
- 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: Build Flutter macOS client
shell: bash
working-directory: client
run: |
flutter build macos --build-name="$PKG_VER" --build-number="$BUILD_NUM"
tar -czvf flet-macos.tar.gz -C build/macos/Build/Products/Release Flet.app
mkdir -p "${SDK_PYTHON}/packages/flet-desktop/src/flet_desktop/app"
cp flet-macos.tar.gz "${SDK_PYTHON}/packages/flet-desktop/src/flet_desktop/app"
- name: Build flet-desktop Python package
shell: bash
working-directory: ${{ env.SDK_PYTHON }}
run: |
source "$SCRIPTS/common.sh"
patch_python_package_versions
uv build --package flet-desktop --wheel
for file in dist/*-py3-none-any.whl; do
repackage_wheel_with_tag "$file" "py3-none-macosx_12_0_arm64"
repackage_wheel_with_tag "$file" "py3-none-macosx_12_0_x86_64"
rm "$file"
done
- name: Upload artifacts
uses: actions/upload-artifact@v4
with:
name: macos-artifacts
if-no-files-found: error
path: |
client/flet-macos.tar.gz
sdk/python/dist/*.whl
# ===========================
# Build Flet Client for Linux
# ===========================
build_linux:
name: Build Flet Client for Linux ${{ matrix.title }}
runs-on: ${{ matrix.runner }}
container:
image: ${{ matrix.container }}
needs:
- python_tests
- build_flet_package
strategy:
matrix:
include:
- distro_id: debian10
container: debian:10
manylinux_tag: manylinux_2_28
arch: amd64
runner: ubuntu-24.04
build_arch: x64
platform_arch: x86_64
rive_enabled: false
title: Debian 10 AMD64
- distro_id: debian10
container: debian:10
manylinux_tag: manylinux_2_28
arch: arm64
runner: ubuntu-24.04-arm
build_arch: arm64
platform_arch: aarch64
rive_enabled: false
title: Debian 10 ARM64
- distro_id: debian12
container: debian:12
manylinux_tag: manylinux_2_36
arch: amd64
runner: ubuntu-24.04
build_arch: x64
platform_arch: x86_64
rive_enabled: false
title: Debian 12 AMD64
- distro_id: debian12
container: debian:12
manylinux_tag: manylinux_2_36
arch: arm64
runner: ubuntu-24.04-arm
build_arch: arm64
platform_arch: aarch64
rive_enabled: false
title: Debian 12 ARM64
- distro_id: ubuntu20.04
container: ubuntu:20.04
manylinux_tag: manylinux_2_31
arch: amd64
runner: ubuntu-24.04
build_arch: x64
platform_arch: x86_64
rive_enabled: false
title: Ubuntu 20.04 AMD64
- distro_id: ubuntu20.04
container: ubuntu:20.04
manylinux_tag: manylinux_2_31
arch: arm64
runner: ubuntu-24.04-arm
build_arch: arm64
platform_arch: aarch64
rive_enabled: false
title: Ubuntu 20.04 ARM64
- distro_id: ubuntu22.04
container: ubuntu:22.04
manylinux_tag: manylinux_2_35
arch: amd64
runner: ubuntu-24.04
build_arch: x64
platform_arch: x86_64
rive_enabled: false
title: Ubuntu 22.04 AMD64
- distro_id: ubuntu22.04
container: ubuntu:22.04
manylinux_tag: manylinux_2_35
arch: arm64
runner: ubuntu-24.04-arm
build_arch: arm64
platform_arch: aarch64
rive_enabled: false
title: Ubuntu 22.04 ARM64
- distro_id: ubuntu24.04
container: ubuntu:24.04
manylinux_tag: manylinux_2_39
arch: amd64
runner: ubuntu-24.04
build_arch: x64
platform_arch: x86_64
rive_enabled: true
title: Ubuntu 24.04 AMD64
- distro_id: ubuntu24.04
container: ubuntu:24.04
manylinux_tag: manylinux_2_39
arch: arm64
runner: ubuntu-24.04-arm
build_arch: arm64
platform_arch: aarch64
rive_enabled: false
title: Ubuntu 24.04 ARM64
env:
PKG_VER: ${{ needs.build_flet_package.outputs.PKG_VER }}
BUILD_NUM: ${{ needs.build_flet_package.outputs.BUILD_NUM }}
PYPI_VER: ${{ needs.build_flet_package.outputs.PYPI_VER }}
ARCH: ${{ matrix.arch }}
BUILD_ARCH: ${{ matrix.build_arch }}
PLATFORM_ARCH: ${{ matrix.platform_arch }}
DISTRO_ID: ${{ matrix.distro_id }}
MANYLINUX_TAG: ${{ matrix.manylinux_tag }}
RIVE_ENABLED: ${{ matrix.rive_enabled }}
steps:
- name: Install base packages
shell: bash
run: |
export DEBIAN_FRONTEND=noninteractive
export TZ=Etc/UTC
if [[ "$DISTRO_ID" == "debian10" ]]; then
printf '%s\n' \
'deb http://archive.debian.org/debian buster main' \
'deb http://archive.debian.org/debian buster-updates main' \
'deb http://archive.debian.org/debian-security buster/updates main' \
> /etc/apt/sources.list
echo 'Acquire::Check-Valid-Until "false";' > /etc/apt/apt.conf.d/99no-check-valid-until
fi
apt-get update
apt-get install -y git curl unzip xz-utils zip ca-certificates jq tzdata
- name: Checkout repository
uses: actions/checkout@v4
- name: Setup uv
uses: astral-sh/setup-uv@v6
- name: Get Flutter version from ".fvmrc"
uses: kuhnroyal/flutter-fvm-config-action/config@v3
id: fvm-config-action
with:
path: '.fvmrc'
- name: Setup Flutter
uses: subosito/flutter-action@v2
with:
flutter-version: ${{ steps.fvm-config-action.outputs.FLUTTER_VERSION }}
channel: ${{ matrix.arch == 'arm64' && 'master' || 'stable' }} # https://github.com/subosito/flutter-action/issues/345#issuecomment-2657332687
cache: true
- name: Mark git safe directories
shell: bash
run: |
git config --global --add safe.directory "$GITHUB_WORKSPACE"
if [[ -n "${FLUTTER_ROOT:-}" ]]; then
git config --global --add safe.directory "$FLUTTER_ROOT"
fi
- name: Install dependencies
shell: bash
run: |
if [[ -f /etc/apt/sources.list ]]; then
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
- name: Build Flutter Linux clients
shell: bash
working-directory: client
run: |
STAGING_DIR="${RUNNER_TEMP:-/tmp}/flet_tars_${ARCH}"
STAGING_DIR="${STAGING_DIR}_${DISTRO_ID}"
echo "STAGING_DIR=$STAGING_DIR" >> "$GITHUB_ENV"
mkdir -p "$STAGING_DIR"
build_flutter() {
local PACKAGE_NAME="$1"
local SUFFIX=""
local FLAVOR="full"
if [[ "$PACKAGE_NAME" == "flet-desktop-light" ]]; then
SUFFIX="-light"
FLAVOR="light"
fi
echo "::group::($PACKAGE_NAME) Preparing sources"
# Reset Flutter app files so light edits don't leak into full or vice-versa
git checkout -- pubspec.yaml lib/main.dart || true
if [[ "$PACKAGE_NAME" == "flet-desktop-light" ]]; then
# Strip FAT_CLIENT blocks for the light flavor
sed -i '/--FAT_CLIENT_START--/,/--FAT_CLIENT_END--/d' pubspec.yaml
sed -i '/--FAT_CLIENT_START--/,/--FAT_CLIENT_END--/d' lib/main.dart
fi
if [[ "$RIVE_ENABLED" != "true" ]]; then
# flet_rive is excluded unless explicitly enabled
sed -i '/--RIVE_CLIENT_START--/,/--RIVE_CLIENT_END--/d' pubspec.yaml
sed -i '/--RIVE_IMPORT_START--/,/--RIVE_IMPORT_END--/d' lib/main.dart
sed -i '/--RIVE_EXTENSION_START--/,/--RIVE_EXTENSION_END--/d' lib/main.dart
fi
echo "::endgroup::"
echo "::group::($PACKAGE_NAME) Flutter build"
flutter build linux --build-name="$PKG_VER" --build-number="$BUILD_NUM"
# Remove any previous build output, so mv below works as expected
rm -rf "build/linux/${BUILD_ARCH}/release/flet"
# Rename Flutter's default "bundle" output directory to "flet"
mv "build/linux/${BUILD_ARCH}/release/bundle" "build/linux/${BUILD_ARCH}/release/flet"
# Create a compressed tarball of the "flet" directory for distribution
tar -czvf "flet-linux-${DISTRO_ID}${SUFFIX}-${ARCH}.tar.gz" -C "build/linux/${BUILD_ARCH}/release" flet
# Stage the archive
cp -f "flet-linux-${DISTRO_ID}${SUFFIX}-${ARCH}.tar.gz" "${STAGING_DIR}/flet-linux-${DISTRO_ID}-${FLAVOR}-${ARCH}.tar.gz"
echo "::endgroup::"
}
build_flutter "flet-desktop-light"
build_flutter "flet-desktop"
- name: Build flet-desktop and flet-desktop-light Python packages
shell: bash
working-directory: client
run: |
source "$SCRIPTS/common.sh"
# Ensure glob expands
shopt -s nullglob
# Patch Python package versions
pushd "$SDK_PYTHON"
patch_python_package_versions
# directory which will contain uv-build output
dist="${SDK_PYTHON}/dist"
FLET_DESKTOP="${SDK_PYTHON}/packages/flet-desktop"
FLET_DESKTOP_LIGHT="${SDK_PYTHON}/packages/flet-desktop-light"
FLET_DESKTOP_APP="${FLET_DESKTOP}/src/flet_desktop/app"
mkdir -p "$FLET_DESKTOP_APP"
build_wheels() {
local PACKAGE_DIR="$1"
local PACKAGE_NAME="$2"
local FLAVOR="full"
if [[ "$PACKAGE_NAME" == "flet-desktop-light" ]]; then
FLAVOR="light"
fi
echo "::group::($PACKAGE_NAME) Build wheels"
pushd "$PACKAGE_DIR"
# Move corresponding staged Linux client to the app directory, so it is part of wheel
rm -f "${FLET_DESKTOP_APP}"/flet-linux-${ARCH}.tar.gz
mv -f "${STAGING_DIR}/flet-linux-${DISTRO_ID}-${FLAVOR}-${ARCH}.tar.gz" "${FLET_DESKTOP_APP}/flet-linux-${ARCH}.tar.gz"
uv build --wheel
if [[ "$PACKAGE_NAME" == "flet-desktop-light" ]]; then
rm -rf "$FLET_DESKTOP_APP"
uv build --sdist
fi
# Find all universal wheels for the current package
universal=( "${dist}/${PACKAGE_NAME//-/_}-"*"-py3-none-any"*.whl )
if (( ${#universal[@]} == 0 )); then
echo "ERROR: No universal wheels found in ${dist} for ${PACKAGE_NAME}."
ls -laR "$dist" || true
exit 1
fi
# Wheel tags to generate from the universal wheel
wheel_tags=(
"py3-none-${MANYLINUX_TAG}_${PLATFORM_ARCH}"
)
# Repackage each universal wheel with all specified platform tags
for wheel in "${universal[@]}"; do
echo "Retagging $wheel"
for tag in "${wheel_tags[@]}"; do
echo "Tagging $wheel with $tag"
uv run "${SCRIPTS}/repackage_wheel_with_tag.py" "$wheel" "$tag"
done
# Delete the original universal wheel
rm -f "$wheel"
done
echo "::endgroup::"
}
build_wheels "$FLET_DESKTOP" "flet-desktop"
build_wheels "$FLET_DESKTOP_LIGHT" "flet-desktop-light"
- name: Upload artifacts
uses: actions/upload-artifact@v4
with:
name: linux-${{ matrix.distro_id }}-${{ matrix.arch }}-artifacts
if-no-files-found: error
path: |
client/flet-linux*.tar.gz
sdk/python/dist/*.whl
sdk/python/dist/*.tar.gz
# =========================
# Build Flet Client for Web
# =========================
build_web:
name: Build Flet Client for Web
runs-on: ubuntu-latest
needs:
- python_tests
- build_flet_package
env:
PYPI_VER: ${{ needs.build_flet_package.outputs.PYPI_VER }}
steps:
- name: Checkout repository
uses: actions/checkout@v4
- 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 Python and Flutter versions
shell: bash
working-directory: ${{ env.SDK_PYTHON }}
run: |
source "$SCRIPTS/common.sh"
patch_python_package_versions
- name: Get Pyodide version
shell: bash
working-directory: ${{ env.SDK_PYTHON }}
run: |
PYODIDE_VERSION="$( uv run python -c 'import flet.version; print(flet.version.pyodide_version)' )"
echo "PYODIDE_VERSION=$PYODIDE_VERSION" >> "$GITHUB_ENV"
echo "Pyodide version: $PYODIDE_VERSION"
- name: Build Web client
shell: bash
working-directory: client
run: |
# Compute Pyodide URLs
PYODIDE_URL="https://github.com/pyodide/pyodide/releases/download/${PYODIDE_VERSION}/pyodide-core-${PYODIDE_VERSION}.tar.bz2"
PYODIDE_CDN_URL="https://cdn.jsdelivr.net/pyodide/v${PYODIDE_VERSION}/full"
FLET_WEB="${SDK_PYTHON}/packages/flet-web/src/flet_web"
flutter build web --wasm
cp -R "build/web" "${FLET_WEB}"
# Safari mobile workaround: https://github.com/flutter/flutter/issues/145111#issuecomment-2714599139
FLUTTER_JS_DIR="$(dirname "$(command -v flutter)")/cache/flutter_web_sdk/flutter_js"
cp "$FLUTTER_JS_DIR/flutter.js.map" "${FLET_WEB}/web"
# Download the Pyodide tarball and extract its contents into the web build folder
curl -L "$PYODIDE_URL" | tar -xj -C "${FLET_WEB}/web"
# Download the prebuilt pyodide wheels
for wheel in "packaging-24.2-py3-none-any.whl" "micropip-0.8.0-py3-none-any.whl"; do
curl -L "${PYODIDE_CDN_URL}/${wheel}" -o "${FLET_WEB}/web/pyodide/${wheel}"
done
# Archive the web client into a gzipped tarball
tar -czvf "flet-web.tar.gz" -C "build/web" .
- name: Build flet-web Python package
shell: bash
working-directory: ${{ env.SDK_PYTHON }}
run: |
uv build --package flet-web --wheel
rm -rf "packages/flet-web/src/flet_web/web"
uv build --package flet-web --sdist
- name: Upload artifacts
uses: actions/upload-artifact@v4
with:
name: web-artifacts
if-no-files-found: error
path: |
client/flet-web.tar.gz
sdk/python/dist/*.whl
sdk/python/dist/*.tar.gz
# ============================================
# Build Flet extension Python packages
# ============================================
build_flet_extensions:
name: Build Flet extensions
runs-on: ubuntu-latest
needs:
- python_tests
- build_flet_package
env:
PYPI_VER: ${{ needs.build_flet_package.outputs.PYPI_VER }}
PKG_VER: ${{ needs.build_flet_package.outputs.PKG_VER }}
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: Analyze and Build Flutter & Python packages
shell: bash
working-directory: ${{ env.SDK_PYTHON }}
run: |
set -euo pipefail
PACKAGES=(
flet-ads
flet-audio
flet-audio-recorder
flet-camera
flet-charts
flet-code-editor
flet-color-pickers
flet-datatable2
flet-flashlight
flet-geolocator
flet-lottie
flet-map
flet-permission-handler
flet-rive
flet-secure-storage
flet-video
flet-webview
)
source "$SCRIPTS/common.sh"
# Keep Flutter extension dependencies resolvable on pub.dev:
# - tag build: use the just-released flet version for this release, PKG_VER
# - non-tag build: use latest released flet tag
if [[ "${GITHUB_REF_TYPE:-}" == "tag" ]]; then
FLET_PUB_VER="$PKG_VER"
else
LATEST_TAG="$(git tag --list 'v[0-9]*.[0-9]*.[0-9]*' --sort=-v:refname | head -n 1)"
if [[ -z "$LATEST_TAG" ]]; then
echo "ERROR: Could not determine latest release tag for flet."
exit 1
fi
FLET_PUB_VER="${LATEST_TAG#v}"
fi
echo "Using flet Flutter dependency version: $FLET_PUB_VER"
for PACKAGE in "${PACKAGES[@]}"; do
echo "::group::Processing ${PACKAGE}"
FLUTTER_PACKAGE="${PACKAGE//-/_}"
FLUTTER_DIR="${SDK_PYTHON}/packages/${PACKAGE}/src/flutter/${FLUTTER_PACKAGE}"
pushd "$FLUTTER_DIR"
# Patch only the flet dependency; keep extension package version unchanged.
patch_pubspec_version "${FLUTTER_DIR}/pubspec.yaml" "$FLET_PUB_VER" --dependencies-only
flutter pub get
dart analyze
popd
patch_toml_versions "packages/${PACKAGE}/pyproject.toml" "$PYPI_VER"
uv build --package "$PACKAGE"
echo "::endgroup::"
done
- name: Upload artifacts
uses: actions/upload-artifact@v4
with:
name: flet-python-extensions
if-no-files-found: error
path: |
sdk/python/dist/*.whl
sdk/python/dist/*.tar.gz
# =====================================
# Build flet, flet-cli and flet-desktop
# =====================================
build_flet_cli_desktop:
name: Build flet, flet-cli and flet-desktop Python packages
runs-on: ubuntu-latest
env:
PYPI_VER: ${{ needs.build_flet_package.outputs.PYPI_VER }}
needs:
- python_tests
- build_flet_package
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Setup uv
uses: astral-sh/setup-uv@v6
- name: Build Python packages
shell: bash
working-directory: ${{ env.SDK_PYTHON }}
run: |
source "$SCRIPTS/common.sh"
patch_python_package_versions
uv build --package flet-cli
uv build --package flet
uv build --package flet-desktop --sdist
- name: Upload artifacts
uses: actions/upload-artifact@v4
with:
name: flet-cli-desktop-python-distribution
path: |
sdk/python/dist/*.whl
sdk/python/dist/*.tar.gz
# ===============================
# Publish Python packages to PyPI
# ===============================
py_publish:
name: Publish Python packages to PyPI
runs-on: ubuntu-latest
if: startsWith(github.ref, 'refs/tags/') || github.ref == 'refs/heads/main'
needs:
- python_tests
- build_flet_package
- build_flet_cli_desktop
- build_windows
- build_macos
- build_linux
- build_web
- build_flet_extensions
steps:
- name: Setup uv
uses: astral-sh/setup-uv@v6
with:
ignore-empty-workdir: true
cache-dependency-glob: ""
- name: Download artifacts
uses: actions/download-artifact@v4
with:
path: dist
merge-multiple: true
- name: Publish packages to PyPI
run: |
# remove client to avoid glob conflicts with its contents
rm -rf dist/client
for pkg in \
flet \
flet_cli \
flet_desktop \
flet_desktop_light \
flet_web \
flet_ads \
flet_audio \
flet_audio_recorder \
flet_camera \
flet_charts \
flet_code_editor \
flet_color_pickers \
flet_datatable2 \
flet_flashlight \
flet_geolocator \
flet_lottie \
flet_map \
flet_permission_handler \
flet_rive \
flet_secure_storage \
flet_video \
flet_webview; do
uv publish dist/**/${pkg}-*
done
# ==============
# GitHub Release
# ==============
release:
name: Publish GitHub Release
runs-on: ubuntu-latest
needs: py_publish
if: ${{ startsWith(github.ref, 'refs/tags/') }}
steps:
- name: Download artifacts
uses: actions/download-artifact@v4
with:
path: dist
merge-multiple: true
- name: Create/Update GitHub Release
uses: softprops/action-gh-release@v2
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
name: ${{ github.ref_name }}
tag_name: ${{ github.ref_name }}
generate_release_notes: true
preserve_order: true
overwrite_files: true
fail_on_unmatched_files: true
files: |
dist/**/*.whl
dist/**/*.tar.gz
dist/**/*.zip