What problem Match is solving
Firstly, I believe it's important to understand what Match does and what problem it's solving. I believe this page made by Fastlane explains it perfectly, so I'll just quote them:
"When deploying an app to the App Store, a beta testing service or even installing it on a single device, most development teams have separate code signing identities for every member. This results in dozens of profiles including a lot of duplicates.
You have to manually renew and download the latest set of provisioning profiles every time you add a new device or a certificate expires. Additionally this requires spending a lot of time when setting up a new machine that will build your app."
Let's get our hands dirty
1. Creating the team account
When using Match, the whole idea is having a single Apple account which will generate and own the certificates. This could be your user, for example, but if you leave the company, then this would have to be changed so other employees could keep updating the certificates.
The recommended and best approach for this is inviting/creating a new Apple developer account to be shared among the team. I'll reference it from now on as email@example.com .
In our case we used a group email but this could be an e-mail of your organisation as well. Also mind that this e-mail must exist because you'll need to confirm it. As for the phone I recommend using someone's phone who thinks of staying in the company for a long time, but it can be changed in the future if you ever need.
2. Choosing and creating the storage for the certificates
This is the source of truth where your certificates will be stored, where you'll update them and where your teammates and the CD server will fetch them.
Here, at Revelo, we use S3 storage but you can also use Git or Google Cloud at the time this article was written. I'll explain how to do it with GitHub below:
Create a private git repository and a user for our CD server on GitHub.
I recommend using the same e-mail address you used before, such as firstname.lastname@example.org . It's not mandatory to use the same e-mail, but it makes things easier to maintain.
This user should be added to the repository and given permission to read it.
You could have used your own user, for example, but then what if you leave the company? This user used on the CD server should not be affected by that.
Later we'll have to generate an API token for this user so it can authenticate on the CD.
3. Install Fastlane
I won't cover this topic because it's already well covered on the docs and there are many articles and videos explaining how to do that, but just make sure it's setup, running and you are ready to write some lanes.
4. Setup Appfile
The Appfile is created within the fastlane folder and it's a configuration file. You should set at least these configurations below so fastlane can get the certificates/provisioning profiles and upload it to Appstore.
- team_name and team_id
Both can be found on Apple Developer membership
This can be the same as the team_name
This is the trickiest to get. I recommend visiting this stackoverflow question and trying any of the answers. Personally I used this answer and it worked flawlessly.
5. Setup match
On the project folder run
- fastlane match init
It will ask you which storage you want to use. If you're following the tutorial from the beginning, select Git repo. If you’re using another storage option, then I recommend you to look Fastlane Match docs on how to set it up.
Then you can enter the git project url (prefer the git@...one if your machine is already using SSH for authenticating with GitHub).
This will just make things easier for now, thinking that you will write the tokens with your own account. Later on if you ever leave the company, it's just a matter of another person with write access to the repo run generate the tokens and update them by using match.
This will create a Matchfile on fastlane folder that should look like this:
This Matchfile is another configuration file with parameters that Match will use, but you could also set them via env vars or pass them as parameters of the functions we will call shortly.
6. Setup your environment variables
Just before that, I recommend that you use Dotenv gem at least for local development so you can make it easier for new developers who join the team to setup the environment more easily. However if you want to set them manually on your ~/.profile , it will work the same.
Go to your Gemfile and add this line:
- gem "dotenv"
and run on the command line
- bundle install
Now create a file inside the fastlane folder called .env.default and another one .env.default.sample . The sample one you should leave it like the file below and it can be committed to git. The other one should be filled with the environment variables that should not be committed, otherwise you risk exposing your keys and secrets. 👀
Fastlane will automatically load the .env.default file so it should be good.
6.1 Fill the environment variables for Match
For local development
Here every developer on the team can use one's own account. So if one's authenticated with SSH on git, then there's no need to fill this one:
This password will be used to encrypt/decrypt the certificates, so don't loose it. Every developer on your team must have it to download the certificates.
This variable should be set with the e-mail of the Apple shared account used on the first step email@example.com. Usually there's no need for every developer to know this and its password, because it's simpler if only a few people can generate new certificates. Otherwise, every time someone leaves your team, then you'd have to change the password for this user.
*The last keys starting with APP_STORE_CONNECT_API_ I will cover later.
On CD server you should generate a personal access token for the team user we mentioned on step 2. For GitHub, follow these instructions and run this on your command line to get the base64 string you will store on this env var.
echo -n your_github_username:your_personal_access_token | base64
This password will be used to encrypt/decrypt the certificates, so don’t loose it.
There's no need to set this on CD, because it will only fetch instead of generating new certificates.
7. Create a fastlane lane to sync the certificates
If Fastlane has already created a Fastfile inside of fastlane folder, then edit it to add the lanes below. Otherwise, create a new Fastfile and copy this:
The first lane :certificates is the one that your CD server must run. This is also useful when you and new developers want to get the newest certificates available.
The second lane :generate_new_certificates will update the certificates if needed. This could happen if they expire, are revoked or if a new device id is added to the list of devices on apple developers portal.
Note: Make sure to add a sync_code_signing method call for each of the types of certificates needed. The available types are development, adhoc and appstore. Don't forget to change the app_identifiers according to your app as well.
After that it is a good practice to revoke and erase the current certificates on the Apple developers portal before generating new ones with Match. Do this by running the command:
- fastlane match nuke
Now run the command below to create and store the new certificates:
- fastlane generate_new_certificates
When you run this command, it might ask the password and a 2 factor authentication code of the user you've created on the first step so it can log into Apple.
8. Change in Xcode the signing option
I assume you previously used automatic signing by Xcode. So you can now disable this check on every build type and scheme you have and select the appropriate provisioning profile that match created. It should start with match AppStore com.company.example depending on the type of build you are selecting.
If an error appears, usually restarting Xcode solves it.
Everyone in your team should do the same.
9. We're almost done, let's get the Appstore Connect API key so our CI can release our app automatically
The Apple account holder of your team must do this step:
- Visit the page https://appstoreconnect.apple.com/access/api
- Generate a new API Key (make sure it's set to App Manager access)
- You must collect three things: issuer_id , key_id and key itself (.p8) file .
These values you’ve just got ideally should stay only on your CD server, but you could also fill it in your local environment for testing. So let's continue filling the .env.default file. I also recommend not to share this with your team because of the same reason I told before: If this person leaves, security-wise it would be better to change revoke and generate a new API Key.
Fill this with the key_id you've just got.
Fill this with the key_issuer_id you've just got.
For this option, you must convert your .p8 key to base64 so you can store it as a secret string in your CD server. You can do that by running this command which will copy your key as base64 string into your clipboard. Finally assign that to this env var.
- openssl base64 < path/to/key.p8 | tr -d '\n' | pbcopy
10. Update the Fastfile script to build the app and upload it to Appstore Connect
Make sure to change the app_identifier as well and the scheme .
Also mind the call to setup_ci . This fastlane action configures the keychain on the CI and a few other options. Locally this is not needed and it's not run by default, because you have your own keychain set up.
This should be enough for you to upload your app locally without having to open Xcode again. So if you want to run it on your CD server, just make sure you install Fastlane, set all your secrets and let them available for the Fastlane script to use. And then just run the command:
- fastlane deploy
Onboarding new developers
New developers entering your team won't have to do any of the heavy lifting you've done. All they got to do is pull the project, set up their env variables to read from the certificates repo and make sure that on Xcode the provisioning profiles selected are the ones starting with match . This could be committed to your project.
If they're simply reading the certificates and don't have to write any, then they should just fill the MATCH_PASSWORD you will share with them and the storage access such as GIT_BASIC_AUTHORIZATION . This last one is better if they generate a personal access token for their own accounts.
If they want to install the app on a physical device, then they or you should add their device ids on the Apple developer portal. Now the certificates must be downloaded again. So the person responsible for generating new certificates should just run:
- fastlane generate_new_certificates
Finally, ask them to run the command below and they should be good to go.
- bundle install
- fastlane certificates
I told most of it throughout the post, but the key takeaways are:
- Not every developer should have the password for the shared Apple account, otherwise when they leave they will still have access to deploying an app.
Since only some developers should have access to generate new certificates due to the topic above, then only some developers should have write access to the storage you will be storing the certificates.
The tokens added to the .env.default should not be committed to a git repository. In order to use on the CI/CD, store them as secrets.
- The APP_STORE_CONNECT_API_* keys shouldn't be shared with anyone. They belong to the CI/CD server and are supposed to be used locally only for tests. If by any chance it gets leaked, don't panic. Revoke it, generate a new one and update the env vars/secrets.
Just before finishing, I’d like to thanks a lot Leandro Tozzetti and Michael Douglas, who helped me understand some of the concepts and the do’s/don’ts. I also appreciate many of existing articles, videos and docs. They were very helpful and if this article was possible it was only because of those materials.
All the code included in this article was written by Douglas Iacovelli
Related Page: Hire Core Data Developers