Mastering iOS Automation: Fastlane with Automatic and Manual Signing
For iOS developers, app signing is a crucial, yet often tedious, process.
Xcode's "Automatically manage signing" feature offers a convenient way to
simplify this process. However, when combined with the automation tool
Fastlane, it presents both opportunities and challenges. This article
explores how to configure Fastlane in a project with automatic Xcode
signing, the problems that can arise, and how to solve them. Someone also
presents a recommended hybrid approach.
Xcode's Automatic Signing: A Double-Edged Sword
The automatic signing feature in Xcode is particularly appealing for solo
developers and small teams. It independently handles the creation and
management of provisioning profiles and certificates, significantly
reducing the initial setup effort.[1] For local development and testing on registered devices, this approach
is often sufficient.
However, the limitations of automatic signing become apparent in larger
teams and especially in Continuous Integration/Continuous Deployment
(CI/CD) environments. Since each developer could potentially generate
their own signing identities, this can lead to inconsistencies and
hard-to-trace errors. This is where Fastlane comes in to standardize and
automate the process.
Configuring Fastlane with Automatic Signing
Fastlane can indeed work with Xcode's automatic signing. The key is in
the configuration of the build_app action (also known as gym) in the Fastfile. Using the xcargs parameter, you can instruct Xcode to use automatic signing and
update provisioning profiles if necessary.
lane :build_with_auto_signing do
build_app(
workspace: "YourApp.xcworkspace",
scheme: "YourApp",
xcargs: "-allowProvisioningUpdates"
)
end
This configuration is useful for development builds that, for example,
are to be distributed to a small internal team of testers.
Potential Issues and Their Solutions
When combining Fastlane and automatic Xcode signing, various problems can
occur:
-
"No profile for team" Error: This error frequently occurs in CI/CD environments, as
there is often no Xcode GUI available to manage signing
automatically.[2][3][4]
-
Solution: For CI/CD builds, it is strongly recommended to
switch to a manual signing method like fastlane match.
-
"Code signing is required" Error: This message appears when no valid signing identity has
been found for a specific build target.[5][6][7] This can happen if automatic signing is disabled for a
particular target or if Fastlane does not have the correct
permissions.
-
Solution: Ensure that you have consistent signing settings
across all targets in your project.[8] In many cases, disabling automatic signing and
explicitly specifying the provisioning profiles is the
more reliable method.[6]
-
Inconsistent Builds: If different developers on a team use automatic signing, it
can lead to builds that are signed with different certificates and
profiles. This makes traceability difficult and can lead to
problems when publishing to the App Store.
-
"errSecInternalComponent Command CodeSign failed with a nonzero
exit code 65" Error: This error frequently occurs in CI/CD environments, as it need to read
your keychain but found out that it has no permissions to do that.
-
Solution: You should execute this "security unlock-keychain -p
YOUR_LOGIN_PASSWORD_HERE login.keychain" to grant the permission to
terminal.[9]
The Recommended Approach: A Hybrid Strategy
The best practice for most teams is a hybrid approach that combines the
advantages of both worlds:
-
Automatic Signing for Local Development: Developers can keep automatic signing enabled in their
local Xcode environment to quickly and easily test on their
devices.
-
Manual Signing with For all builds intended for beta testing (e.g., via
TestFlight) or for App Store publication, a manual signing process
using fastlane match should be used. match stores all certificates and provisioning profiles in a
central, encrypted Git repository, giving everyone on the team and
the CI/CD environment access to the same, consistent signing
data.
Example of a Fastfile for the Hybrid Approach
A Fastfile for this approach could look like this:
default_platform(:ios)
platform :ios do
desc "Builds the app for local testing using automatic signing"
lane :dev_build do
build_app(
workspace: "YourApp.xcworkspace",
scheme: "YourApp-Dev",
xcargs: "-allowProvisioningUpdates"
)
end
desc "Builds and uploads the app to App Store Connect using manual signing"
lane :release do
disable_automatic_code_signing(path: "YourApp.xcodeproj")
match(type: "appstore", readonly: true)
build_app(
workspace: "YourApp.xcworkspace",
scheme: "YourApp-Release",
export_method: "app-store",
export_options: {
provisioningProfiles: {
"com.yourcompany.yourapp" => "match AppStore com.yourcompany.yourapp"
}
}
)
upload_to_app_store
enable_automatic_code_signing(path: "YourApp.xcodeproj")
end
end
In this configuration, the dev_build lane will use Xcode's automatic signing. The release lane, on the other hand, temporarily disables automatic signing,
uses match to synchronize signing data, and builds the app with the explicitly
specified provisioning profiles. After the build process, automatic
signing is re-enabled so as not to disrupt developers in their local
environment.
While the Hybrid Approach is not Necessary
It may resolve your problem, but the match method is not what I want. I really do not need to maintain another repository to store the certificates and profiles. After I tried to add provisioningProfiles to the export_options, it worked as a charm. In this way, what you need to do is creating the profiles it need and download those profiles to local machine by Xcode Account Setting.
If you only need one profile, the export_options is not even necessary at all. I need this just because there are 2 profiles in this project.
default_platform(:ios)
platform :ios do
desc "Builds and uploads the app to App Store Connect using manual signing"
lane :release do
match(type: "appstore", readonly: true)
build_app(
workspace: "YourApp.xcworkspace",
scheme: "YourApp-Release",
export_method: "app-store",
xcargs: "-allowProvisioningUpdates",
export_options: {
provisioningProfiles: {
"com.yourcompany.yourapp" => "match AppStore com.yourcompany.yourapp",
"com.yourcompany.yourwidget" => "match AppStore com.yourcompany.yourwidget"
}
}
)
upload_to_app_store
end
end
Conclusion
Automatic signing in Xcode is a useful tool for local development but
hits its limits in team and CI/CD environments. A combination of automatic
signing for development builds and a robust manual signing process
like fastlane match for release builds offers the best mix of convenience and
reliability. With the right configuration in the Fastfile, this approach can be seamlessly integrated into the development
workflow, ensuring consistent and error-free builds.
Sources
-
polpiella.dev
-
signmycode.com
-
stackoverflow.com
-
circleci.com
-
fastlane.tools
-
stackoverflow.com
-
stackoverflow.com
-
fastlane.tools
- stackoverflow.com
Comments
Post a Comment