|
I am pleased to announce the availability of Fastlane in your AWS Codebuild for MacOS in the area. AWS Codebuild is a fully managed service of continuous integration that compile the source code, launches tests and creates software packages ready to deploy.
Fastlane is a set of tools with an open source code designed to automate various aspects of mobile application development. It provides developers developing mobile applications centralized a set of task management tools such as code signature, screening, Beta distribution and business distribution. It integrates with popular platforms for continuous integration and continuous commitment (CI/CD) and workflows of support and Android development. Although Fastlane significant automation capacity, developers may encounter challenges during their settings and maintenance. Fastlane configuration can be complicated, especially for teams that are not familiar with the syntax and management system in Ruby. Maintaining Fastlane and its dependence of current requirements for Nobre efforts, as updating mobile platforms or third -party services may need to be for existing working postums.
When we introduced Codebuild for MacOS in August 2024, we knew that one of your challenges was the installation and Mainain Fastlane in your assembly. Although it was possible to manually install Fastlane in your own assembly environment, in AWS we remove not deciphered lifting from your infrastructure, so you can spend more time aspects that depend on your business. Starting today, Fastlane is installed by default and you can use a family command fastlane build
in your buildspec.yaml
File.
Signing Fastlane and Code
To distribute the app in the App Store, developers must sign their binary with a private key generated on the Apple Developer Portal. This private key, along with the certificate that verifies it, must be accessible during the assembly process. This may be a challenge for development teams, because the team members must share a private key (which allows you to deploy on selected test devices). In addition, there must be a distribution private key (which allows you to publish in the App Store) must be during the signing process before uploading a binary trade to the app.
Fastlane is a versatile assembly system in that it also helps to develop with development and distribution keys and certificates. Developers can use fastlane match
Share the signing materials in the team and make them safely and easily accessible on the machines of individual developers and the CI environment. match
It allows you to store private keys, certificates and profiles to ensure mobile devices on a secure stock storage. It ensures that the local assembly environment, whether a developer or a cloud server, remains synchronized with a shared storage. At the time of assembly it safely downloads the required certificates to sign your application and configure the assembly machine to allow codesign
The tool is to pick up.
match
It allows you to share signature secrets via GitHub, Gitlab, Google Cloud Storage, Azure Devops and Amazon Simple Storage Service (Amazon S3).
If you already use one of them and migrate your Codebuild projects, you have little to do. You just need to make sure that your Codebuild assembly environment has access to a shared storage (see step 3 in a demo).
We’ll see that it works
If you are new to Fastlane or Codebuild, we’ll see how it works.
For this demo I start with an existing iOS project. The project is already configured to be built on Codebuild. If you want to learn more details, you can return to my previous blog post, add to your continuous integration pipes with AWS Codebuild.
I’ll show you how to start in three steps:
- Import your existing signature materials into shared private Github Repot
- Configure
fastlane
Build and sign your project - Wears
fastlane
With Codebuild
Step 1: Import your signature materials
Most of fastlane
The documentation I read explains how to create a new pair of keys and a new certificate that you can start. Although this certainly applies to new projects, in real life you probably have your project and keys to sign. The first step is to import these existing signature materials.
Apple App Store uses different keys and certificates for development and distribution (there are also ad hoc and business certificates, but they are outside the range of this post). You must have three files for each use (a total of six files):
- Has
.mobileprovision
A file that you can create and download from the Apple Developer Console. The provision profile connects your identity, application identity and demands that the application could have. - Has
.cer
A file that is an Apple certified to verify your private key. You can download this from the Apple Developer Portal. Select a certificate and then select Pull down. - Has
.p12
A file that contains your private key. You can download the key when you create it on the Apple Developer. If you have not downloaded it, but you have it on your computer, you can export it from Apple Keychain. Note that keychain.App is hidden in MacOS 15.x. You can open itopen /System/Library/CoreServices/Applications/Keychain\ Access.app
. Select the key you want to export and right -click Export.
When you have these files, create a fastlane/Matchfile
File with the following content:
git_url("https://github.com/sebsto/secret.git")
storage_mode("git")
type("development")
# or use appstore to use the distribution signing key and certificate
# type("appstore")
Be sure to replace the URL of your Github Restitation Make sure this restilation is private. It will serve as a storage for your signature key and certificate.
Then I import my existing files with fastlane match import --type appstore
Command. I repeat the command for each environment: appstore
and development
.
First fastlane
Challenge me for my Apple ID user name and password. Connect to the App Store Connect and verify the validity of the certificates or create new ones if necessary. The session cookie is stored in ~/.fastlane/spaceship/<your apple user id>/cookie
.
fastlane match
He also asks for a password. It uses this password to generate the key to the crypt of signature materials on the storage. Do not forget this password because it will be used at the time of assembly to import the signature materials on the assembly machine.
Here is the command and its output in full:
fastlane match import --type appstore
(β) π
(16:43:54): Successfully loaded '~/amplify-ios-getting-started/code/fastlane/Matchfile' π
+-----------------------------------------------------+
| Detected Values from './fastlane/Matchfile' |
+--------------+--------------------------------------+
| git_url. | https://github.com/sebsto/secret.git |
| storage_mode | git |
| type | development |
+--------------+--------------------------------------+
(16:43:54): Certificate (.cer) path:
./secrets/sebsto-apple-dist.cer
(16:44:07): Private key (.p12) path:
./secrets/sebsto-apple-dist.p12
(16:44:12): Provisioning profile (.mobileprovision or .provisionprofile) path or leave empty to skip
this file:
./secrets/amplifyiosgettingstarteddist.mobileprovision
(16:44:25): Cloning remote git repo...
(16:44:25): If cloning the repo takes too long, you can use the `clone_branch_directly` option in match.
(16:44:27): Checking out branch master...
(16:44:27): Enter the passphrase that should be used to encrypt/decrypt your certificates
(16:44:27): This passphrase is specific per repository and will be stored in your local keychain
(16:44:27): Make sure to remember the password, as you'll need it when you run match on a different machine
(16:44:27): Passphrase for Match storage: ********
(16:44:30): Type passphrase again: ********
security: SecKeychainAddInternetPassword <NULL>: The specified item already exists in the keychain.
(16:44:31): π Successfully decrypted certificates repo
(16:44:31): Repo is at: '/var/folders/14/nwpsn4b504gfp02_mrbyd2jr0000gr/T/d20250131-41830-z7b4ic'
(16:44:31): Login to App Store Connect (sebsto@mac.com)
(16:44:33): Enter the passphrase that should be used to encrypt/decrypt your certificates
(16:44:33): This passphrase is specific per repository and will be stored in your local keychain
(16:44:33): Make sure to remember the password, as you'll need it when you run match on a different machine
(16:44:33): Passphrase for Match storage: ********
(16:44:37): Type passphrase again: ********
security: SecKeychainAddInternetPassword <NULL>: The specified item already exists in the keychain.
(16:44:39): π Successfully encrypted certificates repo
(16:44:39): Pushing changes to remote git repo...
(16:44:40): Finished uploading files to Git Repo (https://github.com/sebsto/secret.git)
I verify that Fastlane imported my signature material to my GIT restitution.
I can also configure my local machine to use these signature materials during the next assembly:
Β» fastlane match appstore
(β) π
(17:39:08): Successfully loaded '~/amplify-ios-getting-started/code/fastlane/Matchfile' π
+-----------------------------------------------------+
| Detected Values from './fastlane/Matchfile' |
+--------------+--------------------------------------+
| git_url | https://github.com/sebsto/secret.git |
| storage_mode | git |
| type | development |
+--------------+--------------------------------------+
+-------------------------------------------------------------------------------------------+
| Summary for match 2.226.0 |
+----------------------------------------+--------------------------------------------------+
| type | appstore |
| readonly | false |
| generate_apple_certs | true |
| skip_provisioning_profiles | false |
| app_identifier | ("com.amazonaws.amplify.mobile.getting-started") |
| username | xxxx@xxxxxxxxx |
| team_id | XXXXXXXXXX |
| storage_mode | git |
| git_url | https://github.com/sebsto/secret.git |
| git_branch | master |
| shallow_clone | false |
| clone_branch_directly | false |
| skip_google_cloud_account_confirmation | false |
| s3_skip_encryption | false |
| gitlab_host | https://gitlab.com |
| keychain_name | login.keychain |
| force | false |
| force_for_new_devices | false |
| include_mac_in_profiles | false |
| include_all_certificates | false |
| force_for_new_certificates | false |
| skip_confirmation | false |
| safe_remove_certs | false |
| skip_docs | false |
| platform | ios |
| derive_catalyst_app_identifier | false |
| fail_on_name_taken | false |
| skip_certificate_matching | false |
| skip_set_partition_list | false |
| force_legacy_encryption | false |
| verbose | false |
+----------------------------------------+--------------------------------------------------+
(17:39:08): Cloning remote git repo...
(17:39:08): If cloning the repo takes too long, you can use the `clone_branch_directly` option in match.
(17:39:10): Checking out branch master...
(17:39:10): Enter the passphrase that should be used to encrypt/decrypt your certificates
(17:39:10): This passphrase is specific per repository and will be stored in your local keychain
(17:39:10): Make sure to remember the password, as you'll need it when you run match on a different machine
(17:39:10): Passphrase for Match storage: ********
(17:39:13): Type passphrase again: ********
security: SecKeychainAddInternetPassword <NULL>: The specified item already exists in the keychain.
(17:39:15): π Successfully decrypted certificates repo
(17:39:15): Verifying that the certificate and profile are still valid on the Dev Portal...
(17:39:17): Installing certificate...
+-------------------------------------------------------------------------+
| Installed Certificate |
+-------------------+-----------------------------------------------------+
| User ID | XXXXXXXXXX |
| Common Name | Apple Distribution: Sebastien Stormacq (XXXXXXXXXX) |
| Organisation Unit | XXXXXXXXXX |
| Organisation | Sebastien Stormacq |
| Country | US |
| Start Datetime | 2024-10-29 09:55:43 UTC |
| End Datetime | 2025-10-29 09:55:42 UTC |
+-------------------+-----------------------------------------------------+
(17:39:18): Installing provisioning profile...
+-------------------------------------------------------------------------------------------------------------------+
| Installed Provisioning Profile |
+---------------------+----------------------------------------------+----------------------------------------------+
| Parameter | Environment Variable | Value |
+---------------------+----------------------------------------------+----------------------------------------------+
| App Identifier | | com.amazonaws.amplify.mobile.getting-starte |
| | | d |
| Type | | appstore |
| Platform | | ios |
| Profile UUID | sigh_com.amazonaws.amplify.mobile.getting-s | 4e497882-d80f-4684-945a-8bfec1b310b9 |
| | tarted_appstore | |
| Profile Name | sigh_com.amazonaws.amplify.mobile.getting-s | amplify-ios-getting-started-dist |
| | tarted_appstore_profile-name | |
| Profile Path | sigh_com.amazonaws.amplify.mobile.getting-s | /Users/stormacq/Library/MobileDevice/Provis |
| | tarted_appstore_profile-path | ioning |
| | | Profiles/4e497882-d80f-4684-945a-8bfec1b310 |
| | | b9.mobileprovision |
| Development Team ID | sigh_com.amazonaws.amplify.mobile.getting-s | XXXXXXXXXX |
| | tarted_appstore_team-id | |
| Certificate Name | sigh_com.amazonaws.amplify.mobile.getting-s | Apple Distribution: Sebastien Stormacq |
| | tarted_appstore_certificate-name | (XXXXXXXXXX) |
+---------------------+----------------------------------------------+----------------------------------------------+
(17:39:18): All required keys, certificates and provisioning profiles are installed π
Step 2: Fastlane configure to sign your project
I create a Fastlane configuration file fastlane/Fastfile
(You can use fastlane init
to start):
default_platform(:ios)
platform :ios do
before_all do
setup_ci
end
desc "Build and Sign the binary"
lane :build do
match(type: "appstore", readonly: true)
gym(
scheme: "getting started",
export_method: "app-store"
)
end
end
Make sure that setup_ci
The action is added to before_all
part Fastfile
for match
Correctly for a fun event. This action creates a fairy -tale keymade temporalry with the right permissions. Without this step, you can support assembly failure or non -contact results.
And I’m testing the local assembly with the command fastlane build
. I enter the password I used to import my keys and certificate, then I had the system assembled and signed my project. When everything is correctly configured, it creates a similar output.
...
(17:58:33): Successfully exported and compressed dSYM file
(17:58:33): Successfully exported and signed the ipa file:
(17:58:33): ~/amplify-ios-getting-started/code/getting started.ipa
+---------------------------------------+
| fastlane summary |
+------+------------------+-------------+
| Step | Action | Time (in s) |
+------+------------------+-------------+
| 1 | default_platform | 0 |
| 2 | setup_ci | 0 |
| 3 | match | 36 |
| 4 | gym | 151 |
+------+------------------+-------------+
(17:58:33): fastlane.tools finished successfully π
Step 3: Codebuild for using Fastlane Configuration
I will also create a project on Codebuild. I do not go to the guide step by step to help you. You can return to my previous post or Codebuild documentation.
There is only one Fastlane-Security configuration. For access to signing materials, Fastlane requires access to three secret values ββthat the variable environment:
MATCH_PASSWORD
The password I entered when importing the signature material. Fastlane uses this password to decrypt the encrypted files in Github RestitovingFASTLANE_SESSION
The Apple ID Cookie value, placed on~/.fastlane/spaceship/<your apple user id>/cookie
. The session is valid from a few hours to a few days. After the session of the session again re -office with the orderfastlane spaceauth
from the laptop and update the valueFASTLANE_SESSION
With a new value of cookies.MATCH_GIT_BASIC_AUTHORIZATION
Based on 64 coding your Github user name, followed by the large intestine, followed by a personal token verification (PAT) to access your private Github Restitament. You can generate PAT on the GITHUB console in your profile> Settings> Developer Settings> Personal Access Token. I use this command to generate the value of this environment with variable:echo -n my_git_username:my_git_pat | base64
.
Note that for each of these three values ββI can enter the name Amazon Resource Name (ARN) Secrets on AWS Secrets Manager or the value of a simple text. We strongly recommend using the Secrets Administrator to store security -sensitive values.
I’m a secure user, so with these commands I store three secrets in Secrets Manager:
aws --region $REGION secretsmanager create-secret --name /CodeBuild/MATCH_PASSWORD --secret-string MySuperSecretPassword
aws --region $REGION secretsmanager create-secret --name /CodeBuild/FASTLANE_SESSION --secret-string $(cat ~/.fastlane/spaceship/my_appleid_username/cookie)
aws --region $REGION secretsmanager create-secret --name /CodeBuild/MATCH_GIT_BASIC_AUTHORIZATION --secret-string $(echo -n my_git_username:my_git_pat | base64)
If your assembly project refers to the secrets stored in the Secrets Administrator, the service role must enable the project for the project secretsmanager:GetSecretValue
action. If you are a thing New role of services When you create your project, Codebuild includes this action to the default role for your compilation project. If the thing Existing service rolesYou must include this event in your service role separately.
For this demo I use this AWS Identity and Access Management (IAM):
{
"Version": "2012-10-17",
"Statement": (
{
"Effect": "Allow",
"Action": (
"secretsmanager:GetSecretValue"
),
"Resource": (
"arn:aws:secretsmanager:us-east-2:012345678912:secret:/CodeBuild/*"
)
}
)
}
After creating a project in the Codebuild section in the AWS Management Console, I will enter three variables. Note that the value is the name of the Secret in the Secrets Manager manager.
In your name you can also define the variable environment and their secret secret secret buildpsec.yaml
File.
I will further modify buildspec.yaml
File in the root of my project fastlane
Build and sign binary. My buildspec.yaml
The file now looks like this:
# buildspec.yml
version: 0.2
phases:
install:
commands:
- code/ci_actions/00_install_rosetta.sh
pre_build:
commands:
- code/ci_actions/02_amplify.sh
build:
commands:
- (cd code && fastlane build)
artifacts:
name: getting-started-$(date +%Y-%m-%d).ipa
files:
- 'getting started.ipa'
base-directory: 'code'
Rosetta and amplify scripts are obliged to receive amplify configuration for the backend. If you do not use AWS AMPLIFY in your project, you do not need them.
Note that there is nothing in the assembly file that downloads the key signatures or prepares a key piece in the assembly environment; fastlane match
He’ll do it for me.
I’ll add a new one buildspec.yaml
File and my ./fastlane
Directory on Git. I’m shaving and pushing these files. git commit -m "add fastlane support" && git push
When everything goes well, I see assembly running on Codebuild and Succeed message.
Prices and availability
Fastlane is indeed pre -installed in advance without additional costs for all MacOS images used by Codebuild, in all regions where Codebuild for MacOS is available. At the time of this writing it is the US East (Ohio, N. Virginia), US West (Oregon), Asia Pacific (Sydney) and Europe (Frankfurt).
In my experience it takes a little time to configure fastlane match
correctly. When it is configured, it is a straightforward functioning on Codbuilds. Before you try it on Codbuild, make sure it works on a local computer. When something goes wrong on Codebuild, check the environmental variables and make sure Codebuild has access to the AWS Secrets Manager secrets.
Now go build (on macOS)!