diff --git a/.github/workflows/open-shorebird-ci.yml b/.github/workflows/open-shorebird-ci.yml index 37911b5..46b2b24 100644 --- a/.github/workflows/open-shorebird-ci.yml +++ b/.github/workflows/open-shorebird-ci.yml @@ -921,6 +921,9 @@ jobs: distribution: temurin java-version: ${{ env.JAVA_VERSION }} + - name: Install Android Rust target + run: rustup target add aarch64-linux-android + - name: Free Ubuntu runner disk run: ./scripts/free_ci_disk_linux.sh @@ -1108,6 +1111,9 @@ jobs: working-directory: flutter run: gclient sync --no-history + - name: Sync Flutter prebuilt Dart SDK + run: ./scripts/sync_flutter_prebuilt_dart_sdk.sh linux-x64 + - name: Configure web SDK working-directory: flutter/engine/src run: | @@ -1115,8 +1121,7 @@ jobs: --web \ --runtime-mode=release \ --target-dir=wasm_release \ - --no-prebuilt-dart-sdk \ - --gn-args='dart_dynamic_modules=false flutter_prebuilt_dart_sdk=false' + --gn-args='dart_dynamic_modules=false' - name: Build web SDK working-directory: flutter/engine/src @@ -1127,7 +1132,7 @@ jobs: ./scripts/verify_engine_args.sh \ flutter/engine/src/out/wasm_release/args.gn \ dart_dynamic_modules=false \ - flutter_prebuilt_dart_sdk=false + flutter_prebuilt_dart_sdk=true - name: Package web SDK artifact run: | @@ -1206,6 +1211,9 @@ jobs: gclient help >/dev/null ninja --version + - name: Install Apple Rust targets + run: rustup target add aarch64-apple-ios aarch64-apple-darwin + - name: Check runner capacity run: CI_MIN_FREE_DISK_GB="$ENGINE_MIN_FREE_DISK_GB" ./scripts/check_ci_capacity.sh diff --git a/docs/CI.md b/docs/CI.md index 4bd2490..f276e0a 100644 --- a/docs/CI.md +++ b/docs/CI.md @@ -441,15 +441,17 @@ verifies the Android artifacts/symbols zips, `flutter.jar`, `libflutter.so`, host snapshot/analyzer tools, args file, manifest, and mirror subtree. `web-sdk` builds the Flutter web SDK archive from `wasm_release` with -`dart_dynamic_modules=false` and `flutter_prebuilt_dart_sdk=false`, then uploads +`dart_dynamic_modules=false` and `flutter_prebuilt_dart_sdk=true`, then uploads `flutter-web-sdk.zip`, a mirror-ready copy of that SDK archive, `args.gn`, a -manifest with the Flutter engine revision, and a `.sha256` sidecar. The engine -and web jobs use `--no-prebuilt-dart-sdk` because the open workspace disables -Flutter's private prebuilt Dart SDK download path and builds from the linked -Dart checkout instead. Web is still not a Shorebird CodePush release platform -in this CLI/protocol; this job exists to keep the open Flutter SDK/web artifacts -buildable from the workspace. CI extracts the web SDK archive before upload and -verifies the SDK zip, args file, manifest, and mirror subtree. +manifest with the Flutter engine revision, and a `.sha256` sidecar. The web job +does not download Flutter's private prebuilt Dart SDK; it links +`dart-sdk/tools/sdks/dart-sdk` into Flutter's expected prebuilt path before +running GN. Native engine jobs use `--no-prebuilt-dart-sdk` because the open +workspace builds those SDK artifacts from the linked Dart checkout instead. Web +is still not a Shorebird CodePush release platform in this CLI/protocol; this +job exists to keep the open Flutter SDK/web artifacts buildable from the +workspace. CI extracts the web SDK archive before upload and verifies the SDK +zip, args file, manifest, and mirror subtree. Set `run_gclient_sync=false` only for debugging a runner image that already has all gclient-managed dependencies restored. diff --git a/scripts/sync_flutter_prebuilt_dart_sdk.sh b/scripts/sync_flutter_prebuilt_dart_sdk.sh new file mode 100755 index 0000000..1c85f29 --- /dev/null +++ b/scripts/sync_flutter_prebuilt_dart_sdk.sh @@ -0,0 +1,67 @@ +#!/usr/bin/env bash +set -euo pipefail + +ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" +HOST_CONFIG="${1:-linux-x64}" +DART_SDK_SOURCE="${DART_SDK_SOURCE:-$ROOT/dart-sdk/tools/sdks/dart-sdk}" +TARGET="$ROOT/flutter/engine/src/flutter/prebuilts/$HOST_CONFIG/dart-sdk" + +relative_path() { + python3 - "$1" "$2" <<'PY' +import os +import sys +print(os.path.relpath(sys.argv[2], os.path.dirname(sys.argv[1]))) +PY +} + +real_path() { + python3 - "$1" <<'PY' +import os +import sys +print(os.path.realpath(sys.argv[1])) +PY +} + +case "$HOST_CONFIG" in + linux-x64|macos-x64|macos-arm64) + ;; + *) + echo "unsupported Flutter prebuilt Dart SDK host config: $HOST_CONFIG" >&2 + exit 64 + ;; +esac + +if [[ ! -d "$DART_SDK_SOURCE" ]]; then + echo "missing Dart tool SDK source: $DART_SDK_SOURCE" >&2 + exit 66 +fi + +for required in \ + bin/dart \ + bin/dartaotruntime \ + bin/snapshots/dartdevc_aot.dart.snapshot \ + bin/snapshots/kernel_worker_aot.dart.snapshot +do + if [[ ! -e "$DART_SDK_SOURCE/$required" ]]; then + echo "Dart tool SDK is missing $required: $DART_SDK_SOURCE" >&2 + exit 66 + fi +done + +mkdir -p "$(dirname "$TARGET")" + +if [[ -L "$TARGET" ]]; then + source_real="$(real_path "$DART_SDK_SOURCE")" + target_real="$(real_path "$TARGET")" + if [[ "$source_real" != "$target_real" ]]; then + echo "Flutter prebuilt Dart SDK link points at $target_real, expected $source_real" >&2 + exit 70 + fi +elif [[ -e "$TARGET" ]]; then + echo "Flutter prebuilt Dart SDK target exists but is not the workspace Dart tool SDK symlink: $TARGET" >&2 + exit 70 +else + ln -s "$(relative_path "$TARGET" "$DART_SDK_SOURCE")" "$TARGET" +fi + +echo "[open-source-sync] Flutter $HOST_CONFIG prebuilt Dart SDK uses $DART_SDK_SOURCE" diff --git a/scripts/verify_ci_workflow.rb b/scripts/verify_ci_workflow.rb index 95a04ed..99ae446 100755 --- a/scripts/verify_ci_workflow.rb +++ b/scripts/verify_ci_workflow.rb @@ -136,6 +136,7 @@ required_files = %w[ scripts/linux_runtime_patch_smoke.sh scripts/verify_open_infrastructure_defaults.sh scripts/safe_extract_tar.py + scripts/sync_flutter_prebuilt_dart_sdk.sh scripts/sync_open_sources.sh scripts/validate_artifact_mirror.py scripts/validate_release_manifest.py @@ -1023,6 +1024,10 @@ platform_test_common = read_repo_file(repo_root, 'scripts/platform_test_common.s bootstrap_linux = read_repo_file(repo_root, 'scripts/bootstrap_linux.sh') bootstrap_macos = read_repo_file(repo_root, 'scripts/bootstrap_macos.sh') sync_open_sources = read_repo_file(repo_root, 'scripts/sync_open_sources.sh') +sync_flutter_prebuilt_dart_sdk = read_repo_file( + repo_root, + 'scripts/sync_flutter_prebuilt_dart_sdk.sh' +) verify_sync_open_sources = read_repo_file( repo_root, 'scripts/verify_sync_open_sources.sh' @@ -1133,6 +1138,15 @@ assert!( verify_sync_open_sources.include?('expected forbidden explicit UPDATER_URL to fail'), 'source sync smoke test must reject upstream Dart SDK and official Shorebird updater remotes' ) +assert!( + sync_flutter_prebuilt_dart_sdk.include?('dart-sdk/tools/sdks/dart-sdk') && + sync_flutter_prebuilt_dart_sdk.include?('flutter/engine/src/flutter/prebuilts/$HOST_CONFIG/dart-sdk') && + sync_flutter_prebuilt_dart_sdk.include?('bin/dartaotruntime') && + sync_flutter_prebuilt_dart_sdk.include?('bin/snapshots/kernel_worker_aot.dart.snapshot') && + sync_flutter_prebuilt_dart_sdk.include?('ln -s') && + !sync_flutter_prebuilt_dart_sdk.include?('shorebird-dart-sdk-prebuilt'), + 'Flutter web prebuilt Dart SDK sync must link the open Dart tool SDK into Flutter prebuilts' +) assert!( job_runs(jobs.fetch('source-checks')).join("\n").include?('./scripts/verify_release_manifest.sh'), 'source-checks must smoke-test release manifest validation' @@ -1941,6 +1955,7 @@ end assert!( run_text_by_job.fetch('ios-engine').include?('--shorebird-interpreter') && + run_text_by_job.fetch('ios-engine').include?('rustup target add aarch64-apple-ios aarch64-apple-darwin') && run_text_by_job.fetch('ios-engine').include?('--no-prebuilt-dart-sdk') && run_text_by_job.fetch('ios-engine').include?("--gn-args='dart_dynamic_modules=false dart_enable_aot_patching=true dart_enable_shorebird_interpreter=true shorebird_use_interpreter=true flutter_prebuilt_dart_sdk=false'") && run_text_by_job.fetch('ios-engine').include?("--gn-args='flutter_prebuilt_dart_sdk=false'") && @@ -2008,6 +2023,7 @@ assert!( ) assert!( run_text_by_job.fetch('android-engine').include?('verify_engine_args.sh') && + run_text_by_job.fetch('android-engine').include?('rustup target add aarch64-linux-android') && run_text_by_job.fetch('android-engine').include?('--no-prebuilt-dart-sdk') && run_text_by_job.fetch('android-engine').include?('flutter/engine/src/out/android_release_arm64/args.gn') && run_text_by_job.fetch('android-engine').include?('dart_enable_aot_patching=true') && @@ -2021,10 +2037,10 @@ assert!( ) assert!( run_text_by_job.fetch('web-sdk').include?('verify_engine_args.sh') && - run_text_by_job.fetch('web-sdk').include?('--no-prebuilt-dart-sdk') && + run_text_by_job.fetch('web-sdk').include?('sync_flutter_prebuilt_dart_sdk.sh linux-x64') && run_text_by_job.fetch('web-sdk').include?('flutter/engine/src/out/wasm_release/args.gn') && run_text_by_job.fetch('web-sdk').include?('dart_dynamic_modules=false') && - run_text_by_job.fetch('web-sdk').include?('flutter_prebuilt_dart_sdk=false') && + run_text_by_job.fetch('web-sdk').include?('flutter_prebuilt_dart_sdk=true') && run_text_by_job.fetch('web-sdk').include?('mirror/shorebird/flutter_infra_release/flutter/${engine_revision}/flutter-web-sdk.zip'), 'web SDK job must explicitly disable and verify DDM' )