diff --git a/.appveyor.yml b/.appveyor.yml deleted file mode 100644 index 0ca6c2fd..00000000 --- a/.appveyor.yml +++ /dev/null @@ -1,297 +0,0 @@ -skip_branch_with_pr: true - -environment: - FLUTTER_VERSION: 3.29.3 - GITHUB_TOKEN: - secure: 9SKIwc3VSfYJ5IChvNR74mEv2nb0ZFftUzn3sGRdXipXEfKSxY50DoodChHvlqZduQNhjg0oyLWAAa3n+iwWvVM2yI7Cgb14lFNClijz/kHI/PibnjDMNvLKaAygcfAc - - matrix: - - job_name: Test on macOS - job_group: test_serious_python - job_depends_on: build_python_darwin - APPVEYOR_BUILD_WORKER_IMAGE: macos-monterey - - - job_name: Test on iOS - job_group: test_serious_python - job_depends_on: build_python_darwin - APPVEYOR_BUILD_WORKER_IMAGE: macos-ventura - - - job_name: Test on Android - job_group: test_serious_python - job_depends_on: build_python_android - APPVEYOR_BUILD_WORKER_IMAGE: ubuntu-gce-c - - - job_name: Test on Windows - job_group: test_serious_python - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2022 - - - job_name: Test on Linux - job_group: test_serious_python - APPVEYOR_BUILD_WORKER_IMAGE: ubuntu2004 - - - job_name: Test on Linux ARM64 - job_group: test_serious_python - APPVEYOR_BUILD_WORKER_IMAGE: ubuntu2204-arm - - - job_name: Publish serious_python package to pub.dev - job_group: publish_package - job_depends_on: build_python, test_serious_python - APPVEYOR_BUILD_WORKER_IMAGE: Ubuntu2004 - -stack: -- python 3.12 - -for: - # ====================================== - # Test on macOS - # ====================================== - - - matrix: - only: - - job_name: Test on macOS - - install: - - HOMEBREW_NO_AUTO_UPDATE=1 brew install cocoapods - - source ci/install_flutter.sh - - flutter config --enable-macos-desktop - - flutter doctor -v - - xcodebuild -version - - build: off - - test_script: - - export SERIOUS_PYTHON_SITE_PACKAGES=$APPVEYOR_BUILD_FOLDER/site-packages - - cd src/serious_python/example/flet_example - - dart run serious_python:main package app/src -p Darwin -r flet - - flutter test integration_test -d macos - - # ====================================== - # Test on iOS - # ====================================== - - - matrix: - only: - - job_name: Test on iOS - - install: - - HOMEBREW_NO_AUTO_UPDATE=1 brew install cocoapods - - source ci/install_flutter.sh - # - xcrun simctl list runtimes - # - xcrun simctl create "e2e test" "iPhone 12" "com.apple.CoreSimulator.SimRuntime.iOS-17-2" - # - xcrun xctrace list devices - # - | - # UDID=$(xcrun xctrace list devices | grep "^e2e test Simulator (17.2)" | awk '{gsub(/[()]/,""); print $NF}') - # echo $UDID - # xcrun simctl boot "${UDID:?No Simulator with this name found}" - - build: off - - test_script: - - export SERIOUS_PYTHON_SITE_PACKAGES=$APPVEYOR_BUILD_FOLDER/site-packages - - cd src/serious_python/example/flet_example - - dart run serious_python:main package app/src -p iOS -r flet - - flutter build ios --no-codesign - # - flutter drive --driver=test_driver/integration_test.dart --target=integration_test/app_test.dart - - # ====================================== - # Test on Android - # ====================================== - - - matrix: - only: - - job_name: Test on Android - - install: - - API_LEVEL="33" - - TARGET="google_atd" - - ARCH="x86_64" - - DEVICE_NAME="android_emulator" - - DEVICE_TYPE="pixel_5" - - 'export PATH=$ANDROID_SDK_ROOT/platform-tools:$ANDROID_SDK_ROOT/emulator:$PATH' - - sdkmanager "platform-tools" "platforms;android-${API_LEVEL}" - - sdkmanager --install "system-images;android-${API_LEVEL};${TARGET};${ARCH}" - - sdkmanager --update - - echo "y" | sdkmanager --licenses - - echo "no" | avdmanager -v create avd --force --name "${DEVICE_NAME}" --package "system-images;android-${API_LEVEL};${TARGET};${ARCH}" --tag "${TARGET}" --sdcard 128M --device "${DEVICE_TYPE}" - - ls -al ~/.android/avd - - sudo adduser $USER kvm - - sudo chown $USER /dev/kvm - - emulator -avd "${DEVICE_NAME}" -memory 2048 -wipe-data -no-boot-anim -cache-size 1000 -noaudio -no-window -partition-size 8192 & - - adb wait-for-device shell 'while [[ -z $(getprop dev.bootcomplete) ]]; do sleep 1; done;' - - source ci/install_flutter.sh - - build: off - - test_script: - - export SERIOUS_PYTHON_SITE_PACKAGES=$APPVEYOR_BUILD_FOLDER/site-packages - - cd src/serious_python/example/flet_example - - dart run serious_python:main package app/src -p Android -r flet - - flutter test integration_test -d emulator-5554 - - - # ====================================== - # Test on Windows - # ====================================== - - - matrix: - only: - - job_name: Test on Windows - - #environment: - # VC_REDIST_DIR: 'C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Redist\MSVC\14.29.30133\x64\Microsoft.VC142.CRT' - - install: - - dart pub global activate fvm - - set PATH=%LOCALAPPDATA%\Pub\Cache\bin;%USERPROFILE%\fvm\default\bin;%PATH% - - fvm install %FLUTTER_VERSION% - - fvm global %FLUTTER_VERSION% - - flutter --version - - flutter doctor - - build: off - - test_script: - - set SERIOUS_PYTHON_SITE_PACKAGES=%APPVEYOR_BUILD_FOLDER%\site-packages - - cd src/serious_python/example/flet_example - - dart run serious_python:main package app/src -p Windows -r flet - - flutter test integration_test -d windows - - # ====================================== - # Test on Linux - # ====================================== - - - matrix: - only: - - job_name: Test on Linux - - install: - - sudo apt update --allow-releaseinfo-change - - sudo apt install -y xvfb libgtk-3-dev 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-doc gstreamer1.0-tools gstreamer1.0-x gstreamer1.0-alsa gstreamer1.0-gl gstreamer1.0-gtk3 gstreamer1.0-qt5 gstreamer1.0-pulseaudio - - source ci/install_flutter.sh - - build: off - - test_script: - - export SERIOUS_PYTHON_SITE_PACKAGES=$APPVEYOR_BUILD_FOLDER/site-packages - - cd src/serious_python/example/flet_example - - dart run serious_python:main package app/src -p Linux -r flet - - xvfb-run flutter test integration_test -d linux - - # ====================================== - # Test on Linux ARM64 - # ====================================== - - - matrix: - only: - - job_name: Test on Linux ARM64 - - install: - # Flutter SDK - - sudo sed -i "/#\$nrconf{restart} = 'i';/s/.*/\$nrconf{restart} = 'a';/" /etc/needrestart/needrestart.conf - - sudo apt update -y --allow-releaseinfo-change - - sudo apt install -y clang ninja-build xvfb libgtk-3-dev gstreamer1.0-plugins-bad gstreamer1.0-plugins-ugly gstreamer1.0-libav - - git clone https://github.com/flutter/flutter.git -b stable "$HOME/flutter" - - export PATH="$PATH:$HOME/flutter/bin" - - source ci/install_flutter.sh - - build: off - - test_script: - - export SERIOUS_PYTHON_SITE_PACKAGES=$APPVEYOR_BUILD_FOLDER/site-packages - - cd src/serious_python/example/flet_example - - dart run serious_python:main package app/src -p Linux -r flet - - xvfb-run flutter test integration_test -d linux - - # ========================================= - # Publish serious_python package to pub.dev - # ========================================= - - - matrix: - only: - - job_name: Publish serious_python package to pub.dev - - install: - # update build version - - ps: | - if ($env:APPVEYOR_REPO_TAG_NAME) { - $env:PKG_VER = $env:APPVEYOR_REPO_TAG_NAME.replace("v", "") - } else { - $cv = [version](git describe --abbrev=0).substring(1) - $env:PKG_VER = "$($cv.major).$($cv.minor).$($env:APPVEYOR_BUILD_NUMBER)" - } - Write-Host "Package version: $($env:PKG_VER)" - - - pip3 install pyyaml - - flutter upgrade --force - - build_script: - # publish package - - sh: | - if [[ "$APPVEYOR_REPO_TAG_NAME" != "" ]]; then - mkdir -p $HOME/.config/dart - echo $PUB_DEV_TOKEN | base64 --decode > $HOME/.config/dart/pub-credentials.json - - # patch pubspecs - python3 ci/patch_pubspec.py src/serious_python_platform_interface/pubspec.yaml $PKG_VER - python3 ci/patch_pubspec.py src/serious_python/pubspec.yaml $PKG_VER - python3 ci/patch_pubspec.py src/serious_python_android/pubspec.yaml $PKG_VER - python3 ci/patch_pubspec.py src/serious_python_darwin/pubspec.yaml $PKG_VER - python3 ci/patch_pubspec.py src/serious_python_windows/pubspec.yaml $PKG_VER - python3 ci/patch_pubspec.py src/serious_python_linux/pubspec.yaml $PKG_VER - - cd src/serious_python_platform_interface - dart pub publish --force - cd $APPVEYOR_BUILD_FOLDER - - sleep 600 - - cd src/serious_python_android - dart pub publish --force - cd $APPVEYOR_BUILD_FOLDER - - cd src/serious_python_darwin - dart pub publish --force - cd $APPVEYOR_BUILD_FOLDER - - cd src/serious_python_windows - dart pub publish --force - cd $APPVEYOR_BUILD_FOLDER - - cd src/serious_python_linux - dart pub publish --force - cd $APPVEYOR_BUILD_FOLDER - - sleep 600 - - cd src/serious_python - dart pub publish --force || exit 1 - cd $APPVEYOR_BUILD_FOLDER - - elif [[ "$APPVEYOR_PULL_REQUEST_NUMBER" == "" ]]; then - - cd src/serious_python_platform_interface - dart pub publish --dry-run - cd $APPVEYOR_BUILD_FOLDER - - cd src/serious_python_android - dart pub publish --dry-run - cd $APPVEYOR_BUILD_FOLDER - - cd src/serious_python_darwin - dart pub publish --dry-run - cd $APPVEYOR_BUILD_FOLDER - - cd src/serious_python_windows - dart pub publish --dry-run - cd $APPVEYOR_BUILD_FOLDER - - cd src/serious_python_linux - dart pub publish --dry-run - cd $APPVEYOR_BUILD_FOLDER - - cd src/serious_python - dart pub publish --dry-run - cd $APPVEYOR_BUILD_FOLDER - fi - - test: off \ No newline at end of file diff --git a/ci/patch_pubspec.py b/.github/scripts/patch_pubspec.py similarity index 91% rename from ci/patch_pubspec.py rename to .github/scripts/patch_pubspec.py index d655767a..66689a46 100644 --- a/ci/patch_pubspec.py +++ b/.github/scripts/patch_pubspec.py @@ -1,3 +1,7 @@ +# /// script +# dependencies = ["pyyaml"] +# /// + import os import pathlib import sys @@ -22,7 +26,7 @@ "serious_python_macos", ] -with open(pubspec_path, "r") as f: +with open(pubspec_path) as f: data = yaml.safe_load(f) # patch version diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 00000000..0dda04c3 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,296 @@ +name: CI + +on: + push: + branches: + - '**' + tags: + - '*' + pull_request: + workflow_dispatch: + +env: + ROOT: "${{ github.workspace }}" + SCRIPTS: "${{ github.workspace }}/.github/scripts" + SERIOUS_PYTHON_SITE_PACKAGES: "${{ github.workspace }}/site-packages" + UV_PYTHON: "3.12" + +jobs: + macos: + name: Test on macOS + runs-on: macos-latest + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Setup Flutter + uses: kuhnroyal/flutter-fvm-config-action/setup@v3 + with: + path: '.fvmrc' + cache: true + + - name: Run tests + working-directory: "src/serious_python/example/flet_example" + run: | + dart run serious_python:main package app/src --platform Darwin --requirements flet + flutter test integration_test --device-id macos + + ios: + name: Test on iOS + runs-on: macos-latest + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Setup Flutter + uses: kuhnroyal/flutter-fvm-config-action/setup@v3 + with: + path: '.fvmrc' + cache: true + + - name: Setup iOS Simulator + id: simulator + uses: futureware-tech/simulator-action@v4 + with: + # https://github.com/futureware-tech/simulator-action/wiki/Devices-macos-latest + model: 'iPhone 16 Pro Max' + os: "iOS" + os_version: "^18.6" + shutdown_after_job: true + wait_for_boot: true + + - name: Run tests + working-directory: "src/serious_python/example/flet_example" + run: | + dart run serious_python:main package app/src --platform iOS --requirements flet + flutter test integration_test --device-id ${{ steps.simulator.outputs.udid }} + + android: + name: Test on Android + runs-on: ubuntu-latest + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Setup Flutter + uses: kuhnroyal/flutter-fvm-config-action/setup@v3 + with: + path: '.fvmrc' + cache: true + + - name: Enable KVM + run: | + echo 'KERNEL=="kvm", GROUP="kvm", MODE="0666", OPTIONS+="static_node=kvm"' | sudo tee /etc/udev/rules.d/99-kvm4all.rules + sudo udevadm control --reload-rules + sudo udevadm trigger --name-match=kvm + + - name: Gradle cache + uses: gradle/actions/setup-gradle@v3 + + - name: AVD cache + uses: actions/cache@v4 + id: avd-cache + with: + path: | + ~/.android/avd/* + ~/.android/adb* + key: avd + + - name: Setup Android Emulator + Run tests + uses: reactivecircus/android-emulator-runner@v2 + env: + EMULATOR_PORT: 5554 + with: + avd-name: android_emulator + api-level: 33 + target: google_atd + arch: x86_64 + profile: pixel_5 + sdcard-path-or-size: 128M + ram-size: 2048M + disk-size: 4096M + emulator-port: ${{ env.EMULATOR_PORT }} + disable-animations: true + emulator-options: -no-window -noaudio -no-boot-anim -wipe-data -cache-size 1000 -partition-size 8192 + pre-emulator-launch-script: | + sdkmanager --list_installed + script: | + cd src/serious_python/example/flet_example && dart run serious_python:main package app/src --platform Android --requirements flet + cd src/serious_python/example/flet_example && flutter test integration_test --device-id emulator-${{ env.EMULATOR_PORT }} + + windows: + name: Test on Windows + runs-on: windows-latest + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Setup Flutter + uses: kuhnroyal/flutter-fvm-config-action/setup@v3 + with: + path: '.fvmrc' + cache: true + + - name: Run tests + working-directory: "src/serious_python/example/flet_example" + run: | + dart run serious_python:main package app/src --platform Windows --requirements flet + flutter test integration_test -d windows + + linux: + name: Test on Linux ${{ matrix.title }} + runs-on: ${{ matrix.runner }} + strategy: + fail-fast: false + matrix: + include: + - arch: arm64 + runner: ubuntu-24.04-arm + title: ARM64 + - arch: amd64 + runner: ubuntu-24.04 + title: AMD64 + steps: + - 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: Install dependencies + run: | + sudo apt-get update --allow-releaseinfo-change + sudo apt-get install -y xvfb libgtk-3-dev + + if [ "${{ matrix.arch }}" = "amd64" ]; then + sudo apt-get install -y \ + 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 + else + sudo apt-get install -y \ + clang \ + ninja-build \ + gstreamer1.0-plugins-bad \ + gstreamer1.0-plugins-ugly \ + gstreamer1.0-libav + fi + + - name: Run tests + working-directory: src/serious_python/example/flet_example + run: | + flutter pub get + dart run serious_python:main package app/src --platform Linux --requirements flet + xvfb-run flutter test integration_test -d linux + + publish: + name: Publish to pub.dev + needs: + - macos + - ios + - android + - windows + - linux + runs-on: ubuntu-22.04 + if: startsWith(github.ref, 'refs/tags/v') + steps: + + - name: Checkout repository + uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - 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: Compute PKG_VER + run: | + if [[ "$GITHUB_REF" == refs/tags/* ]]; then + # Extract the tag name + tag="${GITHUB_REF#refs/tags/}" + + # Remove leading "v" if present + PKG_VER="${tag#v}" + else + # Get the latest tag, or fall back to "v0.0.0" if none exist + cv=$(git describe --abbrev=0 2>/dev/null || echo "v0.0.0") + # Remove leading "v" if present + cv=${cv#v} + + # Split into major/minor components + major=$(echo "$cv" | cut -d. -f1) + minor=$(echo "$cv" | cut -d. -f2) + + # Construct the package version + PKG_VER="${major}.${minor}.${GITHUB_RUN_NUMBER}" + fi + + export PKG_VER + echo "PKG_VER=$PKG_VER" | tee -a "$GITHUB_ENV" + + - name: Configure pub.dev credentials + run: | + mkdir -p $HOME/.config/dart + echo "${{ secrets.PUB_DEV_TOKEN }}" | base64 --decode > $HOME/.config/dart/pub-credentials.json + + - name: Patch pubspec versions + working-directory: "src" + run: | + for pkg in \ + "serious_python" \ + "serious_python_platform_interface" \ + "serious_python_android" \ + "serious_python_darwin" \ + "serious_python_windows" \ + "serious_python_linux"; do + + uv run "$SCRIPTS/patch_pubspec.py" "$pkg/pubspec.yaml" "$PKG_VER" + done + + - name: Publish packages + run: | + publish_pkg () { + pushd "$1" >/dev/null + dart pub publish --force + popd >/dev/null + } + + publish_pkg src/serious_python_platform_interface + sleep 600 + publish_pkg src/serious_python_android + publish_pkg src/serious_python_darwin + publish_pkg src/serious_python_windows + publish_pkg src/serious_python_linux + sleep 600 + publish_pkg src/serious_python \ No newline at end of file diff --git a/ci/download_artifact.py b/ci/download_artifact.py deleted file mode 100644 index 6b37f5d7..00000000 --- a/ci/download_artifact.py +++ /dev/null @@ -1,51 +0,0 @@ -import json -import os -import pathlib -import sys -import tarfile -import urllib.request - -if len(sys.argv) < 2: - print("Specify artifact job name and artifact deployment name to download") - sys.exit(1) - -artifact_job_name = sys.argv[1] -artifact_file_name = sys.argv[2].format( - version=os.environ.get("APPVEYOR_BUILD_VERSION") -) - -build_jobs = {} - - -def download_job_artifact(job_id, file_name, dest_file): - url = f"https://ci.appveyor.com/api/buildjobs/{job_id}/artifacts/{file_name}" - print(f"Downloading {url}...") - urllib.request.urlretrieve(url, dest_file) - - -def get_build_job_ids(): - account_name = os.environ.get("APPVEYOR_ACCOUNT_NAME") - project_slug = os.environ.get("APPVEYOR_PROJECT_SLUG") - build_id = os.environ.get("APPVEYOR_BUILD_ID") - url = f"https://ci.appveyor.com/api/projects/{account_name}/{project_slug}/builds/{build_id}" - print(f"Fetching build details at {url}") - req = urllib.request.Request(url) - req.add_header("Content-type", "application/json") - project = json.loads(urllib.request.urlopen(req).read().decode()) - for job in project["build"]["jobs"]: - build_jobs[job["name"]] = job["jobId"] - - -current_dir = pathlib.Path(os.getcwd()) -print("current_dir", current_dir) - -get_build_job_ids() - -# create "web" directory -dist_path = current_dir.joinpath("python_dist") -dist_path.mkdir(exist_ok=True) -tar_path = current_dir.joinpath(artifact_file_name) -download_job_artifact(build_jobs[artifact_job_name], artifact_file_name, tar_path) -with tarfile.open(tar_path, "r:gz") as tar: - tar.extractall(str(dist_path)) -os.remove(tar_path) diff --git a/ci/install_flutter.sh b/ci/install_flutter.sh deleted file mode 100755 index 7366c8af..00000000 --- a/ci/install_flutter.sh +++ /dev/null @@ -1,6 +0,0 @@ -dart pub global activate fvm -export PATH=$HOME/.pub-cache/bin:$HOME/fvm/default/bin:$PATH -fvm install $FLUTTER_VERSION -fvm global $FLUTTER_VERSION -flutter --version -flutter doctor \ No newline at end of file diff --git a/src/serious_python/example/flet_example/integration_test/app_test.dart b/src/serious_python/example/flet_example/integration_test/app_test.dart index d32be512..880d75ff 100644 --- a/src/serious_python/example/flet_example/integration_test/app_test.dart +++ b/src/serious_python/example/flet_example/integration_test/app_test.dart @@ -10,7 +10,7 @@ void main() { testWidgets('make sure counter can be incremented and decremented', (tester) async { app.main(); - await tester.pumpAndSettle(); + await tester.pumpAndSettle(const Duration(seconds: 5)); // Wait for up to 10 seconds for the app to start bool counterFound = false; diff --git a/src/serious_python_android/analysis_options.yaml b/src/serious_python_android/analysis_options.yaml index 872a1ebd..e550cb50 100644 --- a/src/serious_python_android/analysis_options.yaml +++ b/src/serious_python_android/analysis_options.yaml @@ -1,4 +1,8 @@ include: package:flutter_lints/flutter.yaml +analyzer: + exclude: + - lib/src/gen.dart + # Additional information about this file can be found at # https://dart.dev/guides/language/analysis-options \ No newline at end of file