Skip to content

Commit 9a6c7f9

Browse files
committed
Merge branch 'firestore-pipelines-dart-api-v2' into firestore-pipelines-web
2 parents 3ebb93d + ac36278 commit 9a6c7f9

File tree

7 files changed

+266
-11
lines changed

7 files changed

+266
-11
lines changed
Lines changed: 208 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,208 @@
1+
name: e2e-pipeline
2+
3+
concurrency:
4+
group: ${{ github.workflow }}-${{ github.ref }}
5+
cancel-in-progress: true
6+
7+
# on:
8+
# pull_request:
9+
# paths:
10+
# - 'packages/cloud_firestore/cloud_firestore/pipeline_example/**'
11+
# - 'packages/cloud_firestore/cloud_firestore/lib/**'
12+
# - '.github/workflows/e2e_tests_pipeline.yaml'
13+
# push:
14+
# branches:
15+
# - main
16+
# - firestore-pipelines-dart-api-v2
17+
# - master
18+
# paths:
19+
# - 'packages/cloud_firestore/cloud_firestore/pipeline_example/**'
20+
# - 'packages/cloud_firestore/cloud_firestore/lib/**'
21+
# - '.github/workflows/e2e_tests_pipeline.yaml'
22+
23+
on:
24+
pull_request:
25+
push:
26+
workflow_dispatch:
27+
28+
jobs:
29+
pipeline-e2e-android:
30+
runs-on: ubuntu-latest
31+
timeout-minutes: 45
32+
env:
33+
AVD_ARCH: x86_64
34+
AVD_API_LEVEL: 34
35+
AVD_TARGET: google_apis
36+
steps:
37+
- uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938
38+
- uses: actions/setup-node@1d0ff469b7ec7b3cb9d8673fde0c81c44821de2a
39+
name: Install Node.js 20
40+
with:
41+
node-version: '20'
42+
- uses: actions/setup-java@8df1039502a15bceb9433410b1a100fbe190c53b
43+
with:
44+
distribution: 'temurin'
45+
java-version: '21'
46+
- uses: subosito/flutter-action@f2c4f6686ca8e8d6e6d0f28410eeef506ed66aff
47+
with:
48+
channel: 'stable'
49+
cache: true
50+
cache-key: "flutter-:os:-:channel:-:version:-:arch:-:hash:"
51+
pub-cache-key: "flutter-pub-:os:-:channel:-:version:-:arch:-:hash:"
52+
- uses: bluefireteam/melos-action@c7dcb921b23cc520cace360b95d02b37bf09cdaa
53+
with:
54+
run-bootstrap: false
55+
melos-version: '5.3.0'
56+
- name: Inject Firebase config for pipeline E2E
57+
env:
58+
FIREBASE_OPTIONS_DART: ${{ secrets.PIPELINE_E2E_FIREBASE_OPTIONS_DART }}
59+
GOOGLE_SERVICES_JSON: ${{ secrets.PIPELINE_E2E_GOOGLE_SERVICES_JSON }}
60+
GOOGLE_SERVICE_INFO_PLIST: ${{ secrets.PIPELINE_E2E_GOOGLE_SERVICE_INFO_PLIST }}
61+
run: |
62+
echo "$FIREBASE_OPTIONS_DART" > packages/cloud_firestore/cloud_firestore/pipeline_example/lib/firebase_options.dart
63+
echo "$GOOGLE_SERVICES_JSON" > packages/cloud_firestore/cloud_firestore/pipeline_example/android/app/google-services.json
64+
echo "$GOOGLE_SERVICE_INFO_PLIST" > packages/cloud_firestore/cloud_firestore/pipeline_example/ios/Runner/GoogleService-Info.plist
65+
- name: Bootstrap package
66+
run: melos bootstrap --scope "cloud_firestore*"
67+
- name: Enable KVM
68+
run: |
69+
echo 'KERNEL=="kvm", GROUP="kvm", MODE="0666", OPTIONS+="static_node=kvm"' | sudo tee /etc/udev/rules.d/99-kvm4all.rules
70+
sudo udevadm control --reload-rules
71+
sudo udevadm trigger --name-match=kvm
72+
- name: Gradle cache
73+
uses: gradle/actions/setup-gradle@v4
74+
- name: Free Disk Space (Ubuntu)
75+
uses: AdityaGarg8/remove-unwanted-software@90e01b21170618765a73370fcc3abbd1684a7793
76+
with:
77+
remove-dotnet: true
78+
remove-haskell: true
79+
remove-codeql: true
80+
remove-docker-images: true
81+
remove-large-packages: true
82+
- name: AVD cache
83+
uses: actions/cache/restore@1bd1e32a3bdc45362d1e726936510720a7c30a57
84+
continue-on-error: true
85+
id: avd-cache
86+
with:
87+
path: |
88+
~/.android/avd/*
89+
~/.android/adb*
90+
key: avd-${{ runner.os }}-${{ env.AVD_API_LEVEL }}-${{ env.AVD_TARGET }}-${{ env.AVD_ARCH }}
91+
- name: Start AVD then run pipeline E2E tests
92+
uses: reactivecircus/android-emulator-runner@b530d96654c385303d652368551fb075bc2f0b6b
93+
with:
94+
api-level: ${{ env.AVD_API_LEVEL }}
95+
target: ${{ env.AVD_TARGET }}
96+
arch: ${{ env.AVD_ARCH }}
97+
emulator-build: 14214601
98+
working-directory: packages/cloud_firestore/cloud_firestore/pipeline_example
99+
script: |
100+
flutter test integration_test/pipeline/pipeline_live_test.dart --timeout 10x --dart-define=CI=true -d emulator-5554
101+
- name: Ensure Appium is shut down
102+
run: |
103+
pgrep -f appium && pkill -f appium || echo "No Appium process found"
104+
- name: Save Android Emulator Cache
105+
if: github.ref == 'refs/heads/main'
106+
uses: actions/cache/save@1bd1e32a3bdc45362d1e726936510720a7c30a57
107+
continue-on-error: true
108+
with:
109+
key: ${{ steps.avd-cache.outputs.cache-primary-key }}
110+
path: |
111+
~/.android/avd/*
112+
~/.android/adb*
113+
114+
pipeline-e2e-web:
115+
runs-on: macos-latest
116+
timeout-minutes: 25
117+
steps:
118+
- uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938
119+
- uses: actions/setup-node@1d0ff469b7ec7b3cb9d8673fde0c81c44821de2a
120+
name: Install Node.js 20
121+
with:
122+
node-version: '20'
123+
- uses: subosito/flutter-action@f2c4f6686ca8e8d6e6d0f28410eeef506ed66aff
124+
with:
125+
channel: 'stable'
126+
cache: true
127+
cache-key: "flutter-:os:-:channel:-:version:-:arch:-:hash:"
128+
pub-cache-key: "flutter-pub-:os:-:channel:-:version:-:arch:-:hash:"
129+
- uses: bluefireteam/melos-action@c7dcb921b23cc520cace360b95d02b37bf09cdaa
130+
with:
131+
run-bootstrap: false
132+
melos-version: '5.3.0'
133+
- name: Inject Firebase config for pipeline E2E
134+
env:
135+
FIREBASE_OPTIONS_DART: ${{ secrets.PIPELINE_E2E_FIREBASE_OPTIONS_DART }}
136+
GOOGLE_SERVICES_JSON: ${{ secrets.PIPELINE_E2E_GOOGLE_SERVICES_JSON }}
137+
GOOGLE_SERVICE_INFO_PLIST: ${{ secrets.PIPELINE_E2E_GOOGLE_SERVICE_INFO_PLIST }}
138+
run: |
139+
echo "$FIREBASE_OPTIONS_DART" > packages/cloud_firestore/cloud_firestore/pipeline_example/lib/firebase_options.dart
140+
echo "$GOOGLE_SERVICES_JSON" > packages/cloud_firestore/cloud_firestore/pipeline_example/android/app/google-services.json
141+
echo "$GOOGLE_SERVICE_INFO_PLIST" > packages/cloud_firestore/cloud_firestore/pipeline_example/ios/Runner/GoogleService-Info.plist
142+
- name: Bootstrap package
143+
run: melos bootstrap --scope "cloud_firestore*"
144+
- name: Run pipeline E2E tests (Chrome)
145+
working-directory: packages/cloud_firestore/cloud_firestore/pipeline_example
146+
# Web devices are not supported for the `flutter test` command yet. As a
147+
# workaround we use the `flutter drive` command. Tracking issue:
148+
# https://github.com/flutter/flutter/issues/66264
149+
run: |
150+
chromedriver --port=4444 --trace-buffer-size=100000 &
151+
flutter drive --target=./integration_test/pipeline/pipeline_live_test.dart --driver=./test_driver/integration_test.dart -d chrome --dart-define=CI=true | tee output.log
152+
output=$(<output.log)
153+
if [[ "$output" =~ \[E\] ]]; then
154+
echo "All tests did not pass. Please check the logs for more information."
155+
exit 1
156+
fi
157+
shell: bash
158+
159+
pipeline-e2e-ios:
160+
runs-on: macos-15
161+
timeout-minutes: 50
162+
steps:
163+
- uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938
164+
- uses: actions/setup-node@1d0ff469b7ec7b3cb9d8673fde0c81c44821de2a
165+
name: Install Node.js 20
166+
with:
167+
node-version: '20'
168+
- name: Xcode
169+
run: sudo xcode-select -s /Applications/Xcode_16.4.app/Contents/Developer
170+
- uses: actions/setup-java@8df1039502a15bceb9433410b1a100fbe190c53b
171+
with:
172+
distribution: 'temurin'
173+
java-version: '21'
174+
- uses: subosito/flutter-action@f2c4f6686ca8e8d6e6d0f28410eeef506ed66aff
175+
with:
176+
channel: 'stable'
177+
cache: true
178+
cache-key: "flutter-:os:-:channel:-:version:-:arch:-:hash:"
179+
pub-cache-key: "flutter-pub-:os:-:channel:-:version:-:arch:-:hash:"
180+
- uses: bluefireteam/melos-action@c7dcb921b23cc520cace360b95d02b37bf09cdaa
181+
with:
182+
run-bootstrap: false
183+
melos-version: '5.3.0'
184+
- name: Inject Firebase config for pipeline E2E
185+
env:
186+
FIREBASE_OPTIONS_DART: ${{ secrets.PIPELINE_E2E_FIREBASE_OPTIONS_DART }}
187+
GOOGLE_SERVICES_JSON: ${{ secrets.PIPELINE_E2E_GOOGLE_SERVICES_JSON }}
188+
GOOGLE_SERVICE_INFO_PLIST: ${{ secrets.PIPELINE_E2E_GOOGLE_SERVICE_INFO_PLIST }}
189+
run: |
190+
echo "$FIREBASE_OPTIONS_DART" > packages/cloud_firestore/cloud_firestore/pipeline_example/lib/firebase_options.dart
191+
echo "$GOOGLE_SERVICES_JSON" > packages/cloud_firestore/cloud_firestore/pipeline_example/android/app/google-services.json
192+
echo "$GOOGLE_SERVICE_INFO_PLIST" > packages/cloud_firestore/cloud_firestore/pipeline_example/ios/Runner/GoogleService-Info.plist
193+
- name: Bootstrap package
194+
run: melos bootstrap --scope "cloud_firestore*"
195+
- uses: futureware-tech/simulator-action@e89aa8f93d3aec35083ff49d2854d07f7186f7f5
196+
id: simulator
197+
with:
198+
model: "iPhone 16"
199+
- name: Build iOS (simulator)
200+
working-directory: packages/cloud_firestore/cloud_firestore/pipeline_example
201+
run: |
202+
flutter build ios --no-codesign --simulator --debug --target=./integration_test/pipeline/pipeline_live_test.dart --dart-define=CI=true
203+
- name: Run pipeline E2E tests (iOS)
204+
working-directory: packages/cloud_firestore/cloud_firestore/pipeline_example
205+
env:
206+
SIMULATOR: ${{ steps.simulator.outputs.udid }}
207+
run: |
208+
flutter test integration_test/pipeline/pipeline_live_test.dart -d "$SIMULATOR" --timeout 10x --dart-define=CI=true

melos.yaml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,13 @@ scripts:
172172
description: |
173173
Run all e2e tests for cloud_firestore.
174174
175+
test:e2e:pipeline:
176+
run: |
177+
cd packages/cloud_firestore/cloud_firestore/pipeline_example
178+
flutter test integration_test/pipeline/pipeline_live_test.dart
179+
description: |
180+
Run pipeline e2e tests.
181+
175182
test:e2e:firebase_performance:
176183
run: |
177184
cd packages/firebase_performance/firebase_performance/example

packages/cloud_firestore/cloud_firestore/pipeline_example/integration_test/pipeline/pipeline_execute_options_e2e.dart

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,6 @@
44

55
import 'package:cloud_firestore/cloud_firestore.dart';
66
import 'package:firebase_core/firebase_core.dart';
7-
import 'package:flutter/foundation.dart'
8-
show defaultTargetPlatform, TargetPlatform;
97
import 'package:flutter_test/flutter_test.dart';
108

119
import 'pipeline_test_helpers.dart';

packages/cloud_firestore/cloud_firestore/pipeline_example/lib/main.dart

Lines changed: 25 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import 'dart:typed_data';
2+
13
import 'package:cloud_firestore/cloud_firestore.dart';
24
import 'package:firebase_core/firebase_core.dart';
35
import 'package:flutter/material.dart';
@@ -12,7 +14,6 @@ Future<void> main() async {
1214
WidgetsFlutterBinding.ensureInitialized();
1315
await Firebase.initializeApp(options: DefaultFirebaseOptions.currentPlatform);
1416
if (shouldUseFirestoreEmulator) {
15-
print('Using Firestore emulator');
1617
FirebaseFirestore.instance.useFirestoreEmulator('localhost', 8080);
1718
}
1819
runApp(const PipelineExampleApp());
@@ -66,7 +67,7 @@ class _PipelineExamplePageState extends State<PipelineExamplePage> {
6667

6768
try {
6869
final col = _firestore.collection(_collectionId);
69-
70+
7071
final batch = _firestore.batch();
7172
_seedDocRefs = [];
7273

@@ -224,6 +225,22 @@ class _PipelineExamplePageState extends State<PipelineExamplePage> {
224225
.execute(),
225226
);
226227

228+
// 1b: execute with ExecuteOptions (indexMode: recommended)
229+
Future<void> _runPipelineExecuteOptions() => _runPipeline(
230+
'Pipeline 1b: same as 1 but execute(options: ExecuteOptions(indexMode: recommended))',
231+
() => _firestore
232+
.pipeline()
233+
.collection(_collectionId)
234+
.where(
235+
Expression.field('score').greaterThan(Expression.constant(10)))
236+
.limit(3)
237+
.execute(
238+
options: const ExecuteOptions(
239+
indexMode: IndexMode.recommended,
240+
),
241+
),
242+
);
243+
227244
// 2: select
228245
Future<void> _runPipeline2() => _runPipeline(
229246
'Pipeline 2: collection → where(year > 2022) → select(title, score, year) → limit(4)',
@@ -464,8 +481,8 @@ class _PipelineExamplePageState extends State<PipelineExamplePage> {
464481
Constant(const GeoPoint(37.7749, -122.4194)).as('c_geo_point'),
465482
// List<int> (raw bytes)
466483
Constant(<int>[72, 101, 108, 108, 111]).as('c_bytes'),
467-
// Blob
468-
Constant(Blob(Uint8List.fromList([1, 2, 3, 4, 5]))).as('c_blob'),
484+
// // Blob
485+
// Constant(Blob(Uint8List.fromList([1, 2, 3, 4, 5]))).as('c_blob'),
469486
// DocumentReference
470487
Constant(docRef).as('c_doc_ref'),
471488
)
@@ -521,7 +538,7 @@ class _PipelineExamplePageState extends State<PipelineExamplePage> {
521538
'Pipeline 21: collection → where(tags arrayContainsAny [x, z]) → select(title, tags) → limit(5)',
522539
() => _firestore
523540
.pipeline()
524-
.collection(_collectionId)
541+
.collection(_collectionId)
525542
.where(
526543
Expression.field('tags').arrayContainsAny(['x', 'z']),
527544
)
@@ -963,6 +980,7 @@ class _PipelineExamplePageState extends State<PipelineExamplePage> {
963980
runSpacing: 8,
964981
children: [
965982
_btn('1: where+limit', _runPipeline1),
983+
_btn('1b: execute(options)', _runPipelineExecuteOptions),
966984
_btn('2: select', _runPipeline2),
967985
_btn('3: aggregate', _runPipeline3),
968986
_btn('4: addFields', _runPipeline4),
@@ -988,7 +1006,7 @@ class _PipelineExamplePageState extends State<PipelineExamplePage> {
9881006
_btn('24: lower/upper', _runPipeline24),
9891007
_btn('25: trim', _runPipeline25),
9901008
_btn('26: substring', _runPipeline26),
991-
// _btn('27: stringReplaceAll', _runPipeline27),
1009+
// test comment
9921010
_btn('28: split', _runPipeline28),
9931011
_btn('29: join', _runPipeline29),
9941012
_btn('30: if_absent', _runPipeline30),
@@ -1057,4 +1075,4 @@ class PipelineExamplePage extends StatefulWidget {
10571075

10581076
@override
10591077
State<PipelineExamplePage> createState() => _PipelineExamplePageState();
1060-
}
1078+
}

packages/cloud_firestore/cloud_firestore/pipeline_example/pubspec.yaml

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,8 @@ environment:
2828
# the latest version available on pub.dev. To see which dependencies have newer
2929
# versions available, run `flutter pub outdated`.
3030
dependencies:
31-
cloud_firestore: ^6.1.2
31+
cloud_firestore:
32+
path: ..
3233
firebase_core: ^4.4.0
3334
flutter:
3435
sdk: flutter
@@ -38,6 +39,22 @@ dependencies:
3839
# Use with the CupertinoIcons class for iOS style icons.
3940
cupertino_icons: ^1.0.8
4041

42+
dependency_overrides:
43+
_flutterfire_internals:
44+
path: ../../../_flutterfire_internals
45+
cloud_firestore:
46+
path: ..
47+
cloud_firestore_platform_interface:
48+
path: ../../cloud_firestore_platform_interface
49+
cloud_firestore_web:
50+
path: ../../cloud_firestore_web
51+
firebase_core:
52+
path: ../../../firebase_core/firebase_core
53+
firebase_core_platform_interface:
54+
path: ../../../firebase_core/firebase_core_platform_interface
55+
firebase_core_web:
56+
path: ../../../firebase_core/firebase_core_web
57+
4158
dev_dependencies:
4259
flutter_test:
4360
sdk: flutter

packages/cloud_firestore/cloud_firestore/pipeline_example/test/widget_test.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ import 'package:pipeline_example/main.dart';
1313
void main() {
1414
testWidgets('Counter increments smoke test', (WidgetTester tester) async {
1515
// Build our app and trigger a frame.
16-
await tester.pumpWidget(const MyApp());
16+
await tester.pumpWidget(const PipelineExampleApp());
1717

1818
// Verify that our counter starts at 0.
1919
expect(find.text('0'), findsOneWidget);
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
// Copyright 2026, the Chromium project authors. Please see the AUTHORS file
2+
// for details. All rights reserved. Use of this source code is governed by a
3+
// BSD-style license that can be found in the LICENSE file.
4+
5+
import 'package:integration_test/integration_test_driver.dart';
6+
7+
Future<void> main() => integrationDriver();

0 commit comments

Comments
 (0)