diff --git a/.github/workflows/release-dart.yml b/.github/workflows/release-dart.yml index 748a6a0f..ce1d7401 100644 --- a/.github/workflows/release-dart.yml +++ b/.github/workflows/release-dart.yml @@ -16,11 +16,22 @@ permissions: contents: write jobs: - build-android-artifacts: + install-dependencies: runs-on: macos-latest-xlarge - + steps: - - uses: actions/checkout@v3 + # Checkout repository + - name: Checkout repository + uses: actions/checkout@v3 + + # Cache Flutter dependencies + - name: Cache Flutter dependencies + uses: actions/cache@v3 + with: + path: ~/.pub-cache + key: ${{ runner.os }}-flutter-${{ hashFiles('**/pubspec.yaml') }} + restore-keys: | + ${{ runner.os }}-flutter- # Install Rust toolchain - name: Install Rust toolchain @@ -30,6 +41,15 @@ jobs: override: true components: rust-src + # Cache Cargo dependencies + - name: Cache Cargo dependencies + uses: actions/cache@v3 + with: + path: ~/.cargo + key: ${{ runner.os }}-cargo-${{ hashFiles('Cargo.toml') }} + restore-keys: | + ${{ runner.os }}-cargo- + # Install Java 17 - name: Install Java 17 uses: actions/setup-java@v3 @@ -38,7 +58,7 @@ jobs: java-version: '17' architecture: x86_64 cache: 'gradle' - + # Cache Gradle - name: Cache Gradle uses: actions/cache@v3 @@ -49,7 +69,7 @@ jobs: key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }} restore-keys: | ${{ runner.os }}-gradle- - + # Install cargo-ndk - name: Install cargo-ndk run: | @@ -65,14 +85,14 @@ jobs: - name: Install flutter_rust_bridge_codegen run: | cargo install flutter_rust_bridge_codegen - + # Get package dependencies - name: Get package dependencies shell: bash working-directory: crates/yttrium_dart run: | flutter pub get - + # Generate Dart Bindings - name: Generate Dart Bindings shell: bash @@ -80,48 +100,103 @@ jobs: run: | flutter_rust_bridge_codegen generate --config-file flutter_rust_bridge.yaml - # Build Native libraries - - name: Build Rust library + build-android-artifacts: + needs: install-dependencies + runs-on: macos-latest-xlarge + + steps: + # Checkout repository + - name: Checkout repository + uses: actions/checkout@v3 + + # Build Native Android libraries + - name: Build Native Android libraries shell: bash working-directory: crates/yttrium_dart/rust run: | rustup target add armv7-linux-androideabi aarch64-linux-android cargo ndk -t armeabi-v7a -t arm64-v8a build --release - - # Prepare artifacts - - name: Prepare artifacts + + # Prepare Android artifacts + - name: Prepare Android artifacts shell: bash - run: | + run: | mkdir -p jniLibs/arm64-v8a mkdir -p jniLibs/armeabi-v7a cp target/aarch64-linux-android/release/libyttrium_dart.so jniLibs/arm64-v8a/libyttrium_dart.so cp target/armv7-linux-androideabi/release/libyttrium_dart.so jniLibs/armeabi-v7a/libyttrium_dart.so - - # Upload artifacts - - name: Upload artifacts + + # Upload Android artifacts + - name: Upload Android artifacts uses: actions/upload-artifact@v3 with: name: artifacts path: jniLibs/ + build-ios-artifacts: + needs: install-dependencies + runs-on: macos-latest-xlarge + + steps: + # Checkout repository + - name: Checkout repository + uses: actions/checkout@v3 + + # Build Native iOS libraries + - name: Build Native iOS libraries + shell: bash + working-directory: crates/yttrium_dart/rust + run: | + rustup target add aarch64-apple-ios x86_64-apple-ios + cargo build --manifest-path Cargo.toml --target aarch64-apple-ios --release + cargo build --manifest-path Cargo.toml --target x86_64-apple-ios --release + + # Prepare iOS artifacts + - name: Prepare iOS artifacts + shell: bash + run: | + mkdir -p universal + lipo -create target/aarch64-apple-ios/release/libyttrium_dart.dylib target/x86_64-apple-ios/release/libyttrium_dart.dylib -output universal/libyttrium_dart_universal.dylib + install_name_tool -id @rpath/libyttrium_dart_universal.dylib universal/libyttrium_dart_universal.dylib + codesign --force --sign - universal/libyttrium_dart_universal.dylib + + # Upload iOS artifacts + - name: Upload iOS artifacts + uses: actions/upload-artifact@v3 + with: + name: artifacts + path: universal/ + create-github-release: - needs: build-android-artifacts + needs: [build-android-artifacts, build-ios-artifacts] runs-on: macos-latest-xlarge steps: + # Checkout repository - name: Checkout repository uses: actions/checkout@v3 - - name: Download artifacts + # Download Android artifacts + - name: Download Android artifacts uses: actions/download-artifact@v3 with: name: artifacts path: jniLibs/ + # Download iOS artifacts + - name: Download iOS artifacts + uses: actions/download-artifact@v3 + with: + name: artifacts + path: universal/ + + # Create artifacts zip - name: Create artifacts zip run: | - zip -r dart-artifacts.zip jniLibs/ + zip -r android-artifacts.zip jniLibs/ + zip -r ios-artifacts.zip universal/ + # Create GitHub Release - name: Create Release id: create_release uses: actions/create-release@v1 @@ -129,19 +204,31 @@ jobs: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} with: tag_name: ${{ env.VERSION }} - release_name: YttriumDart ${{ env.VERSION }} + release_name: Yttrium ${{ env.VERSION }} draft: false prerelease: false - - name: Upload Release Assets + # Upload Android Release Assets + - name: Upload Android Release Assets + uses: actions/upload-release-asset@v1 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + upload_url: ${{ steps.create_release.outputs.upload_url }} + asset_path: android-artifacts.zip + asset_name: android-artifacts.zip + asset_content_type: application/zip + + # Upload iOS Release Assets + - name: Upload iOS Release Assets uses: actions/upload-release-asset@v1 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} with: upload_url: ${{ steps.create_release.outputs.upload_url }} - asset_path: dart-artifacts.zip - asset_name: dart-artifacts.zip + asset_path: ios-artifacts.zip + asset_name: ios-artifacts.zip asset_content_type: application/zip # Launch locally -# act -j build-android-artifacts --container-architecture linux/amd64 -P macos-latest-xlarge=-self-hosted --secret-file .github/workflows/.env.secret -W .github/workflows/release-dart.yml +# act --container-architecture linux/amd64 -P macos-latest-xlarge=-self-hosted --secret-file .github/workflows/.env.secret -W .github/workflows/release-dart.yml workflow_dispatch --input version=0.4.2 diff --git a/crates/yttrium_dart/bin/setup.dart b/crates/yttrium_dart/bin/setup.dart new file mode 100644 index 00000000..027b85e8 --- /dev/null +++ b/crates/yttrium_dart/bin/setup.dart @@ -0,0 +1,103 @@ +// ignore_for_file: avoid_print + +import 'dart:convert'; +import 'dart:io'; +import 'dart:isolate'; + +// flutter pub run yttrium_dart:generate + +void main() async { + print('Running Yttrium setup script...'); + // Locate the package directory + final packagePath = await _getPackageRoot(); + if (packagePath == null) { + print('Error: Could not locate the package directory.'); + exit(1); + } + + // https://github.com/reown-com/yttrium/releases/download/0.0.1/dart-artifacts.zip + const rootPackage = 'https://github.com/reown-com/yttrium'; + const version = '0.0.2'; // TODO dynamically + final url = '$rootPackage/releases/download/$version/dart-artifacts.zip'; + // + final androidTargetDir = '${packagePath.path}android/src/main/'; + final zipFilePath = '${Directory.systemTemp.path}/dart-artifacts.zip'; + + try { + // Step 1: Download the ZIP file + print('Downloading ZIP file...'); + final request = await HttpClient().getUrl(Uri.parse(url)); + final response = await request.close(); + + if (response.statusCode == 200) { + await response.pipe(File(zipFilePath).openWrite()); + print('Downloaded ZIP file to $zipFilePath'); + } else { + throw Exception( + 'Failed to download file. Status code: ${response.statusCode}', + ); + } + + // Step 2: Unzip the file using system command + print('Unzipping the file...'); + final result = await Process.run( + 'unzip', + ['-o', zipFilePath, '-d', androidTargetDir], + ); + // jniLibs/arm64-v8a/libyttrium_dart.so + + if (result.exitCode == 0) { + print('Unzipped contents to $androidTargetDir'); + } else { + print('Failed to unzip file.'); + print('Error: ${result.stderr}'); + } + } catch (e) { + print('An error occurred: $e'); + } finally { + // Cleanup temporary file + File(zipFilePath).deleteSync(); + print('Cleaned up temporary files.'); + } +} + +Future _getPackageRoot() async { + try { + // Get the package configuration file + // Locate the package configuration file + final packageConfigUri = await Isolate.packageConfig; + if (packageConfigUri == null) { + print('Error: Could not locate the package configuration file.'); + exit(1); + } + final packageConfigFile = File.fromUri(packageConfigUri); + + // Read and parse the package_config.json file + final jsonContent = jsonDecode(await packageConfigFile.readAsString()); + final packages = jsonContent['packages'] as List?; + + if ((packages ?? []).isNotEmpty) { + for (final package in packages!) { + if (package['name'] == 'yttrium_dart') { + final rootUri = package['rootUri'] as String?; + if (rootUri != null) { + // Resolve absolute path for relative URIs + final resolvedUri = Uri.parse(rootUri); + if (resolvedUri.isAbsolute) { + return Directory.fromUri(resolvedUri); + } else { + // Resolve relative path based on the package_config.json location + final packageConfigDir = packageConfigFile.parent; + return Directory.fromUri( + packageConfigDir.uri.resolveUri(resolvedUri), + ); + } + } + } + } + } + } catch (e) { + print('Error locating package root: $e'); + } + return null; +} diff --git a/crates/yttrium_dart/generate_android_lib.sh b/crates/yttrium_dart/generate_android_lib.sh new file mode 100644 index 00000000..c97a79a9 --- /dev/null +++ b/crates/yttrium_dart/generate_android_lib.sh @@ -0,0 +1,22 @@ +#!/bin/bash +# run this script from inside /crates/yttrium_dart/ + +cd rust + +rustup target add armv7-linux-androideabi aarch64-linux-android x86_64-linux-android i686-linux-android +cargo ndk -t armeabi-v7a -t arm64-v8a -t x86_64 -t x86 build --release + +cd .. #/yttrium_dart + +mkdir -p android/src/main/jniLibs/arm64-v8a +mkdir -p android/src/main/jniLibs/armeabi-v7a +# mkdir -p android/src/main/jniLibs/x86 +# mkdir -p android/src/main/jniLibs/x86_64 + +cd .. #/crates +cd .. #/yttrium + +cp target/aarch64-linux-android/release/libyttrium_dart.so crates/yttrium_dart/android/src/main/jniLibs/arm64-v8a/libyttrium_dart.so +cp target/armv7-linux-androideabi/release/libyttrium_dart.so crates/yttrium_dart/android/src/main/jniLibs/armeabi-v7a/libyttrium_dart.so +# cp target/i686-linux-android/release/libyttrium_dart.so crates/yttrium_dart/android/src/main/jniLibs/x86/libyttrium_dart.so +# cp target/x86_64-linux-android/release/libyttrium_dart.so crates/yttrium_dart/android/src/main/jniLibs/x86_64/libyttrium_dart.so diff --git a/crates/yttrium_dart/generate_bindings.sh b/crates/yttrium_dart/generate_bindings.sh new file mode 100644 index 00000000..3288218c --- /dev/null +++ b/crates/yttrium_dart/generate_bindings.sh @@ -0,0 +1,4 @@ +#!/bin/bash +# run this script from inside /crates/yttrium_dart/ + +flutter_rust_bridge_codegen generate --config-file flutter_rust_bridge.yaml diff --git a/crates/yttrium_dart/generate_ios_lib.sh b/crates/yttrium_dart/generate_ios_lib.sh new file mode 100644 index 00000000..bc3f6052 --- /dev/null +++ b/crates/yttrium_dart/generate_ios_lib.sh @@ -0,0 +1,60 @@ +#!/bin/bash +# run this script from inside /crates/yttrium_dart/ + +DEFAULT_TARGET="aarch64-apple-ios" + +if [ $# -eq 0 ]; +then + echo "✅ $0: No arguments passed, building for target: $DEFAULT_TARGET" + TARGET=$DEFAULT_TARGET + # exit 1 +elif [ $# -gt 1 ]; +then + echo "❌ $0: Too many arguments, only one accepted. Arguments passed: $@" + exit 1 +else + if [ $1 != "-sim" ]; + then + echo "❌ $0: Wrong argument $1 passed. Only valid argument is '-sim'" + exit 1 + else + TARGET="aarch64-apple-ios$1" + echo "✅ $0: Building for targe: $TARGET" + fi +fi + +cd rust + +echo "✅ $0: building for targest: x86_64-apple-ios $TARGET." + +rustup target add x86_64-apple-ios $TARGET + +cargo build --manifest-path Cargo.toml --target x86_64-apple-ios --release +cargo build --manifest-path Cargo.toml --target $TARGET --release + +cd .. #/yttrium_dart +cd .. #/crates +cd .. #/yttrium + +mkdir -p target/universal/ios/release + +lipo -create target/$TARGET/release/libyttrium_dart.dylib target/x86_64-apple-ios/release/libyttrium_dart.dylib -output target/universal/ios/release/libyttrium_dart_universal.dylib + +lipo -info target/universal/ios/release/libyttrium_dart_universal.dylib + +cp target/universal/ios/release/libyttrium_dart_universal.dylib crates/yttrium_dart/ios/libyttrium_dart_universal.dylib + +# otool -L crates/yttrium_dart/ios/libyttrium_dart_universal.dylib + +install_name_tool -id @rpath/libyttrium_dart_universal.dylib crates/yttrium_dart/ios/libyttrium_dart_universal.dylib + +codesign --force --sign - crates/yttrium_dart/ios/libyttrium_dart_universal.dylib + +# otool -L crates/yttrium_dart/ios/libyttrium_dart_universal.dylib + +cd crates/yttrium_dart/example +flutter clean +flutter pub get + +cd ios +pod deintegrate && rm Podfile.lock && pod cache clean -all && pod install \ No newline at end of file diff --git a/crates/yttrium_dart/lib/generated/frb_generated.dart b/crates/yttrium_dart/lib/generated/frb_generated.dart index 64e88a78..4437b9a5 100644 --- a/crates/yttrium_dart/lib/generated/frb_generated.dart +++ b/crates/yttrium_dart/lib/generated/frb_generated.dart @@ -1,5 +1,5 @@ // This file is automatically generated, so please do not edit it. -// @generated by `flutter_rust_bridge`@ 2.6.0. +// @generated by `flutter_rust_bridge`@ 2.7.0. // ignore_for_file: unused_import, unused_element, unnecessary_import, duplicate_ignore, invalid_use_of_internal_member, annotate_overrides, non_constant_identifier_names, curly_braces_in_flow_control_structures, prefer_const_literals_to_create_immutables, unused_field @@ -64,7 +64,7 @@ class YttriumDart extends BaseEntrypoint '2.6.0'; + String get codegenVersion => '2.7.0'; @override int get rustContentHash => 1789961500; @@ -2970,8 +2970,6 @@ class YttriumDartApiImpl extends YttriumDartApiImplPlatform case Error_General(field0: final field0): sse_encode_i_32(0, serializer); sse_encode_String(field0, serializer); - default: - throw UnimplementedError(''); } } diff --git a/crates/yttrium_dart/lib/generated/frb_generated.io.dart b/crates/yttrium_dart/lib/generated/frb_generated.io.dart index 22261866..13963b81 100644 --- a/crates/yttrium_dart/lib/generated/frb_generated.io.dart +++ b/crates/yttrium_dart/lib/generated/frb_generated.io.dart @@ -1,5 +1,5 @@ // This file is automatically generated, so please do not edit it. -// @generated by `flutter_rust_bridge`@ 2.6.0. +// @generated by `flutter_rust_bridge`@ 2.7.0. // ignore_for_file: unused_import, unused_element, unnecessary_import, duplicate_ignore, invalid_use_of_internal_member, annotate_overrides, non_constant_identifier_names, curly_braces_in_flow_control_structures, prefer_const_literals_to_create_immutables, unused_field diff --git a/crates/yttrium_dart/lib/generated/lib.dart b/crates/yttrium_dart/lib/generated/lib.dart index 41c579d4..038b8096 100644 --- a/crates/yttrium_dart/lib/generated/lib.dart +++ b/crates/yttrium_dart/lib/generated/lib.dart @@ -1,5 +1,5 @@ // This file is automatically generated, so please do not edit it. -// @generated by `flutter_rust_bridge`@ 2.6.0. +// @generated by `flutter_rust_bridge`@ 2.7.0. // ignore_for_file: invalid_use_of_internal_member, unused_import, unnecessary_import diff --git a/crates/yttrium_dart/pubspec.yaml b/crates/yttrium_dart/pubspec.yaml index 4dd95cbc..13a19445 100644 --- a/crates/yttrium_dart/pubspec.yaml +++ b/crates/yttrium_dart/pubspec.yaml @@ -11,7 +11,7 @@ environment: dependencies: flutter: sdk: flutter - flutter_rust_bridge: ^2.6.0 + flutter_rust_bridge: ^2.7.0 flutter_web_plugins: sdk: flutter freezed_annotation: ^2.4.4 diff --git a/crates/yttrium_dart/rust/Cargo.toml b/crates/yttrium_dart/rust/Cargo.toml index c6c73fd8..05bc86ae 100644 --- a/crates/yttrium_dart/rust/Cargo.toml +++ b/crates/yttrium_dart/rust/Cargo.toml @@ -14,7 +14,7 @@ flutter_rust_bridge_codegen = "2.6.0" # uniffi_build = { git = "https://github.com/mozilla/uniffi-rs", rev = "e796e00ad150f8b14b61a859a2e8c6497b35074e" } [dependencies] -flutter_rust_bridge = "=2.6.0" +flutter_rust_bridge = "=2.7.0" yttrium = { git = "https://github.com/reown-com/yttrium.git", package = "yttrium"} # uniffi = { git = "https://github.com/mozilla/uniffi-rs", rev = "e796e00ad150f8b14b61a859a2e8c6497b35074e" } openssl = { version = "0.10", features = ["vendored"] } diff --git a/crates/yttrium_dart/rust/src/frb_generated.rs b/crates/yttrium_dart/rust/src/frb_generated.rs index 31b7273d..e87415c0 100644 --- a/crates/yttrium_dart/rust/src/frb_generated.rs +++ b/crates/yttrium_dart/rust/src/frb_generated.rs @@ -1,5 +1,5 @@ // This file is automatically generated, so please do not edit it. -// @generated by `flutter_rust_bridge`@ 2.6.0. +// @generated by `flutter_rust_bridge`@ 2.7.0. #![allow( non_camel_case_types, @@ -41,7 +41,7 @@ flutter_rust_bridge::frb_generated_boilerplate!( default_rust_opaque = RustOpaqueMoi, default_rust_auto_opaque = RustAutoOpaqueMoi, ); -pub(crate) const FLUTTER_RUST_BRIDGE_CODEGEN_VERSION: &str = "2.6.0"; +pub(crate) const FLUTTER_RUST_BRIDGE_CODEGEN_VERSION: &str = "2.7.0"; pub(crate) const FLUTTER_RUST_BRIDGE_CODEGEN_CONTENT_HASH: i32 = 1789961500; // Section: executor @@ -2832,7 +2832,7 @@ impl SseEncode for i32 { #[cfg(not(target_family = "wasm"))] mod io { // This file is automatically generated, so please do not edit it. - // @generated by `flutter_rust_bridge`@ 2.6.0. + // @generated by `flutter_rust_bridge`@ 2.7.0. // Section: imports