HàPhan 河

Two ways to Upload an ipa to Testflight with Fastlane

After making builds with Fastlane and exported a valid .ipa, you need to automate the process of uploading the file to Testflight. You can do it in two ways with upload_to_testflight (or pilot) action.

With AppStore Connect API key

https://docs.fastlane.tools/app-store-connect-api/#using-fastlane-api-key-json-file

The upload_to_testflight action need an App store connect api key to work. It's result of this action app_store_connect_api_key, the action to create a JWT from a .p8 file.

lane :release do
  api_key = app_store_connect_api_key(
    key_id: "Q58Q4Y9A5W",
    issuer_id: "69a6de95-7865-47e3-e053-5b8c7c11a4d1",
    key_filepath: "./AuthKey_Q58Q4Y9A5W.p8",
    duration: 1200, # optional (maximum 1200)
    in_house: false # optional but may be required if using match/sigh
  )

  upload_to_testflight(
    api_key: api_key,
    skip_submission: true,
    ipa: "#{ipa_path}",
    skip_waiting_for_build_processing: true,
  )
end

.p8 file a private key that can easily get from App Store Connect webpage.
Login to your developer account, go to Users and Access, then to find Request Access button in Keys tab.

Screen-Shot-2022-07-24-at-23.18.53

After requesting access, you can Generate any Key for some roles, use Issue ID, KeyID and Download API key (as an .p8 file) for app_store_connect_api_key

Screen-Shot-2022-07-24-at-23.26.05

Screen-Shot-2022-07-24-at-23.31.34

You are good to go.

In case you want to use key_content instead of key_filepath, you need to modify the .p8 key by replacing all new lines with \n. Eg:

-----BEGIN PRIVATE KEY-----
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB
CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD
EEEEEEEEEEEEE
-----END PRIVATE KEY-----

to

-----BEGIN PRIVATE KEY-----\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\nBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB\nCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC\nDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD\nEEEEEEEEEEEEE\n-----END PRIVATE KEY-----

Find more detail about the key here
https://docs.fastlane.tools/actions/app_store_connect_api_key/

With Enviroment variables FASTLANE_USER and FASTLANE_APPLE_APPLICATION_SPECIFIC_PASSWORD

https://docs.fastlane.tools/best-practices/continuous-integration/#application-specific-passwords

Let take a look as a sample lane that use two env variables above

lane :release do
  upload_to_testflight(
    apple_id: "your-app-apple-id"
    skip_submission: true,
    ipa: "#{ipa_path}",
    skip_waiting_for_build_processing: true,
  )
end

About environment variables: https://support.apple.com/guide/terminal/use-environment-variables-apd382cc5fa-4f58-4449-b20a-41c53c006f8f/mac

It's simpler but to let the script work, we need to find out FASTLANE_USER FASTLANE_APPLE_APPLICATION_SPECIFIC_PASSWORD and apple_id.

  • FASTANE_USER is your developer id

  • FASTLANE_APPLE_APPLICATION_SPECIFIC_PASSWORD is one of App-Specific Passwords in your apple id managemeng page https://appleid.apple.com/account/manage
    Screen-Shot-2022-07-24-at-23.49.06

  • apple_id can be found in your app's information page in App Store Connect web page.

Screen-Shot-2022-07-24-at-23.57.20

Let try and see result.

Conclusion

The first way seems more complicated than the second way, and you need to be an admin to generate .p8 key. But you can control the flow by put the key in any place you want to automate and you don't rely on any user's account.

The second way is base on account, and if you work in an organization the account can be expired if people leave. So it's suitable for personal account.

Thanks a lot for reading. Happy coding.

Comments