mirror of
https://github.com/rustdesk/rustdesk.git
synced 2026-11-03 16:32:22 +00:00
fix(ci): build macOS arm64 with Flutter 3.44 (#16821)
* fix(ci): build macOS arm64 with Flutter 3.44 Flutter 3.24.5's macOS engine can crash in attributedSubstringForProposedRange with an out-of-bounds range on an empty string (#16817). The fix (flutter/flutter#153157) landed after 3.24 and was never cherry-picked, and 3.44 has the bounds check. So macOS arm64 now builds with Flutter 3.44.9, the same way Windows arm64 does: the 3.44 bridge artifact and the shared source patch script. The script uses GNU `sed -i`, which BSD sed on macOS rejects, so the step puts GNU sed first on PATH. The 3.24 dropdown patch is skipped, because 3.44 already has that fix. macOS x86_64 stays on 3.24.5: 3.44's FlutterMacOS needs macOS 10.15 there, and the build targets 10.14. The Dart tests move to the x86_64 job, so CI still runs them against the 3.24.5 sources that most platforms ship. Refs #16817 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(ci): keep CocoaPods on macOS arm64 and run Dart tests on both arches Flutter 3.44 turns on Swift Package Manager by default. On the first `flutter build macos` it would migrate Runner.xcodeproj and Runner.xcscheme, and build file_selector_macos, path_provider_foundation, url_launcher_macos and video_player_avfoundation through SwiftPM while the other 12 plugins stay on CocoaPods. If the migration fails, the build fails. All 16 macOS plugins still ship a podspec, so turning SwiftPM off keeps arm64 on the CocoaPods-only path the 3.24.5 build uses, and this change only swaps the engine. The Dart tests now run on both macOS jobs: x86_64 covers the 3.24.5 sources most platforms ship, and arm64 covers the patched 3.44 sources it ships. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * ci: update comments that still call Windows arm64 the only Flutter 3.44 build The FLUTTER_WINDOWS_ARM_VERSION note, the Windows source-patch step and the header of apply_flutter_3.44_source_patches.sh still said Windows arm64 is the only Flutter 3.44 target. They now mention macOS arm64 too, and the script header records that macOS needs GNU sed for its `sed -i` calls. Comments only. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test: make test_RustDesk_interval_sleep deterministic The test recorded tick times as wall-clock seconds, rounded to the nearest second, and asserted all 5 were unique. If the runner stalled for close to a second, two correct ticks rounded to the same value and the test failed (macOS arm64 CI on #16821: left 5, right 4). It now runs on tokio's paused clock and checks what ThrottledInterval guarantees: ticks are at least 0.9 * period apart. A plain tokio interval bursts its missed ticks with no gap, so a lost throttle still fails. This needs tokio's test-util feature for the existing dev-dependency. It adds no crates, so Cargo.lock is unchanged. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
29d1ab26a1
commit
4ec4ec3d14
5 files changed
+62
-37
No files matched your search
@@ -2,19 +2,22 @@
|
||||
# Applies the Flutter 3.44-only source/pubspec changes on the fly, in CI only.
|
||||
#
|
||||
# Windows arm64 needs Flutter >= 3.44 (the first stable release shipping an arm64 Dart SDK +
|
||||
# engine), which renamed DialogTheme/TabBarTheme -> *Data and needs newer extended_text/
|
||||
# google_fonts. Every other platform is still on Flutter 3.24.5, where the old names/versions
|
||||
# are required, so these changes are kept OUT of the committed sources and applied here instead.
|
||||
# engine), and macOS arm64 builds with 3.44 for its NSTextInputContext crash fix
|
||||
# (https://github.com/rustdesk/rustdesk/issues/16817). 3.44 renamed DialogTheme/TabBarTheme ->
|
||||
# *Data and needs newer extended_text/google_fonts. Every other platform is still on Flutter
|
||||
# 3.24.5, where the old names/versions are required, so these changes are kept OUT of the
|
||||
# committed sources and applied here instead.
|
||||
#
|
||||
# Used by BOTH the Windows arm64 build (flutter-build.yml) and its dedicated bridge artifact
|
||||
# (bridge.yml) so they share an identical 3.44 source state -- the generated *.freezed.dart must
|
||||
# compile against the same Flutter/freezed version the arm64 build resolves.
|
||||
# Used by BOTH arm64 builds (flutter-build.yml) and their shared bridge artifact (bridge.yml) so
|
||||
# they share an identical 3.44 source state -- the generated *.freezed.dart must compile against
|
||||
# the same Flutter/freezed version the arm64 builds resolve.
|
||||
#
|
||||
# Remove this script (and commit the changes) once upstream bumps Flutter across the board.
|
||||
#
|
||||
# Run from the repository root. sed is used (not a git-apply patch) because the checked-out
|
||||
# sources are CRLF on the windows-11-arm runner; the substitutions below are anchor-free and
|
||||
# therefore CRLF-safe.
|
||||
# therefore CRLF-safe. The calls are GNU sed (`sed -i` without a suffix); the macOS arm64 job
|
||||
# puts GNU sed first on PATH because BSD sed rejects them.
|
||||
set -euo pipefail
|
||||
|
||||
readonly NO_MATCHES=0
|
||||
|
||||
@@ -25,7 +25,7 @@ jobs:
|
||||
flutter-version: "3.22.3",
|
||||
artifact-name: "bridge-artifact",
|
||||
}
|
||||
# Dedicated bridge for the Windows arm64 build (Flutter 3.44); runs in parallel.
|
||||
# Dedicated bridge for the Windows and macOS arm64 builds (Flutter 3.44); runs in parallel.
|
||||
- {
|
||||
target: x86_64-unknown-linux-gnu,
|
||||
os: ubuntu-22.04,
|
||||
@@ -92,8 +92,8 @@ jobs:
|
||||
# Default Flutter 3.22.3: extended_text 14 needs a newer Dart, so downgrade for resolution.
|
||||
sed -i -e 's/extended_text: 14.0.0/extended_text: 13.0.0/g' flutter/pubspec.yaml
|
||||
else
|
||||
# Flutter 3.44 bridge for Windows arm64: match that build's source/pubspec state so the
|
||||
# generated *.freezed.dart compiles against the same Flutter/freezed it resolves.
|
||||
# Flutter 3.44 bridge for Windows/macOS arm64: match those builds' source/pubspec state so
|
||||
# the generated *.freezed.dart compiles against the same Flutter/freezed they resolve.
|
||||
bash .github/patches/apply_flutter_3.44_source_patches.sh
|
||||
fi
|
||||
pushd flutter && flutter pub get && popd
|
||||
|
||||
@@ -31,10 +31,15 @@ env:
|
||||
FLUTTER_VERSION: "3.24.5"
|
||||
ANDROID_FLUTTER_VERSION: "3.24.5"
|
||||
# Windows arm64 only: the first stable Flutter to ship a native arm64 Windows Dart SDK +
|
||||
# engine is 3.44. Every other platform stays on FLUTTER_VERSION (3.24.5) until Windows 7
|
||||
# support is restored after the upstream-wide Flutter bump. The arm64 job patches the few
|
||||
# 3.44-only source/pubspec changes on the fly (see "Patch RustDesk sources for Flutter 3.44").
|
||||
# engine is 3.44. Every other platform except macOS arm64 (below) stays on FLUTTER_VERSION
|
||||
# (3.24.5) until Windows 7 support is restored after the upstream-wide Flutter bump. The 3.44
|
||||
# jobs patch the few 3.44-only source/pubspec changes on the fly (see "Patch RustDesk sources
|
||||
# for Flutter 3.44").
|
||||
FLUTTER_WINDOWS_ARM_VERSION: "3.44.9"
|
||||
# macOS arm64 only: 3.24.5's engine crashes in attributedSubstringForProposedRange
|
||||
# (https://github.com/rustdesk/rustdesk/issues/16817, https://github.com/flutter/flutter/issues/153157).
|
||||
# x86_64 stays on FLUTTER_VERSION: 3.44's FlutterMacOS needs macOS 10.15 there, and it targets 10.14.
|
||||
FLUTTER_MACOS_ARM_VERSION: "3.44.9"
|
||||
# for arm64 linux because official Dart SDK does not work
|
||||
FLUTTER_ELINUX_VERSION: "3.16.9"
|
||||
TAG_NAME: "${{ inputs.upload-tag }}"
|
||||
@@ -273,8 +278,9 @@ jobs:
|
||||
fi
|
||||
|
||||
- name: Patch RustDesk sources for Flutter 3.44 (arm64)
|
||||
# arm64 is the only target on Flutter 3.44; apply its source/pubspec deltas on the fly
|
||||
# (shared with the 3.44 bridge job) so the committed sources stay on Flutter 3.24.5.
|
||||
# arm64 is on Flutter 3.44 (as is macOS arm64); apply its source/pubspec deltas on the fly
|
||||
# (shared with the macOS arm64 build and the 3.44 bridge job) so the committed sources
|
||||
# stay on Flutter 3.24.5.
|
||||
# `flutter build` then runs `pub get`, regenerating pubspec.lock for the bumped deps.
|
||||
if: ${{ matrix.job.arch == 'aarch64' }}
|
||||
shell: bash
|
||||
@@ -1004,9 +1010,17 @@ jobs:
|
||||
uses: subosito/flutter-action@1a449444c387b1966244ae4d4f8c696479add0b2 # v2
|
||||
with:
|
||||
channel: "stable"
|
||||
flutter-version: ${{ env.FLUTTER_VERSION }}
|
||||
flutter-version: ${{ matrix.job.arch == 'aarch64' && env.FLUTTER_MACOS_ARM_VERSION || env.FLUTTER_VERSION }}
|
||||
|
||||
- name: Keep CocoaPods for Flutter 3.44 (arm64)
|
||||
# 3.44 turns on Swift Package Manager by default, which would migrate Runner.xcodeproj and
|
||||
# move some plugins off CocoaPods; every plugin still ships a podspec.
|
||||
if: ${{ matrix.job.arch == 'aarch64' }}
|
||||
run: flutter config --no-enable-swift-package-manager
|
||||
|
||||
- name: Patch flutter
|
||||
# Flutter 3.44 (arm64) already has this dropdown fix.
|
||||
if: ${{ matrix.job.arch == 'x86_64' }}
|
||||
run: |
|
||||
cd $(dirname $(dirname $(which flutter)))
|
||||
if [[ "3.24.5" == ${{env.FLUTTER_VERSION}} ]]; then
|
||||
@@ -1021,6 +1035,15 @@ jobs:
|
||||
sed -i -e 's/_setFramesEnabledState(false);/\/\/_setFramesEnabledState(false);/g' ../packages/flutter/lib/src/scheduler/binding.dart
|
||||
grep -n '_setFramesEnabledState(false);' ../packages/flutter/lib/src/scheduler/binding.dart
|
||||
|
||||
- name: Patch RustDesk sources for Flutter 3.44 (arm64)
|
||||
# The script uses GNU `sed -i`, which macOS's BSD sed rejects.
|
||||
if: ${{ matrix.job.arch == 'aarch64' }}
|
||||
shell: bash
|
||||
run: |
|
||||
brew install gnu-sed
|
||||
export PATH="$(brew --prefix gnu-sed)/libexec/gnubin:$PATH"
|
||||
bash .github/patches/apply_flutter_3.44_source_patches.sh
|
||||
|
||||
- name: Install Rust toolchain
|
||||
uses: dtolnay/rust-toolchain@e97e2d8cc328f1b50210efc529dca0028893a2d9 # v1
|
||||
with:
|
||||
@@ -1035,11 +1058,13 @@ jobs:
|
||||
- name: Restore bridge files
|
||||
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
|
||||
with:
|
||||
name: bridge-artifact
|
||||
# arm64's *.freezed.dart must match the freezed it resolves under Flutter 3.44.
|
||||
name: ${{ matrix.job.arch == 'aarch64' && 'bridge-artifact-flutter-3.44' || 'bridge-artifact' }}
|
||||
path: ./
|
||||
|
||||
- name: Run the Dart tests
|
||||
if: ${{ !inputs.upload-artifact && matrix.job.arch == 'aarch64' }}
|
||||
# x86_64 tests the Flutter 3.24.5 sources most platforms ship, arm64 the patched 3.44 ones.
|
||||
if: ${{ !inputs.upload-artifact }}
|
||||
working-directory: flutter
|
||||
run: flutter test --timeout 60s
|
||||
|
||||
|
||||
+1
-1
@@ -273,7 +273,7 @@ os-version = "0.2"
|
||||
[dev-dependencies]
|
||||
hound = "3.5"
|
||||
docopt = "1.1"
|
||||
tokio = "1.44"
|
||||
tokio = { version = "1.44", features = ["test-util"] }
|
||||
|
||||
[package.metadata.bundle]
|
||||
name = "RustDesk"
|
||||
|
||||
+15
-18
@@ -3087,7 +3087,6 @@ mod tests {
|
||||
self,
|
||||
time::{interval, interval_at, sleep, Duration, Instant, Interval},
|
||||
};
|
||||
use std::collections::HashSet;
|
||||
|
||||
#[test]
|
||||
fn parses_stable_rustdesk_release_url() {
|
||||
@@ -3135,16 +3134,6 @@ mod tests {
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn get_timestamp_secs() -> u128 {
|
||||
(std::time::SystemTime::UNIX_EPOCH
|
||||
.elapsed()
|
||||
.unwrap()
|
||||
.as_millis()
|
||||
+ 500)
|
||||
/ 1000
|
||||
}
|
||||
|
||||
fn interval_maker() -> Interval {
|
||||
interval(Duration::from_secs(1))
|
||||
}
|
||||
@@ -3211,9 +3200,10 @@ mod tests {
|
||||
}
|
||||
}
|
||||
|
||||
// ThrottledInterval tick less times than tokio interval, if there're sleeps
|
||||
// ThrottledInterval tick less times than tokio interval, if there're sleeps.
|
||||
// The clock is paused, so a stalled runner cannot make two ticks look close together.
|
||||
#[allow(non_snake_case)]
|
||||
#[tokio::test]
|
||||
#[tokio::test(start_paused = true)]
|
||||
async fn test_RustDesk_interval_sleep() {
|
||||
let base_intervals = [interval_maker, interval_at_maker];
|
||||
for (i, maker) in base_intervals.into_iter().enumerate() {
|
||||
@@ -3223,17 +3213,24 @@ mod tests {
|
||||
loop {
|
||||
tokio::select! {
|
||||
_ = timer.tick() => {
|
||||
times.push(get_timestamp_secs());
|
||||
times.push(Instant::now());
|
||||
if times.len() == 5 {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// No multiple ticks in the `interval` time.
|
||||
// Values in "times" are unique and are less than normal tokio interval.
|
||||
let times2: HashSet<u128> = HashSet::from_iter(times.clone());
|
||||
assert_eq!(times.len(), times2.len(), "test: {}", i);
|
||||
// No multiple ticks in the `interval` time: tokio's interval bursts the missed ticks
|
||||
// with no gap, ThrottledInterval keeps them at least 0.9 * period apart.
|
||||
for pair in times.windows(2) {
|
||||
let gap = pair[1] - pair[0];
|
||||
assert!(
|
||||
gap >= Duration::from_millis(900),
|
||||
"test: {}, gap: {:?}",
|
||||
i,
|
||||
gap
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user