medito-app
medito-app copied to clipboard
chore: add workflow for deploying to appstore
Credits
- This PR is based on the tutorial from Joshua https://joshuamdeguzman.com/continuous-delivery-for-flutter-using-fastlane-and-github-actions-pt-3-ios/
- Most of the command and text are copied from Joshua's blog
- Thanks Joshua for the awesome blog series
Summary
This PR uses the following tools:
-
fastlane
for deploying to app: https://docs.fastlane.tools/ -
fastlane match
to manage apple certificate for development and distribution key: https://docs.fastlane.tools/actions/match/#fastlane and https://codesigning.guide/ - Apple API Key to authenticate with Apple API for managing the deployment: https://docs.fastlane.tools/app-store-connect-api/#using-fastlane-api-key-json-file
These tools are all mentioned and recommended in the official Flutter documentation: https://flutter.dev/docs/deployment/cd
Similarly to the android workflow, I don't expect this to work perfectly at the first time. I am happy to debug as we did with the android part.
Generate distribution key profile
- Create a PRIVATE GH repository to store the certificates. The certificates and profiles will always be encrypted with a passphras but it's the best to keep the repository PRIVATE.
- Run the following command from your local environment to generate certificates and upload it securely in to your private GH repo:
cd ios && MEDITO_APPSTORE_CERTIFICATES_REPO="https://github.com/medito-hq/<repo_name>" fastlane match appstore
You will be prompted to enter a passphrase. Remember it correctly because it will be used later by Github Actions to decrypt your certificates repository.
Generated certificates and provisioning profiles are uploaded to the certificates repository
Lastly, open ios/Runner.xcworkspace in XCode, and update the provisioning profile for the release configuration of your app.
For the CI/CD to import the certificates and provisioning profiles, it needs to have access to the certificates repository. You can do this by generating a personal access token that has the scope to access or read private repositories.
In Github, go to Settings -> Developer Settings -> Personal access tokens -> click Generate New Token -> tick the repo scope -> then click Generate token.
match(
...
git_basic_authorization: Base64.strict_encode64(ENV["GIT_AUTHORIZATION"]),
...
)
Generate Apple API Key for uploading to test flight
- Follow the instruction in https://docs.fastlane.tools/app-store-connect-api/ to get the p8 file
- Create the json key file as https://docs.fastlane.tools/app-store-connect-api/#using-fastlane-api-key-json-file
- Add the json content for the GH secret
APPLE_API_KEY_JSON
Secrets
Assuming you are using prod
enviroment :D
-
APP_STORE_CONNECT_TEAM_ID
- the ID of your App Store Connect team in you’re in multiple teams -
DEVELOPER_APP_ID
- in App Store Connect, go to the app -> App Information -> Scroll down to the General Information section of your app and look for Apple ID. -
DEVELOPER_APP_IDENTIFIER
- your app’s bundle identifier -
DEVELOPER_PORTAL_TEAM_ID
- the ID of your Developer Portal team if you’re in multiple teams -
MEDITO_APPSTORE_CERTIFICATES_REPO
- the github repository for distribution certificates and profile -
GIT_AUTHORIZATION
- <YOUR_GITUSERNAME>:<YOUR_PERSONAL_ACCESS_TOKEN>, eg. joshuadeguzman:mysecretkeyyoudontwanttoknow -
MATCH_PASSWORD
- the passphrase that you assigned when initializing match, this will be used for decrypting the certificates and provisioning profiles -
PROVISIONING_PROFILE_SPECIFIER
-match AppStore <YOUR_APP_BUNDLE_IDENTIFIER>
, eg.match AppStore org.mediationfoundation
. -
TEMP_KEYCHAIN_USER
&TEMP_KEYCHAIN_PASSWORD
- assign a temp keychain user and password for your workflow -
APPLE_API_KEY_JSON
- Apple API Key for uploading the app https://docs.fastlane.tools/app-store-connect-api/
Awesome! I will check it out this week :)
After I input the SMS verification code in the Generate distribution key profile stage, I get this error. My email address is correct, and the SMS code is correct. Not sure what's happening :/
/usr/local/Cellar/fastlane/2.191.0/libexec/gems/http-cookie-1.0.4/lib/http/cookie_jar.rb:261:in `initialize': \e[31m[!] Permission denied @ rb_sysopen - /Users/mike/.fastlane/spaceship/[MY_EMAIL_ADDRESS]/cookie\e[0m (Errno::EACCES)
from /usr/local/Cellar/fastlane/2.191.0/libexec/gems/http-cookie-1.0.4/lib/http/cookie_jar.rb:261:in `open'
from /usr/local/Cellar/fastlane/2.191.0/libexec/gems/http-cookie-1.0.4/lib/http/cookie_jar.rb:261:in `save'
from /usr/local/Cellar/fastlane/2.191.0/libexec/gems/fastlane-2.191.0/spaceship/lib/spaceship/client.rb:292:in `store_cookie'
from /usr/local/Cellar/fastlane/2.191.0/libexec/gems/fastlane-2.191.0/spaceship/lib/spaceship/two_step_or_factor_client.rb:360:in `store_session'
from /usr/local/Cellar/fastlane/2.191.0/libexec/gems/fastlane-2.191.0/spaceship/lib/spaceship/two_step_or_factor_client.rb:207:in `handle_two_factor'
from /usr/local/Cellar/fastlane/2.191.0/libexec/gems/fastlane-2.191.0/spaceship/lib/spaceship/two_step_or_factor_client.rb:21:in `handle_two_step_or_factor'
from /usr/local/Cellar/fastlane/2.191.0/libexec/gems/fastlane-2.191.0/spaceship/lib/spaceship/client.rb:515:in `send_shared_login_request'
from /usr/local/Cellar/fastlane/2.191.0/libexec/gems/fastlane-2.191.0/spaceship/lib/spaceship/portal/portal_client.rb:28:in `send_login_request'
from /usr/local/Cellar/fastlane/2.191.0/libexec/gems/fastlane-2.191.0/spaceship/lib/spaceship/client.rb:824:in `do_login'
from /usr/local/Cellar/fastlane/2.191.0/libexec/gems/fastlane-2.191.0/spaceship/lib/spaceship/client.rb:404:in `login'
from /usr/local/Cellar/fastlane/2.191.0/libexec/gems/fastlane-2.191.0/spaceship/lib/spaceship/client.rb:366:in `login'
from /usr/local/Cellar/fastlane/2.191.0/libexec/gems/fastlane-2.191.0/spaceship/lib/spaceship/portal/spaceship.rb:25:in `login'
from /usr/local/Cellar/fastlane/2.191.0/libexec/gems/fastlane-2.191.0/spaceship/lib/spaceship/connect_api/client.rb:55:in `login'
from /usr/local/Cellar/fastlane/2.191.0/libexec/gems/fastlane-2.191.0/spaceship/lib/spaceship/connect_api/spaceship.rb:85:in `login'
from /usr/local/Cellar/fastlane/2.191.0/libexec/gems/fastlane-2.191.0/match/lib/match/spaceship_ensure.rb:34:in `initialize'
from /usr/local/Cellar/fastlane/2.191.0/libexec/gems/fastlane-2.191.0/match/lib/match/runner.rb:72:in `new'
from /usr/local/Cellar/fastlane/2.191.0/libexec/gems/fastlane-2.191.0/match/lib/match/runner.rb:72:in `run'
from /usr/local/Cellar/fastlane/2.191.0/libexec/gems/fastlane-2.191.0/match/lib/match/commands_generator.rb:69:in `block (3 levels) in run'
from /usr/local/Cellar/fastlane/2.191.0/libexec/gems/commander-4.6.0/lib/commander/command.rb:187:in `call'
from /usr/local/Cellar/fastlane/2.191.0/libexec/gems/commander-4.6.0/lib/commander/command.rb:157:in `run'
from /usr/local/Cellar/fastlane/2.191.0/libexec/gems/commander-4.6.0/lib/commander/runner.rb:444:in `run_active_command'
from /usr/local/Cellar/fastlane/2.191.0/libexec/gems/fastlane-2.191.0/fastlane_core/lib/fastlane_core/ui/fastlane_runner.rb:76:in `run!'
from /usr/local/Cellar/fastlane/2.191.0/libexec/gems/commander-4.6.0/lib/commander/delegates.rb:18:in `run!'
from /usr/local/Cellar/fastlane/2.191.0/libexec/gems/fastlane-2.191.0/match/lib/match/commands_generator.rb:188:in `run'
from /usr/local/Cellar/fastlane/2.191.0/libexec/gems/fastlane-2.191.0/match/lib/match/commands_generator.rb:26:in `start'
from /usr/local/Cellar/fastlane/2.191.0/libexec/gems/fastlane-2.191.0/fastlane/lib/fastlane/cli_tools_distributor.rb:114:in `take_off'
from /usr/local/Cellar/fastlane/2.191.0/libexec/gems/fastlane-2.191.0/bin/fastlane:23:in `<top (required)>'
from /usr/local/Cellar/fastlane/2.191.0/libexec/bin/fastlane:23:in `load'
from /usr/local/Cellar/fastlane/2.191.0/libexec/bin/fastlane:23:in `<main>'
/usr/local/Cellar/fastlane/2.191.0/libexec/gems/http-cookie-1.0.4/lib/http/cookie_jar.rb:261:in `initialize': Permission denied @ rb_sysopen - /Users/mike/.fastlane/spaceship/[MY_EMAIL_ADDRESS]/cookie (Errno::EACCES)
from /usr/local/Cellar/fastlane/2.191.0/libexec/gems/http-cookie-1.0.4/lib/http/cookie_jar.rb:261:in `open'
from /usr/local/Cellar/fastlane/2.191.0/libexec/gems/http-cookie-1.0.4/lib/http/cookie_jar.rb:261:in `save'
from /usr/local/Cellar/fastlane/2.191.0/libexec/gems/fastlane-2.191.0/spaceship/lib/spaceship/client.rb:292:in `store_cookie'
from /usr/local/Cellar/fastlane/2.191.0/libexec/gems/fastlane-2.191.0/spaceship/lib/spaceship/two_step_or_factor_client.rb:360:in `store_session'
from /usr/local/Cellar/fastlane/2.191.0/libexec/gems/fastlane-2.191.0/spaceship/lib/spaceship/two_step_or_factor_client.rb:207:in `handle_two_factor'
from /usr/local/Cellar/fastlane/2.191.0/libexec/gems/fastlane-2.191.0/spaceship/lib/spaceship/two_step_or_factor_client.rb:21:in `handle_two_step_or_factor'
from /usr/local/Cellar/fastlane/2.191.0/libexec/gems/fastlane-2.191.0/spaceship/lib/spaceship/client.rb:515:in `send_shared_login_request'
from /usr/local/Cellar/fastlane/2.191.0/libexec/gems/fastlane-2.191.0/spaceship/lib/spaceship/portal/portal_client.rb:28:in `send_login_request'
from /usr/local/Cellar/fastlane/2.191.0/libexec/gems/fastlane-2.191.0/spaceship/lib/spaceship/client.rb:824:in `do_login'
from /usr/local/Cellar/fastlane/2.191.0/libexec/gems/fastlane-2.191.0/spaceship/lib/spaceship/client.rb:404:in `login'
from /usr/local/Cellar/fastlane/2.191.0/libexec/gems/fastlane-2.191.0/spaceship/lib/spaceship/client.rb:366:in `login'
from /usr/local/Cellar/fastlane/2.191.0/libexec/gems/fastlane-2.191.0/spaceship/lib/spaceship/portal/spaceship.rb:25:in `login'
from /usr/local/Cellar/fastlane/2.191.0/libexec/gems/fastlane-2.191.0/spaceship/lib/spaceship/connect_api/client.rb:55:in `login'
from /usr/local/Cellar/fastlane/2.191.0/libexec/gems/fastlane-2.191.0/spaceship/lib/spaceship/connect_api/spaceship.rb:85:in `login'
from /usr/local/Cellar/fastlane/2.191.0/libexec/gems/fastlane-2.191.0/match/lib/match/spaceship_ensure.rb:34:in `initialize'
from /usr/local/Cellar/fastlane/2.191.0/libexec/gems/fastlane-2.191.0/match/lib/match/runner.rb:72:in `new'
from /usr/local/Cellar/fastlane/2.191.0/libexec/gems/fastlane-2.191.0/match/lib/match/runner.rb:72:in `run'
from /usr/local/Cellar/fastlane/2.191.0/libexec/gems/fastlane-2.191.0/match/lib/match/commands_generator.rb:69:in `block (3 levels) in run'
from /usr/local/Cellar/fastlane/2.191.0/libexec/gems/commander-4.6.0/lib/commander/command.rb:187:in `call'
from /usr/local/Cellar/fastlane/2.191.0/libexec/gems/commander-4.6.0/lib/commander/command.rb:157:in `run'
from /usr/local/Cellar/fastlane/2.191.0/libexec/gems/commander-4.6.0/lib/commander/runner.rb:444:in `run_active_command'
from /usr/local/Cellar/fastlane/2.191.0/libexec/gems/fastlane-2.191.0/fastlane_core/lib/fastlane_core/ui/fastlane_runner.rb:76:in `run!'
from /usr/local/Cellar/fastlane/2.191.0/libexec/gems/commander-4.6.0/lib/commander/delegates.rb:18:in `run!'
from /usr/local/Cellar/fastlane/2.191.0/libexec/gems/fastlane-2.191.0/match/lib/match/commands_generator.rb:188:in `run'
from /usr/local/Cellar/fastlane/2.191.0/libexec/gems/fastlane-2.191.0/match/lib/match/commands_generator.rb:26:in `start'
from /usr/local/Cellar/fastlane/2.191.0/libexec/gems/fastlane-2.191.0/fastlane/lib/fastlane/cli_tools_distributor.rb:114:in `take_off'
from /usr/local/Cellar/fastlane/2.191.0/libexec/gems/fastlane-2.191.0/bin/fastlane:23:in `<top (required)>'
from /usr/local/Cellar/fastlane/2.191.0/libexec/bin/fastlane:23:in `load'
from /usr/local/Cellar/fastlane/2.191.0/libexec/bin/fastlane:23:in `<main>'
@KeirLogan added you to the ticket - you also now have access to the github app repo. If you need access to the app store stuff, ask me or @michaelcspeed by DM :) Cheers
After 1.5 years we finally got this working woo! 🚀🚀 Thanks so much @KeirLogan and @qtdzz