I have a React Native app that I am pairing with Fastlane to build Android AABs and whatever the iOS equivalent is (IPAs?). I have already got the Android side of the build, codesigning and publishing to the Google Play Console working, and have gone through the whole process of setting up a Development Account with Google, submitting the AAB release to them, having them approve it, and getting my beta testers "Early Access" to the app from a closed track on Google Play.
My Fastfile for this project looks like this:
default_platform(:ios)
platform :ios do
desc "iOS Build"
lane :staging do
puts "iOS staging build"
gym(
scheme: "StagingScheme",
project: "./ios/myapp.xcodeproj"
)
end
end
platform :android do
desc "Android build"
lane :staging do
puts "Android staging build"
gradle(task: 'clean', project_dir: './android/')
gradle(
task: 'bundle',
build_type: 'Release',
project_dir: './android/'
)
end
end
As you can see, in the Android platform/lane, I use Gradle to clean the project and then bundle the release, which is what produces the codesigned AAB. I then log in to Google Play Console, create a new release under my closed track, manually upload the AAB, and submit the changes for Google to review. It is a process that is at least working!
Now I need to do the same exact thing inside the iOS platform/lane up above. It sounds like gym
is a Fastlane command that does this for me: I'm happy to use it if its easy to actually use, but I am not married to it.
All I'm looking to do when I run fastlane ios staging
is:
With the current configuration, when I run fastlane ios staging
I get the following error:
/Users/myuser/myapp/ios/myapp.xcodeproj: error: No profiles for 'com.memyself.ios' were found: Xcode couldn't find any iOS App Development provisioning profiles matching 'com.memyself.ios'. Automatic signing is disabled and unable to generate a profile. To enable automatic signing, pass -allowProvisioningUpdates to xcodebuild. (in target 'myapp' from project 'myapp')
It may be important to note that the StagingScheme
value is just something I put in the Fastfile
, I didn't actually go into XCode or its CLI tools and create a scheme called StagingScheme
, so that may be an upstream omission on my part that is causing things to fail downstream. My understanding was that the scheme would be created for me if it didn't already exist, but if that's not the case, please just explain to me what I need to do to create it!
Having said that, it sounds like I need to add a profile somewhere? Can anyone explain to me what I would need to do here and what these profiles would look like? And if they have anything to do with codesigning or autosigning, please explain to me what autosigning is and how it compares to other codesigning options.
Again, at the end of the day I just need to clean the project, build an IPA and codesign it. Any way of getting to that state with Fastlane is a feasible solution, at least at this time! Thanks in advance!
First of all, yes, when we compile an iOS app the output is an IPA
file.
Apple "tracks" work differently. Every you upload a new build, you can add it to either:
Internal testing:
up to 100 members registered to your AppStore Connect, no app review required;External testing:
up to 10.000 members, invited via email or by clicking a link. Requires the build to go through Apple's review process (although it's usually a faster review than the one required to publish to the store.There is no way of separating Production
and Staging
builds on the AppStore Connect
or on TestFlight
.
If you really need that separation, maybe you could use version
or build
numbers to differ one from the other, and create an internal pattern for your project, so you know which one is which.
Another [and, in my opinion, better] option would be to use different Bundle Identifiers
for production and staging environments (which is the approach I use), but this requires having different apps registered to the AppStore Connect
. Their "lanes" will not be integrated. You could, potentially, upload a build to the Staging
app and to the Production
app at the same time, with the same version
and build number
on each, so you can more easily manually track which version on the Staging
app is equivalent to which version on the Production
app.
If you want to follow the second approach, lets first duplicate your main Target
on Xcode to create a Staging
target:
Targets
listMyApp Staging
staging
identifier you want to use.Then duplicate your Scheme, to work with the new target:
New scheme
For cleaning your build before generating a new one, you can add clean_build_artifacts
right in the beginning of the lane and clean: true
as a parameter to gym, so adapting your own lane code it would be:
platform :ios do
desc "iOS Build"
lane :staging do
puts "iOS staging build"
clean_build_artifacts
gym(
scheme: "StagingScheme",
project: "./ios/myapp.xcodeproj",
clean: true
)
end
end
(this is based on the lane code you provided, I haven't tested it)
The error you're getting is because you probably didn't install the Provisioning Profiles. Make sure you have Automatically manage signing
checked on the Signing and Capabilities
tab of your project on Xcode.
Also, check out the "Cert and Sigh" section of this document
to understand how to handle and provisioning profiles through FastLane. If you want to take a step further, check out match
.
Last but not least, check out upload_to_testflight
method. If you want to upload your IPAs
manually through the Transporter
app, you can, but there's really no benefit in doing so, so this upload_to_testflight method will save you some time.
Provisioning profiles basically determines who (which devices) can install an app, and which "capabilities" the app is allowed to use (like Push Notifications, SignIn with Apple, In-app purchase, background modes, bluetooth and so on). (More details about profiles here) (More details about capabilities here)
Back in the day, this used to be a bureaucratic process. You'd have to open Apple developer website, create a profile, select the options you needed, download it, install it and they would expire from time to time.
A few years ago, apple implemented the option to enable capabilities from Xcode, so you wouldn't have to worry about that yourself, but since you want to handle that from inside Github Actions, you can use Fastlane
's Sigh
About not using Xcode directly, keep in mind that these settings (automatically signing and enabling capabilities) only have to be set once for each Target of your app, and not with every build.
If you still need to update it from time to time (in case you are always, automatically, creating new Targets from scripts, like I am, you have a few options:
There's a file in your project called YOUR_PROJECT.entitlements
. It's an XML that holds information on the capabilities that are enabled, and you could easily edit this file using python or ruby before building the app, but to be honest, I'm not sure editing it without opening the project from Xcode afterwards will work (It'd be easy to test it, but this is the kind of setting you'll only change once in a while (usually if you add new features to your app), even if you're constantly adding new targets to your app.
(More information on entitlements here)
The the easiest one is to use FastLane's
enable_automatic_code_signing option.
Also, there's the wrong way: Xcode has a proprietary file format (.pbxproj), which is not always easy to manipulate, but some fields are very straightforward. Theoretically you could run a script that finds the CODE_SIGN_STYLE
key inside the file and changes its value to Automatic
, and changes DEVELOPMENT_TEAM
key to your Development Team's ID (you can find it on the account section of the Apple Developer website) I do not recommend this because it's very easy to break such file.*
Hope this helps!