Process docs as stable on release candidate branches.

The api documentation are processed differently for master and stable.
This change will process api docs as stable for all the release
candidate branches. This is required to be able to post-process only the
version before releasing to firebase.

Bug: https://github.com/flutter/flutter/issues/114900
Bug: https://github.com/flutter/flutter/issues/114795
Change-Id: Ia8539b8ee529ec69148aa1b41f77a8014fc36192
Reviewed-on: https://flutter-review.googlesource.com/c/recipes/+/35881
Reviewed-by: Casey Hillers <chillers@google.com>
Commit-Queue: Godofredo Contreras <godofredoc@google.com>
diff --git a/recipe_modules/adhoc_validation/api.py b/recipe_modules/adhoc_validation/api.py
index fd0869c..00b0af9 100644
--- a/recipe_modules/adhoc_validation/api.py
+++ b/recipe_modules/adhoc_validation/api.py
@@ -62,6 +62,13 @@
               timeout_secs=4500 # 75 minutes
             )
       else:
+        # Override LUCI_BRANCH for docs and release candidate branches. Docs built from
+        # release candidate branches need to be build as stable to ensure they are processed
+        # correctly.
+        checkout_path = self.m.repo_util.sdk_checkout_path()
+        if (validation == 'docs') and self.m.repo_util.is_release_candidate_branch(checkout_path):
+          env['LUCI_BRANCH'] = 'stable'
+
         with self.m.context(env=env, env_prefixes=env_prefixes):
           self.m.test_utils.run_test(
             validation,
diff --git a/recipe_modules/adhoc_validation/examples/full.expected/docs.json b/recipe_modules/adhoc_validation/examples/full.expected/docs.json
new file mode 100644
index 0000000..04b0bbb
--- /dev/null
+++ b/recipe_modules/adhoc_validation/examples/full.expected/docs.json
@@ -0,0 +1,209 @@
+[
+  {
+    "cmd": [
+      "git",
+      "rev-parse",
+      "HEAD"
+    ],
+    "cwd": "[START_DIR]/flutter sdk",
+    "infra_step": true,
+    "name": "git rev-parse"
+  },
+  {
+    "cmd": [],
+    "name": "Docs"
+  },
+  {
+    "cmd": [
+      "chmod",
+      "755",
+      "RECIPE_MODULE[flutter::adhoc_validation]/resources/docs.sh"
+    ],
+    "env": {
+      "DEPOT_TOOLS": "RECIPE_REPO[depot_tools]",
+      "GIT_BRANCH": "",
+      "LUCI_BRANCH": "",
+      "LUCI_CI": "True",
+      "LUCI_PR": "",
+      "OS": "linux",
+      "PUB_CACHE": "[START_DIR]/.pub-cache",
+      "REVISION": "12345abcde12345abcde12345abcde12345abcde",
+      "SDK_CHECKOUT_PATH": "[START_DIR]/flutter sdk"
+    },
+    "env_prefixes": {
+      "PATH": [
+        "[START_DIR]/flutter sdk/bin",
+        "[START_DIR]/flutter sdk/bin/cache/dart-sdk/bin"
+      ]
+    },
+    "infra_step": true,
+    "name": "Docs.Set execute permission",
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@"
+    ]
+  },
+  {
+    "cmd": [],
+    "name": "Docs.Identify branches",
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@"
+    ]
+  },
+  {
+    "cmd": [
+      "git",
+      "rev-parse",
+      "HEAD"
+    ],
+    "cwd": "[START_DIR]/flutter sdk",
+    "env": {
+      "DEPOT_TOOLS": "RECIPE_REPO[depot_tools]",
+      "GIT_BRANCH": "",
+      "LUCI_BRANCH": "",
+      "LUCI_CI": "True",
+      "LUCI_PR": "",
+      "OS": "linux",
+      "PUB_CACHE": "[START_DIR]/.pub-cache",
+      "REVISION": "12345abcde12345abcde12345abcde12345abcde",
+      "SDK_CHECKOUT_PATH": "[START_DIR]/flutter sdk"
+    },
+    "env_prefixes": {
+      "PATH": [
+        "[START_DIR]/flutter sdk/bin",
+        "[START_DIR]/flutter sdk/bin/cache/dart-sdk/bin"
+      ]
+    },
+    "infra_step": true,
+    "name": "Docs.Identify branches.git rev-parse",
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@2@@@"
+    ]
+  },
+  {
+    "cmd": [
+      "git",
+      "branch",
+      "-a",
+      "--contains",
+      "12345abcde12345abcde12345abcde12345abcde"
+    ],
+    "cwd": "[START_DIR]/flutter sdk",
+    "env": {
+      "DEPOT_TOOLS": "RECIPE_REPO[depot_tools]",
+      "GIT_BRANCH": "",
+      "LUCI_BRANCH": "",
+      "LUCI_CI": "True",
+      "LUCI_PR": "",
+      "OS": "linux",
+      "PUB_CACHE": "[START_DIR]/.pub-cache",
+      "REVISION": "12345abcde12345abcde12345abcde12345abcde",
+      "SDK_CHECKOUT_PATH": "[START_DIR]/flutter sdk"
+    },
+    "env_prefixes": {
+      "PATH": [
+        "[START_DIR]/flutter sdk/bin",
+        "[START_DIR]/flutter sdk/bin/cache/dart-sdk/bin"
+      ]
+    },
+    "infra_step": true,
+    "name": "Docs.Identify branches.git branch",
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@2@@@"
+    ]
+  },
+  {
+    "cmd": [
+      "RECIPE_MODULE[flutter::adhoc_validation]/resources/docs.sh"
+    ],
+    "env": {
+      "DEPOT_TOOLS": "RECIPE_REPO[depot_tools]",
+      "GIT_BRANCH": "",
+      "LUCI_BRANCH": "stable",
+      "LUCI_CI": "True",
+      "LUCI_PR": "",
+      "OS": "linux",
+      "PUB_CACHE": "[START_DIR]/.pub-cache",
+      "REVISION": "12345abcde12345abcde12345abcde12345abcde",
+      "SDK_CHECKOUT_PATH": "[START_DIR]/flutter sdk"
+    },
+    "env_prefixes": {
+      "PATH": [
+        "[START_DIR]/flutter sdk/bin",
+        "[START_DIR]/flutter sdk/bin/cache/dart-sdk/bin"
+      ]
+    },
+    "name": "Docs.docs",
+    "timeout": 4500,
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@",
+      "@@@STEP_LOG_LINE@test_stdout@@@@",
+      "@@@STEP_LOG_END@test_stdout@@@",
+      "@@@STEP_LOG_LINE@test_stderr@@@@",
+      "@@@STEP_LOG_END@test_stderr@@@"
+    ]
+  },
+  {
+    "cmd": [
+      "python",
+      "RECIPE_MODULE[flutter::zip]/resources/zip.py"
+    ],
+    "env": {
+      "DEPOT_TOOLS": "RECIPE_REPO[depot_tools]",
+      "GIT_BRANCH": "",
+      "LUCI_BRANCH": "stable",
+      "LUCI_CI": "True",
+      "LUCI_PR": "",
+      "OS": "linux",
+      "PUB_CACHE": "[START_DIR]/.pub-cache",
+      "REVISION": "12345abcde12345abcde12345abcde12345abcde",
+      "SDK_CHECKOUT_PATH": "[START_DIR]/flutter sdk"
+    },
+    "env_prefixes": {
+      "PATH": [
+        "[START_DIR]/flutter sdk/bin",
+        "[START_DIR]/flutter sdk/bin/cache/dart-sdk/bin"
+      ]
+    },
+    "name": "Docs.Zip doc",
+    "stdin": "{\"entries\": [{\"path\": \"[START_DIR]/flutter sdk/dev/docs/doc\", \"type\": \"dir\"}], \"output\": \"[CLEANUP]/tmp_tmp_1/api_docs.zip\", \"root\": \"[START_DIR]/flutter sdk/dev/docs\"}",
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@"
+    ]
+  },
+  {
+    "cmd": [
+      "vpython3",
+      "-u",
+      "RECIPE_MODULE[recipe_engine::file]/resources/fileutil.py",
+      "--json-output",
+      "/path/to/tmp/json",
+      "rmtree",
+      "[CLEANUP]/tmp_tmp_1"
+    ],
+    "env": {
+      "DEPOT_TOOLS": "RECIPE_REPO[depot_tools]",
+      "GIT_BRANCH": "",
+      "LUCI_BRANCH": "stable",
+      "LUCI_CI": "True",
+      "LUCI_PR": "",
+      "OS": "linux",
+      "PUB_CACHE": "[START_DIR]/.pub-cache",
+      "REVISION": "12345abcde12345abcde12345abcde12345abcde",
+      "SDK_CHECKOUT_PATH": "[START_DIR]/flutter sdk"
+    },
+    "env_prefixes": {
+      "PATH": [
+        "[START_DIR]/flutter sdk/bin",
+        "[START_DIR]/flutter sdk/bin/cache/dart-sdk/bin"
+      ]
+    },
+    "infra_step": true,
+    "name": "Docs.temp dir for Upload API Docs",
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@"
+    ]
+  },
+  {
+    "name": "$result"
+  }
+]
\ No newline at end of file
diff --git a/recipe_modules/adhoc_validation/examples/full.expected/invalid_validation.json b/recipe_modules/adhoc_validation/examples/full.expected/invalid_validation.json
index d298e25..d3ad326 100644
--- a/recipe_modules/adhoc_validation/examples/full.expected/invalid_validation.json
+++ b/recipe_modules/adhoc_validation/examples/full.expected/invalid_validation.json
@@ -17,7 +17,7 @@
       "The recipe has crashed at point 'Uncaught exception'!",
       "",
       "Traceback (most recent call last):",
-      "  File \"RECIPE_REPO[flutter]/recipe_modules/adhoc_validation/examples/full.py\", line 23, in RunSteps",
+      "  File \"RECIPE_REPO[flutter]/recipe_modules/adhoc_validation/examples/full.py\", line 24, in RunSteps",
       "    api.adhoc_validation.run('Docs', validation, {}, {})",
       "  File \"RECIPE_REPO[flutter]/recipe_modules/adhoc_validation/api.py\", line 36, in run",
       "    raise AssertionError(msg)",
diff --git a/recipe_modules/adhoc_validation/examples/full.expected/linux.json b/recipe_modules/adhoc_validation/examples/full.expected/linux.json
index 71c7a4a..c862c79 100644
--- a/recipe_modules/adhoc_validation/examples/full.expected/linux.json
+++ b/recipe_modules/adhoc_validation/examples/full.expected/linux.json
@@ -43,6 +43,75 @@
     ]
   },
   {
+    "cmd": [],
+    "name": "Docs.Identify branches",
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@"
+    ]
+  },
+  {
+    "cmd": [
+      "git",
+      "rev-parse",
+      "HEAD"
+    ],
+    "cwd": "[START_DIR]/flutter sdk",
+    "env": {
+      "DEPOT_TOOLS": "RECIPE_REPO[depot_tools]",
+      "GIT_BRANCH": "main",
+      "LUCI_BRANCH": "",
+      "LUCI_CI": "True",
+      "LUCI_PR": "",
+      "OS": "linux",
+      "PUB_CACHE": "[START_DIR]/.pub-cache",
+      "REVISION": "12345abcde12345abcde12345abcde12345abcde",
+      "SDK_CHECKOUT_PATH": "[START_DIR]/flutter sdk"
+    },
+    "env_prefixes": {
+      "PATH": [
+        "[START_DIR]/flutter sdk/bin",
+        "[START_DIR]/flutter sdk/bin/cache/dart-sdk/bin"
+      ]
+    },
+    "infra_step": true,
+    "name": "Docs.Identify branches.git rev-parse",
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@2@@@"
+    ]
+  },
+  {
+    "cmd": [
+      "git",
+      "branch",
+      "-a",
+      "--contains",
+      "12345abcde12345abcde12345abcde12345abcde"
+    ],
+    "cwd": "[START_DIR]/flutter sdk",
+    "env": {
+      "DEPOT_TOOLS": "RECIPE_REPO[depot_tools]",
+      "GIT_BRANCH": "main",
+      "LUCI_BRANCH": "",
+      "LUCI_CI": "True",
+      "LUCI_PR": "",
+      "OS": "linux",
+      "PUB_CACHE": "[START_DIR]/.pub-cache",
+      "REVISION": "12345abcde12345abcde12345abcde12345abcde",
+      "SDK_CHECKOUT_PATH": "[START_DIR]/flutter sdk"
+    },
+    "env_prefixes": {
+      "PATH": [
+        "[START_DIR]/flutter sdk/bin",
+        "[START_DIR]/flutter sdk/bin/cache/dart-sdk/bin"
+      ]
+    },
+    "infra_step": true,
+    "name": "Docs.Identify branches.git branch",
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@2@@@"
+    ]
+  },
+  {
     "cmd": [
       "RECIPE_MODULE[flutter::adhoc_validation]/resources/docs.sh"
     ],
diff --git a/recipe_modules/adhoc_validation/examples/full.expected/mac_nodeps.json b/recipe_modules/adhoc_validation/examples/full.expected/mac_nodeps.json
index 21f78a3..033961d 100644
--- a/recipe_modules/adhoc_validation/examples/full.expected/mac_nodeps.json
+++ b/recipe_modules/adhoc_validation/examples/full.expected/mac_nodeps.json
@@ -43,6 +43,75 @@
     ]
   },
   {
+    "cmd": [],
+    "name": "Docs.Identify branches",
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@"
+    ]
+  },
+  {
+    "cmd": [
+      "git",
+      "rev-parse",
+      "HEAD"
+    ],
+    "cwd": "[START_DIR]/flutter sdk",
+    "env": {
+      "DEPOT_TOOLS": "RECIPE_REPO[depot_tools]",
+      "GIT_BRANCH": "",
+      "LUCI_BRANCH": "",
+      "LUCI_CI": "True",
+      "LUCI_PR": "",
+      "OS": "darwin",
+      "PUB_CACHE": "[START_DIR]/.pub-cache",
+      "REVISION": "12345abcde12345abcde12345abcde12345abcde",
+      "SDK_CHECKOUT_PATH": "[START_DIR]/flutter sdk"
+    },
+    "env_prefixes": {
+      "PATH": [
+        "[START_DIR]/flutter sdk/bin",
+        "[START_DIR]/flutter sdk/bin/cache/dart-sdk/bin"
+      ]
+    },
+    "infra_step": true,
+    "name": "Docs.Identify branches.git rev-parse",
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@2@@@"
+    ]
+  },
+  {
+    "cmd": [
+      "git",
+      "branch",
+      "-a",
+      "--contains",
+      "12345abcde12345abcde12345abcde12345abcde"
+    ],
+    "cwd": "[START_DIR]/flutter sdk",
+    "env": {
+      "DEPOT_TOOLS": "RECIPE_REPO[depot_tools]",
+      "GIT_BRANCH": "",
+      "LUCI_BRANCH": "",
+      "LUCI_CI": "True",
+      "LUCI_PR": "",
+      "OS": "darwin",
+      "PUB_CACHE": "[START_DIR]/.pub-cache",
+      "REVISION": "12345abcde12345abcde12345abcde12345abcde",
+      "SDK_CHECKOUT_PATH": "[START_DIR]/flutter sdk"
+    },
+    "env_prefixes": {
+      "PATH": [
+        "[START_DIR]/flutter sdk/bin",
+        "[START_DIR]/flutter sdk/bin/cache/dart-sdk/bin"
+      ]
+    },
+    "infra_step": true,
+    "name": "Docs.Identify branches.git branch",
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@2@@@"
+    ]
+  },
+  {
     "cmd": [
       "RECIPE_MODULE[flutter::adhoc_validation]/resources/docs.sh"
     ],
diff --git a/recipe_modules/adhoc_validation/examples/full.expected/win.json b/recipe_modules/adhoc_validation/examples/full.expected/win.json
index 95a87dd..7e119f5 100644
--- a/recipe_modules/adhoc_validation/examples/full.expected/win.json
+++ b/recipe_modules/adhoc_validation/examples/full.expected/win.json
@@ -14,6 +14,75 @@
     "name": "Docs"
   },
   {
+    "cmd": [],
+    "name": "Docs.Identify branches",
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@"
+    ]
+  },
+  {
+    "cmd": [
+      "git",
+      "rev-parse",
+      "HEAD"
+    ],
+    "cwd": "[START_DIR]\\flutter sdk",
+    "env": {
+      "DEPOT_TOOLS": "RECIPE_REPO[depot_tools]",
+      "GIT_BRANCH": "",
+      "LUCI_BRANCH": "",
+      "LUCI_CI": "True",
+      "LUCI_PR": "",
+      "OS": "win",
+      "PUB_CACHE": "[START_DIR]\\.pub-cache",
+      "REVISION": "12345abcde12345abcde12345abcde12345abcde",
+      "SDK_CHECKOUT_PATH": "[START_DIR]\\flutter sdk"
+    },
+    "env_prefixes": {
+      "PATH": [
+        "[START_DIR]\\flutter sdk\\bin",
+        "[START_DIR]\\flutter sdk\\bin\\cache\\dart-sdk\\bin"
+      ]
+    },
+    "infra_step": true,
+    "name": "Docs.Identify branches.git rev-parse",
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@2@@@"
+    ]
+  },
+  {
+    "cmd": [
+      "git",
+      "branch",
+      "-a",
+      "--contains",
+      "12345abcde12345abcde12345abcde12345abcde"
+    ],
+    "cwd": "[START_DIR]\\flutter sdk",
+    "env": {
+      "DEPOT_TOOLS": "RECIPE_REPO[depot_tools]",
+      "GIT_BRANCH": "",
+      "LUCI_BRANCH": "",
+      "LUCI_CI": "True",
+      "LUCI_PR": "",
+      "OS": "win",
+      "PUB_CACHE": "[START_DIR]\\.pub-cache",
+      "REVISION": "12345abcde12345abcde12345abcde12345abcde",
+      "SDK_CHECKOUT_PATH": "[START_DIR]\\flutter sdk"
+    },
+    "env_prefixes": {
+      "PATH": [
+        "[START_DIR]\\flutter sdk\\bin",
+        "[START_DIR]\\flutter sdk\\bin\\cache\\dart-sdk\\bin"
+      ]
+    },
+    "infra_step": true,
+    "name": "Docs.Identify branches.git branch",
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@2@@@"
+    ]
+  },
+  {
     "cmd": [
       "RECIPE_MODULE[flutter::adhoc_validation]\\resources\\docs.bat"
     ],
diff --git a/recipe_modules/adhoc_validation/examples/full.py b/recipe_modules/adhoc_validation/examples/full.py
index 5aacd56..239c8c2 100644
--- a/recipe_modules/adhoc_validation/examples/full.py
+++ b/recipe_modules/adhoc_validation/examples/full.py
@@ -11,6 +11,7 @@
     'recipe_engine/path',
     'recipe_engine/platform',
     'recipe_engine/properties',
+    'recipe_engine/raw_io',
 ]
 
 
@@ -48,3 +49,13 @@
       api.expect_exception('AssertionError'),
       api.repo_util.flutter_environment_data(checkout_path)
   )
+  yield api.test(
+      'docs', api.platform.name('linux'),
+      api.properties(firebase_project='myproject',
+                     git_branch=''),
+      api.repo_util.flutter_environment_data(checkout_path),
+      api.step_data(
+          'Docs.Identify branches.git branch',
+          stdout=api.raw_io.output_text('branch1\nbranch2\nflutter-3.2-candidate.5')
+      ),
+  )
diff --git a/recipe_modules/repo_util/api.py b/recipe_modules/repo_util/api.py
index 8e802e5..9a40b57 100644
--- a/recipe_modules/repo_util/api.py
+++ b/recipe_modules/repo_util/api.py
@@ -415,3 +415,11 @@
     checkout_path = self.m.context.env.get('SDK_CHECKOUT_PATH')
     assert checkout_path, 'Outside of a flutter_environment?'
     return self.m.path.abs_to_path(checkout_path)
+
+  def is_release_candidate_branch(self, checkout_path):
+    """Returns true if the branch starts with "flutter-"."""
+    commit_branches = self.current_commit_branches(checkout_path)
+    for branch in commit_branches:
+     if branch.startswith('flutter-'):
+         return True
+    return False
diff --git a/recipe_modules/repo_util/examples/full.expected/basic.json b/recipe_modules/repo_util/examples/full.expected/basic.json
index 9ec8dcb..74a95a4 100644
--- a/recipe_modules/repo_util/examples/full.expected/basic.json
+++ b/recipe_modules/repo_util/examples/full.expected/basic.json
@@ -33,6 +33,38 @@
   },
   {
     "cmd": [],
+    "name": "Identify branches (2)"
+  },
+  {
+    "cmd": [
+      "git",
+      "rev-parse",
+      "HEAD"
+    ],
+    "cwd": "[START_DIR]/flutter",
+    "infra_step": true,
+    "name": "Identify branches (2).git rev-parse",
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@"
+    ]
+  },
+  {
+    "cmd": [
+      "git",
+      "branch",
+      "-a",
+      "--contains",
+      "12345abcde12345abcde12345abcde12345abcde"
+    ],
+    "cwd": "[START_DIR]/flutter",
+    "infra_step": true,
+    "name": "Identify branches (2).git branch",
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@"
+    ]
+  },
+  {
+    "cmd": [],
     "name": "Checkout flutter/flutter"
   },
   {
@@ -597,38 +629,6 @@
   },
   {
     "cmd": [],
-    "name": "Identify branches (2)"
-  },
-  {
-    "cmd": [
-      "git",
-      "rev-parse",
-      "HEAD"
-    ],
-    "cwd": "[START_DIR]/flutter/flutter",
-    "infra_step": true,
-    "name": "Identify branches (2).git rev-parse",
-    "~followup_annotations": [
-      "@@@STEP_NEST_LEVEL@1@@@"
-    ]
-  },
-  {
-    "cmd": [
-      "git",
-      "branch",
-      "-a",
-      "--contains",
-      "12345abcde12345abcde12345abcde12345abcde"
-    ],
-    "cwd": "[START_DIR]/flutter/flutter",
-    "infra_step": true,
-    "name": "Identify branches (2).git branch",
-    "~followup_annotations": [
-      "@@@STEP_NEST_LEVEL@1@@@"
-    ]
-  },
-  {
-    "cmd": [],
     "name": "Identify branches (3)"
   },
   {
@@ -637,7 +637,7 @@
       "rev-parse",
       "HEAD"
     ],
-    "cwd": "[START_DIR]/flutter",
+    "cwd": "[START_DIR]/flutter/flutter",
     "infra_step": true,
     "name": "Identify branches (3).git rev-parse",
     "~followup_annotations": [
@@ -652,7 +652,7 @@
       "--contains",
       "12345abcde12345abcde12345abcde12345abcde"
     ],
-    "cwd": "[START_DIR]/flutter",
+    "cwd": "[START_DIR]/flutter/flutter",
     "infra_step": true,
     "name": "Identify branches (3).git branch",
     "~followup_annotations": [
@@ -660,16 +660,6 @@
     ]
   },
   {
-    "cmd": [
-      "git",
-      "rev-parse",
-      "HEAD"
-    ],
-    "cwd": "[START_DIR]/flutter",
-    "infra_step": true,
-    "name": "git rev-parse"
-  },
-  {
     "cmd": [],
     "name": "Identify branches (4)"
   },
@@ -703,6 +693,48 @@
   },
   {
     "cmd": [
+      "git",
+      "rev-parse",
+      "HEAD"
+    ],
+    "cwd": "[START_DIR]/flutter",
+    "infra_step": true,
+    "name": "git rev-parse"
+  },
+  {
+    "cmd": [],
+    "name": "Identify branches (5)"
+  },
+  {
+    "cmd": [
+      "git",
+      "rev-parse",
+      "HEAD"
+    ],
+    "cwd": "[START_DIR]/flutter",
+    "infra_step": true,
+    "name": "Identify branches (5).git rev-parse",
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@"
+    ]
+  },
+  {
+    "cmd": [
+      "git",
+      "branch",
+      "-a",
+      "--contains",
+      "12345abcde12345abcde12345abcde12345abcde"
+    ],
+    "cwd": "[START_DIR]/flutter",
+    "infra_step": true,
+    "name": "Identify branches (5).git branch",
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@"
+    ]
+  },
+  {
+    "cmd": [
       "vpython3",
       "-u",
       "RECIPE_MODULE[recipe_engine::file]/resources/fileutil.py",
diff --git a/recipe_modules/repo_util/examples/full.expected/bot_update.json b/recipe_modules/repo_util/examples/full.expected/bot_update.json
index a933cf9..aa27bf9 100644
--- a/recipe_modules/repo_util/examples/full.expected/bot_update.json
+++ b/recipe_modules/repo_util/examples/full.expected/bot_update.json
@@ -1,6 +1,38 @@
 [
   {
     "cmd": [],
+    "name": "Identify branches"
+  },
+  {
+    "cmd": [
+      "git",
+      "rev-parse",
+      "HEAD"
+    ],
+    "cwd": "[START_DIR]/flutter",
+    "infra_step": true,
+    "name": "Identify branches.git rev-parse",
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@"
+    ]
+  },
+  {
+    "cmd": [
+      "git",
+      "branch",
+      "-a",
+      "--contains",
+      "12345abcde12345abcde12345abcde12345abcde"
+    ],
+    "cwd": "[START_DIR]/flutter",
+    "infra_step": true,
+    "name": "Identify branches.git branch",
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@"
+    ]
+  },
+  {
+    "cmd": [],
     "name": "Checkout flutter/flutter"
   },
   {
diff --git a/recipe_modules/repo_util/examples/full.expected/failed_flutter_environment.json b/recipe_modules/repo_util/examples/full.expected/failed_flutter_environment.json
index ed44b07..6ed758f 100644
--- a/recipe_modules/repo_util/examples/full.expected/failed_flutter_environment.json
+++ b/recipe_modules/repo_util/examples/full.expected/failed_flutter_environment.json
@@ -1,6 +1,38 @@
 [
   {
     "cmd": [],
+    "name": "Identify branches"
+  },
+  {
+    "cmd": [
+      "git",
+      "rev-parse",
+      "HEAD"
+    ],
+    "cwd": "[START_DIR]/flutter",
+    "infra_step": true,
+    "name": "Identify branches.git rev-parse",
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@"
+    ]
+  },
+  {
+    "cmd": [
+      "git",
+      "branch",
+      "-a",
+      "--contains",
+      "12345abcde12345abcde12345abcde12345abcde"
+    ],
+    "cwd": "[START_DIR]/flutter",
+    "infra_step": true,
+    "name": "Identify branches.git branch",
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@"
+    ]
+  },
+  {
+    "cmd": [],
     "name": "Checkout flutter/flutter"
   },
   {
diff --git a/recipe_modules/repo_util/examples/full.expected/first_bot_update_failed.json b/recipe_modules/repo_util/examples/full.expected/first_bot_update_failed.json
index 60f4534..da8bb2d 100644
--- a/recipe_modules/repo_util/examples/full.expected/first_bot_update_failed.json
+++ b/recipe_modules/repo_util/examples/full.expected/first_bot_update_failed.json
@@ -1,6 +1,38 @@
 [
   {
     "cmd": [],
+    "name": "Identify branches"
+  },
+  {
+    "cmd": [
+      "git",
+      "rev-parse",
+      "HEAD"
+    ],
+    "cwd": "[START_DIR]/flutter",
+    "infra_step": true,
+    "name": "Identify branches.git rev-parse",
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@"
+    ]
+  },
+  {
+    "cmd": [
+      "git",
+      "branch",
+      "-a",
+      "--contains",
+      "12345abcde12345abcde12345abcde12345abcde"
+    ],
+    "cwd": "[START_DIR]/flutter",
+    "infra_step": true,
+    "name": "Identify branches.git branch",
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@"
+    ]
+  },
+  {
+    "cmd": [],
     "name": "Checkout flutter/flutter"
   },
   {
diff --git a/recipe_modules/repo_util/examples/full.expected/first_bot_update_revision_not_found.json b/recipe_modules/repo_util/examples/full.expected/first_bot_update_revision_not_found.json
index 2a732cd..c1f6632 100644
--- a/recipe_modules/repo_util/examples/full.expected/first_bot_update_revision_not_found.json
+++ b/recipe_modules/repo_util/examples/full.expected/first_bot_update_revision_not_found.json
@@ -1,6 +1,38 @@
 [
   {
     "cmd": [],
+    "name": "Identify branches"
+  },
+  {
+    "cmd": [
+      "git",
+      "rev-parse",
+      "HEAD"
+    ],
+    "cwd": "[START_DIR]/flutter",
+    "infra_step": true,
+    "name": "Identify branches.git rev-parse",
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@"
+    ]
+  },
+  {
+    "cmd": [
+      "git",
+      "branch",
+      "-a",
+      "--contains",
+      "12345abcde12345abcde12345abcde12345abcde"
+    ],
+    "cwd": "[START_DIR]/flutter",
+    "infra_step": true,
+    "name": "Identify branches.git branch",
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@"
+    ]
+  },
+  {
+    "cmd": [],
     "name": "Checkout flutter/flutter"
   },
   {
diff --git a/recipe_modules/repo_util/examples/full.expected/monorepo.json b/recipe_modules/repo_util/examples/full.expected/monorepo.json
index 5f442ae..45ef3be 100644
--- a/recipe_modules/repo_util/examples/full.expected/monorepo.json
+++ b/recipe_modules/repo_util/examples/full.expected/monorepo.json
@@ -1,6 +1,62 @@
 [
   {
     "cmd": [],
+    "name": "Identify branches"
+  },
+  {
+    "cmd": [
+      "git",
+      "rev-parse",
+      "HEAD"
+    ],
+    "cwd": "[START_DIR]/flutter",
+    "infra_step": true,
+    "luci_context": {
+      "realm": {
+        "name": "project:ci"
+      },
+      "resultdb": {
+        "current_invocation": {
+          "name": "invocations/build:8945511751514863184",
+          "update_token": "token"
+        },
+        "hostname": "rdbhost"
+      }
+    },
+    "name": "Identify branches.git rev-parse",
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@"
+    ]
+  },
+  {
+    "cmd": [
+      "git",
+      "branch",
+      "-a",
+      "--contains",
+      "12345abcde12345abcde12345abcde12345abcde"
+    ],
+    "cwd": "[START_DIR]/flutter",
+    "infra_step": true,
+    "luci_context": {
+      "realm": {
+        "name": "project:ci"
+      },
+      "resultdb": {
+        "current_invocation": {
+          "name": "invocations/build:8945511751514863184",
+          "update_token": "token"
+        },
+        "hostname": "rdbhost"
+      }
+    },
+    "name": "Identify branches.git branch",
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@"
+    ]
+  },
+  {
+    "cmd": [],
     "name": "Checkout flutter/flutter"
   },
   {
diff --git a/recipe_modules/repo_util/examples/full.expected/monorepo_first_bot_update_failed.json b/recipe_modules/repo_util/examples/full.expected/monorepo_first_bot_update_failed.json
index 6fecc15..b563b55 100644
--- a/recipe_modules/repo_util/examples/full.expected/monorepo_first_bot_update_failed.json
+++ b/recipe_modules/repo_util/examples/full.expected/monorepo_first_bot_update_failed.json
@@ -1,6 +1,62 @@
 [
   {
     "cmd": [],
+    "name": "Identify branches"
+  },
+  {
+    "cmd": [
+      "git",
+      "rev-parse",
+      "HEAD"
+    ],
+    "cwd": "[START_DIR]/flutter",
+    "infra_step": true,
+    "luci_context": {
+      "realm": {
+        "name": "project:ci"
+      },
+      "resultdb": {
+        "current_invocation": {
+          "name": "invocations/build:8945511751514863184",
+          "update_token": "token"
+        },
+        "hostname": "rdbhost"
+      }
+    },
+    "name": "Identify branches.git rev-parse",
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@"
+    ]
+  },
+  {
+    "cmd": [
+      "git",
+      "branch",
+      "-a",
+      "--contains",
+      "12345abcde12345abcde12345abcde12345abcde"
+    ],
+    "cwd": "[START_DIR]/flutter",
+    "infra_step": true,
+    "luci_context": {
+      "realm": {
+        "name": "project:ci"
+      },
+      "resultdb": {
+        "current_invocation": {
+          "name": "invocations/build:8945511751514863184",
+          "update_token": "token"
+        },
+        "hostname": "rdbhost"
+      }
+    },
+    "name": "Identify branches.git branch",
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@"
+    ]
+  },
+  {
+    "cmd": [],
     "name": "Checkout flutter/flutter"
   },
   {
diff --git a/recipe_modules/repo_util/examples/full.expected/monorepo_release.json b/recipe_modules/repo_util/examples/full.expected/monorepo_release.json
index 4361de7..86d3ddd 100644
--- a/recipe_modules/repo_util/examples/full.expected/monorepo_release.json
+++ b/recipe_modules/repo_util/examples/full.expected/monorepo_release.json
@@ -57,6 +57,62 @@
   },
   {
     "cmd": [],
+    "name": "Identify branches (2)"
+  },
+  {
+    "cmd": [
+      "git",
+      "rev-parse",
+      "HEAD"
+    ],
+    "cwd": "[START_DIR]/flutter",
+    "infra_step": true,
+    "luci_context": {
+      "realm": {
+        "name": "project:ci"
+      },
+      "resultdb": {
+        "current_invocation": {
+          "name": "invocations/build:8945511751514863184",
+          "update_token": "token"
+        },
+        "hostname": "rdbhost"
+      }
+    },
+    "name": "Identify branches (2).git rev-parse",
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@"
+    ]
+  },
+  {
+    "cmd": [
+      "git",
+      "branch",
+      "-a",
+      "--contains",
+      "12345abcde12345abcde12345abcde12345abcde"
+    ],
+    "cwd": "[START_DIR]/flutter",
+    "infra_step": true,
+    "luci_context": {
+      "realm": {
+        "name": "project:ci"
+      },
+      "resultdb": {
+        "current_invocation": {
+          "name": "invocations/build:8945511751514863184",
+          "update_token": "token"
+        },
+        "hostname": "rdbhost"
+      }
+    },
+    "name": "Identify branches (2).git branch",
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@"
+    ]
+  },
+  {
+    "cmd": [],
     "name": "Checkout flutter/flutter"
   },
   {
@@ -1052,62 +1108,6 @@
   },
   {
     "cmd": [],
-    "name": "Identify branches (2)"
-  },
-  {
-    "cmd": [
-      "git",
-      "rev-parse",
-      "HEAD"
-    ],
-    "cwd": "[START_DIR]/flutter/flutter",
-    "infra_step": true,
-    "luci_context": {
-      "realm": {
-        "name": "project:ci"
-      },
-      "resultdb": {
-        "current_invocation": {
-          "name": "invocations/build:8945511751514863184",
-          "update_token": "token"
-        },
-        "hostname": "rdbhost"
-      }
-    },
-    "name": "Identify branches (2).git rev-parse",
-    "~followup_annotations": [
-      "@@@STEP_NEST_LEVEL@1@@@"
-    ]
-  },
-  {
-    "cmd": [
-      "git",
-      "branch",
-      "-a",
-      "--contains",
-      "12345abcde12345abcde12345abcde12345abcde"
-    ],
-    "cwd": "[START_DIR]/flutter/flutter",
-    "infra_step": true,
-    "luci_context": {
-      "realm": {
-        "name": "project:ci"
-      },
-      "resultdb": {
-        "current_invocation": {
-          "name": "invocations/build:8945511751514863184",
-          "update_token": "token"
-        },
-        "hostname": "rdbhost"
-      }
-    },
-    "name": "Identify branches (2).git branch",
-    "~followup_annotations": [
-      "@@@STEP_NEST_LEVEL@1@@@"
-    ]
-  },
-  {
-    "cmd": [],
     "name": "Identify branches (3)"
   },
   {
@@ -1116,7 +1116,7 @@
       "rev-parse",
       "HEAD"
     ],
-    "cwd": "[START_DIR]/flutter",
+    "cwd": "[START_DIR]/flutter/flutter",
     "infra_step": true,
     "luci_context": {
       "realm": {
@@ -1143,7 +1143,7 @@
       "--contains",
       "12345abcde12345abcde12345abcde12345abcde"
     ],
-    "cwd": "[START_DIR]/flutter",
+    "cwd": "[START_DIR]/flutter/flutter",
     "infra_step": true,
     "luci_context": {
       "realm": {
@@ -1163,28 +1163,6 @@
     ]
   },
   {
-    "cmd": [
-      "git",
-      "rev-parse",
-      "HEAD"
-    ],
-    "cwd": "[START_DIR]/flutter",
-    "infra_step": true,
-    "luci_context": {
-      "realm": {
-        "name": "project:ci"
-      },
-      "resultdb": {
-        "current_invocation": {
-          "name": "invocations/build:8945511751514863184",
-          "update_token": "token"
-        },
-        "hostname": "rdbhost"
-      }
-    },
-    "name": "git rev-parse"
-  },
-  {
     "cmd": [],
     "name": "Identify branches (4)"
   },
@@ -1242,6 +1220,84 @@
   },
   {
     "cmd": [
+      "git",
+      "rev-parse",
+      "HEAD"
+    ],
+    "cwd": "[START_DIR]/flutter",
+    "infra_step": true,
+    "luci_context": {
+      "realm": {
+        "name": "project:ci"
+      },
+      "resultdb": {
+        "current_invocation": {
+          "name": "invocations/build:8945511751514863184",
+          "update_token": "token"
+        },
+        "hostname": "rdbhost"
+      }
+    },
+    "name": "git rev-parse"
+  },
+  {
+    "cmd": [],
+    "name": "Identify branches (5)"
+  },
+  {
+    "cmd": [
+      "git",
+      "rev-parse",
+      "HEAD"
+    ],
+    "cwd": "[START_DIR]/flutter",
+    "infra_step": true,
+    "luci_context": {
+      "realm": {
+        "name": "project:ci"
+      },
+      "resultdb": {
+        "current_invocation": {
+          "name": "invocations/build:8945511751514863184",
+          "update_token": "token"
+        },
+        "hostname": "rdbhost"
+      }
+    },
+    "name": "Identify branches (5).git rev-parse",
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@"
+    ]
+  },
+  {
+    "cmd": [
+      "git",
+      "branch",
+      "-a",
+      "--contains",
+      "12345abcde12345abcde12345abcde12345abcde"
+    ],
+    "cwd": "[START_DIR]/flutter",
+    "infra_step": true,
+    "luci_context": {
+      "realm": {
+        "name": "project:ci"
+      },
+      "resultdb": {
+        "current_invocation": {
+          "name": "invocations/build:8945511751514863184",
+          "update_token": "token"
+        },
+        "hostname": "rdbhost"
+      }
+    },
+    "name": "Identify branches (5).git branch",
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@"
+    ]
+  },
+  {
+    "cmd": [
       "vpython3",
       "-u",
       "RECIPE_MODULE[recipe_engine::file]/resources/fileutil.py",
diff --git a/recipe_modules/repo_util/examples/full.expected/monorepo_wrong_host.json b/recipe_modules/repo_util/examples/full.expected/monorepo_wrong_host.json
index 0f9f0e4..e284c1b 100644
--- a/recipe_modules/repo_util/examples/full.expected/monorepo_wrong_host.json
+++ b/recipe_modules/repo_util/examples/full.expected/monorepo_wrong_host.json
@@ -1,6 +1,62 @@
 [
   {
     "cmd": [],
+    "name": "Identify branches"
+  },
+  {
+    "cmd": [
+      "git",
+      "rev-parse",
+      "HEAD"
+    ],
+    "cwd": "[START_DIR]/flutter",
+    "infra_step": true,
+    "luci_context": {
+      "realm": {
+        "name": "project:ci"
+      },
+      "resultdb": {
+        "current_invocation": {
+          "name": "invocations/build:8945511751514863184",
+          "update_token": "token"
+        },
+        "hostname": "rdbhost"
+      }
+    },
+    "name": "Identify branches.git rev-parse",
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@"
+    ]
+  },
+  {
+    "cmd": [
+      "git",
+      "branch",
+      "-a",
+      "--contains",
+      "12345abcde12345abcde12345abcde12345abcde"
+    ],
+    "cwd": "[START_DIR]/flutter",
+    "infra_step": true,
+    "luci_context": {
+      "realm": {
+        "name": "project:ci"
+      },
+      "resultdb": {
+        "current_invocation": {
+          "name": "invocations/build:8945511751514863184",
+          "update_token": "token"
+        },
+        "hostname": "rdbhost"
+      }
+    },
+    "name": "Identify branches.git branch",
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@"
+    ]
+  },
+  {
+    "cmd": [],
     "name": "Checkout flutter/flutter"
   },
   {
@@ -1051,7 +1107,7 @@
       "The recipe has crashed at point 'Uncaught exception'!",
       "",
       "Traceback (most recent call last):",
-      "  File \"RECIPE_REPO[flutter]/recipe_modules/repo_util/examples/full.py\", line 45, in RunSteps",
+      "  File \"RECIPE_REPO[flutter]/recipe_modules/repo_util/examples/full.py\", line 46, in RunSteps",
       "    api.repo_util.monorepo_checkout(checkout_path, {}, {})",
       "  File \"RECIPE_REPO[flutter]/recipe_modules/repo_util/api.py\", line 144, in monorepo_checkout",
       "    raise ValueError(",
diff --git a/recipe_modules/repo_util/examples/full.py b/recipe_modules/repo_util/examples/full.py
index 9d106dc..4dd6b6f 100644
--- a/recipe_modules/repo_util/examples/full.py
+++ b/recipe_modules/repo_util/examples/full.py
@@ -17,6 +17,7 @@
 def RunSteps(api):
   flutter_checkout_path = api.path['start_dir'].join('flutter')
   api.repo_util.get_branch(flutter_checkout_path)
+  api.repo_util.is_release_candidate_branch(flutter_checkout_path)
   api.repo_util.checkout(
       'flutter', flutter_checkout_path, ref='refs/heads/master'
   )
@@ -67,15 +68,15 @@
           ),
           api.step_data(
               'Identify branches.git branch',
-              stdout=api.raw_io.output_text('branch1\nbranch2')
+              stdout=api.raw_io.output_text('branch1\nbranch2\nflutter-3.2-candidate.5')
           ),
           api.step_data(
               'Identify branches (2).git branch',
-              stdout=api.raw_io.output_text('branch1\nbranch2')
+              stdout=api.raw_io.output_text('branch1\nbranch2\nflutter-3.2-candidate.5')
           ),
           api.step_data(
               'Identify branches (3).git branch',
-              stdout=api.raw_io.output_text('branch1\nbranch2')
+              stdout=api.raw_io.output_text('branch1\nbranch2\nflutter-3.2-candidate.5')
           )
       )
   )