diff --git a/AGENTS.md b/AGENTS.md index 6a0a5477..265f5c35 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -1,6 +1,5 @@ ## Skills -- Use `xworkmate-acceptance` before claiming build, packaging, installation, or release readiness for this repo. - For any change that touches gateway auth, `.env`, secure storage, tokens, passwords, TLS, file upload, native entitlements, packaging, or release-sensitive settings, follow the security rules in this file and [docs/security/secure-development-rules.md](docs/security/secure-development-rules.md). - For non-trivial implementation work, default to the worktree-first execution flow in this file without asking the user to restate that preference each time. @@ -127,7 +126,6 @@ Soft triggers (recommended execution): `Phase 5 - SECURITY/ACCEPTANCE` - If change scope touches auth/secrets/network/entitlements/release-sensitive settings, apply security baseline checks. -- Before any build/package/install/release readiness claim, run `xworkmate-acceptance`. Baseline commands: - `flutter analyze` diff --git a/Makefile b/Makefile index bfedcfbc..09b3befd 100644 --- a/Makefile +++ b/Makefile @@ -62,8 +62,7 @@ test-api-scenario-contract: ## Run the scenario-oriented API script against exte check-api-external: test-api-contract test-api-scenario-contract ## Run both external API validation scripts test-patrol: ## Run Patrol end-to-end tests - dart pub global activate patrol_cli - patrol test + bash scripts/ci/run_patrol_suite.sh test-go: ## Run xworkmate-bridge Go unit tests cd ../xworkmate-bridge && go test ./... diff --git a/docs/README_TESTING.md b/docs/README_TESTING.md index 28961e7c..3c041706 100644 --- a/docs/README_TESTING.md +++ b/docs/README_TESTING.md @@ -16,10 +16,10 @@ flutter test integration_test ## Patrol -Run Patrol tests: +Run Patrol tests when `patrol_test/` exists and contains `*_test.dart` files: ```bash -patrol test +make test-patrol ``` ## Go @@ -38,4 +38,4 @@ go test ./... - Widget, integration, and Patrol suites are owned by their dedicated commands and release validation flows, not by the lightweight `verify` gate. - Pushes to `main`, version tags, and manual workflow runs publish build artifacts and update the GitHub Release entry for that release mode. - `xworkmate-bridge` Go tests run in the companion repository. -- `release/*` branches run Patrol tests in addition to the PR chain. +- `release/*` branches run Patrol tests in addition to the PR chain when Patrol tests are present. diff --git a/ios/Podfile.lock b/ios/Podfile.lock index cf2be8d2..9d9f0d3f 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -1,5 +1,4 @@ PODS: - - CocoaAsyncSocket (7.6.5) - device_info_plus (0.0.1): - Flutter - file_selector_ios (0.0.1): @@ -14,10 +13,6 @@ PODS: - Flutter - package_info_plus (0.4.5): - Flutter - - patrol (0.0.1): - - CocoaAsyncSocket (~> 7.6) - - Flutter - - FlutterMacOS - shared_preferences_foundation (0.0.1): - Flutter - FlutterMacOS @@ -33,13 +28,11 @@ DEPENDENCIES: - integration_test (from `.symlinks/plugins/integration_test/ios`) - irondash_engine_context (from `.symlinks/plugins/irondash_engine_context/ios`) - package_info_plus (from `.symlinks/plugins/package_info_plus/ios`) - - patrol (from `.symlinks/plugins/patrol/darwin`) - shared_preferences_foundation (from `.symlinks/plugins/shared_preferences_foundation/darwin`) - super_native_extensions (from `.symlinks/plugins/super_native_extensions/ios`) SPEC REPOS: trunk: - - CocoaAsyncSocket - WebRTC-SDK EXTERNAL SOURCES: @@ -57,15 +50,12 @@ EXTERNAL SOURCES: :path: ".symlinks/plugins/irondash_engine_context/ios" package_info_plus: :path: ".symlinks/plugins/package_info_plus/ios" - patrol: - :path: ".symlinks/plugins/patrol/darwin" shared_preferences_foundation: :path: ".symlinks/plugins/shared_preferences_foundation/darwin" super_native_extensions: :path: ".symlinks/plugins/super_native_extensions/ios" SPEC CHECKSUMS: - CocoaAsyncSocket: 065fd1e645c7abab64f7a6a2007a48038fdc6a99 device_info_plus: 21fcca2080fbcd348be798aa36c3e5ed849eefbe file_selector_ios: ec57ec07954363dd730b642e765e58f199bb621a Flutter: cabc95a1d2626b1b06e7179b784ebcf0c0cde467 @@ -73,7 +63,6 @@ SPEC CHECKSUMS: integration_test: 4a889634ef21a45d28d50d622cf412dc6d9f586e irondash_engine_context: 8e58ca8e0212ee9d1c7dc6a42121849986c88486 package_info_plus: af8e2ca6888548050f16fa2f1938db7b5a5df499 - patrol: cea8074f183a2a4232d0ebd10569ae05149ada42 shared_preferences_foundation: 7036424c3d8ec98dfe75ff1667cb0cd531ec82bb super_native_extensions: b763c02dc3a8fd078389f410bf15149179020cb4 WebRTC-SDK: 79942c006ea64f6fb48d7da8a4786dfc820bc1db diff --git a/macos/Flutter/GeneratedPluginRegistrant.swift b/macos/Flutter/GeneratedPluginRegistrant.swift index 4e32b0e3..7052f39a 100644 --- a/macos/Flutter/GeneratedPluginRegistrant.swift +++ b/macos/Flutter/GeneratedPluginRegistrant.swift @@ -10,7 +10,6 @@ import file_selector_macos import flutter_webrtc import irondash_engine_context import package_info_plus -import patrol import shared_preferences_foundation import super_native_extensions @@ -20,7 +19,6 @@ func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) { FlutterWebRTCPlugin.register(with: registry.registrar(forPlugin: "FlutterWebRTCPlugin")) IrondashEngineContextPlugin.register(with: registry.registrar(forPlugin: "IrondashEngineContextPlugin")) FPPPackageInfoPlusPlugin.register(with: registry.registrar(forPlugin: "FPPPackageInfoPlusPlugin")) - PatrolPlugin.register(with: registry.registrar(forPlugin: "PatrolPlugin")) SharedPreferencesPlugin.register(with: registry.registrar(forPlugin: "SharedPreferencesPlugin")) SuperNativeExtensionsPlugin.register(with: registry.registrar(forPlugin: "SuperNativeExtensionsPlugin")) } diff --git a/macos/Podfile b/macos/Podfile index beb9aa8e..09129ab9 100644 --- a/macos/Podfile +++ b/macos/Podfile @@ -99,7 +99,7 @@ post_install do |installer| target.build_configurations.each do |config| config.build_settings['MACOSX_DEPLOYMENT_TARGET'] = '11.5' - next unless ['patrol', 'CocoaAsyncSocket', 'Pods-Runner', 'Pods-RunnerTests', 'WebRTC-SDK', 'flutter_webrtc'].include?(target.name) + next unless ['Pods-Runner', 'Pods-RunnerTests', 'WebRTC-SDK', 'flutter_webrtc'].include?(target.name) append_ignored_attributes_suppression.call(config.build_settings) append_deprecation_suppression.call(config.build_settings) diff --git a/macos/Podfile.lock b/macos/Podfile.lock index 14228be0..3720858f 100644 --- a/macos/Podfile.lock +++ b/macos/Podfile.lock @@ -1,5 +1,4 @@ PODS: - - CocoaAsyncSocket (7.6.5) - device_info_plus (0.0.1): - FlutterMacOS - file_selector_macos (0.0.1): @@ -12,10 +11,6 @@ PODS: - FlutterMacOS - package_info_plus (0.0.1): - FlutterMacOS - - patrol (0.0.1): - - CocoaAsyncSocket (~> 7.6) - - Flutter - - FlutterMacOS - shared_preferences_foundation (0.0.1): - Flutter - FlutterMacOS @@ -30,13 +25,11 @@ DEPENDENCIES: - FlutterMacOS (from `Flutter/ephemeral`) - irondash_engine_context (from `Flutter/ephemeral/.symlinks/plugins/irondash_engine_context/macos`) - package_info_plus (from `Flutter/ephemeral/.symlinks/plugins/package_info_plus/macos`) - - patrol (from `Flutter/ephemeral/.symlinks/plugins/patrol/darwin`) - shared_preferences_foundation (from `Flutter/ephemeral/.symlinks/plugins/shared_preferences_foundation/darwin`) - super_native_extensions (from `Flutter/ephemeral/.symlinks/plugins/super_native_extensions/macos`) SPEC REPOS: trunk: - - CocoaAsyncSocket - WebRTC-SDK EXTERNAL SOURCES: @@ -52,26 +45,22 @@ EXTERNAL SOURCES: :path: Flutter/ephemeral/.symlinks/plugins/irondash_engine_context/macos package_info_plus: :path: Flutter/ephemeral/.symlinks/plugins/package_info_plus/macos - patrol: - :path: Flutter/ephemeral/.symlinks/plugins/patrol/darwin shared_preferences_foundation: :path: Flutter/ephemeral/.symlinks/plugins/shared_preferences_foundation/darwin super_native_extensions: :path: Flutter/ephemeral/.symlinks/plugins/super_native_extensions/macos SPEC CHECKSUMS: - CocoaAsyncSocket: 065fd1e645c7abab64f7a6a2007a48038fdc6a99 device_info_plus: 4fb280989f669696856f8b129e4a5e3cd6c48f76 file_selector_macos: 9e9e068e90ebee155097d00e89ae91edb2374db7 flutter_webrtc: 377dbcebdde6fed0fc40de87bcaaa2bffcec9a88 FlutterMacOS: d0db08ddef1a9af05a5ec4b724367152bb0500b1 irondash_engine_context: 893c7d96d20ce361d7e996f39d360c4c2f9869ba package_info_plus: f0052d280d17aa382b932f399edf32507174e870 - patrol: cea8074f183a2a4232d0ebd10569ae05149ada42 shared_preferences_foundation: 7036424c3d8ec98dfe75ff1667cb0cd531ec82bb super_native_extensions: c2795d6d9aedf4a79fae25cb6160b71b50549189 WebRTC-SDK: 79942c006ea64f6fb48d7da8a4786dfc820bc1db -PODFILE CHECKSUM: d6c0f271ccdc2e48bb44003eee71c5d884660a71 +PODFILE CHECKSUM: 0ff086e365498790bfa0f77c18fab96518c27b1e COCOAPODS: 1.16.2 diff --git a/pubspec.lock b/pubspec.lock index cdc2431d..07740240 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -121,22 +121,6 @@ packages: url: "https://pub.dev" source: hosted version: "7.0.3" - dispose_scope: - dependency: transitive - description: - name: dispose_scope - sha256: "48ec38ca2631c53c4f8fa96b294c801e55c335db5e3fb9f82cede150cfe5a2af" - url: "https://pub.dev" - source: hosted - version: "2.1.0" - equatable: - dependency: transitive - description: - name: equatable - sha256: "3e0141505477fd8ad55d6eb4e7776d3fe8430be8e497ccb1521370c3f21a3e2b" - url: "https://pub.dev" - source: hosted - version: "2.0.8" fake_async: dependency: transitive description: @@ -372,14 +356,6 @@ packages: url: "https://pub.dev" source: hosted version: "0.7.2" - json_annotation: - dependency: transitive - description: - name: json_annotation - sha256: cb09e7dac6210041fad964ed7fbee004f14258b4eca4040f72d1234062ace4c8 - url: "https://pub.dev" - source: hosted - version: "4.11.0" leak_tracker: dependency: transitive description: @@ -547,30 +523,6 @@ packages: url: "https://pub.dev" source: hosted version: "2.3.0" - patrol: - dependency: "direct dev" - description: - name: patrol - sha256: "7825a6e96a8f0755f68eec600a91a08b19bd0975488a70885b3696f6b65ffc0f" - url: "https://pub.dev" - source: hosted - version: "4.5.0" - patrol_finders: - dependency: transitive - description: - name: patrol_finders - sha256: "9970eac0669a90b20ec7e1bcaabd0475655655998068ca656f4df9f6ec84f336" - url: "https://pub.dev" - source: hosted - version: "3.2.0" - patrol_log: - dependency: transitive - description: - name: patrol_log - sha256: a2360db165c34692665c0de146e5157887d6b584fdccca8f141f947a5acf1b2e - url: "https://pub.dev" - source: hosted - version: "0.8.0" pixel_snap: dependency: transitive description: @@ -667,14 +619,6 @@ packages: url: "https://pub.dev" source: hosted version: "2.4.1" - shelf: - dependency: transitive - description: - name: shelf - sha256: e7dd780a7ffb623c57850b33f43309312fc863fb6aa3d276a754bb299839ef12 - url: "https://pub.dev" - source: hosted - version: "1.4.2" sky_engine: dependency: transitive description: flutter diff --git a/pubspec.yaml b/pubspec.yaml index 6db159f7..4db29340 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -36,7 +36,6 @@ dev_dependencies: sdk: flutter integration_test: sdk: flutter - patrol: ^4.3.0 flutter_lints: ^6.0.0 dependency_overrides: diff --git a/scripts/ci/run_patrol_suite.sh b/scripts/ci/run_patrol_suite.sh index f88dbb70..dc6a5ed7 100644 --- a/scripts/ci/run_patrol_suite.sh +++ b/scripts/ci/run_patrol_suite.sh @@ -1,6 +1,15 @@ #!/usr/bin/env bash set -euo pipefail +has_patrol_tests() { + [[ -d patrol_test ]] && find patrol_test -name '*_test.dart' -print -quit | grep -q . +} + +if ! has_patrol_tests; then + echo "[skip] no Patrol tests found under patrol_test" + exit 0 +fi + flutter pub get dart pub global activate patrol_cli -patrol test +patrol test patrol_test diff --git a/scripts/validate-macos-app-bundle.sh b/scripts/validate-macos-app-bundle.sh index 345d6665..46902bfd 100644 --- a/scripts/validate-macos-app-bundle.sh +++ b/scripts/validate-macos-app-bundle.sh @@ -68,6 +68,20 @@ is_macho_file() { otool -L "$path" >/dev/null 2>&1 } +validate_no_test_only_frameworks() { + local app_path="$1" + local frameworks_dir="$app_path/Contents/Frameworks" + [[ -d "$frameworks_dir" ]] || return 0 + + local forbidden_framework + for forbidden_framework in patrol.framework; do + if [[ -e "$frameworks_dir/$forbidden_framework" ]]; then + echo "Test-only framework must not be bundled in packaged app: $frameworks_dir/$forbidden_framework" >&2 + return 1 + fi + done +} + resolve_dependency() { local dependency="$1" local binary_path="$2" @@ -178,6 +192,8 @@ validate_binary() { echo "Validating macOS app bundle dynamic dependencies: $APP_PATH" +validate_no_test_only_frameworks "$APP_PATH" + EXECUTABLE_DIR="$(cd "$APP_PATH/Contents/MacOS" && pwd)" declare -a macho_files=("$MAIN_EXECUTABLE")