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