Skip to content

Commit 59761b5

Browse files
authored
feat: add build tests (#3)
1 parent 10bd726 commit 59761b5

File tree

4 files changed

+213
-3
lines changed

4 files changed

+213
-3
lines changed

.github/workflows/check_and_lint.yml

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,17 @@ jobs:
2121
- uses: subosito/flutter-action@44ac965b96f18d999802d4b807e3256d5a3f9fa1 # 2.16.0
2222
with:
2323
channel: "main"
24+
- name: Set up Java
25+
uses: actions/setup-java@99b8673ff64fbf99d8d325f52d9a5bdedb8483e9 #v4.2.1
26+
with:
27+
distribution: "temurin"
28+
java-version: 17
29+
- name: Install GTK
30+
if: (matrix.os == 'ubuntu-latest')
31+
run: sudo apt-get update && sudo apt-get install libgtk-3-dev
32+
- name: Install ninja-build
33+
if: (matrix.os == 'ubuntu-latest')
34+
run: sudo apt-get update && sudo apt-get install ninja-build
2435
- name: enable native assets
2536
run: flutter config --enable-native-assets
2637
- name: install melos
@@ -31,10 +42,12 @@ jobs:
3142
run: melos exec -c 1 dart format . --output=none --set-exit-if-changed
3243
- name: flutter analyze
3344
run: melos exec -c 1 flutter analyze
45+
- name: native doctor
46+
run: dart native_doctor/bin/native_doctor.dart --path example/flutter_package/example --yes
3447
- name: futter test
3548
run: melos exec -c 1 flutter test
3649
# Run Dart test directly for the package (not through flutter)
37-
- name: dart package Test
50+
- name: dart test
3851
run: dart --enable-experiment=native-assets test
3952
working-directory: example/dart_package
4053
- name: dart run

native_toolchain_rust/pubspec.lock

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -93,10 +93,10 @@ packages:
9393
dependency: transitive
9494
description:
9595
name: frontend_server_client
96-
sha256: "408e3ca148b31c20282ad6f37ebfa6f4bdc8fede5b74bc2f08d9d92b55db3612"
96+
sha256: f64a0333a82f30b0cca061bc3d143813a486dc086b574bfb233b7c1372427694
9797
url: "https://pub.dev"
9898
source: hosted
99-
version: "3.2.0"
99+
version: "4.0.0"
100100
glob:
101101
dependency: transitive
102102
description:

native_toolchain_rust/pubspec.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ name: native_toolchain_rust
22
description: Library to interact with rustup and cargo when building Dart and Flutter native assets written in Rust.
33
version: 0.1.0-dev.2
44
homepage: https://github.com/irondash/native_toolchain_rust.git
5+
publish_to: none
56

67
environment:
78
sdk: ">=3.4.0-190.0.dev <4.0.0"
Lines changed: 196 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,196 @@
1+
import 'dart:io';
2+
3+
import 'package:native_assets_cli/native_assets_cli.dart';
4+
import 'package:native_toolchain_rust_common/native_toolchain_rust_common.dart';
5+
import 'package:path/path.dart' as p;
6+
import 'package:test/test.dart';
7+
8+
void copyPathSync(String from, String to) {
9+
Directory(to).createSync(recursive: true);
10+
for (final file in Directory(from).listSync(recursive: false)) {
11+
if (file.uri.pathSegments.contains('.dart_tool') ||
12+
file.uri.pathSegments.contains('build')) {
13+
continue;
14+
}
15+
16+
final copyTo = p.join(to, p.relative(file.path, from: from));
17+
if (file is Directory) {
18+
copyPathSync(file.path, copyTo);
19+
} else if (file is File) {
20+
File(file.path).copySync(copyTo);
21+
} else if (file is Link) {
22+
Link(copyTo).createSync(file.targetSync(), recursive: true);
23+
}
24+
}
25+
}
26+
27+
Future<void> withFlutterExampleProject(
28+
Future<void> Function(Uri) testFn,
29+
) async {
30+
final tempDir = Directory.systemTemp.createTempSync('buildTest');
31+
try {
32+
final workspaceRoot = Directory.current.uri.resolve('../');
33+
34+
final exampleRoot = workspaceRoot.resolve('example/flutter_package');
35+
36+
copyPathSync(exampleRoot.toFilePath(), tempDir.path);
37+
38+
final pubspecOverrides = """
39+
dependency_overrides:
40+
flutter_package:
41+
path: ../
42+
native_toolchain_rust:
43+
path: ${workspaceRoot.resolve('native_toolchain_rust').toFilePath()}
44+
native_toolchain_rust_common:
45+
path: ${workspaceRoot.resolve('native_toolchain_rust_common').toFilePath()}
46+
rustup:
47+
path: ${workspaceRoot.resolve('rustup').toFilePath()}
48+
""";
49+
50+
File(tempDir.uri.resolve('example/pubspec_overrides.yaml').toFilePath())
51+
.writeAsStringSync(pubspecOverrides);
52+
53+
final exampleUri = tempDir.uri.resolve('example/');
54+
55+
await runCommand(
56+
'flutter',
57+
['clean'],
58+
workingDirectory: exampleUri.toFilePath(),
59+
);
60+
61+
await runCommand(
62+
'flutter',
63+
['pub', 'get'],
64+
workingDirectory: exampleUri.toFilePath(),
65+
);
66+
67+
await testFn(exampleUri);
68+
} finally {
69+
int attempt = 0;
70+
while (true) {
71+
try {
72+
await tempDir.delete(recursive: true);
73+
break;
74+
} catch (e) {
75+
if (attempt > 5) {
76+
rethrow;
77+
}
78+
attempt++;
79+
// Windows being windows.
80+
print('Failed to clean temp installer temp dir: $e');
81+
await Future.delayed(const Duration(seconds: 1));
82+
}
83+
}
84+
}
85+
}
86+
87+
void main() async {
88+
test(
89+
'macOS project',
90+
() async {
91+
await withFlutterExampleProject((uri) async {
92+
for (final config in ['Debug', 'Profile', 'Release']) {
93+
await runCommand(
94+
'flutter',
95+
['build', 'macos', '--${config.toLowerCase()}'],
96+
workingDirectory: uri.toFilePath(),
97+
);
98+
99+
// Check if the library is built
100+
final library = File.fromUri(uri.resolve(
101+
'build/macos/Build/Products/$config/example.app/Contents/Frameworks/flutter_ffi_plugin.framework/Versions/A/flutter_ffi_plugin'));
102+
expect(library.existsSync(), isTrue);
103+
}
104+
});
105+
},
106+
timeout: const Timeout(Duration(minutes: 10)),
107+
skip: !Platform.isMacOS,
108+
);
109+
test(
110+
'iOS project',
111+
() async {
112+
await withFlutterExampleProject((uri) async {
113+
for (final config in ['Debug', 'Profile', 'Release']) {
114+
await runCommand(
115+
'flutter',
116+
['build', 'ios', '--${config.toLowerCase()}', '--no-codesign'],
117+
workingDirectory: uri.toFilePath(),
118+
);
119+
120+
// Check if the library is built
121+
final library = File.fromUri(uri.resolve(
122+
'build/ios/$config-iphoneos/Runner.app/Frameworks/flutter_ffi_plugin.framework/flutter_ffi_plugin',
123+
));
124+
expect(library.existsSync(), isTrue);
125+
}
126+
});
127+
},
128+
timeout: const Timeout(Duration(minutes: 10)),
129+
skip: !Platform.isMacOS,
130+
);
131+
test(
132+
'windows project',
133+
() async {
134+
await withFlutterExampleProject((uri) async {
135+
for (final config in ['Debug', 'Profile', 'Release']) {
136+
await runCommand(
137+
'flutter',
138+
['build', 'windows', '--${config.toLowerCase()}'],
139+
workingDirectory: uri.toFilePath(),
140+
);
141+
142+
// Check if the library is built
143+
final library = File.fromUri(uri.resolve(
144+
'build/windows/${Architecture.current}/runner/$config/flutter_ffi_plugin.dll',
145+
));
146+
expect(library.existsSync(), isTrue);
147+
}
148+
});
149+
},
150+
timeout: const Timeout(Duration(minutes: 10)),
151+
skip: !Platform.isWindows,
152+
);
153+
test(
154+
'linux project',
155+
() async {
156+
await withFlutterExampleProject((uri) async {
157+
for (final config in ['debug', 'profile', 'release']) {
158+
await runCommand(
159+
'flutter',
160+
['build', 'linux', '--$config'],
161+
workingDirectory: uri.toFilePath(),
162+
);
163+
164+
// Check if the library is built
165+
final library = File.fromUri(uri.resolve(
166+
'build/linux/${Architecture.current}/$config/bundle/lib/libflutter_ffi_plugin.so',
167+
));
168+
expect(library.existsSync(), isTrue);
169+
}
170+
});
171+
},
172+
timeout: const Timeout(Duration(minutes: 10)),
173+
skip: !Platform.isLinux,
174+
);
175+
test(
176+
'android project',
177+
() async {
178+
await withFlutterExampleProject((uri) async {
179+
for (final config in ['debug', 'profile', 'release']) {
180+
await runCommand(
181+
'flutter',
182+
['build', 'apk', '--$config'],
183+
workingDirectory: uri.toFilePath(),
184+
);
185+
186+
// Check if the library is built
187+
final library = File.fromUri(uri.resolve(
188+
'build/app/intermediates/merged_jni_libs/$config/out/arm64-v8a/libflutter_ffi_plugin.so',
189+
));
190+
expect(library.existsSync(), isTrue);
191+
}
192+
});
193+
},
194+
timeout: const Timeout(Duration(minutes: 10)),
195+
);
196+
}

0 commit comments

Comments
 (0)