From 97675f9f483cfed4763b48d3f07b51474e677f32 Mon Sep 17 00:00:00 2001 From: Doug Borg Date: Tue, 10 Feb 2026 19:14:52 -0700 Subject: [PATCH 1/3] Comment on commit c7cfdc471cfc91a3c365642791fdb63d00aedc33 by dougborg on 2026-02-11 02:14:40 UTC --- COMMENT | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 COMMENT diff --git a/COMMENT b/COMMENT new file mode 100644 index 0000000..4a57ce4 --- /dev/null +++ b/COMMENT @@ -0,0 +1,11 @@ +--- +An alternative approach to addressing this issue could be adjusting the `optionsBuilder` logic to avoid returning any suggestions when the input text field is empty, rather than guarding `onFieldSubmitted`. For instance: + +```dart +optionsBuilder: (TextEditingValue textEditingValue) { + if (textEditingValue.text.isEmpty) return []; + return suggestions.where((s) => s.contains(textEditingValue.text)); +} +``` + +This ensures that the `RawAutocomplete` widget doesn't offer any options to auto-select on submission when the field is cleared, potentially simplifying the implementation and avoiding the need for additional boolean flags (`guardOnSubmitted`). This pattern can be seen in some implementations "in the wild." \ No newline at end of file From 8a759e88e9a7cf89ff68608db344e3cc780864fa Mon Sep 17 00:00:00 2001 From: Doug Borg Date: Sat, 14 Feb 2026 19:41:13 -0700 Subject: [PATCH 2/3] Add debug build artifacts and download links to PR workflow Let reviewers download and test PR changes on a device without building locally. A sticky PR comment links directly to the artifacts page. Closes #52 Co-Authored-By: Claude Opus 4.6 --- .github/workflows/pr.yml | 124 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 124 insertions(+) diff --git a/.github/workflows/pr.yml b/.github/workflows/pr.yml index 3acb74d..79714fd 100644 --- a/.github/workflows/pr.yml +++ b/.github/workflows/pr.yml @@ -24,3 +24,127 @@ jobs: - name: Test run: flutter test + + build-debug-apk: + name: Build Debug APK + runs-on: ubuntu-latest + if: github.event_name == 'pull_request' + steps: + - uses: actions/checkout@v5 + + - uses: actions/setup-java@v5 + with: + distribution: 'temurin' + java-version: '17' + + - uses: subosito/flutter-action@v2 + with: + channel: 'stable' + + - run: flutter pub get + + - name: Generate icons and splash screens + run: | + dart run flutter_launcher_icons + dart run flutter_native_splash:create + + - name: Build debug APK + run: flutter build apk --debug + + - name: Upload debug APK + uses: actions/upload-artifact@v4 + with: + name: debug-apk + path: build/app/outputs/flutter-apk/app-debug.apk + if-no-files-found: error + retention-days: 14 + + build-ios-simulator: + name: Build iOS Simulator + runs-on: macos-26 + if: github.event_name == 'pull_request' + steps: + - uses: actions/checkout@v5 + + - uses: subosito/flutter-action@v2 + with: + channel: 'stable' + + - run: flutter pub get + + - name: Generate icons and splash screens + run: | + dart run flutter_launcher_icons + dart run flutter_native_splash:create + + - name: Build iOS simulator app + run: flutter build ios --debug --simulator + + - name: Zip Runner.app + run: cd build/ios/iphonesimulator && zip -r "$GITHUB_WORKSPACE/Runner.app.zip" Runner.app + + - name: Upload simulator build + uses: actions/upload-artifact@v4 + with: + name: ios-simulator + path: Runner.app.zip + if-no-files-found: error + retention-days: 14 + + comment-artifacts: + name: Post Artifact Links + needs: [build-debug-apk, build-ios-simulator] + runs-on: ubuntu-latest + if: github.event_name == 'pull_request' && !cancelled() + permissions: + pull-requests: write + steps: + - uses: actions/github-script@v7 + continue-on-error: true + env: + APK_RESULT: ${{ needs.build-debug-apk.result }} + IOS_RESULT: ${{ needs.build-ios-simulator.result }} + with: + script: | + const runUrl = `${context.serverUrl}/${context.repo.owner}/${context.repo.repo}/actions/runs/${context.runId}#artifacts`; + const apkOk = process.env.APK_RESULT === 'success'; + const iosOk = process.env.IOS_RESULT === 'success'; + + const lines = ['## Debug builds', '']; + + if (apkOk || iosOk) { + lines.push(`Download from the [artifacts page](${runUrl}):`); + if (apkOk) lines.push('- **debug-apk** — install on Android device/emulator'); + if (iosOk) lines.push('- **ios-simulator** — unzip and install with `xcrun simctl install booted Runner.app`'); + } + + if (!apkOk || !iosOk) { + const failed = []; + if (!apkOk) failed.push('Android APK'); + if (!iosOk) failed.push('iOS simulator'); + lines.push('', `**Failed:** ${failed.join(', ')} — check the [workflow run](${runUrl}) for details.`); + } + + const body = lines.join('\n'); + + const { data: comments } = await github.rest.issues.listComments({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: context.issue.number, + }); + const existing = comments.find(c => c.body.startsWith('## Debug builds')); + if (existing) { + await github.rest.issues.updateComment({ + owner: context.repo.owner, + repo: context.repo.repo, + comment_id: existing.id, + body, + }); + } else { + await github.rest.issues.createComment({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: context.issue.number, + body, + }); + } From 348256270d6e5772b0c12c239b5c0665f5d43859 Mon Sep 17 00:00:00 2001 From: Doug Borg Date: Tue, 24 Feb 2026 18:23:20 -0700 Subject: [PATCH 3/3] Cache Flutter SDK, Gradle, and CocoaPods in CI Cold Gradle builds were taking ~8.5 min for the APK job. Add caching for Flutter/pub (via flutter-action), Gradle deps, and CocoaPods to speed up subsequent runs. Co-Authored-By: Claude Opus 4.6 --- .github/workflows/pr.yml | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/.github/workflows/pr.yml b/.github/workflows/pr.yml index 79714fd..3b894d3 100644 --- a/.github/workflows/pr.yml +++ b/.github/workflows/pr.yml @@ -16,6 +16,7 @@ jobs: - uses: subosito/flutter-action@v2 with: channel: 'stable' + cache: true - run: flutter pub get @@ -40,6 +41,15 @@ jobs: - uses: subosito/flutter-action@v2 with: channel: 'stable' + cache: true + + - uses: actions/cache@v4 + with: + path: | + ~/.gradle/caches + ~/.gradle/wrapper + key: gradle-${{ runner.os }}-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }} + restore-keys: gradle-${{ runner.os }}- - run: flutter pub get @@ -69,6 +79,13 @@ jobs: - uses: subosito/flutter-action@v2 with: channel: 'stable' + cache: true + + - uses: actions/cache@v4 + with: + path: ios/Pods + key: pods-${{ runner.os }}-${{ hashFiles('ios/Podfile.lock') }} + restore-keys: pods-${{ runner.os }}- - run: flutter pub get