Use hermetic ruby for jazzy gem install

Change-Id: I2c3c1dbc37f67b64c695071cc9ec61c82f4e57d9
Reviewed-on: https://flutter-review.googlesource.com/c/recipes/+/38093
Reviewed-by: Godofredo Contreras <godofredoc@google.com>
Commit-Queue: Nehal Patel <nehalvpatel@google.com>
diff --git a/recipe_modules/flutter_deps/api.py b/recipe_modules/flutter_deps/api.py
index 023cb06..0f3edbe 100644
--- a/recipe_modules/flutter_deps/api.py
+++ b/recipe_modules/flutter_deps/api.py
@@ -583,27 +583,19 @@
       env_prefixes(dict):  Current environment prefixes variables.
       gemfile_dir(Path): The path to the location of the repository gemfile.
     """
+    # TODO: Use bundler to install jazzy
+    # https://github.com/flutter/flutter/issues/118486
     version = version or '0.9.5'
     gem_dir = self.m.path['start_dir'].join('gems')
     with self.m.step.nest('Install jazzy'):
+      # TODO: Don't hardcode the version here.
+      self._install_ruby(env, env_prefixes, 'v3.3.14')
       self.m.file.ensure_directory('mkdir gems', gem_dir)
       with self.m.context(cwd=gem_dir):
-        # jazzy depends on sqlite3, which started serving precompiled gems with version 1.5.0.
-        # The instance of Ruby currently packaged with macOS installs precompiled gems incorrectly.
-        # Specifically, if a gem vends precompiled binaries, it installs the arm64 variant even on x86 machines.
-        # https://github.com/flutter/flutter/issues/111193#issuecomment-1248714857
-        # https://github.com/sparklemotion/nokogiri/issues/2165#issuecomment-754101252
-        # https://rubygems.org/gems/sqlite3/versions
-
-        platform_id = ('x86_64-darwin'
-          if self.m.platform.arch == 'intel'
-          else 'arm64-darwin')
-
         self.m.step(
             'install jazzy', [
                 'gem', 'install', 'jazzy:%s' % version,
-                '--platform', platform_id,
-                '--install-dir', '.'
+            '--install-dir', '.'
             ]
         )
       env['GEM_HOME'] = gem_dir
diff --git a/recipe_modules/flutter_deps/examples/full.expected/basic.json b/recipe_modules/flutter_deps/examples/full.expected/basic.json
index fd5dfcd..f8824e2 100644
--- a/recipe_modules/flutter_deps/examples/full.expected/basic.json
+++ b/recipe_modules/flutter_deps/examples/full.expected/basic.json
@@ -664,6 +664,42 @@
     "name": "Install jazzy"
   },
   {
+    "cmd": [],
+    "name": "Install jazzy.Install ruby",
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@"
+    ]
+  },
+  {
+    "cmd": [
+      "cipd",
+      "ensure",
+      "-root",
+      "[CACHE]/ruby",
+      "-ensure-file",
+      "flutter/ruby/${platform} v3.3.14",
+      "-max-threads",
+      "0",
+      "-json-output",
+      "/path/to/tmp/json"
+    ],
+    "name": "Install jazzy.Install ruby.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-v3.3.14---------\", @@@",
+      "@@@STEP_LOG_LINE@json.output@        \"package\": \"flutter/ruby/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": [
       "vpython3",
       "-u",
@@ -686,8 +722,6 @@
       "gem",
       "install",
       "jazzy:0.9.5",
-      "--platform",
-      "x86_64-darwin",
       "--install-dir",
       "."
     ],
@@ -746,10 +780,12 @@
       "GEM_HOME": "[START_DIR]/gems",
       "GOPATH": "[CLEANUP]/go_path",
       "GRADLE_OPTS": "-Dorg.gradle.daemon=false",
-      "GRADLE_USER_HOME": "[CACHE]/gradle"
+      "GRADLE_USER_HOME": "[CACHE]/gradle",
+      "RUBY_HOME": "[CACHE]/ruby/bin"
     },
     "env_prefixes": {
       "PATH": [
+        "[CACHE]/ruby/bin",
         "[CACHE]/dart_sdk",
         "[CACHE]/chrome/chrome",
         "[CACHE]/chrome/drivers",
diff --git a/recipe_modules/flutter_deps/examples/full.expected/flutter_engine.json b/recipe_modules/flutter_deps/examples/full.expected/flutter_engine.json
index 394e273..c11db33 100644
--- a/recipe_modules/flutter_deps/examples/full.expected/flutter_engine.json
+++ b/recipe_modules/flutter_deps/examples/full.expected/flutter_engine.json
@@ -748,6 +748,42 @@
     "name": "Install jazzy"
   },
   {
+    "cmd": [],
+    "name": "Install jazzy.Install ruby",
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@"
+    ]
+  },
+  {
+    "cmd": [
+      "cipd",
+      "ensure",
+      "-root",
+      "[CACHE]/ruby",
+      "-ensure-file",
+      "flutter/ruby/${platform} v3.3.14",
+      "-max-threads",
+      "0",
+      "-json-output",
+      "/path/to/tmp/json"
+    ],
+    "name": "Install jazzy.Install ruby.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-v3.3.14---------\", @@@",
+      "@@@STEP_LOG_LINE@json.output@        \"package\": \"flutter/ruby/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": [
       "vpython3",
       "-u",
@@ -770,8 +806,6 @@
       "gem",
       "install",
       "jazzy:0.9.5",
-      "--platform",
-      "x86_64-darwin",
       "--install-dir",
       "."
     ],
@@ -831,10 +865,12 @@
       "GOPATH": "[CLEANUP]/go_path",
       "GRADLE_OPTS": "-Dorg.gradle.daemon=false",
       "GRADLE_USER_HOME": "[CACHE]/gradle",
-      "LOCAL_ENGINE": "[CLEANUP]/builder/src/out/host_debug_unopt"
+      "LOCAL_ENGINE": "[CLEANUP]/builder/src/out/host_debug_unopt",
+      "RUBY_HOME": "[CACHE]/ruby/bin"
     },
     "env_prefixes": {
       "PATH": [
+        "[CACHE]/ruby/bin",
         "[CACHE]/dart_sdk",
         "[CLEANUP]/builder/src/out/host_debug_unopt/dart-sdk/bin",
         "[CACHE]/chrome/chrome",
diff --git a/recipe_modules/flutter_deps/examples/full.expected/goldTryjob.json b/recipe_modules/flutter_deps/examples/full.expected/goldTryjob.json
index fd5dfcd..f8824e2 100644
--- a/recipe_modules/flutter_deps/examples/full.expected/goldTryjob.json
+++ b/recipe_modules/flutter_deps/examples/full.expected/goldTryjob.json
@@ -664,6 +664,42 @@
     "name": "Install jazzy"
   },
   {
+    "cmd": [],
+    "name": "Install jazzy.Install ruby",
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@"
+    ]
+  },
+  {
+    "cmd": [
+      "cipd",
+      "ensure",
+      "-root",
+      "[CACHE]/ruby",
+      "-ensure-file",
+      "flutter/ruby/${platform} v3.3.14",
+      "-max-threads",
+      "0",
+      "-json-output",
+      "/path/to/tmp/json"
+    ],
+    "name": "Install jazzy.Install ruby.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-v3.3.14---------\", @@@",
+      "@@@STEP_LOG_LINE@json.output@        \"package\": \"flutter/ruby/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": [
       "vpython3",
       "-u",
@@ -686,8 +722,6 @@
       "gem",
       "install",
       "jazzy:0.9.5",
-      "--platform",
-      "x86_64-darwin",
       "--install-dir",
       "."
     ],
@@ -746,10 +780,12 @@
       "GEM_HOME": "[START_DIR]/gems",
       "GOPATH": "[CLEANUP]/go_path",
       "GRADLE_OPTS": "-Dorg.gradle.daemon=false",
-      "GRADLE_USER_HOME": "[CACHE]/gradle"
+      "GRADLE_USER_HOME": "[CACHE]/gradle",
+      "RUBY_HOME": "[CACHE]/ruby/bin"
     },
     "env_prefixes": {
       "PATH": [
+        "[CACHE]/ruby/bin",
         "[CACHE]/dart_sdk",
         "[CACHE]/chrome/chrome",
         "[CACHE]/chrome/drivers",
diff --git a/recipe_modules/flutter_deps/examples/full.expected/linux.json b/recipe_modules/flutter_deps/examples/full.expected/linux.json
index fd5dfcd..f8824e2 100644
--- a/recipe_modules/flutter_deps/examples/full.expected/linux.json
+++ b/recipe_modules/flutter_deps/examples/full.expected/linux.json
@@ -664,6 +664,42 @@
     "name": "Install jazzy"
   },
   {
+    "cmd": [],
+    "name": "Install jazzy.Install ruby",
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@"
+    ]
+  },
+  {
+    "cmd": [
+      "cipd",
+      "ensure",
+      "-root",
+      "[CACHE]/ruby",
+      "-ensure-file",
+      "flutter/ruby/${platform} v3.3.14",
+      "-max-threads",
+      "0",
+      "-json-output",
+      "/path/to/tmp/json"
+    ],
+    "name": "Install jazzy.Install ruby.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-v3.3.14---------\", @@@",
+      "@@@STEP_LOG_LINE@json.output@        \"package\": \"flutter/ruby/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": [
       "vpython3",
       "-u",
@@ -686,8 +722,6 @@
       "gem",
       "install",
       "jazzy:0.9.5",
-      "--platform",
-      "x86_64-darwin",
       "--install-dir",
       "."
     ],
@@ -746,10 +780,12 @@
       "GEM_HOME": "[START_DIR]/gems",
       "GOPATH": "[CLEANUP]/go_path",
       "GRADLE_OPTS": "-Dorg.gradle.daemon=false",
-      "GRADLE_USER_HOME": "[CACHE]/gradle"
+      "GRADLE_USER_HOME": "[CACHE]/gradle",
+      "RUBY_HOME": "[CACHE]/ruby/bin"
     },
     "env_prefixes": {
       "PATH": [
+        "[CACHE]/ruby/bin",
         "[CACHE]/dart_sdk",
         "[CACHE]/chrome/chrome",
         "[CACHE]/chrome/drivers",
diff --git a/recipe_modules/flutter_deps/examples/full.expected/local_engine_cas.json b/recipe_modules/flutter_deps/examples/full.expected/local_engine_cas.json
index c21da3c..4ceed5f 100644
--- a/recipe_modules/flutter_deps/examples/full.expected/local_engine_cas.json
+++ b/recipe_modules/flutter_deps/examples/full.expected/local_engine_cas.json
@@ -748,6 +748,42 @@
     "name": "Install jazzy"
   },
   {
+    "cmd": [],
+    "name": "Install jazzy.Install ruby",
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@"
+    ]
+  },
+  {
+    "cmd": [
+      "cipd",
+      "ensure",
+      "-root",
+      "[CACHE]/ruby",
+      "-ensure-file",
+      "flutter/ruby/${platform} v3.3.14",
+      "-max-threads",
+      "0",
+      "-json-output",
+      "/path/to/tmp/json"
+    ],
+    "name": "Install jazzy.Install ruby.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-v3.3.14---------\", @@@",
+      "@@@STEP_LOG_LINE@json.output@        \"package\": \"flutter/ruby/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": [
       "vpython3",
       "-u",
@@ -770,8 +806,6 @@
       "gem",
       "install",
       "jazzy:0.9.5",
-      "--platform",
-      "x86_64-darwin",
       "--install-dir",
       "."
     ],
@@ -831,10 +865,12 @@
       "GOPATH": "[CLEANUP]/go_path",
       "GRADLE_OPTS": "-Dorg.gradle.daemon=false",
       "GRADLE_USER_HOME": "[CACHE]/gradle",
-      "LOCAL_ENGINE": "[CLEANUP]/builder/src/out/host-release"
+      "LOCAL_ENGINE": "[CLEANUP]/builder/src/out/host-release",
+      "RUBY_HOME": "[CACHE]/ruby/bin"
     },
     "env_prefixes": {
       "PATH": [
+        "[CACHE]/ruby/bin",
         "[CACHE]/dart_sdk",
         "[CLEANUP]/builder/src/out/host-release/dart-sdk/bin",
         "[CACHE]/chrome/chrome",
diff --git a/recipe_modules/flutter_deps/examples/full.expected/mac.json b/recipe_modules/flutter_deps/examples/full.expected/mac.json
index 61a1746..32eb2d7 100644
--- a/recipe_modules/flutter_deps/examples/full.expected/mac.json
+++ b/recipe_modules/flutter_deps/examples/full.expected/mac.json
@@ -679,6 +679,42 @@
     "name": "Install jazzy"
   },
   {
+    "cmd": [],
+    "name": "Install jazzy.Install ruby",
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@"
+    ]
+  },
+  {
+    "cmd": [
+      "cipd",
+      "ensure",
+      "-root",
+      "[CACHE]/ruby",
+      "-ensure-file",
+      "flutter/ruby/${platform} v3.3.14",
+      "-max-threads",
+      "0",
+      "-json-output",
+      "/path/to/tmp/json"
+    ],
+    "name": "Install jazzy.Install ruby.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-v3.3.14---------\", @@@",
+      "@@@STEP_LOG_LINE@json.output@        \"package\": \"flutter/ruby/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": [
       "vpython3",
       "-u",
@@ -701,8 +737,6 @@
       "gem",
       "install",
       "jazzy:0.9.5",
-      "--platform",
-      "x86_64-darwin",
       "--install-dir",
       "."
     ],
diff --git a/recipe_modules/flutter_deps/examples/full.expected/windows.json b/recipe_modules/flutter_deps/examples/full.expected/windows.json
index 5fc963f..20b3c26 100644
--- a/recipe_modules/flutter_deps/examples/full.expected/windows.json
+++ b/recipe_modules/flutter_deps/examples/full.expected/windows.json
@@ -815,6 +815,42 @@
     "name": "Install jazzy"
   },
   {
+    "cmd": [],
+    "name": "Install jazzy.Install ruby",
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@"
+    ]
+  },
+  {
+    "cmd": [
+      "cipd.bat",
+      "ensure",
+      "-root",
+      "[CACHE]\\ruby",
+      "-ensure-file",
+      "flutter/ruby/${platform} v3.3.14",
+      "-max-threads",
+      "0",
+      "-json-output",
+      "/path/to/tmp/json"
+    ],
+    "name": "Install jazzy.Install ruby.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-v3.3.14---------\", @@@",
+      "@@@STEP_LOG_LINE@json.output@        \"package\": \"flutter/ruby/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": [
       "vpython3",
       "-u",
@@ -837,8 +873,6 @@
       "gem",
       "install",
       "jazzy:0.9.5",
-      "--platform",
-      "x86_64-darwin",
       "--install-dir",
       "."
     ],
diff --git a/recipe_modules/flutter_deps/examples/full.expected/with-arm64ruby.json b/recipe_modules/flutter_deps/examples/full.expected/with-arm64ruby.json
index b925859..cc5717f 100644
--- a/recipe_modules/flutter_deps/examples/full.expected/with-arm64ruby.json
+++ b/recipe_modules/flutter_deps/examples/full.expected/with-arm64ruby.json
@@ -664,6 +664,42 @@
     "name": "Install jazzy"
   },
   {
+    "cmd": [],
+    "name": "Install jazzy.Install ruby",
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@"
+    ]
+  },
+  {
+    "cmd": [
+      "cipd",
+      "ensure",
+      "-root",
+      "[CACHE]/ruby",
+      "-ensure-file",
+      "flutter/ruby/${platform} v3.3.14",
+      "-max-threads",
+      "0",
+      "-json-output",
+      "/path/to/tmp/json"
+    ],
+    "name": "Install jazzy.Install ruby.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-v3.3.14---------\", @@@",
+      "@@@STEP_LOG_LINE@json.output@        \"package\": \"flutter/ruby/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": [
       "vpython3",
       "-u",
@@ -686,8 +722,6 @@
       "gem",
       "install",
       "jazzy:0.9.5",
-      "--platform",
-      "arm64-darwin",
       "--install-dir",
       "."
     ],
@@ -746,10 +780,12 @@
       "GEM_HOME": "[START_DIR]/gems",
       "GOPATH": "[CLEANUP]/go_path",
       "GRADLE_OPTS": "-Dorg.gradle.daemon=false",
-      "GRADLE_USER_HOME": "[CACHE]/gradle"
+      "GRADLE_USER_HOME": "[CACHE]/gradle",
+      "RUBY_HOME": "[CACHE]/ruby/bin"
     },
     "env_prefixes": {
       "PATH": [
+        "[CACHE]/ruby/bin",
         "[CACHE]/dart_sdk",
         "[CACHE]/chrome/chrome",
         "[CACHE]/chrome/drivers",
diff --git a/recipe_modules/flutter_deps/examples/full.expected/with-gems.json b/recipe_modules/flutter_deps/examples/full.expected/with-gems.json
index 8c23b12..362c1b2 100644
--- a/recipe_modules/flutter_deps/examples/full.expected/with-gems.json
+++ b/recipe_modules/flutter_deps/examples/full.expected/with-gems.json
@@ -664,6 +664,42 @@
     "name": "Install jazzy"
   },
   {
+    "cmd": [],
+    "name": "Install jazzy.Install ruby",
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@"
+    ]
+  },
+  {
+    "cmd": [
+      "cipd",
+      "ensure",
+      "-root",
+      "[CACHE]/ruby",
+      "-ensure-file",
+      "flutter/ruby/${platform} v3.3.14",
+      "-max-threads",
+      "0",
+      "-json-output",
+      "/path/to/tmp/json"
+    ],
+    "name": "Install jazzy.Install ruby.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-v3.3.14---------\", @@@",
+      "@@@STEP_LOG_LINE@json.output@        \"package\": \"flutter/ruby/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": [
       "vpython3",
       "-u",
@@ -686,8 +722,6 @@
       "gem",
       "install",
       "jazzy:0.9.5",
-      "--platform",
-      "x86_64-darwin",
       "--install-dir",
       "."
     ],
@@ -746,10 +780,12 @@
       "GEM_HOME": "[START_DIR]/gems",
       "GOPATH": "[CLEANUP]/go_path",
       "GRADLE_OPTS": "-Dorg.gradle.daemon=false",
-      "GRADLE_USER_HOME": "[CACHE]/gradle"
+      "GRADLE_USER_HOME": "[CACHE]/gradle",
+      "RUBY_HOME": "[CACHE]/ruby/bin"
     },
     "env_prefixes": {
       "PATH": [
+        "[CACHE]/ruby/bin",
         "[CACHE]/dart_sdk",
         "[CACHE]/chrome/chrome",
         "[CACHE]/chrome/drivers",
diff --git a/recipes/engine/engine.expected/mac.json b/recipes/engine/engine.expected/mac.json
index a253d65..f649bb5 100644
--- a/recipes/engine/engine.expected/mac.json
+++ b/recipes/engine/engine.expected/mac.json
@@ -11629,6 +11629,79 @@
     ]
   },
   {
+    "cmd": [],
+    "name": "Install jazzy"
+  },
+  {
+    "cmd": [],
+    "name": "Install jazzy.Install ruby",
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@"
+    ]
+  },
+  {
+    "cmd": [
+      "cipd",
+      "ensure",
+      "-root",
+      "[CACHE]/ruby",
+      "-ensure-file",
+      "flutter/ruby/${platform} v3.3.14",
+      "-max-threads",
+      "0",
+      "-json-output",
+      "/path/to/tmp/json"
+    ],
+    "cwd": "[CACHE]/builder",
+    "env": {
+      "ANDROID_HOME": "[CACHE]/builder/src/third_party/android_tools/sdk",
+      "FLUTTER_LOGS_DIR": "[CLEANUP]/flutter_logs_dir",
+      "FLUTTER_PREBUILT_DART_SDK": "True",
+      "FLUTTER_TEST_OUTPUTS_DIR": "[CLEANUP]/flutter_logs_dir",
+      "GOMA_DIR": "[CACHE]/goma/client"
+    },
+    "env_prefixes": {
+      "PATH": [
+        "[CACHE]/builder/src/third_party/dart/tools/sdks/dart-sdk/bin"
+      ]
+    },
+    "env_suffixes": {
+      "DEPOT_TOOLS_UPDATE": [
+        "0"
+      ],
+      "PATH": [
+        "RECIPE_REPO[depot_tools]"
+      ]
+    },
+    "luci_context": {
+      "realm": {
+        "name": "flutter:ci"
+      },
+      "resultdb": {
+        "current_invocation": {
+          "name": "invocations/build:8945511751514863184",
+          "update_token": "token"
+        },
+        "hostname": "rdbhost"
+      }
+    },
+    "name": "Install jazzy.Install ruby.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-v3.3.14---------\", @@@",
+      "@@@STEP_LOG_LINE@json.output@        \"package\": \"flutter/ruby/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": [
       "vpython3",
       "-u",
@@ -11674,15 +11747,16 @@
         "hostname": "rdbhost"
       }
     },
-    "name": "mkdir gems"
+    "name": "Install jazzy.mkdir gems",
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@"
+    ]
   },
   {
     "cmd": [
       "gem",
       "install",
-      "jazzy:0.8.4",
-      "--platform",
-      "x86_64-darwin",
+      "jazzy:0.9.5",
       "--install-dir",
       "."
     ],
@@ -11719,7 +11793,10 @@
         "hostname": "rdbhost"
       }
     },
-    "name": "install jazzy"
+    "name": "Install jazzy.install jazzy",
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@"
+    ]
   },
   {
     "cmd": [
diff --git a/recipes/engine/engine.expected/mac_font_subset.json b/recipes/engine/engine.expected/mac_font_subset.json
index a253d65..f649bb5 100644
--- a/recipes/engine/engine.expected/mac_font_subset.json
+++ b/recipes/engine/engine.expected/mac_font_subset.json
@@ -11629,6 +11629,79 @@
     ]
   },
   {
+    "cmd": [],
+    "name": "Install jazzy"
+  },
+  {
+    "cmd": [],
+    "name": "Install jazzy.Install ruby",
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@"
+    ]
+  },
+  {
+    "cmd": [
+      "cipd",
+      "ensure",
+      "-root",
+      "[CACHE]/ruby",
+      "-ensure-file",
+      "flutter/ruby/${platform} v3.3.14",
+      "-max-threads",
+      "0",
+      "-json-output",
+      "/path/to/tmp/json"
+    ],
+    "cwd": "[CACHE]/builder",
+    "env": {
+      "ANDROID_HOME": "[CACHE]/builder/src/third_party/android_tools/sdk",
+      "FLUTTER_LOGS_DIR": "[CLEANUP]/flutter_logs_dir",
+      "FLUTTER_PREBUILT_DART_SDK": "True",
+      "FLUTTER_TEST_OUTPUTS_DIR": "[CLEANUP]/flutter_logs_dir",
+      "GOMA_DIR": "[CACHE]/goma/client"
+    },
+    "env_prefixes": {
+      "PATH": [
+        "[CACHE]/builder/src/third_party/dart/tools/sdks/dart-sdk/bin"
+      ]
+    },
+    "env_suffixes": {
+      "DEPOT_TOOLS_UPDATE": [
+        "0"
+      ],
+      "PATH": [
+        "RECIPE_REPO[depot_tools]"
+      ]
+    },
+    "luci_context": {
+      "realm": {
+        "name": "flutter:ci"
+      },
+      "resultdb": {
+        "current_invocation": {
+          "name": "invocations/build:8945511751514863184",
+          "update_token": "token"
+        },
+        "hostname": "rdbhost"
+      }
+    },
+    "name": "Install jazzy.Install ruby.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-v3.3.14---------\", @@@",
+      "@@@STEP_LOG_LINE@json.output@        \"package\": \"flutter/ruby/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": [
       "vpython3",
       "-u",
@@ -11674,15 +11747,16 @@
         "hostname": "rdbhost"
       }
     },
-    "name": "mkdir gems"
+    "name": "Install jazzy.mkdir gems",
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@"
+    ]
   },
   {
     "cmd": [
       "gem",
       "install",
-      "jazzy:0.8.4",
-      "--platform",
-      "x86_64-darwin",
+      "jazzy:0.9.5",
       "--install-dir",
       "."
     ],
@@ -11719,7 +11793,10 @@
         "hostname": "rdbhost"
       }
     },
-    "name": "install jazzy"
+    "name": "Install jazzy.install jazzy",
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@"
+    ]
   },
   {
     "cmd": [
diff --git a/recipes/engine/engine.expected/mac_no_lto.json b/recipes/engine/engine.expected/mac_no_lto.json
index 951028b..51195f8 100644
--- a/recipes/engine/engine.expected/mac_no_lto.json
+++ b/recipes/engine/engine.expected/mac_no_lto.json
@@ -11637,6 +11637,79 @@
     ]
   },
   {
+    "cmd": [],
+    "name": "Install jazzy"
+  },
+  {
+    "cmd": [],
+    "name": "Install jazzy.Install ruby",
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@"
+    ]
+  },
+  {
+    "cmd": [
+      "cipd",
+      "ensure",
+      "-root",
+      "[CACHE]/ruby",
+      "-ensure-file",
+      "flutter/ruby/${platform} v3.3.14",
+      "-max-threads",
+      "0",
+      "-json-output",
+      "/path/to/tmp/json"
+    ],
+    "cwd": "[CACHE]/builder",
+    "env": {
+      "ANDROID_HOME": "[CACHE]/builder/src/third_party/android_tools/sdk",
+      "FLUTTER_LOGS_DIR": "[CLEANUP]/flutter_logs_dir",
+      "FLUTTER_PREBUILT_DART_SDK": "True",
+      "FLUTTER_TEST_OUTPUTS_DIR": "[CLEANUP]/flutter_logs_dir",
+      "GOMA_DIR": "[CACHE]/goma/client"
+    },
+    "env_prefixes": {
+      "PATH": [
+        "[CACHE]/builder/src/third_party/dart/tools/sdks/dart-sdk/bin"
+      ]
+    },
+    "env_suffixes": {
+      "DEPOT_TOOLS_UPDATE": [
+        "0"
+      ],
+      "PATH": [
+        "RECIPE_REPO[depot_tools]"
+      ]
+    },
+    "luci_context": {
+      "realm": {
+        "name": "flutter:ci"
+      },
+      "resultdb": {
+        "current_invocation": {
+          "name": "invocations/build:8945511751514863184",
+          "update_token": "token"
+        },
+        "hostname": "rdbhost"
+      }
+    },
+    "name": "Install jazzy.Install ruby.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-v3.3.14---------\", @@@",
+      "@@@STEP_LOG_LINE@json.output@        \"package\": \"flutter/ruby/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": [
       "vpython3",
       "-u",
@@ -11682,15 +11755,16 @@
         "hostname": "rdbhost"
       }
     },
-    "name": "mkdir gems"
+    "name": "Install jazzy.mkdir gems",
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@"
+    ]
   },
   {
     "cmd": [
       "gem",
       "install",
-      "jazzy:0.8.4",
-      "--platform",
-      "x86_64-darwin",
+      "jazzy:0.9.5",
       "--install-dir",
       "."
     ],
@@ -11727,7 +11801,10 @@
         "hostname": "rdbhost"
       }
     },
-    "name": "install jazzy"
+    "name": "Install jazzy.install jazzy",
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@"
+    ]
   },
   {
     "cmd": [
diff --git a/recipes/engine/engine.expected/mac_no_lto_font_subset.json b/recipes/engine/engine.expected/mac_no_lto_font_subset.json
index 951028b..51195f8 100644
--- a/recipes/engine/engine.expected/mac_no_lto_font_subset.json
+++ b/recipes/engine/engine.expected/mac_no_lto_font_subset.json
@@ -11637,6 +11637,79 @@
     ]
   },
   {
+    "cmd": [],
+    "name": "Install jazzy"
+  },
+  {
+    "cmd": [],
+    "name": "Install jazzy.Install ruby",
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@"
+    ]
+  },
+  {
+    "cmd": [
+      "cipd",
+      "ensure",
+      "-root",
+      "[CACHE]/ruby",
+      "-ensure-file",
+      "flutter/ruby/${platform} v3.3.14",
+      "-max-threads",
+      "0",
+      "-json-output",
+      "/path/to/tmp/json"
+    ],
+    "cwd": "[CACHE]/builder",
+    "env": {
+      "ANDROID_HOME": "[CACHE]/builder/src/third_party/android_tools/sdk",
+      "FLUTTER_LOGS_DIR": "[CLEANUP]/flutter_logs_dir",
+      "FLUTTER_PREBUILT_DART_SDK": "True",
+      "FLUTTER_TEST_OUTPUTS_DIR": "[CLEANUP]/flutter_logs_dir",
+      "GOMA_DIR": "[CACHE]/goma/client"
+    },
+    "env_prefixes": {
+      "PATH": [
+        "[CACHE]/builder/src/third_party/dart/tools/sdks/dart-sdk/bin"
+      ]
+    },
+    "env_suffixes": {
+      "DEPOT_TOOLS_UPDATE": [
+        "0"
+      ],
+      "PATH": [
+        "RECIPE_REPO[depot_tools]"
+      ]
+    },
+    "luci_context": {
+      "realm": {
+        "name": "flutter:ci"
+      },
+      "resultdb": {
+        "current_invocation": {
+          "name": "invocations/build:8945511751514863184",
+          "update_token": "token"
+        },
+        "hostname": "rdbhost"
+      }
+    },
+    "name": "Install jazzy.Install ruby.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-v3.3.14---------\", @@@",
+      "@@@STEP_LOG_LINE@json.output@        \"package\": \"flutter/ruby/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": [
       "vpython3",
       "-u",
@@ -11682,15 +11755,16 @@
         "hostname": "rdbhost"
       }
     },
-    "name": "mkdir gems"
+    "name": "Install jazzy.mkdir gems",
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@"
+    ]
   },
   {
     "cmd": [
       "gem",
       "install",
-      "jazzy:0.8.4",
-      "--platform",
-      "x86_64-darwin",
+      "jazzy:0.9.5",
       "--install-dir",
       "."
     ],
@@ -11727,7 +11801,10 @@
         "hostname": "rdbhost"
       }
     },
-    "name": "install jazzy"
+    "name": "Install jazzy.install jazzy",
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@"
+    ]
   },
   {
     "cmd": [
diff --git a/recipes/engine/engine.expected/mac_publish_cipd.json b/recipes/engine/engine.expected/mac_publish_cipd.json
index a253d65..f649bb5 100644
--- a/recipes/engine/engine.expected/mac_publish_cipd.json
+++ b/recipes/engine/engine.expected/mac_publish_cipd.json
@@ -11629,6 +11629,79 @@
     ]
   },
   {
+    "cmd": [],
+    "name": "Install jazzy"
+  },
+  {
+    "cmd": [],
+    "name": "Install jazzy.Install ruby",
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@"
+    ]
+  },
+  {
+    "cmd": [
+      "cipd",
+      "ensure",
+      "-root",
+      "[CACHE]/ruby",
+      "-ensure-file",
+      "flutter/ruby/${platform} v3.3.14",
+      "-max-threads",
+      "0",
+      "-json-output",
+      "/path/to/tmp/json"
+    ],
+    "cwd": "[CACHE]/builder",
+    "env": {
+      "ANDROID_HOME": "[CACHE]/builder/src/third_party/android_tools/sdk",
+      "FLUTTER_LOGS_DIR": "[CLEANUP]/flutter_logs_dir",
+      "FLUTTER_PREBUILT_DART_SDK": "True",
+      "FLUTTER_TEST_OUTPUTS_DIR": "[CLEANUP]/flutter_logs_dir",
+      "GOMA_DIR": "[CACHE]/goma/client"
+    },
+    "env_prefixes": {
+      "PATH": [
+        "[CACHE]/builder/src/third_party/dart/tools/sdks/dart-sdk/bin"
+      ]
+    },
+    "env_suffixes": {
+      "DEPOT_TOOLS_UPDATE": [
+        "0"
+      ],
+      "PATH": [
+        "RECIPE_REPO[depot_tools]"
+      ]
+    },
+    "luci_context": {
+      "realm": {
+        "name": "flutter:ci"
+      },
+      "resultdb": {
+        "current_invocation": {
+          "name": "invocations/build:8945511751514863184",
+          "update_token": "token"
+        },
+        "hostname": "rdbhost"
+      }
+    },
+    "name": "Install jazzy.Install ruby.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-v3.3.14---------\", @@@",
+      "@@@STEP_LOG_LINE@json.output@        \"package\": \"flutter/ruby/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": [
       "vpython3",
       "-u",
@@ -11674,15 +11747,16 @@
         "hostname": "rdbhost"
       }
     },
-    "name": "mkdir gems"
+    "name": "Install jazzy.mkdir gems",
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@"
+    ]
   },
   {
     "cmd": [
       "gem",
       "install",
-      "jazzy:0.8.4",
-      "--platform",
-      "x86_64-darwin",
+      "jazzy:0.9.5",
       "--install-dir",
       "."
     ],
@@ -11719,7 +11793,10 @@
         "hostname": "rdbhost"
       }
     },
-    "name": "install jazzy"
+    "name": "Install jazzy.install jazzy",
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@"
+    ]
   },
   {
     "cmd": [
diff --git a/recipes/engine/engine.expected/mac_publish_cipd_font_subset.json b/recipes/engine/engine.expected/mac_publish_cipd_font_subset.json
index a253d65..f649bb5 100644
--- a/recipes/engine/engine.expected/mac_publish_cipd_font_subset.json
+++ b/recipes/engine/engine.expected/mac_publish_cipd_font_subset.json
@@ -11629,6 +11629,79 @@
     ]
   },
   {
+    "cmd": [],
+    "name": "Install jazzy"
+  },
+  {
+    "cmd": [],
+    "name": "Install jazzy.Install ruby",
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@"
+    ]
+  },
+  {
+    "cmd": [
+      "cipd",
+      "ensure",
+      "-root",
+      "[CACHE]/ruby",
+      "-ensure-file",
+      "flutter/ruby/${platform} v3.3.14",
+      "-max-threads",
+      "0",
+      "-json-output",
+      "/path/to/tmp/json"
+    ],
+    "cwd": "[CACHE]/builder",
+    "env": {
+      "ANDROID_HOME": "[CACHE]/builder/src/third_party/android_tools/sdk",
+      "FLUTTER_LOGS_DIR": "[CLEANUP]/flutter_logs_dir",
+      "FLUTTER_PREBUILT_DART_SDK": "True",
+      "FLUTTER_TEST_OUTPUTS_DIR": "[CLEANUP]/flutter_logs_dir",
+      "GOMA_DIR": "[CACHE]/goma/client"
+    },
+    "env_prefixes": {
+      "PATH": [
+        "[CACHE]/builder/src/third_party/dart/tools/sdks/dart-sdk/bin"
+      ]
+    },
+    "env_suffixes": {
+      "DEPOT_TOOLS_UPDATE": [
+        "0"
+      ],
+      "PATH": [
+        "RECIPE_REPO[depot_tools]"
+      ]
+    },
+    "luci_context": {
+      "realm": {
+        "name": "flutter:ci"
+      },
+      "resultdb": {
+        "current_invocation": {
+          "name": "invocations/build:8945511751514863184",
+          "update_token": "token"
+        },
+        "hostname": "rdbhost"
+      }
+    },
+    "name": "Install jazzy.Install ruby.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-v3.3.14---------\", @@@",
+      "@@@STEP_LOG_LINE@json.output@        \"package\": \"flutter/ruby/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": [
       "vpython3",
       "-u",
@@ -11674,15 +11747,16 @@
         "hostname": "rdbhost"
       }
     },
-    "name": "mkdir gems"
+    "name": "Install jazzy.mkdir gems",
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@"
+    ]
   },
   {
     "cmd": [
       "gem",
       "install",
-      "jazzy:0.8.4",
-      "--platform",
-      "x86_64-darwin",
+      "jazzy:0.9.5",
       "--install-dir",
       "."
     ],
@@ -11719,7 +11793,10 @@
         "hostname": "rdbhost"
       }
     },
-    "name": "install jazzy"
+    "name": "Install jazzy.install jazzy",
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@"
+    ]
   },
   {
     "cmd": [
diff --git a/recipes/engine/engine.expected/mac_publish_cipd_no_lto.json b/recipes/engine/engine.expected/mac_publish_cipd_no_lto.json
index 951028b..51195f8 100644
--- a/recipes/engine/engine.expected/mac_publish_cipd_no_lto.json
+++ b/recipes/engine/engine.expected/mac_publish_cipd_no_lto.json
@@ -11637,6 +11637,79 @@
     ]
   },
   {
+    "cmd": [],
+    "name": "Install jazzy"
+  },
+  {
+    "cmd": [],
+    "name": "Install jazzy.Install ruby",
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@"
+    ]
+  },
+  {
+    "cmd": [
+      "cipd",
+      "ensure",
+      "-root",
+      "[CACHE]/ruby",
+      "-ensure-file",
+      "flutter/ruby/${platform} v3.3.14",
+      "-max-threads",
+      "0",
+      "-json-output",
+      "/path/to/tmp/json"
+    ],
+    "cwd": "[CACHE]/builder",
+    "env": {
+      "ANDROID_HOME": "[CACHE]/builder/src/third_party/android_tools/sdk",
+      "FLUTTER_LOGS_DIR": "[CLEANUP]/flutter_logs_dir",
+      "FLUTTER_PREBUILT_DART_SDK": "True",
+      "FLUTTER_TEST_OUTPUTS_DIR": "[CLEANUP]/flutter_logs_dir",
+      "GOMA_DIR": "[CACHE]/goma/client"
+    },
+    "env_prefixes": {
+      "PATH": [
+        "[CACHE]/builder/src/third_party/dart/tools/sdks/dart-sdk/bin"
+      ]
+    },
+    "env_suffixes": {
+      "DEPOT_TOOLS_UPDATE": [
+        "0"
+      ],
+      "PATH": [
+        "RECIPE_REPO[depot_tools]"
+      ]
+    },
+    "luci_context": {
+      "realm": {
+        "name": "flutter:ci"
+      },
+      "resultdb": {
+        "current_invocation": {
+          "name": "invocations/build:8945511751514863184",
+          "update_token": "token"
+        },
+        "hostname": "rdbhost"
+      }
+    },
+    "name": "Install jazzy.Install ruby.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-v3.3.14---------\", @@@",
+      "@@@STEP_LOG_LINE@json.output@        \"package\": \"flutter/ruby/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": [
       "vpython3",
       "-u",
@@ -11682,15 +11755,16 @@
         "hostname": "rdbhost"
       }
     },
-    "name": "mkdir gems"
+    "name": "Install jazzy.mkdir gems",
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@"
+    ]
   },
   {
     "cmd": [
       "gem",
       "install",
-      "jazzy:0.8.4",
-      "--platform",
-      "x86_64-darwin",
+      "jazzy:0.9.5",
       "--install-dir",
       "."
     ],
@@ -11727,7 +11801,10 @@
         "hostname": "rdbhost"
       }
     },
-    "name": "install jazzy"
+    "name": "Install jazzy.install jazzy",
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@"
+    ]
   },
   {
     "cmd": [
diff --git a/recipes/engine/engine.expected/mac_publish_cipd_no_lto_font_subset.json b/recipes/engine/engine.expected/mac_publish_cipd_no_lto_font_subset.json
index 951028b..51195f8 100644
--- a/recipes/engine/engine.expected/mac_publish_cipd_no_lto_font_subset.json
+++ b/recipes/engine/engine.expected/mac_publish_cipd_no_lto_font_subset.json
@@ -11637,6 +11637,79 @@
     ]
   },
   {
+    "cmd": [],
+    "name": "Install jazzy"
+  },
+  {
+    "cmd": [],
+    "name": "Install jazzy.Install ruby",
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@"
+    ]
+  },
+  {
+    "cmd": [
+      "cipd",
+      "ensure",
+      "-root",
+      "[CACHE]/ruby",
+      "-ensure-file",
+      "flutter/ruby/${platform} v3.3.14",
+      "-max-threads",
+      "0",
+      "-json-output",
+      "/path/to/tmp/json"
+    ],
+    "cwd": "[CACHE]/builder",
+    "env": {
+      "ANDROID_HOME": "[CACHE]/builder/src/third_party/android_tools/sdk",
+      "FLUTTER_LOGS_DIR": "[CLEANUP]/flutter_logs_dir",
+      "FLUTTER_PREBUILT_DART_SDK": "True",
+      "FLUTTER_TEST_OUTPUTS_DIR": "[CLEANUP]/flutter_logs_dir",
+      "GOMA_DIR": "[CACHE]/goma/client"
+    },
+    "env_prefixes": {
+      "PATH": [
+        "[CACHE]/builder/src/third_party/dart/tools/sdks/dart-sdk/bin"
+      ]
+    },
+    "env_suffixes": {
+      "DEPOT_TOOLS_UPDATE": [
+        "0"
+      ],
+      "PATH": [
+        "RECIPE_REPO[depot_tools]"
+      ]
+    },
+    "luci_context": {
+      "realm": {
+        "name": "flutter:ci"
+      },
+      "resultdb": {
+        "current_invocation": {
+          "name": "invocations/build:8945511751514863184",
+          "update_token": "token"
+        },
+        "hostname": "rdbhost"
+      }
+    },
+    "name": "Install jazzy.Install ruby.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-v3.3.14---------\", @@@",
+      "@@@STEP_LOG_LINE@json.output@        \"package\": \"flutter/ruby/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": [
       "vpython3",
       "-u",
@@ -11682,15 +11755,16 @@
         "hostname": "rdbhost"
       }
     },
-    "name": "mkdir gems"
+    "name": "Install jazzy.mkdir gems",
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@"
+    ]
   },
   {
     "cmd": [
       "gem",
       "install",
-      "jazzy:0.8.4",
-      "--platform",
-      "x86_64-darwin",
+      "jazzy:0.9.5",
       "--install-dir",
       "."
     ],
@@ -11727,7 +11801,10 @@
         "hostname": "rdbhost"
       }
     },
-    "name": "install jazzy"
+    "name": "Install jazzy.install jazzy",
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@"
+    ]
   },
   {
     "cmd": [
diff --git a/recipes/engine/engine.expected/mac_upload.json b/recipes/engine/engine.expected/mac_upload.json
index 62ed9c7..d0f6678 100644
--- a/recipes/engine/engine.expected/mac_upload.json
+++ b/recipes/engine/engine.expected/mac_upload.json
@@ -12802,6 +12802,79 @@
     ]
   },
   {
+    "cmd": [],
+    "name": "Install jazzy"
+  },
+  {
+    "cmd": [],
+    "name": "Install jazzy.Install ruby",
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@"
+    ]
+  },
+  {
+    "cmd": [
+      "cipd",
+      "ensure",
+      "-root",
+      "[CACHE]/ruby",
+      "-ensure-file",
+      "flutter/ruby/${platform} v3.3.14",
+      "-max-threads",
+      "0",
+      "-json-output",
+      "/path/to/tmp/json"
+    ],
+    "cwd": "[CACHE]/builder",
+    "env": {
+      "ANDROID_HOME": "[CACHE]/builder/src/third_party/android_tools/sdk",
+      "FLUTTER_LOGS_DIR": "[CLEANUP]/flutter_logs_dir",
+      "FLUTTER_PREBUILT_DART_SDK": "True",
+      "FLUTTER_TEST_OUTPUTS_DIR": "[CLEANUP]/flutter_logs_dir",
+      "GOMA_DIR": "[CACHE]/goma/client"
+    },
+    "env_prefixes": {
+      "PATH": [
+        "[CACHE]/builder/src/third_party/dart/tools/sdks/dart-sdk/bin"
+      ]
+    },
+    "env_suffixes": {
+      "DEPOT_TOOLS_UPDATE": [
+        "0"
+      ],
+      "PATH": [
+        "RECIPE_REPO[depot_tools]"
+      ]
+    },
+    "luci_context": {
+      "realm": {
+        "name": "flutter:ci"
+      },
+      "resultdb": {
+        "current_invocation": {
+          "name": "invocations/build:8945511751514863184",
+          "update_token": "token"
+        },
+        "hostname": "rdbhost"
+      }
+    },
+    "name": "Install jazzy.Install ruby.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-v3.3.14---------\", @@@",
+      "@@@STEP_LOG_LINE@json.output@        \"package\": \"flutter/ruby/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": [
       "vpython3",
       "-u",
@@ -12847,15 +12920,16 @@
         "hostname": "rdbhost"
       }
     },
-    "name": "mkdir gems"
+    "name": "Install jazzy.mkdir gems",
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@"
+    ]
   },
   {
     "cmd": [
       "gem",
       "install",
-      "jazzy:0.8.4",
-      "--platform",
-      "x86_64-darwin",
+      "jazzy:0.9.5",
       "--install-dir",
       "."
     ],
@@ -12892,7 +12966,10 @@
         "hostname": "rdbhost"
       }
     },
-    "name": "install jazzy"
+    "name": "Install jazzy.install jazzy",
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@"
+    ]
   },
   {
     "cmd": [
diff --git a/recipes/engine/engine.expected/mac_upload_font_subset.json b/recipes/engine/engine.expected/mac_upload_font_subset.json
index 22575b3..e39d484 100644
--- a/recipes/engine/engine.expected/mac_upload_font_subset.json
+++ b/recipes/engine/engine.expected/mac_upload_font_subset.json
@@ -12904,6 +12904,79 @@
     ]
   },
   {
+    "cmd": [],
+    "name": "Install jazzy"
+  },
+  {
+    "cmd": [],
+    "name": "Install jazzy.Install ruby",
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@"
+    ]
+  },
+  {
+    "cmd": [
+      "cipd",
+      "ensure",
+      "-root",
+      "[CACHE]/ruby",
+      "-ensure-file",
+      "flutter/ruby/${platform} v3.3.14",
+      "-max-threads",
+      "0",
+      "-json-output",
+      "/path/to/tmp/json"
+    ],
+    "cwd": "[CACHE]/builder",
+    "env": {
+      "ANDROID_HOME": "[CACHE]/builder/src/third_party/android_tools/sdk",
+      "FLUTTER_LOGS_DIR": "[CLEANUP]/flutter_logs_dir",
+      "FLUTTER_PREBUILT_DART_SDK": "True",
+      "FLUTTER_TEST_OUTPUTS_DIR": "[CLEANUP]/flutter_logs_dir",
+      "GOMA_DIR": "[CACHE]/goma/client"
+    },
+    "env_prefixes": {
+      "PATH": [
+        "[CACHE]/builder/src/third_party/dart/tools/sdks/dart-sdk/bin"
+      ]
+    },
+    "env_suffixes": {
+      "DEPOT_TOOLS_UPDATE": [
+        "0"
+      ],
+      "PATH": [
+        "RECIPE_REPO[depot_tools]"
+      ]
+    },
+    "luci_context": {
+      "realm": {
+        "name": "flutter:ci"
+      },
+      "resultdb": {
+        "current_invocation": {
+          "name": "invocations/build:8945511751514863184",
+          "update_token": "token"
+        },
+        "hostname": "rdbhost"
+      }
+    },
+    "name": "Install jazzy.Install ruby.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-v3.3.14---------\", @@@",
+      "@@@STEP_LOG_LINE@json.output@        \"package\": \"flutter/ruby/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": [
       "vpython3",
       "-u",
@@ -12949,15 +13022,16 @@
         "hostname": "rdbhost"
       }
     },
-    "name": "mkdir gems"
+    "name": "Install jazzy.mkdir gems",
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@"
+    ]
   },
   {
     "cmd": [
       "gem",
       "install",
-      "jazzy:0.8.4",
-      "--platform",
-      "x86_64-darwin",
+      "jazzy:0.9.5",
       "--install-dir",
       "."
     ],
@@ -12994,7 +13068,10 @@
         "hostname": "rdbhost"
       }
     },
-    "name": "install jazzy"
+    "name": "Install jazzy.install jazzy",
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@"
+    ]
   },
   {
     "cmd": [
diff --git a/recipes/engine/engine.expected/mac_upload_no_lto.json b/recipes/engine/engine.expected/mac_upload_no_lto.json
index 0c23280..cb22051 100644
--- a/recipes/engine/engine.expected/mac_upload_no_lto.json
+++ b/recipes/engine/engine.expected/mac_upload_no_lto.json
@@ -12810,6 +12810,79 @@
     ]
   },
   {
+    "cmd": [],
+    "name": "Install jazzy"
+  },
+  {
+    "cmd": [],
+    "name": "Install jazzy.Install ruby",
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@"
+    ]
+  },
+  {
+    "cmd": [
+      "cipd",
+      "ensure",
+      "-root",
+      "[CACHE]/ruby",
+      "-ensure-file",
+      "flutter/ruby/${platform} v3.3.14",
+      "-max-threads",
+      "0",
+      "-json-output",
+      "/path/to/tmp/json"
+    ],
+    "cwd": "[CACHE]/builder",
+    "env": {
+      "ANDROID_HOME": "[CACHE]/builder/src/third_party/android_tools/sdk",
+      "FLUTTER_LOGS_DIR": "[CLEANUP]/flutter_logs_dir",
+      "FLUTTER_PREBUILT_DART_SDK": "True",
+      "FLUTTER_TEST_OUTPUTS_DIR": "[CLEANUP]/flutter_logs_dir",
+      "GOMA_DIR": "[CACHE]/goma/client"
+    },
+    "env_prefixes": {
+      "PATH": [
+        "[CACHE]/builder/src/third_party/dart/tools/sdks/dart-sdk/bin"
+      ]
+    },
+    "env_suffixes": {
+      "DEPOT_TOOLS_UPDATE": [
+        "0"
+      ],
+      "PATH": [
+        "RECIPE_REPO[depot_tools]"
+      ]
+    },
+    "luci_context": {
+      "realm": {
+        "name": "flutter:ci"
+      },
+      "resultdb": {
+        "current_invocation": {
+          "name": "invocations/build:8945511751514863184",
+          "update_token": "token"
+        },
+        "hostname": "rdbhost"
+      }
+    },
+    "name": "Install jazzy.Install ruby.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-v3.3.14---------\", @@@",
+      "@@@STEP_LOG_LINE@json.output@        \"package\": \"flutter/ruby/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": [
       "vpython3",
       "-u",
@@ -12855,15 +12928,16 @@
         "hostname": "rdbhost"
       }
     },
-    "name": "mkdir gems"
+    "name": "Install jazzy.mkdir gems",
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@"
+    ]
   },
   {
     "cmd": [
       "gem",
       "install",
-      "jazzy:0.8.4",
-      "--platform",
-      "x86_64-darwin",
+      "jazzy:0.9.5",
       "--install-dir",
       "."
     ],
@@ -12900,7 +12974,10 @@
         "hostname": "rdbhost"
       }
     },
-    "name": "install jazzy"
+    "name": "Install jazzy.install jazzy",
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@"
+    ]
   },
   {
     "cmd": [
diff --git a/recipes/engine/engine.expected/mac_upload_no_lto_font_subset.json b/recipes/engine/engine.expected/mac_upload_no_lto_font_subset.json
index da7073b..c2a2ae6 100644
--- a/recipes/engine/engine.expected/mac_upload_no_lto_font_subset.json
+++ b/recipes/engine/engine.expected/mac_upload_no_lto_font_subset.json
@@ -12912,6 +12912,79 @@
     ]
   },
   {
+    "cmd": [],
+    "name": "Install jazzy"
+  },
+  {
+    "cmd": [],
+    "name": "Install jazzy.Install ruby",
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@"
+    ]
+  },
+  {
+    "cmd": [
+      "cipd",
+      "ensure",
+      "-root",
+      "[CACHE]/ruby",
+      "-ensure-file",
+      "flutter/ruby/${platform} v3.3.14",
+      "-max-threads",
+      "0",
+      "-json-output",
+      "/path/to/tmp/json"
+    ],
+    "cwd": "[CACHE]/builder",
+    "env": {
+      "ANDROID_HOME": "[CACHE]/builder/src/third_party/android_tools/sdk",
+      "FLUTTER_LOGS_DIR": "[CLEANUP]/flutter_logs_dir",
+      "FLUTTER_PREBUILT_DART_SDK": "True",
+      "FLUTTER_TEST_OUTPUTS_DIR": "[CLEANUP]/flutter_logs_dir",
+      "GOMA_DIR": "[CACHE]/goma/client"
+    },
+    "env_prefixes": {
+      "PATH": [
+        "[CACHE]/builder/src/third_party/dart/tools/sdks/dart-sdk/bin"
+      ]
+    },
+    "env_suffixes": {
+      "DEPOT_TOOLS_UPDATE": [
+        "0"
+      ],
+      "PATH": [
+        "RECIPE_REPO[depot_tools]"
+      ]
+    },
+    "luci_context": {
+      "realm": {
+        "name": "flutter:ci"
+      },
+      "resultdb": {
+        "current_invocation": {
+          "name": "invocations/build:8945511751514863184",
+          "update_token": "token"
+        },
+        "hostname": "rdbhost"
+      }
+    },
+    "name": "Install jazzy.Install ruby.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-v3.3.14---------\", @@@",
+      "@@@STEP_LOG_LINE@json.output@        \"package\": \"flutter/ruby/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": [
       "vpython3",
       "-u",
@@ -12957,15 +13030,16 @@
         "hostname": "rdbhost"
       }
     },
-    "name": "mkdir gems"
+    "name": "Install jazzy.mkdir gems",
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@"
+    ]
   },
   {
     "cmd": [
       "gem",
       "install",
-      "jazzy:0.8.4",
-      "--platform",
-      "x86_64-darwin",
+      "jazzy:0.9.5",
       "--install-dir",
       "."
     ],
@@ -13002,7 +13076,10 @@
         "hostname": "rdbhost"
       }
     },
-    "name": "install jazzy"
+    "name": "Install jazzy.install jazzy",
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@"
+    ]
   },
   {
     "cmd": [
diff --git a/recipes/engine/engine.expected/mac_upload_publish_cipd.json b/recipes/engine/engine.expected/mac_upload_publish_cipd.json
index 62ed9c7..d0f6678 100644
--- a/recipes/engine/engine.expected/mac_upload_publish_cipd.json
+++ b/recipes/engine/engine.expected/mac_upload_publish_cipd.json
@@ -12802,6 +12802,79 @@
     ]
   },
   {
+    "cmd": [],
+    "name": "Install jazzy"
+  },
+  {
+    "cmd": [],
+    "name": "Install jazzy.Install ruby",
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@"
+    ]
+  },
+  {
+    "cmd": [
+      "cipd",
+      "ensure",
+      "-root",
+      "[CACHE]/ruby",
+      "-ensure-file",
+      "flutter/ruby/${platform} v3.3.14",
+      "-max-threads",
+      "0",
+      "-json-output",
+      "/path/to/tmp/json"
+    ],
+    "cwd": "[CACHE]/builder",
+    "env": {
+      "ANDROID_HOME": "[CACHE]/builder/src/third_party/android_tools/sdk",
+      "FLUTTER_LOGS_DIR": "[CLEANUP]/flutter_logs_dir",
+      "FLUTTER_PREBUILT_DART_SDK": "True",
+      "FLUTTER_TEST_OUTPUTS_DIR": "[CLEANUP]/flutter_logs_dir",
+      "GOMA_DIR": "[CACHE]/goma/client"
+    },
+    "env_prefixes": {
+      "PATH": [
+        "[CACHE]/builder/src/third_party/dart/tools/sdks/dart-sdk/bin"
+      ]
+    },
+    "env_suffixes": {
+      "DEPOT_TOOLS_UPDATE": [
+        "0"
+      ],
+      "PATH": [
+        "RECIPE_REPO[depot_tools]"
+      ]
+    },
+    "luci_context": {
+      "realm": {
+        "name": "flutter:ci"
+      },
+      "resultdb": {
+        "current_invocation": {
+          "name": "invocations/build:8945511751514863184",
+          "update_token": "token"
+        },
+        "hostname": "rdbhost"
+      }
+    },
+    "name": "Install jazzy.Install ruby.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-v3.3.14---------\", @@@",
+      "@@@STEP_LOG_LINE@json.output@        \"package\": \"flutter/ruby/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": [
       "vpython3",
       "-u",
@@ -12847,15 +12920,16 @@
         "hostname": "rdbhost"
       }
     },
-    "name": "mkdir gems"
+    "name": "Install jazzy.mkdir gems",
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@"
+    ]
   },
   {
     "cmd": [
       "gem",
       "install",
-      "jazzy:0.8.4",
-      "--platform",
-      "x86_64-darwin",
+      "jazzy:0.9.5",
       "--install-dir",
       "."
     ],
@@ -12892,7 +12966,10 @@
         "hostname": "rdbhost"
       }
     },
-    "name": "install jazzy"
+    "name": "Install jazzy.install jazzy",
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@"
+    ]
   },
   {
     "cmd": [
diff --git a/recipes/engine/engine.expected/mac_upload_publish_cipd_font_subset.json b/recipes/engine/engine.expected/mac_upload_publish_cipd_font_subset.json
index 22575b3..e39d484 100644
--- a/recipes/engine/engine.expected/mac_upload_publish_cipd_font_subset.json
+++ b/recipes/engine/engine.expected/mac_upload_publish_cipd_font_subset.json
@@ -12904,6 +12904,79 @@
     ]
   },
   {
+    "cmd": [],
+    "name": "Install jazzy"
+  },
+  {
+    "cmd": [],
+    "name": "Install jazzy.Install ruby",
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@"
+    ]
+  },
+  {
+    "cmd": [
+      "cipd",
+      "ensure",
+      "-root",
+      "[CACHE]/ruby",
+      "-ensure-file",
+      "flutter/ruby/${platform} v3.3.14",
+      "-max-threads",
+      "0",
+      "-json-output",
+      "/path/to/tmp/json"
+    ],
+    "cwd": "[CACHE]/builder",
+    "env": {
+      "ANDROID_HOME": "[CACHE]/builder/src/third_party/android_tools/sdk",
+      "FLUTTER_LOGS_DIR": "[CLEANUP]/flutter_logs_dir",
+      "FLUTTER_PREBUILT_DART_SDK": "True",
+      "FLUTTER_TEST_OUTPUTS_DIR": "[CLEANUP]/flutter_logs_dir",
+      "GOMA_DIR": "[CACHE]/goma/client"
+    },
+    "env_prefixes": {
+      "PATH": [
+        "[CACHE]/builder/src/third_party/dart/tools/sdks/dart-sdk/bin"
+      ]
+    },
+    "env_suffixes": {
+      "DEPOT_TOOLS_UPDATE": [
+        "0"
+      ],
+      "PATH": [
+        "RECIPE_REPO[depot_tools]"
+      ]
+    },
+    "luci_context": {
+      "realm": {
+        "name": "flutter:ci"
+      },
+      "resultdb": {
+        "current_invocation": {
+          "name": "invocations/build:8945511751514863184",
+          "update_token": "token"
+        },
+        "hostname": "rdbhost"
+      }
+    },
+    "name": "Install jazzy.Install ruby.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-v3.3.14---------\", @@@",
+      "@@@STEP_LOG_LINE@json.output@        \"package\": \"flutter/ruby/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": [
       "vpython3",
       "-u",
@@ -12949,15 +13022,16 @@
         "hostname": "rdbhost"
       }
     },
-    "name": "mkdir gems"
+    "name": "Install jazzy.mkdir gems",
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@"
+    ]
   },
   {
     "cmd": [
       "gem",
       "install",
-      "jazzy:0.8.4",
-      "--platform",
-      "x86_64-darwin",
+      "jazzy:0.9.5",
       "--install-dir",
       "."
     ],
@@ -12994,7 +13068,10 @@
         "hostname": "rdbhost"
       }
     },
-    "name": "install jazzy"
+    "name": "Install jazzy.install jazzy",
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@"
+    ]
   },
   {
     "cmd": [
diff --git a/recipes/engine/engine.expected/mac_upload_publish_cipd_no_lto.json b/recipes/engine/engine.expected/mac_upload_publish_cipd_no_lto.json
index 0c23280..cb22051 100644
--- a/recipes/engine/engine.expected/mac_upload_publish_cipd_no_lto.json
+++ b/recipes/engine/engine.expected/mac_upload_publish_cipd_no_lto.json
@@ -12810,6 +12810,79 @@
     ]
   },
   {
+    "cmd": [],
+    "name": "Install jazzy"
+  },
+  {
+    "cmd": [],
+    "name": "Install jazzy.Install ruby",
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@"
+    ]
+  },
+  {
+    "cmd": [
+      "cipd",
+      "ensure",
+      "-root",
+      "[CACHE]/ruby",
+      "-ensure-file",
+      "flutter/ruby/${platform} v3.3.14",
+      "-max-threads",
+      "0",
+      "-json-output",
+      "/path/to/tmp/json"
+    ],
+    "cwd": "[CACHE]/builder",
+    "env": {
+      "ANDROID_HOME": "[CACHE]/builder/src/third_party/android_tools/sdk",
+      "FLUTTER_LOGS_DIR": "[CLEANUP]/flutter_logs_dir",
+      "FLUTTER_PREBUILT_DART_SDK": "True",
+      "FLUTTER_TEST_OUTPUTS_DIR": "[CLEANUP]/flutter_logs_dir",
+      "GOMA_DIR": "[CACHE]/goma/client"
+    },
+    "env_prefixes": {
+      "PATH": [
+        "[CACHE]/builder/src/third_party/dart/tools/sdks/dart-sdk/bin"
+      ]
+    },
+    "env_suffixes": {
+      "DEPOT_TOOLS_UPDATE": [
+        "0"
+      ],
+      "PATH": [
+        "RECIPE_REPO[depot_tools]"
+      ]
+    },
+    "luci_context": {
+      "realm": {
+        "name": "flutter:ci"
+      },
+      "resultdb": {
+        "current_invocation": {
+          "name": "invocations/build:8945511751514863184",
+          "update_token": "token"
+        },
+        "hostname": "rdbhost"
+      }
+    },
+    "name": "Install jazzy.Install ruby.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-v3.3.14---------\", @@@",
+      "@@@STEP_LOG_LINE@json.output@        \"package\": \"flutter/ruby/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": [
       "vpython3",
       "-u",
@@ -12855,15 +12928,16 @@
         "hostname": "rdbhost"
       }
     },
-    "name": "mkdir gems"
+    "name": "Install jazzy.mkdir gems",
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@"
+    ]
   },
   {
     "cmd": [
       "gem",
       "install",
-      "jazzy:0.8.4",
-      "--platform",
-      "x86_64-darwin",
+      "jazzy:0.9.5",
       "--install-dir",
       "."
     ],
@@ -12900,7 +12974,10 @@
         "hostname": "rdbhost"
       }
     },
-    "name": "install jazzy"
+    "name": "Install jazzy.install jazzy",
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@"
+    ]
   },
   {
     "cmd": [
diff --git a/recipes/engine/engine.expected/mac_upload_publish_cipd_no_lto_font_subset.json b/recipes/engine/engine.expected/mac_upload_publish_cipd_no_lto_font_subset.json
index da7073b..c2a2ae6 100644
--- a/recipes/engine/engine.expected/mac_upload_publish_cipd_no_lto_font_subset.json
+++ b/recipes/engine/engine.expected/mac_upload_publish_cipd_no_lto_font_subset.json
@@ -12912,6 +12912,79 @@
     ]
   },
   {
+    "cmd": [],
+    "name": "Install jazzy"
+  },
+  {
+    "cmd": [],
+    "name": "Install jazzy.Install ruby",
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@"
+    ]
+  },
+  {
+    "cmd": [
+      "cipd",
+      "ensure",
+      "-root",
+      "[CACHE]/ruby",
+      "-ensure-file",
+      "flutter/ruby/${platform} v3.3.14",
+      "-max-threads",
+      "0",
+      "-json-output",
+      "/path/to/tmp/json"
+    ],
+    "cwd": "[CACHE]/builder",
+    "env": {
+      "ANDROID_HOME": "[CACHE]/builder/src/third_party/android_tools/sdk",
+      "FLUTTER_LOGS_DIR": "[CLEANUP]/flutter_logs_dir",
+      "FLUTTER_PREBUILT_DART_SDK": "True",
+      "FLUTTER_TEST_OUTPUTS_DIR": "[CLEANUP]/flutter_logs_dir",
+      "GOMA_DIR": "[CACHE]/goma/client"
+    },
+    "env_prefixes": {
+      "PATH": [
+        "[CACHE]/builder/src/third_party/dart/tools/sdks/dart-sdk/bin"
+      ]
+    },
+    "env_suffixes": {
+      "DEPOT_TOOLS_UPDATE": [
+        "0"
+      ],
+      "PATH": [
+        "RECIPE_REPO[depot_tools]"
+      ]
+    },
+    "luci_context": {
+      "realm": {
+        "name": "flutter:ci"
+      },
+      "resultdb": {
+        "current_invocation": {
+          "name": "invocations/build:8945511751514863184",
+          "update_token": "token"
+        },
+        "hostname": "rdbhost"
+      }
+    },
+    "name": "Install jazzy.Install ruby.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-v3.3.14---------\", @@@",
+      "@@@STEP_LOG_LINE@json.output@        \"package\": \"flutter/ruby/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": [
       "vpython3",
       "-u",
@@ -12957,15 +13030,16 @@
         "hostname": "rdbhost"
       }
     },
-    "name": "mkdir gems"
+    "name": "Install jazzy.mkdir gems",
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@"
+    ]
   },
   {
     "cmd": [
       "gem",
       "install",
-      "jazzy:0.8.4",
-      "--platform",
-      "x86_64-darwin",
+      "jazzy:0.9.5",
       "--install-dir",
       "."
     ],
@@ -13002,7 +13076,10 @@
         "hostname": "rdbhost"
       }
     },
-    "name": "install jazzy"
+    "name": "Install jazzy.install jazzy",
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@"
+    ]
   },
   {
     "cmd": [
diff --git a/recipes/engine/engine.py b/recipes/engine/engine.py
index 837806d..d6a9da2 100644
--- a/recipes/engine/engine.py
+++ b/recipes/engine/engine.py
@@ -1431,7 +1431,7 @@
     api.bucket_util.safe_upload(dsym_zip, remote_zip)
 
 
-def BuildIOS(api):
+def BuildIOS(api, env, env_prefixes):
   # Simulator binary is needed in all runtime modes.
   RunGN(api, '--ios', '--runtime-mode', 'debug', '--simulator', '--no-lto')
   Build(api, 'ios_debug_sim')
@@ -1460,7 +1460,7 @@
     )
     Build(api, 'ios_debug')
 
-    BuildObjcDoc(api)
+    BuildObjcDoc(api, env, env_prefixes)
 
     PackageIOSVariant(
         api, 'debug', 'ios_debug', 'ios_debug_sim',
@@ -1643,37 +1643,19 @@
 
 
 @contextmanager
-def InstallGems(api):
+def InstallGems(api, env, env_prefixes):
+  api.flutter_deps.jazzy(env, env_prefixes)
+
+  # Update PATH to reflect where jazzy was installed by the above command.
   gem_dir = api.path['start_dir'].join('gems')
-  api.file.ensure_directory('mkdir gems', gem_dir)
-
-  with api.context(cwd=gem_dir):
-    # jazzy depends on sqlite3, which started serving precompiled gems with version 1.5.0.
-    # The instance of Ruby currently packaged with macOS installs precompiled gems incorrectly.
-    # Specifically, if a gem vends precompiled binaries, it installs the arm64 variant even on x86 machines.
-    # https://github.com/flutter/flutter/issues/111193#issuecomment-1248714857
-    # https://github.com/sparklemotion/nokogiri/issues/2165#issuecomment-754101252
-    # https://rubygems.org/gems/sqlite3/versions
-
-    platform_id = ('x86_64-darwin'
-      if api.platform.arch == 'intel'
-      else 'arm64-darwin')
-
-    api.step(
-        'install jazzy', [
-            'gem', 'install', 'jazzy:' + api.properties['jazzy_version'],
-            '--platform', platform_id,
-            '--install-dir', '.'
-        ]
-    )
   with api.context(env={"GEM_HOME": gem_dir},
                    env_prefixes={'PATH': [gem_dir.join('bin')]}):
     yield
 
 
-def BuildObjcDoc(api):
+def BuildObjcDoc(api, env, env_prefixes):
   """Builds documentation for the Objective-C variant of engine."""
-  with InstallGems(api):
+  with InstallGems(api, env, env_prefixes):
     checkout = GetCheckoutPath(api)
     with api.os_utils.make_temp_directory('BuildObjcDoc') as temp_dir:
       objcdoc_cmd = [checkout.join('flutter/tools/gen_objcdoc.sh'), temp_dir]
@@ -1758,7 +1740,7 @@
         with SetupXcode(api):
           BuildMac(api)
           if api.properties.get('build_ios', True):
-            BuildIOS(api)
+            BuildIOS(api, env, env_prefixes)
           if api.properties.get('build_fuchsia', True):
             BuildFuchsia(api, gclient_vars)
           VerifyExportedSymbols(api)