In previous posts I have covered how to set up and use access key with App Store API and later how to automatically generate certificate and profiles using the access key. Let’s crank it up to 11 and have automated app uploads to App Store using GitHub Actions so we never ever have to see Xcode’s archiving steps again. For this to work, 2 tasks need to be done (given fastlane is available):
- Create fastlane action with release flow
- Create GitHub workflow based on preferred events
For the first task, the following action is added to Fastfile:
app_store_connect_api_key
lane :release do
if is_ci
setup_ci
end
sync_certs
build_app
upload_to_testflight
end
First, setup_ci needs to be called to setup temporary keychain to ensure sync_certs works correctly on any CI provider. To prevent setup_ci from running locally, in case it is triggered on your local machine, is_ci check is required.
sync_certs function comes from iOS: automate certificate and profile creation using fastlane post. Essentially, it can be replaced with fastlane’s match action directly. It will ensure that certificates and profiles are downloaded and installed on CI machine’s keychain for later signing.
build_app and upload_to_testflight actions most likely look familiar to you. It simply builds, signs and uploads generated .ipa file to the App Store. Refer to fastlane docs for more information about available lanes and possible arguments for further possible configurations.
Note: Remember to add
app_store_connect_api_keytoFastfile. This will ensure App Store API keys are correctly loaded before executingreleaseaction.
For the GitHub workflow, the following .yml file is added under .github/workflows directory:
name: Upload build to App Store
on:
workflow_dispatch
jobs:
upload-build:
runs-on: macos-latest
env:
APP_STORE_CONNECT_API_KEY_KEY_ID: ${{ secrets.APP_STORE_KEY_ID }}
APP_STORE_CONNECT_API_KEY_ISSUER_ID: ${{ secrets.APP_STORE_ISSUER_ID }}
APP_STORE_CONNECT_API_KEY_KEY: ${{ secrets.APP_STORE_ACCES_KEY }}
APP_STORE_CONNECT_API_KEY_IS_KEY_CONTENT_BASE64: true
MATCH_PASSWORD: ${{ secrets.MATCH_PASSWORD }}
MATCH_GIT_BASIC_AUTHORIZATION: ${{ secrets.MATCH_GIT_BASIC_AUTHORIZATION }}
steps:
- name: Checkout
uses: actions/checkout@v2
- name: Upload to App Store
run: fastlane release
3 important parts:
ontrigger. In this case,workflow_dispatchis used which is part of manual events and can be triggered via GitHub API or via GitHub web interface. However, there are different options as well which can suit your needs better, such as recurring weekly builds. Have a look at GitHub documentation.envvalues. These values are important and have to be configured similarly to values used in.envfile as in earlier post on access keys. There are few additional values -MATCH_PASSWORDandMATCH_GIT_BASIC_AUTHORIZATION:MATCH_PASSWORD- secret value used by fastlane match to encrypt/decrypt certificates and profiles within private remote repository.MATCH_GIT_BASIC_AUTHORIZATION- access token which fastlane match will use to download certificates from private remote repository. It can be generated by accessingPersonal access tokenspage on GitHub. At minimumreposcope has to be granted to allow access to private repositories.
All of the actual secrets must be added to
Repository secretswhich is underSettings->SecretsNote: Environment keys under
envsection in.ymlfile need to be exactly as shown above. These keys are directly used by fastlane to load values. For more information, refer to fastlane’s match action documentationstepssection. It simply contains 2 steps - checkout the code and trigger fastlane action that was created previously. This can be extended with more steps, e.g. to notify others about new builds.
And voilà, if done correctly, you should be able to automatically and consistently upload iOS builds to App Store using GitHub Actions.