Signer recipe downloads artifact, codesigns file, and upload artifact back. Editions include adding kms secrets, tmp directory tracking, unlock keychain in the same session
12/13 led run:
https://ci.chromium.org/raw/build/logs.chromium.org/flutter/led/xilaizhang_google.com/dd35e456014e3ea3360ba3ffadd9dc565abc8213d7076dd45c1774e49c0a87eb/+/build.proto?server=chromium-swarm.appspot.com
12/12 led run: https://ci.chromium.org/raw/build/logs.chromium.org/flutter/led/xilaizhang_google.com/2be4003ab0497daf0e90f84cd6e74a2cdaaa00cf1b6783c9e759386bfdb93afb/+/build.proto?server=chromium-swarm.appspot.com
12/02 led run: https://luci-milo.appspot.com/raw/build/logs.chromium.org/flutter/led/xilaizhang_google.com/8d785d3c27550b0524c00d5ae1ed278721b587ce2c3b7528b952d1889c43bc1a/+/build.proto
Change-Id: I55eeae2bec1ca765006d9d4d2b606299ff5c7e7a
Reviewed-on: https://flutter-review.googlesource.com/c/recipes/+/35322
Reviewed-by: Godofredo Contreras <godofredoc@google.com>
Commit-Queue: Xilai Zhang <xilaizhang@google.com>
diff --git a/recipe_modules/flutter_deps/api.py b/recipe_modules/flutter_deps/api.py
index 7ed10df..4ffd3d2 100644
--- a/recipe_modules/flutter_deps/api.py
+++ b/recipe_modules/flutter_deps/api.py
@@ -417,11 +417,8 @@
env(dict): Current environment variables.
env_prefixes(dict): Current environment prefixes variables.
"""
- if version != 'latest':
- msg = 'codesign version is None.'
- raise ValueError(msg)
version = version or 'latest'
- codesign_path = self.m.path.mkdtemp().join('codesign')
+ codesign_path = self.m.path.mkdtemp()
codesign = self.m.cipd.EnsureFile()
codesign.add_package('flutter/codesign/${platform}', version)
with self.m.step.nest('Installing Mac codesign CIPD pkg'):
@@ -429,6 +426,7 @@
paths = env_prefixes.get('PATH', [])
paths.append(codesign_path)
env_prefixes['PATH'] = paths
+ return codesign_path.join('codesign')
def cosign(self, env, env_prefixes, version=None):
"""Installs cosign.
diff --git a/recipe_modules/flutter_deps/examples/full.expected/basic.json b/recipe_modules/flutter_deps/examples/full.expected/basic.json
index 54c4ba7..fd5dfcd 100644
--- a/recipe_modules/flutter_deps/examples/full.expected/basic.json
+++ b/recipe_modules/flutter_deps/examples/full.expected/basic.json
@@ -414,7 +414,7 @@
"cipd",
"ensure",
"-root",
- "[CLEANUP]/tmp_tmp_1/codesign",
+ "[CLEANUP]/tmp_tmp_1",
"-ensure-file",
"flutter/codesign/${platform} latest",
"-max-threads",
@@ -760,7 +760,7 @@
"[CLEANUP]/go_path/bin",
"[START_DIR]/firebase",
"[CACHE]/cmake/bin",
- "[CLEANUP]/tmp_tmp_1/codesign",
+ "[CLEANUP]/tmp_tmp_1",
"[CACHE]/cosign/bin",
"[CACHE]/ninja",
"[CACHE]/clang/bin",
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 5b33f44..394e273 100644
--- a/recipe_modules/flutter_deps/examples/full.expected/flutter_engine.json
+++ b/recipe_modules/flutter_deps/examples/full.expected/flutter_engine.json
@@ -498,7 +498,7 @@
"cipd",
"ensure",
"-root",
- "[CLEANUP]/tmp_tmp_1/codesign",
+ "[CLEANUP]/tmp_tmp_1",
"-ensure-file",
"flutter/codesign/${platform} latest",
"-max-threads",
@@ -846,7 +846,7 @@
"[CLEANUP]/go_path/bin",
"[START_DIR]/firebase",
"[CACHE]/cmake/bin",
- "[CLEANUP]/tmp_tmp_1/codesign",
+ "[CLEANUP]/tmp_tmp_1",
"[CACHE]/cosign/bin",
"[CACHE]/ninja",
"[CACHE]/clang/bin",
diff --git a/recipe_modules/flutter_deps/examples/full.expected/goldTryjob.json b/recipe_modules/flutter_deps/examples/full.expected/goldTryjob.json
index 54c4ba7..fd5dfcd 100644
--- a/recipe_modules/flutter_deps/examples/full.expected/goldTryjob.json
+++ b/recipe_modules/flutter_deps/examples/full.expected/goldTryjob.json
@@ -414,7 +414,7 @@
"cipd",
"ensure",
"-root",
- "[CLEANUP]/tmp_tmp_1/codesign",
+ "[CLEANUP]/tmp_tmp_1",
"-ensure-file",
"flutter/codesign/${platform} latest",
"-max-threads",
@@ -760,7 +760,7 @@
"[CLEANUP]/go_path/bin",
"[START_DIR]/firebase",
"[CACHE]/cmake/bin",
- "[CLEANUP]/tmp_tmp_1/codesign",
+ "[CLEANUP]/tmp_tmp_1",
"[CACHE]/cosign/bin",
"[CACHE]/ninja",
"[CACHE]/clang/bin",
diff --git a/recipe_modules/flutter_deps/examples/full.expected/linux.json b/recipe_modules/flutter_deps/examples/full.expected/linux.json
index 54c4ba7..fd5dfcd 100644
--- a/recipe_modules/flutter_deps/examples/full.expected/linux.json
+++ b/recipe_modules/flutter_deps/examples/full.expected/linux.json
@@ -414,7 +414,7 @@
"cipd",
"ensure",
"-root",
- "[CLEANUP]/tmp_tmp_1/codesign",
+ "[CLEANUP]/tmp_tmp_1",
"-ensure-file",
"flutter/codesign/${platform} latest",
"-max-threads",
@@ -760,7 +760,7 @@
"[CLEANUP]/go_path/bin",
"[START_DIR]/firebase",
"[CACHE]/cmake/bin",
- "[CLEANUP]/tmp_tmp_1/codesign",
+ "[CLEANUP]/tmp_tmp_1",
"[CACHE]/cosign/bin",
"[CACHE]/ninja",
"[CACHE]/clang/bin",
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 c3d4e15..c21da3c 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
@@ -498,7 +498,7 @@
"cipd",
"ensure",
"-root",
- "[CLEANUP]/tmp_tmp_1/codesign",
+ "[CLEANUP]/tmp_tmp_1",
"-ensure-file",
"flutter/codesign/${platform} latest",
"-max-threads",
@@ -846,7 +846,7 @@
"[CLEANUP]/go_path/bin",
"[START_DIR]/firebase",
"[CACHE]/cmake/bin",
- "[CLEANUP]/tmp_tmp_1/codesign",
+ "[CLEANUP]/tmp_tmp_1",
"[CACHE]/cosign/bin",
"[CACHE]/ninja",
"[CACHE]/clang/bin",
diff --git a/recipe_modules/flutter_deps/examples/full.expected/mac.json b/recipe_modules/flutter_deps/examples/full.expected/mac.json
index 3a19982..61a1746 100644
--- a/recipe_modules/flutter_deps/examples/full.expected/mac.json
+++ b/recipe_modules/flutter_deps/examples/full.expected/mac.json
@@ -476,7 +476,7 @@
"cipd",
"ensure",
"-root",
- "[CLEANUP]/tmp_tmp_1/codesign",
+ "[CLEANUP]/tmp_tmp_1",
"-ensure-file",
"flutter/codesign/${platform} latest",
"-max-threads",
diff --git a/recipe_modules/flutter_deps/examples/full.expected/windows.json b/recipe_modules/flutter_deps/examples/full.expected/windows.json
index 4f7e5a0..5fc963f 100644
--- a/recipe_modules/flutter_deps/examples/full.expected/windows.json
+++ b/recipe_modules/flutter_deps/examples/full.expected/windows.json
@@ -414,7 +414,7 @@
"cipd.bat",
"ensure",
"-root",
- "[CLEANUP]\\tmp_tmp_1\\codesign",
+ "[CLEANUP]\\tmp_tmp_1",
"-ensure-file",
"flutter/codesign/${platform} latest",
"-max-threads",
@@ -725,7 +725,7 @@
"[CLEANUP]\\go_path\\bin",
"[START_DIR]\\firebase",
"[CACHE]\\cmake\\bin",
- "[CLEANUP]\\tmp_tmp_1\\codesign",
+ "[CLEANUP]\\tmp_tmp_1",
"[CACHE]\\cosign\\bin",
"[CACHE]\\ninja",
"[CACHE]\\clang\\bin",
@@ -801,7 +801,7 @@
"[CLEANUP]\\go_path\\bin",
"[START_DIR]\\firebase",
"[CACHE]\\cmake\\bin",
- "[CLEANUP]\\tmp_tmp_1\\codesign",
+ "[CLEANUP]\\tmp_tmp_1",
"[CACHE]\\cosign\\bin",
"[CACHE]\\ninja",
"[CACHE]\\clang\\bin",
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 25c37cd..782134b 100644
--- a/recipe_modules/flutter_deps/examples/full.expected/with-arm64ruby.json
+++ b/recipe_modules/flutter_deps/examples/full.expected/with-arm64ruby.json
@@ -414,7 +414,7 @@
"cipd",
"ensure",
"-root",
- "[CLEANUP]/tmp_tmp_1/codesign",
+ "[CLEANUP]/tmp_tmp_1",
"-ensure-file",
"flutter/codesign/${platform} latest",
"-max-threads",
@@ -760,7 +760,7 @@
"[CLEANUP]/go_path/bin",
"[START_DIR]/firebase",
"[CACHE]/cmake/bin",
- "[CLEANUP]/tmp_tmp_1/codesign",
+ "[CLEANUP]/tmp_tmp_1",
"[CACHE]/cosign/bin",
"[CACHE]/ninja",
"[CACHE]/clang/bin",
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 e409a1d..d9c7054 100644
--- a/recipe_modules/flutter_deps/examples/full.expected/with-gems.json
+++ b/recipe_modules/flutter_deps/examples/full.expected/with-gems.json
@@ -414,7 +414,7 @@
"cipd",
"ensure",
"-root",
- "[CLEANUP]/tmp_tmp_1/codesign",
+ "[CLEANUP]/tmp_tmp_1",
"-ensure-file",
"flutter/codesign/${platform} latest",
"-max-threads",
@@ -760,7 +760,7 @@
"[CLEANUP]/go_path/bin",
"[START_DIR]/firebase",
"[CACHE]/cmake/bin",
- "[CLEANUP]/tmp_tmp_1/codesign",
+ "[CLEANUP]/tmp_tmp_1",
"[CACHE]/cosign/bin",
"[CACHE]/ninja",
"[CACHE]/clang/bin",
diff --git a/recipe_modules/flutter_deps/examples/full.py b/recipe_modules/flutter_deps/examples/full.py
index a6d85b3..12f3bf7 100644
--- a/recipe_modules/flutter_deps/examples/full.py
+++ b/recipe_modules/flutter_deps/examples/full.py
@@ -55,8 +55,6 @@
api.flutter_deps.flutter_engine(env, env_prefixes)
api.flutter_deps.firebase(env, env_prefixes)
api.flutter_deps.cmake(env, env_prefixes)
- with api.assertions.assertRaises(ValueError):
- api.flutter_deps.codesign(env, env_prefixes)
api.flutter_deps.codesign(env, env_prefixes, 'latest')
api.flutter_deps.cosign(env, env_prefixes)
api.flutter_deps.ninja(env, env_prefixes)
diff --git a/recipes/engine_v2/signer.expected/config_from_file.json b/recipes/engine_v2/signer.expected/config_from_file.json
index 8de884f..f4441a2 100644
--- a/recipes/engine_v2/signer.expected/config_from_file.json
+++ b/recipes/engine_v2/signer.expected/config_from_file.json
@@ -15,7 +15,7 @@
"cipd",
"ensure",
"-root",
- "[CLEANUP]/tmp_tmp_1/codesign",
+ "[CLEANUP]/tmp_tmp_1",
"-ensure-file",
"flutter/codesign/${platform} latest",
"-max-threads",
@@ -41,20 +41,282 @@
},
{
"cmd": [
- "codesign",
- "--gcs-download-path",
- "gs://a/b/c/artifact.zip",
- "--gcs-upload-path",
- "gs://a/b/c/artifact.zip"
+ "cipd",
+ "ensure",
+ "-root",
+ "[START_DIR]/cloudkms",
+ "-ensure-file",
+ "infra/tools/luci/cloudkms/${platform} latest",
+ "-max-threads",
+ "0",
+ "-json-output",
+ "/path/to/tmp/json"
+ ],
+ "name": "ensure_installed",
+ "~followup_annotations": [
+ "@@@STEP_LOG_LINE@json.output@{@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"result\": {@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"\": [@@@",
+ "@@@STEP_LOG_LINE@json.output@ {@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"instance_id\": \"resolved-instance_id-of-latest----------\", @@@",
+ "@@@STEP_LOG_LINE@json.output@ \"package\": \"infra/tools/luci/cloudkms/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": [
+ "python3",
+ "-u",
+ "RECIPE_MODULE[depot_tools::gsutil]/resources/gsutil_smart_retry.py",
+ "--",
+ "RECIPE_REPO[depot_tools]/gsutil.py",
+ "----",
+ "cp",
+ "gs://flutter_configs/codesign_team_id.encrypted",
+ "[CLEANUP]/codesign_team_id.encrypted"
+ ],
+ "infra_step": true,
+ "name": "gsutil download"
+ },
+ {
+ "cmd": [
+ "[START_DIR]/cloudkms/cloudkms",
+ "decrypt",
+ "-input",
+ "[CLEANUP]/codesign_team_id.encrypted",
+ "-output",
+ "[CLEANUP]/tmp_tmp_2/codesign_team_id.encrypted",
+ "projects/flutter-infra-staging/locations/global/keyRings/luci/cryptoKeys/flutter-infra"
+ ],
+ "name": "cloudkms get key"
+ },
+ {
+ "cmd": [
+ "cipd",
+ "ensure",
+ "-root",
+ "[START_DIR]/cloudkms",
+ "-ensure-file",
+ "infra/tools/luci/cloudkms/${platform} latest",
+ "-max-threads",
+ "0",
+ "-json-output",
+ "/path/to/tmp/json"
+ ],
+ "name": "ensure_installed (2)",
+ "~followup_annotations": [
+ "@@@STEP_LOG_LINE@json.output@{@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"result\": {@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"\": [@@@",
+ "@@@STEP_LOG_LINE@json.output@ {@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"instance_id\": \"resolved-instance_id-of-latest----------\", @@@",
+ "@@@STEP_LOG_LINE@json.output@ \"package\": \"infra/tools/luci/cloudkms/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": [
+ "python3",
+ "-u",
+ "RECIPE_MODULE[depot_tools::gsutil]/resources/gsutil_smart_retry.py",
+ "--",
+ "RECIPE_REPO[depot_tools]/gsutil.py",
+ "----",
+ "cp",
+ "gs://flutter_configs/codesign_app_specific_password.encrypted",
+ "[CLEANUP]/codesign_app_specific_password.encrypted"
+ ],
+ "infra_step": true,
+ "name": "gsutil download (2)"
+ },
+ {
+ "cmd": [
+ "[START_DIR]/cloudkms/cloudkms",
+ "decrypt",
+ "-input",
+ "[CLEANUP]/codesign_app_specific_password.encrypted",
+ "-output",
+ "[CLEANUP]/tmp_tmp_2/codesign_app_specific_password.encrypted",
+ "projects/flutter-infra-staging/locations/global/keyRings/luci/cryptoKeys/flutter-infra"
+ ],
+ "name": "cloudkms get key (2)"
+ },
+ {
+ "cmd": [
+ "cipd",
+ "ensure",
+ "-root",
+ "[START_DIR]/cloudkms",
+ "-ensure-file",
+ "infra/tools/luci/cloudkms/${platform} latest",
+ "-max-threads",
+ "0",
+ "-json-output",
+ "/path/to/tmp/json"
+ ],
+ "name": "ensure_installed (3)",
+ "~followup_annotations": [
+ "@@@STEP_LOG_LINE@json.output@{@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"result\": {@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"\": [@@@",
+ "@@@STEP_LOG_LINE@json.output@ {@@@",
+ "@@@STEP_LOG_LINE@json.output@ \"instance_id\": \"resolved-instance_id-of-latest----------\", @@@",
+ "@@@STEP_LOG_LINE@json.output@ \"package\": \"infra/tools/luci/cloudkms/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": [
+ "python3",
+ "-u",
+ "RECIPE_MODULE[depot_tools::gsutil]/resources/gsutil_smart_retry.py",
+ "--",
+ "RECIPE_REPO[depot_tools]/gsutil.py",
+ "----",
+ "cp",
+ "gs://flutter_configs/codesign_app_store_id.encrypted",
+ "[CLEANUP]/codesign_app_store_id.encrypted"
+ ],
+ "infra_step": true,
+ "name": "gsutil download (3)"
+ },
+ {
+ "cmd": [
+ "[START_DIR]/cloudkms/cloudkms",
+ "decrypt",
+ "-input",
+ "[CLEANUP]/codesign_app_store_id.encrypted",
+ "-output",
+ "[CLEANUP]/tmp_tmp_2/codesign_app_store_id.encrypted",
+ "projects/flutter-infra-staging/locations/global/keyRings/luci/cryptoKeys/flutter-infra"
+ ],
+ "name": "cloudkms get key (3)"
+ },
+ {
+ "cmd": [
+ "chmod",
+ "755",
+ "RECIPE[flutter::engine_v2/signer].resources/runner.sh"
],
"env_prefixes": {
"PATH": [
- "[CLEANUP]/tmp_tmp_1/codesign"
+ "[CLEANUP]/tmp_tmp_1"
+ ]
+ },
+ "name": "Set execute permission"
+ },
+ {
+ "cmd": [
+ "bash",
+ "RECIPE[flutter::engine_v2/signer].resources/runner.sh"
+ ],
+ "env_prefixes": {
+ "PATH": [
+ "[CLEANUP]/tmp_tmp_1"
+ ]
+ },
+ "name": "unlock keychain"
+ },
+ {
+ "cmd": [
+ "python3",
+ "-u",
+ "RECIPE_MODULE[depot_tools::gsutil]/resources/gsutil_smart_retry.py",
+ "--",
+ "RECIPE_REPO[depot_tools]/gsutil.py",
+ "----",
+ "cp",
+ "gs://a/b/c/artifact.zip",
+ "[CLEANUP]/tmp_tmp_3/unsigned_artifact.zip"
+ ],
+ "infra_step": true,
+ "name": "gsutil download gs://a/b/c/artifact.zip"
+ },
+ {
+ "cmd": [
+ "[CLEANUP]/tmp_tmp_1/codesign",
+ "--codesign-cert-name",
+ "FLUTTER.IO LLC",
+ "--no-dryrun",
+ "--app-specific-password-file-path",
+ "[CLEANUP]/tmp_tmp_2/codesign_app_specific_password.encrypted",
+ "--codesign-appstore-id-file-path",
+ "[CLEANUP]/tmp_tmp_2/codesign_app_store_id.encrypted",
+ "--codesign-team-id-file-path",
+ "[CLEANUP]/tmp_tmp_2/codesign_team_id.encrypted",
+ "--input-zip-file-path",
+ "[CLEANUP]/tmp_tmp_3/unsigned_artifact.zip",
+ "--output-zip-file-path",
+ "[CLEANUP]/tmp_tmp_3/artifact.zip"
+ ],
+ "env_prefixes": {
+ "PATH": [
+ "[CLEANUP]/tmp_tmp_1"
]
},
"name": "codesign Apple engine binaries"
},
{
+ "cmd": [
+ "vpython3",
+ "-u",
+ "RECIPE_MODULE[recipe_engine::file]/resources/fileutil.py",
+ "--json-output",
+ "/path/to/tmp/json",
+ "ensure-directory",
+ "--mode",
+ "0777",
+ "[CLEANUP]/tmp_tmp_4/b/c"
+ ],
+ "infra_step": true,
+ "name": "Ensure b/c"
+ },
+ {
+ "cmd": [
+ "vpython3",
+ "-u",
+ "RECIPE_MODULE[recipe_engine::file]/resources/fileutil.py",
+ "--json-output",
+ "/path/to/tmp/json",
+ "copy",
+ "[CLEANUP]/tmp_tmp_3/artifact.zip",
+ "[CLEANUP]/tmp_tmp_4/b/c"
+ ],
+ "infra_step": true,
+ "name": "Copy gs://a/b/c/artifact.zip"
+ },
+ {
+ "cmd": [
+ "python3",
+ "-u",
+ "RECIPE_MODULE[depot_tools::gsutil]/resources/gsutil_smart_retry.py",
+ "--",
+ "RECIPE_REPO[depot_tools]/gsutil.py",
+ "----",
+ "cp",
+ "-r",
+ "[CLEANUP]/tmp_tmp_4/*",
+ "gs://a/"
+ ],
+ "infra_step": true,
+ "name": "gsutil b/c/artifact.zip",
+ "~followup_annotations": [
+ "@@@STEP_LINK@gsutil.upload@https://console.cloud.google.com/storage/browser/a/@@@"
+ ]
+ },
+ {
"name": "$result"
}
]
\ No newline at end of file
diff --git a/recipes/engine_v2/signer.py b/recipes/engine_v2/signer.py
index f804fd4..a9740cd 100644
--- a/recipes/engine_v2/signer.py
+++ b/recipes/engine_v2/signer.py
@@ -2,15 +2,34 @@
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
+# Recipe that executes apple code signing on a code signing bot. A code
+# signing bot is a machine with flutter certificates and signing related
+# set ups.
+#
+# This recipe receives as properties the list of google cloud bucket paths
+# of engine artifacts, and reads code sign related passwords from
+# kms securely. The engine artifact bucket paths and codesign credentials
+# are then supplied to a codesign standalone app, which communicates with
+# Apple notary server to finish code signing. The codesign standalone app
+# is run as a cipd package, and the codesigned artifacts are uploaded back
+# to the same google cloud bucket path.
+
DEPS = [
+ 'depot_tools/gsutil',
+ 'flutter/archives',
'flutter/flutter_deps',
'recipe_engine/context',
'recipe_engine/futures',
+ 'flutter/kms',
+ 'flutter/osx_sdk',
+ 'recipe_engine/file',
+ 'recipe_engine/path',
'recipe_engine/platform',
'recipe_engine/properties',
'recipe_engine/step',
]
+
def RunSteps(api):
if not api.platform.is_mac:
pass
@@ -19,32 +38,100 @@
env = {}
env_prefixes = {}
with api.step.nest('Dependencies'):
- codesign_deps = api.properties.get('dependencies')
- api.flutter_deps.required_deps(env, env_prefixes, codesign_deps)
+ codesign_path = api.flutter_deps.codesign(env, env_prefixes)
# The list is iterated running one signer tool command per file. This can be
# optimized using the multiprocessing API.
- final_list = api.properties.get('signing_file_list', [])
+ final_sources_list = api.properties.get('signing_file_list', [])
signer_builds = []
- for gcsPath in final_list:
- signer_builds.append(
- api.futures.spawn(RunSignerToolCommand, api, env, env_prefixes, gcsPath, gcsPath)
- )
- futures = api.futures.wait(signer_builds)
- for future in futures:
- future.result()
+ codesign_dir = api.path.mkdtemp()
+ app_specific_password_filepath = codesign_dir.join(
+ 'codesign_app_specific_password.encrypted'
+ )
+ appstore_id_filepath = codesign_dir.join('codesign_app_store_id.encrypted')
+ team_id_filepath = codesign_dir.join('codesign_team_id.encrypted')
+ api.kms.get_secret('codesign_team_id.encrypted', team_id_filepath)
+ api.kms.get_secret(
+ 'codesign_app_specific_password.encrypted', app_specific_password_filepath
+ )
+ api.kms.get_secret('codesign_app_store_id.encrypted', appstore_id_filepath)
+ # unlock keychain
+ with api.context(env=env, env_prefixes=env_prefixes):
+ resource_name = api.resource('runner.sh')
+ api.step('Set execute permission', ['chmod', '755', resource_name])
+ cmd = ['bash', resource_name]
+ api.step('unlock keychain', cmd)
-def RunSignerToolCommand(api, env, env_prefixes, gcsDownloadPath, gcsUploadPath):
+ # keep track of the output zip files in separate temp folders to avoid name conflicts
+ output_zips = {}
+
+ codesign_string_path = "%s" % codesign_path
+ with api.osx_sdk('ios'):
+ for source_path in final_sources_list:
+ input_tmp_folder = api.path.mkdtemp()
+ _, artifact_base_name = api.path.split(source_path)
+ local_zip_path = input_tmp_folder.join('unsigned_%s' % artifact_base_name)
+ local_zip_string_path = str(local_zip_path)
+
+ output_zip_path = input_tmp_folder.join(artifact_base_name)
+ output_zip_string_path = str(output_zip_path)
+ output_zips[source_path] = output_zip_string_path
+ api.archives.download(source_path, local_zip_path)
+ signer_builds.append(
+ api.futures.spawn(
+ RunSignerToolCommand, api, env, env_prefixes,
+ local_zip_string_path, output_zip_string_path,
+ app_specific_password_filepath, appstore_id_filepath,
+ team_id_filepath, codesign_string_path
+ )
+ )
+
+ futures = api.futures.wait(signer_builds)
+ for future in futures:
+ future.result()
+
+ for source_path, output_zip_path in output_zips.items():
+ api.archives.upload_artifact(src=output_zip_path, dst=source_path)
+
+def RunSignerToolCommand(
+ api, env, env_prefixes, input_zip_string_path, output_zip_string_path,
+ app_specific_password_filepath, appstore_id_filepath, team_id_filepath,
+ codesign_string_path
+):
+ """Runs code sign standalone app.
+
+ Args:
+ input_zip_string_path (str): path of the unsigned artifact in the file system.
+ output_zip_string_path (str): path of the signed artifact in the file system.
+ app_specific_password_filepath (str) : path of app specific password, one of
+ the code sign credentials.
+ appstore_id_filepath (str) : path of apple store id, one of the codesign
+ credentials.
+ team_id_filepath (str) : path of flutter team id used for codesign, one of the
+ codesign credentials.
+ codesign_string_path (str): the absolute path of the codesign standalone app
+ cipd package. This is to differentiate codesign cipd from mac system codesign.
+ """
+ flutter_certificate_name = 'FLUTTER.IO LLC'
with api.context(env=env, env_prefixes=env_prefixes):
api.step(
'codesign Apple engine binaries',
[
- 'codesign',
- '--gcs-download-path',
- gcsDownloadPath,
- '--gcs-upload-path',
- gcsUploadPath,
+ codesign_string_path,
+ '--codesign-cert-name',
+ flutter_certificate_name,
+ '--no-dryrun',
+ '--app-specific-password-file-path',
+ app_specific_password_filepath,
+ '--codesign-appstore-id-file-path',
+ appstore_id_filepath,
+ '--codesign-team-id-file-path',
+ team_id_filepath,
+ '--input-zip-file-path',
+ input_zip_string_path,
+ '--output-zip-file-path',
+ output_zip_string_path,
],
)
@@ -58,7 +145,6 @@
'dependency': 'codesign',
'version': 'latest',
}],
- signing_file_list = ["gs://a/b/c/artifact.zip"]
+ signing_file_list=["gs://a/b/c/artifact.zip"]
)
)
-
diff --git a/recipes/engine_v2/signer.resources/runner.sh b/recipes/engine_v2/signer.resources/runner.sh
new file mode 100644
index 0000000..a35286d
--- /dev/null
+++ b/recipes/engine_v2/signer.resources/runner.sh
@@ -0,0 +1,12 @@
+#!/bin/bash
+
+# Helper script to unlock the keychain in the same session
+# as the test runner script.
+set -e
+
+if [ -f /usr/local/bin/unlock_login_keychain.sh ]
+then
+ /usr/local/bin/unlock_login_keychain.sh
+else
+ echo "This bot does not support codesigning"
+fi
\ No newline at end of file