[ci] Run analyze with minimum resolved packages (#6207)

diff --git a/.cirrus.yml b/.cirrus.yml
index 8496150..3d0c525 100644
--- a/.cirrus.yml
+++ b/.cirrus.yml
@@ -171,6 +171,14 @@
         # Only analyze lib/; non-client code doesn't need to work on
         # all supported legacy version.
         - ./script/tool_runner.sh analyze --lib-only --skip-if-not-supporting-flutter-version="$CHANNEL" --custom-analysis=script/configs/custom_analysis.yaml
+    # Does a sanity check that plugins pass analysis with the lowest possible
+    # versions of all dependencies. This is to catch cases where we add use of
+    # new APIs but forget to update minimum versions of dependencies to when
+    # those APIs are introduced.
+    - name: downgraded_analyze
+      depends_on: analyze
+      analyze_script:
+        - ./script/tool_runner.sh analyze --downgrade
     - name: readme_excerpts
       env:
         CIRRUS_CLONE_SUBMODULES: true
diff --git a/packages/image_picker/image_picker_android/CHANGELOG.md b/packages/image_picker/image_picker_android/CHANGELOG.md
index 664be36..1938280 100644
--- a/packages/image_picker/image_picker_android/CHANGELOG.md
+++ b/packages/image_picker/image_picker_android/CHANGELOG.md
@@ -1,3 +1,8 @@
+## 0.8.5+2
+
+* Updates `image_picker_platform_interface` constraint to the correct minimum
+  version.
+
 ## 0.8.5+1
 
 * Switches to an internal method channel implementation.
diff --git a/packages/image_picker/image_picker_android/pubspec.yaml b/packages/image_picker/image_picker_android/pubspec.yaml
index 8cbaaac..6ae7687 100755
--- a/packages/image_picker/image_picker_android/pubspec.yaml
+++ b/packages/image_picker/image_picker_android/pubspec.yaml
@@ -2,7 +2,7 @@
 description: Android implementation of the image_picker plugin.
 repository: https://github.com/flutter/plugins/tree/main/packages/image_picker/image_picker_android
 issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+image_picker%22
-version: 0.8.5+1
+version: 0.8.5+2
 
 environment:
   sdk: ">=2.14.0 <3.0.0"
@@ -21,7 +21,7 @@
   flutter:
     sdk: flutter
   flutter_plugin_android_lifecycle: ^2.0.1
-  image_picker_platform_interface: ^2.3.0
+  image_picker_platform_interface: ^2.5.0
 
 dev_dependencies:
   flutter_test:
diff --git a/packages/local_auth/local_auth_android/CHANGELOG.md b/packages/local_auth/local_auth_android/CHANGELOG.md
index 6a308ee..97f4f7f 100644
--- a/packages/local_auth/local_auth_android/CHANGELOG.md
+++ b/packages/local_auth/local_auth_android/CHANGELOG.md
@@ -1,3 +1,8 @@
+## 1.0.10
+
+* Updates `local_auth_platform_interface` constraint to the correct minimum
+  version.
+
 ## 1.0.9
 
 * Updates  androidx.fragment version to 1.5.1.
diff --git a/packages/local_auth/local_auth_android/pubspec.yaml b/packages/local_auth/local_auth_android/pubspec.yaml
index b36b92e..af1ec51 100644
--- a/packages/local_auth/local_auth_android/pubspec.yaml
+++ b/packages/local_auth/local_auth_android/pubspec.yaml
@@ -2,7 +2,7 @@
 description: Android implementation of the local_auth plugin.
 repository: https://github.com/flutter/plugins/tree/main/packages/local_auth/local_auth_android
 issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+local_auth%22
-version: 1.0.9
+version: 1.0.10
 
 environment:
   sdk: ">=2.14.0 <3.0.0"
@@ -22,7 +22,7 @@
     sdk: flutter
   flutter_plugin_android_lifecycle: ^2.0.1
   intl: ^0.17.0
-  local_auth_platform_interface: ^1.0.0
+  local_auth_platform_interface: ^1.0.1
 
 dev_dependencies:
   flutter_test:
diff --git a/packages/local_auth/local_auth_ios/CHANGELOG.md b/packages/local_auth/local_auth_ios/CHANGELOG.md
index 4b8e065..7892bbc 100644
--- a/packages/local_auth/local_auth_ios/CHANGELOG.md
+++ b/packages/local_auth/local_auth_ios/CHANGELOG.md
@@ -1,3 +1,8 @@
+## 1.0.8
+
+* Updates `local_auth_platform_interface` constraint to the correct minimum
+  version.
+
 ## 1.0.7
 
 * Updates references to the obsolete master branch.
diff --git a/packages/local_auth/local_auth_ios/pubspec.yaml b/packages/local_auth/local_auth_ios/pubspec.yaml
index 043d84e..e38e303 100644
--- a/packages/local_auth/local_auth_ios/pubspec.yaml
+++ b/packages/local_auth/local_auth_ios/pubspec.yaml
@@ -2,7 +2,7 @@
 description: iOS implementation of the local_auth plugin.
 repository: https://github.com/flutter/plugins/tree/main/packages/local_auth/local_auth_ios
 issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+local_auth%22
-version: 1.0.7
+version: 1.0.8
 
 environment:
   sdk: ">=2.14.0 <3.0.0"
@@ -20,7 +20,7 @@
   flutter:
     sdk: flutter
   intl: ^0.17.0
-  local_auth_platform_interface: ^1.0.0
+  local_auth_platform_interface: ^1.0.1
 
 dev_dependencies:
   flutter_test:
diff --git a/packages/local_auth/local_auth_windows/CHANGELOG.md b/packages/local_auth/local_auth_windows/CHANGELOG.md
index f6c5e90..14ac67d 100644
--- a/packages/local_auth/local_auth_windows/CHANGELOG.md
+++ b/packages/local_auth/local_auth_windows/CHANGELOG.md
@@ -1,3 +1,8 @@
+## 1.0.2
+
+* Updates `local_auth_platform_interface` constraint to the correct minimum
+  version.
+
 ## 1.0.1
 
 * Updates references to the obsolete master branch.
diff --git a/packages/local_auth/local_auth_windows/pubspec.yaml b/packages/local_auth/local_auth_windows/pubspec.yaml
index b42a4f8..99af0cc 100644
--- a/packages/local_auth/local_auth_windows/pubspec.yaml
+++ b/packages/local_auth/local_auth_windows/pubspec.yaml
@@ -2,7 +2,7 @@
 description: Windows implementation of the local_auth plugin.
 repository: https://github.com/flutter/plugins/tree/main/packages/local_auth/local_auth_windows
 issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+local_auth%22
-version: 1.0.1
+version: 1.0.2
 
 environment:
   sdk: ">=2.14.0 <3.0.0"
@@ -19,7 +19,7 @@
 dependencies:
   flutter:
     sdk: flutter
-  local_auth_platform_interface: ^1.0.0
+  local_auth_platform_interface: ^1.0.1
 
 dev_dependencies:
   flutter_test:
diff --git a/packages/url_launcher/url_launcher_web/CHANGELOG.md b/packages/url_launcher/url_launcher_web/CHANGELOG.md
index 75c0819..01d7392 100644
--- a/packages/url_launcher/url_launcher_web/CHANGELOG.md
+++ b/packages/url_launcher/url_launcher_web/CHANGELOG.md
@@ -1,3 +1,8 @@
+## 2.0.13
+
+* Updates `url_launcher_platform_interface` constraint to the correct minimum
+  version.
+
 ## 2.0.12
 
 * Fixes call to `setState` after dispose on the `Link` widget.
diff --git a/packages/url_launcher/url_launcher_web/pubspec.yaml b/packages/url_launcher/url_launcher_web/pubspec.yaml
index d0e0fa9..6d4c806 100644
--- a/packages/url_launcher/url_launcher_web/pubspec.yaml
+++ b/packages/url_launcher/url_launcher_web/pubspec.yaml
@@ -2,7 +2,7 @@
 description: Web platform implementation of url_launcher
 repository: https://github.com/flutter/plugins/tree/main/packages/url_launcher/url_launcher_web
 issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+url_launcher%22
-version: 2.0.12
+version: 2.0.13
 
 environment:
   sdk: ">=2.12.0 <3.0.0"
@@ -21,7 +21,7 @@
     sdk: flutter
   flutter_web_plugins:
     sdk: flutter
-  url_launcher_platform_interface: ^2.0.0
+  url_launcher_platform_interface: ^2.0.3
 
 dev_dependencies:
   flutter_test:
diff --git a/packages/webview_flutter/webview_flutter_wkwebview/CHANGELOG.md b/packages/webview_flutter/webview_flutter_wkwebview/CHANGELOG.md
index 5d44502..a533ce6 100644
--- a/packages/webview_flutter/webview_flutter_wkwebview/CHANGELOG.md
+++ b/packages/webview_flutter/webview_flutter_wkwebview/CHANGELOG.md
@@ -1,3 +1,8 @@
+## 2.9.3
+
+* Updates `webview_flutter_platform_interface` constraint to the correct minimum
+  version.
+
 ## 2.9.2
 
 * Fixes crash when an Objective-C object in `FWFInstanceManager` is released, but the dealloc
diff --git a/packages/webview_flutter/webview_flutter_wkwebview/pubspec.yaml b/packages/webview_flutter/webview_flutter_wkwebview/pubspec.yaml
index 9837519..a4847d5 100644
--- a/packages/webview_flutter/webview_flutter_wkwebview/pubspec.yaml
+++ b/packages/webview_flutter/webview_flutter_wkwebview/pubspec.yaml
@@ -2,7 +2,7 @@
 description: A Flutter plugin that provides a WebView widget based on Apple's WKWebView control.
 repository: https://github.com/flutter/plugins/tree/main/packages/webview_flutter/webview_flutter_wkwebview
 issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+webview%22
-version: 2.9.2
+version: 2.9.3
 
 environment:
   sdk: ">=2.17.0 <3.0.0"
@@ -19,7 +19,7 @@
   flutter:
     sdk: flutter
   path: ^1.8.0
-  webview_flutter_platform_interface: ^1.8.0
+  webview_flutter_platform_interface: ^1.9.0
 
 dev_dependencies:
   build_runner: ^2.1.5
diff --git a/script/tool/CHANGELOG.md b/script/tool/CHANGELOG.md
index 667f1a1..50e389f 100644
--- a/script/tool/CHANGELOG.md
+++ b/script/tool/CHANGELOG.md
@@ -1,10 +1,15 @@
+## 0.9.1
+
+* Adds a `--downgrade` flag to `analyze` for analyzing with the oldest possible
+  versions of packages.
+
 ## 0.9.0
 
 * Replaces PR-description-based version/changelog/breaking change check
   overrides in `version-check` with label-based overrides using a new
   `pr-labels` flag, since we don't actually have reliable access to the
   PR description in checks.
-  
+
 ## 0.8.10
 
 - Adds a new `remove-dev-dependencies` command to remove `dev_dependencies`
diff --git a/script/tool/lib/src/analyze_command.dart b/script/tool/lib/src/analyze_command.dart
index 54b4f33..c7a953c 100644
--- a/script/tool/lib/src/analyze_command.dart
+++ b/script/tool/lib/src/analyze_command.dart
@@ -32,12 +32,16 @@
         valueHelp: 'dart-sdk',
         help: 'An optional path to a Dart SDK; this is used to override the '
             'SDK used to provide analysis.');
+    argParser.addFlag(_downgradeFlag,
+        help: 'Runs "flutter pub downgrade" before analysis to verify that '
+            'the minimum constraints are sufficiently new for APIs used.');
     argParser.addFlag(_libOnlyFlag,
         help: 'Only analyze the lib/ directory of the main package, not the '
             'entire package.');
   }
 
   static const String _customAnalysisFlag = 'custom-analysis';
+  static const String _downgradeFlag = 'downgrade';
   static const String _libOnlyFlag = 'lib-only';
   static const String _analysisSdk = 'analysis-sdk';
 
@@ -113,6 +117,12 @@
       return PackageResult.skip('No lib/ directory.');
     }
 
+    if (getBoolArg(_downgradeFlag)) {
+      if (!await _runPubCommand(package, 'downgrade')) {
+        return PackageResult.fail(<String>['Unable to downgrade dependencies']);
+      }
+    }
+
     // Analysis runs over the package and all subpackages (unless only lib/ is
     // being analyzed), so all of them need `flutter pub get` run before
     // analyzing. `example` packages can be skipped since 'flutter packages get'
@@ -127,10 +137,7 @@
           !RepositoryPackage(packageToGet.directory.parent)
               .pubspecFile
               .existsSync()) {
-        final int exitCode = await processRunner.runAndStream(
-            flutterCommand, <String>['pub', 'get'],
-            workingDir: packageToGet.directory);
-        if (exitCode != 0) {
+        if (!await _runPubCommand(packageToGet, 'get')) {
           return PackageResult.fail(<String>['Unable to get dependencies']);
         }
       }
@@ -147,4 +154,11 @@
     }
     return PackageResult.success();
   }
+
+  Future<bool> _runPubCommand(RepositoryPackage package, String command) async {
+    final int exitCode = await processRunner.runAndStream(
+        flutterCommand, <String>['pub', command],
+        workingDir: package.directory);
+    return exitCode == 0;
+  }
 }
diff --git a/script/tool/pubspec.yaml b/script/tool/pubspec.yaml
index a99be70..e80afa2 100644
--- a/script/tool/pubspec.yaml
+++ b/script/tool/pubspec.yaml
@@ -1,7 +1,7 @@
 name: flutter_plugin_tools
 description: Productivity utils for flutter/plugins and flutter/packages
 repository: https://github.com/flutter/plugins/tree/main/script/tool
-version: 0.9.0
+version: 0.9.1
 
 dependencies:
   args: ^2.1.0
diff --git a/script/tool/test/analyze_command_test.dart b/script/tool/test/analyze_command_test.dart
index d3abf0b..e10780f 100644
--- a/script/tool/test/analyze_command_test.dart
+++ b/script/tool/test/analyze_command_test.dart
@@ -187,6 +187,33 @@
     );
   });
 
+  test('downgrades first when requested', () async {
+    final RepositoryPackage plugin = createFakePlugin('a', packagesDir);
+
+    await runCapturingPrint(runner, <String>['analyze', '--downgrade']);
+
+    expect(
+      processRunner.recordedCalls,
+      orderedEquals(<ProcessCall>[
+        ProcessCall(
+          'flutter',
+          const <String>['pub', 'downgrade'],
+          plugin.path,
+        ),
+        ProcessCall(
+          'flutter',
+          const <String>['pub', 'get'],
+          plugin.path,
+        ),
+        ProcessCall(
+          'dart',
+          const <String>['analyze', '--fatal-infos'],
+          plugin.path,
+        ),
+      ]),
+    );
+  });
+
   group('verifies analysis settings', () {
     test('fails analysis_options.yaml', () async {
       createFakePlugin('foo', packagesDir,
@@ -312,6 +339,28 @@
     );
   });
 
+  test('fails if "pub downgrade" fails', () async {
+    createFakePlugin('foo', packagesDir);
+
+    processRunner.mockProcessesForExecutable['flutter'] = <io.Process>[
+      MockProcess(exitCode: 1) // flutter pub downgrade
+    ];
+
+    Error? commandError;
+    final List<String> output = await runCapturingPrint(
+        runner, <String>['analyze', '--downgrade'], errorHandler: (Error e) {
+      commandError = e;
+    });
+
+    expect(commandError, isA<ToolExit>());
+    expect(
+      output,
+      containsAllInOrder(<Matcher>[
+        contains('Unable to downgrade dependencies'),
+      ]),
+    );
+  });
+
   test('fails if "analyze" fails', () async {
     createFakePlugin('foo', packagesDir);