Using App Store Connect API with Fastlane Match
source link: https://sarunw.com/posts/using-app-store-connect-api-with-fastlane-match/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
Using App Store Connect API with Fastlane Match
Table of Contents
Starting February 2021, two-factor authentication or two-step verification will be required for all users to sign in to App Store Connect. This extra layer of security for your Apple ID helps ensure that you’re the only person who can access your account.
From Apple Support
Right now, Apple is enforcing two-factor authentication (2FA) for all accounts. If you don't use any Continuous Integration (CI) and always submit your app via Xcode, you have nothing to worry about. You can checkout Apple suport and enabled 2FA if you don't already have it enabled.
But if you use Fastlane with a username and password authentication for your CI, it is a time for the change.
Apple announced the App Store Connect API back in WWDC18. It provides an official way to interact with App Store Connect, and Fastlane already supports this. Let's see what we need to do to adopt it.
This post assumes you already have a Fastlane match set up and having working certificates and provisioning profiles on a git repo. If you want to get started with Fastlane, you can find out more about it here.
Requirements
To be able to use App Store Connect API, Fastlane needs three things.
- Issuer ID.
- Key ID.
- Key file or Key content.
I will show you how to generate these three in the next section.
Creating an App Store Connect API Key
To generate keys, you must have Admin permission in App Store Connect. If you don't have that permission, you can direct the relevant person to this article and follow the following instructions. You need three things at the end of the process.
- Log in to App Store Connect.
- Select Users and Access.
- Select the API Keys tab.
- Click Generate API Key or the Add (+) button.
- Enter a name for the key. The name is for your reference only and is not part of the key itself.
- Under Access, select the role for the key. The roles that apply to keys are the same roles that apply to users on your team. See role permissions.
- Click Generate.
An API key's access cannot be limited to specific apps.
The new key's name, key ID, a download link, and other information appear on the page.
Your newly created key will show up on the page.You can grab all three necessary information here.
<1> Issue ID.
<2> Key ID.
<3> Click "Download API Key" to download your API private key. The download link appears only if the private key has not yet been downloaded. Apple does not keep a copy of the private key. So you can download it only once.
Store your private key in a safe place. You should never share your keys, store keys in a code repository, or include keys in client-side code.
Now you got everything you need to use App Store Connect API, let's put it into use.
Using an App Store Connect API Key
The API Key file (p8 file that you download), the key id, and the issuer id are needed to create the JWT token for authorization. There are multiple ways that these pieces of information can be input into Fastlane using Fastlane's new action, app_store_connect_api_key
. I will show only one way to do this. You can learn other ways in fastlane documentation. I show this method because I think it is the easiest way to work with most CI out there, where you can set environment variables.
Use return value and pass in as an option
First, you need to create a JWT token for authorization using the app_store_connect_api_key
action. Then you inject that as an argument to other Fastlane actions (match in this case).
lane :release do
api_key = app_store_connect_api_key(
key_id: ENV['ASCAPI_KEY_ID'],
issuer_id: ENV['ASCAPI_ISSUER_ID'],
key_content: ENV['ASCAPI_KEY_CONTENT']
)
match(
type: 'appstore',
app_identifier: ["com.sarunw.app"],
api_key: api_key,
readonly: true
)
...
end
In this example, we put issuer id, key id, and key content into three environment variables, ASCAPI_ISSUER_ID
, ASCAPI_KEY_ID
, and ASCAPI_KEY_CONTENT
, respectively. Then we call app_store_connect_api_key
with those variables and get back an authentication key for the match
action.
Use the shared value in lane context
Under the hood, the app_store_connect_api_key
action sets shared variable (Actions.lane_context[SharedValues::APP_STORE_CONNECT_API_KEY]
) for other action to easily use. Other actions (like match
) will automatically load the API Key from Actions.lane_context
if you don't provide api_key
argument.
You can shorten the code to something like this:
lane :release do
app_store_connect_api_key(
key_id: ENV['ASCAPI_KEY_ID'],
issuer_id: ENV['ASCAPI_ISSUER_ID'],
key_content: ENV['ASCAPI_KEY_CONTENT']
)
match(
type: 'appstore',
app_identifier: ["com.sarunw.app"],
readonly: true
)
...
end
Use default ENV name
Each key in Fastlane action has a default environment key that automatically loads if set (and you don't explicitly provide them as method arguments).
Here is the list of defaults key for our parameters.
Key Description ENV key key_id The key ID APP_STORE_CONNECT_API_KEY_KEY_ID issuer_id The issuer ID APP_STORE_CONNECT_API_KEY_ISSUER_ID key_content The content of the key p8 file APP_STORE_CONNECT_API_KEY_KEY key_filepath The path to the key p8 file APP_STORE_CONNECT_API_KEY_KEY_FILEPATH duration The token session duration APP_STORE_CONNECT_API_KEY_DURATION in_house Is App Store or Enterprise (in house) APP_STORE_CONNECT_API_KEY_IN_HOUSESo if you set those three keys set in your CI environment variables, you can further shorten the code.
lane :release do
app_store_connect_api_key()
match(
type: 'appstore',
app_identifier: ["com.sarunw.app"],
readonly: true
)
...
end
Caveats
Newline problem
This doesn't happen to me, but if your CI has a problem with a newline character when setting an environmental variable with newline characters (like a private key), you might consider using a base64 encoded version of your private key (p8 file). Reference issue.
To do that, first, encode your p8 file.
cat AuthKey_ABCDEFGH.p8 | base64
If you don't have the base64 command, try to install the coreutils via Brew (brew install coreutils
), which will provide the base64 command.
Then use an encoded version of your p8 file in key_content
and add the is_key_content_base64
key with a value of true
.
app_store_connect_api_key(
key_id: "D83848D23",
issuer_id: "227b0bbf-ada8-458c-9d62-3d8022b7d07f",
key_content: "Base64_encode_of_-----BEGIN EC PRIVATE KEY-----\nfewfawefawfe\n-----END EC PRIVATE KEY-----",
is_key_content_base64: true
)
Missing some actions
Some actions such as download_dsyms that used to work with cookie-based web session won't work with Appstore Connect API since Apple does not have all endpoint available yet. But this problem should be getting better if Apple keeps updating their API.
Conclusion
In this article, I just show you one way to handle the situation, but this isn't the only way. If you interest in other ways to handle this, check out a nice article from Josh Holtz, Lead maintainer of the Fastlane. He goes through all possible scenarios and solutions for each case.
You may also like
Fastlane Match saves us a lot of time managing certificates and provisioning profiles, but there is one thing that we have to do it manually. That is a renewal expired certificate. Luckily, we have to do it once a year. Let's learn how to do it.
FastlaneRead more article about Fastlane
or see all available topic
Get new posts weekly
If you enjoy this article, you can subscribe to the weekly newsletter.
Every Friday, you’ll get a quick recap of all articles and tips posted on this site — entirely for free.
Feel free to follow me on Twitter and ask your questions related to this post. Thanks for reading and see you next time.
If you enjoy my writing, please check out my Patreon https://www.patreon.com/sarunw and become my supporter. Sharing the article is also greatly appreciated.
How to fix "no identity found - Command CodeSign failed with a nonzero exit code" error in Xcode
There might be several reasons that cause this error. I will share one that just happened to me.
Tuist Template: What is it and how to create them
The template is a way to group repetitive code structure into a reusable component. You will learn how to create them in this article.
Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK