Support new Apple Certificate in codesigning

Cherry picks the following CLs that were made against the
flutter-3.18-candidate.18 branch in order to run test release builds
to verify the correctness (since codesigning has to happen in the
dart-internal pool which does not support LED builds):

- 56640: Update certificate and password used for codesigning | https://flutter-review.googlesource.com/c/recipes/+/56640
- 57081: port setup_keychain.sh to dart and upload logs to GCS | https://flutter-review.googlesource.com/c/recipes/+/57081
- 57160: ensure dart sdk from engine checkout is on the path, fix broken usage of flutter/gsutil module, log output to secure log file on failure | https://flutter-review.googlesource.com/c/recipes/+/57160
- 57180: ensure we always log all certificates to secure log file | https://flutter-review.googlesource.com/c/recipes/+/57180
- 57280: Download Apple CA cert and import to keychain. | https://flutter-review.googlesource.com/c/recipes/+/57280
- 57820: Reapply "Use git ref to determine release branch name" | https://flutter-review.googlesource.com/c/recipes/+/57820

Bug: b/333426905
Change-Id: If1e227452179f7330fc3d487952664f3b702e1d4
Reviewed-on: https://flutter-review.googlesource.com/c/recipes/+/58160
Commit-Queue: Christopher Fujino <fujino@google.com>
Reviewed-by: Chris Bracken <cbracken@google.com>
diff --git a/recipe_modules/signing/__init__.py b/recipe_modules/signing/__init__.py
index 0c7164d..0f8be88 100644
--- a/recipe_modules/signing/__init__.py
+++ b/recipe_modules/signing/__init__.py
@@ -3,9 +3,11 @@
 # found in the LICENSE file.
 
 DEPS = [
+    'depot_tools/gsutil',
     'flutter/flutter_deps',
     'flutter/kms',
     'flutter/zip',
+    'fuchsia/buildbucket_util',
     'recipe_engine/context',
     'recipe_engine/file',
     'recipe_engine/futures',
diff --git a/recipe_modules/signing/api.py b/recipe_modules/signing/api.py
index b4e4137..19d976d 100644
--- a/recipe_modules/signing/api.py
+++ b/recipe_modules/signing/api.py
@@ -71,9 +71,11 @@
     with self.m.step.nest('Setup codesign environment'):
       secrets_dict = {
           'FLUTTER_P12':
-              'flutter_p12.encrypted', 'FLUTTER_P12_PASSWORD':
-                  'p12_password.encrypted', 'CODESIGN_TEAM_ID':
-                      'codesign_team_id.encrypted',
+              'exported_p12.encrypted',
+          'FLUTTER_P12_PASSWORD':
+              '0325_p12_password.encrypted',
+          'CODESIGN_TEAM_ID':
+              'codesign_team_id.encrypted',
           'CODESIGN_APP_SPECIFIC_PASSWORD':
               'codesign_app_specific_password.encrypted',
           'CODESIGN_APP_STORE_ID':
@@ -84,9 +86,9 @@
 
   def _keychain_setup(self, env, env_prefixes):
     """KeychainSetup sets up keychain for codesign.
-    
+
     This function triggers a shell script that creates a keychain named
-    build.keychain. It unlocks the keychain, 
+    build.keychain. It unlocks the keychain,
     adds keychain to codesign search list, and adds flutter .p12
     to this keychain. This script also supplies p12 password,
     and grants codesign cipd and system codesign the correct access controls.
@@ -97,7 +99,7 @@
       env_prefixes (dict) : environment paths.
     """
     with self.m.step.nest('Setup keychain'):
-      resource_name = self.resource('setup_keychain.sh')
+      resource_name = self.resource('setup_keychain.dart')
       self.m.step(
           'Set execute permission',
           ['chmod', '755', resource_name],
@@ -106,11 +108,25 @@
     # Only filepath with a .p12 suffix will be recognized.
     p12_suffix_filepath = self.m.path['cleanup'].join('flutter.p12')
     env['P12_SUFFIX_FILEPATH'] = p12_suffix_filepath
+    setup_keychain_log_file = self.m.path['cleanup'].join('setup_keychain_logs.txt')
+
+    env['SETUP_KEYCHAIN_LOGS_PATH'] = setup_keychain_log_file
     with self.m.context(env=env, env_prefixes=env_prefixes):
-      self.m.step(
-          'run keychain setup script', [resource_name],
-          stdout=self.m.raw_io.output_text()
-      )
+      try:
+          self.m.step(
+              'run keychain setup script', [resource_name],
+          )
+      finally:
+          # This will namespace the remote GCS path by the buildbucket build ID
+          buildbucket_id = self.m.buildbucket_util.id
+          remote_path = '%s/setup_keychain_logs.txt' % buildbucket_id
+          self.m.gsutil.upload(
+              bucket='flutter_tmp_logs',
+              source=setup_keychain_log_file,
+              dest=remote_path,
+              args=['-r'],
+              name='upload debug logs to %s' % remote_path
+          )
 
   def _signer_tasks(self, env, env_prefixes, files_to_sign):
     """Concurrently creates jobs to codesign each binary.
diff --git a/recipe_modules/signing/examples/code_sign.expected/mac_require_signing.json b/recipe_modules/signing/examples/code_sign.expected/mac_require_signing.json
index 85b5b6b..4ff4eac 100644
--- a/recipe_modules/signing/examples/code_sign.expected/mac_require_signing.json
+++ b/recipe_modules/signing/examples/code_sign.expected/mac_require_signing.json
@@ -88,8 +88,8 @@
       "RECIPE_REPO[depot_tools]/gsutil.py",
       "----",
       "cp",
-      "gs://flutter_configs/flutter_p12.encrypted",
-      "[CLEANUP]/flutter_p12.encrypted"
+      "gs://flutter_configs/exported_p12.encrypted",
+      "[CLEANUP]/exported_p12.encrypted"
     ],
     "infra_step": true,
     "name": "Setup codesign environment.gsutil download",
@@ -102,7 +102,7 @@
       "[START_DIR]/cloudkms/cloudkms",
       "decrypt",
       "-input",
-      "[CLEANUP]/flutter_p12.encrypted",
+      "[CLEANUP]/exported_p12.encrypted",
       "-output",
       "[CLEANUP]/FLUTTER_P12",
       "projects/flutter-infra-staging/locations/global/keyRings/luci/cryptoKeys/flutter-infra"
@@ -150,8 +150,8 @@
       "RECIPE_REPO[depot_tools]/gsutil.py",
       "----",
       "cp",
-      "gs://flutter_configs/p12_password.encrypted",
-      "[CLEANUP]/p12_password.encrypted"
+      "gs://flutter_configs/0325_p12_password.encrypted",
+      "[CLEANUP]/0325_p12_password.encrypted"
     ],
     "infra_step": true,
     "name": "Setup codesign environment.gsutil download (2)",
@@ -164,7 +164,7 @@
       "[START_DIR]/cloudkms/cloudkms",
       "decrypt",
       "-input",
-      "[CLEANUP]/p12_password.encrypted",
+      "[CLEANUP]/0325_p12_password.encrypted",
       "-output",
       "[CLEANUP]/FLUTTER_P12_PASSWORD",
       "projects/flutter-infra-staging/locations/global/keyRings/luci/cryptoKeys/flutter-infra"
@@ -368,7 +368,7 @@
     "cmd": [
       "chmod",
       "755",
-      "RECIPE_MODULE[flutter::signing]/resources/setup_keychain.sh"
+      "RECIPE_MODULE[flutter::signing]/resources/setup_keychain.dart"
     ],
     "infra_step": true,
     "name": "Setup keychain.Set execute permission",
@@ -378,7 +378,7 @@
   },
   {
     "cmd": [
-      "RECIPE_MODULE[flutter::signing]/resources/setup_keychain.sh"
+      "RECIPE_MODULE[flutter::signing]/resources/setup_keychain.dart"
     ],
     "env": {
       "CODESIGN_APP_SPECIFIC_PASSWORD": "[CLEANUP]/CODESIGN_APP_SPECIFIC_PASSWORD",
@@ -387,12 +387,42 @@
       "CODESIGN_TEAM_ID": "[CLEANUP]/CODESIGN_TEAM_ID",
       "FLUTTER_P12": "[CLEANUP]/FLUTTER_P12",
       "FLUTTER_P12_PASSWORD": "[CLEANUP]/FLUTTER_P12_PASSWORD",
-      "P12_SUFFIX_FILEPATH": "[CLEANUP]/flutter.p12"
+      "P12_SUFFIX_FILEPATH": "[CLEANUP]/flutter.p12",
+      "SETUP_KEYCHAIN_LOGS_PATH": "[CLEANUP]/setup_keychain_logs.txt"
     },
     "name": "run keychain setup script"
   },
   {
     "cmd": [
+      "python3",
+      "-u",
+      "RECIPE_MODULE[depot_tools::gsutil]/resources/gsutil_smart_retry.py",
+      "--",
+      "RECIPE_REPO[depot_tools]/gsutil.py",
+      "----",
+      "cp",
+      "-r",
+      "[CLEANUP]/setup_keychain_logs.txt",
+      "gs://flutter_tmp_logs/0/setup_keychain_logs.txt"
+    ],
+    "env": {
+      "CODESIGN_APP_SPECIFIC_PASSWORD": "[CLEANUP]/CODESIGN_APP_SPECIFIC_PASSWORD",
+      "CODESIGN_APP_STORE_ID": "[CLEANUP]/CODESIGN_APP_STORE_ID",
+      "CODESIGN_PATH": "[CLEANUP]/tmp_tmp_1/codesign",
+      "CODESIGN_TEAM_ID": "[CLEANUP]/CODESIGN_TEAM_ID",
+      "FLUTTER_P12": "[CLEANUP]/FLUTTER_P12",
+      "FLUTTER_P12_PASSWORD": "[CLEANUP]/FLUTTER_P12_PASSWORD",
+      "P12_SUFFIX_FILEPATH": "[CLEANUP]/flutter.p12",
+      "SETUP_KEYCHAIN_LOGS_PATH": "[CLEANUP]/setup_keychain_logs.txt"
+    },
+    "infra_step": true,
+    "name": "gsutil upload debug logs to 0/setup_keychain_logs.txt",
+    "~followup_annotations": [
+      "@@@STEP_LINK@gsutil.upload@https://console.cloud.google.com/storage/browser/flutter_tmp_logs/0/setup_keychain_logs.txt@@@"
+    ]
+  },
+  {
+    "cmd": [
       "vpython3",
       "-u",
       "RECIPE_MODULE[recipe_engine::file]/resources/fileutil.py",
@@ -446,7 +476,8 @@
       "CODESIGN_TEAM_ID": "[CLEANUP]/CODESIGN_TEAM_ID",
       "FLUTTER_P12": "[CLEANUP]/FLUTTER_P12",
       "FLUTTER_P12_PASSWORD": "[CLEANUP]/FLUTTER_P12_PASSWORD",
-      "P12_SUFFIX_FILEPATH": "[CLEANUP]/flutter.p12"
+      "P12_SUFFIX_FILEPATH": "[CLEANUP]/flutter.p12",
+      "SETUP_KEYCHAIN_LOGS_PATH": "[CLEANUP]/setup_keychain_logs.txt"
     },
     "name": "Codesign unsigned_file1.zip.codesign Apple engine binaries",
     "~followup_annotations": [
diff --git a/recipe_modules/signing/examples/code_sign.expected/no_signing_identity.json b/recipe_modules/signing/examples/code_sign.expected/no_signing_identity.json
index 85b5b6b..4ff4eac 100644
--- a/recipe_modules/signing/examples/code_sign.expected/no_signing_identity.json
+++ b/recipe_modules/signing/examples/code_sign.expected/no_signing_identity.json
@@ -88,8 +88,8 @@
       "RECIPE_REPO[depot_tools]/gsutil.py",
       "----",
       "cp",
-      "gs://flutter_configs/flutter_p12.encrypted",
-      "[CLEANUP]/flutter_p12.encrypted"
+      "gs://flutter_configs/exported_p12.encrypted",
+      "[CLEANUP]/exported_p12.encrypted"
     ],
     "infra_step": true,
     "name": "Setup codesign environment.gsutil download",
@@ -102,7 +102,7 @@
       "[START_DIR]/cloudkms/cloudkms",
       "decrypt",
       "-input",
-      "[CLEANUP]/flutter_p12.encrypted",
+      "[CLEANUP]/exported_p12.encrypted",
       "-output",
       "[CLEANUP]/FLUTTER_P12",
       "projects/flutter-infra-staging/locations/global/keyRings/luci/cryptoKeys/flutter-infra"
@@ -150,8 +150,8 @@
       "RECIPE_REPO[depot_tools]/gsutil.py",
       "----",
       "cp",
-      "gs://flutter_configs/p12_password.encrypted",
-      "[CLEANUP]/p12_password.encrypted"
+      "gs://flutter_configs/0325_p12_password.encrypted",
+      "[CLEANUP]/0325_p12_password.encrypted"
     ],
     "infra_step": true,
     "name": "Setup codesign environment.gsutil download (2)",
@@ -164,7 +164,7 @@
       "[START_DIR]/cloudkms/cloudkms",
       "decrypt",
       "-input",
-      "[CLEANUP]/p12_password.encrypted",
+      "[CLEANUP]/0325_p12_password.encrypted",
       "-output",
       "[CLEANUP]/FLUTTER_P12_PASSWORD",
       "projects/flutter-infra-staging/locations/global/keyRings/luci/cryptoKeys/flutter-infra"
@@ -368,7 +368,7 @@
     "cmd": [
       "chmod",
       "755",
-      "RECIPE_MODULE[flutter::signing]/resources/setup_keychain.sh"
+      "RECIPE_MODULE[flutter::signing]/resources/setup_keychain.dart"
     ],
     "infra_step": true,
     "name": "Setup keychain.Set execute permission",
@@ -378,7 +378,7 @@
   },
   {
     "cmd": [
-      "RECIPE_MODULE[flutter::signing]/resources/setup_keychain.sh"
+      "RECIPE_MODULE[flutter::signing]/resources/setup_keychain.dart"
     ],
     "env": {
       "CODESIGN_APP_SPECIFIC_PASSWORD": "[CLEANUP]/CODESIGN_APP_SPECIFIC_PASSWORD",
@@ -387,12 +387,42 @@
       "CODESIGN_TEAM_ID": "[CLEANUP]/CODESIGN_TEAM_ID",
       "FLUTTER_P12": "[CLEANUP]/FLUTTER_P12",
       "FLUTTER_P12_PASSWORD": "[CLEANUP]/FLUTTER_P12_PASSWORD",
-      "P12_SUFFIX_FILEPATH": "[CLEANUP]/flutter.p12"
+      "P12_SUFFIX_FILEPATH": "[CLEANUP]/flutter.p12",
+      "SETUP_KEYCHAIN_LOGS_PATH": "[CLEANUP]/setup_keychain_logs.txt"
     },
     "name": "run keychain setup script"
   },
   {
     "cmd": [
+      "python3",
+      "-u",
+      "RECIPE_MODULE[depot_tools::gsutil]/resources/gsutil_smart_retry.py",
+      "--",
+      "RECIPE_REPO[depot_tools]/gsutil.py",
+      "----",
+      "cp",
+      "-r",
+      "[CLEANUP]/setup_keychain_logs.txt",
+      "gs://flutter_tmp_logs/0/setup_keychain_logs.txt"
+    ],
+    "env": {
+      "CODESIGN_APP_SPECIFIC_PASSWORD": "[CLEANUP]/CODESIGN_APP_SPECIFIC_PASSWORD",
+      "CODESIGN_APP_STORE_ID": "[CLEANUP]/CODESIGN_APP_STORE_ID",
+      "CODESIGN_PATH": "[CLEANUP]/tmp_tmp_1/codesign",
+      "CODESIGN_TEAM_ID": "[CLEANUP]/CODESIGN_TEAM_ID",
+      "FLUTTER_P12": "[CLEANUP]/FLUTTER_P12",
+      "FLUTTER_P12_PASSWORD": "[CLEANUP]/FLUTTER_P12_PASSWORD",
+      "P12_SUFFIX_FILEPATH": "[CLEANUP]/flutter.p12",
+      "SETUP_KEYCHAIN_LOGS_PATH": "[CLEANUP]/setup_keychain_logs.txt"
+    },
+    "infra_step": true,
+    "name": "gsutil upload debug logs to 0/setup_keychain_logs.txt",
+    "~followup_annotations": [
+      "@@@STEP_LINK@gsutil.upload@https://console.cloud.google.com/storage/browser/flutter_tmp_logs/0/setup_keychain_logs.txt@@@"
+    ]
+  },
+  {
+    "cmd": [
       "vpython3",
       "-u",
       "RECIPE_MODULE[recipe_engine::file]/resources/fileutil.py",
@@ -446,7 +476,8 @@
       "CODESIGN_TEAM_ID": "[CLEANUP]/CODESIGN_TEAM_ID",
       "FLUTTER_P12": "[CLEANUP]/FLUTTER_P12",
       "FLUTTER_P12_PASSWORD": "[CLEANUP]/FLUTTER_P12_PASSWORD",
-      "P12_SUFFIX_FILEPATH": "[CLEANUP]/flutter.p12"
+      "P12_SUFFIX_FILEPATH": "[CLEANUP]/flutter.p12",
+      "SETUP_KEYCHAIN_LOGS_PATH": "[CLEANUP]/setup_keychain_logs.txt"
     },
     "name": "Codesign unsigned_file1.zip.codesign Apple engine binaries",
     "~followup_annotations": [
diff --git a/recipe_modules/signing/resources/setup_keychain.dart b/recipe_modules/signing/resources/setup_keychain.dart
new file mode 100755
index 0000000..83658e0
--- /dev/null
+++ b/recipe_modules/signing/resources/setup_keychain.dart
@@ -0,0 +1,195 @@
+#!/usr/bin/env dart
+// Copyright 2024 The Flutter Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Helper script to import a flutter p12 identity.
+
+import 'dart:io' as io;
+
+const String keychainName = 'build.keychain';
+const String keychainPassword = '';
+const int totalRetryAttempts = 3;
+
+Future<void> main() async {
+  final io.File logFile =
+      io.File(io.Platform.environment['SETUP_KEYCHAIN_LOGS_PATH']!);
+  final logSink = logFile.openWrite();
+  void log(String line) {
+    logSink.writeln('$line\n');
+  }
+
+  int exitCode = 1;
+  try {
+    exitCode = await innerMain(
+      passwordPath: io.Platform.environment['FLUTTER_P12_PASSWORD']!,
+      flutterP12Path: io.Platform.environment['FLUTTER_P12']!,
+      p12SuffixFilePath: io.Platform.environment['P12_SUFFIX_FILEPATH']!,
+      codesignPath: io.Platform.environment['CODESIGN_PATH']!,
+      log: log,
+    );
+  } finally {
+    await logSink.flush();
+    await logSink.close();
+  }
+  io.exit(exitCode);
+}
+
+Future<int> innerMain({
+  required String passwordPath,
+  required String flutterP12Path,
+  required String p12SuffixFilePath,
+  required String codesignPath,
+  required void Function(String) log,
+}) async {
+  String security(List<String> args, {bool allowNonzero = false}) {
+    log('Executing ${<String>['/usr/bin/security', ...args]}');
+
+    final io.ProcessResult result =
+        io.Process.runSync('/usr/bin/security', args);
+
+    log('process finished with exitCode ${result.exitCode}');
+    log('STDOUT:\n\n${result.stdout}');
+    log('STDERR:\n\n${result.stderr}');
+
+    if (!allowNonzero && result.exitCode != 0) {
+      throw io.ProcessException(
+          '/usr/bin/security', args, 'failed', result.exitCode);
+    }
+
+    return result.stdout as String;
+  }
+
+  try {
+    final String rawPassword = io.File(passwordPath).readAsStringSync();
+
+    // Only filepath with a .p12 suffix will be recognized
+    io.File(flutterP12Path).renameSync(p12SuffixFilePath);
+
+    // Delete build.keychain if it exists
+    security(const <String>['delete-keychain', keychainName], allowNonzero: true);
+
+    // Create keychain.
+    security(const <String>[
+      'create-keychain',
+      '-p',
+      keychainPassword,
+      keychainName,
+    ]);
+
+    // TODO(fujino): cache this via CIPD
+    final io.File g2CertFile = await _downloadFile(
+      // Link from https://www.apple.com/certificateauthority
+      remoteUri: Uri.parse('https://www.apple.com/certificateauthority/DeveloperIDG2CA.cer'),
+      localPath: './DeveloperIDG2CA.cer',
+    );
+
+    // LOAD certificate authority into the build keychain
+    await security(<String>[
+      'import',
+      g2CertFile.absolute.path,
+      '-k', keychainName,
+      // -T allows the specified program to access this identity
+      '-T', codesignPath,
+      '-T', '/usr/bin/codesign',
+    ]);
+
+    // Retrieve current list of keychains on the search list of current machine.
+    final keychains = security(const <String>['list-keychains', '-d', 'user'])
+        .split('\n')
+        .map<String?>((String line) {
+      final RegExp pattern = RegExp(r'^\s*".*\/([a-zA-Z0-9.]+)-db"');
+      final RegExpMatch? match = pattern.firstMatch(line);
+      if (match == null) {
+        return null;
+      }
+      // The first (and only) capture group is the name of the keychain
+      return match.group(1);
+    }).whereType<String>();
+
+    print('User keychains on this machine: $keychains');
+
+    // Add keychain name to search list.
+    // Without this, future commands such as `security import`,
+    // `security find-identity` and `codesign ...` will fail to find the cert
+    // in our newly created keychain.
+    security(<String>[
+      '-v',
+      'list-keychains',
+      // TODO(fujino): we probably don't need $keychains here, only keychainName should be required
+      '-s', ...keychains, keychainName,
+    ]);
+
+    // For diagnostic purposes, list keychains AFTER adding our newly created
+    // keychain to the search list.
+    security(const <String>['list-keychains', '-d', 'user']);
+
+    // Set $keychainName as default.
+    security(<String>[
+      'default-keychain',
+      '-s',
+      keychainName,
+    ]);
+
+    // Unlock keychainName to allow sign commands to use its certs.
+    security(<String>['unlock-keychain', '-p', keychainPassword, keychainName]);
+
+    // This will be exponentially increased on retries
+    int sleepSeconds = 2;
+
+    for (int attempt = 0; attempt < totalRetryAttempts; attempt++) {
+      security(<String>[
+        'import',
+        p12SuffixFilePath,
+        '-k', keychainName,
+        '-P', rawPassword,
+        // -T allows the specified program to access this identity
+        '-T', codesignPath,
+        '-T', '/usr/bin/codesign',
+      ]);
+      security(<String>[
+        'set-key-partition-list',
+        '-S',
+        'apple-tool:,apple:,codesign:',
+        '-s',
+        '-k',
+        '',
+        keychainName,
+      ]);
+
+      final String identities =
+          security(const <String>['find-identity', '-v', keychainName]);
+      if (identities.contains('FLUTTER.IO LLC')) {
+        log('successfully found a Flutter identity in the $keychainName keychain');
+        return 0;
+      }
+      log('failed to find a Flutter identity in the $keychainName keychain on attempt $attempt');
+      await Future<void>.delayed(Duration(seconds: sleepSeconds));
+      sleepSeconds *= sleepSeconds;
+    }
+  } finally {
+    security(const <String>[
+      'find-certificate',
+      // Find all matching certificates, not just the first
+      '-a',
+    ]);
+  }
+  log('failed to find a Flutter identity after $totalRetryAttempts attempts.');
+  return 1;
+}
+
+Future<io.File> _downloadFile({
+  required Uri remoteUri,
+  required String localPath,
+}) async {
+  final io.HttpClient client = io.HttpClient();
+
+  final io.HttpClientRequest request = await client.getUrl(remoteUri);
+  final io.HttpClientResponse response = await request.close();
+  final io.File g2CertFile = io.File(localPath);
+  final io.IOSink sink = g2CertFile.openWrite();
+  await response.pipe(sink);
+
+  client.close();
+  return g2CertFile;
+}
diff --git a/recipe_modules/signing/resources/setup_keychain.sh b/recipe_modules/signing/resources/setup_keychain.sh
deleted file mode 100644
index b2dd94a..0000000
--- a/recipe_modules/signing/resources/setup_keychain.sh
+++ /dev/null
@@ -1,56 +0,0 @@
-#!/bin/bash
-# Copyright 2024 The Flutter Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-# Helper script to import a flutter p12 identity.
-# Note: do not enable -x to display expanded values of the variables, as this will leak the passwords.
-set -e
-
-RAW_PASSWORD=$(cat $FLUTTER_P12_PASSWORD)
-# Only filepath with a .p12 suffix will be recognized
-mv $FLUTTER_P12 $P12_SUFFIX_FILEPATH
-
-# Delete build.keychain if it exists, do no-op if not exist.
-if /usr/bin/security delete-keychain build.keychain; then
-  :
-fi
-# Create build.keychain.
-/usr/bin/security create-keychain -p '' build.keychain
-
-# Retrieve current list of keychains on the search list of current machine.
-keychains=$(security list-keychains -d user)
-
-keychainNames=();
-
-for keychain in $keychains
-do
-  basename=$(basename "$keychain")
-  keychainName=${basename::${#basename}-4}
-  keychainNames+=("$keychainName")
-done
-
-echo "User keychains on this machine: ${keychainNames[@]}";
-
-# Add keychain name to search list. (FML, took me 5 days to hunt this down)
-/usr/bin/security -v list-keychains -s "${keychainNames[@]}" build.keychain
-
-# Set build.keychain as default.
-/usr/bin/security default-keychain -s build.keychain
-
-# Unlock build.keychain to allow sign commands to use its certs.
-/usr/bin/security unlock-keychain -p '' build.keychain
-
-attempt=0
-sleep_time=2
-while [ $attempt -lt 3 ]; do
-   /usr/bin/security import $P12_SUFFIX_FILEPATH -k build.keychain -P $RAW_PASSWORD -T $CODESIGN_PATH -T /usr/bin/codesign
-   /usr/bin/security set-key-partition-list -S apple-tool:,apple:,codesign: -s -k '' build.keychain
-   if /usr/bin/security find-identity -v build.keychain | grep 'FLUTTER.IO LLC'; then
-     exit 0
-   fi
-   sleep $sleep_time
-   attempt=$(( attempt + 1 ))
-   sleep_time=$(( sleep_time * sleep_time ))
-done
-exit 1
\ No newline at end of file
diff --git a/recipes/engine_v2/builder.expected/mac_release_candidate.json b/recipes/engine_v2/builder.expected/mac_release_candidate.json
index 985cb62..ad5051f 100644
--- a/recipes/engine_v2/builder.expected/mac_release_candidate.json
+++ b/recipes/engine_v2/builder.expected/mac_release_candidate.json
@@ -4013,8 +4013,8 @@
       "RECIPE_REPO[depot_tools]/gsutil.py",
       "----",
       "cp",
-      "gs://flutter_configs/flutter_p12.encrypted",
-      "[CLEANUP]/flutter_p12.encrypted"
+      "gs://flutter_configs/exported_p12.encrypted",
+      "[CLEANUP]/exported_p12.encrypted"
     ],
     "cwd": "[CACHE]/builder/src/flutter",
     "env": {
@@ -4074,7 +4074,7 @@
       "[START_DIR]/cloudkms/cloudkms",
       "decrypt",
       "-input",
-      "[CLEANUP]/flutter_p12.encrypted",
+      "[CLEANUP]/exported_p12.encrypted",
       "-output",
       "[CLEANUP]/FLUTTER_P12",
       "projects/flutter-infra-staging/locations/global/keyRings/luci/cryptoKeys/flutter-infra"
@@ -4216,8 +4216,8 @@
       "RECIPE_REPO[depot_tools]/gsutil.py",
       "----",
       "cp",
-      "gs://flutter_configs/p12_password.encrypted",
-      "[CLEANUP]/p12_password.encrypted"
+      "gs://flutter_configs/0325_p12_password.encrypted",
+      "[CLEANUP]/0325_p12_password.encrypted"
     ],
     "cwd": "[CACHE]/builder/src/flutter",
     "env": {
@@ -4277,7 +4277,7 @@
       "[START_DIR]/cloudkms/cloudkms",
       "decrypt",
       "-input",
-      "[CLEANUP]/p12_password.encrypted",
+      "[CLEANUP]/0325_p12_password.encrypted",
       "-output",
       "[CLEANUP]/FLUTTER_P12_PASSWORD",
       "projects/flutter-infra-staging/locations/global/keyRings/luci/cryptoKeys/flutter-infra"
@@ -4951,7 +4951,7 @@
     "cmd": [
       "chmod",
       "755",
-      "RECIPE_MODULE[flutter::signing]/resources/setup_keychain.sh"
+      "RECIPE_MODULE[flutter::signing]/resources/setup_keychain.dart"
     ],
     "cwd": "[CACHE]/builder/src/flutter",
     "env": {
@@ -5008,7 +5008,7 @@
   },
   {
     "cmd": [
-      "RECIPE_MODULE[flutter::signing]/resources/setup_keychain.sh"
+      "RECIPE_MODULE[flutter::signing]/resources/setup_keychain.dart"
     ],
     "cwd": "[CACHE]/builder/src/flutter",
     "env": {
@@ -5036,7 +5036,8 @@
       "LUCI_WORKDIR": "[START_DIR]",
       "OS": "darwin",
       "P12_SUFFIX_FILEPATH": "[CLEANUP]/flutter.p12",
-      "REVISION": "abcdabcdabcdabcdabcdabcdabcdabcdabcdabcd"
+      "REVISION": "abcdabcdabcdabcdabcdabcdabcdabcdabcdabcd",
+      "SETUP_KEYCHAIN_LOGS_PATH": "[CLEANUP]/setup_keychain_logs.txt"
     },
     "env_prefixes": {
       "PATH": [
@@ -5067,6 +5068,80 @@
     "name": "run keychain setup script"
   },
   {
+    "cmd": [
+      "python3",
+      "-u",
+      "RECIPE_MODULE[depot_tools::gsutil]/resources/gsutil_smart_retry.py",
+      "--",
+      "RECIPE_REPO[depot_tools]/gsutil.py",
+      "----",
+      "cp",
+      "-r",
+      "[CLEANUP]/setup_keychain_logs.txt",
+      "gs://flutter_tmp_logs/8945511751514863184/setup_keychain_logs.txt"
+    ],
+    "cwd": "[CACHE]/builder/src/flutter",
+    "env": {
+      "ANDROID_HOME": "[CACHE]/builder/src/third_party/android_tools/sdk",
+      "ANDROID_SDK_HOME": "[CLEANUP]/tmp_tmp_2",
+      "ANDROID_USER_HOME": "[CLEANUP]/tmp_tmp_2/.android",
+      "CLANG_CRASH_DIAGNOSTICS_DIR": "[CLEANUP]/tmp_tmp_3",
+      "CLANG_MODULE_CACHE_PATH": "",
+      "CODESIGN_APP_SPECIFIC_PASSWORD": "[CLEANUP]/CODESIGN_APP_SPECIFIC_PASSWORD",
+      "CODESIGN_APP_STORE_ID": "[CLEANUP]/CODESIGN_APP_STORE_ID",
+      "CODESIGN_PATH": "[CLEANUP]/tmp_tmp_5/codesign",
+      "CODESIGN_TEAM_ID": "[CLEANUP]/CODESIGN_TEAM_ID",
+      "DEPOT_TOOLS": "RECIPE_REPO[depot_tools]",
+      "ENGINE_CHECKOUT_PATH": "[CACHE]/builder",
+      "ENGINE_PATH": "[CACHE]/builder",
+      "FLUTTER_LOGS_DIR": "[CLEANUP]/flutter_logs_dir",
+      "FLUTTER_P12": "[CLEANUP]/FLUTTER_P12",
+      "FLUTTER_P12_PASSWORD": "[CLEANUP]/FLUTTER_P12_PASSWORD",
+      "FLUTTER_TEST_OUTPUTS_DIR": "[CLEANUP]/flutter_logs_dir",
+      "GIT_BRANCH": "",
+      "LUCI_BRANCH": "",
+      "LUCI_CI": "True",
+      "LUCI_CLEANUP": "[CLEANUP]",
+      "LUCI_PR": "",
+      "LUCI_WORKDIR": "[START_DIR]",
+      "OS": "darwin",
+      "P12_SUFFIX_FILEPATH": "[CLEANUP]/flutter.p12",
+      "REVISION": "abcdabcdabcdabcdabcdabcdabcdabcdabcdabcd",
+      "SETUP_KEYCHAIN_LOGS_PATH": "[CLEANUP]/setup_keychain_logs.txt"
+    },
+    "env_prefixes": {
+      "PATH": [
+        "[CACHE]/builder/src/third_party/dart/tools/sdks/dart-sdk/bin",
+        "[CACHE]/builder/src/flutter/third_party/dart/tools/sdks/dart-sdk/bin"
+      ]
+    },
+    "env_suffixes": {
+      "DEPOT_TOOLS_UPDATE": [
+        "0"
+      ],
+      "PATH": [
+        "RECIPE_REPO[depot_tools]"
+      ]
+    },
+    "infra_step": true,
+    "luci_context": {
+      "realm": {
+        "name": "flutter:prod"
+      },
+      "resultdb": {
+        "current_invocation": {
+          "name": "invocations/build:8945511751514863184",
+          "update_token": "token"
+        },
+        "hostname": "rdbhost"
+      }
+    },
+    "name": "gsutil upload debug logs to 8945511751514863184/setup_keychain_logs.txt",
+    "~followup_annotations": [
+      "@@@STEP_LINK@gsutil.upload@https://console.cloud.google.com/storage/browser/flutter_tmp_logs/8945511751514863184/setup_keychain_logs.txt@@@"
+    ]
+  },
+  {
     "cmd": [],
     "name": "Keychain cleanup"
   },
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 30920c5..ede9705 100644
--- a/recipes/engine_v2/engine_v2.expected/codesign_release_branch.json
+++ b/recipes/engine_v2/engine_v2.expected/codesign_release_branch.json
@@ -2226,6 +2226,30 @@
       "-json-output",
       "/path/to/tmp/json"
     ],
+    "env": {
+      "ANDROID_HOME": "[CACHE]/builder/src/third_party/android_tools/sdk",
+      "ANDROID_SDK_HOME": "[CLEANUP]/tmp_tmp_1",
+      "ANDROID_USER_HOME": "[CLEANUP]/tmp_tmp_1/.android",
+      "CLANG_CRASH_DIAGNOSTICS_DIR": "[CLEANUP]/tmp_tmp_2",
+      "CLANG_MODULE_CACHE_PATH": "",
+      "DEPOT_TOOLS": "RECIPE_REPO[depot_tools]",
+      "ENGINE_CHECKOUT_PATH": "[CACHE]/builder",
+      "ENGINE_PATH": "[CACHE]/builder",
+      "GIT_BRANCH": "",
+      "LUCI_BRANCH": "",
+      "LUCI_CI": "True",
+      "LUCI_CLEANUP": "[CLEANUP]",
+      "LUCI_PR": "",
+      "LUCI_WORKDIR": "[START_DIR]",
+      "OS": "darwin",
+      "REVISION": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+    },
+    "env_prefixes": {
+      "PATH": [
+        "[CACHE]/builder/src/third_party/dart/tools/sdks/dart-sdk/bin",
+        "[CACHE]/builder/src/flutter/third_party/dart/tools/sdks/dart-sdk/bin"
+      ]
+    },
     "luci_context": {
       "realm": {
         "name": "proj:try"
@@ -2274,6 +2298,30 @@
       "-json-output",
       "/path/to/tmp/json"
     ],
+    "env": {
+      "ANDROID_HOME": "[CACHE]/builder/src/third_party/android_tools/sdk",
+      "ANDROID_SDK_HOME": "[CLEANUP]/tmp_tmp_1",
+      "ANDROID_USER_HOME": "[CLEANUP]/tmp_tmp_1/.android",
+      "CLANG_CRASH_DIAGNOSTICS_DIR": "[CLEANUP]/tmp_tmp_2",
+      "CLANG_MODULE_CACHE_PATH": "",
+      "DEPOT_TOOLS": "RECIPE_REPO[depot_tools]",
+      "ENGINE_CHECKOUT_PATH": "[CACHE]/builder",
+      "ENGINE_PATH": "[CACHE]/builder",
+      "GIT_BRANCH": "",
+      "LUCI_BRANCH": "",
+      "LUCI_CI": "True",
+      "LUCI_CLEANUP": "[CLEANUP]",
+      "LUCI_PR": "",
+      "LUCI_WORKDIR": "[START_DIR]",
+      "OS": "darwin",
+      "REVISION": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+    },
+    "env_prefixes": {
+      "PATH": [
+        "[CACHE]/builder/src/third_party/dart/tools/sdks/dart-sdk/bin",
+        "[CACHE]/builder/src/flutter/third_party/dart/tools/sdks/dart-sdk/bin"
+      ]
+    },
     "luci_context": {
       "realm": {
         "name": "proj:try"
@@ -2311,9 +2359,33 @@
       "RECIPE_REPO[depot_tools]/gsutil.py",
       "----",
       "cp",
-      "gs://flutter_configs/flutter_p12.encrypted",
-      "[CLEANUP]/flutter_p12.encrypted"
+      "gs://flutter_configs/exported_p12.encrypted",
+      "[CLEANUP]/exported_p12.encrypted"
     ],
+    "env": {
+      "ANDROID_HOME": "[CACHE]/builder/src/third_party/android_tools/sdk",
+      "ANDROID_SDK_HOME": "[CLEANUP]/tmp_tmp_1",
+      "ANDROID_USER_HOME": "[CLEANUP]/tmp_tmp_1/.android",
+      "CLANG_CRASH_DIAGNOSTICS_DIR": "[CLEANUP]/tmp_tmp_2",
+      "CLANG_MODULE_CACHE_PATH": "",
+      "DEPOT_TOOLS": "RECIPE_REPO[depot_tools]",
+      "ENGINE_CHECKOUT_PATH": "[CACHE]/builder",
+      "ENGINE_PATH": "[CACHE]/builder",
+      "GIT_BRANCH": "",
+      "LUCI_BRANCH": "",
+      "LUCI_CI": "True",
+      "LUCI_CLEANUP": "[CLEANUP]",
+      "LUCI_PR": "",
+      "LUCI_WORKDIR": "[START_DIR]",
+      "OS": "darwin",
+      "REVISION": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+    },
+    "env_prefixes": {
+      "PATH": [
+        "[CACHE]/builder/src/third_party/dart/tools/sdks/dart-sdk/bin",
+        "[CACHE]/builder/src/flutter/third_party/dart/tools/sdks/dart-sdk/bin"
+      ]
+    },
     "infra_step": true,
     "luci_context": {
       "realm": {
@@ -2337,11 +2409,35 @@
       "[START_DIR]/cloudkms/cloudkms",
       "decrypt",
       "-input",
-      "[CLEANUP]/flutter_p12.encrypted",
+      "[CLEANUP]/exported_p12.encrypted",
       "-output",
       "[CLEANUP]/FLUTTER_P12",
       "projects/flutter-infra-staging/locations/global/keyRings/luci/cryptoKeys/flutter-infra"
     ],
+    "env": {
+      "ANDROID_HOME": "[CACHE]/builder/src/third_party/android_tools/sdk",
+      "ANDROID_SDK_HOME": "[CLEANUP]/tmp_tmp_1",
+      "ANDROID_USER_HOME": "[CLEANUP]/tmp_tmp_1/.android",
+      "CLANG_CRASH_DIAGNOSTICS_DIR": "[CLEANUP]/tmp_tmp_2",
+      "CLANG_MODULE_CACHE_PATH": "",
+      "DEPOT_TOOLS": "RECIPE_REPO[depot_tools]",
+      "ENGINE_CHECKOUT_PATH": "[CACHE]/builder",
+      "ENGINE_PATH": "[CACHE]/builder",
+      "GIT_BRANCH": "",
+      "LUCI_BRANCH": "",
+      "LUCI_CI": "True",
+      "LUCI_CLEANUP": "[CLEANUP]",
+      "LUCI_PR": "",
+      "LUCI_WORKDIR": "[START_DIR]",
+      "OS": "darwin",
+      "REVISION": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+    },
+    "env_prefixes": {
+      "PATH": [
+        "[CACHE]/builder/src/third_party/dart/tools/sdks/dart-sdk/bin",
+        "[CACHE]/builder/src/flutter/third_party/dart/tools/sdks/dart-sdk/bin"
+      ]
+    },
     "luci_context": {
       "realm": {
         "name": "proj:try"
@@ -2372,6 +2468,30 @@
       "-json-output",
       "/path/to/tmp/json"
     ],
+    "env": {
+      "ANDROID_HOME": "[CACHE]/builder/src/third_party/android_tools/sdk",
+      "ANDROID_SDK_HOME": "[CLEANUP]/tmp_tmp_1",
+      "ANDROID_USER_HOME": "[CLEANUP]/tmp_tmp_1/.android",
+      "CLANG_CRASH_DIAGNOSTICS_DIR": "[CLEANUP]/tmp_tmp_2",
+      "CLANG_MODULE_CACHE_PATH": "",
+      "DEPOT_TOOLS": "RECIPE_REPO[depot_tools]",
+      "ENGINE_CHECKOUT_PATH": "[CACHE]/builder",
+      "ENGINE_PATH": "[CACHE]/builder",
+      "GIT_BRANCH": "",
+      "LUCI_BRANCH": "",
+      "LUCI_CI": "True",
+      "LUCI_CLEANUP": "[CLEANUP]",
+      "LUCI_PR": "",
+      "LUCI_WORKDIR": "[START_DIR]",
+      "OS": "darwin",
+      "REVISION": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+    },
+    "env_prefixes": {
+      "PATH": [
+        "[CACHE]/builder/src/third_party/dart/tools/sdks/dart-sdk/bin",
+        "[CACHE]/builder/src/flutter/third_party/dart/tools/sdks/dart-sdk/bin"
+      ]
+    },
     "luci_context": {
       "realm": {
         "name": "proj:try"
@@ -2409,9 +2529,33 @@
       "RECIPE_REPO[depot_tools]/gsutil.py",
       "----",
       "cp",
-      "gs://flutter_configs/p12_password.encrypted",
-      "[CLEANUP]/p12_password.encrypted"
+      "gs://flutter_configs/0325_p12_password.encrypted",
+      "[CLEANUP]/0325_p12_password.encrypted"
     ],
+    "env": {
+      "ANDROID_HOME": "[CACHE]/builder/src/third_party/android_tools/sdk",
+      "ANDROID_SDK_HOME": "[CLEANUP]/tmp_tmp_1",
+      "ANDROID_USER_HOME": "[CLEANUP]/tmp_tmp_1/.android",
+      "CLANG_CRASH_DIAGNOSTICS_DIR": "[CLEANUP]/tmp_tmp_2",
+      "CLANG_MODULE_CACHE_PATH": "",
+      "DEPOT_TOOLS": "RECIPE_REPO[depot_tools]",
+      "ENGINE_CHECKOUT_PATH": "[CACHE]/builder",
+      "ENGINE_PATH": "[CACHE]/builder",
+      "GIT_BRANCH": "",
+      "LUCI_BRANCH": "",
+      "LUCI_CI": "True",
+      "LUCI_CLEANUP": "[CLEANUP]",
+      "LUCI_PR": "",
+      "LUCI_WORKDIR": "[START_DIR]",
+      "OS": "darwin",
+      "REVISION": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+    },
+    "env_prefixes": {
+      "PATH": [
+        "[CACHE]/builder/src/third_party/dart/tools/sdks/dart-sdk/bin",
+        "[CACHE]/builder/src/flutter/third_party/dart/tools/sdks/dart-sdk/bin"
+      ]
+    },
     "infra_step": true,
     "luci_context": {
       "realm": {
@@ -2435,11 +2579,35 @@
       "[START_DIR]/cloudkms/cloudkms",
       "decrypt",
       "-input",
-      "[CLEANUP]/p12_password.encrypted",
+      "[CLEANUP]/0325_p12_password.encrypted",
       "-output",
       "[CLEANUP]/FLUTTER_P12_PASSWORD",
       "projects/flutter-infra-staging/locations/global/keyRings/luci/cryptoKeys/flutter-infra"
     ],
+    "env": {
+      "ANDROID_HOME": "[CACHE]/builder/src/third_party/android_tools/sdk",
+      "ANDROID_SDK_HOME": "[CLEANUP]/tmp_tmp_1",
+      "ANDROID_USER_HOME": "[CLEANUP]/tmp_tmp_1/.android",
+      "CLANG_CRASH_DIAGNOSTICS_DIR": "[CLEANUP]/tmp_tmp_2",
+      "CLANG_MODULE_CACHE_PATH": "",
+      "DEPOT_TOOLS": "RECIPE_REPO[depot_tools]",
+      "ENGINE_CHECKOUT_PATH": "[CACHE]/builder",
+      "ENGINE_PATH": "[CACHE]/builder",
+      "GIT_BRANCH": "",
+      "LUCI_BRANCH": "",
+      "LUCI_CI": "True",
+      "LUCI_CLEANUP": "[CLEANUP]",
+      "LUCI_PR": "",
+      "LUCI_WORKDIR": "[START_DIR]",
+      "OS": "darwin",
+      "REVISION": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+    },
+    "env_prefixes": {
+      "PATH": [
+        "[CACHE]/builder/src/third_party/dart/tools/sdks/dart-sdk/bin",
+        "[CACHE]/builder/src/flutter/third_party/dart/tools/sdks/dart-sdk/bin"
+      ]
+    },
     "luci_context": {
       "realm": {
         "name": "proj:try"
@@ -2470,6 +2638,30 @@
       "-json-output",
       "/path/to/tmp/json"
     ],
+    "env": {
+      "ANDROID_HOME": "[CACHE]/builder/src/third_party/android_tools/sdk",
+      "ANDROID_SDK_HOME": "[CLEANUP]/tmp_tmp_1",
+      "ANDROID_USER_HOME": "[CLEANUP]/tmp_tmp_1/.android",
+      "CLANG_CRASH_DIAGNOSTICS_DIR": "[CLEANUP]/tmp_tmp_2",
+      "CLANG_MODULE_CACHE_PATH": "",
+      "DEPOT_TOOLS": "RECIPE_REPO[depot_tools]",
+      "ENGINE_CHECKOUT_PATH": "[CACHE]/builder",
+      "ENGINE_PATH": "[CACHE]/builder",
+      "GIT_BRANCH": "",
+      "LUCI_BRANCH": "",
+      "LUCI_CI": "True",
+      "LUCI_CLEANUP": "[CLEANUP]",
+      "LUCI_PR": "",
+      "LUCI_WORKDIR": "[START_DIR]",
+      "OS": "darwin",
+      "REVISION": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+    },
+    "env_prefixes": {
+      "PATH": [
+        "[CACHE]/builder/src/third_party/dart/tools/sdks/dart-sdk/bin",
+        "[CACHE]/builder/src/flutter/third_party/dart/tools/sdks/dart-sdk/bin"
+      ]
+    },
     "luci_context": {
       "realm": {
         "name": "proj:try"
@@ -2510,6 +2702,30 @@
       "gs://flutter_configs/codesign_team_id.encrypted",
       "[CLEANUP]/codesign_team_id.encrypted"
     ],
+    "env": {
+      "ANDROID_HOME": "[CACHE]/builder/src/third_party/android_tools/sdk",
+      "ANDROID_SDK_HOME": "[CLEANUP]/tmp_tmp_1",
+      "ANDROID_USER_HOME": "[CLEANUP]/tmp_tmp_1/.android",
+      "CLANG_CRASH_DIAGNOSTICS_DIR": "[CLEANUP]/tmp_tmp_2",
+      "CLANG_MODULE_CACHE_PATH": "",
+      "DEPOT_TOOLS": "RECIPE_REPO[depot_tools]",
+      "ENGINE_CHECKOUT_PATH": "[CACHE]/builder",
+      "ENGINE_PATH": "[CACHE]/builder",
+      "GIT_BRANCH": "",
+      "LUCI_BRANCH": "",
+      "LUCI_CI": "True",
+      "LUCI_CLEANUP": "[CLEANUP]",
+      "LUCI_PR": "",
+      "LUCI_WORKDIR": "[START_DIR]",
+      "OS": "darwin",
+      "REVISION": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+    },
+    "env_prefixes": {
+      "PATH": [
+        "[CACHE]/builder/src/third_party/dart/tools/sdks/dart-sdk/bin",
+        "[CACHE]/builder/src/flutter/third_party/dart/tools/sdks/dart-sdk/bin"
+      ]
+    },
     "infra_step": true,
     "luci_context": {
       "realm": {
@@ -2538,6 +2754,30 @@
       "[CLEANUP]/CODESIGN_TEAM_ID",
       "projects/flutter-infra-staging/locations/global/keyRings/luci/cryptoKeys/flutter-infra"
     ],
+    "env": {
+      "ANDROID_HOME": "[CACHE]/builder/src/third_party/android_tools/sdk",
+      "ANDROID_SDK_HOME": "[CLEANUP]/tmp_tmp_1",
+      "ANDROID_USER_HOME": "[CLEANUP]/tmp_tmp_1/.android",
+      "CLANG_CRASH_DIAGNOSTICS_DIR": "[CLEANUP]/tmp_tmp_2",
+      "CLANG_MODULE_CACHE_PATH": "",
+      "DEPOT_TOOLS": "RECIPE_REPO[depot_tools]",
+      "ENGINE_CHECKOUT_PATH": "[CACHE]/builder",
+      "ENGINE_PATH": "[CACHE]/builder",
+      "GIT_BRANCH": "",
+      "LUCI_BRANCH": "",
+      "LUCI_CI": "True",
+      "LUCI_CLEANUP": "[CLEANUP]",
+      "LUCI_PR": "",
+      "LUCI_WORKDIR": "[START_DIR]",
+      "OS": "darwin",
+      "REVISION": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+    },
+    "env_prefixes": {
+      "PATH": [
+        "[CACHE]/builder/src/third_party/dart/tools/sdks/dart-sdk/bin",
+        "[CACHE]/builder/src/flutter/third_party/dart/tools/sdks/dart-sdk/bin"
+      ]
+    },
     "luci_context": {
       "realm": {
         "name": "proj:try"
@@ -2568,6 +2808,30 @@
       "-json-output",
       "/path/to/tmp/json"
     ],
+    "env": {
+      "ANDROID_HOME": "[CACHE]/builder/src/third_party/android_tools/sdk",
+      "ANDROID_SDK_HOME": "[CLEANUP]/tmp_tmp_1",
+      "ANDROID_USER_HOME": "[CLEANUP]/tmp_tmp_1/.android",
+      "CLANG_CRASH_DIAGNOSTICS_DIR": "[CLEANUP]/tmp_tmp_2",
+      "CLANG_MODULE_CACHE_PATH": "",
+      "DEPOT_TOOLS": "RECIPE_REPO[depot_tools]",
+      "ENGINE_CHECKOUT_PATH": "[CACHE]/builder",
+      "ENGINE_PATH": "[CACHE]/builder",
+      "GIT_BRANCH": "",
+      "LUCI_BRANCH": "",
+      "LUCI_CI": "True",
+      "LUCI_CLEANUP": "[CLEANUP]",
+      "LUCI_PR": "",
+      "LUCI_WORKDIR": "[START_DIR]",
+      "OS": "darwin",
+      "REVISION": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+    },
+    "env_prefixes": {
+      "PATH": [
+        "[CACHE]/builder/src/third_party/dart/tools/sdks/dart-sdk/bin",
+        "[CACHE]/builder/src/flutter/third_party/dart/tools/sdks/dart-sdk/bin"
+      ]
+    },
     "luci_context": {
       "realm": {
         "name": "proj:try"
@@ -2608,6 +2872,30 @@
       "gs://flutter_configs/codesign_app_specific_password.encrypted",
       "[CLEANUP]/codesign_app_specific_password.encrypted"
     ],
+    "env": {
+      "ANDROID_HOME": "[CACHE]/builder/src/third_party/android_tools/sdk",
+      "ANDROID_SDK_HOME": "[CLEANUP]/tmp_tmp_1",
+      "ANDROID_USER_HOME": "[CLEANUP]/tmp_tmp_1/.android",
+      "CLANG_CRASH_DIAGNOSTICS_DIR": "[CLEANUP]/tmp_tmp_2",
+      "CLANG_MODULE_CACHE_PATH": "",
+      "DEPOT_TOOLS": "RECIPE_REPO[depot_tools]",
+      "ENGINE_CHECKOUT_PATH": "[CACHE]/builder",
+      "ENGINE_PATH": "[CACHE]/builder",
+      "GIT_BRANCH": "",
+      "LUCI_BRANCH": "",
+      "LUCI_CI": "True",
+      "LUCI_CLEANUP": "[CLEANUP]",
+      "LUCI_PR": "",
+      "LUCI_WORKDIR": "[START_DIR]",
+      "OS": "darwin",
+      "REVISION": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+    },
+    "env_prefixes": {
+      "PATH": [
+        "[CACHE]/builder/src/third_party/dart/tools/sdks/dart-sdk/bin",
+        "[CACHE]/builder/src/flutter/third_party/dart/tools/sdks/dart-sdk/bin"
+      ]
+    },
     "infra_step": true,
     "luci_context": {
       "realm": {
@@ -2636,6 +2924,30 @@
       "[CLEANUP]/CODESIGN_APP_SPECIFIC_PASSWORD",
       "projects/flutter-infra-staging/locations/global/keyRings/luci/cryptoKeys/flutter-infra"
     ],
+    "env": {
+      "ANDROID_HOME": "[CACHE]/builder/src/third_party/android_tools/sdk",
+      "ANDROID_SDK_HOME": "[CLEANUP]/tmp_tmp_1",
+      "ANDROID_USER_HOME": "[CLEANUP]/tmp_tmp_1/.android",
+      "CLANG_CRASH_DIAGNOSTICS_DIR": "[CLEANUP]/tmp_tmp_2",
+      "CLANG_MODULE_CACHE_PATH": "",
+      "DEPOT_TOOLS": "RECIPE_REPO[depot_tools]",
+      "ENGINE_CHECKOUT_PATH": "[CACHE]/builder",
+      "ENGINE_PATH": "[CACHE]/builder",
+      "GIT_BRANCH": "",
+      "LUCI_BRANCH": "",
+      "LUCI_CI": "True",
+      "LUCI_CLEANUP": "[CLEANUP]",
+      "LUCI_PR": "",
+      "LUCI_WORKDIR": "[START_DIR]",
+      "OS": "darwin",
+      "REVISION": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+    },
+    "env_prefixes": {
+      "PATH": [
+        "[CACHE]/builder/src/third_party/dart/tools/sdks/dart-sdk/bin",
+        "[CACHE]/builder/src/flutter/third_party/dart/tools/sdks/dart-sdk/bin"
+      ]
+    },
     "luci_context": {
       "realm": {
         "name": "proj:try"
@@ -2666,6 +2978,30 @@
       "-json-output",
       "/path/to/tmp/json"
     ],
+    "env": {
+      "ANDROID_HOME": "[CACHE]/builder/src/third_party/android_tools/sdk",
+      "ANDROID_SDK_HOME": "[CLEANUP]/tmp_tmp_1",
+      "ANDROID_USER_HOME": "[CLEANUP]/tmp_tmp_1/.android",
+      "CLANG_CRASH_DIAGNOSTICS_DIR": "[CLEANUP]/tmp_tmp_2",
+      "CLANG_MODULE_CACHE_PATH": "",
+      "DEPOT_TOOLS": "RECIPE_REPO[depot_tools]",
+      "ENGINE_CHECKOUT_PATH": "[CACHE]/builder",
+      "ENGINE_PATH": "[CACHE]/builder",
+      "GIT_BRANCH": "",
+      "LUCI_BRANCH": "",
+      "LUCI_CI": "True",
+      "LUCI_CLEANUP": "[CLEANUP]",
+      "LUCI_PR": "",
+      "LUCI_WORKDIR": "[START_DIR]",
+      "OS": "darwin",
+      "REVISION": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+    },
+    "env_prefixes": {
+      "PATH": [
+        "[CACHE]/builder/src/third_party/dart/tools/sdks/dart-sdk/bin",
+        "[CACHE]/builder/src/flutter/third_party/dart/tools/sdks/dart-sdk/bin"
+      ]
+    },
     "luci_context": {
       "realm": {
         "name": "proj:try"
@@ -2706,6 +3042,30 @@
       "gs://flutter_configs/codesign_app_store_id.encrypted",
       "[CLEANUP]/codesign_app_store_id.encrypted"
     ],
+    "env": {
+      "ANDROID_HOME": "[CACHE]/builder/src/third_party/android_tools/sdk",
+      "ANDROID_SDK_HOME": "[CLEANUP]/tmp_tmp_1",
+      "ANDROID_USER_HOME": "[CLEANUP]/tmp_tmp_1/.android",
+      "CLANG_CRASH_DIAGNOSTICS_DIR": "[CLEANUP]/tmp_tmp_2",
+      "CLANG_MODULE_CACHE_PATH": "",
+      "DEPOT_TOOLS": "RECIPE_REPO[depot_tools]",
+      "ENGINE_CHECKOUT_PATH": "[CACHE]/builder",
+      "ENGINE_PATH": "[CACHE]/builder",
+      "GIT_BRANCH": "",
+      "LUCI_BRANCH": "",
+      "LUCI_CI": "True",
+      "LUCI_CLEANUP": "[CLEANUP]",
+      "LUCI_PR": "",
+      "LUCI_WORKDIR": "[START_DIR]",
+      "OS": "darwin",
+      "REVISION": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+    },
+    "env_prefixes": {
+      "PATH": [
+        "[CACHE]/builder/src/third_party/dart/tools/sdks/dart-sdk/bin",
+        "[CACHE]/builder/src/flutter/third_party/dart/tools/sdks/dart-sdk/bin"
+      ]
+    },
     "infra_step": true,
     "luci_context": {
       "realm": {
@@ -2734,6 +3094,30 @@
       "[CLEANUP]/CODESIGN_APP_STORE_ID",
       "projects/flutter-infra-staging/locations/global/keyRings/luci/cryptoKeys/flutter-infra"
     ],
+    "env": {
+      "ANDROID_HOME": "[CACHE]/builder/src/third_party/android_tools/sdk",
+      "ANDROID_SDK_HOME": "[CLEANUP]/tmp_tmp_1",
+      "ANDROID_USER_HOME": "[CLEANUP]/tmp_tmp_1/.android",
+      "CLANG_CRASH_DIAGNOSTICS_DIR": "[CLEANUP]/tmp_tmp_2",
+      "CLANG_MODULE_CACHE_PATH": "",
+      "DEPOT_TOOLS": "RECIPE_REPO[depot_tools]",
+      "ENGINE_CHECKOUT_PATH": "[CACHE]/builder",
+      "ENGINE_PATH": "[CACHE]/builder",
+      "GIT_BRANCH": "",
+      "LUCI_BRANCH": "",
+      "LUCI_CI": "True",
+      "LUCI_CLEANUP": "[CLEANUP]",
+      "LUCI_PR": "",
+      "LUCI_WORKDIR": "[START_DIR]",
+      "OS": "darwin",
+      "REVISION": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+    },
+    "env_prefixes": {
+      "PATH": [
+        "[CACHE]/builder/src/third_party/dart/tools/sdks/dart-sdk/bin",
+        "[CACHE]/builder/src/flutter/third_party/dart/tools/sdks/dart-sdk/bin"
+      ]
+    },
     "luci_context": {
       "realm": {
         "name": "proj:try"
@@ -2762,8 +3146,32 @@
     "cmd": [
       "chmod",
       "755",
-      "RECIPE_MODULE[flutter::signing]/resources/setup_keychain.sh"
+      "RECIPE_MODULE[flutter::signing]/resources/setup_keychain.dart"
     ],
+    "env": {
+      "ANDROID_HOME": "[CACHE]/builder/src/third_party/android_tools/sdk",
+      "ANDROID_SDK_HOME": "[CLEANUP]/tmp_tmp_1",
+      "ANDROID_USER_HOME": "[CLEANUP]/tmp_tmp_1/.android",
+      "CLANG_CRASH_DIAGNOSTICS_DIR": "[CLEANUP]/tmp_tmp_2",
+      "CLANG_MODULE_CACHE_PATH": "",
+      "DEPOT_TOOLS": "RECIPE_REPO[depot_tools]",
+      "ENGINE_CHECKOUT_PATH": "[CACHE]/builder",
+      "ENGINE_PATH": "[CACHE]/builder",
+      "GIT_BRANCH": "",
+      "LUCI_BRANCH": "",
+      "LUCI_CI": "True",
+      "LUCI_CLEANUP": "[CLEANUP]",
+      "LUCI_PR": "",
+      "LUCI_WORKDIR": "[START_DIR]",
+      "OS": "darwin",
+      "REVISION": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+    },
+    "env_prefixes": {
+      "PATH": [
+        "[CACHE]/builder/src/third_party/dart/tools/sdks/dart-sdk/bin",
+        "[CACHE]/builder/src/flutter/third_party/dart/tools/sdks/dart-sdk/bin"
+      ]
+    },
     "infra_step": true,
     "luci_context": {
       "realm": {
@@ -2784,16 +3192,39 @@
   },
   {
     "cmd": [
-      "RECIPE_MODULE[flutter::signing]/resources/setup_keychain.sh"
+      "RECIPE_MODULE[flutter::signing]/resources/setup_keychain.dart"
     ],
     "env": {
+      "ANDROID_HOME": "[CACHE]/builder/src/third_party/android_tools/sdk",
+      "ANDROID_SDK_HOME": "[CLEANUP]/tmp_tmp_1",
+      "ANDROID_USER_HOME": "[CLEANUP]/tmp_tmp_1/.android",
+      "CLANG_CRASH_DIAGNOSTICS_DIR": "[CLEANUP]/tmp_tmp_2",
+      "CLANG_MODULE_CACHE_PATH": "",
       "CODESIGN_APP_SPECIFIC_PASSWORD": "[CLEANUP]/CODESIGN_APP_SPECIFIC_PASSWORD",
       "CODESIGN_APP_STORE_ID": "[CLEANUP]/CODESIGN_APP_STORE_ID",
       "CODESIGN_PATH": "[CLEANUP]/tmp_tmp_3/codesign",
       "CODESIGN_TEAM_ID": "[CLEANUP]/CODESIGN_TEAM_ID",
+      "DEPOT_TOOLS": "RECIPE_REPO[depot_tools]",
+      "ENGINE_CHECKOUT_PATH": "[CACHE]/builder",
+      "ENGINE_PATH": "[CACHE]/builder",
       "FLUTTER_P12": "[CLEANUP]/FLUTTER_P12",
       "FLUTTER_P12_PASSWORD": "[CLEANUP]/FLUTTER_P12_PASSWORD",
-      "P12_SUFFIX_FILEPATH": "[CLEANUP]/flutter.p12"
+      "GIT_BRANCH": "",
+      "LUCI_BRANCH": "",
+      "LUCI_CI": "True",
+      "LUCI_CLEANUP": "[CLEANUP]",
+      "LUCI_PR": "",
+      "LUCI_WORKDIR": "[START_DIR]",
+      "OS": "darwin",
+      "P12_SUFFIX_FILEPATH": "[CLEANUP]/flutter.p12",
+      "REVISION": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
+      "SETUP_KEYCHAIN_LOGS_PATH": "[CLEANUP]/setup_keychain_logs.txt"
+    },
+    "env_prefixes": {
+      "PATH": [
+        "[CACHE]/builder/src/third_party/dart/tools/sdks/dart-sdk/bin",
+        "[CACHE]/builder/src/flutter/third_party/dart/tools/sdks/dart-sdk/bin"
+      ]
     },
     "luci_context": {
       "realm": {
@@ -2813,6 +3244,70 @@
     ]
   },
   {
+    "cmd": [
+      "python3",
+      "-u",
+      "RECIPE_MODULE[depot_tools::gsutil]/resources/gsutil_smart_retry.py",
+      "--",
+      "RECIPE_REPO[depot_tools]/gsutil.py",
+      "----",
+      "cp",
+      "-r",
+      "[CLEANUP]/setup_keychain_logs.txt",
+      "gs://flutter_tmp_logs/8945511751514863184/setup_keychain_logs.txt"
+    ],
+    "env": {
+      "ANDROID_HOME": "[CACHE]/builder/src/third_party/android_tools/sdk",
+      "ANDROID_SDK_HOME": "[CLEANUP]/tmp_tmp_1",
+      "ANDROID_USER_HOME": "[CLEANUP]/tmp_tmp_1/.android",
+      "CLANG_CRASH_DIAGNOSTICS_DIR": "[CLEANUP]/tmp_tmp_2",
+      "CLANG_MODULE_CACHE_PATH": "",
+      "CODESIGN_APP_SPECIFIC_PASSWORD": "[CLEANUP]/CODESIGN_APP_SPECIFIC_PASSWORD",
+      "CODESIGN_APP_STORE_ID": "[CLEANUP]/CODESIGN_APP_STORE_ID",
+      "CODESIGN_PATH": "[CLEANUP]/tmp_tmp_3/codesign",
+      "CODESIGN_TEAM_ID": "[CLEANUP]/CODESIGN_TEAM_ID",
+      "DEPOT_TOOLS": "RECIPE_REPO[depot_tools]",
+      "ENGINE_CHECKOUT_PATH": "[CACHE]/builder",
+      "ENGINE_PATH": "[CACHE]/builder",
+      "FLUTTER_P12": "[CLEANUP]/FLUTTER_P12",
+      "FLUTTER_P12_PASSWORD": "[CLEANUP]/FLUTTER_P12_PASSWORD",
+      "GIT_BRANCH": "",
+      "LUCI_BRANCH": "",
+      "LUCI_CI": "True",
+      "LUCI_CLEANUP": "[CLEANUP]",
+      "LUCI_PR": "",
+      "LUCI_WORKDIR": "[START_DIR]",
+      "OS": "darwin",
+      "P12_SUFFIX_FILEPATH": "[CLEANUP]/flutter.p12",
+      "REVISION": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
+      "SETUP_KEYCHAIN_LOGS_PATH": "[CLEANUP]/setup_keychain_logs.txt"
+    },
+    "env_prefixes": {
+      "PATH": [
+        "[CACHE]/builder/src/third_party/dart/tools/sdks/dart-sdk/bin",
+        "[CACHE]/builder/src/flutter/third_party/dart/tools/sdks/dart-sdk/bin"
+      ]
+    },
+    "infra_step": true,
+    "luci_context": {
+      "realm": {
+        "name": "proj:try"
+      },
+      "resultdb": {
+        "current_invocation": {
+          "name": "invocations/build:8945511751514863184",
+          "update_token": "token"
+        },
+        "hostname": "rdbhost"
+      }
+    },
+    "name": "Global generators.gsutil upload debug logs to 8945511751514863184/setup_keychain_logs.txt",
+    "~followup_annotations": [
+      "@@@STEP_NEST_LEVEL@1@@@",
+      "@@@STEP_LINK@gsutil.upload@https://console.cloud.google.com/storage/browser/flutter_tmp_logs/8945511751514863184/setup_keychain_logs.txt@@@"
+    ]
+  },
+  {
     "cmd": [],
     "name": "Global generators.Keychain cleanup",
     "~followup_annotations": [
@@ -2825,6 +3320,30 @@
       "delete-keychain",
       "build.keychain"
     ],
+    "env": {
+      "ANDROID_HOME": "[CACHE]/builder/src/third_party/android_tools/sdk",
+      "ANDROID_SDK_HOME": "[CLEANUP]/tmp_tmp_1",
+      "ANDROID_USER_HOME": "[CLEANUP]/tmp_tmp_1/.android",
+      "CLANG_CRASH_DIAGNOSTICS_DIR": "[CLEANUP]/tmp_tmp_2",
+      "CLANG_MODULE_CACHE_PATH": "",
+      "DEPOT_TOOLS": "RECIPE_REPO[depot_tools]",
+      "ENGINE_CHECKOUT_PATH": "[CACHE]/builder",
+      "ENGINE_PATH": "[CACHE]/builder",
+      "GIT_BRANCH": "",
+      "LUCI_BRANCH": "",
+      "LUCI_CI": "True",
+      "LUCI_CLEANUP": "[CLEANUP]",
+      "LUCI_PR": "",
+      "LUCI_WORKDIR": "[START_DIR]",
+      "OS": "darwin",
+      "REVISION": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+    },
+    "env_prefixes": {
+      "PATH": [
+        "[CACHE]/builder/src/third_party/dart/tools/sdks/dart-sdk/bin",
+        "[CACHE]/builder/src/flutter/third_party/dart/tools/sdks/dart-sdk/bin"
+      ]
+    },
     "luci_context": {
       "realm": {
         "name": "proj:try"
@@ -2849,6 +3368,30 @@
       "-s",
       "login.keychain"
     ],
+    "env": {
+      "ANDROID_HOME": "[CACHE]/builder/src/third_party/android_tools/sdk",
+      "ANDROID_SDK_HOME": "[CLEANUP]/tmp_tmp_1",
+      "ANDROID_USER_HOME": "[CLEANUP]/tmp_tmp_1/.android",
+      "CLANG_CRASH_DIAGNOSTICS_DIR": "[CLEANUP]/tmp_tmp_2",
+      "CLANG_MODULE_CACHE_PATH": "",
+      "DEPOT_TOOLS": "RECIPE_REPO[depot_tools]",
+      "ENGINE_CHECKOUT_PATH": "[CACHE]/builder",
+      "ENGINE_PATH": "[CACHE]/builder",
+      "GIT_BRANCH": "",
+      "LUCI_BRANCH": "",
+      "LUCI_CI": "True",
+      "LUCI_CLEANUP": "[CLEANUP]",
+      "LUCI_PR": "",
+      "LUCI_WORKDIR": "[START_DIR]",
+      "OS": "darwin",
+      "REVISION": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
+    },
+    "env_prefixes": {
+      "PATH": [
+        "[CACHE]/builder/src/third_party/dart/tools/sdks/dart-sdk/bin",
+        "[CACHE]/builder/src/flutter/third_party/dart/tools/sdks/dart-sdk/bin"
+      ]
+    },
     "luci_context": {
       "realm": {
         "name": "proj:try"
diff --git a/recipes/engine_v2/engine_v2.py b/recipes/engine_v2/engine_v2.py
index 09d62d2..e9d8089 100644
--- a/recipes/engine_v2/engine_v2.py
+++ b/recipes/engine_v2/engine_v2.py
@@ -157,12 +157,12 @@
             _run_global_generators(
                 api, generators, full_engine_checkout, env, env_prefixes
             )
-            _archive(api, archives, full_engine_checkout)
+            _archive(api, archives, full_engine_checkout, env, env_prefixes)
         else:
           _run_global_generators(
               api, generators, full_engine_checkout, env, env_prefixes
           )
-          _archive(api, archives, full_engine_checkout)
+          _archive(api, archives, full_engine_checkout, env, env_prefixes)
 
   # Run tests
   if not api.flutter_bcid.is_official_build():
@@ -181,7 +181,7 @@
     )
 
 
-def _archive(api, archives, full_engine_checkout):
+def _archive(api, archives, full_engine_checkout, env, env_prefixes):
   """Proces global archives.
 
   Args:
@@ -215,7 +215,8 @@
         for path in files_to_archive
         if api.signing.requires_signing(path.local)
     ]
-    api.signing.code_sign(signing_paths)
+    with api.context(env=env, env_prefixes=env_prefixes):
+      api.signing.code_sign(signing_paths)
   for archive in files_to_archive:
     api.archives.upload_artifact(archive.local, archive.remote)
     api.flutter_bcid.upload_provenance(archive.local, archive.remote)