From 884b8688ab016f7cd1d17492b62edbcf45067d5a Mon Sep 17 00:00:00 2001 From: Dennis Moschina <45356478+DennisMoschina@users.noreply.github.com> Date: Mon, 2 Mar 2026 13:04:26 +0100 Subject: [PATCH 1/4] feat(workflows): Add CI workflow for building PR artifacts across platforms --- .github/workflows/pr_build_all_platforms.yml | 130 ++++++++++++++++++ .../Flutter/GeneratedPluginRegistrant.swift | 2 + open_wearable/pubspec.lock | 72 ++-------- 3 files changed, 144 insertions(+), 60 deletions(-) create mode 100644 .github/workflows/pr_build_all_platforms.yml diff --git a/.github/workflows/pr_build_all_platforms.yml b/.github/workflows/pr_build_all_platforms.yml new file mode 100644 index 00000000..abb6ea9f --- /dev/null +++ b/.github/workflows/pr_build_all_platforms.yml @@ -0,0 +1,130 @@ +name: Build PR Artifacts + +on: + pull_request: + types: + - opened + - synchronize + - reopened + - ready_for_review + +permissions: + contents: read + +concurrency: + group: pr-build-artifacts-${{ github.event.pull_request.number || github.ref }} + cancel-in-progress: true + +env: + APP_DIR: open_wearable + +jobs: + build_ubuntu_targets: + name: Build Android, Linux, and Web + runs-on: ubuntu-latest + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Set up Java + uses: actions/setup-java@v4 + with: + distribution: zulu + java-version: "17" + cache: gradle + + - name: Install Linux build dependencies + run: | + sudo apt-get update + sudo apt-get install -y \ + clang \ + cmake \ + libgtk-3-dev \ + ninja-build \ + pkg-config + + - name: Read Flutter version + run: echo "flutter_version=$(cat $APP_DIR/.flutter_version)" >> "$GITHUB_ENV" + + - name: Set up Flutter + uses: subosito/flutter-action@v2 + with: + channel: stable + flutter-version: ${{ env.flutter_version }} + cache: true + + - name: Install dependencies + working-directory: ${{ env.APP_DIR }} + run: flutter pub get + + - name: Analyze project + working-directory: ${{ env.APP_DIR }} + run: flutter analyze + + - name: Build Android APK + working-directory: ${{ env.APP_DIR }} + run: flutter build apk --release + + - name: Build Linux bundle + working-directory: ${{ env.APP_DIR }} + run: flutter build linux --release + + - name: Build Web bundle + working-directory: ${{ env.APP_DIR }} + run: flutter build web --release + + - name: Upload Android APK + uses: actions/upload-artifact@v4 + with: + name: android-apk + path: open_wearable/build/app/outputs/flutter-apk/app-release.apk + if-no-files-found: error + + - name: Upload Linux bundle + uses: actions/upload-artifact@v4 + with: + name: linux-bundle + path: open_wearable/build/linux/x64/release/bundle + if-no-files-found: error + + - name: Upload Web bundle + uses: actions/upload-artifact@v4 + with: + name: web-bundle + path: open_wearable/build/web + if-no-files-found: error + + build_windows_target: + name: Build Windows + runs-on: windows-latest + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Read Flutter version + shell: bash + run: echo "flutter_version=$(cat $APP_DIR/.flutter_version)" >> "$GITHUB_ENV" + + - name: Set up Flutter + uses: subosito/flutter-action@v2 + with: + channel: stable + flutter-version: ${{ env.flutter_version }} + cache: true + + - name: Install dependencies + working-directory: ${{ env.APP_DIR }} + run: flutter pub get + + - name: Build Windows runner + working-directory: ${{ env.APP_DIR }} + run: flutter build windows --release + + - name: Upload Windows runner + uses: actions/upload-artifact@v4 + with: + name: windows-runner + path: open_wearable/build/windows/x64/runner/Release + if-no-files-found: error \ No newline at end of file diff --git a/open_wearable/macos/Flutter/GeneratedPluginRegistrant.swift b/open_wearable/macos/Flutter/GeneratedPluginRegistrant.swift index 7da018f9..a3e457d4 100644 --- a/open_wearable/macos/Flutter/GeneratedPluginRegistrant.swift +++ b/open_wearable/macos/Flutter/GeneratedPluginRegistrant.swift @@ -9,6 +9,7 @@ import file_picker import file_selector_macos import flutter_archive import open_file_mac +import path_provider_foundation import share_plus import shared_preferences_foundation import universal_ble @@ -19,6 +20,7 @@ func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) { FileSelectorPlugin.register(with: registry.registrar(forPlugin: "FileSelectorPlugin")) FlutterArchivePlugin.register(with: registry.registrar(forPlugin: "FlutterArchivePlugin")) OpenFilePlugin.register(with: registry.registrar(forPlugin: "OpenFilePlugin")) + PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin")) SharePlusMacosPlugin.register(with: registry.registrar(forPlugin: "SharePlusMacosPlugin")) SharedPreferencesPlugin.register(with: registry.registrar(forPlugin: "SharedPreferencesPlugin")) UniversalBlePlugin.register(with: registry.registrar(forPlugin: "UniversalBlePlugin")) diff --git a/open_wearable/pubspec.lock b/open_wearable/pubspec.lock index 034ce0e3..063d40a4 100644 --- a/open_wearable/pubspec.lock +++ b/open_wearable/pubspec.lock @@ -45,10 +45,10 @@ packages: dependency: transitive description: name: characters - sha256: faf38497bda5ead2a8c7615f4f7939df04333478bf32e4173fcb06d428b5716b + sha256: f71061c654a3380576a52b451dd5532377954cf9dbd272a78fc8479606670803 url: "https://pub.dev" source: hosted - version: "1.4.1" + version: "1.4.0" clock: dependency: transitive description: @@ -57,14 +57,6 @@ packages: url: "https://pub.dev" source: hosted version: "1.1.2" - code_assets: - dependency: transitive - description: - name: code_assets - sha256: "83ccdaa064c980b5596c35dd64a8d3ecc68620174ab9b90b6343b753aa721687" - url: "https://pub.dev" - source: hosted - version: "1.0.0" collection: dependency: transitive description: @@ -336,14 +328,6 @@ packages: description: flutter source: sdk version: "0.0.0" - glob: - dependency: transitive - description: - name: glob - sha256: c3f1ee72c96f8f78935e18aa8cecced9ab132419e8625dc187e1c2408efc20de - url: "https://pub.dev" - source: hosted - version: "2.1.3" go_router: dependency: "direct main" description: @@ -352,14 +336,6 @@ packages: url: "https://pub.dev" source: hosted version: "14.8.1" - hooks: - dependency: transitive - description: - name: hooks - sha256: "7a08a0d684cb3b8fb604b78455d5d352f502b68079f7b80b831c62220ab0a4f6" - url: "https://pub.dev" - source: hosted - version: "1.0.1" http: dependency: "direct main" description: @@ -444,18 +420,18 @@ packages: dependency: transitive description: name: matcher - sha256: "12956d0ad8390bbcc63ca2e1469c0619946ccb52809807067a7020d57e647aa6" + sha256: dc58c723c3c24bf8d3e2d3ad3f2f9d7bd9cf43ec6feaa64181775e60190153f2 url: "https://pub.dev" source: hosted - version: "0.12.18" + version: "0.12.17" material_color_utilities: dependency: transitive description: name: material_color_utilities - sha256: "9c337007e82b1889149c82ed242ed1cb24a66044e30979c44912381e9be4c48b" + sha256: f7142bb1154231d7ea5f96bc7bde4bda2a0945d2806bb11670e30b850d56bdec url: "https://pub.dev" source: hosted - version: "0.13.0" + version: "0.11.1" mcumgr_flutter: dependency: "direct main" description: @@ -480,14 +456,6 @@ packages: url: "https://pub.dev" source: hosted version: "2.0.0" - native_toolchain_c: - dependency: transitive - description: - name: native_toolchain_c - sha256: "89e83885ba09da5fdf2cdacc8002a712ca238c28b7f717910b34bcd27b0d03ac" - url: "https://pub.dev" - source: hosted - version: "0.17.4" nested: dependency: transitive description: @@ -496,14 +464,6 @@ packages: url: "https://pub.dev" source: hosted version: "1.0.0" - objective_c: - dependency: transitive - description: - name: objective_c - sha256: "983c7fa1501f6dcc0cb7af4e42072e9993cb28d73604d25ebf4dab08165d997e" - url: "https://pub.dev" - source: hosted - version: "9.2.5" open_earable_flutter: dependency: "direct main" description: @@ -612,10 +572,10 @@ packages: dependency: transitive description: name: path_provider_foundation - sha256: "2a376b7d6392d80cd3705782d2caa734ca4727776db0b6ec36ef3f1855197699" + sha256: "6d13aece7b3f5c5a9731eaf553ff9dcbc2eff41087fd2df587fd0fed9a3eb0c4" url: "https://pub.dev" source: hosted - version: "2.6.0" + version: "2.5.1" path_provider_linux: dependency: transitive description: @@ -865,10 +825,10 @@ packages: dependency: transitive description: name: test_api - sha256: "19a78f63e83d3a61f00826d09bc2f60e191bf3504183c001262be6ac75589fb8" + sha256: ab2726c1a94d3176a45960b6234466ec367179b87dd74f1611adb1f3b5fb9d55 url: "https://pub.dev" source: hosted - version: "0.7.8" + version: "0.7.7" tuple: dependency: transitive description: @@ -1037,14 +997,6 @@ packages: url: "https://pub.dev" source: hosted version: "6.6.1" - yaml: - dependency: transitive - description: - name: yaml - sha256: b9da305ac7c39faa3f030eccd175340f968459dae4af175130b3fc47e40d76ce - url: "https://pub.dev" - source: hosted - version: "3.1.3" sdks: - dart: ">=3.10.3 <4.0.0" - flutter: ">=3.38.4" + dart: ">=3.10.0 <4.0.0" + flutter: ">=3.38.0" From 1d59cb7927c3c4d1ea8ab56657a86a321c7f09e7 Mon Sep 17 00:00:00 2001 From: Dennis Moschina <45356478+DennisMoschina@users.noreply.github.com> Date: Mon, 9 Mar 2026 09:34:13 +0100 Subject: [PATCH 2/4] feat(workflows): Enhance CI workflow to build Android, Linux, Windows, and Web artifacts with artifact commenting --- .github/actions/flutter-prepare/action.yml | 27 +++ .github/workflows/pr_build_all_platforms.yml | 193 +++++++++++++------ 2 files changed, 165 insertions(+), 55 deletions(-) create mode 100644 .github/actions/flutter-prepare/action.yml diff --git a/.github/actions/flutter-prepare/action.yml b/.github/actions/flutter-prepare/action.yml new file mode 100644 index 00000000..f40b9d5a --- /dev/null +++ b/.github/actions/flutter-prepare/action.yml @@ -0,0 +1,27 @@ +name: Flutter Prepare +description: Set up Flutter from .flutter_version and fetch dependencies. + +inputs: + app-dir: + description: Path to the Flutter application directory. + required: true + +runs: + using: composite + steps: + - name: Read Flutter version + id: flutter_version + shell: bash + run: echo "version=$(cat ${{ inputs.app-dir }}/.flutter_version)" >> "$GITHUB_OUTPUT" + + - name: Set up Flutter + uses: subosito/flutter-action@v2 + with: + channel: stable + flutter-version: ${{ steps.flutter_version.outputs.version }} + cache: true + + - name: Install dependencies + shell: bash + working-directory: ${{ inputs.app-dir }} + run: flutter pub get diff --git a/.github/workflows/pr_build_all_platforms.yml b/.github/workflows/pr_build_all_platforms.yml index abb6ea9f..fa58cadc 100644 --- a/.github/workflows/pr_build_all_platforms.yml +++ b/.github/workflows/pr_build_all_platforms.yml @@ -10,6 +10,7 @@ on: permissions: contents: read + pull-requests: write concurrency: group: pr-build-artifacts-${{ github.event.pull_request.number || github.ref }} @@ -19,9 +20,11 @@ env: APP_DIR: open_wearable jobs: - build_ubuntu_targets: - name: Build Android, Linux, and Web + build_android: + name: Build Android runs-on: ubuntu-latest + outputs: + artifact_id: ${{ steps.upload_android.outputs.artifact-id }} steps: - name: Checkout repository @@ -34,6 +37,33 @@ jobs: java-version: "17" cache: gradle + - name: Set up Flutter project + uses: ./.github/actions/flutter-prepare + with: + app-dir: ${{ env.APP_DIR }} + + - name: Build Android APK + working-directory: ${{ env.APP_DIR }} + run: flutter build apk --release + + - name: Upload Android APK + id: upload_android + uses: actions/upload-artifact@v4 + with: + name: android-apk + path: open_wearable/build/app/outputs/flutter-apk/app-release.apk + if-no-files-found: error + + build_linux: + name: Build Linux + runs-on: ubuntu-latest + outputs: + artifact_id: ${{ steps.upload_linux.outputs.artifact-id }} + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + - name: Install Linux build dependencies run: | sudo apt-get update @@ -44,87 +74,140 @@ jobs: ninja-build \ pkg-config - - name: Read Flutter version - run: echo "flutter_version=$(cat $APP_DIR/.flutter_version)" >> "$GITHUB_ENV" - - - name: Set up Flutter - uses: subosito/flutter-action@v2 + - name: Set up Flutter project + uses: ./.github/actions/flutter-prepare with: - channel: stable - flutter-version: ${{ env.flutter_version }} - cache: true - - - name: Install dependencies - working-directory: ${{ env.APP_DIR }} - run: flutter pub get - - - name: Analyze project - working-directory: ${{ env.APP_DIR }} - run: flutter analyze - - - name: Build Android APK - working-directory: ${{ env.APP_DIR }} - run: flutter build apk --release + app-dir: ${{ env.APP_DIR }} - name: Build Linux bundle working-directory: ${{ env.APP_DIR }} run: flutter build linux --release - - name: Build Web bundle - working-directory: ${{ env.APP_DIR }} - run: flutter build web --release - - - name: Upload Android APK - uses: actions/upload-artifact@v4 - with: - name: android-apk - path: open_wearable/build/app/outputs/flutter-apk/app-release.apk - if-no-files-found: error - - name: Upload Linux bundle + id: upload_linux uses: actions/upload-artifact@v4 with: name: linux-bundle path: open_wearable/build/linux/x64/release/bundle if-no-files-found: error - - name: Upload Web bundle - uses: actions/upload-artifact@v4 - with: - name: web-bundle - path: open_wearable/build/web - if-no-files-found: error - - build_windows_target: + build_windows: name: Build Windows runs-on: windows-latest + outputs: + artifact_id: ${{ steps.upload_windows.outputs.artifact-id }} steps: - name: Checkout repository uses: actions/checkout@v4 - - name: Read Flutter version - shell: bash - run: echo "flutter_version=$(cat $APP_DIR/.flutter_version)" >> "$GITHUB_ENV" - - - name: Set up Flutter - uses: subosito/flutter-action@v2 + - name: Set up Flutter project + uses: ./.github/actions/flutter-prepare with: - channel: stable - flutter-version: ${{ env.flutter_version }} - cache: true - - - name: Install dependencies - working-directory: ${{ env.APP_DIR }} - run: flutter pub get + app-dir: ${{ env.APP_DIR }} - name: Build Windows runner working-directory: ${{ env.APP_DIR }} run: flutter build windows --release - name: Upload Windows runner + id: upload_windows uses: actions/upload-artifact@v4 with: name: windows-runner path: open_wearable/build/windows/x64/runner/Release - if-no-files-found: error \ No newline at end of file + if-no-files-found: error + + build_web: + name: Build Web + runs-on: ubuntu-latest + outputs: + artifact_id: ${{ steps.upload_web.outputs.artifact-id }} + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Set up Flutter project + uses: ./.github/actions/flutter-prepare + with: + app-dir: ${{ env.APP_DIR }} + + - name: Build Web bundle + working-directory: ${{ env.APP_DIR }} + run: flutter build web --release + + - name: Upload Web bundle + id: upload_web + uses: actions/upload-artifact@v4 + with: + name: web-bundle + path: open_wearable/build/web + if-no-files-found: error + + comment_artifact_links: + name: Comment Artifact Links + runs-on: ubuntu-latest + needs: + - build_android + - build_linux + - build_windows + - build_web + if: always() + + steps: + - name: Post or update PR comment with artifact links + uses: actions/github-script@v7 + env: + RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }} + ANDROID_ARTIFACT_ID: ${{ needs.build_android.outputs.artifact_id }} + LINUX_ARTIFACT_ID: ${{ needs.build_linux.outputs.artifact_id }} + WINDOWS_ARTIFACT_ID: ${{ needs.build_windows.outputs.artifact_id }} + WEB_ARTIFACT_ID: ${{ needs.build_web.outputs.artifact_id }} + with: + script: | + const marker = ''; + const prNumber = context.payload.pull_request.number; + const runUrl = process.env.RUN_URL; + const repoUrl = `${context.serverUrl}/${context.repo.owner}/${context.repo.repo}`; + const linkFor = (id) => id + ? `${repoUrl}/actions/runs/${context.runId}/artifacts/${id}` + : runUrl; + + const body = `${marker} + ### PR Build Artifacts + - Android: [Download artifact](${linkFor(process.env.ANDROID_ARTIFACT_ID)}) + - Linux: [Download artifact](${linkFor(process.env.LINUX_ARTIFACT_ID)}) + - Windows: [Download artifact](${linkFor(process.env.WINDOWS_ARTIFACT_ID)}) + - Web: [Download artifact](${linkFor(process.env.WEB_ARTIFACT_ID)}) + + Full workflow run: ${runUrl}`; + + const { data: comments } = await github.rest.issues.listComments({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: prNumber, + }); + + const previous = comments.find( + (comment) => + comment.user.type === 'Bot' && + comment.body && + comment.body.includes(marker) + ); + + if (previous) { + await github.rest.issues.updateComment({ + owner: context.repo.owner, + repo: context.repo.repo, + comment_id: previous.id, + body, + }); + } else { + await github.rest.issues.createComment({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: prNumber, + body, + }); + } From 42bf8696428416f12d1d15f7febdb96bb57f2aef Mon Sep 17 00:00:00 2001 From: Dennis Moschina <45356478+DennisMoschina@users.noreply.github.com> Date: Mon, 9 Mar 2026 13:18:30 +0100 Subject: [PATCH 3/4] fix(workflows): Update artifact download links in PR comment for clarity --- .github/workflows/pr_build_all_platforms.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/pr_build_all_platforms.yml b/.github/workflows/pr_build_all_platforms.yml index fa58cadc..fef8de90 100644 --- a/.github/workflows/pr_build_all_platforms.yml +++ b/.github/workflows/pr_build_all_platforms.yml @@ -176,10 +176,10 @@ jobs: const body = `${marker} ### PR Build Artifacts - - Android: [Download artifact](${linkFor(process.env.ANDROID_ARTIFACT_ID)}) - - Linux: [Download artifact](${linkFor(process.env.LINUX_ARTIFACT_ID)}) - - Windows: [Download artifact](${linkFor(process.env.WINDOWS_ARTIFACT_ID)}) - - Web: [Download artifact](${linkFor(process.env.WEB_ARTIFACT_ID)}) + - Android APK: [Download Android build](${linkFor(process.env.ANDROID_ARTIFACT_ID)}) + - Linux Bundle: [Download Linux build](${linkFor(process.env.LINUX_ARTIFACT_ID)}) + - Windows Runner: [Download Windows build](${linkFor(process.env.WINDOWS_ARTIFACT_ID)}) + - Web Bundle: [Download Web build](${linkFor(process.env.WEB_ARTIFACT_ID)}) Full workflow run: ${runUrl}`; From b879a0ca6e704bdb068d5ba62d92c620cb8b4c98 Mon Sep 17 00:00:00 2001 From: Dennis Moschina <45356478+DennisMoschina@users.noreply.github.com> Date: Mon, 9 Mar 2026 13:24:59 +0100 Subject: [PATCH 4/4] fix(workflows): Upgrade action versions in PR build workflow for consistency --- .github/workflows/pr_build_all_platforms.yml | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/.github/workflows/pr_build_all_platforms.yml b/.github/workflows/pr_build_all_platforms.yml index fef8de90..18215c22 100644 --- a/.github/workflows/pr_build_all_platforms.yml +++ b/.github/workflows/pr_build_all_platforms.yml @@ -28,10 +28,10 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@v4 + uses: actions/checkout@v6 - name: Set up Java - uses: actions/setup-java@v4 + uses: actions/setup-java@v5 with: distribution: zulu java-version: "17" @@ -48,7 +48,7 @@ jobs: - name: Upload Android APK id: upload_android - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@v6 with: name: android-apk path: open_wearable/build/app/outputs/flutter-apk/app-release.apk @@ -62,7 +62,7 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@v4 + uses: actions/checkout@v6 - name: Install Linux build dependencies run: | @@ -85,7 +85,7 @@ jobs: - name: Upload Linux bundle id: upload_linux - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@v6 with: name: linux-bundle path: open_wearable/build/linux/x64/release/bundle @@ -99,7 +99,7 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@v4 + uses: actions/checkout@v6 - name: Set up Flutter project uses: ./.github/actions/flutter-prepare @@ -112,7 +112,7 @@ jobs: - name: Upload Windows runner id: upload_windows - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@v6 with: name: windows-runner path: open_wearable/build/windows/x64/runner/Release @@ -126,7 +126,7 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@v4 + uses: actions/checkout@v6 - name: Set up Flutter project uses: ./.github/actions/flutter-prepare @@ -139,7 +139,7 @@ jobs: - name: Upload Web bundle id: upload_web - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@v6 with: name: web-bundle path: open_wearable/build/web @@ -157,7 +157,7 @@ jobs: steps: - name: Post or update PR comment with artifact links - uses: actions/github-script@v7 + uses: actions/github-script@v8 env: RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }} ANDROID_ARTIFACT_ID: ${{ needs.build_android.outputs.artifact_id }}