Reset Xcode before `flutter doctor` to prevent Xcode corruption from causing it to fail.

Also, add check to verify Xcode is not damaged/corrupted and if it is, clear the cache and try to install. On second attempt to re-install, try using a different output path.

This fix is aimed at preventing continuous failures on subsequent builds if the Xcode package becomes corrupted.

Fixes: https://github.com/flutter/flutter/issues/139152
Related bug: https://github.com/flutter/flutter/issues/138238

Change-Id: I0f72974241916e9a66f26291ddce01b4b615121f
Reviewed-on: https://flutter-review.googlesource.com/c/recipes/+/52702
Reviewed-by: Keyong Han <keyonghan@google.com>
Commit-Queue: Victoria Ashworth <vashworth@google.com>
diff --git a/recipe_modules/adhoc_validation/examples/full.expected/mac.json b/recipe_modules/adhoc_validation/examples/full.expected/mac.json
index e5e678e..e82ee4e 100644
--- a/recipe_modules/adhoc_validation/examples/full.expected/mac.json
+++ b/recipe_modules/adhoc_validation/examples/full.expected/mac.json
@@ -74,6 +74,13 @@
     ]
   },
   {
+    "cmd": [],
+    "name": "Docs.install xcode",
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@"
+    ]
+  },
+  {
     "cmd": [
       "cipd",
       "ensure",
@@ -105,9 +112,9 @@
       ]
     },
     "infra_step": true,
-    "name": "Docs.ensure_installed",
+    "name": "Docs.install xcode.ensure_installed",
     "~followup_annotations": [
-      "@@@STEP_NEST_LEVEL@1@@@",
+      "@@@STEP_NEST_LEVEL@2@@@",
       "@@@STEP_LOG_LINE@json.output@{@@@",
       "@@@STEP_LOG_LINE@json.output@  \"result\": {@@@",
       "@@@STEP_LOG_LINE@json.output@    \"\": [@@@",
@@ -155,9 +162,10 @@
       ]
     },
     "infra_step": true,
-    "name": "Docs.install xcode",
+    "name": "Docs.install xcode.install xcode from cipd",
+    "timeout": 1800,
     "~followup_annotations": [
-      "@@@STEP_NEST_LEVEL@1@@@"
+      "@@@STEP_NEST_LEVEL@2@@@"
     ]
   },
   {
@@ -216,7 +224,7 @@
       ]
     },
     "infra_step": true,
-    "name": "Docs.select XCode",
+    "name": "Docs.select xcode",
     "~followup_annotations": [
       "@@@STEP_NEST_LEVEL@1@@@"
     ]
@@ -317,6 +325,13 @@
     ]
   },
   {
+    "cmd": [],
+    "name": "Docs.install xcode (2)",
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@"
+    ]
+  },
+  {
     "cmd": [
       "cipd",
       "ensure",
@@ -348,9 +363,9 @@
       ]
     },
     "infra_step": true,
-    "name": "Docs.ensure_installed (2)",
+    "name": "Docs.install xcode (2).ensure_installed",
     "~followup_annotations": [
-      "@@@STEP_NEST_LEVEL@1@@@",
+      "@@@STEP_NEST_LEVEL@2@@@",
       "@@@STEP_LOG_LINE@json.output@{@@@",
       "@@@STEP_LOG_LINE@json.output@  \"result\": {@@@",
       "@@@STEP_LOG_LINE@json.output@    \"\": [@@@",
@@ -398,9 +413,10 @@
       ]
     },
     "infra_step": true,
-    "name": "Docs.install xcode (2)",
+    "name": "Docs.install xcode (2).install xcode from cipd",
+    "timeout": 1800,
     "~followup_annotations": [
-      "@@@STEP_NEST_LEVEL@1@@@"
+      "@@@STEP_NEST_LEVEL@2@@@"
     ]
   },
   {
@@ -459,7 +475,7 @@
       ]
     },
     "infra_step": true,
-    "name": "Docs.select XCode (2)",
+    "name": "Docs.select xcode (2)",
     "~followup_annotations": [
       "@@@STEP_NEST_LEVEL@1@@@"
     ]
diff --git a/recipe_modules/flutter_deps/examples/full.expected/mac.json b/recipe_modules/flutter_deps/examples/full.expected/mac.json
index b1849e4..4de2f65 100644
--- a/recipe_modules/flutter_deps/examples/full.expected/mac.json
+++ b/recipe_modules/flutter_deps/examples/full.expected/mac.json
@@ -812,6 +812,10 @@
     "name": "Show xcode cache"
   },
   {
+    "cmd": [],
+    "name": "install xcode"
+  },
+  {
     "cmd": [
       "cipd",
       "ensure",
@@ -825,8 +829,9 @@
       "/path/to/tmp/json"
     ],
     "infra_step": true,
-    "name": "ensure_installed (7)",
+    "name": "install xcode.ensure_installed",
     "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@",
       "@@@STEP_LOG_LINE@json.output@{@@@",
       "@@@STEP_LOG_LINE@json.output@  \"result\": {@@@",
       "@@@STEP_LOG_LINE@json.output@    \"\": [@@@",
@@ -856,7 +861,11 @@
       "-verbose"
     ],
     "infra_step": true,
-    "name": "install xcode"
+    "name": "install xcode.install xcode from cipd",
+    "timeout": 1800,
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@"
+    ]
   },
   {
     "cmd": [
@@ -875,7 +884,7 @@
       "[CACHE]/osx_sdk/xcode_9f2000/XCode.app"
     ],
     "infra_step": true,
-    "name": "select XCode"
+    "name": "select xcode"
   },
   {
     "cmd": [
@@ -910,6 +919,10 @@
     "name": "Cleaning up Xcode cache"
   },
   {
+    "cmd": [],
+    "name": "install xcode (2)"
+  },
+  {
     "cmd": [
       "cipd",
       "ensure",
@@ -923,8 +936,9 @@
       "/path/to/tmp/json"
     ],
     "infra_step": true,
-    "name": "ensure_installed (8)",
+    "name": "install xcode (2).ensure_installed",
     "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@",
       "@@@STEP_LOG_LINE@json.output@{@@@",
       "@@@STEP_LOG_LINE@json.output@  \"result\": {@@@",
       "@@@STEP_LOG_LINE@json.output@    \"\": [@@@",
@@ -954,7 +968,11 @@
       "-verbose"
     ],
     "infra_step": true,
-    "name": "install xcode (2)"
+    "name": "install xcode (2).install xcode from cipd",
+    "timeout": 1800,
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@"
+    ]
   },
   {
     "cmd": [
@@ -973,7 +991,7 @@
       "[CACHE]/osx_sdk/xcode_9f2000/XCode.app"
     ],
     "infra_step": true,
-    "name": "select XCode (2)"
+    "name": "select xcode (2)"
   },
   {
     "cmd": [
@@ -1007,6 +1025,10 @@
     "name": "Cleaning up Xcode cache (2)"
   },
   {
+    "cmd": [],
+    "name": "install xcode (3)"
+  },
+  {
     "cmd": [
       "cipd",
       "ensure",
@@ -1020,8 +1042,9 @@
       "/path/to/tmp/json"
     ],
     "infra_step": true,
-    "name": "ensure_installed (9)",
+    "name": "install xcode (3).ensure_installed",
     "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@",
       "@@@STEP_LOG_LINE@json.output@{@@@",
       "@@@STEP_LOG_LINE@json.output@  \"result\": {@@@",
       "@@@STEP_LOG_LINE@json.output@    \"\": [@@@",
@@ -1051,7 +1074,11 @@
       "-verbose"
     ],
     "infra_step": true,
-    "name": "install xcode (3)"
+    "name": "install xcode (3).install xcode from cipd",
+    "timeout": 1800,
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@"
+    ]
   },
   {
     "cmd": [
@@ -1070,7 +1097,7 @@
       "/opt/flutter/xcode/9f2000/XCode.app"
     ],
     "infra_step": true,
-    "name": "select XCode (3)"
+    "name": "select xcode (3)"
   },
   {
     "cmd": [
@@ -1105,6 +1132,10 @@
     "name": "Cleaning up Xcode cache (3)"
   },
   {
+    "cmd": [],
+    "name": "install xcode (4)"
+  },
+  {
     "cmd": [
       "cipd",
       "ensure",
@@ -1118,8 +1149,9 @@
       "/path/to/tmp/json"
     ],
     "infra_step": true,
-    "name": "ensure_installed (10)",
+    "name": "install xcode (4).ensure_installed",
     "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@",
       "@@@STEP_LOG_LINE@json.output@{@@@",
       "@@@STEP_LOG_LINE@json.output@  \"result\": {@@@",
       "@@@STEP_LOG_LINE@json.output@    \"\": [@@@",
@@ -1149,7 +1181,11 @@
       "-verbose"
     ],
     "infra_step": true,
-    "name": "install xcode (4)"
+    "name": "install xcode (4).install xcode from cipd",
+    "timeout": 1800,
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@"
+    ]
   },
   {
     "cmd": [
@@ -1168,7 +1204,7 @@
       "/opt/flutter/xcode/9f2000/XCode.app"
     ],
     "infra_step": true,
-    "name": "select XCode (4)"
+    "name": "select xcode (4)"
   },
   {
     "cmd": [
diff --git a/recipe_modules/flutter_deps/examples/full.expected/mac_old.json b/recipe_modules/flutter_deps/examples/full.expected/mac_old.json
index 84c4e6e..b8e3e08 100644
--- a/recipe_modules/flutter_deps/examples/full.expected/mac_old.json
+++ b/recipe_modules/flutter_deps/examples/full.expected/mac_old.json
@@ -812,6 +812,10 @@
     "name": "Show xcode cache"
   },
   {
+    "cmd": [],
+    "name": "install xcode"
+  },
+  {
     "cmd": [
       "cipd",
       "ensure",
@@ -825,8 +829,9 @@
       "/path/to/tmp/json"
     ],
     "infra_step": true,
-    "name": "ensure_installed (7)",
+    "name": "install xcode.ensure_installed",
     "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@",
       "@@@STEP_LOG_LINE@json.output@{@@@",
       "@@@STEP_LOG_LINE@json.output@  \"result\": {@@@",
       "@@@STEP_LOG_LINE@json.output@    \"\": [@@@",
@@ -856,7 +861,11 @@
       "-verbose"
     ],
     "infra_step": true,
-    "name": "install xcode"
+    "name": "install xcode.install xcode from cipd",
+    "timeout": 1800,
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@"
+    ]
   },
   {
     "cmd": [
@@ -875,7 +884,7 @@
       "[CACHE]/osx_sdk/xcode_9f2000/XCode.app"
     ],
     "infra_step": true,
-    "name": "select XCode"
+    "name": "select xcode"
   },
   {
     "cmd": [
@@ -910,6 +919,10 @@
     "name": "Cleaning up Xcode cache"
   },
   {
+    "cmd": [],
+    "name": "install xcode (2)"
+  },
+  {
     "cmd": [
       "cipd",
       "ensure",
@@ -923,8 +936,9 @@
       "/path/to/tmp/json"
     ],
     "infra_step": true,
-    "name": "ensure_installed (8)",
+    "name": "install xcode (2).ensure_installed",
     "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@",
       "@@@STEP_LOG_LINE@json.output@{@@@",
       "@@@STEP_LOG_LINE@json.output@  \"result\": {@@@",
       "@@@STEP_LOG_LINE@json.output@    \"\": [@@@",
@@ -954,7 +968,11 @@
       "-verbose"
     ],
     "infra_step": true,
-    "name": "install xcode (2)"
+    "name": "install xcode (2).install xcode from cipd",
+    "timeout": 1800,
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@"
+    ]
   },
   {
     "cmd": [
@@ -973,7 +991,7 @@
       "[CACHE]/osx_sdk/xcode_9f2000/XCode.app"
     ],
     "infra_step": true,
-    "name": "select XCode (2)"
+    "name": "select xcode (2)"
   },
   {
     "cmd": [
@@ -1007,6 +1025,10 @@
     "name": "Cleaning up Xcode cache (2)"
   },
   {
+    "cmd": [],
+    "name": "install xcode (3)"
+  },
+  {
     "cmd": [
       "cipd",
       "ensure",
@@ -1020,8 +1042,9 @@
       "/path/to/tmp/json"
     ],
     "infra_step": true,
-    "name": "ensure_installed (9)",
+    "name": "install xcode (3).ensure_installed",
     "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@",
       "@@@STEP_LOG_LINE@json.output@{@@@",
       "@@@STEP_LOG_LINE@json.output@  \"result\": {@@@",
       "@@@STEP_LOG_LINE@json.output@    \"\": [@@@",
@@ -1051,7 +1074,11 @@
       "-verbose"
     ],
     "infra_step": true,
-    "name": "install xcode (3)"
+    "name": "install xcode (3).install xcode from cipd",
+    "timeout": 1800,
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@"
+    ]
   },
   {
     "cmd": [
@@ -1070,7 +1097,7 @@
       "/opt/flutter/xcode/9f2000/XCode.app"
     ],
     "infra_step": true,
-    "name": "select XCode (3)"
+    "name": "select xcode (3)"
   },
   {
     "cmd": [
@@ -1105,6 +1132,10 @@
     "name": "Cleaning up Xcode cache (3)"
   },
   {
+    "cmd": [],
+    "name": "install xcode (4)"
+  },
+  {
     "cmd": [
       "cipd",
       "ensure",
@@ -1118,8 +1149,9 @@
       "/path/to/tmp/json"
     ],
     "infra_step": true,
-    "name": "ensure_installed (10)",
+    "name": "install xcode (4).ensure_installed",
     "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@",
       "@@@STEP_LOG_LINE@json.output@{@@@",
       "@@@STEP_LOG_LINE@json.output@  \"result\": {@@@",
       "@@@STEP_LOG_LINE@json.output@    \"\": [@@@",
@@ -1149,7 +1181,11 @@
       "-verbose"
     ],
     "infra_step": true,
-    "name": "install xcode (4)"
+    "name": "install xcode (4).install xcode from cipd",
+    "timeout": 1800,
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@"
+    ]
   },
   {
     "cmd": [
@@ -1168,7 +1204,7 @@
       "/opt/flutter/xcode/9f2000/XCode.app"
     ],
     "infra_step": true,
-    "name": "select XCode (4)"
+    "name": "select xcode (4)"
   },
   {
     "cmd": [
diff --git a/recipe_modules/osx_sdk/__init__.py b/recipe_modules/osx_sdk/__init__.py
index f3de677..01dff5b 100644
--- a/recipe_modules/osx_sdk/__init__.py
+++ b/recipe_modules/osx_sdk/__init__.py
@@ -13,6 +13,7 @@
     'recipe_engine/raw_io',
     'recipe_engine/step',
     'recipe_engine/version',
+    'recipe_engine/uuid',
 ]
 
 from recipe_engine.recipe_api import Property
diff --git a/recipe_modules/osx_sdk/api.py b/recipe_modules/osx_sdk/api.py
index 5e25884..561f57e 100644
--- a/recipe_modules/osx_sdk/api.py
+++ b/recipe_modules/osx_sdk/api.py
@@ -166,8 +166,14 @@
           self._setup_osx_sdk(kind, devicelab)
       yield
     finally:
-      with self.m.context(infra_steps=True):
-        self.m.step('reset XCode', ['sudo', 'xcode-select', '--reset'])
+      self.reset_xcode()
+
+  def reset_xcode(self):
+    '''Unset manually defined Xcode path for Xcode command line tools on macOS.'''
+    if not self.m.platform.is_mac:
+      return
+    with self.m.context(infra_steps=True):
+      self.m.step('reset XCode', ['sudo', 'xcode-select', '--reset'])
 
   def _missing_runtime(self, runtime_simulators):
     """Check if there is any missing runtime.
@@ -199,7 +205,7 @@
     self._clean_xcode_cache(devicelab)
     app = self._ensure_sdk(kind, devicelab)
     self.m.os_utils.kill_simulators()
-    self.m.step('select XCode', ['sudo', 'xcode-select', '--switch', app])
+    self._select_xcode(app)
     self.m.step('list simulators', ['xcrun', 'simctl', 'list'])
 
   def _clean_xcode_cache(self, devicelab):
@@ -228,15 +234,118 @@
     ef.add_package(self._tool_pkg, self._tool_ver)
     self.m.cipd.ensure(tool_dir, ef)
 
-  def _try_install_xcode(self, tool_dir, kind, app_dir, devicelab):
-    """Installs xcode using mac_toolchain. If install fails, clear the cache and try again."""
-    try:
-      self._install_xcode(tool_dir, kind, app_dir, devicelab)
-    except self.m.step.StepFailure:
-      self._install_xcode(tool_dir, kind, app_dir, devicelab)
+  def _select_xcode(self, sdk_app):
+    self.m.step('select xcode', ['sudo', 'xcode-select', '--switch', sdk_app])
 
-  def _install_xcode(self, tool_dir, kind, app_dir, devicelab):
-    """Installs xcode using mac_toolchain."""
+  def _verify_xcode(self, sdk_app):
+    '''If Xcode is already downloaded, verify that it's not damaged.
+
+    Args:
+    sdk_app: (Path) Path to installed Xcode app bundle.
+    '''
+    if not self.m.path.exists(sdk_app):
+      return
+
+    with self.m.step.nest('verify xcode %s' % sdk_app):
+      version_check_failed = False
+      try:
+        self._select_xcode(sdk_app)
+
+        # This step is expected to timeout if Xcode is damaged.
+        self.m.step(
+            'check xcode version',
+            [
+                'xcrun',
+                'xcodebuild',
+                '-version',
+            ],
+            timeout=60 * 5,  # 5 minutes
+        )
+      except self.m.step.StepFailure:
+        version_check_failed = True
+        raise
+      finally:
+        self.reset_xcode()
+        self._dimiss_damaged_notification()
+
+        if version_check_failed:
+          self._diagnose_codesign_failure(sdk_app)
+
+  def _diagnose_codesign_failure(self, sdk_app):
+    '''Check if Xcode verification may have failed due to code not matching
+    original signed code. Used to help debug issues.
+    '''
+    self.m.step(
+        'verify codesign',
+        [
+            'codesign',
+            '-vv',
+            sdk_app,
+        ],
+        ok_ret='any',
+    )
+
+  def _dimiss_damaged_notification(self):
+    '''If Xcode is damaged, it may show a notification that can cause
+    Xcode processes to hang until it's closed. Kill `CoreServicesUIAgent`
+    to close it.
+    '''
+    self.m.step(
+        'dismiss damaged notification',
+        ['killall', '-9', 'CoreServicesUIAgent'],
+        ok_ret='any',
+    )
+
+  def _try_install_xcode(self, tool_dir, kind, app_dir, sdk_app, devicelab):
+    """Installs xcode using mac_toolchain. If install fails, clear the cache and try again.
+
+    Args:
+      devicelab: (bool) Whether this is a devicelab tasks. Don't install
+        explicit runtimes for devicelab tasks.
+      app_dir: (Path) Path to Xcode cache directory.
+      tool_dir: (Path) Path to mac_toolchain cache directory.
+      sdk_app: (Path) Path to installed Xcode app bundle.
+      kind ('mac'|'ios'): How the SDK should be configured.
+    """
+    with self.m.step.nest('install xcode'):
+      try:
+        self._install_xcode(tool_dir, kind, app_dir, sdk_app, devicelab)
+      except self.m.step.StepFailure:
+        self._install_xcode(tool_dir, kind, app_dir, sdk_app, devicelab, True)
+
+  def _install_xcode(
+      self, tool_dir, kind, app_dir, sdk_app, devicelab, retry=False
+  ):
+    """Installs xcode using mac_toolchain.
+
+    Args:
+      devicelab: (bool) Whether this is a devicelab tasks. Don't install
+        explicit runtimes for devicelab tasks.
+      app_dir: (Path) Path to Xcode cache directory.
+      tool_dir: (Path) Path to mac_toolchain cache directory.
+      sdk_app: (Path) Path to installed Xcode app bundle.
+      kind ('mac'|'ios'): How the SDK should be configured.
+      retry: (bool) Whether this is the second attempt to install Xcode.
+    """
+
+    install_path = sdk_app
+
+    # On retry, install Xcode to a different path and later move it to the
+    # original path. Although unproven, there is a theory that re-installing
+    # Xcode to the same path as a previously damaged version may cause the new
+    # version to also be considered damaged.
+    if retry:
+      uuid = self.m.uuid.random()
+      install_path = self.m.path.join(app_dir, 'temp_%s_xcode.app' % uuid)
+
+    try:
+      # Verify that existing Xcode is not damaged. If it's damaged, the
+      # 'install xcode from cipd' step may get stuck until it times out.
+      self._verify_xcode(install_path)
+    except self.m.step.StepFailure:
+      self._cleanup_cache = True
+      self._clean_xcode_cache(devicelab)
+
     try:
       self._ensure_mac_toolchain(tool_dir)
       if self.macos_13_or_later:
@@ -244,27 +353,50 @@
         # https://github.com/flutter/flutter/issues/138238 is resolved.
         self.m.step('Show tool_dir cache', ['ls', '-al', tool_dir])
       self.m.step(
-          'install xcode',
+          'install xcode from cipd',
           [
               tool_dir.join('mac_toolchain'), 'install', '-kind', kind,
-              '-xcode-version', self._sdk_version, '-output-dir', app_dir,
+              '-xcode-version', self._sdk_version, '-output-dir', install_path,
               '-cipd-package-prefix', self._xcode_cipd_package_source,
               '-with-runtime=%s' % (not bool(self._runtime_versions)),
               '-verbose',
           ],
+          timeout=60 * 30  # 30 minutes
       )
+      if retry:
+        self.m.step(
+            'move to final destination',
+            [
+                'mv',
+                install_path,
+                sdk_app,
+            ],
+        )
     except self.m.step.StepFailure:
       if self.macos_13_or_later:
         # TODO(vashworth): Remove macOS 13 specific install steps once
         # https://github.com/flutter/flutter/issues/138238 is resolved.
         self.m.step('Show tool_dir cache', ['ls', '-al', tool_dir])
         self.m.step('Show app_dir cache', ['ls', '-al', app_dir], ok_ret='any')
+      self._dimiss_damaged_notification()
+      self._diagnose_codesign_failure(sdk_app)
       self._cleanup_cache = True
       self._clean_xcode_cache(devicelab)
       self.m.step.empty(
           'Failed to install Xcode',
           status=self.m.step.INFRA_FAILURE,
       )
+    finally:
+      if retry:
+        self.m.step(
+            'clean temporary install path',
+            [
+                'rm',
+                '-rf',
+                install_path,
+            ],
+            ok_ret='any',
+        )
 
   def _ensure_sdk(self, kind, devicelab):
     """Ensures the mac_toolchain tool and OSX SDK packages are installed.
@@ -273,7 +405,7 @@
     app_dir = self._xcode_dir(devicelab)
     tool_dir = self.m.path.mkdtemp().join('osx_sdk') if devicelab else app_dir
     sdk_app = self.m.path.join(app_dir, 'XCode.app')
-    self._try_install_xcode(tool_dir, kind, sdk_app, devicelab)
+    self._try_install_xcode(tool_dir, kind, app_dir, sdk_app, devicelab)
 
     self._cleanup_runtimes_cache(sdk_app)
 
@@ -317,7 +449,7 @@
       # removed. So re-call `_try_install_xcode` to reinstall the removed runtime.
       if self.macos_13_or_later and self._cleanup_cache:
         with self.m.step.nest('install runtimes'):
-          self._try_install_xcode(tool_dir, kind, sdk_app, devicelab)
+          self._try_install_xcode(tool_dir, kind, app_dir, sdk_app, devicelab)
       return
 
     if devicelab:
@@ -325,9 +457,7 @@
 
     with self.m.step.nest('install runtimes'):
       if self.macos_13_or_later:
-        self.m.step(
-            'select XCode', ['sudo', 'xcode-select', '--switch', sdk_app]
-        )
+        self._select_xcode(sdk_app)
         runtime_simulators = self.m.step(
             'list runtimes', ['xcrun', 'simctl', 'list', 'runtimes'],
             stdout=self.m.raw_io.output_text(add_output_log=True)
@@ -463,7 +593,7 @@
       return
 
     with self.m.step.nest('Cleaning up runtimes cache'):
-      self.m.step('select XCode', ['sudo', 'xcode-select', '--switch', sdk_app])
+      self._select_xcode(sdk_app)
 
       simulator_cleanup_result = self.m.step(
           'Cleaning up mounted simulator runtimes',
diff --git a/recipe_modules/osx_sdk/examples/full.expected/ancient_version.json b/recipe_modules/osx_sdk/examples/full.expected/ancient_version.json
index 5c0638e..a2142e2 100644
--- a/recipe_modules/osx_sdk/examples/full.expected/ancient_version.json
+++ b/recipe_modules/osx_sdk/examples/full.expected/ancient_version.json
@@ -9,6 +9,10 @@
     "name": "Show xcode cache"
   },
   {
+    "cmd": [],
+    "name": "install xcode"
+  },
+  {
     "cmd": [
       "cipd",
       "ensure",
@@ -22,8 +26,9 @@
       "/path/to/tmp/json"
     ],
     "infra_step": true,
-    "name": "ensure_installed",
+    "name": "install xcode.ensure_installed",
     "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@",
       "@@@STEP_LOG_LINE@json.output@{@@@",
       "@@@STEP_LOG_LINE@json.output@  \"result\": {@@@",
       "@@@STEP_LOG_LINE@json.output@    \"\": [@@@",
@@ -53,7 +58,11 @@
       "-verbose"
     ],
     "infra_step": true,
-    "name": "install xcode"
+    "name": "install xcode.install xcode from cipd",
+    "timeout": 1800,
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@"
+    ]
   },
   {
     "cmd": [
@@ -72,7 +81,7 @@
       "[CACHE]/osx_sdk/xcode_9c40b/XCode.app"
     ],
     "infra_step": true,
-    "name": "select XCode"
+    "name": "select xcode"
   },
   {
     "cmd": [
@@ -107,6 +116,10 @@
     "name": "Cleaning up Xcode cache"
   },
   {
+    "cmd": [],
+    "name": "install xcode (2)"
+  },
+  {
     "cmd": [
       "cipd",
       "ensure",
@@ -120,8 +133,9 @@
       "/path/to/tmp/json"
     ],
     "infra_step": true,
-    "name": "ensure_installed (2)",
+    "name": "install xcode (2).ensure_installed",
     "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@",
       "@@@STEP_LOG_LINE@json.output@{@@@",
       "@@@STEP_LOG_LINE@json.output@  \"result\": {@@@",
       "@@@STEP_LOG_LINE@json.output@    \"\": [@@@",
@@ -151,7 +165,11 @@
       "-verbose"
     ],
     "infra_step": true,
-    "name": "install xcode (2)"
+    "name": "install xcode (2).install xcode from cipd",
+    "timeout": 1800,
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@"
+    ]
   },
   {
     "cmd": [
@@ -170,7 +188,7 @@
       "[CACHE]/osx_sdk/xcode_9c40b/XCode.app"
     ],
     "infra_step": true,
-    "name": "select XCode (2)"
+    "name": "select xcode (2)"
   },
   {
     "cmd": [
@@ -229,6 +247,10 @@
     "name": "Cleaning up Xcode cache (2)"
   },
   {
+    "cmd": [],
+    "name": "install xcode (3)"
+  },
+  {
     "cmd": [
       "cipd",
       "ensure",
@@ -242,8 +264,9 @@
       "/path/to/tmp/json"
     ],
     "infra_step": true,
-    "name": "ensure_installed (3)",
+    "name": "install xcode (3).ensure_installed",
     "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@",
       "@@@STEP_LOG_LINE@json.output@{@@@",
       "@@@STEP_LOG_LINE@json.output@  \"result\": {@@@",
       "@@@STEP_LOG_LINE@json.output@    \"\": [@@@",
@@ -273,7 +296,11 @@
       "-verbose"
     ],
     "infra_step": true,
-    "name": "install xcode (3)"
+    "name": "install xcode (3).install xcode from cipd",
+    "timeout": 1800,
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@"
+    ]
   },
   {
     "cmd": [
@@ -292,7 +319,7 @@
       "/opt/flutter/xcode/9c40b/XCode.app"
     ],
     "infra_step": true,
-    "name": "select XCode (3)"
+    "name": "select xcode (3)"
   },
   {
     "cmd": [
@@ -327,6 +354,10 @@
     "name": "Cleaning up Xcode cache (3)"
   },
   {
+    "cmd": [],
+    "name": "install xcode (4)"
+  },
+  {
     "cmd": [
       "cipd",
       "ensure",
@@ -340,8 +371,9 @@
       "/path/to/tmp/json"
     ],
     "infra_step": true,
-    "name": "ensure_installed (4)",
+    "name": "install xcode (4).ensure_installed",
     "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@",
       "@@@STEP_LOG_LINE@json.output@{@@@",
       "@@@STEP_LOG_LINE@json.output@  \"result\": {@@@",
       "@@@STEP_LOG_LINE@json.output@    \"\": [@@@",
@@ -371,7 +403,11 @@
       "-verbose"
     ],
     "infra_step": true,
-    "name": "install xcode (4)"
+    "name": "install xcode (4).install xcode from cipd",
+    "timeout": 1800,
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@"
+    ]
   },
   {
     "cmd": [
@@ -390,7 +426,7 @@
       "/opt/flutter/xcode/9c40b/XCode.app"
     ],
     "infra_step": true,
-    "name": "select XCode (4)"
+    "name": "select xcode (4)"
   },
   {
     "cmd": [
@@ -427,6 +463,15 @@
     "name": "reset XCode (2)"
   },
   {
+    "cmd": [
+      "sudo",
+      "xcode-select",
+      "--reset"
+    ],
+    "infra_step": true,
+    "name": "reset XCode (3)"
+  },
+  {
     "name": "$result"
   }
 ]
\ No newline at end of file
diff --git a/recipe_modules/osx_sdk/examples/full.expected/automatic_version.json b/recipe_modules/osx_sdk/examples/full.expected/automatic_version.json
index be39af3..ea0ab76 100644
--- a/recipe_modules/osx_sdk/examples/full.expected/automatic_version.json
+++ b/recipe_modules/osx_sdk/examples/full.expected/automatic_version.json
@@ -9,6 +9,10 @@
     "name": "Show xcode cache"
   },
   {
+    "cmd": [],
+    "name": "install xcode"
+  },
+  {
     "cmd": [
       "cipd",
       "ensure",
@@ -22,8 +26,9 @@
       "/path/to/tmp/json"
     ],
     "infra_step": true,
-    "name": "ensure_installed",
+    "name": "install xcode.ensure_installed",
     "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@",
       "@@@STEP_LOG_LINE@json.output@{@@@",
       "@@@STEP_LOG_LINE@json.output@  \"result\": {@@@",
       "@@@STEP_LOG_LINE@json.output@    \"\": [@@@",
@@ -53,7 +58,11 @@
       "-verbose"
     ],
     "infra_step": true,
-    "name": "install xcode"
+    "name": "install xcode.install xcode from cipd",
+    "timeout": 1800,
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@"
+    ]
   },
   {
     "cmd": [
@@ -72,7 +81,7 @@
       "[CACHE]/osx_sdk/xcode_12a7209/XCode.app"
     ],
     "infra_step": true,
-    "name": "select XCode"
+    "name": "select xcode"
   },
   {
     "cmd": [
@@ -107,6 +116,10 @@
     "name": "Cleaning up Xcode cache"
   },
   {
+    "cmd": [],
+    "name": "install xcode (2)"
+  },
+  {
     "cmd": [
       "cipd",
       "ensure",
@@ -120,8 +133,9 @@
       "/path/to/tmp/json"
     ],
     "infra_step": true,
-    "name": "ensure_installed (2)",
+    "name": "install xcode (2).ensure_installed",
     "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@",
       "@@@STEP_LOG_LINE@json.output@{@@@",
       "@@@STEP_LOG_LINE@json.output@  \"result\": {@@@",
       "@@@STEP_LOG_LINE@json.output@    \"\": [@@@",
@@ -151,7 +165,11 @@
       "-verbose"
     ],
     "infra_step": true,
-    "name": "install xcode (2)"
+    "name": "install xcode (2).install xcode from cipd",
+    "timeout": 1800,
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@"
+    ]
   },
   {
     "cmd": [
@@ -170,7 +188,7 @@
       "[CACHE]/osx_sdk/xcode_12a7209/XCode.app"
     ],
     "infra_step": true,
-    "name": "select XCode (2)"
+    "name": "select xcode (2)"
   },
   {
     "cmd": [
@@ -229,6 +247,10 @@
     "name": "Cleaning up Xcode cache (2)"
   },
   {
+    "cmd": [],
+    "name": "install xcode (3)"
+  },
+  {
     "cmd": [
       "cipd",
       "ensure",
@@ -242,8 +264,9 @@
       "/path/to/tmp/json"
     ],
     "infra_step": true,
-    "name": "ensure_installed (3)",
+    "name": "install xcode (3).ensure_installed",
     "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@",
       "@@@STEP_LOG_LINE@json.output@{@@@",
       "@@@STEP_LOG_LINE@json.output@  \"result\": {@@@",
       "@@@STEP_LOG_LINE@json.output@    \"\": [@@@",
@@ -273,7 +296,11 @@
       "-verbose"
     ],
     "infra_step": true,
-    "name": "install xcode (3)"
+    "name": "install xcode (3).install xcode from cipd",
+    "timeout": 1800,
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@"
+    ]
   },
   {
     "cmd": [
@@ -292,7 +319,7 @@
       "/opt/flutter/xcode/12a7209/XCode.app"
     ],
     "infra_step": true,
-    "name": "select XCode (3)"
+    "name": "select xcode (3)"
   },
   {
     "cmd": [
@@ -327,6 +354,10 @@
     "name": "Cleaning up Xcode cache (3)"
   },
   {
+    "cmd": [],
+    "name": "install xcode (4)"
+  },
+  {
     "cmd": [
       "cipd",
       "ensure",
@@ -340,8 +371,9 @@
       "/path/to/tmp/json"
     ],
     "infra_step": true,
-    "name": "ensure_installed (4)",
+    "name": "install xcode (4).ensure_installed",
     "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@",
       "@@@STEP_LOG_LINE@json.output@{@@@",
       "@@@STEP_LOG_LINE@json.output@  \"result\": {@@@",
       "@@@STEP_LOG_LINE@json.output@    \"\": [@@@",
@@ -371,7 +403,11 @@
       "-verbose"
     ],
     "infra_step": true,
-    "name": "install xcode (4)"
+    "name": "install xcode (4).install xcode from cipd",
+    "timeout": 1800,
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@"
+    ]
   },
   {
     "cmd": [
@@ -390,7 +426,7 @@
       "/opt/flutter/xcode/12a7209/XCode.app"
     ],
     "infra_step": true,
-    "name": "select XCode (4)"
+    "name": "select xcode (4)"
   },
   {
     "cmd": [
@@ -427,6 +463,15 @@
     "name": "reset XCode (2)"
   },
   {
+    "cmd": [
+      "sudo",
+      "xcode-select",
+      "--reset"
+    ],
+    "infra_step": true,
+    "name": "reset XCode (3)"
+  },
+  {
     "name": "$result"
   }
 ]
\ No newline at end of file
diff --git a/recipe_modules/osx_sdk/examples/full.expected/explicit_invalid_runtime_version_with_mac_13.json b/recipe_modules/osx_sdk/examples/full.expected/explicit_invalid_runtime_version_with_mac_13.json
index a90432e..40b120d 100644
--- a/recipe_modules/osx_sdk/examples/full.expected/explicit_invalid_runtime_version_with_mac_13.json
+++ b/recipe_modules/osx_sdk/examples/full.expected/explicit_invalid_runtime_version_with_mac_13.json
@@ -9,6 +9,10 @@
     "name": "Show xcode cache"
   },
   {
+    "cmd": [],
+    "name": "install xcode"
+  },
+  {
     "cmd": [
       "cipd",
       "ensure",
@@ -22,8 +26,9 @@
       "/path/to/tmp/json"
     ],
     "infra_step": true,
-    "name": "ensure_installed",
+    "name": "install xcode.ensure_installed",
     "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@",
       "@@@STEP_LOG_LINE@json.output@{@@@",
       "@@@STEP_LOG_LINE@json.output@  \"result\": {@@@",
       "@@@STEP_LOG_LINE@json.output@    \"\": [@@@",
@@ -44,7 +49,10 @@
       "[CACHE]/osx_sdk/xcode_deadbeef_runtime_ios-16-4_ios-16-2"
     ],
     "infra_step": true,
-    "name": "Show tool_dir cache"
+    "name": "install xcode.Show tool_dir cache",
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@"
+    ]
   },
   {
     "cmd": [
@@ -62,7 +70,11 @@
       "-verbose"
     ],
     "infra_step": true,
-    "name": "install xcode"
+    "name": "install xcode.install xcode from cipd",
+    "timeout": 1800,
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@"
+    ]
   },
   {
     "cmd": [],
@@ -79,7 +91,7 @@
       "[CACHE]/osx_sdk/xcode_deadbeef_runtime_ios-16-4_ios-16-2/XCode.app"
     ],
     "infra_step": true,
-    "name": "install runtimes.select XCode",
+    "name": "install runtimes.select xcode",
     "~followup_annotations": [
       "@@@STEP_NEST_LEVEL@1@@@"
     ]
diff --git a/recipe_modules/osx_sdk/examples/full.expected/explicit_package_source.json b/recipe_modules/osx_sdk/examples/full.expected/explicit_package_source.json
index 0be2c63..740ab05 100644
--- a/recipe_modules/osx_sdk/examples/full.expected/explicit_package_source.json
+++ b/recipe_modules/osx_sdk/examples/full.expected/explicit_package_source.json
@@ -22,6 +22,10 @@
     "name": "Cleaning up Xcode cache"
   },
   {
+    "cmd": [],
+    "name": "install xcode"
+  },
+  {
     "cmd": [
       "cipd",
       "ensure",
@@ -35,8 +39,9 @@
       "/path/to/tmp/json"
     ],
     "infra_step": true,
-    "name": "ensure_installed",
+    "name": "install xcode.ensure_installed",
     "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@",
       "@@@STEP_LOG_LINE@json.output@{@@@",
       "@@@STEP_LOG_LINE@json.output@  \"result\": {@@@",
       "@@@STEP_LOG_LINE@json.output@    \"\": [@@@",
@@ -66,7 +71,11 @@
       "-verbose"
     ],
     "infra_step": true,
-    "name": "install xcode"
+    "name": "install xcode.install xcode from cipd",
+    "timeout": 1800,
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@"
+    ]
   },
   {
     "cmd": [
@@ -85,7 +94,7 @@
       "[CACHE]/osx_sdk/xcode_deadbeef/XCode.app"
     ],
     "infra_step": true,
-    "name": "select XCode"
+    "name": "select xcode"
   },
   {
     "cmd": [
@@ -120,6 +129,10 @@
     "name": "Cleaning up Xcode cache (2)"
   },
   {
+    "cmd": [],
+    "name": "install xcode (2)"
+  },
+  {
     "cmd": [
       "cipd",
       "ensure",
@@ -133,8 +146,9 @@
       "/path/to/tmp/json"
     ],
     "infra_step": true,
-    "name": "ensure_installed (2)",
+    "name": "install xcode (2).ensure_installed",
     "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@",
       "@@@STEP_LOG_LINE@json.output@{@@@",
       "@@@STEP_LOG_LINE@json.output@  \"result\": {@@@",
       "@@@STEP_LOG_LINE@json.output@    \"\": [@@@",
@@ -164,7 +178,11 @@
       "-verbose"
     ],
     "infra_step": true,
-    "name": "install xcode (2)"
+    "name": "install xcode (2).install xcode from cipd",
+    "timeout": 1800,
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@"
+    ]
   },
   {
     "cmd": [
@@ -183,7 +201,7 @@
       "[CACHE]/osx_sdk/xcode_deadbeef/XCode.app"
     ],
     "infra_step": true,
-    "name": "select XCode (2)"
+    "name": "select xcode (2)"
   },
   {
     "cmd": [
@@ -242,6 +260,10 @@
     "name": "Cleaning up Xcode cache (3)"
   },
   {
+    "cmd": [],
+    "name": "install xcode (3)"
+  },
+  {
     "cmd": [
       "cipd",
       "ensure",
@@ -255,8 +277,9 @@
       "/path/to/tmp/json"
     ],
     "infra_step": true,
-    "name": "ensure_installed (3)",
+    "name": "install xcode (3).ensure_installed",
     "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@",
       "@@@STEP_LOG_LINE@json.output@{@@@",
       "@@@STEP_LOG_LINE@json.output@  \"result\": {@@@",
       "@@@STEP_LOG_LINE@json.output@    \"\": [@@@",
@@ -286,7 +309,11 @@
       "-verbose"
     ],
     "infra_step": true,
-    "name": "install xcode (3)"
+    "name": "install xcode (3).install xcode from cipd",
+    "timeout": 1800,
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@"
+    ]
   },
   {
     "cmd": [
@@ -305,7 +332,7 @@
       "/opt/flutter/xcode/deadbeef/XCode.app"
     ],
     "infra_step": true,
-    "name": "select XCode (3)"
+    "name": "select xcode (3)"
   },
   {
     "cmd": [
@@ -340,6 +367,10 @@
     "name": "Cleaning up Xcode cache (4)"
   },
   {
+    "cmd": [],
+    "name": "install xcode (4)"
+  },
+  {
     "cmd": [
       "cipd",
       "ensure",
@@ -353,8 +384,9 @@
       "/path/to/tmp/json"
     ],
     "infra_step": true,
-    "name": "ensure_installed (4)",
+    "name": "install xcode (4).ensure_installed",
     "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@",
       "@@@STEP_LOG_LINE@json.output@{@@@",
       "@@@STEP_LOG_LINE@json.output@  \"result\": {@@@",
       "@@@STEP_LOG_LINE@json.output@    \"\": [@@@",
@@ -384,7 +416,11 @@
       "-verbose"
     ],
     "infra_step": true,
-    "name": "install xcode (4)"
+    "name": "install xcode (4).install xcode from cipd",
+    "timeout": 1800,
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@"
+    ]
   },
   {
     "cmd": [
@@ -403,7 +439,7 @@
       "/opt/flutter/xcode/deadbeef/XCode.app"
     ],
     "infra_step": true,
-    "name": "select XCode (4)"
+    "name": "select xcode (4)"
   },
   {
     "cmd": [
@@ -440,6 +476,15 @@
     "name": "reset XCode (2)"
   },
   {
+    "cmd": [
+      "sudo",
+      "xcode-select",
+      "--reset"
+    ],
+    "infra_step": true,
+    "name": "reset XCode (3)"
+  },
+  {
     "name": "$result"
   }
 ]
\ No newline at end of file
diff --git a/recipe_modules/osx_sdk/examples/full.expected/explicit_runtime_version.json b/recipe_modules/osx_sdk/examples/full.expected/explicit_runtime_version.json
index eaa45cd..a56c86a 100644
--- a/recipe_modules/osx_sdk/examples/full.expected/explicit_runtime_version.json
+++ b/recipe_modules/osx_sdk/examples/full.expected/explicit_runtime_version.json
@@ -9,6 +9,10 @@
     "name": "Show xcode cache"
   },
   {
+    "cmd": [],
+    "name": "install xcode"
+  },
+  {
     "cmd": [
       "cipd",
       "ensure",
@@ -22,8 +26,9 @@
       "/path/to/tmp/json"
     ],
     "infra_step": true,
-    "name": "ensure_installed",
+    "name": "install xcode.ensure_installed",
     "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@",
       "@@@STEP_LOG_LINE@json.output@{@@@",
       "@@@STEP_LOG_LINE@json.output@  \"result\": {@@@",
       "@@@STEP_LOG_LINE@json.output@    \"\": [@@@",
@@ -53,7 +58,11 @@
       "-verbose"
     ],
     "infra_step": true,
-    "name": "install xcode"
+    "name": "install xcode.install xcode from cipd",
+    "timeout": 1800,
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@"
+    ]
   },
   {
     "cmd": [],
@@ -164,7 +173,7 @@
       "[CACHE]/osx_sdk/xcode_deadbeef_runtime_ios-14-0_ios-13-0/XCode.app"
     ],
     "infra_step": true,
-    "name": "select XCode"
+    "name": "select xcode"
   },
   {
     "cmd": [
@@ -220,6 +229,10 @@
     "name": "Show xcode cache (2)"
   },
   {
+    "cmd": [],
+    "name": "install xcode (2)"
+  },
+  {
     "cmd": [
       "cipd",
       "ensure",
@@ -233,8 +246,9 @@
       "/path/to/tmp/json"
     ],
     "infra_step": true,
-    "name": "ensure_installed (2)",
+    "name": "install xcode (2).ensure_installed",
     "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@",
       "@@@STEP_LOG_LINE@json.output@{@@@",
       "@@@STEP_LOG_LINE@json.output@  \"result\": {@@@",
       "@@@STEP_LOG_LINE@json.output@    \"\": [@@@",
@@ -264,7 +278,11 @@
       "-verbose"
     ],
     "infra_step": true,
-    "name": "install xcode (2)"
+    "name": "install xcode (2).install xcode from cipd",
+    "timeout": 1800,
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@"
+    ]
   },
   {
     "cmd": [
@@ -283,7 +301,7 @@
       "/opt/flutter/xcode/deadbeef/XCode.app"
     ],
     "infra_step": true,
-    "name": "select XCode (2)"
+    "name": "select xcode (2)"
   },
   {
     "cmd": [
@@ -318,6 +336,10 @@
     "name": "Cleaning up Xcode cache"
   },
   {
+    "cmd": [],
+    "name": "install xcode (3)"
+  },
+  {
     "cmd": [
       "cipd",
       "ensure",
@@ -331,8 +353,9 @@
       "/path/to/tmp/json"
     ],
     "infra_step": true,
-    "name": "ensure_installed (3)",
+    "name": "install xcode (3).ensure_installed",
     "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@",
       "@@@STEP_LOG_LINE@json.output@{@@@",
       "@@@STEP_LOG_LINE@json.output@  \"result\": {@@@",
       "@@@STEP_LOG_LINE@json.output@    \"\": [@@@",
@@ -362,7 +385,11 @@
       "-verbose"
     ],
     "infra_step": true,
-    "name": "install xcode (3)"
+    "name": "install xcode (3).install xcode from cipd",
+    "timeout": 1800,
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@"
+    ]
   },
   {
     "cmd": [
@@ -381,7 +408,7 @@
       "/opt/flutter/xcode/deadbeef/XCode.app"
     ],
     "infra_step": true,
-    "name": "select XCode (3)"
+    "name": "select xcode (3)"
   },
   {
     "cmd": [
@@ -418,6 +445,15 @@
     "name": "reset XCode (2)"
   },
   {
+    "cmd": [
+      "sudo",
+      "xcode-select",
+      "--reset"
+    ],
+    "infra_step": true,
+    "name": "reset XCode (3)"
+  },
+  {
     "name": "$result"
   }
 ]
\ No newline at end of file
diff --git a/recipe_modules/osx_sdk/examples/full.expected/explicit_version.json b/recipe_modules/osx_sdk/examples/full.expected/explicit_version.json
index efe1a61..32da7dd 100644
--- a/recipe_modules/osx_sdk/examples/full.expected/explicit_version.json
+++ b/recipe_modules/osx_sdk/examples/full.expected/explicit_version.json
@@ -22,6 +22,10 @@
     "name": "Cleaning up Xcode cache"
   },
   {
+    "cmd": [],
+    "name": "install xcode"
+  },
+  {
     "cmd": [
       "cipd",
       "ensure",
@@ -35,8 +39,9 @@
       "/path/to/tmp/json"
     ],
     "infra_step": true,
-    "name": "ensure_installed",
+    "name": "install xcode.ensure_installed",
     "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@",
       "@@@STEP_LOG_LINE@json.output@{@@@",
       "@@@STEP_LOG_LINE@json.output@  \"result\": {@@@",
       "@@@STEP_LOG_LINE@json.output@    \"\": [@@@",
@@ -66,7 +71,11 @@
       "-verbose"
     ],
     "infra_step": true,
-    "name": "install xcode"
+    "name": "install xcode.install xcode from cipd",
+    "timeout": 1800,
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@"
+    ]
   },
   {
     "cmd": [
@@ -85,7 +94,7 @@
       "[CACHE]/osx_sdk/xcode_deadbeef/XCode.app"
     ],
     "infra_step": true,
-    "name": "select XCode"
+    "name": "select xcode"
   },
   {
     "cmd": [
@@ -120,6 +129,10 @@
     "name": "Cleaning up Xcode cache (2)"
   },
   {
+    "cmd": [],
+    "name": "install xcode (2)"
+  },
+  {
     "cmd": [
       "cipd",
       "ensure",
@@ -133,8 +146,9 @@
       "/path/to/tmp/json"
     ],
     "infra_step": true,
-    "name": "ensure_installed (2)",
+    "name": "install xcode (2).ensure_installed",
     "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@",
       "@@@STEP_LOG_LINE@json.output@{@@@",
       "@@@STEP_LOG_LINE@json.output@  \"result\": {@@@",
       "@@@STEP_LOG_LINE@json.output@    \"\": [@@@",
@@ -164,7 +178,11 @@
       "-verbose"
     ],
     "infra_step": true,
-    "name": "install xcode (2)"
+    "name": "install xcode (2).install xcode from cipd",
+    "timeout": 1800,
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@"
+    ]
   },
   {
     "cmd": [
@@ -183,7 +201,7 @@
       "[CACHE]/osx_sdk/xcode_deadbeef/XCode.app"
     ],
     "infra_step": true,
-    "name": "select XCode (2)"
+    "name": "select xcode (2)"
   },
   {
     "cmd": [
@@ -242,6 +260,10 @@
     "name": "Cleaning up Xcode cache (3)"
   },
   {
+    "cmd": [],
+    "name": "install xcode (3)"
+  },
+  {
     "cmd": [
       "cipd",
       "ensure",
@@ -255,8 +277,9 @@
       "/path/to/tmp/json"
     ],
     "infra_step": true,
-    "name": "ensure_installed (3)",
+    "name": "install xcode (3).ensure_installed",
     "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@",
       "@@@STEP_LOG_LINE@json.output@{@@@",
       "@@@STEP_LOG_LINE@json.output@  \"result\": {@@@",
       "@@@STEP_LOG_LINE@json.output@    \"\": [@@@",
@@ -286,7 +309,11 @@
       "-verbose"
     ],
     "infra_step": true,
-    "name": "install xcode (3)"
+    "name": "install xcode (3).install xcode from cipd",
+    "timeout": 1800,
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@"
+    ]
   },
   {
     "cmd": [
@@ -305,7 +332,7 @@
       "/opt/flutter/xcode/deadbeef/XCode.app"
     ],
     "infra_step": true,
-    "name": "select XCode (3)"
+    "name": "select xcode (3)"
   },
   {
     "cmd": [
@@ -340,6 +367,10 @@
     "name": "Cleaning up Xcode cache (4)"
   },
   {
+    "cmd": [],
+    "name": "install xcode (4)"
+  },
+  {
     "cmd": [
       "cipd",
       "ensure",
@@ -353,8 +384,9 @@
       "/path/to/tmp/json"
     ],
     "infra_step": true,
-    "name": "ensure_installed (4)",
+    "name": "install xcode (4).ensure_installed",
     "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@",
       "@@@STEP_LOG_LINE@json.output@{@@@",
       "@@@STEP_LOG_LINE@json.output@  \"result\": {@@@",
       "@@@STEP_LOG_LINE@json.output@    \"\": [@@@",
@@ -384,7 +416,11 @@
       "-verbose"
     ],
     "infra_step": true,
-    "name": "install xcode (4)"
+    "name": "install xcode (4).install xcode from cipd",
+    "timeout": 1800,
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@"
+    ]
   },
   {
     "cmd": [
@@ -403,7 +439,7 @@
       "/opt/flutter/xcode/deadbeef/XCode.app"
     ],
     "infra_step": true,
-    "name": "select XCode (4)"
+    "name": "select xcode (4)"
   },
   {
     "cmd": [
@@ -440,6 +476,15 @@
     "name": "reset XCode (2)"
   },
   {
+    "cmd": [
+      "sudo",
+      "xcode-select",
+      "--reset"
+    ],
+    "infra_step": true,
+    "name": "reset XCode (3)"
+  },
+  {
     "name": "$result"
   }
 ]
\ No newline at end of file
diff --git a/recipe_modules/osx_sdk/examples/full.expected/failed_to_delete_runtimes_err_in_stderr.json b/recipe_modules/osx_sdk/examples/full.expected/failed_to_delete_runtimes_err_in_stderr.json
index da01aad..61a901c 100644
--- a/recipe_modules/osx_sdk/examples/full.expected/failed_to_delete_runtimes_err_in_stderr.json
+++ b/recipe_modules/osx_sdk/examples/full.expected/failed_to_delete_runtimes_err_in_stderr.json
@@ -18,6 +18,10 @@
     "name": "Cleaning up Xcode cache"
   },
   {
+    "cmd": [],
+    "name": "install xcode"
+  },
+  {
     "cmd": [
       "cipd",
       "ensure",
@@ -31,8 +35,9 @@
       "/path/to/tmp/json"
     ],
     "infra_step": true,
-    "name": "ensure_installed",
+    "name": "install xcode.ensure_installed",
     "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@",
       "@@@STEP_LOG_LINE@json.output@{@@@",
       "@@@STEP_LOG_LINE@json.output@  \"result\": {@@@",
       "@@@STEP_LOG_LINE@json.output@    \"\": [@@@",
@@ -53,7 +58,10 @@
       "[CACHE]/osx_sdk/xcode_deadbeef_runtime_ios-16-4_14e300c_ios-16-2_14c18"
     ],
     "infra_step": true,
-    "name": "Show tool_dir cache"
+    "name": "install xcode.Show tool_dir cache",
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@"
+    ]
   },
   {
     "cmd": [
@@ -71,7 +79,11 @@
       "-verbose"
     ],
     "infra_step": true,
-    "name": "install xcode"
+    "name": "install xcode.install xcode from cipd",
+    "timeout": 1800,
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@"
+    ]
   },
   {
     "cmd": [],
@@ -88,7 +100,7 @@
       "[CACHE]/osx_sdk/xcode_deadbeef_runtime_ios-16-4_14e300c_ios-16-2_14c18/XCode.app"
     ],
     "infra_step": true,
-    "name": "Cleaning up runtimes cache.select XCode",
+    "name": "Cleaning up runtimes cache.select xcode",
     "~followup_annotations": [
       "@@@STEP_NEST_LEVEL@1@@@"
     ]
diff --git a/recipe_modules/osx_sdk/examples/full.expected/failed_to_delete_runtimes_err_in_stdout.json b/recipe_modules/osx_sdk/examples/full.expected/failed_to_delete_runtimes_err_in_stdout.json
index 3ed6373..083c8bb 100644
--- a/recipe_modules/osx_sdk/examples/full.expected/failed_to_delete_runtimes_err_in_stdout.json
+++ b/recipe_modules/osx_sdk/examples/full.expected/failed_to_delete_runtimes_err_in_stdout.json
@@ -18,6 +18,10 @@
     "name": "Cleaning up Xcode cache"
   },
   {
+    "cmd": [],
+    "name": "install xcode"
+  },
+  {
     "cmd": [
       "cipd",
       "ensure",
@@ -31,8 +35,9 @@
       "/path/to/tmp/json"
     ],
     "infra_step": true,
-    "name": "ensure_installed",
+    "name": "install xcode.ensure_installed",
     "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@",
       "@@@STEP_LOG_LINE@json.output@{@@@",
       "@@@STEP_LOG_LINE@json.output@  \"result\": {@@@",
       "@@@STEP_LOG_LINE@json.output@    \"\": [@@@",
@@ -53,7 +58,10 @@
       "[CACHE]/osx_sdk/xcode_deadbeef_runtime_ios-16-4_14e300c_ios-16-2_14c18"
     ],
     "infra_step": true,
-    "name": "Show tool_dir cache"
+    "name": "install xcode.Show tool_dir cache",
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@"
+    ]
   },
   {
     "cmd": [
@@ -71,7 +79,11 @@
       "-verbose"
     ],
     "infra_step": true,
-    "name": "install xcode"
+    "name": "install xcode.install xcode from cipd",
+    "timeout": 1800,
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@"
+    ]
   },
   {
     "cmd": [],
@@ -88,7 +100,7 @@
       "[CACHE]/osx_sdk/xcode_deadbeef_runtime_ios-16-4_14e300c_ios-16-2_14c18/XCode.app"
     ],
     "infra_step": true,
-    "name": "Cleaning up runtimes cache.select XCode",
+    "name": "Cleaning up runtimes cache.select xcode",
     "~followup_annotations": [
       "@@@STEP_NEST_LEVEL@1@@@"
     ]
diff --git a/recipe_modules/osx_sdk/examples/full.expected/mac.json b/recipe_modules/osx_sdk/examples/full.expected/mac.json
index 2e04610..9e6df99 100644
--- a/recipe_modules/osx_sdk/examples/full.expected/mac.json
+++ b/recipe_modules/osx_sdk/examples/full.expected/mac.json
@@ -9,6 +9,10 @@
     "name": "Show xcode cache"
   },
   {
+    "cmd": [],
+    "name": "install xcode"
+  },
+  {
     "cmd": [
       "cipd",
       "ensure",
@@ -22,8 +26,9 @@
       "/path/to/tmp/json"
     ],
     "infra_step": true,
-    "name": "ensure_installed",
+    "name": "install xcode.ensure_installed",
     "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@",
       "@@@STEP_LOG_LINE@json.output@{@@@",
       "@@@STEP_LOG_LINE@json.output@  \"result\": {@@@",
       "@@@STEP_LOG_LINE@json.output@    \"\": [@@@",
@@ -53,7 +58,11 @@
       "-verbose"
     ],
     "infra_step": true,
-    "name": "install xcode"
+    "name": "install xcode.install xcode from cipd",
+    "timeout": 1800,
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@"
+    ]
   },
   {
     "cmd": [
@@ -72,7 +81,7 @@
       "[CACHE]/osx_sdk/xcode_9f2000/XCode.app"
     ],
     "infra_step": true,
-    "name": "select XCode"
+    "name": "select xcode"
   },
   {
     "cmd": [
@@ -107,6 +116,10 @@
     "name": "Cleaning up Xcode cache"
   },
   {
+    "cmd": [],
+    "name": "install xcode (2)"
+  },
+  {
     "cmd": [
       "cipd",
       "ensure",
@@ -120,8 +133,9 @@
       "/path/to/tmp/json"
     ],
     "infra_step": true,
-    "name": "ensure_installed (2)",
+    "name": "install xcode (2).ensure_installed",
     "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@",
       "@@@STEP_LOG_LINE@json.output@{@@@",
       "@@@STEP_LOG_LINE@json.output@  \"result\": {@@@",
       "@@@STEP_LOG_LINE@json.output@    \"\": [@@@",
@@ -151,7 +165,11 @@
       "-verbose"
     ],
     "infra_step": true,
-    "name": "install xcode (2)"
+    "name": "install xcode (2).install xcode from cipd",
+    "timeout": 1800,
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@"
+    ]
   },
   {
     "cmd": [
@@ -170,7 +188,7 @@
       "[CACHE]/osx_sdk/xcode_9f2000/XCode.app"
     ],
     "infra_step": true,
-    "name": "select XCode (2)"
+    "name": "select xcode (2)"
   },
   {
     "cmd": [
@@ -229,6 +247,10 @@
     "name": "Cleaning up Xcode cache (2)"
   },
   {
+    "cmd": [],
+    "name": "install xcode (3)"
+  },
+  {
     "cmd": [
       "cipd",
       "ensure",
@@ -242,8 +264,9 @@
       "/path/to/tmp/json"
     ],
     "infra_step": true,
-    "name": "ensure_installed (3)",
+    "name": "install xcode (3).ensure_installed",
     "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@",
       "@@@STEP_LOG_LINE@json.output@{@@@",
       "@@@STEP_LOG_LINE@json.output@  \"result\": {@@@",
       "@@@STEP_LOG_LINE@json.output@    \"\": [@@@",
@@ -273,7 +296,11 @@
       "-verbose"
     ],
     "infra_step": true,
-    "name": "install xcode (3)"
+    "name": "install xcode (3).install xcode from cipd",
+    "timeout": 1800,
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@"
+    ]
   },
   {
     "cmd": [
@@ -292,7 +319,7 @@
       "/opt/flutter/xcode/9f2000/XCode.app"
     ],
     "infra_step": true,
-    "name": "select XCode (3)"
+    "name": "select xcode (3)"
   },
   {
     "cmd": [
@@ -327,6 +354,10 @@
     "name": "Cleaning up Xcode cache (3)"
   },
   {
+    "cmd": [],
+    "name": "install xcode (4)"
+  },
+  {
     "cmd": [
       "cipd",
       "ensure",
@@ -340,8 +371,9 @@
       "/path/to/tmp/json"
     ],
     "infra_step": true,
-    "name": "ensure_installed (4)",
+    "name": "install xcode (4).ensure_installed",
     "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@",
       "@@@STEP_LOG_LINE@json.output@{@@@",
       "@@@STEP_LOG_LINE@json.output@  \"result\": {@@@",
       "@@@STEP_LOG_LINE@json.output@    \"\": [@@@",
@@ -371,7 +403,11 @@
       "-verbose"
     ],
     "infra_step": true,
-    "name": "install xcode (4)"
+    "name": "install xcode (4).install xcode from cipd",
+    "timeout": 1800,
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@"
+    ]
   },
   {
     "cmd": [
@@ -390,7 +426,7 @@
       "/opt/flutter/xcode/9f2000/XCode.app"
     ],
     "infra_step": true,
-    "name": "select XCode (4)"
+    "name": "select xcode (4)"
   },
   {
     "cmd": [
@@ -427,6 +463,15 @@
     "name": "reset XCode (2)"
   },
   {
+    "cmd": [
+      "sudo",
+      "xcode-select",
+      "--reset"
+    ],
+    "infra_step": true,
+    "name": "reset XCode (3)"
+  },
+  {
     "name": "$result"
   }
 ]
\ No newline at end of file
diff --git a/recipe_modules/osx_sdk/examples/full.expected/mac_13_arm_host.json b/recipe_modules/osx_sdk/examples/full.expected/mac_13_arm_host.json
index a7bb723..fb9de50 100644
--- a/recipe_modules/osx_sdk/examples/full.expected/mac_13_arm_host.json
+++ b/recipe_modules/osx_sdk/examples/full.expected/mac_13_arm_host.json
@@ -9,6 +9,10 @@
     "name": "Show xcode cache"
   },
   {
+    "cmd": [],
+    "name": "install xcode"
+  },
+  {
     "cmd": [
       "cipd",
       "ensure",
@@ -22,8 +26,9 @@
       "/path/to/tmp/json"
     ],
     "infra_step": true,
-    "name": "ensure_installed",
+    "name": "install xcode.ensure_installed",
     "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@",
       "@@@STEP_LOG_LINE@json.output@{@@@",
       "@@@STEP_LOG_LINE@json.output@  \"result\": {@@@",
       "@@@STEP_LOG_LINE@json.output@    \"\": [@@@",
@@ -44,7 +49,10 @@
       "[CACHE]/osx_sdk/xcode_deadbeef"
     ],
     "infra_step": true,
-    "name": "Show tool_dir cache"
+    "name": "install xcode.Show tool_dir cache",
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@"
+    ]
   },
   {
     "cmd": [
@@ -62,7 +70,11 @@
       "-verbose"
     ],
     "infra_step": true,
-    "name": "install xcode"
+    "name": "install xcode.install xcode from cipd",
+    "timeout": 1800,
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@"
+    ]
   },
   {
     "cmd": [
@@ -81,7 +93,7 @@
       "[CACHE]/osx_sdk/xcode_deadbeef/XCode.app"
     ],
     "infra_step": true,
-    "name": "select XCode"
+    "name": "select xcode"
   },
   {
     "cmd": [
@@ -112,6 +124,10 @@
     "name": "Cleaning up Xcode cache"
   },
   {
+    "cmd": [],
+    "name": "install xcode (2)"
+  },
+  {
     "cmd": [
       "cipd",
       "ensure",
@@ -125,8 +141,9 @@
       "/path/to/tmp/json"
     ],
     "infra_step": true,
-    "name": "ensure_installed (2)",
+    "name": "install xcode (2).ensure_installed",
     "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@",
       "@@@STEP_LOG_LINE@json.output@{@@@",
       "@@@STEP_LOG_LINE@json.output@  \"result\": {@@@",
       "@@@STEP_LOG_LINE@json.output@    \"\": [@@@",
@@ -147,7 +164,10 @@
       "[CACHE]/osx_sdk/xcode_deadbeef"
     ],
     "infra_step": true,
-    "name": "Show tool_dir cache (2)"
+    "name": "install xcode (2).Show tool_dir cache",
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@"
+    ]
   },
   {
     "cmd": [
@@ -165,7 +185,11 @@
       "-verbose"
     ],
     "infra_step": true,
-    "name": "install xcode (2)"
+    "name": "install xcode (2).install xcode from cipd",
+    "timeout": 1800,
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@"
+    ]
   },
   {
     "cmd": [],
@@ -179,7 +203,7 @@
       "[CACHE]/osx_sdk/xcode_deadbeef/XCode.app"
     ],
     "infra_step": true,
-    "name": "Cleaning up runtimes cache.select XCode",
+    "name": "Cleaning up runtimes cache.select xcode",
     "~followup_annotations": [
       "@@@STEP_NEST_LEVEL@1@@@"
     ]
@@ -218,6 +242,13 @@
     "name": "install runtimes"
   },
   {
+    "cmd": [],
+    "name": "install runtimes.install xcode",
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@"
+    ]
+  },
+  {
     "cmd": [
       "cipd",
       "ensure",
@@ -231,9 +262,9 @@
       "/path/to/tmp/json"
     ],
     "infra_step": true,
-    "name": "install runtimes.ensure_installed",
+    "name": "install runtimes.install xcode.ensure_installed",
     "~followup_annotations": [
-      "@@@STEP_NEST_LEVEL@1@@@",
+      "@@@STEP_NEST_LEVEL@2@@@",
       "@@@STEP_LOG_LINE@json.output@{@@@",
       "@@@STEP_LOG_LINE@json.output@  \"result\": {@@@",
       "@@@STEP_LOG_LINE@json.output@    \"\": [@@@",
@@ -254,9 +285,9 @@
       "[CACHE]/osx_sdk/xcode_deadbeef"
     ],
     "infra_step": true,
-    "name": "install runtimes.Show tool_dir cache",
+    "name": "install runtimes.install xcode.Show tool_dir cache",
     "~followup_annotations": [
-      "@@@STEP_NEST_LEVEL@1@@@"
+      "@@@STEP_NEST_LEVEL@2@@@"
     ]
   },
   {
@@ -275,9 +306,10 @@
       "-verbose"
     ],
     "infra_step": true,
-    "name": "install runtimes.install xcode",
+    "name": "install runtimes.install xcode.install xcode from cipd",
+    "timeout": 1800,
     "~followup_annotations": [
-      "@@@STEP_NEST_LEVEL@1@@@"
+      "@@@STEP_NEST_LEVEL@2@@@"
     ]
   },
   {
@@ -297,7 +329,7 @@
       "[CACHE]/osx_sdk/xcode_deadbeef/XCode.app"
     ],
     "infra_step": true,
-    "name": "select XCode (2)"
+    "name": "select xcode (2)"
   },
   {
     "cmd": [
@@ -356,6 +388,10 @@
     "name": "Cleaning up Xcode cache (2)"
   },
   {
+    "cmd": [],
+    "name": "install xcode (3)"
+  },
+  {
     "cmd": [
       "cipd",
       "ensure",
@@ -369,8 +405,9 @@
       "/path/to/tmp/json"
     ],
     "infra_step": true,
-    "name": "ensure_installed (3)",
+    "name": "install xcode (3).ensure_installed",
     "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@",
       "@@@STEP_LOG_LINE@json.output@{@@@",
       "@@@STEP_LOG_LINE@json.output@  \"result\": {@@@",
       "@@@STEP_LOG_LINE@json.output@    \"\": [@@@",
@@ -391,7 +428,10 @@
       "[CLEANUP]/tmp_tmp_1/osx_sdk"
     ],
     "infra_step": true,
-    "name": "Show tool_dir cache (3)"
+    "name": "install xcode (3).Show tool_dir cache",
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@"
+    ]
   },
   {
     "cmd": [
@@ -409,7 +449,11 @@
       "-verbose"
     ],
     "infra_step": true,
-    "name": "install xcode (3)"
+    "name": "install xcode (3).install xcode from cipd",
+    "timeout": 1800,
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@"
+    ]
   },
   {
     "cmd": [],
@@ -423,7 +467,7 @@
       "/opt/flutter/xcode/deadbeef/XCode.app"
     ],
     "infra_step": true,
-    "name": "Cleaning up runtimes cache (2).select XCode",
+    "name": "Cleaning up runtimes cache (2).select xcode",
     "~followup_annotations": [
       "@@@STEP_NEST_LEVEL@1@@@"
     ]
@@ -462,6 +506,13 @@
     "name": "install runtimes (2)"
   },
   {
+    "cmd": [],
+    "name": "install runtimes (2).install xcode",
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@"
+    ]
+  },
+  {
     "cmd": [
       "cipd",
       "ensure",
@@ -475,9 +526,9 @@
       "/path/to/tmp/json"
     ],
     "infra_step": true,
-    "name": "install runtimes (2).ensure_installed",
+    "name": "install runtimes (2).install xcode.ensure_installed",
     "~followup_annotations": [
-      "@@@STEP_NEST_LEVEL@1@@@",
+      "@@@STEP_NEST_LEVEL@2@@@",
       "@@@STEP_LOG_LINE@json.output@{@@@",
       "@@@STEP_LOG_LINE@json.output@  \"result\": {@@@",
       "@@@STEP_LOG_LINE@json.output@    \"\": [@@@",
@@ -498,9 +549,9 @@
       "[CLEANUP]/tmp_tmp_1/osx_sdk"
     ],
     "infra_step": true,
-    "name": "install runtimes (2).Show tool_dir cache",
+    "name": "install runtimes (2).install xcode.Show tool_dir cache",
     "~followup_annotations": [
-      "@@@STEP_NEST_LEVEL@1@@@"
+      "@@@STEP_NEST_LEVEL@2@@@"
     ]
   },
   {
@@ -519,9 +570,10 @@
       "-verbose"
     ],
     "infra_step": true,
-    "name": "install runtimes (2).install xcode",
+    "name": "install runtimes (2).install xcode.install xcode from cipd",
+    "timeout": 1800,
     "~followup_annotations": [
-      "@@@STEP_NEST_LEVEL@1@@@"
+      "@@@STEP_NEST_LEVEL@2@@@"
     ]
   },
   {
@@ -541,7 +593,7 @@
       "/opt/flutter/xcode/deadbeef/XCode.app"
     ],
     "infra_step": true,
-    "name": "select XCode (3)"
+    "name": "select xcode (3)"
   },
   {
     "cmd": [
@@ -576,6 +628,10 @@
     "name": "Cleaning up Xcode cache (3)"
   },
   {
+    "cmd": [],
+    "name": "install xcode (4)"
+  },
+  {
     "cmd": [
       "cipd",
       "ensure",
@@ -589,8 +645,9 @@
       "/path/to/tmp/json"
     ],
     "infra_step": true,
-    "name": "ensure_installed (4)",
+    "name": "install xcode (4).ensure_installed",
     "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@",
       "@@@STEP_LOG_LINE@json.output@{@@@",
       "@@@STEP_LOG_LINE@json.output@  \"result\": {@@@",
       "@@@STEP_LOG_LINE@json.output@    \"\": [@@@",
@@ -611,7 +668,10 @@
       "[CLEANUP]/tmp_tmp_2/osx_sdk"
     ],
     "infra_step": true,
-    "name": "Show tool_dir cache (4)"
+    "name": "install xcode (4).Show tool_dir cache",
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@"
+    ]
   },
   {
     "cmd": [
@@ -629,7 +689,11 @@
       "-verbose"
     ],
     "infra_step": true,
-    "name": "install xcode (4)"
+    "name": "install xcode (4).install xcode from cipd",
+    "timeout": 1800,
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@"
+    ]
   },
   {
     "cmd": [],
@@ -643,7 +707,7 @@
       "/opt/flutter/xcode/deadbeef/XCode.app"
     ],
     "infra_step": true,
-    "name": "Cleaning up runtimes cache (3).select XCode",
+    "name": "Cleaning up runtimes cache (3).select xcode",
     "~followup_annotations": [
       "@@@STEP_NEST_LEVEL@1@@@"
     ]
@@ -682,6 +746,13 @@
     "name": "install runtimes (3)"
   },
   {
+    "cmd": [],
+    "name": "install runtimes (3).install xcode",
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@"
+    ]
+  },
+  {
     "cmd": [
       "cipd",
       "ensure",
@@ -695,9 +766,9 @@
       "/path/to/tmp/json"
     ],
     "infra_step": true,
-    "name": "install runtimes (3).ensure_installed",
+    "name": "install runtimes (3).install xcode.ensure_installed",
     "~followup_annotations": [
-      "@@@STEP_NEST_LEVEL@1@@@",
+      "@@@STEP_NEST_LEVEL@2@@@",
       "@@@STEP_LOG_LINE@json.output@{@@@",
       "@@@STEP_LOG_LINE@json.output@  \"result\": {@@@",
       "@@@STEP_LOG_LINE@json.output@    \"\": [@@@",
@@ -718,9 +789,9 @@
       "[CLEANUP]/tmp_tmp_2/osx_sdk"
     ],
     "infra_step": true,
-    "name": "install runtimes (3).Show tool_dir cache",
+    "name": "install runtimes (3).install xcode.Show tool_dir cache",
     "~followup_annotations": [
-      "@@@STEP_NEST_LEVEL@1@@@"
+      "@@@STEP_NEST_LEVEL@2@@@"
     ]
   },
   {
@@ -739,9 +810,10 @@
       "-verbose"
     ],
     "infra_step": true,
-    "name": "install runtimes (3).install xcode",
+    "name": "install runtimes (3).install xcode.install xcode from cipd",
+    "timeout": 1800,
     "~followup_annotations": [
-      "@@@STEP_NEST_LEVEL@1@@@"
+      "@@@STEP_NEST_LEVEL@2@@@"
     ]
   },
   {
@@ -761,7 +833,7 @@
       "/opt/flutter/xcode/deadbeef/XCode.app"
     ],
     "infra_step": true,
-    "name": "select XCode (4)"
+    "name": "select xcode (4)"
   },
   {
     "cmd": [
@@ -798,6 +870,15 @@
     "name": "reset XCode (2)"
   },
   {
+    "cmd": [
+      "sudo",
+      "xcode-select",
+      "--reset"
+    ],
+    "infra_step": true,
+    "name": "reset XCode (3)"
+  },
+  {
     "name": "$result"
   }
 ]
\ No newline at end of file
diff --git a/recipe_modules/osx_sdk/examples/full.expected/mac_13_cleanup_no_runtimes.json b/recipe_modules/osx_sdk/examples/full.expected/mac_13_cleanup_no_runtimes.json
index 2b28763..81bcac0 100644
--- a/recipe_modules/osx_sdk/examples/full.expected/mac_13_cleanup_no_runtimes.json
+++ b/recipe_modules/osx_sdk/examples/full.expected/mac_13_cleanup_no_runtimes.json
@@ -18,6 +18,10 @@
     "name": "Cleaning up Xcode cache"
   },
   {
+    "cmd": [],
+    "name": "install xcode"
+  },
+  {
     "cmd": [
       "cipd",
       "ensure",
@@ -31,8 +35,9 @@
       "/path/to/tmp/json"
     ],
     "infra_step": true,
-    "name": "ensure_installed",
+    "name": "install xcode.ensure_installed",
     "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@",
       "@@@STEP_LOG_LINE@json.output@{@@@",
       "@@@STEP_LOG_LINE@json.output@  \"result\": {@@@",
       "@@@STEP_LOG_LINE@json.output@    \"\": [@@@",
@@ -53,7 +58,10 @@
       "[CACHE]/osx_sdk/xcode_deadbeef"
     ],
     "infra_step": true,
-    "name": "Show tool_dir cache"
+    "name": "install xcode.Show tool_dir cache",
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@"
+    ]
   },
   {
     "cmd": [
@@ -71,7 +79,11 @@
       "-verbose"
     ],
     "infra_step": true,
-    "name": "install xcode"
+    "name": "install xcode.install xcode from cipd",
+    "timeout": 1800,
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@"
+    ]
   },
   {
     "cmd": [],
@@ -85,7 +97,7 @@
       "[CACHE]/osx_sdk/xcode_deadbeef/XCode.app"
     ],
     "infra_step": true,
-    "name": "Cleaning up runtimes cache.select XCode",
+    "name": "Cleaning up runtimes cache.select xcode",
     "~followup_annotations": [
       "@@@STEP_NEST_LEVEL@1@@@"
     ]
@@ -124,6 +136,13 @@
     "name": "install runtimes"
   },
   {
+    "cmd": [],
+    "name": "install runtimes.install xcode",
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@"
+    ]
+  },
+  {
     "cmd": [
       "cipd",
       "ensure",
@@ -137,9 +156,9 @@
       "/path/to/tmp/json"
     ],
     "infra_step": true,
-    "name": "install runtimes.ensure_installed",
+    "name": "install runtimes.install xcode.ensure_installed",
     "~followup_annotations": [
-      "@@@STEP_NEST_LEVEL@1@@@",
+      "@@@STEP_NEST_LEVEL@2@@@",
       "@@@STEP_LOG_LINE@json.output@{@@@",
       "@@@STEP_LOG_LINE@json.output@  \"result\": {@@@",
       "@@@STEP_LOG_LINE@json.output@    \"\": [@@@",
@@ -160,9 +179,9 @@
       "[CACHE]/osx_sdk/xcode_deadbeef"
     ],
     "infra_step": true,
-    "name": "install runtimes.Show tool_dir cache",
+    "name": "install runtimes.install xcode.Show tool_dir cache",
     "~followup_annotations": [
-      "@@@STEP_NEST_LEVEL@1@@@"
+      "@@@STEP_NEST_LEVEL@2@@@"
     ]
   },
   {
@@ -181,9 +200,10 @@
       "-verbose"
     ],
     "infra_step": true,
-    "name": "install runtimes.install xcode",
+    "name": "install runtimes.install xcode.install xcode from cipd",
+    "timeout": 1800,
     "~followup_annotations": [
-      "@@@STEP_NEST_LEVEL@1@@@"
+      "@@@STEP_NEST_LEVEL@2@@@"
     ]
   },
   {
@@ -203,7 +223,7 @@
       "[CACHE]/osx_sdk/xcode_deadbeef/XCode.app"
     ],
     "infra_step": true,
-    "name": "select XCode"
+    "name": "select xcode"
   },
   {
     "cmd": [
@@ -234,6 +254,10 @@
     "name": "Cleaning up Xcode cache (2)"
   },
   {
+    "cmd": [],
+    "name": "install xcode (2)"
+  },
+  {
     "cmd": [
       "cipd",
       "ensure",
@@ -247,8 +271,9 @@
       "/path/to/tmp/json"
     ],
     "infra_step": true,
-    "name": "ensure_installed (2)",
+    "name": "install xcode (2).ensure_installed",
     "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@",
       "@@@STEP_LOG_LINE@json.output@{@@@",
       "@@@STEP_LOG_LINE@json.output@  \"result\": {@@@",
       "@@@STEP_LOG_LINE@json.output@    \"\": [@@@",
@@ -269,7 +294,10 @@
       "[CACHE]/osx_sdk/xcode_deadbeef"
     ],
     "infra_step": true,
-    "name": "Show tool_dir cache (2)"
+    "name": "install xcode (2).Show tool_dir cache",
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@"
+    ]
   },
   {
     "cmd": [
@@ -287,7 +315,11 @@
       "-verbose"
     ],
     "infra_step": true,
-    "name": "install xcode (2)"
+    "name": "install xcode (2).install xcode from cipd",
+    "timeout": 1800,
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@"
+    ]
   },
   {
     "cmd": [],
@@ -301,7 +333,7 @@
       "[CACHE]/osx_sdk/xcode_deadbeef/XCode.app"
     ],
     "infra_step": true,
-    "name": "Cleaning up runtimes cache (2).select XCode",
+    "name": "Cleaning up runtimes cache (2).select xcode",
     "~followup_annotations": [
       "@@@STEP_NEST_LEVEL@1@@@"
     ]
@@ -340,6 +372,13 @@
     "name": "install runtimes (2)"
   },
   {
+    "cmd": [],
+    "name": "install runtimes (2).install xcode",
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@"
+    ]
+  },
+  {
     "cmd": [
       "cipd",
       "ensure",
@@ -353,9 +392,9 @@
       "/path/to/tmp/json"
     ],
     "infra_step": true,
-    "name": "install runtimes (2).ensure_installed",
+    "name": "install runtimes (2).install xcode.ensure_installed",
     "~followup_annotations": [
-      "@@@STEP_NEST_LEVEL@1@@@",
+      "@@@STEP_NEST_LEVEL@2@@@",
       "@@@STEP_LOG_LINE@json.output@{@@@",
       "@@@STEP_LOG_LINE@json.output@  \"result\": {@@@",
       "@@@STEP_LOG_LINE@json.output@    \"\": [@@@",
@@ -376,9 +415,9 @@
       "[CACHE]/osx_sdk/xcode_deadbeef"
     ],
     "infra_step": true,
-    "name": "install runtimes (2).Show tool_dir cache",
+    "name": "install runtimes (2).install xcode.Show tool_dir cache",
     "~followup_annotations": [
-      "@@@STEP_NEST_LEVEL@1@@@"
+      "@@@STEP_NEST_LEVEL@2@@@"
     ]
   },
   {
@@ -397,9 +436,10 @@
       "-verbose"
     ],
     "infra_step": true,
-    "name": "install runtimes (2).install xcode",
+    "name": "install runtimes (2).install xcode.install xcode from cipd",
+    "timeout": 1800,
     "~followup_annotations": [
-      "@@@STEP_NEST_LEVEL@1@@@"
+      "@@@STEP_NEST_LEVEL@2@@@"
     ]
   },
   {
@@ -419,7 +459,7 @@
       "[CACHE]/osx_sdk/xcode_deadbeef/XCode.app"
     ],
     "infra_step": true,
-    "name": "select XCode (2)"
+    "name": "select xcode (2)"
   },
   {
     "cmd": [
@@ -478,6 +518,10 @@
     "name": "Cleaning up Xcode cache (3)"
   },
   {
+    "cmd": [],
+    "name": "install xcode (3)"
+  },
+  {
     "cmd": [
       "cipd",
       "ensure",
@@ -491,8 +535,9 @@
       "/path/to/tmp/json"
     ],
     "infra_step": true,
-    "name": "ensure_installed (3)",
+    "name": "install xcode (3).ensure_installed",
     "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@",
       "@@@STEP_LOG_LINE@json.output@{@@@",
       "@@@STEP_LOG_LINE@json.output@  \"result\": {@@@",
       "@@@STEP_LOG_LINE@json.output@    \"\": [@@@",
@@ -513,7 +558,10 @@
       "[CLEANUP]/tmp_tmp_1/osx_sdk"
     ],
     "infra_step": true,
-    "name": "Show tool_dir cache (3)"
+    "name": "install xcode (3).Show tool_dir cache",
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@"
+    ]
   },
   {
     "cmd": [
@@ -531,7 +579,11 @@
       "-verbose"
     ],
     "infra_step": true,
-    "name": "install xcode (3)"
+    "name": "install xcode (3).install xcode from cipd",
+    "timeout": 1800,
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@"
+    ]
   },
   {
     "cmd": [],
@@ -545,7 +597,7 @@
       "/opt/flutter/xcode/deadbeef/XCode.app"
     ],
     "infra_step": true,
-    "name": "Cleaning up runtimes cache (3).select XCode",
+    "name": "Cleaning up runtimes cache (3).select xcode",
     "~followup_annotations": [
       "@@@STEP_NEST_LEVEL@1@@@"
     ]
@@ -584,6 +636,13 @@
     "name": "install runtimes (3)"
   },
   {
+    "cmd": [],
+    "name": "install runtimes (3).install xcode",
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@"
+    ]
+  },
+  {
     "cmd": [
       "cipd",
       "ensure",
@@ -597,9 +656,9 @@
       "/path/to/tmp/json"
     ],
     "infra_step": true,
-    "name": "install runtimes (3).ensure_installed",
+    "name": "install runtimes (3).install xcode.ensure_installed",
     "~followup_annotations": [
-      "@@@STEP_NEST_LEVEL@1@@@",
+      "@@@STEP_NEST_LEVEL@2@@@",
       "@@@STEP_LOG_LINE@json.output@{@@@",
       "@@@STEP_LOG_LINE@json.output@  \"result\": {@@@",
       "@@@STEP_LOG_LINE@json.output@    \"\": [@@@",
@@ -620,9 +679,9 @@
       "[CLEANUP]/tmp_tmp_1/osx_sdk"
     ],
     "infra_step": true,
-    "name": "install runtimes (3).Show tool_dir cache",
+    "name": "install runtimes (3).install xcode.Show tool_dir cache",
     "~followup_annotations": [
-      "@@@STEP_NEST_LEVEL@1@@@"
+      "@@@STEP_NEST_LEVEL@2@@@"
     ]
   },
   {
@@ -641,9 +700,10 @@
       "-verbose"
     ],
     "infra_step": true,
-    "name": "install runtimes (3).install xcode",
+    "name": "install runtimes (3).install xcode.install xcode from cipd",
+    "timeout": 1800,
     "~followup_annotations": [
-      "@@@STEP_NEST_LEVEL@1@@@"
+      "@@@STEP_NEST_LEVEL@2@@@"
     ]
   },
   {
@@ -663,7 +723,7 @@
       "/opt/flutter/xcode/deadbeef/XCode.app"
     ],
     "infra_step": true,
-    "name": "select XCode (3)"
+    "name": "select xcode (3)"
   },
   {
     "cmd": [
@@ -698,6 +758,10 @@
     "name": "Cleaning up Xcode cache (4)"
   },
   {
+    "cmd": [],
+    "name": "install xcode (4)"
+  },
+  {
     "cmd": [
       "cipd",
       "ensure",
@@ -711,8 +775,9 @@
       "/path/to/tmp/json"
     ],
     "infra_step": true,
-    "name": "ensure_installed (4)",
+    "name": "install xcode (4).ensure_installed",
     "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@",
       "@@@STEP_LOG_LINE@json.output@{@@@",
       "@@@STEP_LOG_LINE@json.output@  \"result\": {@@@",
       "@@@STEP_LOG_LINE@json.output@    \"\": [@@@",
@@ -733,7 +798,10 @@
       "[CLEANUP]/tmp_tmp_2/osx_sdk"
     ],
     "infra_step": true,
-    "name": "Show tool_dir cache (4)"
+    "name": "install xcode (4).Show tool_dir cache",
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@"
+    ]
   },
   {
     "cmd": [
@@ -751,7 +819,11 @@
       "-verbose"
     ],
     "infra_step": true,
-    "name": "install xcode (4)"
+    "name": "install xcode (4).install xcode from cipd",
+    "timeout": 1800,
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@"
+    ]
   },
   {
     "cmd": [],
@@ -765,7 +837,7 @@
       "/opt/flutter/xcode/deadbeef/XCode.app"
     ],
     "infra_step": true,
-    "name": "Cleaning up runtimes cache (4).select XCode",
+    "name": "Cleaning up runtimes cache (4).select xcode",
     "~followup_annotations": [
       "@@@STEP_NEST_LEVEL@1@@@"
     ]
@@ -804,6 +876,13 @@
     "name": "install runtimes (4)"
   },
   {
+    "cmd": [],
+    "name": "install runtimes (4).install xcode",
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@"
+    ]
+  },
+  {
     "cmd": [
       "cipd",
       "ensure",
@@ -817,9 +896,9 @@
       "/path/to/tmp/json"
     ],
     "infra_step": true,
-    "name": "install runtimes (4).ensure_installed",
+    "name": "install runtimes (4).install xcode.ensure_installed",
     "~followup_annotations": [
-      "@@@STEP_NEST_LEVEL@1@@@",
+      "@@@STEP_NEST_LEVEL@2@@@",
       "@@@STEP_LOG_LINE@json.output@{@@@",
       "@@@STEP_LOG_LINE@json.output@  \"result\": {@@@",
       "@@@STEP_LOG_LINE@json.output@    \"\": [@@@",
@@ -840,9 +919,9 @@
       "[CLEANUP]/tmp_tmp_2/osx_sdk"
     ],
     "infra_step": true,
-    "name": "install runtimes (4).Show tool_dir cache",
+    "name": "install runtimes (4).install xcode.Show tool_dir cache",
     "~followup_annotations": [
-      "@@@STEP_NEST_LEVEL@1@@@"
+      "@@@STEP_NEST_LEVEL@2@@@"
     ]
   },
   {
@@ -861,9 +940,10 @@
       "-verbose"
     ],
     "infra_step": true,
-    "name": "install runtimes (4).install xcode",
+    "name": "install runtimes (4).install xcode.install xcode from cipd",
+    "timeout": 1800,
     "~followup_annotations": [
-      "@@@STEP_NEST_LEVEL@1@@@"
+      "@@@STEP_NEST_LEVEL@2@@@"
     ]
   },
   {
@@ -883,7 +963,7 @@
       "/opt/flutter/xcode/deadbeef/XCode.app"
     ],
     "infra_step": true,
-    "name": "select XCode (4)"
+    "name": "select xcode (4)"
   },
   {
     "cmd": [
@@ -920,6 +1000,15 @@
     "name": "reset XCode (2)"
   },
   {
+    "cmd": [
+      "sudo",
+      "xcode-select",
+      "--reset"
+    ],
+    "infra_step": true,
+    "name": "reset XCode (3)"
+  },
+  {
     "name": "$result"
   }
 ]
\ No newline at end of file
diff --git a/recipe_modules/osx_sdk/examples/full.expected/mac_13_explicit_runtime_version_already_mounted.json b/recipe_modules/osx_sdk/examples/full.expected/mac_13_explicit_runtime_version_already_mounted.json
index 6ef0e73..5844b51 100644
--- a/recipe_modules/osx_sdk/examples/full.expected/mac_13_explicit_runtime_version_already_mounted.json
+++ b/recipe_modules/osx_sdk/examples/full.expected/mac_13_explicit_runtime_version_already_mounted.json
@@ -9,6 +9,10 @@
     "name": "Show xcode cache"
   },
   {
+    "cmd": [],
+    "name": "install xcode"
+  },
+  {
     "cmd": [
       "cipd",
       "ensure",
@@ -22,8 +26,9 @@
       "/path/to/tmp/json"
     ],
     "infra_step": true,
-    "name": "ensure_installed",
+    "name": "install xcode.ensure_installed",
     "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@",
       "@@@STEP_LOG_LINE@json.output@{@@@",
       "@@@STEP_LOG_LINE@json.output@  \"result\": {@@@",
       "@@@STEP_LOG_LINE@json.output@    \"\": [@@@",
@@ -44,7 +49,10 @@
       "[CACHE]/osx_sdk/xcode_deadbeef_runtime_ios-16-4_14e300c"
     ],
     "infra_step": true,
-    "name": "Show tool_dir cache"
+    "name": "install xcode.Show tool_dir cache",
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@"
+    ]
   },
   {
     "cmd": [
@@ -62,7 +70,11 @@
       "-verbose"
     ],
     "infra_step": true,
-    "name": "install xcode"
+    "name": "install xcode.install xcode from cipd",
+    "timeout": 1800,
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@"
+    ]
   },
   {
     "cmd": [],
@@ -76,7 +88,7 @@
       "[CACHE]/osx_sdk/xcode_deadbeef_runtime_ios-16-4_14e300c/XCode.app"
     ],
     "infra_step": true,
-    "name": "install runtimes.select XCode",
+    "name": "install runtimes.select xcode",
     "~followup_annotations": [
       "@@@STEP_NEST_LEVEL@1@@@"
     ]
@@ -257,7 +269,7 @@
       "[CACHE]/osx_sdk/xcode_deadbeef_runtime_ios-16-4_14e300c/XCode.app"
     ],
     "infra_step": true,
-    "name": "select XCode"
+    "name": "select xcode"
   },
   {
     "cmd": [
@@ -313,6 +325,10 @@
     "name": "Show xcode cache (2)"
   },
   {
+    "cmd": [],
+    "name": "install xcode (2)"
+  },
+  {
     "cmd": [
       "cipd",
       "ensure",
@@ -326,8 +342,9 @@
       "/path/to/tmp/json"
     ],
     "infra_step": true,
-    "name": "ensure_installed (2)",
+    "name": "install xcode (2).ensure_installed",
     "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@",
       "@@@STEP_LOG_LINE@json.output@{@@@",
       "@@@STEP_LOG_LINE@json.output@  \"result\": {@@@",
       "@@@STEP_LOG_LINE@json.output@    \"\": [@@@",
@@ -348,7 +365,10 @@
       "[CLEANUP]/tmp_tmp_1/osx_sdk"
     ],
     "infra_step": true,
-    "name": "Show tool_dir cache (2)"
+    "name": "install xcode (2).Show tool_dir cache",
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@"
+    ]
   },
   {
     "cmd": [
@@ -366,7 +386,11 @@
       "-verbose"
     ],
     "infra_step": true,
-    "name": "install xcode (2)"
+    "name": "install xcode (2).install xcode from cipd",
+    "timeout": 1800,
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@"
+    ]
   },
   {
     "cmd": [
@@ -385,7 +409,7 @@
       "/opt/flutter/xcode/deadbeef/XCode.app"
     ],
     "infra_step": true,
-    "name": "select XCode (2)"
+    "name": "select xcode (2)"
   },
   {
     "cmd": [
@@ -420,6 +444,10 @@
     "name": "Cleaning up Xcode cache"
   },
   {
+    "cmd": [],
+    "name": "install xcode (3)"
+  },
+  {
     "cmd": [
       "cipd",
       "ensure",
@@ -433,8 +461,9 @@
       "/path/to/tmp/json"
     ],
     "infra_step": true,
-    "name": "ensure_installed (3)",
+    "name": "install xcode (3).ensure_installed",
     "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@",
       "@@@STEP_LOG_LINE@json.output@{@@@",
       "@@@STEP_LOG_LINE@json.output@  \"result\": {@@@",
       "@@@STEP_LOG_LINE@json.output@    \"\": [@@@",
@@ -455,7 +484,10 @@
       "[CLEANUP]/tmp_tmp_2/osx_sdk"
     ],
     "infra_step": true,
-    "name": "Show tool_dir cache (3)"
+    "name": "install xcode (3).Show tool_dir cache",
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@"
+    ]
   },
   {
     "cmd": [
@@ -473,7 +505,11 @@
       "-verbose"
     ],
     "infra_step": true,
-    "name": "install xcode (3)"
+    "name": "install xcode (3).install xcode from cipd",
+    "timeout": 1800,
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@"
+    ]
   },
   {
     "cmd": [],
@@ -487,7 +523,7 @@
       "/opt/flutter/xcode/deadbeef/XCode.app"
     ],
     "infra_step": true,
-    "name": "Cleaning up runtimes cache.select XCode",
+    "name": "Cleaning up runtimes cache.select xcode",
     "~followup_annotations": [
       "@@@STEP_NEST_LEVEL@1@@@"
     ]
@@ -554,7 +590,7 @@
       "/opt/flutter/xcode/deadbeef/XCode.app"
     ],
     "infra_step": true,
-    "name": "select XCode (3)"
+    "name": "select xcode (3)"
   },
   {
     "cmd": [
@@ -591,6 +627,15 @@
     "name": "reset XCode (2)"
   },
   {
+    "cmd": [
+      "sudo",
+      "xcode-select",
+      "--reset"
+    ],
+    "infra_step": true,
+    "name": "reset XCode (3)"
+  },
+  {
     "name": "$result"
   }
 ]
\ No newline at end of file
diff --git a/recipe_modules/osx_sdk/examples/full.expected/mac_13_explicit_runtime_version_build_verion_failure.json b/recipe_modules/osx_sdk/examples/full.expected/mac_13_explicit_runtime_version_build_verion_failure.json
index b7a7489..d3c1a12 100644
--- a/recipe_modules/osx_sdk/examples/full.expected/mac_13_explicit_runtime_version_build_verion_failure.json
+++ b/recipe_modules/osx_sdk/examples/full.expected/mac_13_explicit_runtime_version_build_verion_failure.json
@@ -9,6 +9,10 @@
     "name": "Show xcode cache"
   },
   {
+    "cmd": [],
+    "name": "install xcode"
+  },
+  {
     "cmd": [
       "cipd",
       "ensure",
@@ -22,8 +26,9 @@
       "/path/to/tmp/json"
     ],
     "infra_step": true,
-    "name": "ensure_installed",
+    "name": "install xcode.ensure_installed",
     "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@",
       "@@@STEP_LOG_LINE@json.output@{@@@",
       "@@@STEP_LOG_LINE@json.output@  \"result\": {@@@",
       "@@@STEP_LOG_LINE@json.output@    \"\": [@@@",
@@ -44,7 +49,10 @@
       "[CACHE]/osx_sdk/xcode_deadbeef_runtime_ios-16-4_14e300c"
     ],
     "infra_step": true,
-    "name": "Show tool_dir cache"
+    "name": "install xcode.Show tool_dir cache",
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@"
+    ]
   },
   {
     "cmd": [
@@ -62,7 +70,11 @@
       "-verbose"
     ],
     "infra_step": true,
-    "name": "install xcode"
+    "name": "install xcode.install xcode from cipd",
+    "timeout": 1800,
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@"
+    ]
   },
   {
     "cmd": [],
@@ -79,7 +91,7 @@
       "[CACHE]/osx_sdk/xcode_deadbeef_runtime_ios-16-4_14e300c/XCode.app"
     ],
     "infra_step": true,
-    "name": "install runtimes.select XCode",
+    "name": "install runtimes.select xcode",
     "~followup_annotations": [
       "@@@STEP_NEST_LEVEL@1@@@"
     ]
diff --git a/recipe_modules/osx_sdk/examples/full.expected/mac_13_explicit_runtime_version_clean.json b/recipe_modules/osx_sdk/examples/full.expected/mac_13_explicit_runtime_version_clean.json
index 8161e51..831e225 100644
--- a/recipe_modules/osx_sdk/examples/full.expected/mac_13_explicit_runtime_version_clean.json
+++ b/recipe_modules/osx_sdk/examples/full.expected/mac_13_explicit_runtime_version_clean.json
@@ -18,6 +18,10 @@
     "name": "Cleaning up Xcode cache"
   },
   {
+    "cmd": [],
+    "name": "install xcode"
+  },
+  {
     "cmd": [
       "cipd",
       "ensure",
@@ -31,8 +35,9 @@
       "/path/to/tmp/json"
     ],
     "infra_step": true,
-    "name": "ensure_installed",
+    "name": "install xcode.ensure_installed",
     "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@",
       "@@@STEP_LOG_LINE@json.output@{@@@",
       "@@@STEP_LOG_LINE@json.output@  \"result\": {@@@",
       "@@@STEP_LOG_LINE@json.output@    \"\": [@@@",
@@ -53,7 +58,10 @@
       "[CACHE]/osx_sdk/xcode_deadbeef_runtime_ios-16-4_14e300c"
     ],
     "infra_step": true,
-    "name": "Show tool_dir cache"
+    "name": "install xcode.Show tool_dir cache",
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@"
+    ]
   },
   {
     "cmd": [
@@ -71,7 +79,11 @@
       "-verbose"
     ],
     "infra_step": true,
-    "name": "install xcode"
+    "name": "install xcode.install xcode from cipd",
+    "timeout": 1800,
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@"
+    ]
   },
   {
     "cmd": [],
@@ -85,7 +97,7 @@
       "[CACHE]/osx_sdk/xcode_deadbeef_runtime_ios-16-4_14e300c/XCode.app"
     ],
     "infra_step": true,
-    "name": "Cleaning up runtimes cache.select XCode",
+    "name": "Cleaning up runtimes cache.select xcode",
     "~followup_annotations": [
       "@@@STEP_NEST_LEVEL@1@@@"
     ]
@@ -165,7 +177,7 @@
       "[CACHE]/osx_sdk/xcode_deadbeef_runtime_ios-16-4_14e300c/XCode.app"
     ],
     "infra_step": true,
-    "name": "install runtimes.select XCode",
+    "name": "install runtimes.select xcode",
     "~followup_annotations": [
       "@@@STEP_NEST_LEVEL@1@@@"
     ]
@@ -305,7 +317,7 @@
       "[CACHE]/osx_sdk/xcode_deadbeef_runtime_ios-16-4_14e300c/XCode.app"
     ],
     "infra_step": true,
-    "name": "select XCode"
+    "name": "select xcode"
   },
   {
     "cmd": [
@@ -374,6 +386,10 @@
     "name": "Cleaning up Xcode cache (2)"
   },
   {
+    "cmd": [],
+    "name": "install xcode (2)"
+  },
+  {
     "cmd": [
       "cipd",
       "ensure",
@@ -387,8 +403,9 @@
       "/path/to/tmp/json"
     ],
     "infra_step": true,
-    "name": "ensure_installed (2)",
+    "name": "install xcode (2).ensure_installed",
     "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@",
       "@@@STEP_LOG_LINE@json.output@{@@@",
       "@@@STEP_LOG_LINE@json.output@  \"result\": {@@@",
       "@@@STEP_LOG_LINE@json.output@    \"\": [@@@",
@@ -409,7 +426,10 @@
       "[CLEANUP]/tmp_tmp_1/osx_sdk"
     ],
     "infra_step": true,
-    "name": "Show tool_dir cache (2)"
+    "name": "install xcode (2).Show tool_dir cache",
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@"
+    ]
   },
   {
     "cmd": [
@@ -427,7 +447,11 @@
       "-verbose"
     ],
     "infra_step": true,
-    "name": "install xcode (2)"
+    "name": "install xcode (2).install xcode from cipd",
+    "timeout": 1800,
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@"
+    ]
   },
   {
     "cmd": [],
@@ -441,7 +465,7 @@
       "/opt/flutter/xcode/deadbeef/XCode.app"
     ],
     "infra_step": true,
-    "name": "Cleaning up runtimes cache (2).select XCode",
+    "name": "Cleaning up runtimes cache (2).select xcode",
     "~followup_annotations": [
       "@@@STEP_NEST_LEVEL@1@@@"
     ]
@@ -508,7 +532,7 @@
       "/opt/flutter/xcode/deadbeef/XCode.app"
     ],
     "infra_step": true,
-    "name": "select XCode (2)"
+    "name": "select xcode (2)"
   },
   {
     "cmd": [
@@ -543,6 +567,10 @@
     "name": "Cleaning up Xcode cache (3)"
   },
   {
+    "cmd": [],
+    "name": "install xcode (3)"
+  },
+  {
     "cmd": [
       "cipd",
       "ensure",
@@ -556,8 +584,9 @@
       "/path/to/tmp/json"
     ],
     "infra_step": true,
-    "name": "ensure_installed (3)",
+    "name": "install xcode (3).ensure_installed",
     "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@",
       "@@@STEP_LOG_LINE@json.output@{@@@",
       "@@@STEP_LOG_LINE@json.output@  \"result\": {@@@",
       "@@@STEP_LOG_LINE@json.output@    \"\": [@@@",
@@ -578,7 +607,10 @@
       "[CLEANUP]/tmp_tmp_2/osx_sdk"
     ],
     "infra_step": true,
-    "name": "Show tool_dir cache (3)"
+    "name": "install xcode (3).Show tool_dir cache",
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@"
+    ]
   },
   {
     "cmd": [
@@ -596,7 +628,11 @@
       "-verbose"
     ],
     "infra_step": true,
-    "name": "install xcode (3)"
+    "name": "install xcode (3).install xcode from cipd",
+    "timeout": 1800,
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@"
+    ]
   },
   {
     "cmd": [],
@@ -610,7 +646,7 @@
       "/opt/flutter/xcode/deadbeef/XCode.app"
     ],
     "infra_step": true,
-    "name": "Cleaning up runtimes cache (3).select XCode",
+    "name": "Cleaning up runtimes cache (3).select xcode",
     "~followup_annotations": [
       "@@@STEP_NEST_LEVEL@1@@@"
     ]
@@ -677,7 +713,7 @@
       "/opt/flutter/xcode/deadbeef/XCode.app"
     ],
     "infra_step": true,
-    "name": "select XCode (3)"
+    "name": "select xcode (3)"
   },
   {
     "cmd": [
@@ -714,6 +750,15 @@
     "name": "reset XCode (2)"
   },
   {
+    "cmd": [
+      "sudo",
+      "xcode-select",
+      "--reset"
+    ],
+    "infra_step": true,
+    "name": "reset XCode (3)"
+  },
+  {
     "name": "$result"
   }
 ]
\ No newline at end of file
diff --git a/recipe_modules/osx_sdk/examples/full.expected/mac_13_explicit_runtime_version_not_mounted.json b/recipe_modules/osx_sdk/examples/full.expected/mac_13_explicit_runtime_version_not_mounted.json
index 0d27871..8e0ac9b 100644
--- a/recipe_modules/osx_sdk/examples/full.expected/mac_13_explicit_runtime_version_not_mounted.json
+++ b/recipe_modules/osx_sdk/examples/full.expected/mac_13_explicit_runtime_version_not_mounted.json
@@ -9,6 +9,10 @@
     "name": "Show xcode cache"
   },
   {
+    "cmd": [],
+    "name": "install xcode"
+  },
+  {
     "cmd": [
       "cipd",
       "ensure",
@@ -22,8 +26,9 @@
       "/path/to/tmp/json"
     ],
     "infra_step": true,
-    "name": "ensure_installed",
+    "name": "install xcode.ensure_installed",
     "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@",
       "@@@STEP_LOG_LINE@json.output@{@@@",
       "@@@STEP_LOG_LINE@json.output@  \"result\": {@@@",
       "@@@STEP_LOG_LINE@json.output@    \"\": [@@@",
@@ -44,7 +49,10 @@
       "[CACHE]/osx_sdk/xcode_deadbeef_runtime_ios-16-4_14e300c"
     ],
     "infra_step": true,
-    "name": "Show tool_dir cache"
+    "name": "install xcode.Show tool_dir cache",
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@"
+    ]
   },
   {
     "cmd": [
@@ -62,7 +70,11 @@
       "-verbose"
     ],
     "infra_step": true,
-    "name": "install xcode"
+    "name": "install xcode.install xcode from cipd",
+    "timeout": 1800,
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@"
+    ]
   },
   {
     "cmd": [],
@@ -76,7 +88,7 @@
       "[CACHE]/osx_sdk/xcode_deadbeef_runtime_ios-16-4_14e300c/XCode.app"
     ],
     "infra_step": true,
-    "name": "install runtimes.select XCode",
+    "name": "install runtimes.select xcode",
     "~followup_annotations": [
       "@@@STEP_NEST_LEVEL@1@@@"
     ]
@@ -270,7 +282,7 @@
       "[CACHE]/osx_sdk/xcode_deadbeef_runtime_ios-16-4_14e300c/XCode.app"
     ],
     "infra_step": true,
-    "name": "select XCode"
+    "name": "select xcode"
   },
   {
     "cmd": [
@@ -326,6 +338,10 @@
     "name": "Show xcode cache (2)"
   },
   {
+    "cmd": [],
+    "name": "install xcode (2)"
+  },
+  {
     "cmd": [
       "cipd",
       "ensure",
@@ -339,8 +355,9 @@
       "/path/to/tmp/json"
     ],
     "infra_step": true,
-    "name": "ensure_installed (2)",
+    "name": "install xcode (2).ensure_installed",
     "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@",
       "@@@STEP_LOG_LINE@json.output@{@@@",
       "@@@STEP_LOG_LINE@json.output@  \"result\": {@@@",
       "@@@STEP_LOG_LINE@json.output@    \"\": [@@@",
@@ -361,7 +378,10 @@
       "[CLEANUP]/tmp_tmp_1/osx_sdk"
     ],
     "infra_step": true,
-    "name": "Show tool_dir cache (2)"
+    "name": "install xcode (2).Show tool_dir cache",
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@"
+    ]
   },
   {
     "cmd": [
@@ -379,7 +399,11 @@
       "-verbose"
     ],
     "infra_step": true,
-    "name": "install xcode (2)"
+    "name": "install xcode (2).install xcode from cipd",
+    "timeout": 1800,
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@"
+    ]
   },
   {
     "cmd": [
@@ -398,7 +422,7 @@
       "/opt/flutter/xcode/deadbeef/XCode.app"
     ],
     "infra_step": true,
-    "name": "select XCode (2)"
+    "name": "select xcode (2)"
   },
   {
     "cmd": [
@@ -433,6 +457,10 @@
     "name": "Cleaning up Xcode cache"
   },
   {
+    "cmd": [],
+    "name": "install xcode (3)"
+  },
+  {
     "cmd": [
       "cipd",
       "ensure",
@@ -446,8 +474,9 @@
       "/path/to/tmp/json"
     ],
     "infra_step": true,
-    "name": "ensure_installed (3)",
+    "name": "install xcode (3).ensure_installed",
     "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@",
       "@@@STEP_LOG_LINE@json.output@{@@@",
       "@@@STEP_LOG_LINE@json.output@  \"result\": {@@@",
       "@@@STEP_LOG_LINE@json.output@    \"\": [@@@",
@@ -468,7 +497,10 @@
       "[CLEANUP]/tmp_tmp_2/osx_sdk"
     ],
     "infra_step": true,
-    "name": "Show tool_dir cache (3)"
+    "name": "install xcode (3).Show tool_dir cache",
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@"
+    ]
   },
   {
     "cmd": [
@@ -486,7 +518,11 @@
       "-verbose"
     ],
     "infra_step": true,
-    "name": "install xcode (3)"
+    "name": "install xcode (3).install xcode from cipd",
+    "timeout": 1800,
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@"
+    ]
   },
   {
     "cmd": [],
@@ -500,7 +536,7 @@
       "/opt/flutter/xcode/deadbeef/XCode.app"
     ],
     "infra_step": true,
-    "name": "Cleaning up runtimes cache.select XCode",
+    "name": "Cleaning up runtimes cache.select xcode",
     "~followup_annotations": [
       "@@@STEP_NEST_LEVEL@1@@@"
     ]
@@ -567,7 +603,7 @@
       "/opt/flutter/xcode/deadbeef/XCode.app"
     ],
     "infra_step": true,
-    "name": "select XCode (3)"
+    "name": "select xcode (3)"
   },
   {
     "cmd": [
@@ -604,6 +640,15 @@
     "name": "reset XCode (2)"
   },
   {
+    "cmd": [
+      "sudo",
+      "xcode-select",
+      "--reset"
+    ],
+    "infra_step": true,
+    "name": "reset XCode (3)"
+  },
+  {
     "name": "$result"
   }
 ]
\ No newline at end of file
diff --git a/recipe_modules/osx_sdk/examples/full.expected/mac_13_x86_host.json b/recipe_modules/osx_sdk/examples/full.expected/mac_13_x86_host.json
index f0ba57d..32f4e18 100644
--- a/recipe_modules/osx_sdk/examples/full.expected/mac_13_x86_host.json
+++ b/recipe_modules/osx_sdk/examples/full.expected/mac_13_x86_host.json
@@ -9,6 +9,10 @@
     "name": "Show xcode cache"
   },
   {
+    "cmd": [],
+    "name": "install xcode"
+  },
+  {
     "cmd": [
       "cipd",
       "ensure",
@@ -22,8 +26,9 @@
       "/path/to/tmp/json"
     ],
     "infra_step": true,
-    "name": "ensure_installed",
+    "name": "install xcode.ensure_installed",
     "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@",
       "@@@STEP_LOG_LINE@json.output@{@@@",
       "@@@STEP_LOG_LINE@json.output@  \"result\": {@@@",
       "@@@STEP_LOG_LINE@json.output@    \"\": [@@@",
@@ -44,7 +49,10 @@
       "[CACHE]/osx_sdk/xcode_deadbeef"
     ],
     "infra_step": true,
-    "name": "Show tool_dir cache"
+    "name": "install xcode.Show tool_dir cache",
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@"
+    ]
   },
   {
     "cmd": [
@@ -62,7 +70,11 @@
       "-verbose"
     ],
     "infra_step": true,
-    "name": "install xcode"
+    "name": "install xcode.install xcode from cipd",
+    "timeout": 1800,
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@"
+    ]
   },
   {
     "cmd": [
@@ -81,7 +93,7 @@
       "[CACHE]/osx_sdk/xcode_deadbeef/XCode.app"
     ],
     "infra_step": true,
-    "name": "select XCode"
+    "name": "select xcode"
   },
   {
     "cmd": [
@@ -112,6 +124,10 @@
     "name": "Cleaning up Xcode cache"
   },
   {
+    "cmd": [],
+    "name": "install xcode (2)"
+  },
+  {
     "cmd": [
       "cipd",
       "ensure",
@@ -125,8 +141,9 @@
       "/path/to/tmp/json"
     ],
     "infra_step": true,
-    "name": "ensure_installed (2)",
+    "name": "install xcode (2).ensure_installed",
     "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@",
       "@@@STEP_LOG_LINE@json.output@{@@@",
       "@@@STEP_LOG_LINE@json.output@  \"result\": {@@@",
       "@@@STEP_LOG_LINE@json.output@    \"\": [@@@",
@@ -147,7 +164,10 @@
       "[CACHE]/osx_sdk/xcode_deadbeef"
     ],
     "infra_step": true,
-    "name": "Show tool_dir cache (2)"
+    "name": "install xcode (2).Show tool_dir cache",
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@"
+    ]
   },
   {
     "cmd": [
@@ -165,7 +185,11 @@
       "-verbose"
     ],
     "infra_step": true,
-    "name": "install xcode (2)"
+    "name": "install xcode (2).install xcode from cipd",
+    "timeout": 1800,
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@"
+    ]
   },
   {
     "cmd": [],
@@ -179,7 +203,7 @@
       "[CACHE]/osx_sdk/xcode_deadbeef/XCode.app"
     ],
     "infra_step": true,
-    "name": "Cleaning up runtimes cache.select XCode",
+    "name": "Cleaning up runtimes cache.select xcode",
     "~followup_annotations": [
       "@@@STEP_NEST_LEVEL@1@@@"
     ]
@@ -218,6 +242,13 @@
     "name": "install runtimes"
   },
   {
+    "cmd": [],
+    "name": "install runtimes.install xcode",
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@"
+    ]
+  },
+  {
     "cmd": [
       "cipd",
       "ensure",
@@ -231,9 +262,9 @@
       "/path/to/tmp/json"
     ],
     "infra_step": true,
-    "name": "install runtimes.ensure_installed",
+    "name": "install runtimes.install xcode.ensure_installed",
     "~followup_annotations": [
-      "@@@STEP_NEST_LEVEL@1@@@",
+      "@@@STEP_NEST_LEVEL@2@@@",
       "@@@STEP_LOG_LINE@json.output@{@@@",
       "@@@STEP_LOG_LINE@json.output@  \"result\": {@@@",
       "@@@STEP_LOG_LINE@json.output@    \"\": [@@@",
@@ -254,9 +285,9 @@
       "[CACHE]/osx_sdk/xcode_deadbeef"
     ],
     "infra_step": true,
-    "name": "install runtimes.Show tool_dir cache",
+    "name": "install runtimes.install xcode.Show tool_dir cache",
     "~followup_annotations": [
-      "@@@STEP_NEST_LEVEL@1@@@"
+      "@@@STEP_NEST_LEVEL@2@@@"
     ]
   },
   {
@@ -275,9 +306,10 @@
       "-verbose"
     ],
     "infra_step": true,
-    "name": "install runtimes.install xcode",
+    "name": "install runtimes.install xcode.install xcode from cipd",
+    "timeout": 1800,
     "~followup_annotations": [
-      "@@@STEP_NEST_LEVEL@1@@@"
+      "@@@STEP_NEST_LEVEL@2@@@"
     ]
   },
   {
@@ -297,7 +329,7 @@
       "[CACHE]/osx_sdk/xcode_deadbeef/XCode.app"
     ],
     "infra_step": true,
-    "name": "select XCode (2)"
+    "name": "select xcode (2)"
   },
   {
     "cmd": [
@@ -356,6 +388,10 @@
     "name": "Cleaning up Xcode cache (2)"
   },
   {
+    "cmd": [],
+    "name": "install xcode (3)"
+  },
+  {
     "cmd": [
       "cipd",
       "ensure",
@@ -369,8 +405,9 @@
       "/path/to/tmp/json"
     ],
     "infra_step": true,
-    "name": "ensure_installed (3)",
+    "name": "install xcode (3).ensure_installed",
     "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@",
       "@@@STEP_LOG_LINE@json.output@{@@@",
       "@@@STEP_LOG_LINE@json.output@  \"result\": {@@@",
       "@@@STEP_LOG_LINE@json.output@    \"\": [@@@",
@@ -391,7 +428,10 @@
       "[CLEANUP]/tmp_tmp_1/osx_sdk"
     ],
     "infra_step": true,
-    "name": "Show tool_dir cache (3)"
+    "name": "install xcode (3).Show tool_dir cache",
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@"
+    ]
   },
   {
     "cmd": [
@@ -409,7 +449,11 @@
       "-verbose"
     ],
     "infra_step": true,
-    "name": "install xcode (3)"
+    "name": "install xcode (3).install xcode from cipd",
+    "timeout": 1800,
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@"
+    ]
   },
   {
     "cmd": [],
@@ -423,7 +467,7 @@
       "/opt/flutter/xcode/deadbeef/XCode.app"
     ],
     "infra_step": true,
-    "name": "Cleaning up runtimes cache (2).select XCode",
+    "name": "Cleaning up runtimes cache (2).select xcode",
     "~followup_annotations": [
       "@@@STEP_NEST_LEVEL@1@@@"
     ]
@@ -462,6 +506,13 @@
     "name": "install runtimes (2)"
   },
   {
+    "cmd": [],
+    "name": "install runtimes (2).install xcode",
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@"
+    ]
+  },
+  {
     "cmd": [
       "cipd",
       "ensure",
@@ -475,9 +526,9 @@
       "/path/to/tmp/json"
     ],
     "infra_step": true,
-    "name": "install runtimes (2).ensure_installed",
+    "name": "install runtimes (2).install xcode.ensure_installed",
     "~followup_annotations": [
-      "@@@STEP_NEST_LEVEL@1@@@",
+      "@@@STEP_NEST_LEVEL@2@@@",
       "@@@STEP_LOG_LINE@json.output@{@@@",
       "@@@STEP_LOG_LINE@json.output@  \"result\": {@@@",
       "@@@STEP_LOG_LINE@json.output@    \"\": [@@@",
@@ -498,9 +549,9 @@
       "[CLEANUP]/tmp_tmp_1/osx_sdk"
     ],
     "infra_step": true,
-    "name": "install runtimes (2).Show tool_dir cache",
+    "name": "install runtimes (2).install xcode.Show tool_dir cache",
     "~followup_annotations": [
-      "@@@STEP_NEST_LEVEL@1@@@"
+      "@@@STEP_NEST_LEVEL@2@@@"
     ]
   },
   {
@@ -519,9 +570,10 @@
       "-verbose"
     ],
     "infra_step": true,
-    "name": "install runtimes (2).install xcode",
+    "name": "install runtimes (2).install xcode.install xcode from cipd",
+    "timeout": 1800,
     "~followup_annotations": [
-      "@@@STEP_NEST_LEVEL@1@@@"
+      "@@@STEP_NEST_LEVEL@2@@@"
     ]
   },
   {
@@ -541,7 +593,7 @@
       "/opt/flutter/xcode/deadbeef/XCode.app"
     ],
     "infra_step": true,
-    "name": "select XCode (3)"
+    "name": "select xcode (3)"
   },
   {
     "cmd": [
@@ -576,6 +628,10 @@
     "name": "Cleaning up Xcode cache (3)"
   },
   {
+    "cmd": [],
+    "name": "install xcode (4)"
+  },
+  {
     "cmd": [
       "cipd",
       "ensure",
@@ -589,8 +645,9 @@
       "/path/to/tmp/json"
     ],
     "infra_step": true,
-    "name": "ensure_installed (4)",
+    "name": "install xcode (4).ensure_installed",
     "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@",
       "@@@STEP_LOG_LINE@json.output@{@@@",
       "@@@STEP_LOG_LINE@json.output@  \"result\": {@@@",
       "@@@STEP_LOG_LINE@json.output@    \"\": [@@@",
@@ -611,7 +668,10 @@
       "[CLEANUP]/tmp_tmp_2/osx_sdk"
     ],
     "infra_step": true,
-    "name": "Show tool_dir cache (4)"
+    "name": "install xcode (4).Show tool_dir cache",
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@"
+    ]
   },
   {
     "cmd": [
@@ -629,7 +689,11 @@
       "-verbose"
     ],
     "infra_step": true,
-    "name": "install xcode (4)"
+    "name": "install xcode (4).install xcode from cipd",
+    "timeout": 1800,
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@"
+    ]
   },
   {
     "cmd": [],
@@ -643,7 +707,7 @@
       "/opt/flutter/xcode/deadbeef/XCode.app"
     ],
     "infra_step": true,
-    "name": "Cleaning up runtimes cache (3).select XCode",
+    "name": "Cleaning up runtimes cache (3).select xcode",
     "~followup_annotations": [
       "@@@STEP_NEST_LEVEL@1@@@"
     ]
@@ -682,6 +746,13 @@
     "name": "install runtimes (3)"
   },
   {
+    "cmd": [],
+    "name": "install runtimes (3).install xcode",
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@"
+    ]
+  },
+  {
     "cmd": [
       "cipd",
       "ensure",
@@ -695,9 +766,9 @@
       "/path/to/tmp/json"
     ],
     "infra_step": true,
-    "name": "install runtimes (3).ensure_installed",
+    "name": "install runtimes (3).install xcode.ensure_installed",
     "~followup_annotations": [
-      "@@@STEP_NEST_LEVEL@1@@@",
+      "@@@STEP_NEST_LEVEL@2@@@",
       "@@@STEP_LOG_LINE@json.output@{@@@",
       "@@@STEP_LOG_LINE@json.output@  \"result\": {@@@",
       "@@@STEP_LOG_LINE@json.output@    \"\": [@@@",
@@ -718,9 +789,9 @@
       "[CLEANUP]/tmp_tmp_2/osx_sdk"
     ],
     "infra_step": true,
-    "name": "install runtimes (3).Show tool_dir cache",
+    "name": "install runtimes (3).install xcode.Show tool_dir cache",
     "~followup_annotations": [
-      "@@@STEP_NEST_LEVEL@1@@@"
+      "@@@STEP_NEST_LEVEL@2@@@"
     ]
   },
   {
@@ -739,9 +810,10 @@
       "-verbose"
     ],
     "infra_step": true,
-    "name": "install runtimes (3).install xcode",
+    "name": "install runtimes (3).install xcode.install xcode from cipd",
+    "timeout": 1800,
     "~followup_annotations": [
-      "@@@STEP_NEST_LEVEL@1@@@"
+      "@@@STEP_NEST_LEVEL@2@@@"
     ]
   },
   {
@@ -761,7 +833,7 @@
       "/opt/flutter/xcode/deadbeef/XCode.app"
     ],
     "infra_step": true,
-    "name": "select XCode (4)"
+    "name": "select xcode (4)"
   },
   {
     "cmd": [
@@ -798,6 +870,15 @@
     "name": "reset XCode (2)"
   },
   {
+    "cmd": [
+      "sudo",
+      "xcode-select",
+      "--reset"
+    ],
+    "infra_step": true,
+    "name": "reset XCode (3)"
+  },
+  {
     "name": "$result"
   }
 ]
\ No newline at end of file
diff --git a/recipe_modules/osx_sdk/examples/full.expected/mac_13_xcode_install_fails.json b/recipe_modules/osx_sdk/examples/full.expected/mac_13_xcode_install_fails.json
deleted file mode 100644
index a244fc2..0000000
--- a/recipe_modules/osx_sdk/examples/full.expected/mac_13_xcode_install_fails.json
+++ /dev/null
@@ -1,212 +0,0 @@
-[
-  {
-    "cmd": [
-      "ls",
-      "-al",
-      "[CACHE]/osx_sdk"
-    ],
-    "infra_step": true,
-    "name": "Show xcode cache"
-  },
-  {
-    "cmd": [
-      "cipd",
-      "ensure",
-      "-root",
-      "[CACHE]/osx_sdk/xcode_deadbeef",
-      "-ensure-file",
-      "infra/tools/mac_toolchain/${platform} latest",
-      "-max-threads",
-      "0",
-      "-json-output",
-      "/path/to/tmp/json"
-    ],
-    "infra_step": true,
-    "name": "ensure_installed",
-    "~followup_annotations": [
-      "@@@STEP_LOG_LINE@json.output@{@@@",
-      "@@@STEP_LOG_LINE@json.output@  \"result\": {@@@",
-      "@@@STEP_LOG_LINE@json.output@    \"\": [@@@",
-      "@@@STEP_LOG_LINE@json.output@      {@@@",
-      "@@@STEP_LOG_LINE@json.output@        \"instance_id\": \"resolved-instance_id-of-latest----------\",@@@",
-      "@@@STEP_LOG_LINE@json.output@        \"package\": \"infra/tools/mac_toolchain/resolved-platform\"@@@",
-      "@@@STEP_LOG_LINE@json.output@      }@@@",
-      "@@@STEP_LOG_LINE@json.output@    ]@@@",
-      "@@@STEP_LOG_LINE@json.output@  }@@@",
-      "@@@STEP_LOG_LINE@json.output@}@@@",
-      "@@@STEP_LOG_END@json.output@@@"
-    ]
-  },
-  {
-    "cmd": [
-      "ls",
-      "-al",
-      "[CACHE]/osx_sdk/xcode_deadbeef"
-    ],
-    "infra_step": true,
-    "name": "Show tool_dir cache"
-  },
-  {
-    "cmd": [
-      "[CACHE]/osx_sdk/xcode_deadbeef/mac_toolchain",
-      "install",
-      "-kind",
-      "mac",
-      "-xcode-version",
-      "deadbeef",
-      "-output-dir",
-      "[CACHE]/osx_sdk/xcode_deadbeef/XCode.app",
-      "-cipd-package-prefix",
-      "infra_internal/ios/xcode",
-      "-with-runtime=True",
-      "-verbose"
-    ],
-    "infra_step": true,
-    "name": "install xcode",
-    "~followup_annotations": [
-      "@@@STEP_EXCEPTION@@@"
-    ]
-  },
-  {
-    "cmd": [
-      "ls",
-      "-al",
-      "[CACHE]/osx_sdk/xcode_deadbeef"
-    ],
-    "infra_step": true,
-    "name": "Show tool_dir cache (2)"
-  },
-  {
-    "cmd": [
-      "ls",
-      "-al",
-      "[CACHE]/osx_sdk/xcode_deadbeef/XCode.app"
-    ],
-    "infra_step": true,
-    "name": "Show app_dir cache"
-  },
-  {
-    "cmd": [
-      "rm",
-      "-rf",
-      "[CACHE]/osx_sdk/xcode_deadbeef"
-    ],
-    "infra_step": true,
-    "name": "Cleaning up Xcode cache"
-  },
-  {
-    "cmd": [],
-    "name": "Failed to install Xcode",
-    "~followup_annotations": [
-      "@@@STEP_EXCEPTION@@@"
-    ]
-  },
-  {
-    "cmd": [
-      "cipd",
-      "ensure",
-      "-root",
-      "[CACHE]/osx_sdk/xcode_deadbeef",
-      "-ensure-file",
-      "infra/tools/mac_toolchain/${platform} latest",
-      "-max-threads",
-      "0",
-      "-json-output",
-      "/path/to/tmp/json"
-    ],
-    "infra_step": true,
-    "name": "ensure_installed (2)",
-    "~followup_annotations": [
-      "@@@STEP_LOG_LINE@json.output@{@@@",
-      "@@@STEP_LOG_LINE@json.output@  \"result\": {@@@",
-      "@@@STEP_LOG_LINE@json.output@    \"\": [@@@",
-      "@@@STEP_LOG_LINE@json.output@      {@@@",
-      "@@@STEP_LOG_LINE@json.output@        \"instance_id\": \"resolved-instance_id-of-latest----------\",@@@",
-      "@@@STEP_LOG_LINE@json.output@        \"package\": \"infra/tools/mac_toolchain/resolved-platform\"@@@",
-      "@@@STEP_LOG_LINE@json.output@      }@@@",
-      "@@@STEP_LOG_LINE@json.output@    ]@@@",
-      "@@@STEP_LOG_LINE@json.output@  }@@@",
-      "@@@STEP_LOG_LINE@json.output@}@@@",
-      "@@@STEP_LOG_END@json.output@@@"
-    ]
-  },
-  {
-    "cmd": [
-      "ls",
-      "-al",
-      "[CACHE]/osx_sdk/xcode_deadbeef"
-    ],
-    "infra_step": true,
-    "name": "Show tool_dir cache (3)"
-  },
-  {
-    "cmd": [
-      "[CACHE]/osx_sdk/xcode_deadbeef/mac_toolchain",
-      "install",
-      "-kind",
-      "mac",
-      "-xcode-version",
-      "deadbeef",
-      "-output-dir",
-      "[CACHE]/osx_sdk/xcode_deadbeef/XCode.app",
-      "-cipd-package-prefix",
-      "infra_internal/ios/xcode",
-      "-with-runtime=True",
-      "-verbose"
-    ],
-    "infra_step": true,
-    "name": "install xcode (2)",
-    "~followup_annotations": [
-      "@@@STEP_EXCEPTION@@@"
-    ]
-  },
-  {
-    "cmd": [
-      "ls",
-      "-al",
-      "[CACHE]/osx_sdk/xcode_deadbeef"
-    ],
-    "infra_step": true,
-    "name": "Show tool_dir cache (4)"
-  },
-  {
-    "cmd": [
-      "ls",
-      "-al",
-      "[CACHE]/osx_sdk/xcode_deadbeef/XCode.app"
-    ],
-    "infra_step": true,
-    "name": "Show app_dir cache (2)"
-  },
-  {
-    "cmd": [
-      "rm",
-      "-rf",
-      "[CACHE]/osx_sdk/xcode_deadbeef"
-    ],
-    "infra_step": true,
-    "name": "Cleaning up Xcode cache (2)"
-  },
-  {
-    "cmd": [],
-    "name": "Failed to install Xcode (2)",
-    "~followup_annotations": [
-      "@@@STEP_EXCEPTION@@@"
-    ]
-  },
-  {
-    "cmd": [
-      "sudo",
-      "xcode-select",
-      "--reset"
-    ],
-    "infra_step": true,
-    "name": "reset XCode"
-  },
-  {
-    "failure": {
-      "humanReason": "Infra Failure: Step('Failed to install Xcode (2)') (retcode: 0)"
-    },
-    "name": "$result"
-  }
-]
\ No newline at end of file
diff --git a/recipe_modules/osx_sdk/examples/full.expected/no_runtime_version.json b/recipe_modules/osx_sdk/examples/full.expected/no_runtime_version.json
index 4611673..78acf66 100644
--- a/recipe_modules/osx_sdk/examples/full.expected/no_runtime_version.json
+++ b/recipe_modules/osx_sdk/examples/full.expected/no_runtime_version.json
@@ -9,6 +9,67 @@
     "name": "Show xcode cache"
   },
   {
+    "cmd": [],
+    "name": "install xcode"
+  },
+  {
+    "cmd": [],
+    "name": "install xcode.verify xcode [CACHE]/osx_sdk/xcode_deadbeef/XCode.app",
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@"
+    ]
+  },
+  {
+    "cmd": [
+      "sudo",
+      "xcode-select",
+      "--switch",
+      "[CACHE]/osx_sdk/xcode_deadbeef/XCode.app"
+    ],
+    "infra_step": true,
+    "name": "install xcode.verify xcode [CACHE]/osx_sdk/xcode_deadbeef/XCode.app.select xcode",
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@2@@@"
+    ]
+  },
+  {
+    "cmd": [
+      "xcrun",
+      "xcodebuild",
+      "-version"
+    ],
+    "infra_step": true,
+    "name": "install xcode.verify xcode [CACHE]/osx_sdk/xcode_deadbeef/XCode.app.check xcode version",
+    "timeout": 300,
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@2@@@"
+    ]
+  },
+  {
+    "cmd": [
+      "sudo",
+      "xcode-select",
+      "--reset"
+    ],
+    "infra_step": true,
+    "name": "install xcode.verify xcode [CACHE]/osx_sdk/xcode_deadbeef/XCode.app.reset XCode",
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@2@@@"
+    ]
+  },
+  {
+    "cmd": [
+      "killall",
+      "-9",
+      "CoreServicesUIAgent"
+    ],
+    "infra_step": true,
+    "name": "install xcode.verify xcode [CACHE]/osx_sdk/xcode_deadbeef/XCode.app.dismiss damaged notification",
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@2@@@"
+    ]
+  },
+  {
     "cmd": [
       "cipd",
       "ensure",
@@ -22,8 +83,9 @@
       "/path/to/tmp/json"
     ],
     "infra_step": true,
-    "name": "ensure_installed",
+    "name": "install xcode.ensure_installed",
     "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@",
       "@@@STEP_LOG_LINE@json.output@{@@@",
       "@@@STEP_LOG_LINE@json.output@  \"result\": {@@@",
       "@@@STEP_LOG_LINE@json.output@    \"\": [@@@",
@@ -53,7 +115,11 @@
       "-verbose"
     ],
     "infra_step": true,
-    "name": "install xcode"
+    "name": "install xcode.install xcode from cipd",
+    "timeout": 1800,
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@"
+    ]
   },
   {
     "cmd": [
@@ -72,7 +138,7 @@
       "[CACHE]/osx_sdk/xcode_deadbeef/XCode.app"
     ],
     "infra_step": true,
-    "name": "select XCode"
+    "name": "select xcode"
   },
   {
     "cmd": [
@@ -107,6 +173,10 @@
     "name": "Cleaning up Xcode cache"
   },
   {
+    "cmd": [],
+    "name": "install xcode (2)"
+  },
+  {
     "cmd": [
       "cipd",
       "ensure",
@@ -120,8 +190,9 @@
       "/path/to/tmp/json"
     ],
     "infra_step": true,
-    "name": "ensure_installed (2)",
+    "name": "install xcode (2).ensure_installed",
     "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@",
       "@@@STEP_LOG_LINE@json.output@{@@@",
       "@@@STEP_LOG_LINE@json.output@  \"result\": {@@@",
       "@@@STEP_LOG_LINE@json.output@    \"\": [@@@",
@@ -151,7 +222,11 @@
       "-verbose"
     ],
     "infra_step": true,
-    "name": "install xcode (2)"
+    "name": "install xcode (2).install xcode from cipd",
+    "timeout": 1800,
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@"
+    ]
   },
   {
     "cmd": [
@@ -170,7 +245,7 @@
       "[CACHE]/osx_sdk/xcode_deadbeef/XCode.app"
     ],
     "infra_step": true,
-    "name": "select XCode (2)"
+    "name": "select xcode (2)"
   },
   {
     "cmd": [
@@ -229,6 +304,10 @@
     "name": "Cleaning up Xcode cache (2)"
   },
   {
+    "cmd": [],
+    "name": "install xcode (3)"
+  },
+  {
     "cmd": [
       "cipd",
       "ensure",
@@ -242,8 +321,9 @@
       "/path/to/tmp/json"
     ],
     "infra_step": true,
-    "name": "ensure_installed (3)",
+    "name": "install xcode (3).ensure_installed",
     "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@",
       "@@@STEP_LOG_LINE@json.output@{@@@",
       "@@@STEP_LOG_LINE@json.output@  \"result\": {@@@",
       "@@@STEP_LOG_LINE@json.output@    \"\": [@@@",
@@ -273,7 +353,11 @@
       "-verbose"
     ],
     "infra_step": true,
-    "name": "install xcode (3)"
+    "name": "install xcode (3).install xcode from cipd",
+    "timeout": 1800,
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@"
+    ]
   },
   {
     "cmd": [
@@ -292,7 +376,7 @@
       "/opt/flutter/xcode/deadbeef/XCode.app"
     ],
     "infra_step": true,
-    "name": "select XCode (3)"
+    "name": "select xcode (3)"
   },
   {
     "cmd": [
@@ -327,6 +411,10 @@
     "name": "Cleaning up Xcode cache (3)"
   },
   {
+    "cmd": [],
+    "name": "install xcode (4)"
+  },
+  {
     "cmd": [
       "cipd",
       "ensure",
@@ -340,8 +428,9 @@
       "/path/to/tmp/json"
     ],
     "infra_step": true,
-    "name": "ensure_installed (4)",
+    "name": "install xcode (4).ensure_installed",
     "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@",
       "@@@STEP_LOG_LINE@json.output@{@@@",
       "@@@STEP_LOG_LINE@json.output@  \"result\": {@@@",
       "@@@STEP_LOG_LINE@json.output@    \"\": [@@@",
@@ -371,7 +460,11 @@
       "-verbose"
     ],
     "infra_step": true,
-    "name": "install xcode (4)"
+    "name": "install xcode (4).install xcode from cipd",
+    "timeout": 1800,
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@"
+    ]
   },
   {
     "cmd": [
@@ -390,7 +483,7 @@
       "/opt/flutter/xcode/deadbeef/XCode.app"
     ],
     "infra_step": true,
-    "name": "select XCode (4)"
+    "name": "select xcode (4)"
   },
   {
     "cmd": [
@@ -427,6 +520,15 @@
     "name": "reset XCode (2)"
   },
   {
+    "cmd": [
+      "sudo",
+      "xcode-select",
+      "--reset"
+    ],
+    "infra_step": true,
+    "name": "reset XCode (3)"
+  },
+  {
     "name": "$result"
   }
 ]
\ No newline at end of file
diff --git a/recipe_modules/osx_sdk/examples/full.expected/xcode_install_fails.json b/recipe_modules/osx_sdk/examples/full.expected/xcode_install_fails.json
deleted file mode 100644
index 80122f4..0000000
--- a/recipe_modules/osx_sdk/examples/full.expected/xcode_install_fails.json
+++ /dev/null
@@ -1,166 +0,0 @@
-[
-  {
-    "cmd": [
-      "ls",
-      "-al",
-      "[CACHE]/osx_sdk"
-    ],
-    "infra_step": true,
-    "name": "Show xcode cache"
-  },
-  {
-    "cmd": [
-      "cipd",
-      "ensure",
-      "-root",
-      "[CACHE]/osx_sdk/xcode_deadbeef",
-      "-ensure-file",
-      "infra/tools/mac_toolchain/${platform} latest",
-      "-max-threads",
-      "0",
-      "-json-output",
-      "/path/to/tmp/json"
-    ],
-    "infra_step": true,
-    "name": "ensure_installed",
-    "~followup_annotations": [
-      "@@@STEP_LOG_LINE@json.output@{@@@",
-      "@@@STEP_LOG_LINE@json.output@  \"result\": {@@@",
-      "@@@STEP_LOG_LINE@json.output@    \"\": [@@@",
-      "@@@STEP_LOG_LINE@json.output@      {@@@",
-      "@@@STEP_LOG_LINE@json.output@        \"instance_id\": \"resolved-instance_id-of-latest----------\",@@@",
-      "@@@STEP_LOG_LINE@json.output@        \"package\": \"infra/tools/mac_toolchain/resolved-platform\"@@@",
-      "@@@STEP_LOG_LINE@json.output@      }@@@",
-      "@@@STEP_LOG_LINE@json.output@    ]@@@",
-      "@@@STEP_LOG_LINE@json.output@  }@@@",
-      "@@@STEP_LOG_LINE@json.output@}@@@",
-      "@@@STEP_LOG_END@json.output@@@"
-    ]
-  },
-  {
-    "cmd": [
-      "[CACHE]/osx_sdk/xcode_deadbeef/mac_toolchain",
-      "install",
-      "-kind",
-      "mac",
-      "-xcode-version",
-      "deadbeef",
-      "-output-dir",
-      "[CACHE]/osx_sdk/xcode_deadbeef/XCode.app",
-      "-cipd-package-prefix",
-      "flutter_internal/ios/xcode",
-      "-with-runtime=True",
-      "-verbose"
-    ],
-    "infra_step": true,
-    "name": "install xcode",
-    "~followup_annotations": [
-      "@@@STEP_EXCEPTION@@@"
-    ]
-  },
-  {
-    "cmd": [
-      "vpython3",
-      "-u",
-      "RECIPE_MODULE[recipe_engine::file]/resources/fileutil.py",
-      "--json-output",
-      "/path/to/tmp/json",
-      "rmtree",
-      "[CACHE]/osx_sdk/xcode_deadbeef"
-    ],
-    "infra_step": true,
-    "name": "Cleaning up Xcode cache"
-  },
-  {
-    "cmd": [],
-    "name": "Failed to install Xcode",
-    "~followup_annotations": [
-      "@@@STEP_EXCEPTION@@@"
-    ]
-  },
-  {
-    "cmd": [
-      "cipd",
-      "ensure",
-      "-root",
-      "[CACHE]/osx_sdk/xcode_deadbeef",
-      "-ensure-file",
-      "infra/tools/mac_toolchain/${platform} latest",
-      "-max-threads",
-      "0",
-      "-json-output",
-      "/path/to/tmp/json"
-    ],
-    "infra_step": true,
-    "name": "ensure_installed (2)",
-    "~followup_annotations": [
-      "@@@STEP_LOG_LINE@json.output@{@@@",
-      "@@@STEP_LOG_LINE@json.output@  \"result\": {@@@",
-      "@@@STEP_LOG_LINE@json.output@    \"\": [@@@",
-      "@@@STEP_LOG_LINE@json.output@      {@@@",
-      "@@@STEP_LOG_LINE@json.output@        \"instance_id\": \"resolved-instance_id-of-latest----------\",@@@",
-      "@@@STEP_LOG_LINE@json.output@        \"package\": \"infra/tools/mac_toolchain/resolved-platform\"@@@",
-      "@@@STEP_LOG_LINE@json.output@      }@@@",
-      "@@@STEP_LOG_LINE@json.output@    ]@@@",
-      "@@@STEP_LOG_LINE@json.output@  }@@@",
-      "@@@STEP_LOG_LINE@json.output@}@@@",
-      "@@@STEP_LOG_END@json.output@@@"
-    ]
-  },
-  {
-    "cmd": [
-      "[CACHE]/osx_sdk/xcode_deadbeef/mac_toolchain",
-      "install",
-      "-kind",
-      "mac",
-      "-xcode-version",
-      "deadbeef",
-      "-output-dir",
-      "[CACHE]/osx_sdk/xcode_deadbeef/XCode.app",
-      "-cipd-package-prefix",
-      "flutter_internal/ios/xcode",
-      "-with-runtime=True",
-      "-verbose"
-    ],
-    "infra_step": true,
-    "name": "install xcode (2)",
-    "~followup_annotations": [
-      "@@@STEP_EXCEPTION@@@"
-    ]
-  },
-  {
-    "cmd": [
-      "vpython3",
-      "-u",
-      "RECIPE_MODULE[recipe_engine::file]/resources/fileutil.py",
-      "--json-output",
-      "/path/to/tmp/json",
-      "rmtree",
-      "[CACHE]/osx_sdk/xcode_deadbeef"
-    ],
-    "infra_step": true,
-    "name": "Cleaning up Xcode cache (2)"
-  },
-  {
-    "cmd": [],
-    "name": "Failed to install Xcode (2)",
-    "~followup_annotations": [
-      "@@@STEP_EXCEPTION@@@"
-    ]
-  },
-  {
-    "cmd": [
-      "sudo",
-      "xcode-select",
-      "--reset"
-    ],
-    "infra_step": true,
-    "name": "reset XCode"
-  },
-  {
-    "failure": {
-      "humanReason": "Infra Failure: Step('Failed to install Xcode (2)') (retcode: 0)"
-    },
-    "name": "$result"
-  }
-]
\ No newline at end of file
diff --git a/recipe_modules/osx_sdk/examples/full.expected/xcode_install_fails_passes_on_retry.json b/recipe_modules/osx_sdk/examples/full.expected/xcode_install_fails_passes_on_retry.json
new file mode 100644
index 0000000..340d458
--- /dev/null
+++ b/recipe_modules/osx_sdk/examples/full.expected/xcode_install_fails_passes_on_retry.json
@@ -0,0 +1,1419 @@
+[
+  {
+    "cmd": [
+      "ls",
+      "-al",
+      "[CACHE]/osx_sdk"
+    ],
+    "infra_step": true,
+    "name": "Show xcode cache"
+  },
+  {
+    "cmd": [],
+    "name": "install xcode",
+    "~followup_annotations": [
+      "@@@STEP_EXCEPTION@@@"
+    ]
+  },
+  {
+    "cmd": [],
+    "name": "install xcode.verify xcode [CACHE]/osx_sdk/xcode_deadbeef/XCode.app",
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@",
+      "@@@STEP_EXCEPTION@@@"
+    ]
+  },
+  {
+    "cmd": [
+      "sudo",
+      "xcode-select",
+      "--switch",
+      "[CACHE]/osx_sdk/xcode_deadbeef/XCode.app"
+    ],
+    "infra_step": true,
+    "name": "install xcode.verify xcode [CACHE]/osx_sdk/xcode_deadbeef/XCode.app.select xcode",
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@2@@@"
+    ]
+  },
+  {
+    "cmd": [
+      "xcrun",
+      "xcodebuild",
+      "-version"
+    ],
+    "infra_step": true,
+    "name": "install xcode.verify xcode [CACHE]/osx_sdk/xcode_deadbeef/XCode.app.check xcode version",
+    "timeout": 300,
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@2@@@",
+      "@@@STEP_EXCEPTION@@@"
+    ]
+  },
+  {
+    "cmd": [
+      "sudo",
+      "xcode-select",
+      "--reset"
+    ],
+    "infra_step": true,
+    "name": "install xcode.verify xcode [CACHE]/osx_sdk/xcode_deadbeef/XCode.app.reset XCode",
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@2@@@"
+    ]
+  },
+  {
+    "cmd": [
+      "killall",
+      "-9",
+      "CoreServicesUIAgent"
+    ],
+    "infra_step": true,
+    "name": "install xcode.verify xcode [CACHE]/osx_sdk/xcode_deadbeef/XCode.app.dismiss damaged notification",
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@2@@@"
+    ]
+  },
+  {
+    "cmd": [
+      "codesign",
+      "-vv",
+      "[CACHE]/osx_sdk/xcode_deadbeef/XCode.app"
+    ],
+    "infra_step": true,
+    "name": "install xcode.verify xcode [CACHE]/osx_sdk/xcode_deadbeef/XCode.app.verify codesign",
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@2@@@"
+    ]
+  },
+  {
+    "cmd": [
+      "rm",
+      "-rf",
+      "[CACHE]/osx_sdk/xcode_deadbeef"
+    ],
+    "infra_step": true,
+    "name": "install xcode.Cleaning up Xcode cache",
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@"
+    ]
+  },
+  {
+    "cmd": [
+      "cipd",
+      "ensure",
+      "-root",
+      "[CACHE]/osx_sdk/xcode_deadbeef",
+      "-ensure-file",
+      "infra/tools/mac_toolchain/${platform} latest",
+      "-max-threads",
+      "0",
+      "-json-output",
+      "/path/to/tmp/json"
+    ],
+    "infra_step": true,
+    "name": "install xcode.ensure_installed",
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@",
+      "@@@STEP_LOG_LINE@json.output@{@@@",
+      "@@@STEP_LOG_LINE@json.output@  \"result\": {@@@",
+      "@@@STEP_LOG_LINE@json.output@    \"\": [@@@",
+      "@@@STEP_LOG_LINE@json.output@      {@@@",
+      "@@@STEP_LOG_LINE@json.output@        \"instance_id\": \"resolved-instance_id-of-latest----------\",@@@",
+      "@@@STEP_LOG_LINE@json.output@        \"package\": \"infra/tools/mac_toolchain/resolved-platform\"@@@",
+      "@@@STEP_LOG_LINE@json.output@      }@@@",
+      "@@@STEP_LOG_LINE@json.output@    ]@@@",
+      "@@@STEP_LOG_LINE@json.output@  }@@@",
+      "@@@STEP_LOG_LINE@json.output@}@@@",
+      "@@@STEP_LOG_END@json.output@@@"
+    ]
+  },
+  {
+    "cmd": [
+      "ls",
+      "-al",
+      "[CACHE]/osx_sdk/xcode_deadbeef"
+    ],
+    "infra_step": true,
+    "name": "install xcode.Show tool_dir cache",
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@"
+    ]
+  },
+  {
+    "cmd": [
+      "[CACHE]/osx_sdk/xcode_deadbeef/mac_toolchain",
+      "install",
+      "-kind",
+      "mac",
+      "-xcode-version",
+      "deadbeef",
+      "-output-dir",
+      "[CACHE]/osx_sdk/xcode_deadbeef/XCode.app",
+      "-cipd-package-prefix",
+      "infra_internal/ios/xcode",
+      "-with-runtime=True",
+      "-verbose"
+    ],
+    "infra_step": true,
+    "name": "install xcode.install xcode from cipd",
+    "timeout": 1800,
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@",
+      "@@@STEP_EXCEPTION@@@"
+    ]
+  },
+  {
+    "cmd": [
+      "ls",
+      "-al",
+      "[CACHE]/osx_sdk/xcode_deadbeef"
+    ],
+    "infra_step": true,
+    "name": "install xcode.Show tool_dir cache (2)",
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@"
+    ]
+  },
+  {
+    "cmd": [
+      "ls",
+      "-al",
+      "[CACHE]/osx_sdk/xcode_deadbeef"
+    ],
+    "infra_step": true,
+    "name": "install xcode.Show app_dir cache",
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@"
+    ]
+  },
+  {
+    "cmd": [
+      "killall",
+      "-9",
+      "CoreServicesUIAgent"
+    ],
+    "infra_step": true,
+    "name": "install xcode.dismiss damaged notification",
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@"
+    ]
+  },
+  {
+    "cmd": [
+      "codesign",
+      "-vv",
+      "[CACHE]/osx_sdk/xcode_deadbeef/XCode.app"
+    ],
+    "infra_step": true,
+    "name": "install xcode.verify codesign",
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@"
+    ]
+  },
+  {
+    "cmd": [
+      "rm",
+      "-rf",
+      "[CACHE]/osx_sdk/xcode_deadbeef"
+    ],
+    "infra_step": true,
+    "name": "install xcode.Cleaning up Xcode cache (2)",
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@"
+    ]
+  },
+  {
+    "cmd": [],
+    "name": "install xcode.Failed to install Xcode",
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@",
+      "@@@STEP_EXCEPTION@@@"
+    ]
+  },
+  {
+    "cmd": [
+      "cipd",
+      "ensure",
+      "-root",
+      "[CACHE]/osx_sdk/xcode_deadbeef",
+      "-ensure-file",
+      "infra/tools/mac_toolchain/${platform} latest",
+      "-max-threads",
+      "0",
+      "-json-output",
+      "/path/to/tmp/json"
+    ],
+    "infra_step": true,
+    "name": "install xcode.ensure_installed (2)",
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@",
+      "@@@STEP_LOG_LINE@json.output@{@@@",
+      "@@@STEP_LOG_LINE@json.output@  \"result\": {@@@",
+      "@@@STEP_LOG_LINE@json.output@    \"\": [@@@",
+      "@@@STEP_LOG_LINE@json.output@      {@@@",
+      "@@@STEP_LOG_LINE@json.output@        \"instance_id\": \"resolved-instance_id-of-latest----------\",@@@",
+      "@@@STEP_LOG_LINE@json.output@        \"package\": \"infra/tools/mac_toolchain/resolved-platform\"@@@",
+      "@@@STEP_LOG_LINE@json.output@      }@@@",
+      "@@@STEP_LOG_LINE@json.output@    ]@@@",
+      "@@@STEP_LOG_LINE@json.output@  }@@@",
+      "@@@STEP_LOG_LINE@json.output@}@@@",
+      "@@@STEP_LOG_END@json.output@@@"
+    ]
+  },
+  {
+    "cmd": [
+      "ls",
+      "-al",
+      "[CACHE]/osx_sdk/xcode_deadbeef"
+    ],
+    "infra_step": true,
+    "name": "install xcode.Show tool_dir cache (3)",
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@"
+    ]
+  },
+  {
+    "cmd": [
+      "[CACHE]/osx_sdk/xcode_deadbeef/mac_toolchain",
+      "install",
+      "-kind",
+      "mac",
+      "-xcode-version",
+      "deadbeef",
+      "-output-dir",
+      "[CACHE]/osx_sdk/xcode_deadbeef/temp_00000000-0000-0000-0000-000000001337_xcode.app",
+      "-cipd-package-prefix",
+      "infra_internal/ios/xcode",
+      "-with-runtime=True",
+      "-verbose"
+    ],
+    "infra_step": true,
+    "name": "install xcode.install xcode from cipd (2)",
+    "timeout": 1800,
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@"
+    ]
+  },
+  {
+    "cmd": [
+      "mv",
+      "[CACHE]/osx_sdk/xcode_deadbeef/temp_00000000-0000-0000-0000-000000001337_xcode.app",
+      "[CACHE]/osx_sdk/xcode_deadbeef/XCode.app"
+    ],
+    "infra_step": true,
+    "name": "install xcode.move to final destination",
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@"
+    ]
+  },
+  {
+    "cmd": [
+      "rm",
+      "-rf",
+      "[CACHE]/osx_sdk/xcode_deadbeef/temp_00000000-0000-0000-0000-000000001337_xcode.app"
+    ],
+    "infra_step": true,
+    "name": "install xcode.clean temporary install path",
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@"
+    ]
+  },
+  {
+    "cmd": [],
+    "name": "Cleaning up runtimes cache"
+  },
+  {
+    "cmd": [
+      "sudo",
+      "xcode-select",
+      "--switch",
+      "[CACHE]/osx_sdk/xcode_deadbeef/XCode.app"
+    ],
+    "infra_step": true,
+    "name": "Cleaning up runtimes cache.select xcode",
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@"
+    ]
+  },
+  {
+    "cmd": [
+      "xcrun",
+      "simctl",
+      "runtime",
+      "delete",
+      "all"
+    ],
+    "infra_step": true,
+    "name": "Cleaning up runtimes cache.Cleaning up mounted simulator runtimes",
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@",
+      "@@@STEP_LOG_END@raw_io.output_text@@@"
+    ]
+  },
+  {
+    "cmd": [
+      "xcrun",
+      "simctl",
+      "list",
+      "runtimes"
+    ],
+    "infra_step": true,
+    "name": "Cleaning up runtimes cache.list runtimes",
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@",
+      "@@@STEP_LOG_END@raw_io.output_text@@@"
+    ]
+  },
+  {
+    "cmd": [],
+    "name": "install runtimes"
+  },
+  {
+    "cmd": [],
+    "name": "install runtimes.install xcode",
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@"
+    ]
+  },
+  {
+    "cmd": [],
+    "name": "install runtimes.install xcode.verify xcode [CACHE]/osx_sdk/xcode_deadbeef/XCode.app",
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@2@@@"
+    ]
+  },
+  {
+    "cmd": [
+      "sudo",
+      "xcode-select",
+      "--switch",
+      "[CACHE]/osx_sdk/xcode_deadbeef/XCode.app"
+    ],
+    "infra_step": true,
+    "name": "install runtimes.install xcode.verify xcode [CACHE]/osx_sdk/xcode_deadbeef/XCode.app.select xcode",
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@3@@@"
+    ]
+  },
+  {
+    "cmd": [
+      "xcrun",
+      "xcodebuild",
+      "-version"
+    ],
+    "infra_step": true,
+    "name": "install runtimes.install xcode.verify xcode [CACHE]/osx_sdk/xcode_deadbeef/XCode.app.check xcode version",
+    "timeout": 300,
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@3@@@"
+    ]
+  },
+  {
+    "cmd": [
+      "sudo",
+      "xcode-select",
+      "--reset"
+    ],
+    "infra_step": true,
+    "name": "install runtimes.install xcode.verify xcode [CACHE]/osx_sdk/xcode_deadbeef/XCode.app.reset XCode",
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@3@@@"
+    ]
+  },
+  {
+    "cmd": [
+      "killall",
+      "-9",
+      "CoreServicesUIAgent"
+    ],
+    "infra_step": true,
+    "name": "install runtimes.install xcode.verify xcode [CACHE]/osx_sdk/xcode_deadbeef/XCode.app.dismiss damaged notification",
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@3@@@"
+    ]
+  },
+  {
+    "cmd": [
+      "cipd",
+      "ensure",
+      "-root",
+      "[CACHE]/osx_sdk/xcode_deadbeef",
+      "-ensure-file",
+      "infra/tools/mac_toolchain/${platform} latest",
+      "-max-threads",
+      "0",
+      "-json-output",
+      "/path/to/tmp/json"
+    ],
+    "infra_step": true,
+    "name": "install runtimes.install xcode.ensure_installed",
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@2@@@",
+      "@@@STEP_LOG_LINE@json.output@{@@@",
+      "@@@STEP_LOG_LINE@json.output@  \"result\": {@@@",
+      "@@@STEP_LOG_LINE@json.output@    \"\": [@@@",
+      "@@@STEP_LOG_LINE@json.output@      {@@@",
+      "@@@STEP_LOG_LINE@json.output@        \"instance_id\": \"resolved-instance_id-of-latest----------\",@@@",
+      "@@@STEP_LOG_LINE@json.output@        \"package\": \"infra/tools/mac_toolchain/resolved-platform\"@@@",
+      "@@@STEP_LOG_LINE@json.output@      }@@@",
+      "@@@STEP_LOG_LINE@json.output@    ]@@@",
+      "@@@STEP_LOG_LINE@json.output@  }@@@",
+      "@@@STEP_LOG_LINE@json.output@}@@@",
+      "@@@STEP_LOG_END@json.output@@@"
+    ]
+  },
+  {
+    "cmd": [
+      "ls",
+      "-al",
+      "[CACHE]/osx_sdk/xcode_deadbeef"
+    ],
+    "infra_step": true,
+    "name": "install runtimes.install xcode.Show tool_dir cache",
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@2@@@"
+    ]
+  },
+  {
+    "cmd": [
+      "[CACHE]/osx_sdk/xcode_deadbeef/mac_toolchain",
+      "install",
+      "-kind",
+      "mac",
+      "-xcode-version",
+      "deadbeef",
+      "-output-dir",
+      "[CACHE]/osx_sdk/xcode_deadbeef/XCode.app",
+      "-cipd-package-prefix",
+      "infra_internal/ios/xcode",
+      "-with-runtime=True",
+      "-verbose"
+    ],
+    "infra_step": true,
+    "name": "install runtimes.install xcode.install xcode from cipd",
+    "timeout": 1800,
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@2@@@"
+    ]
+  },
+  {
+    "cmd": [
+      "killall",
+      "-9",
+      "com.apple.CoreSimulator.CoreSimulatorDevice"
+    ],
+    "infra_step": true,
+    "name": "kill dart"
+  },
+  {
+    "cmd": [
+      "sudo",
+      "xcode-select",
+      "--switch",
+      "[CACHE]/osx_sdk/xcode_deadbeef/XCode.app"
+    ],
+    "infra_step": true,
+    "name": "select xcode"
+  },
+  {
+    "cmd": [
+      "xcrun",
+      "simctl",
+      "list"
+    ],
+    "infra_step": true,
+    "name": "list simulators"
+  },
+  {
+    "cmd": [
+      "xcrun",
+      "simctl",
+      "list",
+      "runtimes"
+    ],
+    "infra_step": true,
+    "name": "list runtimes"
+  },
+  {
+    "cmd": [
+      "rm",
+      "-rf",
+      "[CACHE]/osx_sdk/xcode_deadbeef"
+    ],
+    "infra_step": true,
+    "name": "Cleaning up Xcode cache"
+  },
+  {
+    "cmd": [],
+    "name": "install xcode (2)"
+  },
+  {
+    "cmd": [],
+    "name": "install xcode (2).verify xcode [CACHE]/osx_sdk/xcode_deadbeef/XCode.app",
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@"
+    ]
+  },
+  {
+    "cmd": [
+      "sudo",
+      "xcode-select",
+      "--switch",
+      "[CACHE]/osx_sdk/xcode_deadbeef/XCode.app"
+    ],
+    "infra_step": true,
+    "name": "install xcode (2).verify xcode [CACHE]/osx_sdk/xcode_deadbeef/XCode.app.select xcode",
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@2@@@"
+    ]
+  },
+  {
+    "cmd": [
+      "xcrun",
+      "xcodebuild",
+      "-version"
+    ],
+    "infra_step": true,
+    "name": "install xcode (2).verify xcode [CACHE]/osx_sdk/xcode_deadbeef/XCode.app.check xcode version",
+    "timeout": 300,
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@2@@@"
+    ]
+  },
+  {
+    "cmd": [
+      "sudo",
+      "xcode-select",
+      "--reset"
+    ],
+    "infra_step": true,
+    "name": "install xcode (2).verify xcode [CACHE]/osx_sdk/xcode_deadbeef/XCode.app.reset XCode",
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@2@@@"
+    ]
+  },
+  {
+    "cmd": [
+      "killall",
+      "-9",
+      "CoreServicesUIAgent"
+    ],
+    "infra_step": true,
+    "name": "install xcode (2).verify xcode [CACHE]/osx_sdk/xcode_deadbeef/XCode.app.dismiss damaged notification",
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@2@@@"
+    ]
+  },
+  {
+    "cmd": [
+      "cipd",
+      "ensure",
+      "-root",
+      "[CACHE]/osx_sdk/xcode_deadbeef",
+      "-ensure-file",
+      "infra/tools/mac_toolchain/${platform} latest",
+      "-max-threads",
+      "0",
+      "-json-output",
+      "/path/to/tmp/json"
+    ],
+    "infra_step": true,
+    "name": "install xcode (2).ensure_installed",
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@",
+      "@@@STEP_LOG_LINE@json.output@{@@@",
+      "@@@STEP_LOG_LINE@json.output@  \"result\": {@@@",
+      "@@@STEP_LOG_LINE@json.output@    \"\": [@@@",
+      "@@@STEP_LOG_LINE@json.output@      {@@@",
+      "@@@STEP_LOG_LINE@json.output@        \"instance_id\": \"resolved-instance_id-of-latest----------\",@@@",
+      "@@@STEP_LOG_LINE@json.output@        \"package\": \"infra/tools/mac_toolchain/resolved-platform\"@@@",
+      "@@@STEP_LOG_LINE@json.output@      }@@@",
+      "@@@STEP_LOG_LINE@json.output@    ]@@@",
+      "@@@STEP_LOG_LINE@json.output@  }@@@",
+      "@@@STEP_LOG_LINE@json.output@}@@@",
+      "@@@STEP_LOG_END@json.output@@@"
+    ]
+  },
+  {
+    "cmd": [
+      "ls",
+      "-al",
+      "[CACHE]/osx_sdk/xcode_deadbeef"
+    ],
+    "infra_step": true,
+    "name": "install xcode (2).Show tool_dir cache",
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@"
+    ]
+  },
+  {
+    "cmd": [
+      "[CACHE]/osx_sdk/xcode_deadbeef/mac_toolchain",
+      "install",
+      "-kind",
+      "mac",
+      "-xcode-version",
+      "deadbeef",
+      "-output-dir",
+      "[CACHE]/osx_sdk/xcode_deadbeef/XCode.app",
+      "-cipd-package-prefix",
+      "infra_internal/ios/xcode",
+      "-with-runtime=True",
+      "-verbose"
+    ],
+    "infra_step": true,
+    "name": "install xcode (2).install xcode from cipd",
+    "timeout": 1800,
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@"
+    ]
+  },
+  {
+    "cmd": [],
+    "name": "Cleaning up runtimes cache (2)"
+  },
+  {
+    "cmd": [
+      "sudo",
+      "xcode-select",
+      "--switch",
+      "[CACHE]/osx_sdk/xcode_deadbeef/XCode.app"
+    ],
+    "infra_step": true,
+    "name": "Cleaning up runtimes cache (2).select xcode",
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@"
+    ]
+  },
+  {
+    "cmd": [
+      "xcrun",
+      "simctl",
+      "runtime",
+      "delete",
+      "all"
+    ],
+    "infra_step": true,
+    "name": "Cleaning up runtimes cache (2).Cleaning up mounted simulator runtimes",
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@",
+      "@@@STEP_LOG_END@raw_io.output_text@@@"
+    ]
+  },
+  {
+    "cmd": [
+      "xcrun",
+      "simctl",
+      "list",
+      "runtimes"
+    ],
+    "infra_step": true,
+    "name": "Cleaning up runtimes cache (2).list runtimes",
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@",
+      "@@@STEP_LOG_END@raw_io.output_text@@@"
+    ]
+  },
+  {
+    "cmd": [],
+    "name": "install runtimes (2)"
+  },
+  {
+    "cmd": [],
+    "name": "install runtimes (2).install xcode",
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@"
+    ]
+  },
+  {
+    "cmd": [],
+    "name": "install runtimes (2).install xcode.verify xcode [CACHE]/osx_sdk/xcode_deadbeef/XCode.app",
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@2@@@"
+    ]
+  },
+  {
+    "cmd": [
+      "sudo",
+      "xcode-select",
+      "--switch",
+      "[CACHE]/osx_sdk/xcode_deadbeef/XCode.app"
+    ],
+    "infra_step": true,
+    "name": "install runtimes (2).install xcode.verify xcode [CACHE]/osx_sdk/xcode_deadbeef/XCode.app.select xcode",
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@3@@@"
+    ]
+  },
+  {
+    "cmd": [
+      "xcrun",
+      "xcodebuild",
+      "-version"
+    ],
+    "infra_step": true,
+    "name": "install runtimes (2).install xcode.verify xcode [CACHE]/osx_sdk/xcode_deadbeef/XCode.app.check xcode version",
+    "timeout": 300,
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@3@@@"
+    ]
+  },
+  {
+    "cmd": [
+      "sudo",
+      "xcode-select",
+      "--reset"
+    ],
+    "infra_step": true,
+    "name": "install runtimes (2).install xcode.verify xcode [CACHE]/osx_sdk/xcode_deadbeef/XCode.app.reset XCode",
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@3@@@"
+    ]
+  },
+  {
+    "cmd": [
+      "killall",
+      "-9",
+      "CoreServicesUIAgent"
+    ],
+    "infra_step": true,
+    "name": "install runtimes (2).install xcode.verify xcode [CACHE]/osx_sdk/xcode_deadbeef/XCode.app.dismiss damaged notification",
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@3@@@"
+    ]
+  },
+  {
+    "cmd": [
+      "cipd",
+      "ensure",
+      "-root",
+      "[CACHE]/osx_sdk/xcode_deadbeef",
+      "-ensure-file",
+      "infra/tools/mac_toolchain/${platform} latest",
+      "-max-threads",
+      "0",
+      "-json-output",
+      "/path/to/tmp/json"
+    ],
+    "infra_step": true,
+    "name": "install runtimes (2).install xcode.ensure_installed",
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@2@@@",
+      "@@@STEP_LOG_LINE@json.output@{@@@",
+      "@@@STEP_LOG_LINE@json.output@  \"result\": {@@@",
+      "@@@STEP_LOG_LINE@json.output@    \"\": [@@@",
+      "@@@STEP_LOG_LINE@json.output@      {@@@",
+      "@@@STEP_LOG_LINE@json.output@        \"instance_id\": \"resolved-instance_id-of-latest----------\",@@@",
+      "@@@STEP_LOG_LINE@json.output@        \"package\": \"infra/tools/mac_toolchain/resolved-platform\"@@@",
+      "@@@STEP_LOG_LINE@json.output@      }@@@",
+      "@@@STEP_LOG_LINE@json.output@    ]@@@",
+      "@@@STEP_LOG_LINE@json.output@  }@@@",
+      "@@@STEP_LOG_LINE@json.output@}@@@",
+      "@@@STEP_LOG_END@json.output@@@"
+    ]
+  },
+  {
+    "cmd": [
+      "ls",
+      "-al",
+      "[CACHE]/osx_sdk/xcode_deadbeef"
+    ],
+    "infra_step": true,
+    "name": "install runtimes (2).install xcode.Show tool_dir cache",
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@2@@@"
+    ]
+  },
+  {
+    "cmd": [
+      "[CACHE]/osx_sdk/xcode_deadbeef/mac_toolchain",
+      "install",
+      "-kind",
+      "mac",
+      "-xcode-version",
+      "deadbeef",
+      "-output-dir",
+      "[CACHE]/osx_sdk/xcode_deadbeef/XCode.app",
+      "-cipd-package-prefix",
+      "infra_internal/ios/xcode",
+      "-with-runtime=True",
+      "-verbose"
+    ],
+    "infra_step": true,
+    "name": "install runtimes (2).install xcode.install xcode from cipd",
+    "timeout": 1800,
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@2@@@"
+    ]
+  },
+  {
+    "cmd": [
+      "killall",
+      "-9",
+      "com.apple.CoreSimulator.CoreSimulatorDevice"
+    ],
+    "infra_step": true,
+    "name": "kill dart (2)"
+  },
+  {
+    "cmd": [
+      "sudo",
+      "xcode-select",
+      "--switch",
+      "[CACHE]/osx_sdk/xcode_deadbeef/XCode.app"
+    ],
+    "infra_step": true,
+    "name": "select xcode (2)"
+  },
+  {
+    "cmd": [
+      "xcrun",
+      "simctl",
+      "list"
+    ],
+    "infra_step": true,
+    "name": "list simulators (2)"
+  },
+  {
+    "cmd": [
+      "gn",
+      "gen",
+      "out/Release"
+    ],
+    "name": "gn"
+  },
+  {
+    "cmd": [
+      "ninja",
+      "-C",
+      "out/Release"
+    ],
+    "name": "ninja"
+  },
+  {
+    "cmd": [
+      "sudo",
+      "xcode-select",
+      "--reset"
+    ],
+    "infra_step": true,
+    "name": "reset XCode"
+  },
+  {
+    "cmd": [
+      "ls",
+      "-al",
+      "[CACHE]/osx_sdk"
+    ],
+    "infra_step": true,
+    "name": "Show xcode cache (2)"
+  },
+  {
+    "cmd": [
+      "vpython3",
+      "-u",
+      "RECIPE_MODULE[recipe_engine::file]/resources/fileutil.py",
+      "--json-output",
+      "/path/to/tmp/json",
+      "rmtree",
+      "/opt/flutter/xcode/deadbeef"
+    ],
+    "infra_step": true,
+    "name": "Cleaning up Xcode cache (2)"
+  },
+  {
+    "cmd": [],
+    "name": "install xcode (3)"
+  },
+  {
+    "cmd": [
+      "cipd",
+      "ensure",
+      "-root",
+      "[CLEANUP]/tmp_tmp_1/osx_sdk",
+      "-ensure-file",
+      "infra/tools/mac_toolchain/${platform} latest",
+      "-max-threads",
+      "0",
+      "-json-output",
+      "/path/to/tmp/json"
+    ],
+    "infra_step": true,
+    "name": "install xcode (3).ensure_installed",
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@",
+      "@@@STEP_LOG_LINE@json.output@{@@@",
+      "@@@STEP_LOG_LINE@json.output@  \"result\": {@@@",
+      "@@@STEP_LOG_LINE@json.output@    \"\": [@@@",
+      "@@@STEP_LOG_LINE@json.output@      {@@@",
+      "@@@STEP_LOG_LINE@json.output@        \"instance_id\": \"resolved-instance_id-of-latest----------\",@@@",
+      "@@@STEP_LOG_LINE@json.output@        \"package\": \"infra/tools/mac_toolchain/resolved-platform\"@@@",
+      "@@@STEP_LOG_LINE@json.output@      }@@@",
+      "@@@STEP_LOG_LINE@json.output@    ]@@@",
+      "@@@STEP_LOG_LINE@json.output@  }@@@",
+      "@@@STEP_LOG_LINE@json.output@}@@@",
+      "@@@STEP_LOG_END@json.output@@@"
+    ]
+  },
+  {
+    "cmd": [
+      "ls",
+      "-al",
+      "[CLEANUP]/tmp_tmp_1/osx_sdk"
+    ],
+    "infra_step": true,
+    "name": "install xcode (3).Show tool_dir cache",
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@"
+    ]
+  },
+  {
+    "cmd": [
+      "[CLEANUP]/tmp_tmp_1/osx_sdk/mac_toolchain",
+      "install",
+      "-kind",
+      "mac",
+      "-xcode-version",
+      "deadbeef",
+      "-output-dir",
+      "/opt/flutter/xcode/deadbeef/XCode.app",
+      "-cipd-package-prefix",
+      "infra_internal/ios/xcode",
+      "-with-runtime=True",
+      "-verbose"
+    ],
+    "infra_step": true,
+    "name": "install xcode (3).install xcode from cipd",
+    "timeout": 1800,
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@"
+    ]
+  },
+  {
+    "cmd": [],
+    "name": "Cleaning up runtimes cache (3)"
+  },
+  {
+    "cmd": [
+      "sudo",
+      "xcode-select",
+      "--switch",
+      "/opt/flutter/xcode/deadbeef/XCode.app"
+    ],
+    "infra_step": true,
+    "name": "Cleaning up runtimes cache (3).select xcode",
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@"
+    ]
+  },
+  {
+    "cmd": [
+      "xcrun",
+      "simctl",
+      "runtime",
+      "delete",
+      "all"
+    ],
+    "infra_step": true,
+    "name": "Cleaning up runtimes cache (3).Cleaning up mounted simulator runtimes",
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@",
+      "@@@STEP_LOG_END@raw_io.output_text@@@"
+    ]
+  },
+  {
+    "cmd": [
+      "xcrun",
+      "simctl",
+      "list",
+      "runtimes"
+    ],
+    "infra_step": true,
+    "name": "Cleaning up runtimes cache (3).list runtimes",
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@",
+      "@@@STEP_LOG_END@raw_io.output_text@@@"
+    ]
+  },
+  {
+    "cmd": [],
+    "name": "install runtimes (3)"
+  },
+  {
+    "cmd": [],
+    "name": "install runtimes (3).install xcode",
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@"
+    ]
+  },
+  {
+    "cmd": [
+      "cipd",
+      "ensure",
+      "-root",
+      "[CLEANUP]/tmp_tmp_1/osx_sdk",
+      "-ensure-file",
+      "infra/tools/mac_toolchain/${platform} latest",
+      "-max-threads",
+      "0",
+      "-json-output",
+      "/path/to/tmp/json"
+    ],
+    "infra_step": true,
+    "name": "install runtimes (3).install xcode.ensure_installed",
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@2@@@",
+      "@@@STEP_LOG_LINE@json.output@{@@@",
+      "@@@STEP_LOG_LINE@json.output@  \"result\": {@@@",
+      "@@@STEP_LOG_LINE@json.output@    \"\": [@@@",
+      "@@@STEP_LOG_LINE@json.output@      {@@@",
+      "@@@STEP_LOG_LINE@json.output@        \"instance_id\": \"resolved-instance_id-of-latest----------\",@@@",
+      "@@@STEP_LOG_LINE@json.output@        \"package\": \"infra/tools/mac_toolchain/resolved-platform\"@@@",
+      "@@@STEP_LOG_LINE@json.output@      }@@@",
+      "@@@STEP_LOG_LINE@json.output@    ]@@@",
+      "@@@STEP_LOG_LINE@json.output@  }@@@",
+      "@@@STEP_LOG_LINE@json.output@}@@@",
+      "@@@STEP_LOG_END@json.output@@@"
+    ]
+  },
+  {
+    "cmd": [
+      "ls",
+      "-al",
+      "[CLEANUP]/tmp_tmp_1/osx_sdk"
+    ],
+    "infra_step": true,
+    "name": "install runtimes (3).install xcode.Show tool_dir cache",
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@2@@@"
+    ]
+  },
+  {
+    "cmd": [
+      "[CLEANUP]/tmp_tmp_1/osx_sdk/mac_toolchain",
+      "install",
+      "-kind",
+      "mac",
+      "-xcode-version",
+      "deadbeef",
+      "-output-dir",
+      "/opt/flutter/xcode/deadbeef/XCode.app",
+      "-cipd-package-prefix",
+      "infra_internal/ios/xcode",
+      "-with-runtime=True",
+      "-verbose"
+    ],
+    "infra_step": true,
+    "name": "install runtimes (3).install xcode.install xcode from cipd",
+    "timeout": 1800,
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@2@@@"
+    ]
+  },
+  {
+    "cmd": [
+      "killall",
+      "-9",
+      "com.apple.CoreSimulator.CoreSimulatorDevice"
+    ],
+    "infra_step": true,
+    "name": "kill dart (3)"
+  },
+  {
+    "cmd": [
+      "sudo",
+      "xcode-select",
+      "--switch",
+      "/opt/flutter/xcode/deadbeef/XCode.app"
+    ],
+    "infra_step": true,
+    "name": "select xcode (3)"
+  },
+  {
+    "cmd": [
+      "xcrun",
+      "simctl",
+      "list"
+    ],
+    "infra_step": true,
+    "name": "list simulators (3)"
+  },
+  {
+    "cmd": [
+      "xcrun",
+      "simctl",
+      "list",
+      "runtimes"
+    ],
+    "infra_step": true,
+    "name": "list runtimes (2)"
+  },
+  {
+    "cmd": [
+      "vpython3",
+      "-u",
+      "RECIPE_MODULE[recipe_engine::file]/resources/fileutil.py",
+      "--json-output",
+      "/path/to/tmp/json",
+      "rmtree",
+      "/opt/flutter/xcode/deadbeef"
+    ],
+    "infra_step": true,
+    "name": "Cleaning up Xcode cache (3)"
+  },
+  {
+    "cmd": [],
+    "name": "install xcode (4)"
+  },
+  {
+    "cmd": [
+      "cipd",
+      "ensure",
+      "-root",
+      "[CLEANUP]/tmp_tmp_2/osx_sdk",
+      "-ensure-file",
+      "infra/tools/mac_toolchain/${platform} latest",
+      "-max-threads",
+      "0",
+      "-json-output",
+      "/path/to/tmp/json"
+    ],
+    "infra_step": true,
+    "name": "install xcode (4).ensure_installed",
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@",
+      "@@@STEP_LOG_LINE@json.output@{@@@",
+      "@@@STEP_LOG_LINE@json.output@  \"result\": {@@@",
+      "@@@STEP_LOG_LINE@json.output@    \"\": [@@@",
+      "@@@STEP_LOG_LINE@json.output@      {@@@",
+      "@@@STEP_LOG_LINE@json.output@        \"instance_id\": \"resolved-instance_id-of-latest----------\",@@@",
+      "@@@STEP_LOG_LINE@json.output@        \"package\": \"infra/tools/mac_toolchain/resolved-platform\"@@@",
+      "@@@STEP_LOG_LINE@json.output@      }@@@",
+      "@@@STEP_LOG_LINE@json.output@    ]@@@",
+      "@@@STEP_LOG_LINE@json.output@  }@@@",
+      "@@@STEP_LOG_LINE@json.output@}@@@",
+      "@@@STEP_LOG_END@json.output@@@"
+    ]
+  },
+  {
+    "cmd": [
+      "ls",
+      "-al",
+      "[CLEANUP]/tmp_tmp_2/osx_sdk"
+    ],
+    "infra_step": true,
+    "name": "install xcode (4).Show tool_dir cache",
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@"
+    ]
+  },
+  {
+    "cmd": [
+      "[CLEANUP]/tmp_tmp_2/osx_sdk/mac_toolchain",
+      "install",
+      "-kind",
+      "mac",
+      "-xcode-version",
+      "deadbeef",
+      "-output-dir",
+      "/opt/flutter/xcode/deadbeef/XCode.app",
+      "-cipd-package-prefix",
+      "infra_internal/ios/xcode",
+      "-with-runtime=True",
+      "-verbose"
+    ],
+    "infra_step": true,
+    "name": "install xcode (4).install xcode from cipd",
+    "timeout": 1800,
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@"
+    ]
+  },
+  {
+    "cmd": [],
+    "name": "Cleaning up runtimes cache (4)"
+  },
+  {
+    "cmd": [
+      "sudo",
+      "xcode-select",
+      "--switch",
+      "/opt/flutter/xcode/deadbeef/XCode.app"
+    ],
+    "infra_step": true,
+    "name": "Cleaning up runtimes cache (4).select xcode",
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@"
+    ]
+  },
+  {
+    "cmd": [
+      "xcrun",
+      "simctl",
+      "runtime",
+      "delete",
+      "all"
+    ],
+    "infra_step": true,
+    "name": "Cleaning up runtimes cache (4).Cleaning up mounted simulator runtimes",
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@",
+      "@@@STEP_LOG_END@raw_io.output_text@@@"
+    ]
+  },
+  {
+    "cmd": [
+      "xcrun",
+      "simctl",
+      "list",
+      "runtimes"
+    ],
+    "infra_step": true,
+    "name": "Cleaning up runtimes cache (4).list runtimes",
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@",
+      "@@@STEP_LOG_END@raw_io.output_text@@@"
+    ]
+  },
+  {
+    "cmd": [],
+    "name": "install runtimes (4)"
+  },
+  {
+    "cmd": [],
+    "name": "install runtimes (4).install xcode",
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@"
+    ]
+  },
+  {
+    "cmd": [
+      "cipd",
+      "ensure",
+      "-root",
+      "[CLEANUP]/tmp_tmp_2/osx_sdk",
+      "-ensure-file",
+      "infra/tools/mac_toolchain/${platform} latest",
+      "-max-threads",
+      "0",
+      "-json-output",
+      "/path/to/tmp/json"
+    ],
+    "infra_step": true,
+    "name": "install runtimes (4).install xcode.ensure_installed",
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@2@@@",
+      "@@@STEP_LOG_LINE@json.output@{@@@",
+      "@@@STEP_LOG_LINE@json.output@  \"result\": {@@@",
+      "@@@STEP_LOG_LINE@json.output@    \"\": [@@@",
+      "@@@STEP_LOG_LINE@json.output@      {@@@",
+      "@@@STEP_LOG_LINE@json.output@        \"instance_id\": \"resolved-instance_id-of-latest----------\",@@@",
+      "@@@STEP_LOG_LINE@json.output@        \"package\": \"infra/tools/mac_toolchain/resolved-platform\"@@@",
+      "@@@STEP_LOG_LINE@json.output@      }@@@",
+      "@@@STEP_LOG_LINE@json.output@    ]@@@",
+      "@@@STEP_LOG_LINE@json.output@  }@@@",
+      "@@@STEP_LOG_LINE@json.output@}@@@",
+      "@@@STEP_LOG_END@json.output@@@"
+    ]
+  },
+  {
+    "cmd": [
+      "ls",
+      "-al",
+      "[CLEANUP]/tmp_tmp_2/osx_sdk"
+    ],
+    "infra_step": true,
+    "name": "install runtimes (4).install xcode.Show tool_dir cache",
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@2@@@"
+    ]
+  },
+  {
+    "cmd": [
+      "[CLEANUP]/tmp_tmp_2/osx_sdk/mac_toolchain",
+      "install",
+      "-kind",
+      "mac",
+      "-xcode-version",
+      "deadbeef",
+      "-output-dir",
+      "/opt/flutter/xcode/deadbeef/XCode.app",
+      "-cipd-package-prefix",
+      "infra_internal/ios/xcode",
+      "-with-runtime=True",
+      "-verbose"
+    ],
+    "infra_step": true,
+    "name": "install runtimes (4).install xcode.install xcode from cipd",
+    "timeout": 1800,
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@2@@@"
+    ]
+  },
+  {
+    "cmd": [
+      "killall",
+      "-9",
+      "com.apple.CoreSimulator.CoreSimulatorDevice"
+    ],
+    "infra_step": true,
+    "name": "kill dart (4)"
+  },
+  {
+    "cmd": [
+      "sudo",
+      "xcode-select",
+      "--switch",
+      "/opt/flutter/xcode/deadbeef/XCode.app"
+    ],
+    "infra_step": true,
+    "name": "select xcode (4)"
+  },
+  {
+    "cmd": [
+      "xcrun",
+      "simctl",
+      "list"
+    ],
+    "infra_step": true,
+    "name": "list simulators (4)"
+  },
+  {
+    "cmd": [
+      "gn",
+      "gen",
+      "out/Release"
+    ],
+    "name": "gn (2)"
+  },
+  {
+    "cmd": [
+      "ninja",
+      "-C",
+      "out/Release"
+    ],
+    "name": "ninja (2)"
+  },
+  {
+    "cmd": [
+      "sudo",
+      "xcode-select",
+      "--reset"
+    ],
+    "infra_step": true,
+    "name": "reset XCode (2)"
+  },
+  {
+    "cmd": [
+      "sudo",
+      "xcode-select",
+      "--reset"
+    ],
+    "infra_step": true,
+    "name": "reset XCode (3)"
+  },
+  {
+    "name": "$result"
+  }
+]
\ No newline at end of file
diff --git a/recipe_modules/osx_sdk/examples/full.py b/recipe_modules/osx_sdk/examples/full.py
index efd2b0b..54a8858 100644
--- a/recipe_modules/osx_sdk/examples/full.py
+++ b/recipe_modules/osx_sdk/examples/full.py
@@ -23,6 +23,7 @@
   with api.osx_sdk('mac', devicelab=True):
     api.step('gn', ['gn', 'gen', 'out/Release'])
     api.step('ninja', ['ninja', '-C', 'out/Release'])
+  api.osx_sdk.reset_xcode()
 
 
 def GenTests(api):
@@ -412,20 +413,14 @@
   )
 
   yield api.test(
-      'xcode_install_fails',
-      api.platform.name('mac'),
-      api.properties(**{'$flutter/osx_sdk': {'sdk_version': 'deadbeef',}}),
-      api.step_data('install xcode', retcode=1),
-      api.step_data('install xcode (2)', retcode=1),
-      status='INFRA_FAILURE'
-  )
-
-  yield api.test(
-      'mac_13_xcode_install_fails',
+      'xcode_install_fails_passes_on_retry',
       api.platform.name('mac'),
       api.platform.mac_release('13.5.1'),
       api.properties(**{'$flutter/osx_sdk': {'sdk_version': 'deadbeef',}}),
-      api.step_data('install xcode', retcode=1),
-      api.step_data('install xcode (2)', retcode=1),
-      status='INFRA_FAILURE'
+      api.path.exists(sdk_app_path),
+      api.step_data(
+          'install xcode.verify xcode [CACHE]/osx_sdk/xcode_deadbeef/XCode.app.check xcode version',
+          retcode=1
+      ),
+      api.step_data('install xcode.install xcode from cipd', retcode=1),
   )
diff --git a/recipes/devicelab/devicelab_drone.expected/no-task-name.json b/recipes/devicelab/devicelab_drone.expected/no-task-name.json
index 1b63109..a801877 100644
--- a/recipes/devicelab/devicelab_drone.expected/no-task-name.json
+++ b/recipes/devicelab/devicelab_drone.expected/no-task-name.json
@@ -19,7 +19,7 @@
       "The recipe has crashed at point 'Uncaught exception'!",
       "",
       "Traceback (most recent call last):",
-      "  File \"RECIPE_REPO[flutter]/recipes/devicelab/devicelab_drone.py\", line 43, in RunSteps",
+      "  File \"RECIPE_REPO[flutter]/recipes/devicelab/devicelab_drone.py\", line 46, in RunSteps",
       "    raise ValueError('A task_name property is required')",
       "ValueError('A task_name property is required')"
     ]
diff --git a/recipes/devicelab/devicelab_drone.expected/upload-metrics-mac.json b/recipes/devicelab/devicelab_drone.expected/upload-metrics-mac.json
index 309be5f..68a8bbc 100644
--- a/recipes/devicelab/devicelab_drone.expected/upload-metrics-mac.json
+++ b/recipes/devicelab/devicelab_drone.expected/upload-metrics-mac.json
@@ -63,6 +63,27 @@
     "name": "git xattr info"
   },
   {
+    "cmd": [
+      "sudo",
+      "xcode-select",
+      "--reset"
+    ],
+    "infra_step": true,
+    "luci_context": {
+      "realm": {
+        "name": "project:ci"
+      },
+      "resultdb": {
+        "current_invocation": {
+          "name": "invocations/build:8945511751514863184",
+          "update_token": "token"
+        },
+        "hostname": "rdbhost"
+      }
+    },
+    "name": "reset XCode"
+  },
+  {
     "cmd": [],
     "name": "Checkout flutter/flutter"
   },
@@ -584,6 +605,10 @@
     "name": "Show xcode cache"
   },
   {
+    "cmd": [],
+    "name": "install xcode"
+  },
+  {
     "cmd": [
       "cipd",
       "ensure",
@@ -631,8 +656,9 @@
         "hostname": "rdbhost"
       }
     },
-    "name": "ensure_installed",
+    "name": "install xcode.ensure_installed",
     "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@",
       "@@@STEP_LOG_LINE@json.output@{@@@",
       "@@@STEP_LOG_LINE@json.output@  \"result\": {@@@",
       "@@@STEP_LOG_LINE@json.output@    \"\": [@@@",
@@ -696,7 +722,11 @@
         "hostname": "rdbhost"
       }
     },
-    "name": "install xcode"
+    "name": "install xcode.install xcode from cipd",
+    "timeout": 1800,
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@"
+    ]
   },
   {
     "cmd": [
@@ -783,7 +813,7 @@
         "hostname": "rdbhost"
       }
     },
-    "name": "select XCode"
+    "name": "select xcode"
   },
   {
     "cmd": [
@@ -920,6 +950,10 @@
     "name": "Cleaning up Xcode cache"
   },
   {
+    "cmd": [],
+    "name": "install xcode (2)"
+  },
+  {
     "cmd": [
       "cipd",
       "ensure",
@@ -967,8 +1001,9 @@
         "hostname": "rdbhost"
       }
     },
-    "name": "ensure_installed (2)",
+    "name": "install xcode (2).ensure_installed",
     "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@",
       "@@@STEP_LOG_LINE@json.output@{@@@",
       "@@@STEP_LOG_LINE@json.output@  \"result\": {@@@",
       "@@@STEP_LOG_LINE@json.output@    \"\": [@@@",
@@ -1032,7 +1067,11 @@
         "hostname": "rdbhost"
       }
     },
-    "name": "install xcode (2)"
+    "name": "install xcode (2).install xcode from cipd",
+    "timeout": 1800,
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@"
+    ]
   },
   {
     "cmd": [
@@ -1119,7 +1158,7 @@
         "hostname": "rdbhost"
       }
     },
-    "name": "select XCode (2)"
+    "name": "select xcode (2)"
   },
   {
     "cmd": [
@@ -2002,7 +2041,7 @@
         "hostname": "rdbhost"
       }
     },
-    "name": "reset XCode"
+    "name": "reset XCode (2)"
   },
   {
     "cmd": [],
diff --git a/recipes/devicelab/devicelab_drone.expected/xcode-chromium-mac.json b/recipes/devicelab/devicelab_drone.expected/xcode-chromium-mac.json
index 51e6843..6084f13 100644
--- a/recipes/devicelab/devicelab_drone.expected/xcode-chromium-mac.json
+++ b/recipes/devicelab/devicelab_drone.expected/xcode-chromium-mac.json
@@ -63,6 +63,27 @@
     "name": "git xattr info"
   },
   {
+    "cmd": [
+      "sudo",
+      "xcode-select",
+      "--reset"
+    ],
+    "infra_step": true,
+    "luci_context": {
+      "realm": {
+        "name": "project:ci"
+      },
+      "resultdb": {
+        "current_invocation": {
+          "name": "invocations/build:8945511751514863184",
+          "update_token": "token"
+        },
+        "hostname": "rdbhost"
+      }
+    },
+    "name": "reset XCode"
+  },
+  {
     "cmd": [],
     "name": "Checkout flutter/flutter"
   },
@@ -584,6 +605,10 @@
     "name": "Show xcode cache"
   },
   {
+    "cmd": [],
+    "name": "install xcode"
+  },
+  {
     "cmd": [
       "cipd",
       "ensure",
@@ -631,8 +656,9 @@
         "hostname": "rdbhost"
       }
     },
-    "name": "ensure_installed",
+    "name": "install xcode.ensure_installed",
     "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@",
       "@@@STEP_LOG_LINE@json.output@{@@@",
       "@@@STEP_LOG_LINE@json.output@  \"result\": {@@@",
       "@@@STEP_LOG_LINE@json.output@    \"\": [@@@",
@@ -696,7 +722,11 @@
         "hostname": "rdbhost"
       }
     },
-    "name": "install xcode"
+    "name": "install xcode.install xcode from cipd",
+    "timeout": 1800,
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@"
+    ]
   },
   {
     "cmd": [
@@ -783,7 +813,7 @@
         "hostname": "rdbhost"
       }
     },
-    "name": "select XCode"
+    "name": "select xcode"
   },
   {
     "cmd": [
@@ -920,6 +950,10 @@
     "name": "Cleaning up Xcode cache"
   },
   {
+    "cmd": [],
+    "name": "install xcode (2)"
+  },
+  {
     "cmd": [
       "cipd",
       "ensure",
@@ -967,8 +1001,9 @@
         "hostname": "rdbhost"
       }
     },
-    "name": "ensure_installed (2)",
+    "name": "install xcode (2).ensure_installed",
     "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@",
       "@@@STEP_LOG_LINE@json.output@{@@@",
       "@@@STEP_LOG_LINE@json.output@  \"result\": {@@@",
       "@@@STEP_LOG_LINE@json.output@    \"\": [@@@",
@@ -1032,7 +1067,11 @@
         "hostname": "rdbhost"
       }
     },
-    "name": "install xcode (2)"
+    "name": "install xcode (2).install xcode from cipd",
+    "timeout": 1800,
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@"
+    ]
   },
   {
     "cmd": [
@@ -1119,7 +1158,7 @@
         "hostname": "rdbhost"
       }
     },
-    "name": "select XCode (2)"
+    "name": "select xcode (2)"
   },
   {
     "cmd": [
@@ -2002,7 +2041,7 @@
         "hostname": "rdbhost"
       }
     },
-    "name": "reset XCode"
+    "name": "reset XCode (2)"
   },
   {
     "cmd": [],
diff --git a/recipes/devicelab/devicelab_drone.expected/xcode-devicelab-timeout.json b/recipes/devicelab/devicelab_drone.expected/xcode-devicelab-timeout.json
index cf2de1e..990dceb 100644
--- a/recipes/devicelab/devicelab_drone.expected/xcode-devicelab-timeout.json
+++ b/recipes/devicelab/devicelab_drone.expected/xcode-devicelab-timeout.json
@@ -63,6 +63,27 @@
     "name": "git xattr info"
   },
   {
+    "cmd": [
+      "sudo",
+      "xcode-select",
+      "--reset"
+    ],
+    "infra_step": true,
+    "luci_context": {
+      "realm": {
+        "name": "project:ci"
+      },
+      "resultdb": {
+        "current_invocation": {
+          "name": "invocations/build:8945511751514863184",
+          "update_token": "token"
+        },
+        "hostname": "rdbhost"
+      }
+    },
+    "name": "reset XCode"
+  },
+  {
     "cmd": [],
     "name": "Checkout flutter/flutter"
   },
@@ -584,6 +605,10 @@
     "name": "Show xcode cache"
   },
   {
+    "cmd": [],
+    "name": "install xcode"
+  },
+  {
     "cmd": [
       "cipd",
       "ensure",
@@ -631,8 +656,9 @@
         "hostname": "rdbhost"
       }
     },
-    "name": "ensure_installed",
+    "name": "install xcode.ensure_installed",
     "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@",
       "@@@STEP_LOG_LINE@json.output@{@@@",
       "@@@STEP_LOG_LINE@json.output@  \"result\": {@@@",
       "@@@STEP_LOG_LINE@json.output@    \"\": [@@@",
@@ -696,7 +722,11 @@
         "hostname": "rdbhost"
       }
     },
-    "name": "install xcode"
+    "name": "install xcode.install xcode from cipd",
+    "timeout": 1800,
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@"
+    ]
   },
   {
     "cmd": [
@@ -783,7 +813,7 @@
         "hostname": "rdbhost"
       }
     },
-    "name": "select XCode"
+    "name": "select xcode"
   },
   {
     "cmd": [
@@ -920,6 +950,10 @@
     "name": "Cleaning up Xcode cache"
   },
   {
+    "cmd": [],
+    "name": "install xcode (2)"
+  },
+  {
     "cmd": [
       "cipd",
       "ensure",
@@ -967,8 +1001,9 @@
         "hostname": "rdbhost"
       }
     },
-    "name": "ensure_installed (2)",
+    "name": "install xcode (2).ensure_installed",
     "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@",
       "@@@STEP_LOG_LINE@json.output@{@@@",
       "@@@STEP_LOG_LINE@json.output@  \"result\": {@@@",
       "@@@STEP_LOG_LINE@json.output@    \"\": [@@@",
@@ -1032,7 +1067,11 @@
         "hostname": "rdbhost"
       }
     },
-    "name": "install xcode (2)"
+    "name": "install xcode (2).install xcode from cipd",
+    "timeout": 1800,
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@"
+    ]
   },
   {
     "cmd": [
@@ -1119,7 +1158,7 @@
         "hostname": "rdbhost"
       }
     },
-    "name": "select XCode (2)"
+    "name": "select xcode (2)"
   },
   {
     "cmd": [
@@ -4171,7 +4210,7 @@
         "hostname": "rdbhost"
       }
     },
-    "name": "reset XCode"
+    "name": "reset XCode (2)"
   },
   {
     "failure": {
diff --git a/recipes/devicelab/devicelab_drone.expected/xcode-devicelab.json b/recipes/devicelab/devicelab_drone.expected/xcode-devicelab.json
index 8233684..996c5ae 100644
--- a/recipes/devicelab/devicelab_drone.expected/xcode-devicelab.json
+++ b/recipes/devicelab/devicelab_drone.expected/xcode-devicelab.json
@@ -63,6 +63,27 @@
     "name": "git xattr info"
   },
   {
+    "cmd": [
+      "sudo",
+      "xcode-select",
+      "--reset"
+    ],
+    "infra_step": true,
+    "luci_context": {
+      "realm": {
+        "name": "project:ci"
+      },
+      "resultdb": {
+        "current_invocation": {
+          "name": "invocations/build:8945511751514863184",
+          "update_token": "token"
+        },
+        "hostname": "rdbhost"
+      }
+    },
+    "name": "reset XCode"
+  },
+  {
     "cmd": [],
     "name": "Checkout flutter/flutter"
   },
@@ -584,6 +605,10 @@
     "name": "Show xcode cache"
   },
   {
+    "cmd": [],
+    "name": "install xcode"
+  },
+  {
     "cmd": [
       "cipd",
       "ensure",
@@ -631,8 +656,9 @@
         "hostname": "rdbhost"
       }
     },
-    "name": "ensure_installed",
+    "name": "install xcode.ensure_installed",
     "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@",
       "@@@STEP_LOG_LINE@json.output@{@@@",
       "@@@STEP_LOG_LINE@json.output@  \"result\": {@@@",
       "@@@STEP_LOG_LINE@json.output@    \"\": [@@@",
@@ -696,7 +722,11 @@
         "hostname": "rdbhost"
       }
     },
-    "name": "install xcode"
+    "name": "install xcode.install xcode from cipd",
+    "timeout": 1800,
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@"
+    ]
   },
   {
     "cmd": [
@@ -783,7 +813,7 @@
         "hostname": "rdbhost"
       }
     },
-    "name": "select XCode"
+    "name": "select xcode"
   },
   {
     "cmd": [
@@ -920,6 +950,10 @@
     "name": "Cleaning up Xcode cache"
   },
   {
+    "cmd": [],
+    "name": "install xcode (2)"
+  },
+  {
     "cmd": [
       "cipd",
       "ensure",
@@ -967,8 +1001,9 @@
         "hostname": "rdbhost"
       }
     },
-    "name": "ensure_installed (2)",
+    "name": "install xcode (2).ensure_installed",
     "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@",
       "@@@STEP_LOG_LINE@json.output@{@@@",
       "@@@STEP_LOG_LINE@json.output@  \"result\": {@@@",
       "@@@STEP_LOG_LINE@json.output@    \"\": [@@@",
@@ -1032,7 +1067,11 @@
         "hostname": "rdbhost"
       }
     },
-    "name": "install xcode (2)"
+    "name": "install xcode (2).install xcode from cipd",
+    "timeout": 1800,
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@"
+    ]
   },
   {
     "cmd": [
@@ -1119,7 +1158,7 @@
         "hostname": "rdbhost"
       }
     },
-    "name": "select XCode (2)"
+    "name": "select xcode (2)"
   },
   {
     "cmd": [
@@ -3707,7 +3746,7 @@
         "hostname": "rdbhost"
       }
     },
-    "name": "reset XCode"
+    "name": "reset XCode (2)"
   },
   {
     "cmd": [],
diff --git a/recipes/devicelab/devicelab_drone.py b/recipes/devicelab/devicelab_drone.py
index 9496b1a..d459325 100644
--- a/recipes/devicelab/devicelab_drone.py
+++ b/recipes/devicelab/devicelab_drone.py
@@ -38,6 +38,9 @@
   # Collect memory/cpu/process before task execution.
   api.os_utils.collect_os_info()
 
+  # If on macOS, reset Xcode in case a previous build failed to do so.
+  api.osx_sdk.reset_xcode()
+
   task_name = api.properties.get("task_name")
   if not task_name:
     raise ValueError('A task_name property is required')
diff --git a/recipes/devicelab/devicelab_drone_build_test.expected/no-task-name.json b/recipes/devicelab/devicelab_drone_build_test.expected/no-task-name.json
index d4546a6..9793034 100644
--- a/recipes/devicelab/devicelab_drone_build_test.expected/no-task-name.json
+++ b/recipes/devicelab/devicelab_drone_build_test.expected/no-task-name.json
@@ -19,7 +19,7 @@
       "The recipe has crashed at point 'Uncaught exception'!",
       "",
       "Traceback (most recent call last):",
-      "  File \"RECIPE_REPO[flutter]/recipes/devicelab/devicelab_drone_build_test.py\", line 60, in RunSteps",
+      "  File \"RECIPE_REPO[flutter]/recipes/devicelab/devicelab_drone_build_test.py\", line 63, in RunSteps",
       "    raise ValueError('A task_name property is required')",
       "ValueError('A task_name property is required')"
     ]
diff --git a/recipes/devicelab/devicelab_drone_build_test.expected/xcode-mac.json b/recipes/devicelab/devicelab_drone_build_test.expected/xcode-mac.json
index d8d3521..ad7bb1f 100644
--- a/recipes/devicelab/devicelab_drone_build_test.expected/xcode-mac.json
+++ b/recipes/devicelab/devicelab_drone_build_test.expected/xcode-mac.json
@@ -64,6 +64,27 @@
   },
   {
     "cmd": [
+      "sudo",
+      "xcode-select",
+      "--reset"
+    ],
+    "infra_step": true,
+    "luci_context": {
+      "realm": {
+        "name": "project:ci"
+      },
+      "resultdb": {
+        "current_invocation": {
+          "name": "invocations/build:8945511751514863184",
+          "update_token": "token"
+        },
+        "hostname": "rdbhost"
+      }
+    },
+    "name": "reset XCode"
+  },
+  {
+    "cmd": [
       "python3",
       "-u",
       "RECIPE_MODULE[depot_tools::gsutil]/resources/gsutil_smart_retry.py",
@@ -500,6 +521,10 @@
     "name": "Show xcode cache"
   },
   {
+    "cmd": [],
+    "name": "install xcode"
+  },
+  {
     "cmd": [
       "cipd",
       "ensure",
@@ -546,8 +571,9 @@
         "hostname": "rdbhost"
       }
     },
-    "name": "ensure_installed",
+    "name": "install xcode.ensure_installed",
     "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@",
       "@@@STEP_LOG_LINE@json.output@{@@@",
       "@@@STEP_LOG_LINE@json.output@  \"result\": {@@@",
       "@@@STEP_LOG_LINE@json.output@    \"\": [@@@",
@@ -610,7 +636,11 @@
         "hostname": "rdbhost"
       }
     },
-    "name": "install xcode"
+    "name": "install xcode.install xcode from cipd",
+    "timeout": 1800,
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@"
+    ]
   },
   {
     "cmd": [
@@ -695,7 +725,7 @@
         "hostname": "rdbhost"
       }
     },
-    "name": "select XCode"
+    "name": "select xcode"
   },
   {
     "cmd": [
@@ -829,6 +859,10 @@
     "name": "Cleaning up Xcode cache"
   },
   {
+    "cmd": [],
+    "name": "install xcode (2)"
+  },
+  {
     "cmd": [
       "cipd",
       "ensure",
@@ -875,8 +909,9 @@
         "hostname": "rdbhost"
       }
     },
-    "name": "ensure_installed (2)",
+    "name": "install xcode (2).ensure_installed",
     "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@",
       "@@@STEP_LOG_LINE@json.output@{@@@",
       "@@@STEP_LOG_LINE@json.output@  \"result\": {@@@",
       "@@@STEP_LOG_LINE@json.output@    \"\": [@@@",
@@ -939,7 +974,11 @@
         "hostname": "rdbhost"
       }
     },
-    "name": "install xcode (2)"
+    "name": "install xcode (2).install xcode from cipd",
+    "timeout": 1800,
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@"
+    ]
   },
   {
     "cmd": [
@@ -1024,7 +1063,7 @@
         "hostname": "rdbhost"
       }
     },
-    "name": "select XCode (2)"
+    "name": "select xcode (2)"
   },
   {
     "cmd": [
@@ -1633,7 +1672,7 @@
         "hostname": "rdbhost"
       }
     },
-    "name": "reset XCode"
+    "name": "reset XCode (2)"
   },
   {
     "cmd": [
diff --git a/recipes/devicelab/devicelab_drone_build_test.py b/recipes/devicelab/devicelab_drone_build_test.py
index b595da7..0362206 100644
--- a/recipes/devicelab/devicelab_drone_build_test.py
+++ b/recipes/devicelab/devicelab_drone_build_test.py
@@ -54,6 +54,9 @@
   # Collect memory/cpu/process before task execution.
   api.os_utils.collect_os_info()
 
+  # If on macOS, reset Xcode in case a previous build failed to do so.
+  api.osx_sdk.reset_xcode()
+
   api.os_utils.print_pub_certs()
   task_name = api.properties.get("task_name")
   if not task_name:
diff --git a/recipes/devicelab/devicelab_test_drone.expected/mac.json b/recipes/devicelab/devicelab_test_drone.expected/mac.json
index 73bdedb..8bd64cf 100644
--- a/recipes/devicelab/devicelab_test_drone.expected/mac.json
+++ b/recipes/devicelab/devicelab_test_drone.expected/mac.json
@@ -63,6 +63,27 @@
     "name": "git xattr info"
   },
   {
+    "cmd": [
+      "sudo",
+      "xcode-select",
+      "--reset"
+    ],
+    "infra_step": true,
+    "luci_context": {
+      "realm": {
+        "name": "project:ci"
+      },
+      "resultdb": {
+        "current_invocation": {
+          "name": "invocations/build:8945511751514863184",
+          "update_token": "token"
+        },
+        "hostname": "rdbhost"
+      }
+    },
+    "name": "reset XCode"
+  },
+  {
     "cmd": [],
     "name": "Checkout flutter/flutter"
   },
@@ -607,6 +628,10 @@
     "name": "Show xcode cache"
   },
   {
+    "cmd": [],
+    "name": "install xcode"
+  },
+  {
     "cmd": [
       "cipd",
       "ensure",
@@ -653,8 +678,9 @@
         "hostname": "rdbhost"
       }
     },
-    "name": "ensure_installed",
+    "name": "install xcode.ensure_installed",
     "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@",
       "@@@STEP_LOG_LINE@json.output@{@@@",
       "@@@STEP_LOG_LINE@json.output@  \"result\": {@@@",
       "@@@STEP_LOG_LINE@json.output@    \"\": [@@@",
@@ -717,7 +743,11 @@
         "hostname": "rdbhost"
       }
     },
-    "name": "install xcode"
+    "name": "install xcode.install xcode from cipd",
+    "timeout": 1800,
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@"
+    ]
   },
   {
     "cmd": [
@@ -802,7 +832,7 @@
         "hostname": "rdbhost"
       }
     },
-    "name": "select XCode"
+    "name": "select xcode"
   },
   {
     "cmd": [
@@ -936,6 +966,10 @@
     "name": "Cleaning up Xcode cache"
   },
   {
+    "cmd": [],
+    "name": "install xcode (2)"
+  },
+  {
     "cmd": [
       "cipd",
       "ensure",
@@ -982,8 +1016,9 @@
         "hostname": "rdbhost"
       }
     },
-    "name": "ensure_installed (2)",
+    "name": "install xcode (2).ensure_installed",
     "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@",
       "@@@STEP_LOG_LINE@json.output@{@@@",
       "@@@STEP_LOG_LINE@json.output@  \"result\": {@@@",
       "@@@STEP_LOG_LINE@json.output@    \"\": [@@@",
@@ -1046,7 +1081,11 @@
         "hostname": "rdbhost"
       }
     },
-    "name": "install xcode (2)"
+    "name": "install xcode (2).install xcode from cipd",
+    "timeout": 1800,
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@"
+    ]
   },
   {
     "cmd": [
@@ -1131,7 +1170,7 @@
         "hostname": "rdbhost"
       }
     },
-    "name": "select XCode (2)"
+    "name": "select xcode (2)"
   },
   {
     "cmd": [
@@ -2007,7 +2046,7 @@
         "hostname": "rdbhost"
       }
     },
-    "name": "reset XCode"
+    "name": "reset XCode (2)"
   },
   {
     "cmd": [],
diff --git a/recipes/devicelab/devicelab_test_drone.expected/no-artifact-name.json b/recipes/devicelab/devicelab_test_drone.expected/no-artifact-name.json
index 285b968..767b13e 100644
--- a/recipes/devicelab/devicelab_test_drone.expected/no-artifact-name.json
+++ b/recipes/devicelab/devicelab_test_drone.expected/no-artifact-name.json
@@ -19,7 +19,7 @@
       "The recipe has crashed at point 'Uncaught exception'!",
       "",
       "Traceback (most recent call last):",
-      "  File \"RECIPE_REPO[flutter]/recipes/devicelab/devicelab_test_drone.py\", line 51, in RunSteps",
+      "  File \"RECIPE_REPO[flutter]/recipes/devicelab/devicelab_test_drone.py\", line 55, in RunSteps",
       "    raise ValueError('An artifact property is required')",
       "ValueError('An artifact property is required')"
     ]
diff --git a/recipes/devicelab/devicelab_test_drone.expected/no-task-name.json b/recipes/devicelab/devicelab_test_drone.expected/no-task-name.json
index c918fb5..52dd4c0 100644
--- a/recipes/devicelab/devicelab_test_drone.expected/no-task-name.json
+++ b/recipes/devicelab/devicelab_test_drone.expected/no-task-name.json
@@ -19,7 +19,7 @@
       "The recipe has crashed at point 'Uncaught exception'!",
       "",
       "Traceback (most recent call last):",
-      "  File \"RECIPE_REPO[flutter]/recipes/devicelab/devicelab_test_drone.py\", line 46, in RunSteps",
+      "  File \"RECIPE_REPO[flutter]/recipes/devicelab/devicelab_test_drone.py\", line 50, in RunSteps",
       "    raise ValueError('A task_name property is required')",
       "ValueError('A task_name property is required')"
     ]
diff --git a/recipes/devicelab/devicelab_test_drone.py b/recipes/devicelab/devicelab_test_drone.py
index b7daed9..52a4f0b 100644
--- a/recipes/devicelab/devicelab_test_drone.py
+++ b/recipes/devicelab/devicelab_test_drone.py
@@ -40,6 +40,10 @@
 def RunSteps(api):
   # Collect memory/cpu/process before task execution.
   api.os_utils.collect_os_info()
+
+  # If on macOS, reset Xcode in case a previous build failed to do so.
+  api.osx_sdk.reset_xcode()
+
   api.os_utils.print_pub_certs()
   task_name = api.properties.get("task_name")
   if not task_name:
diff --git a/recipes/engine_v2/builder.expected/mac.json b/recipes/engine_v2/builder.expected/mac.json
index c2f0a47..2424515 100644
--- a/recipes/engine_v2/builder.expected/mac.json
+++ b/recipes/engine_v2/builder.expected/mac.json
@@ -64,6 +64,27 @@
   },
   {
     "cmd": [
+      "sudo",
+      "xcode-select",
+      "--reset"
+    ],
+    "infra_step": true,
+    "luci_context": {
+      "realm": {
+        "name": "flutter:prod"
+      },
+      "resultdb": {
+        "current_invocation": {
+          "name": "invocations/build:8945511751514863184",
+          "update_token": "token"
+        },
+        "hostname": "rdbhost"
+      }
+    },
+    "name": "reset XCode"
+  },
+  {
+    "cmd": [
       "vpython3",
       "-u",
       "RECIPE_MODULE[recipe_engine::file]/resources/fileutil.py",
@@ -378,6 +399,10 @@
     "name": "Show xcode cache"
   },
   {
+    "cmd": [],
+    "name": "install xcode"
+  },
+  {
     "cmd": [
       "cipd",
       "ensure",
@@ -403,8 +428,9 @@
         "hostname": "rdbhost"
       }
     },
-    "name": "ensure_installed",
+    "name": "install xcode.ensure_installed",
     "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@",
       "@@@STEP_LOG_LINE@json.output@{@@@",
       "@@@STEP_LOG_LINE@json.output@  \"result\": {@@@",
       "@@@STEP_LOG_LINE@json.output@    \"\": [@@@",
@@ -446,7 +472,11 @@
         "hostname": "rdbhost"
       }
     },
-    "name": "install xcode"
+    "name": "install xcode.install xcode from cipd",
+    "timeout": 1800,
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@"
+    ]
   },
   {
     "cmd": [
@@ -489,7 +519,7 @@
         "hostname": "rdbhost"
       }
     },
-    "name": "select XCode"
+    "name": "select xcode"
   },
   {
     "cmd": [
@@ -560,6 +590,10 @@
     "name": "Cleaning up Xcode cache"
   },
   {
+    "cmd": [],
+    "name": "install xcode (2)"
+  },
+  {
     "cmd": [
       "cipd",
       "ensure",
@@ -585,8 +619,9 @@
         "hostname": "rdbhost"
       }
     },
-    "name": "ensure_installed (2)",
+    "name": "install xcode (2).ensure_installed",
     "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@",
       "@@@STEP_LOG_LINE@json.output@{@@@",
       "@@@STEP_LOG_LINE@json.output@  \"result\": {@@@",
       "@@@STEP_LOG_LINE@json.output@    \"\": [@@@",
@@ -628,7 +663,11 @@
         "hostname": "rdbhost"
       }
     },
-    "name": "install xcode (2)"
+    "name": "install xcode (2).install xcode from cipd",
+    "timeout": 1800,
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@"
+    ]
   },
   {
     "cmd": [
@@ -671,7 +710,7 @@
         "hostname": "rdbhost"
       }
     },
-    "name": "select XCode (2)"
+    "name": "select xcode (2)"
   },
   {
     "cmd": [
@@ -5711,7 +5750,7 @@
         "hostname": "rdbhost"
       }
     },
-    "name": "reset XCode"
+    "name": "reset XCode (2)"
   },
   {
     "cmd": [],
diff --git a/recipes/engine_v2/builder.py b/recipes/engine_v2/builder.py
index eff6378..e5cb18c 100644
--- a/recipes/engine_v2/builder.py
+++ b/recipes/engine_v2/builder.py
@@ -276,6 +276,10 @@
 def RunSteps(api):
   # Collect memory/cpu/process before task execution.
   api.os_utils.collect_os_info()
+
+  # If on macOS, reset Xcode in case a previous build failed to do so.
+  api.osx_sdk.reset_xcode()
+
   api.flutter_bcid.report_stage('start')
   checkout = api.path['cache'].join('builder', 'src')
   api.file.rmtree('Clobber build output', checkout.join('out'))
diff --git a/recipes/engine_v2/engine_v2.expected/basic_mac.json b/recipes/engine_v2/engine_v2.expected/basic_mac.json
index f7e3e02..f4b2bf9 100644
--- a/recipes/engine_v2/engine_v2.expected/basic_mac.json
+++ b/recipes/engine_v2/engine_v2.expected/basic_mac.json
@@ -590,6 +590,27 @@
   },
   {
     "cmd": [
+      "sudo",
+      "xcode-select",
+      "--reset"
+    ],
+    "infra_step": true,
+    "luci_context": {
+      "realm": {
+        "name": "flutter:prod"
+      },
+      "resultdb": {
+        "current_invocation": {
+          "name": "invocations/build:8945511751514863184",
+          "update_token": "token"
+        },
+        "hostname": "rdbhost"
+      }
+    },
+    "name": "reset XCode"
+  },
+  {
+    "cmd": [
       "vpython3",
       "-u",
       "RECIPE_MODULE[recipe_engine::file]/resources/fileutil.py",
@@ -642,6 +663,13 @@
     ]
   },
   {
+    "cmd": [],
+    "name": "Global generators.install xcode",
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@"
+    ]
+  },
+  {
     "cmd": [
       "cipd",
       "ensure",
@@ -667,9 +695,9 @@
         "hostname": "rdbhost"
       }
     },
-    "name": "Global generators.ensure_installed",
+    "name": "Global generators.install xcode.ensure_installed",
     "~followup_annotations": [
-      "@@@STEP_NEST_LEVEL@1@@@",
+      "@@@STEP_NEST_LEVEL@2@@@",
       "@@@STEP_LOG_LINE@json.output@{@@@",
       "@@@STEP_LOG_LINE@json.output@  \"result\": {@@@",
       "@@@STEP_LOG_LINE@json.output@    \"\": [@@@",
@@ -711,9 +739,10 @@
         "hostname": "rdbhost"
       }
     },
-    "name": "Global generators.install xcode",
+    "name": "Global generators.install xcode.install xcode from cipd",
+    "timeout": 1800,
     "~followup_annotations": [
-      "@@@STEP_NEST_LEVEL@1@@@"
+      "@@@STEP_NEST_LEVEL@2@@@"
     ]
   },
   {
@@ -760,7 +789,7 @@
         "hostname": "rdbhost"
       }
     },
-    "name": "Global generators.select XCode",
+    "name": "Global generators.select xcode",
     "~followup_annotations": [
       "@@@STEP_NEST_LEVEL@1@@@"
     ]
@@ -843,6 +872,13 @@
     ]
   },
   {
+    "cmd": [],
+    "name": "Global generators.install xcode (2)",
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@"
+    ]
+  },
+  {
     "cmd": [
       "cipd",
       "ensure",
@@ -868,9 +904,9 @@
         "hostname": "rdbhost"
       }
     },
-    "name": "Global generators.ensure_installed (2)",
+    "name": "Global generators.install xcode (2).ensure_installed",
     "~followup_annotations": [
-      "@@@STEP_NEST_LEVEL@1@@@",
+      "@@@STEP_NEST_LEVEL@2@@@",
       "@@@STEP_LOG_LINE@json.output@{@@@",
       "@@@STEP_LOG_LINE@json.output@  \"result\": {@@@",
       "@@@STEP_LOG_LINE@json.output@    \"\": [@@@",
@@ -912,9 +948,10 @@
         "hostname": "rdbhost"
       }
     },
-    "name": "Global generators.install xcode (2)",
+    "name": "Global generators.install xcode (2).install xcode from cipd",
+    "timeout": 1800,
     "~followup_annotations": [
-      "@@@STEP_NEST_LEVEL@1@@@"
+      "@@@STEP_NEST_LEVEL@2@@@"
     ]
   },
   {
@@ -961,7 +998,7 @@
         "hostname": "rdbhost"
       }
     },
-    "name": "Global generators.select XCode (2)",
+    "name": "Global generators.select xcode (2)",
     "~followup_annotations": [
       "@@@STEP_NEST_LEVEL@1@@@"
     ]
diff --git a/recipes/engine_v2/engine_v2.expected/basic_mac_dart_internal.json b/recipes/engine_v2/engine_v2.expected/basic_mac_dart_internal.json
index 10d56af..ebd4483 100644
--- a/recipes/engine_v2/engine_v2.expected/basic_mac_dart_internal.json
+++ b/recipes/engine_v2/engine_v2.expected/basic_mac_dart_internal.json
@@ -619,6 +619,27 @@
   },
   {
     "cmd": [
+      "sudo",
+      "xcode-select",
+      "--reset"
+    ],
+    "infra_step": true,
+    "luci_context": {
+      "realm": {
+        "name": "dart-internal:flutter"
+      },
+      "resultdb": {
+        "current_invocation": {
+          "name": "invocations/build:8945511751514863184",
+          "update_token": "token"
+        },
+        "hostname": "rdbhost"
+      }
+    },
+    "name": "reset XCode"
+  },
+  {
+    "cmd": [
       "vpython3",
       "-u",
       "RECIPE_MODULE[recipe_engine::file]/resources/fileutil.py",
@@ -695,6 +716,13 @@
     ]
   },
   {
+    "cmd": [],
+    "name": "Global generators.install xcode",
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@"
+    ]
+  },
+  {
     "cmd": [
       "cipd",
       "ensure",
@@ -720,9 +748,9 @@
         "hostname": "rdbhost"
       }
     },
-    "name": "Global generators.ensure_installed",
+    "name": "Global generators.install xcode.ensure_installed",
     "~followup_annotations": [
-      "@@@STEP_NEST_LEVEL@1@@@",
+      "@@@STEP_NEST_LEVEL@2@@@",
       "@@@STEP_LOG_LINE@json.output@{@@@",
       "@@@STEP_LOG_LINE@json.output@  \"result\": {@@@",
       "@@@STEP_LOG_LINE@json.output@    \"\": [@@@",
@@ -764,9 +792,10 @@
         "hostname": "rdbhost"
       }
     },
-    "name": "Global generators.install xcode",
+    "name": "Global generators.install xcode.install xcode from cipd",
+    "timeout": 1800,
     "~followup_annotations": [
-      "@@@STEP_NEST_LEVEL@1@@@"
+      "@@@STEP_NEST_LEVEL@2@@@"
     ]
   },
   {
@@ -813,7 +842,7 @@
         "hostname": "rdbhost"
       }
     },
-    "name": "Global generators.select XCode",
+    "name": "Global generators.select xcode",
     "~followup_annotations": [
       "@@@STEP_NEST_LEVEL@1@@@"
     ]
@@ -896,6 +925,13 @@
     ]
   },
   {
+    "cmd": [],
+    "name": "Global generators.install xcode (2)",
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@"
+    ]
+  },
+  {
     "cmd": [
       "cipd",
       "ensure",
@@ -921,9 +957,9 @@
         "hostname": "rdbhost"
       }
     },
-    "name": "Global generators.ensure_installed (2)",
+    "name": "Global generators.install xcode (2).ensure_installed",
     "~followup_annotations": [
-      "@@@STEP_NEST_LEVEL@1@@@",
+      "@@@STEP_NEST_LEVEL@2@@@",
       "@@@STEP_LOG_LINE@json.output@{@@@",
       "@@@STEP_LOG_LINE@json.output@  \"result\": {@@@",
       "@@@STEP_LOG_LINE@json.output@    \"\": [@@@",
@@ -965,9 +1001,10 @@
         "hostname": "rdbhost"
       }
     },
-    "name": "Global generators.install xcode (2)",
+    "name": "Global generators.install xcode (2).install xcode from cipd",
+    "timeout": 1800,
     "~followup_annotations": [
-      "@@@STEP_NEST_LEVEL@1@@@"
+      "@@@STEP_NEST_LEVEL@2@@@"
     ]
   },
   {
@@ -1014,7 +1051,7 @@
         "hostname": "rdbhost"
       }
     },
-    "name": "Global generators.select XCode (2)",
+    "name": "Global generators.select xcode (2)",
     "~followup_annotations": [
       "@@@STEP_NEST_LEVEL@1@@@"
     ]
diff --git a/recipes/engine_v2/engine_v2.expected/codesign_release_branch.json b/recipes/engine_v2/engine_v2.expected/codesign_release_branch.json
index 85f23c9..fba5b6e 100644
--- a/recipes/engine_v2/engine_v2.expected/codesign_release_branch.json
+++ b/recipes/engine_v2/engine_v2.expected/codesign_release_branch.json
@@ -1064,6 +1064,27 @@
   },
   {
     "cmd": [
+      "sudo",
+      "xcode-select",
+      "--reset"
+    ],
+    "infra_step": true,
+    "luci_context": {
+      "realm": {
+        "name": "proj:try"
+      },
+      "resultdb": {
+        "current_invocation": {
+          "name": "invocations/build:8945511751514863184",
+          "update_token": "token"
+        },
+        "hostname": "rdbhost"
+      }
+    },
+    "name": "reset XCode"
+  },
+  {
+    "cmd": [
       "vpython3",
       "-u",
       "RECIPE_MODULE[recipe_engine::file]/resources/fileutil.py",
@@ -1116,6 +1137,13 @@
     ]
   },
   {
+    "cmd": [],
+    "name": "Global generators.install xcode",
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@"
+    ]
+  },
+  {
     "cmd": [
       "cipd",
       "ensure",
@@ -1141,9 +1169,9 @@
         "hostname": "rdbhost"
       }
     },
-    "name": "Global generators.ensure_installed",
+    "name": "Global generators.install xcode.ensure_installed",
     "~followup_annotations": [
-      "@@@STEP_NEST_LEVEL@1@@@",
+      "@@@STEP_NEST_LEVEL@2@@@",
       "@@@STEP_LOG_LINE@json.output@{@@@",
       "@@@STEP_LOG_LINE@json.output@  \"result\": {@@@",
       "@@@STEP_LOG_LINE@json.output@    \"\": [@@@",
@@ -1185,9 +1213,10 @@
         "hostname": "rdbhost"
       }
     },
-    "name": "Global generators.install xcode",
+    "name": "Global generators.install xcode.install xcode from cipd",
+    "timeout": 1800,
     "~followup_annotations": [
-      "@@@STEP_NEST_LEVEL@1@@@"
+      "@@@STEP_NEST_LEVEL@2@@@"
     ]
   },
   {
@@ -1234,7 +1263,7 @@
         "hostname": "rdbhost"
       }
     },
-    "name": "Global generators.select XCode",
+    "name": "Global generators.select xcode",
     "~followup_annotations": [
       "@@@STEP_NEST_LEVEL@1@@@"
     ]
@@ -1317,6 +1346,13 @@
     ]
   },
   {
+    "cmd": [],
+    "name": "Global generators.install xcode (2)",
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@"
+    ]
+  },
+  {
     "cmd": [
       "cipd",
       "ensure",
@@ -1342,9 +1378,9 @@
         "hostname": "rdbhost"
       }
     },
-    "name": "Global generators.ensure_installed (2)",
+    "name": "Global generators.install xcode (2).ensure_installed",
     "~followup_annotations": [
-      "@@@STEP_NEST_LEVEL@1@@@",
+      "@@@STEP_NEST_LEVEL@2@@@",
       "@@@STEP_LOG_LINE@json.output@{@@@",
       "@@@STEP_LOG_LINE@json.output@  \"result\": {@@@",
       "@@@STEP_LOG_LINE@json.output@    \"\": [@@@",
@@ -1386,9 +1422,10 @@
         "hostname": "rdbhost"
       }
     },
-    "name": "Global generators.install xcode (2)",
+    "name": "Global generators.install xcode (2).install xcode from cipd",
+    "timeout": 1800,
     "~followup_annotations": [
-      "@@@STEP_NEST_LEVEL@1@@@"
+      "@@@STEP_NEST_LEVEL@2@@@"
     ]
   },
   {
@@ -1435,7 +1472,7 @@
         "hostname": "rdbhost"
       }
     },
-    "name": "Global generators.select XCode (2)",
+    "name": "Global generators.select xcode (2)",
     "~followup_annotations": [
       "@@@STEP_NEST_LEVEL@1@@@"
     ]
diff --git a/recipes/engine_v2/engine_v2.py b/recipes/engine_v2/engine_v2.py
index fcd14e1..321e94f 100644
--- a/recipes/engine_v2/engine_v2.py
+++ b/recipes/engine_v2/engine_v2.py
@@ -134,6 +134,9 @@
       )
 
   if generators:
+    # If on macOS, reset Xcode in case a previous build failed to do so.
+    api.osx_sdk.reset_xcode()
+
     # Download sub-builds
     out_builds_path = full_engine_checkout.join('src', 'out')
     api.file.rmtree('Clobber build download folder', out_builds_path)
diff --git a/recipes/flutter/flutter.py b/recipes/flutter/flutter.py
index 07b46c6..073f901 100644
--- a/recipes/flutter/flutter.py
+++ b/recipes/flutter/flutter.py
@@ -17,6 +17,7 @@
     'flutter/flutter_bcid',
     'flutter/flutter_deps',
     'flutter/os_utils',
+    'flutter/osx_sdk',
     'flutter/repo_util',
     'recipe_engine/context',
     'recipe_engine/defer',
@@ -31,6 +32,10 @@
   api.flutter_bcid.report_stage(BcidStage.START.value)
   # Collect memory/cpu/process before task execution.
   api.os_utils.collect_os_info()
+
+  # If on macOS, reset Xcode in case a previous build failed to do so.
+  api.osx_sdk.reset_xcode()
+
   api.os_utils.print_pub_certs()
 
   # Trigger validation tests. This is to optimize resources usage
diff --git a/recipes/flutter/flutter_drone.py b/recipes/flutter/flutter_drone.py
index 19da867..3b793dc 100644
--- a/recipes/flutter/flutter_drone.py
+++ b/recipes/flutter/flutter_drone.py
@@ -67,6 +67,10 @@
   api.flutter_bcid.report_stage(BcidStage.START.value)
   # Collect memory/cpu/process before task execution.
   api.os_utils.collect_os_info()
+
+  # If on macOS, reset Xcode in case a previous build failed to do so.
+  api.osx_sdk.reset_xcode()
+
   api.os_utils.print_pub_certs()
 
   checkout_path = api.path['start_dir'].join('flutter')
diff --git a/recipes/ios_usb_dependencies/ios-usb-dependencies.py b/recipes/ios_usb_dependencies/ios-usb-dependencies.py
index d65d32f..0759ddd 100644
--- a/recipes/ios_usb_dependencies/ios-usb-dependencies.py
+++ b/recipes/ios_usb_dependencies/ios-usb-dependencies.py
@@ -125,13 +125,13 @@
 def GetDylibFilenames(api, dir, package_name):
   """Returns a list of file names that matches dylib file regex in given directory.
 
-  A package_name maps to a regex pattern based on DIRNAME_PATTERN_DICT(dict). All 
+  A package_name maps to a regex pattern based on DIRNAME_PATTERN_DICT(dict). All
   file names in the current dir that matches this regex pattern are returned.
 
   Args:
 
       dir(Path): The directory in which to search for dylib files.
-      package_name(str): Name of the ios usb dependency passed in. 
+      package_name(str): Name of the ios usb dependency passed in.
   """
   directory_paths = api.file.listdir(
       "checking dylib file inside: %s" % dir,
@@ -163,7 +163,7 @@
   Args:
 
       package_out_dir(Path): The directory in which ios usb dependency artifact is generated.
-      package_name(str): Name of the ios usb dependency passed in. 
+      package_name(str): Name of the ios usb dependency passed in.
   """
   entitlement_file_contents = []
   without_entitlement_file_contents = []
@@ -295,6 +295,9 @@
 
 
 def RunSteps(api):
+  # If on macOS, reset Xcode in case a previous build failed to do so.
+  api.osx_sdk.reset_xcode()
+
   with api.osx_sdk('ios', devicelab=True):
     env_prefixes = {'PATH': [], 'LIBRARY_PATH': []}
     env = {}
diff --git a/recipes/packages/packages.py b/recipes/packages/packages.py
index 875d48d..33b9d4f 100644
--- a/recipes/packages/packages.py
+++ b/recipes/packages/packages.py
@@ -28,6 +28,9 @@
   # Collect memory/cpu/process before task execution.
   api.os_utils.collect_os_info()
 
+  # If on macOS, reset Xcode in case a previous build failed to do so.
+  api.osx_sdk.reset_xcode()
+
   packages_checkout_path = api.path['start_dir'].join('packages')
   flutter_checkout_path = api.path['start_dir'].join('flutter')
   channel = api.properties.get('channel')