Skip to content

Commit

Permalink
[Flutter] Setup script and modified workflow (#86)
Browse files Browse the repository at this point in the history
* Modified workflow to include ios release and created setup script for post install with flutter

* Added script for manual generation and updated flutter_rust_bridge
  • Loading branch information
quetool authored Dec 11, 2024
1 parent 58f2d00 commit fb2ba7c
Show file tree
Hide file tree
Showing 11 changed files with 309 additions and 35 deletions.
135 changes: 111 additions & 24 deletions .github/workflows/release-dart.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand All @@ -38,7 +58,7 @@ jobs:
java-version: '17'
architecture: x86_64
cache: 'gradle'

# Cache Gradle
- name: Cache Gradle
uses: actions/cache@v3
Expand All @@ -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: |
Expand All @@ -65,83 +85,150 @@ 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
working-directory: crates/yttrium_dart
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
env:
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
103 changes: 103 additions & 0 deletions crates/yttrium_dart/bin/setup.dart
Original file line number Diff line number Diff line change
@@ -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<Directory?> _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<dynamic>?;

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;
}
22 changes: 22 additions & 0 deletions crates/yttrium_dart/generate_android_lib.sh
Original file line number Diff line number Diff line change
@@ -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
4 changes: 4 additions & 0 deletions crates/yttrium_dart/generate_bindings.sh
Original file line number Diff line number Diff line change
@@ -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
Loading

0 comments on commit fb2ba7c

Please sign in to comment.