From b0239d291c5ed6430523c183552ad4def8eb77d5 Mon Sep 17 00:00:00 2001 From: Ivar Derksen Date: Fri, 20 Jan 2023 17:21:44 +0100 Subject: [PATCH 1/2] Feat: support to let Fastlane fetch iOS provisioning profiles using the App Store Connect API --- fastlane/Fastfile | 16 +++++++++++++++ fastlane/README.md | 50 ++++++++++++++++++++++++++++++++-------------- 2 files changed, 51 insertions(+), 15 deletions(-) diff --git a/fastlane/Fastfile b/fastlane/Fastfile index 7d7e3734a..1d0d4d906 100644 --- a/fastlane/Fastfile +++ b/fastlane/Fastfile @@ -152,6 +152,7 @@ lane :ios_build_app do |options| end # When a provisioning profile is given, we ensure it is installed and selected in the project. + # If none is specified, we try to fetch the right provisioning profile using the Apple App Store Connect API. # Otherwise, we use the profile that is currently selected in XCode. if options[:provisioning_profile_path] provisioning_profile_path = File.absolute_path(options[:provisioning_profile_path]) @@ -162,6 +163,21 @@ lane :ios_build_app do |options| xcodeproj: "ios/Runner.xcodeproj", profile: provisioning_profile_path ) + elsif options[:api_key_filepath] + api_key_filepath = File.absolute_path(options[:api_key_filepath]) + api_key = app_store_connect_api_key( + key_id: options[:api_key_id], + issuer_id: options[:api_key_issuer_id], + key_filepath: api_key_filepath, + duration: 60 + ) + # Automatically fetch the provisioning profile matching the current distribution certificate and app identifier. + get_provisioning_profile( + adhoc: export_method == "ad-hoc", + app_identifier: app_identifier, + api_key: api_key, + readonly: true + ) end # The 'flutter build ipa' command does not support changing the export method in Flutter 2. diff --git a/fastlane/README.md b/fastlane/README.md index 074d26848..c3bc9a003 100644 --- a/fastlane/README.md +++ b/fastlane/README.md @@ -16,27 +16,35 @@ For _fastlane_ installation instructions, see [Installing _fastlane_](https://do # Apple provisioning profiles The `ios_build_app` action needs the app's provisioning profile and the corresponding PKCS#12 certificate bundle. -Therefore, these actions require the parameters `provisioning_profile_path`, `certificate_path` and `certificate_password`. +Therefore, these actions require the parameters `certificate_path`, `certificate_password` and either +`api_key_filepath`, `api_key_id` and `api_key_issuer_id` (to download the provisioning +profile automatically using the App Store Connect API) or `provisioning_profile_path` (to manually pass it). +In the latter case, if you later edit the provisioning profile in App Store Connect, then you need to update +the provisioning profile manually. Below we describe how to generate these assets. This can only be done by users with the 'Admin' role or the 'App Manager' role with access to certificates, identifiers and profiles in Apple App Store Connect. -Generated provisioning profiles are valid for one year. +Generated provisioning profiles are valid for one year. If you already have a valid certificate bundle, and you only +want to generate a new provisioning profile, you can skip step 1 through 7. - 1. Go to the ./fastlane directory in irmamobile + 1. Go to the ./fastlane directory in irmamobile. 2. Run `mkdir -p ./profiles && cd ./profiles` - 3. Run `openssl req -nodes -newkey rsa:2048 -keyout apple_distribution.key -out apple_distribution.csr` + 3. Run `openssl req -nodes -newkey rsa:2048 -keyout apple_distribution.key -out apple_distribution.csr`. 4. Upload the CSR to Apple: go to https://developer.apple.com/account/resources/certificates/list, press the '+' sign - and choose "iOS Distribution (App Store and Ad Hoc)" + and choose "iOS Distribution (App Store and Ad Hoc)". 5. When finished, download the .cer file and save it to the directory created in step 2 as `apple_distribution.cer` 6. Convert the .cer file to a .pem file: - `openssl x509 -in apple_distribution.cer -inform DER -out apple_distribution.pem -outform PEM` + `openssl x509 -in apple_distribution.cer -inform DER -out apple_distribution.pem -outform PEM`. 7. Convert the .pem to a .p12 and choose the certificate password: - `openssl pkcs12 -export -inkey apple_distribution.key -in apple_distribution.pem -out apple_distribution.p12` + `openssl pkcs12 -export -inkey apple_distribution.key -in apple_distribution.pem -out apple_distribution.p12`. + The generated `.p12` file and the corresponding password are the input values for the + `certificate_path` and `certificate_password` parameters. 8. You can now create a provisioning profile: go to https://developer.apple.com/account/resources/profiles/list, - press the '+' sign and follow the instructions - 9. When finished, download the provisioning profile and save it to the directory created in step 2 + press the '+' sign and follow the instructions. + 9. In case you want to use the `provisioning_profile_path` parameter, download the provisioning profile and save it + to the directory created in step 2. If you want to use the `api_key_filepath` parameter, you can skip this step. 10. In case you need to upload the assets to a secret vault, then you need to encode the files with base64, - i.e. `cat apple_distribution.p12 | base64 > apple_distribution.p12.base64` + i.e. `cat apple_distribution.p12 | base64 > apple_distribution.p12.base64`. When generating keys for CI platforms, it's recommended to protect the certificate bundle as a secret in protected deployment environments. In this way, you prevent that development builds get signed. @@ -142,11 +150,26 @@ Builds an iOS IPA file for requested flavor. This action assumes the `ios_build_irmagobridge` action has been run first. The signed iOS IPA file is written to the `build` directory (so `fastlane/build` from the repository's root). -Optionally, you can specify the paths to the app provisioning profile and the corresponding PKCS#12 certificate bundle -that should be used to provision and sign the build. If the given path is relative, then it is evaluated using the +Optionally, you can specify the following for extra functionality: + + - You can specify which iOS distribution certificate should be used to sign the build. + The path to the PKCS#12 certificate bundle of the iOS distribution key can be specified using the `certificate_path` + parameter. The certificate bundle's password can be specified using the `certificate_password` parameter. + + - You can specify which provisioning profile should be used to provision the app. To automatically fetch + the right provisioning profile from the App Store Connect API based on the requested flavor and iOS distribution certificate, + you can use the `api_key_filepath`, `api_key_id` and `api_key_issuer_id` parameters. More information about this + mechanism can be found [here](https://developer.apple.com/documentation/appstoreconnectapi/creating_api_keys_for_app_store_connect_api). + You can also supply a provisioning profile manually by using the `provisioning_profile_path` parameter. + The `alpha` flavor expects an ad-hoc provisioning profile and the `beta` flavor an app-store provisioning profile. + +If file path are relative, then it is evaluated using the fastlane directory as base (so `./fastlane` from the repository's root). +More information on how to generate distribution certificates and provisioning profiles can be found [above](#apple-provisioning-profiles). + ```sh +[bundle exec] fastlane ios_build_app flavor: api_key_filepath: api_key_id: api_key_issuer_id: certificate_path: certificate_password: [bundle exec] fastlane ios_build_app flavor: provisioning_profile_path: certificate_path: certificate_password: ``` @@ -159,9 +182,6 @@ This can be useful for testing purposes if you don't have access to the keys. The `flavor` parameter accepts the values `alpha` or `beta`. -The `alpha` flavor expects an ad-hoc provisioning profile and the `beta` flavor an app-store provisioning profile. -More information on how to achieve app provisioning profiles can be found [above](#apple-provisioning-profiles). - ---- More information about _fastlane_ can be found on [fastlane.tools](https://fastlane.tools). From f06a6157b5651418fdff798493db521cb531c2b3 Mon Sep 17 00:00:00 2001 From: Ivar Derksen Date: Fri, 20 Jan 2023 17:49:34 +0100 Subject: [PATCH 2/2] Refactor: make parameter name for api issuer id consistent with other parameters --- fastlane/Fastfile | 2 +- fastlane/README.md | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/fastlane/Fastfile b/fastlane/Fastfile index 1d0d4d906..477cd4cab 100644 --- a/fastlane/Fastfile +++ b/fastlane/Fastfile @@ -167,7 +167,7 @@ lane :ios_build_app do |options| api_key_filepath = File.absolute_path(options[:api_key_filepath]) api_key = app_store_connect_api_key( key_id: options[:api_key_id], - issuer_id: options[:api_key_issuer_id], + issuer_id: options[:api_issuer_id], key_filepath: api_key_filepath, duration: 60 ) diff --git a/fastlane/README.md b/fastlane/README.md index c3bc9a003..ed6d25327 100644 --- a/fastlane/README.md +++ b/fastlane/README.md @@ -17,7 +17,7 @@ For _fastlane_ installation instructions, see [Installing _fastlane_](https://do # Apple provisioning profiles The `ios_build_app` action needs the app's provisioning profile and the corresponding PKCS#12 certificate bundle. Therefore, these actions require the parameters `certificate_path`, `certificate_password` and either -`api_key_filepath`, `api_key_id` and `api_key_issuer_id` (to download the provisioning +`api_key_filepath`, `api_key_id` and `api_issuer_id` (to download the provisioning profile automatically using the App Store Connect API) or `provisioning_profile_path` (to manually pass it). In the latter case, if you later edit the provisioning profile in App Store Connect, then you need to update the provisioning profile manually. @@ -158,7 +158,7 @@ Optionally, you can specify the following for extra functionality: - You can specify which provisioning profile should be used to provision the app. To automatically fetch the right provisioning profile from the App Store Connect API based on the requested flavor and iOS distribution certificate, - you can use the `api_key_filepath`, `api_key_id` and `api_key_issuer_id` parameters. More information about this + you can use the `api_key_filepath`, `api_key_id` and `api_issuer_id` parameters. More information about this mechanism can be found [here](https://developer.apple.com/documentation/appstoreconnectapi/creating_api_keys_for_app_store_connect_api). You can also supply a provisioning profile manually by using the `provisioning_profile_path` parameter. The `alpha` flavor expects an ad-hoc provisioning profile and the `beta` flavor an app-store provisioning profile. @@ -169,7 +169,7 @@ fastlane directory as base (so `./fastlane` from the repository's root). More information on how to generate distribution certificates and provisioning profiles can be found [above](#apple-provisioning-profiles). ```sh -[bundle exec] fastlane ios_build_app flavor: api_key_filepath: api_key_id: api_key_issuer_id: certificate_path: certificate_password: +[bundle exec] fastlane ios_build_app flavor: api_key_filepath: api_key_id: api_issuer_id: certificate_path: certificate_password: [bundle exec] fastlane ios_build_app flavor: provisioning_profile_path: certificate_path: certificate_password: ```