[flutter_conductor] updates (#86452)

diff --git a/dev/conductor/bin/conductor b/dev/conductor/bin/conductor
index 2897339..627db25 100755
--- a/dev/conductor/bin/conductor
+++ b/dev/conductor/bin/conductor
@@ -37,4 +37,7 @@
 REPO_DIR="$BIN_DIR/../../.."
 DART_BIN="$REPO_DIR/bin/dart"
 
+# Ensure pub get has been run in the repo before running the conductor
+(cd "$REPO_DIR/dev/conductor"; $DART_BIN pub get 1>&2)
+
 "$DART_BIN" --enable-asserts "$REPO_DIR/dev/conductor/bin/conductor.dart" "$@"
diff --git a/dev/conductor/lib/globals.dart b/dev/conductor/lib/globals.dart
index 670041c..ff8adff 100644
--- a/dev/conductor/lib/globals.dart
+++ b/dev/conductor/lib/globals.dart
@@ -85,11 +85,10 @@
   String name,
   ArgResults argResults,
   Map<String, String> env, {
-    bool allowNull = false,
-  }
-) {
+  bool allowNull = false,
+}) {
   final String envName = fromArgToEnvName(name);
-  if (env[envName] != null ) {
+  if (env[envName] != null) {
     return env[envName];
   }
   final String? argValue = argResults[name] as String?;
@@ -139,3 +138,13 @@
 String fromArgToEnvName(String argName) {
   return argName.toUpperCase().replaceAll(r'-', r'_');
 }
+
+/// Return a web link for the user to open a new PR.
+String getNewPrLink({
+  required String userName,
+  required String repoName,
+  required String candidateBranch,
+  required String workingBranch,
+}) {
+  return 'https://github.com/flutter/$repoName/compare/$candidateBranch...$userName:$workingBranch?expand=1';
+}
diff --git a/dev/conductor/lib/next.dart b/dev/conductor/lib/next.dart
index cef5e89..d3686c5 100644
--- a/dev/conductor/lib/next.dart
+++ b/dev/conductor/lib/next.dart
@@ -102,7 +102,7 @@
         }
       }
 
-      if (state.engine.cherrypicks.isEmpty && state.engine.dartRevision.isEmpty) {
+      if (!requiresEnginePR(state)) {
         stdio.printStatus(
           'This release has no engine cherrypicks. No Engine PR is necessary.\n',
         );
@@ -110,18 +110,16 @@
       }
 
       if (unappliedCherrypicks.isEmpty) {
-        stdio.printStatus('All engine cherrypicks have been auto-applied by '
-            'the conductor.\n');
+        stdio.printStatus('All engine cherrypicks have been auto-applied by the conductor.\n');
       } else {
-        stdio.printStatus(
-          'There were ${unappliedCherrypicks.length} cherrypicks that were not auto-applied.');
+        stdio.printStatus('There were ${unappliedCherrypicks.length} cherrypicks that were not auto-applied.');
         stdio.printStatus('These must be applied manually in the directory '
-          '${state.engine.checkoutPath} before proceeding.\n');
+            '${state.engine.checkoutPath} before proceeding.\n');
       }
       if (autoAccept == false) {
         final bool response = prompt(
-            'Are you ready to push your engine branch to the repository '
-            '${state.engine.mirror.url}?',
+          'Are you ready to push your engine branch to the repository '
+          '${state.engine.mirror.url}?',
           stdio,
         );
         if (!response) {
@@ -189,13 +187,15 @@
           break;
         }
       }
+      final Remote engineUpstreamRemote = Remote(
+        name: RemoteName.upstream,
+        url: state.engine.upstream.url,
+      );
       final EngineRepository engine = EngineRepository(
         checkouts,
-        initialRef: state.engine.candidateBranch,
-        upstreamRemote: Remote(
-          name: RemoteName.upstream,
-          url: state.engine.upstream.url,
-        ),
+        // We explicitly want to check out the merged version from upstream
+        initialRef: '${engineUpstreamRemote.name}/${state.engine.candidateBranch}',
+        upstreamRemote: engineUpstreamRemote,
         previousCheckoutLocation: state.engine.checkoutPath,
       );
 
@@ -215,7 +215,9 @@
 
       stdio.printStatus('Rolling new engine hash $engineRevision to framework checkout...');
       framework.updateEngineRevision(engineRevision);
-      framework.commit('Update Engine revision to $engineRevision for ${state.releaseChannel} release ${state.releaseVersion}', addFirst: true);
+      framework.commit(
+          'Update Engine revision to $engineRevision for ${state.releaseChannel} release ${state.releaseVersion}',
+          addFirst: true);
 
       if (state.framework.cherrypicks.isEmpty) {
         stdio.printStatus(
@@ -262,7 +264,8 @@
       );
       final FrameworkRepository framework = FrameworkRepository(
         checkouts,
-        initialRef: state.framework.candidateBranch,
+        // We explicitly want to check out the merged version from upstream
+        initialRef: '${upstream.name}/${state.framework.candidateBranch}',
         upstreamRemote: upstream,
         previousCheckoutLocation: state.framework.checkoutPath,
       );
@@ -288,7 +291,8 @@
       );
       final FrameworkRepository framework = FrameworkRepository(
         checkouts,
-        initialRef: state.framework.candidateBranch,
+        // We explicitly want to check out the merged version from upstream
+        initialRef: '${upstream.name}/${state.framework.candidateBranch}',
         upstreamRemote: upstream,
         previousCheckoutLocation: state.framework.checkoutPath,
       );
diff --git a/dev/conductor/lib/proto/conductor_state.pb.dart b/dev/conductor/lib/proto/conductor_state.pb.dart
index 7da9b37..1ab4e96 100644
--- a/dev/conductor/lib/proto/conductor_state.pb.dart
+++ b/dev/conductor/lib/proto/conductor_state.pb.dart
@@ -403,6 +403,8 @@
         enumValues: ReleasePhase.values)
     ..aOS(10, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'conductorVersion',
         protoName: 'conductorVersion')
+    ..aOS(11, const $core.bool.fromEnvironment('protobuf.omit_field_names') ? '' : 'incrementLevel',
+        protoName: 'incrementLevel')
     ..hasRequiredFields = false;
 
   ConductorState._() : super();
@@ -416,6 +418,7 @@
     $core.Iterable<$core.String>? logs,
     ReleasePhase? currentPhase,
     $core.String? conductorVersion,
+    $core.String? incrementLevel,
   }) {
     final _result = create();
     if (releaseChannel != null) {
@@ -445,6 +448,9 @@
     if (conductorVersion != null) {
       _result.conductorVersion = conductorVersion;
     }
+    if (incrementLevel != null) {
+      _result.incrementLevel = incrementLevel;
+    }
     return _result;
   }
   factory ConductorState.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) =>
@@ -572,4 +578,16 @@
   $core.bool hasConductorVersion() => $_has(8);
   @$pb.TagNumber(10)
   void clearConductorVersion() => clearField(10);
+
+  @$pb.TagNumber(11)
+  $core.String get incrementLevel => $_getSZ(9);
+  @$pb.TagNumber(11)
+  set incrementLevel($core.String v) {
+    $_setString(9, v);
+  }
+
+  @$pb.TagNumber(11)
+  $core.bool hasIncrementLevel() => $_has(9);
+  @$pb.TagNumber(11)
+  void clearIncrementLevel() => clearField(11);
 }
diff --git a/dev/conductor/lib/proto/conductor_state.pbjson.dart b/dev/conductor/lib/proto/conductor_state.pbjson.dart
index 6f16e23..f35275d 100644
--- a/dev/conductor/lib/proto/conductor_state.pbjson.dart
+++ b/dev/conductor/lib/proto/conductor_state.pbjson.dart
@@ -101,9 +101,10 @@
     const {'1': 'logs', '3': 8, '4': 3, '5': 9, '10': 'logs'},
     const {'1': 'currentPhase', '3': 9, '4': 1, '5': 14, '6': '.conductor_state.ReleasePhase', '10': 'currentPhase'},
     const {'1': 'conductorVersion', '3': 10, '4': 1, '5': 9, '10': 'conductorVersion'},
+    const {'1': 'incrementLevel', '3': 11, '4': 1, '5': 9, '10': 'incrementLevel'},
   ],
 };
 
 /// Descriptor for `ConductorState`. Decode as a `google.protobuf.DescriptorProto`.
 final $typed_data.Uint8List conductorStateDescriptor = $convert.base64Decode(
-    'Cg5Db25kdWN0b3JTdGF0ZRImCg5yZWxlYXNlQ2hhbm5lbBgBIAEoCVIOcmVsZWFzZUNoYW5uZWwSJgoOcmVsZWFzZVZlcnNpb24YAiABKAlSDnJlbGVhc2VWZXJzaW9uEjMKBmVuZ2luZRgEIAEoCzIbLmNvbmR1Y3Rvcl9zdGF0ZS5SZXBvc2l0b3J5UgZlbmdpbmUSOQoJZnJhbWV3b3JrGAUgASgLMhsuY29uZHVjdG9yX3N0YXRlLlJlcG9zaXRvcnlSCWZyYW1ld29yaxIgCgtjcmVhdGVkRGF0ZRgGIAEoA1ILY3JlYXRlZERhdGUSKAoPbGFzdFVwZGF0ZWREYXRlGAcgASgDUg9sYXN0VXBkYXRlZERhdGUSEgoEbG9ncxgIIAMoCVIEbG9ncxJBCgxjdXJyZW50UGhhc2UYCSABKA4yHS5jb25kdWN0b3Jfc3RhdGUuUmVsZWFzZVBoYXNlUgxjdXJyZW50UGhhc2USKgoQY29uZHVjdG9yVmVyc2lvbhgKIAEoCVIQY29uZHVjdG9yVmVyc2lvbg==');
+    'Cg5Db25kdWN0b3JTdGF0ZRImCg5yZWxlYXNlQ2hhbm5lbBgBIAEoCVIOcmVsZWFzZUNoYW5uZWwSJgoOcmVsZWFzZVZlcnNpb24YAiABKAlSDnJlbGVhc2VWZXJzaW9uEjMKBmVuZ2luZRgEIAEoCzIbLmNvbmR1Y3Rvcl9zdGF0ZS5SZXBvc2l0b3J5UgZlbmdpbmUSOQoJZnJhbWV3b3JrGAUgASgLMhsuY29uZHVjdG9yX3N0YXRlLlJlcG9zaXRvcnlSCWZyYW1ld29yaxIgCgtjcmVhdGVkRGF0ZRgGIAEoA1ILY3JlYXRlZERhdGUSKAoPbGFzdFVwZGF0ZWREYXRlGAcgASgDUg9sYXN0VXBkYXRlZERhdGUSEgoEbG9ncxgIIAMoCVIEbG9ncxJBCgxjdXJyZW50UGhhc2UYCSABKA4yHS5jb25kdWN0b3Jfc3RhdGUuUmVsZWFzZVBoYXNlUgxjdXJyZW50UGhhc2USKgoQY29uZHVjdG9yVmVyc2lvbhgKIAEoCVIQY29uZHVjdG9yVmVyc2lvbhImCg5pbmNyZW1lbnRMZXZlbBgLIAEoCVIOaW5jcmVtZW50TGV2ZWw=');
diff --git a/dev/conductor/lib/proto/conductor_state.proto b/dev/conductor/lib/proto/conductor_state.proto
index 126f9c7..228bfa1 100644
--- a/dev/conductor/lib/proto/conductor_state.proto
+++ b/dev/conductor/lib/proto/conductor_state.proto
@@ -111,4 +111,7 @@
 
   // Commit hash of the Conductor tool.
   string conductorVersion = 10;
+
+  // One of x, y, z, m, or n.
+  string incrementLevel = 11;
 }
diff --git a/dev/conductor/lib/repository.dart b/dev/conductor/lib/repository.dart
index 3a12a4d..07aeab4 100644
--- a/dev/conductor/lib/repository.dart
+++ b/dev/conductor/lib/repository.dart
@@ -74,8 +74,10 @@
           'Fetch ${upstreamRemote.name} to ensure we have latest refs',
           workingDirectory: _checkoutDirectory!.path,
         );
+        // Note: if [initialRef] is a remote ref the checkout will be left in a
+        // detached HEAD state.
         git.run(
-          <String>['checkout', '${upstreamRemote.name}/$initialRef'],
+          <String>['checkout', initialRef!],
           'Checking out initialRef $initialRef',
           workingDirectory: _checkoutDirectory!.path,
         );
diff --git a/dev/conductor/lib/start.dart b/dev/conductor/lib/start.dart
index 932fd9b..b22f790 100644
--- a/dev/conductor/lib/start.dart
+++ b/dev/conductor/lib/start.dart
@@ -213,6 +213,7 @@
     state.releaseChannel = releaseChannel;
     state.createdDate = unixDate;
     state.lastUpdatedDate = unixDate;
+    state.incrementLevel = incrementLetter;
 
     final EngineRepository engine = EngineRepository(
       checkouts,
diff --git a/dev/conductor/lib/state.dart b/dev/conductor/lib/state.dart
index eb97d1a..c8167ac 100644
--- a/dev/conductor/lib/state.dart
+++ b/dev/conductor/lib/state.dart
@@ -43,10 +43,8 @@
   buffer.writeln('Release channel: ${state.releaseChannel}');
   buffer.writeln('Release version: ${state.releaseVersion}');
   buffer.writeln('');
-  buffer.writeln(
-      'Release started at: ${DateTime.fromMillisecondsSinceEpoch(state.createdDate.toInt())}');
-  buffer.writeln(
-      'Last updated at: ${DateTime.fromMillisecondsSinceEpoch(state.lastUpdatedDate.toInt())}');
+  buffer.writeln('Release started at: ${DateTime.fromMillisecondsSinceEpoch(state.createdDate.toInt())}');
+  buffer.writeln('Last updated at: ${DateTime.fromMillisecondsSinceEpoch(state.lastUpdatedDate.toInt())}');
   buffer.writeln('');
   buffer.writeln('Engine Repo');
   buffer.writeln('\tCandidate branch: ${state.engine.candidateBranch}');
@@ -128,15 +126,27 @@
       return <String>[
         'You must now manually apply the following engine cherrypicks to the checkout',
         'at ${state.engine.checkoutPath} in order:',
-        for (final pb.Cherrypick cherrypick in state.engine.cherrypicks)
-          '\t${cherrypick.trunkRevision}',
+        for (final pb.Cherrypick cherrypick in state.engine.cherrypicks) '\t${cherrypick.trunkRevision}',
         'See $kReleaseDocumentationUrl for more information.',
       ].join('\n');
     case ReleasePhase.CODESIGN_ENGINE_BINARIES:
+      if (!requiresEnginePR(state)) {
+        return 'You must now codesign the engine binaries for commit '
+            '${state.engine.startingGitHead}.';
+      }
+      // User's working branch was pushed to their mirror, but a PR needs to be
+      // opened on GitHub.
+      final String newPrLink = getNewPrLink(
+        userName: githubAccount(state.engine.mirror.url),
+        repoName: 'engine',
+        candidateBranch: state.engine.candidateBranch,
+        workingBranch: state.engine.workingBranch,
+      );
       return <String>[
-        'You must verify pre-submit CI builds on your engine pull request are successful,',
-        'merge your pull request, validate post-submit CI, and then codesign the binaries ',
-        'on the merge commit.',
+        'Your working branch ${state.engine.workingBranch} was pushed to your mirror.',
+        'You must now open a pull request at $newPrLink, verify pre-submit CI',
+        'builds on your engine pull request are successful, merge your pull request,',
+        'validate post-submit CI, and then codesign the binaries on the merge commit.',
       ].join('\n');
     case ReleasePhase.APPLY_FRAMEWORK_CHERRYPICKS:
       final List<pb.Cherrypick> outstandingCherrypicks = state.framework.cherrypicks.where(
@@ -144,17 +154,31 @@
           return cp.state == pb.CherrypickState.PENDING || cp.state == pb.CherrypickState.PENDING_WITH_CONFLICT;
         },
       ).toList();
-      return <String>[
-        'You must now manually apply the following framework cherrypicks to the checkout',
-        'at ${state.framework.checkoutPath} in order:',
-        for (final pb.Cherrypick cherrypick in outstandingCherrypicks)
-          '\t${cherrypick.trunkRevision}',
-      ].join('\n');
+      if (outstandingCherrypicks.isNotEmpty) {
+        return <String>[
+          'You must now manually apply the following framework cherrypicks to the checkout',
+          'at ${state.framework.checkoutPath} in order:',
+          for (final pb.Cherrypick cherrypick in outstandingCherrypicks) '\t${cherrypick.trunkRevision}',
+        ].join('\n');
+      }
+      return <String>['Either all cherrypicks have been auto-applied or there were none.'].join('\n');
     case ReleasePhase.PUBLISH_VERSION:
+      if (!requiresFrameworkPR(state)) {
+        return 'Since there are no code changes in this release, no Framework '
+            'PR is necessary.';
+      }
+
+      final String newPrLink = getNewPrLink(
+        userName: githubAccount(state.framework.mirror.url),
+        repoName: 'framework',
+        candidateBranch: state.framework.candidateBranch,
+        workingBranch: state.framework.workingBranch,
+      );
       return <String>[
-        'You must verify pre-submit CI builds on your framework pull request are successful,',
-        'merge your pull request, and validate post-submit CI. See $kReleaseDocumentationUrl,',
-        'for more information.',
+        'Your working branch ${state.framework.workingBranch} was pushed to your mirror.',
+        'You must now open a pull request at $newPrLink',
+        'verify pre-submit CI builds on your pull request are successful, merge your ',
+        'pull request, validate post-submit CI.',
       ].join('\n');
     case ReleasePhase.PUBLISH_CHANNEL:
       return 'Issue `conductor next` to publish your release to the release branch.';
@@ -163,8 +187,36 @@
     case ReleasePhase.RELEASE_COMPLETED:
       return 'This release has been completed.';
   }
-  assert(false);
-  return ''; // For analyzer
+  // For analyzer
+  throw ConductorException('Unimplemented phase ${state.currentPhase}');
+}
+
+/// Regex pattern for git remote host URLs.
+///
+/// First group = git host (currently must be github.com)
+/// Second group = account name
+/// Third group = repo name
+final RegExp githubRemotePattern =
+    RegExp(r'^(git@github\.com:|https?:\/\/github\.com\/)([a-zA-Z0-9_-]+)\/([a-zA-Z0-9_-]+)(\.git)?$');
+
+/// Parses a Git remote URL and returns the account name.
+///
+/// Uses [githubRemotePattern].
+String githubAccount(String remoteUrl) {
+  final String engineUrl = remoteUrl;
+  final RegExpMatch? match = githubRemotePattern.firstMatch(engineUrl);
+  if (match == null) {
+    throw ConductorException(
+      'Cannot determine the GitHub account from $engineUrl',
+    );
+  }
+  final String? accountName = match.group(2);
+  if (accountName == null || accountName.isEmpty) {
+    throw ConductorException(
+      'Cannot determine the GitHub account from $match',
+    );
+  }
+  return accountName;
 }
 
 /// Returns the next phase in the ReleasePhase enum.
@@ -196,3 +248,38 @@
   );
   return state;
 }
+
+/// This release will require a new Engine PR.
+///
+/// The logic is if there are engine cherrypicks that have not been abandoned OR
+/// there is a new Dart revision, then return true, else false.
+bool requiresEnginePR(pb.ConductorState state) {
+  final bool hasRequiredCherrypicks = state.engine.cherrypicks.any(
+    (pb.Cherrypick cp) => cp.state != pb.CherrypickState.ABANDONED,
+  );
+  if (hasRequiredCherrypicks) {
+    return true;
+  }
+  return state.engine.dartRevision.isNotEmpty;
+}
+
+/// This release will require a new Framework PR.
+///
+/// The logic is if there was an Engine PR OR there are framework cherrypicks
+/// that have not been abandoned OR the increment level is 'm', then return
+/// true, else false.
+bool requiresFrameworkPR(pb.ConductorState state) {
+  if (requiresEnginePR(state)) {
+    return true;
+  }
+  final bool hasRequiredCherrypicks =
+      state.framework.cherrypicks.any((pb.Cherrypick cp) => cp.state != pb.CherrypickState.ABANDONED);
+  if (hasRequiredCherrypicks) {
+    return true;
+  }
+  if (state.incrementLevel == 'm') {
+    // requires an update to .ci.yaml
+    return true;
+  }
+  return false;
+}
diff --git a/dev/conductor/lib/stdio.dart b/dev/conductor/lib/stdio.dart
index a909996..9076511 100644
--- a/dev/conductor/lib/stdio.dart
+++ b/dev/conductor/lib/stdio.dart
@@ -46,10 +46,10 @@
   });
 
   factory VerboseStdio.local() => VerboseStdio(
-    stdout: io.stdout,
-    stderr: io.stderr,
-    stdin: io.stdin,
-  );
+        stdout: io.stdout,
+        stderr: io.stderr,
+        stdin: io.stdin,
+      );
 
   final io.Stdout stdout;
   final io.Stdout stderr;
diff --git a/dev/conductor/test/next_test.dart b/dev/conductor/test/next_test.dart
index e991dc4..b519c38 100644
--- a/dev/conductor/test/next_test.dart
+++ b/dev/conductor/test/next_test.dart
@@ -89,6 +89,9 @@
         );
         final pb.ConductorState state = pb.ConductorState(
           currentPhase: ReleasePhase.APPLY_ENGINE_CHERRYPICKS,
+          engine: pb.Repository(
+            startingGitHead: revision1,
+          ),
         );
         writeStateToFile(
           fileSystem.file(stateFile),
@@ -116,10 +119,13 @@
         expect(processManager, hasNoRemainingExpectations);
         expect(finalState.currentPhase, ReleasePhase.CODESIGN_ENGINE_BINARIES);
         expect(stdio.error, isEmpty);
+        expect(
+          stdio.stdout,
+          contains('You must now codesign the engine binaries for commit $revision1'));
       });
 
       test('confirms to stdout when all engine cherrypicks were auto-applied', () async {
-        const String remoteUrl = 'https://githost.com/org/repo.git';
+        const String remoteUrl = 'https://github.com/org/repo.git';
         stdio.stdin.add('n');
         final FakeProcessManager processManager = FakeProcessManager.empty();
         final FakePlatform platform = FakePlatform(
@@ -170,13 +176,14 @@
       });
 
       test('updates lastPhase if user responds yes', () async {
-        const String remoteUrl = 'https://githost.com/org/repo.git';
+        const String remoteUrl = 'https://github.com/org/repo.git';
+        const String releaseChannel = 'dev';
         stdio.stdin.add('y');
         final FakeProcessManager processManager = FakeProcessManager.list(<FakeCommand>[
           const FakeCommand(
             command: <String>['git', 'fetch', 'upstream'],
           ),
-          const FakeCommand(command: <String>['git', 'checkout', 'upstream/$workingBranch']),
+          const FakeCommand(command: <String>['git', 'checkout', workingBranch]),
           const FakeCommand(
             command: <String>['git', 'rev-parse', 'HEAD'],
             stdout: revision1,
@@ -191,7 +198,9 @@
           pathSeparator: localPathSeparator,
         );
         final pb.ConductorState state = pb.ConductorState(
+          currentPhase: ReleasePhase.APPLY_ENGINE_CHERRYPICKS,
           engine: pb.Repository(
+            candidateBranch: candidateBranch,
             cherrypicks: <pb.Cherrypick>[
               pb.Cherrypick(
                 trunkRevision: 'abc123',
@@ -202,7 +211,7 @@
             upstream: pb.Remote(name: 'upstream', url: remoteUrl),
             mirror: pb.Remote(name: 'mirror', url: remoteUrl),
           ),
-          currentPhase: ReleasePhase.APPLY_ENGINE_CHERRYPICKS,
+          releaseChannel: releaseChannel,
         );
         writeStateToFile(
           fileSystem.file(stateFile),
@@ -228,6 +237,9 @@
         );
 
         expect(processManager, hasNoRemainingExpectations);
+        expect(
+          stdio.stdout,
+          contains('You must now open a pull request at https://github.com/flutter/engine/compare/flutter-1.2-candidate.3...org:cherrypicks-flutter-1.2-candidate.3?expand=1'));
         expect(stdio.stdout, contains(
                 'Are you ready to push your engine branch to the repository $remoteUrl? (y/n) '));
         expect(finalState.currentPhase, ReleasePhase.CODESIGN_ENGINE_BINARIES);
@@ -332,9 +344,9 @@
     });
 
     group('APPLY_FRAMEWORK_CHERRYPICKS to PUBLISH_VERSION', () {
-      const String mirrorRemoteUrl = 'https://githost.com/org/repo.git';
-      const String upstreamRemoteUrl = 'https://githost.com/mirror/repo.git';
-      const String engineUpstreamRemoteUrl = 'https://githost.com/mirror/engine.git';
+      const String mirrorRemoteUrl = 'https://github.com/org/repo.git';
+      const String upstreamRemoteUrl = 'https://github.com/mirror/repo.git';
+      const String engineUpstreamRemoteUrl = 'https://github.com/mirror/engine.git';
       const String frameworkCheckoutPath = '$checkoutsParentDirectory/framework';
       const String engineCheckoutPath = '$checkoutsParentDirectory/engine';
       const String oldEngineVersion = '000000001';
@@ -441,13 +453,14 @@
         stdio.stdin.add('n');
         processManager.addCommands(const <FakeCommand>[
           FakeCommand(command: <String>['git', 'fetch', 'upstream']),
+          // we want merged upstream commit, not local working commit
           FakeCommand(command: <String>['git', 'checkout', 'upstream/$candidateBranch']),
           FakeCommand(
             command: <String>['git', 'rev-parse', 'HEAD'],
             stdout: revision1,
           ),
           FakeCommand(command: <String>['git', 'fetch', 'upstream']),
-          FakeCommand(command: <String>['git', 'checkout', 'upstream/$workingBranch']),
+          FakeCommand(command: <String>['git', 'checkout', workingBranch]),
           FakeCommand(
             command: <String>['git', 'rev-parse', 'HEAD'],
             stdout: revision2,
@@ -509,13 +522,14 @@
         stdio.stdin.add('n');
         processManager.addCommands(const <FakeCommand>[
           FakeCommand(command: <String>['git', 'fetch', 'upstream']),
+          // we want merged upstream commit, not local working commit
           FakeCommand(command: <String>['git', 'checkout', 'upstream/$candidateBranch']),
           FakeCommand(
             command: <String>['git', 'rev-parse', 'HEAD'],
             stdout: revision1,
           ),
           FakeCommand(command: <String>['git', 'fetch', 'upstream']),
-          FakeCommand(command: <String>['git', 'checkout', 'upstream/$workingBranch']),
+          FakeCommand(command: <String>['git', 'checkout', workingBranch]),
           FakeCommand(
             command: <String>['git', 'rev-parse', 'HEAD'],
             stdout: revision2,
@@ -564,6 +578,7 @@
         processManager.addCommands(const <FakeCommand>[
           // Engine repo
           FakeCommand(command: <String>['git', 'fetch', 'upstream']),
+          // we want merged upstream commit, not local working commit
           FakeCommand(command: <String>['git', 'checkout', 'upstream/$candidateBranch']),
           FakeCommand(
             command: <String>['git', 'rev-parse', 'HEAD'],
@@ -571,7 +586,7 @@
           ),
           // Framework repo
           FakeCommand(command: <String>['git', 'fetch', 'upstream']),
-          FakeCommand(command: <String>['git', 'checkout', 'upstream/$workingBranch']),
+          FakeCommand(command: <String>['git', 'checkout', workingBranch]),
           FakeCommand(
             command: <String>['git', 'rev-parse', 'HEAD'],
             stdout: revision2,
diff --git a/dev/conductor/test/start_test.dart b/dev/conductor/test/start_test.dart
index 1eb2826..24937d4 100644
--- a/dev/conductor/test/start_test.dart
+++ b/dev/conductor/test/start_test.dart
@@ -115,6 +115,7 @@
       const String nextDartRevision = 'f6c91128be6b77aef8351e1e3a9d07c85bc2e46e';
       const String previousVersion = '1.2.0-1.0.pre';
       const String nextVersion = '1.2.0-3.0.pre';
+      const String incrementLevel = 'm';
 
       final Directory engine = fileSystem.directory(checkoutsParentDirectory)
           .childDirectory('flutter_conductor_checkouts')
@@ -261,7 +262,7 @@
         '--$kDartRevisionOption',
         nextDartRevision,
         '--$kIncrementOption',
-        'm',
+        incrementLevel,
       ]);
 
       final File stateFile = fileSystem.file(stateFilePath);
@@ -281,6 +282,7 @@
       expect(state.framework.startingGitHead, revision3);
       expect(state.currentPhase, ReleasePhase.APPLY_ENGINE_CHERRYPICKS);
       expect(state.conductorVersion, revision);
+      expect(state.incrementLevel, incrementLevel);
     });
   }, onPlatform: <String, dynamic>{
     'windows': const Skip('Flutter Conductor only supported on macos/linux'),