Skip to content

Commit a4da91f

Browse files
rasendubileoromanovskyfelipecsl
authored
FF-3753 feat(dart): Dart SDK (#197)
* feat(dart): setup minimal example Copied flutter_rust_bridge minimal example[1] and beat it into working: - vendored simple_build.dart to remove dependency on an unpublished git-only package - updated packages because I couldn't get dart test to work otherwise - stripped flutter_rust_bridge internal options [1]: https://github.com/fzyzcjy/flutter_rust_bridge/tree/05247dd90a7fcb2512c5ede13cf00271b0eb548e/frb_example/dart_minimal * chore: add logs for stopping background runtime Dropping `BackgroundRuntime` cancels all tracked tasks. This may (and have) lead to hard to debug issues when configuration poller just stops working and `.wait_for_configuration()` unhelpfully returns `PollerThreadPanicked`. (I am a little embarrassed to say how long this simple issue took me to debug when it was paired with running in Dart environment.) * feat(dart): PoC implementation of SDK * feat(dart): boolean assignment, bandits, logging * feat(dart): rest of assignment methods * test(dart): sdk-test-data tests * feat(dart): enable wasm_js for getrandom on wasm platform * feat(core,dart): abstract over async runtimes to support Dart web * chore(dart): upgrade flutter_rust_bridge * chore(dart): integrate with changeset * fix: add .gitkeep for dart-sdk/lib/src/rust directory * fix(dart): use poll interval/jitter initialization parameters * chore(dart): add build&test CI setup * chore(dart): add hook/build.dart It looks like newer versions of dart look at hook/build.dart instead of build.dart in the root and this is the longer-term plan, too. * chore(dart): update lockfile * chore(dart): bump eppo_core version * chore(dart): pin to 3.6 (for testing) * chore(dart): properly install flutter_rust_bridge_codegen * chore(dart): add missing working-directory * chore(dart): install toolchain for wasm * chore(dart): fix lint errors * chore(dart): downgrade version to 0.1.0, prepare to publish * chore(dart): bump minimal sdk boundary to 3.6.0 This is required to use hook/build.dart. * chore(dart): lower meta boundary * fix(core): fix configuration poller running in wasm target * fix(dart): properly default base url * chore(dart): rename eppo_dart to eppo_sdk This is used as the name of js/wasm generated files. * fix(dart): enable logging in web * chore(dart): upload dart web files in ci * chore(dart): CI to publish dart sdk * docs(dart): add dart tag format to documentation * chore(dart): add license file * chore(dart): add missing id-token permissions for write * chore(dart): refresh pub.dev auth token? * chore(dart): release on tag, not release event 🤷 * chore(dart): silence publish dry-run error code * chore(android): Setup dart-sdk for android target (#220) * add plugin info * remove plugin details * vendor libs * remove corepack changes * add rust api files * add more generated code * add another missing file * catch reqwest panic * replace openssl with rustls-tls * update deps * remove native-tls and openssl * remove generated files * another file to remove * remove openssl-sys * newlines * revert this * keep vendored feature * try to fix python CI * set vars for linux gnu * install deps * another try * build with `cross` instead * fix cross commang * fix target platform triple * another try * revert action changes * another try - see PyO3/maturin-action#222 * once again * anotehr place * chore: add changeset for openssl->rustls change * chore(dart): build release artifacts for web This reduces wasm file from 12M down to 2M. * chore(ci): `dart-sdk` rust cross compile for Android target (#222) * chore(ci): dart-sdk rust cross compile for android target * eppo_dart instead of eppo_sdk * revert this * build patches * revert this * update file path for testing * another try * change working dir * CI tweaks * better logs * more fix attempts * aaaand another try * 10th time is the charm * check for path instead * check CI env var * passthrough env var * use the fork of maturin-action * yup * bump action version * fix step * fix ste * update action version, another shot at android fix * fix pytest * move file * add file * set rust root to current dir * fix cross build config * manually run codegen * install dart * reorder steps * another reorder * another try * go back to main maturin-action * remove custom build scripts * add android x86 * remove images cross config * go back to maturin-action v1 --------- Co-authored-by: Leo Romanovsky <[email protected]> Co-authored-by: Felipe Lima <[email protected]>
1 parent c3ac535 commit a4da91f

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

58 files changed

+7638
-86
lines changed

.changeset/giant-eyes-tie.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
---
2+
"eppo_core": major
3+
---
4+
5+
Make async runtime abstract.
6+
7+
This introduces an `AsyncRuntime` trait that allows us to abstract over different async runtimes. This is required to support Dart SDK that doesn't use tokio runtime in web build.

.changeset/khaki-hairs-leave.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
---
2+
"python-sdk": minor
3+
"eppo_core": minor
4+
"ruby-sdk": minor
5+
"rust-sdk": minor
6+
---
7+
8+
Change TLS implementation from openssl to rustls.

.changeset/ten-bananas-check.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
---
2+
"eppo_core": patch
3+
---
4+
5+
Fix configuration poller running in wasm target.
6+
7+
It was failing because time is not implemented for wasm platform. We use wasmtimer for that now.

.github/workflows/android.yml

Lines changed: 134 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,134 @@
1+
name: Dart SDK Android Build
2+
3+
on:
4+
push:
5+
branches:
6+
- main
7+
tags:
8+
- "dart-sdk@*"
9+
paths:
10+
- "dart-sdk/rust/**"
11+
- "eppo_core/**"
12+
- ".github/workflows/android.yml"
13+
pull_request:
14+
paths:
15+
- "dart-sdk/rust/**"
16+
- "eppo_core/**"
17+
- ".github/workflows/android.yml"
18+
workflow_dispatch:
19+
20+
permissions:
21+
contents: read
22+
23+
env:
24+
CI: true
25+
26+
jobs:
27+
build-android:
28+
name: Build Android (${{ matrix.target }})
29+
runs-on: ubuntu-latest
30+
strategy:
31+
fail-fast: false
32+
matrix:
33+
target:
34+
[aarch64-linux-android, x86_64-linux-android, armv7-linux-androideabi]
35+
include:
36+
- target: aarch64-linux-android
37+
android_abi: arm64-v8a
38+
- target: x86_64-linux-android
39+
android_abi: x86_64
40+
- target: armv7-linux-androideabi
41+
android_abi: armeabi-v7a
42+
- target: i686-linux-android
43+
android_abi: x86
44+
45+
steps:
46+
- uses: actions/checkout@v4
47+
with:
48+
submodules: true
49+
50+
- uses: dart-lang/setup-dart@v1
51+
with:
52+
sdk: 3.6
53+
54+
- name: Setup Rust
55+
uses: dtolnay/rust-toolchain@stable
56+
57+
- name: Install cross
58+
run: cargo install cross --git https://github.com/cross-rs/cross
59+
60+
- name: Cache Rust dependencies
61+
uses: Swatinem/rust-cache@v2
62+
with:
63+
workspaces: dart-sdk/rust -> target
64+
key: ${{ matrix.target }}
65+
66+
- name: Override eppo_core for testing
67+
shell: bash
68+
run: |
69+
mkdir -p "${CARGO_HOME:-$HOME/.cargo}"
70+
echo "[patch.crates-io.eppo_core]" >> "${CARGO_HOME:-$HOME/.cargo}/config.toml"
71+
echo "path = '${{ github.workspace }}/eppo_core'" >> "${CARGO_HOME:-$HOME/.cargo}/config.toml"
72+
73+
- name: Setup Docker
74+
uses: docker/setup-buildx-action@v3
75+
76+
- name: Create logs directory
77+
run: mkdir -p dart-sdk/rust/logs
78+
79+
- name: Install flutter_rust_bridge_codegen
80+
run: cargo install flutter_rust_bridge_codegen@=2.8.0 cargo-expand
81+
82+
- name: Run flutter codegen
83+
working-directory: dart-sdk
84+
run: flutter_rust_bridge_codegen generate --config-file flutter_rust_bridge.yaml
85+
86+
- name: Build for ${{ matrix.target }}
87+
env:
88+
RING_PREGENERATE_ASM: "1"
89+
CARGO_BUILD_TARGET: ${{ matrix.target }}
90+
working-directory: dart-sdk/rust
91+
run: cross build --release --target ${{ matrix.target }} -p eppo_sdk
92+
93+
- name: Create output directory
94+
run: mkdir -p android-libs/${{ matrix.android_abi }}
95+
96+
- name: Copy library to output directory
97+
run: |
98+
cp dart-sdk/rust/target/${{ matrix.target }}/release/libeppo_sdk.so android-libs/${{ matrix.android_abi }}/
99+
100+
- name: Upload Android libraries
101+
uses: actions/upload-artifact@v4
102+
with:
103+
name: android-libs-${{ matrix.android_abi }}
104+
path: android-libs/${{ matrix.android_abi }}
105+
106+
collect-artifacts:
107+
name: Collect Android Artifacts
108+
runs-on: ubuntu-latest
109+
needs: build-android
110+
steps:
111+
- uses: actions/checkout@v4
112+
with:
113+
submodules: true
114+
115+
- name: Download all artifacts
116+
uses: actions/download-artifact@v4
117+
with:
118+
path: android-libs
119+
pattern: android-libs-*
120+
merge-multiple: true
121+
122+
- name: Display structure of downloaded files
123+
run: ls -R android-libs
124+
125+
- name: Create jniLibs directory structure
126+
run: |
127+
mkdir -p dart-sdk/android/src/main/jniLibs
128+
cp -r android-libs/* dart-sdk/android/src/main/jniLibs/
129+
130+
- name: Upload combined artifacts
131+
uses: actions/upload-artifact@v4
132+
with:
133+
name: android-jniLibs
134+
path: dart-sdk/android/src/main/jniLibs

.github/workflows/dart.yml

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
name: Dart SDK
2+
3+
on:
4+
push:
5+
branches:
6+
- main
7+
tags:
8+
- "dart-sdk-*"
9+
paths:
10+
- "dart-sdk/**"
11+
- "eppo_core/**"
12+
- "sdk-test-data"
13+
- "mock-server/**"
14+
- "package-lock.json"
15+
- "package.json"
16+
pull_request:
17+
paths:
18+
- "dart-sdk/**"
19+
- "eppo_core/**"
20+
- "sdk-test-data"
21+
- "mock-server/**"
22+
- "package-lock.json"
23+
- "package.json"
24+
workflow_dispatch:
25+
26+
jobs:
27+
dart:
28+
name: Dart SDK
29+
runs-on: ubuntu-latest
30+
permissions:
31+
id-token: write # Required for authentication using OIDC
32+
33+
steps:
34+
- uses: actions/checkout@v4
35+
with:
36+
submodules: true
37+
38+
- uses: dart-lang/setup-dart@v1
39+
with:
40+
sdk: 3.6
41+
42+
- run: rustup update stable && rustup default stable
43+
- run: npm ci
44+
45+
- name: Override eppo_core for testing
46+
run: |
47+
mkdir -p "${CARGO_HOME:-$HOME/.cargo}"
48+
echo "[patch.crates-io.eppo_core]" >> "${CARGO_HOME:-$HOME/.cargo}/config.toml"
49+
echo "path = '$PWD/eppo_core'" >> "${CARGO_HOME:-$HOME/.cargo}/config.toml"
50+
51+
- name: Install dependencies
52+
run: cargo install flutter_rust_bridge_codegen@=2.8.0 wasm-pack wasm-bindgen-cli cargo-expand
53+
54+
- name: Run flutter codegen
55+
working-directory: dart-sdk
56+
run: flutter_rust_bridge_codegen generate --config-file flutter_rust_bridge.yaml
57+
58+
- run: npm run with-server test:dart
59+
60+
- name: Install toolchain for wasm build
61+
run: rustup toolchain install nightly -c rust-src
62+
63+
- name: Build web
64+
run: flutter_rust_bridge_codegen build-web --release --wasm-pack-rustflags '--cfg getrandom_backend="wasm_js" -C target-feature=+atomics,+bulk-memory,+mutable-globals'
65+
working-directory: dart-sdk
66+
67+
- uses: actions/upload-artifact@v4
68+
with:
69+
name: dart-sdk-web-files
70+
path: |
71+
dart-sdk/web/pkg/eppo_sdk.js
72+
dart-sdk/web/pkg/eppo_sdk_bg.wasm
73+
74+
- name: Publish - dry run
75+
if: "!startsWith(github.ref, 'refs/tags/dart-sdk-')"
76+
run: dart pub publish --dry-run || true
77+
working-directory: dart-sdk
78+
79+
- name: Refresh dart auth token
80+
if: "startsWith(github.ref, 'refs/tags/dart-sdk-')"
81+
uses: dart-lang/setup-dart@v1
82+
with:
83+
sdk: 3.6
84+
85+
- name: Publish
86+
if: "startsWith(github.ref, 'refs/tags/dart-sdk-')"
87+
run: dart pub publish --force
88+
working-directory: dart-sdk

.github/workflows/python.yml

Lines changed: 19 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -43,16 +43,23 @@ jobs:
4343
platform:
4444
- runner: ubuntu-latest
4545
target: x86_64
46+
manylinux: auto
4647
- runner: ubuntu-latest
47-
target: x86
48+
target: i686-unknown-linux-gnu
49+
manylinux: auto
4850
- runner: ubuntu-latest
4951
target: aarch64
52+
# https://github.com/PyO3/maturin-action/issues/222
53+
manylinux: "2_28"
5054
- runner: ubuntu-latest
5155
target: armv7
56+
manylinux: auto
5257
- runner: ubuntu-latest
5358
target: s390x
59+
manylinux: auto
5460
- runner: ubuntu-latest
5561
target: ppc64le
62+
manylinux: auto
5663
steps:
5764
- uses: actions/checkout@v4
5865
with:
@@ -63,25 +70,25 @@ jobs:
6370

6471
- name: Build wheels
6572
uses: PyO3/maturin-action@v1
66-
if: ${{ startsWith(matrix.platform.target, 'x86') }}
73+
if: ${{ startsWith(matrix.platform.target, 'x86') || startsWith(matrix.platform.target, 'i686') }}
6774
with:
6875
target: ${{ matrix.platform.target }}
6976
args: --release --out dist --find-interpreter --manifest-path ./python-sdk/Cargo.toml
70-
sccache: 'true'
71-
manylinux: auto
77+
sccache: "true"
78+
manylinux: ${{ matrix.platform.manylinux }}
7279
before-script-linux: |
7380
yum install -y perl-IPC-Cmd devtoolset-10-libatomic-devel
7481
- name: Build wheels
7582
uses: PyO3/maturin-action@v1
76-
if: ${{ !startsWith(matrix.platform.target, 'x86') }}
83+
if: ${{ !startsWith(matrix.platform.target, 'x86') && !startsWith(matrix.platform.target, 'i686') }}
7784
with:
7885
target: ${{ matrix.platform.target }}
7986
args: --release --out dist --find-interpreter --manifest-path ./python-sdk/Cargo.toml
80-
sccache: 'true'
81-
manylinux: auto
87+
sccache: "true"
88+
manylinux: ${{ matrix.platform.manylinux }}
8289
before-script-linux: |
8390
apt-get update
84-
apt-get install --no-install-recommends -y libssl-dev
91+
apt-get install --no-install-recommends -y libssl-dev libatomic1
8592
8693
- name: Upload wheels
8794
uses: actions/upload-artifact@v4
@@ -101,7 +108,7 @@ jobs:
101108
npm ci
102109
npm run with-server test:python
103110
- name: pytest
104-
if: ${{ !startsWith(matrix.platform.target, 'x86') && matrix.platform.target != 'ppc64' }}
111+
if: ${{ !startsWith(matrix.platform.target, 'x86') && !startsWith(matrix.platform.target, 'i686') && matrix.platform.target != 'ppc64' }}
105112
uses: uraimo/run-on-arch-action@v2
106113
with:
107114
arch: ${{ matrix.platform.target }}
@@ -142,7 +149,7 @@ jobs:
142149
with:
143150
target: ${{ matrix.platform.target }}
144151
args: --release --out dist --find-interpreter --manifest-path ./python-sdk/Cargo.toml
145-
sccache: 'true'
152+
sccache: "true"
146153
manylinux: musllinux_1_2
147154
- name: Upload wheels
148155
uses: actions/upload-artifact@v4
@@ -207,7 +214,7 @@ jobs:
207214
with:
208215
target: ${{ matrix.platform.target }}
209216
args: --release --out dist --find-interpreter --manifest-path ./python-sdk/Cargo.toml
210-
sccache: 'true'
217+
sccache: "true"
211218
- name: Upload wheels
212219
uses: actions/upload-artifact@v4
213220
with:
@@ -247,7 +254,7 @@ jobs:
247254
with:
248255
target: ${{ matrix.platform.target }}
249256
args: --release --out dist --interpreter ${{ matrix.python-version }} --manifest-path ./python-sdk/Cargo.toml
250-
sccache: 'true'
257+
sccache: "true"
251258

252259
- name: List dist directory
253260
run: ls -l dist

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ To release new versions:
3737
3838
3939
40+
- `dart-sdk-x.y.z` — note the `-` instead of `@`
4041
- Copy release notes from `CHANGELOG.md` file.
4142
- Publish release.
4243
- CI will automatically push a new release out to package registries.

0 commit comments

Comments
 (0)