Signer recipe command line migration led run 03/27 patchset 22: https://ci.chromium.org/raw/build/logs.chromium.org/flutter/led/xilaizhang_google.com/b6f51d410a2f26fb1766b10e844afc80fb5e2b7cc4282ea57be6e822ee6a5a04/+/build.proto?server=chromium-swarm.appspot.com led run 03/27 patchset 20: https://ci.chromium.org/raw/build/logs.chromium.org/flutter/led/xilaizhang_google.com/4afa328e0dcfa2fbbf7f11934c97aebf5d0991eb644402e4bf499e2055619b80/+/build.proto?server=chromium-swarm.appspot.com led run 03/27 patchset 18: https://ci.chromium.org/raw/build/logs.chromium.org/flutter/led/xilaizhang_google.com/af2c80b6a1f57ac57b6a5d7dd12409a15274f455644a824f6f454b90f8826abd/+/build.proto?server=chromium-swarm.appspot.com led run 03/27 patchset 16: https://ci.chromium.org/raw/build/logs.chromium.org/flutter/led/xilaizhang_google.com/a3f8a69d36d1009faa73eb6d42f734f06a065540cca9c3f54ee8c25865f326e2/+/build.proto?server=chromium-swarm.appspot.com led run 03/27 patchset 13: https://ci.chromium.org/raw/build/logs.chromium.org/flutter/led/xilaizhang_google.com/e7d129d8f49afacf8f06fedd6210be2ad3d9aa668ffae39adb74898a0f3a53bd/+/build.proto?server=chromium-swarm.appspot.com led run 03/25 patchset 11: https://ci.chromium.org/raw/build/logs.chromium.org/flutter/led/xilaizhang_google.com/a44ca0c6a64e82c384d0f4612effcda2581029e5fe7dfd542653b624cd053ebf/+/build.proto?server=chromium-swarm.appspot.com led run 03/25 patchset 9: https://ci.chromium.org/raw/build/logs.chromium.org/flutter/led/xilaizhang_google.com/3e3be689bac963a2e85a79afda1eaafb6ab416726fa9a1683f11d17652162f0d/+/build.proto?server=chromium-swarm.appspot.com led run 03/25 patchset 6: https://ci.chromium.org/raw/build/logs.chromium.org/flutter/led/xilaizhang_google.com/6ea9024db20773d52a967e72870c07cc0544c8eaa51b38bbd58286e3a6694ec1/+/build.proto?server=chromium-swarm.appspot.com led run 03/24 patchset 3: https://ci.chromium.org/raw/build/logs.chromium.org/flutter/led/xilaizhang_google.com/875f0539a3fddcf8741248198f5314428557248708678f04aef8e3c292b48d66/+/build.proto?server=chromium-swarm.appspot.com led run 03/24 patchset 1: https://ci.chromium.org/raw/build/logs.chromium.org/flutter/led/xilaizhang_google.com/7554c4be4b1f8afda3db337c7cca605bc4ff3791d76b473050b55539e1316dd2/+/build.proto?server=chromium-swarm.appspot.com scheduled with: led get build <mac host engine at engine head> | led edit-recipe-bundle | led edit-system -p 20 | led launch Once this lands, the next step is to push engine_v2 recipe to finish. Change-Id: Ie564477abedac60235bac0c51f5513c35f9e9bf9 Reviewed-on: https://flutter-review.googlesource.com/c/recipes/+/41123 Reviewed-by: Godofredo Contreras <godofredoc@google.com> Commit-Queue: Xilai Zhang <xilaizhang@google.com>
diff --git a/.style.yapf b/.style.yapf index 3c79e54..a4860f7 100644 --- a/.style.yapf +++ b/.style.yapf
@@ -9,3 +9,4 @@ dedent_closing_brackets = true coalesce_brackets = true each_dict_entry_on_separate_line = false +column_limit: 80
diff --git a/recipe_modules/kms/api.py b/recipe_modules/kms/api.py index 5eac74e..ad9c269 100644 --- a/recipe_modules/kms/api.py +++ b/recipe_modules/kms/api.py
@@ -45,7 +45,7 @@ Args: env(dict): Current environment variables. - secrets(dict): The key is the n. me of the env variable referencing the + secrets(dict): The key is the name of the env variable referencing the decrypted file and the value is the path to the encrypted file in gcs. """ for k, v in secrets.items():
diff --git a/recipes/engine_v2/signer.expected/config_from_file.json b/recipes/engine_v2/signer.expected/config_from_file.json index f8c2f61..1a8e114 100644 --- a/recipes/engine_v2/signer.expected/config_from_file.json +++ b/recipes/engine_v2/signer.expected/config_from_file.json
@@ -76,8 +76,8 @@ "RECIPE_REPO[depot_tools]/gsutil.py", "----", "cp", - "gs://flutter_configs/codesign_team_id.encrypted", - "[CLEANUP]/codesign_team_id.encrypted" + "gs://flutter_configs/flutter_p12.encrypted", + "[CLEANUP]/flutter_p12.encrypted" ], "infra_step": true, "name": "gsutil download" @@ -87,9 +87,9 @@ "[START_DIR]/cloudkms/cloudkms", "decrypt", "-input", - "[CLEANUP]/codesign_team_id.encrypted", + "[CLEANUP]/flutter_p12.encrypted", "-output", - "[CLEANUP]/tmp_tmp_2/codesign_team_id.encrypted", + "[CLEANUP]/FLUTTER_P12", "projects/flutter-infra-staging/locations/global/keyRings/luci/cryptoKeys/flutter-infra" ], "name": "cloudkms get key" @@ -131,8 +131,8 @@ "RECIPE_REPO[depot_tools]/gsutil.py", "----", "cp", - "gs://flutter_configs/codesign_app_specific_password.encrypted", - "[CLEANUP]/codesign_app_specific_password.encrypted" + "gs://flutter_configs/p12_password.encrypted", + "[CLEANUP]/p12_password.encrypted" ], "infra_step": true, "name": "gsutil download (2)" @@ -142,9 +142,9 @@ "[START_DIR]/cloudkms/cloudkms", "decrypt", "-input", - "[CLEANUP]/codesign_app_specific_password.encrypted", + "[CLEANUP]/p12_password.encrypted", "-output", - "[CLEANUP]/tmp_tmp_2/codesign_app_specific_password.encrypted", + "[CLEANUP]/FLUTTER_P12_PASSWORD", "projects/flutter-infra-staging/locations/global/keyRings/luci/cryptoKeys/flutter-infra" ], "name": "cloudkms get key (2)" @@ -186,8 +186,8 @@ "RECIPE_REPO[depot_tools]/gsutil.py", "----", "cp", - "gs://flutter_configs/codesign_app_store_id.encrypted", - "[CLEANUP]/codesign_app_store_id.encrypted" + "gs://flutter_configs/codesign_team_id.encrypted", + "[CLEANUP]/codesign_team_id.encrypted" ], "infra_step": true, "name": "gsutil download (3)" @@ -197,37 +197,209 @@ "[START_DIR]/cloudkms/cloudkms", "decrypt", "-input", - "[CLEANUP]/codesign_app_store_id.encrypted", + "[CLEANUP]/codesign_team_id.encrypted", "-output", - "[CLEANUP]/tmp_tmp_2/codesign_app_store_id.encrypted", + "[CLEANUP]/CODESIGN_TEAM_ID", "projects/flutter-infra-staging/locations/global/keyRings/luci/cryptoKeys/flutter-infra" ], "name": "cloudkms get key (3)" }, { "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 (4)", + "~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 (4)" + }, + { + "cmd": [ + "[START_DIR]/cloudkms/cloudkms", + "decrypt", + "-input", + "[CLEANUP]/codesign_app_specific_password.encrypted", + "-output", + "[CLEANUP]/CODESIGN_APP_SPECIFIC_PASSWORD", + "projects/flutter-infra-staging/locations/global/keyRings/luci/cryptoKeys/flutter-infra" + ], + "name": "cloudkms get key (4)" + }, + { + "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 (5)", + "~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 (5)" + }, + { + "cmd": [ + "[START_DIR]/cloudkms/cloudkms", + "decrypt", + "-input", + "[CLEANUP]/codesign_app_store_id.encrypted", + "-output", + "[CLEANUP]/CODESIGN_APP_STORE_ID", + "projects/flutter-infra-staging/locations/global/keyRings/luci/cryptoKeys/flutter-infra" + ], + "name": "cloudkms get key (5)" + }, + { + "cmd": [ + "security", + "delete-keychain", + "build.keychain" + ], + "name": "delete previous keychain" + }, + { + "cmd": [ + "security", + "create-keychain", + "-p", + "", + "build.keychain" + ], + "name": "create keychain" + }, + { + "cmd": [ + "security", + "default-keychain", + "-s", + "build.keychain" + ], + "name": "default keychain" + }, + { + "cmd": [ + "security", + "unlock-keychain", + "-p", + "", + "build.keychain" + ], + "name": "unlock build keychain" + }, + { + "cmd": [ "chmod", "755", - "RECIPE[flutter::engine_v2/signer].resources/runner.sh" + "RECIPE[flutter::engine_v2/signer].resources/import_certificate.sh" ], - "env_prefixes": { - "PATH": [ - "[CLEANUP]/tmp_tmp_1" - ] - }, + "infra_step": true, "name": "Set execute permission" }, { "cmd": [ - "bash", - "RECIPE[flutter::engine_v2/signer].resources/runner.sh" + "RECIPE[flutter::engine_v2/signer].resources/import_certificate.sh" ], + "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" + }, "env_prefixes": { "PATH": [ "[CLEANUP]/tmp_tmp_1" ] }, - "name": "unlock keychain" + "name": "import certificate" + }, + { + "cmd": [ + "security", + "set-key-partition-list", + "-S", + "apple-tool:,apple:,codesign:", + "-s", + "-k", + "", + "build.keychain" + ], + "name": "set key partition list" + }, + { + "cmd": [ + "security", + "find-identity", + "-v" + ], + "name": "show-identities" }, { "cmd": [ @@ -239,28 +411,47 @@ "----", "cp", "gs://a/b/c/artifact.zip", - "[CLEANUP]/tmp_tmp_3/unsigned_artifact.zip" + "[CLEANUP]/tmp_tmp_2/unsigned_artifact.zip" ], "infra_step": true, "name": "gsutil download gs://a/b/c/artifact.zip" }, { "cmd": [ + "security", + "unlock-keychain", + "-p", + "", + "build.keychain" + ], + "name": "unlock build keychain (2)" + }, + { + "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", + "[CLEANUP]/CODESIGN_APP_SPECIFIC_PASSWORD", "--codesign-appstore-id-file-path", - "[CLEANUP]/tmp_tmp_2/codesign_app_store_id.encrypted", + "[CLEANUP]/CODESIGN_APP_STORE_ID", "--codesign-team-id-file-path", - "[CLEANUP]/tmp_tmp_2/codesign_team_id.encrypted", + "[CLEANUP]/CODESIGN_TEAM_ID", "--input-zip-file-path", - "[CLEANUP]/tmp_tmp_3/unsigned_artifact.zip", + "[CLEANUP]/tmp_tmp_2/unsigned_artifact.zip", "--output-zip-file-path", - "[CLEANUP]/tmp_tmp_3/artifact.zip" + "[CLEANUP]/tmp_tmp_2/artifact.zip" ], + "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" + }, "env_prefixes": { "PATH": [ "[CLEANUP]/tmp_tmp_1" @@ -278,7 +469,7 @@ "ensure-directory", "--mode", "0777", - "[CLEANUP]/tmp_tmp_4/b/c" + "[CLEANUP]/tmp_tmp_3/b/c" ], "infra_step": true, "name": "Ensure b/c" @@ -291,11 +482,11 @@ "--json-output", "/path/to/tmp/json", "copy", - "[CLEANUP]/tmp_tmp_3/artifact.zip", - "[CLEANUP]/tmp_tmp_4/b/c" + "[CLEANUP]/tmp_tmp_2/artifact.zip", + "[CLEANUP]/tmp_tmp_3/b/c" ], "infra_step": true, - "name": "Copy [CLEANUP]/tmp_tmp_3/artifact.zip to tmp location" + "name": "Copy [CLEANUP]/tmp_tmp_2/artifact.zip to tmp location" }, { "cmd": [ @@ -307,16 +498,33 @@ "----", "cp", "-r", - "[CLEANUP]/tmp_tmp_4/*", + "[CLEANUP]/tmp_tmp_3/*", "gs://a/" ], "infra_step": true, - "name": "gsutil Upload [CLEANUP]/tmp_tmp_3/artifact.zip to gs://a/b/c/artifact.zip", + "name": "gsutil Upload [CLEANUP]/tmp_tmp_2/artifact.zip to gs://a/b/c/artifact.zip", "~followup_annotations": [ "@@@STEP_LINK@gsutil.upload@https://console.cloud.google.com/storage/browser/a/@@@" ] }, { + "cmd": [ + "security", + "delete-keychain", + "build.keychain" + ], + "name": "delete keychain" + }, + { + "cmd": [ + "security", + "default-keychain", + "-s", + "login.keychain" + ], + "name": "restore default keychain" + }, + { "name": "$result" } ] \ No newline at end of file
diff --git a/recipes/engine_v2/signer.expected/import_flutter_identity_failure.json b/recipes/engine_v2/signer.expected/import_flutter_identity_failure.json new file mode 100644 index 0000000..392890c --- /dev/null +++ b/recipes/engine_v2/signer.expected/import_flutter_identity_failure.json
@@ -0,0 +1,442 @@ +[ + { + "cmd": [], + "name": "Dependencies" + }, + { + "cmd": [], + "name": "Dependencies.Installing Mac codesign CIPD pkg", + "~followup_annotations": [ + "@@@STEP_NEST_LEVEL@1@@@" + ] + }, + { + "cmd": [ + "cipd", + "ensure", + "-root", + "[CLEANUP]/tmp_tmp_1", + "-ensure-file", + "flutter/codesign/${platform} latest", + "-max-threads", + "0", + "-json-output", + "/path/to/tmp/json" + ], + "name": "Dependencies.Installing Mac codesign CIPD pkg.ensure_installed", + "~followup_annotations": [ + "@@@STEP_NEST_LEVEL@2@@@", + "@@@STEP_LOG_LINE@json.output@{@@@", + "@@@STEP_LOG_LINE@json.output@ \"result\": {@@@", + "@@@STEP_LOG_LINE@json.output@ \"\": [@@@", + "@@@STEP_LOG_LINE@json.output@ {@@@", + "@@@STEP_LOG_LINE@json.output@ \"instance_id\": \"resolved-instance_id-of-latest----------\", @@@", + "@@@STEP_LOG_LINE@json.output@ \"package\": \"flutter/codesign/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": [ + "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/flutter_p12.encrypted", + "[CLEANUP]/flutter_p12.encrypted" + ], + "infra_step": true, + "name": "gsutil download" + }, + { + "cmd": [ + "[START_DIR]/cloudkms/cloudkms", + "decrypt", + "-input", + "[CLEANUP]/flutter_p12.encrypted", + "-output", + "[CLEANUP]/FLUTTER_P12", + "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/p12_password.encrypted", + "[CLEANUP]/p12_password.encrypted" + ], + "infra_step": true, + "name": "gsutil download (2)" + }, + { + "cmd": [ + "[START_DIR]/cloudkms/cloudkms", + "decrypt", + "-input", + "[CLEANUP]/p12_password.encrypted", + "-output", + "[CLEANUP]/FLUTTER_P12_PASSWORD", + "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_team_id.encrypted", + "[CLEANUP]/codesign_team_id.encrypted" + ], + "infra_step": true, + "name": "gsutil download (3)" + }, + { + "cmd": [ + "[START_DIR]/cloudkms/cloudkms", + "decrypt", + "-input", + "[CLEANUP]/codesign_team_id.encrypted", + "-output", + "[CLEANUP]/CODESIGN_TEAM_ID", + "projects/flutter-infra-staging/locations/global/keyRings/luci/cryptoKeys/flutter-infra" + ], + "name": "cloudkms get key (3)" + }, + { + "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 (4)", + "~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 (4)" + }, + { + "cmd": [ + "[START_DIR]/cloudkms/cloudkms", + "decrypt", + "-input", + "[CLEANUP]/codesign_app_specific_password.encrypted", + "-output", + "[CLEANUP]/CODESIGN_APP_SPECIFIC_PASSWORD", + "projects/flutter-infra-staging/locations/global/keyRings/luci/cryptoKeys/flutter-infra" + ], + "name": "cloudkms get key (4)" + }, + { + "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 (5)", + "~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 (5)" + }, + { + "cmd": [ + "[START_DIR]/cloudkms/cloudkms", + "decrypt", + "-input", + "[CLEANUP]/codesign_app_store_id.encrypted", + "-output", + "[CLEANUP]/CODESIGN_APP_STORE_ID", + "projects/flutter-infra-staging/locations/global/keyRings/luci/cryptoKeys/flutter-infra" + ], + "name": "cloudkms get key (5)" + }, + { + "cmd": [ + "security", + "delete-keychain", + "build.keychain" + ], + "name": "delete previous keychain" + }, + { + "cmd": [ + "security", + "create-keychain", + "-p", + "", + "build.keychain" + ], + "name": "create keychain" + }, + { + "cmd": [ + "security", + "default-keychain", + "-s", + "build.keychain" + ], + "name": "default keychain" + }, + { + "cmd": [ + "security", + "unlock-keychain", + "-p", + "", + "build.keychain" + ], + "name": "unlock build keychain" + }, + { + "cmd": [ + "chmod", + "755", + "RECIPE[flutter::engine_v2/signer].resources/import_certificate.sh" + ], + "infra_step": true, + "name": "Set execute permission" + }, + { + "cmd": [ + "RECIPE[flutter::engine_v2/signer].resources/import_certificate.sh" + ], + "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" + }, + "env_prefixes": { + "PATH": [ + "[CLEANUP]/tmp_tmp_1" + ] + }, + "name": "import certificate" + }, + { + "cmd": [ + "security", + "set-key-partition-list", + "-S", + "apple-tool:,apple:,codesign:", + "-s", + "-k", + "", + "build.keychain" + ], + "name": "set key partition list" + }, + { + "cmd": [ + "security", + "find-identity", + "-v" + ], + "name": "show-identities" + }, + { + "cmd": [ + "security", + "delete-keychain", + "build.keychain" + ], + "name": "delete keychain" + }, + { + "cmd": [ + "security", + "default-keychain", + "-s", + "login.keychain" + ], + "name": "restore default keychain" + }, + { + "cmd": [], + "name": "RECIPE CRASH (Uncaught exception)", + "~followup_annotations": [ + "@@@STEP_EXCEPTION@@@", + "The recipe has crashed at point 'Uncaught exception'!", + "", + "Traceback (most recent call last):", + " File \"RECIPE_REPO[flutter]/recipes/engine_v2/signer.py\", line 56, in RunSteps", + " KeychainSetup(api, env, env_prefixes)", + " File \"RECIPE_REPO[flutter]/recipes/engine_v2/signer.py\", line 106, in KeychainSetup", + " raise ValueError(", + "ValueError('identities are , does not include flutter identity')" + ] + }, + { + "failure": { + "humanReason": "Uncaught Exception: ValueError('identities are , does not include flutter identity')" + }, + "name": "$result" + } +] \ No newline at end of file
diff --git a/recipes/engine_v2/signer.py b/recipes/engine_v2/signer.py index a9740cd..ec7534c 100644 --- a/recipes/engine_v2/signer.py +++ b/recipes/engine_v2/signer.py
@@ -2,9 +2,7 @@ # 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. +# Recipe that executes apple code signing on a mac bot. # # This recipe receives as properties the list of google cloud bucket paths # of engine artifacts, and reads code sign related passwords from @@ -26,6 +24,7 @@ 'recipe_engine/path', 'recipe_engine/platform', 'recipe_engine/properties', + 'recipe_engine/raw_io', 'recipe_engine/step', ] @@ -34,43 +33,133 @@ if not api.platform.is_mac: pass - # Installing dependencies for code sign. + # Install dependencies for code sign. env = {} env_prefixes = {} with api.step.nest('Dependencies'): codesign_path = api.flutter_deps.codesign(env, env_prefixes) + secrets_dict = { + 'FLUTTER_P12': 'flutter_p12.encrypted', + 'FLUTTER_P12_PASSWORD': 'p12_password.encrypted', + 'CODESIGN_TEAM_ID': 'codesign_team_id.encrypted', + 'CODESIGN_APP_SPECIFIC_PASSWORD': + 'codesign_app_specific_password.encrypted', + 'CODESIGN_APP_STORE_ID': 'codesign_app_store_id.encrypted' + } + + api.kms.decrypt_secrets(env, secrets_dict) + + env['CODESIGN_PATH'] = codesign_path + + try: + KeychainSetup(api, env, env_prefixes) + + SignerBuilds( + api, codesign_path, env, env_prefixes + ) + + finally: + KeychainCleanup(api) + + +def KeychainSetup(api, env, env_prefixes): + """KeychainSetup adds flutter .p12 to a temporary keychain named 'build'. + + Args: + codesign_path (str): path of codesign cipd package. + p12_filepath (str) : path of the .p12 file that has flutter credentials. + p12_password_raw (str) : the password to decode the .p12 flutter file. + """ + api.step( + 'delete previous keychain', + ['security', 'delete-keychain', 'build.keychain'], + ok_ret='any' + ) + api.step( + 'create keychain', + ['security', 'create-keychain', '-p', '', 'build.keychain'] + ) + api.step( + 'default keychain', + ['security', 'default-keychain', '-s', 'build.keychain'] + ) + api.step( + 'unlock build keychain', + ['security', 'unlock-keychain', '-p', '', 'build.keychain'] + ) + ImportCertificate(api, env, env_prefixes) + api.step( + 'set key partition list', [ + 'security', 'set-key-partition-list', '-S', + 'apple-tool:,apple:,codesign:', '-s', '-k', '', 'build.keychain' + ] + ) + show_identities_step = api.step( + 'show-identities', ['security', 'find-identity', '-v'], + ok_ret='any', + stdout=api.raw_io.output_text(), + stderr=api.raw_io.output_text() + ) + flutter_identity_name = 'FLUTTER.IO LLC' + if flutter_identity_name not in show_identities_step.stdout: + raise ValueError( + 'identities are %s, does not include flutter identity' % + (show_identities_step.stdout) + ) + + +def ImportCertificate(api, env, env_prefixes): + """Import flutter codesign identity into keychain. + + This function triggers a shell script that supplies p12 password, + and grants codesign cipd and system codesign the correct access controls. + The p12 password is hidden from stdout. + + Args: + env (dict): environment variables. + env_prefixes (dict) : environment paths. + """ + resource_name = api.resource('import_certificate.sh') + api.step( + 'Set execute permission', + ['chmod', '755', resource_name], + infra_step=True, + ) + # Only filepath with a .p12 suffix will be recognized. + p12_suffix_filepath = api.path['cleanup'].join('flutter.p12') + env['P12_SUFFIX_FILEPATH'] = p12_suffix_filepath + with api.context(env=env, env_prefixes=env_prefixes): + api.step('import certificate', [resource_name]) + + +def SignerBuilds( + api, codesign_path, env, env_prefixes +): + """Concurrently creates jobs to codesign each binary. + + Args: + codesign_path (str): path of codesign cipd package. + env (dict): environment variables. + env_prefixes (dict) : environment paths. + """ # The list is iterated running one signer tool command per file. This can be # optimized using the multiprocessing API. final_sources_list = api.properties.get('signing_file_list', []) - signer_builds = [] - 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) - - # keep track of the output zip files in separate temp folders to avoid name conflicts + # keep track of the output zip files in separate temp folders to avoid name + # conflicts output_zips = {} codesign_string_path = "%s" % codesign_path + app_specific_password_filepath = env['CODESIGN_APP_SPECIFIC_PASSWORD'] + appstore_id_filepath = env['CODESIGN_APP_STORE_ID'] + team_id_filepath = env['CODESIGN_TEAM_ID'] + signer_builds = [] 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) + _, 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) @@ -94,6 +183,7 @@ 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, @@ -114,6 +204,10 @@ cipd package. This is to differentiate codesign cipd from mac system codesign. """ flutter_certificate_name = 'FLUTTER.IO LLC' + api.step( + 'unlock build keychain', + ['security', 'unlock-keychain', '-p', '', 'build.keychain'] + ) with api.context(env=env, env_prefixes=env_prefixes): api.step( 'codesign Apple engine binaries', @@ -136,6 +230,15 @@ ) +def KeychainCleanup(api): + """Clean up temporary keychain used in codesign process.""" + api.step('delete keychain', ['security', 'delete-keychain', 'build.keychain']) + api.step( + 'restore default keychain', + ['security', 'default-keychain', '-s', 'login.keychain'] + ) + + def GenTests(api): yield api.test( @@ -146,5 +249,23 @@ 'version': 'latest', }], signing_file_list=["gs://a/b/c/artifact.zip"] - ) + ), + api.step_data( + 'show-identities', + stdout=api.raw_io.output_text( + '1) ABCD "Developer ID Application: FLUTTER.IO LLC (ABCD)"' + ) + ), + ) + + yield api.test( + 'import_flutter_identity_failure', + api.properties( + dependencies=[{ + 'dependency': 'codesign', + 'version': 'latest', + }], + signing_file_list=["gs://a/b/c/artifact.zip"] + ), + api.expect_exception('ValueError'), )
diff --git a/recipes/engine_v2/signer.resources/import_certificate.sh b/recipes/engine_v2/signer.resources/import_certificate.sh new file mode 100644 index 0000000..f4151e1 --- /dev/null +++ b/recipes/engine_v2/signer.resources/import_certificate.sh
@@ -0,0 +1,10 @@ +#!/bin/bash + +# 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 +/usr/bin/security import $P12_SUFFIX_FILEPATH -k build.keychain -P $RAW_PASSWORD -T $CODESIGN_PATH -T /usr/bin/codesign \ No newline at end of file
diff --git a/recipes/engine_v2/signer.resources/runner.sh b/recipes/engine_v2/signer.resources/runner.sh deleted file mode 100644 index a35286d..0000000 --- a/recipes/engine_v2/signer.resources/runner.sh +++ /dev/null
@@ -1,12 +0,0 @@ -#!/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