Fastlane Match environment variables are not picked up by build_app - ios

I started using fastLane and match for codesigning on jenkins. match is able to successfully create the certificates and provisioning profile. The build_app step however fails since the pbxproj file is setting the CODE_SIGN_STYLE to Automatic. I want to achieve the build without modifying the pbxproj file since the devs use automatic signing.
FastFile
lane :upload_debug_test_flight do
setup_jenkins
match
build_app(scheme: "MyWork Dev", clean: true, export_method: "app-store")
upload_to_testflight(.....)
end
Match file:
git_url("git#github.mywork/cert_repo.git")
storage_mode("git")
type("appstore")
api_key_path("./test.json")
app_identifier(["com.mywork.mywork-test"])
username("developer#mywork.com")
In our project.pbxproj we have
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
PROVISIONING_PROFILE_SPECIFIER= ''
Also tried the following, but still gym/build_app is not picking the match env variables:
build_app(
skip_profile_detection: true,
export_method: "app-store",
export_options:{
signingStyle: "manual",
provisioningProfiles:{
"com.mywork.mywork-test": "match AppStore com.mywork.mywork-test"
}
}
)

Gym (build_app) uses the provisioning profile mapping defined by Match for archiving (export_options), but not for building the app (these are two different steps).
Thus, you need to either configure your Xcode project to use specific profiles, or update the PROVISIONING_PROFILE_SPECIFIER value before calling build_app.
If developers only use the Debug configuration, you can specify different settings between Debug and Release. This way, you can keep the Automatic option for the Debug configuration and specify the code signing identity and profile manually for the Release configuration.
If you don't want to touch your Xcode project at all and define everything dynamically from fastlane, you can use the update_code_signing_settings action to use the provisioning profile managed by Match:
match(...)
profile_mapping = Actions.lane_context[SharedValues::MATCH_PROVISIONING_PROFILE_MAPPING]
update_code_signing_settings(
use_automatic_signing: false,
path: "path/to/your/project.xcodeproj",
profile_name: profile_mapping['app_identifier'] # app_identifier could be an environment variable: ENV['APP_ID']
)
build_app(...)
Another solution is to pass the PROVISIONING_PROFILE_SPECIFIER variable to the xcargs option. Note that it will update the value in all your targets, so it may not work if you have an app extension with a different profile for example.
build_app(
...
xcargs: "PROVISIONING_PROFILE_SPECIFIER='profile_name'"
)

Related

error: exportArchive: Code signing "MyFramework.framework" failed in fastlane build

Archive succeeded but export failed through Fastlane build.
But the same export is working fine through Xcode because Xcode is not even asking for MyFrameworkIOS to sign.
I have two ways in mind to get this resolution:
How to avoid signing MyFrameworkIOS when building through fastlane in build machine? Because as you can see above, when building through xcode then MyFrameworkIOS signing is not required at all.
If we need to sign it then how to sign MyFrameworkIOS which is our own Framework created separately and being embedded in MyProject?
Fastfile:
default_platform(:ios)
platform :ios do
desc "Build the application"
lane :testflightbuild do
build_app(
scheme: "MyScheme",
workspace: "MyProject.xcworkspace",
export_method: "app-store",
export_options: {
},
include_bitcode: true
)
end
end
Thanks for helping in advance.

Fastlane selecting wrong provisioning profile

I've configured my iOS project with 2 targets and several configurations (6 for the 1st target, debug and release for the 2nd target).
Each of the release configurations has different bundleID, hence the appropriate adhoc distribution provisioning profiles are selected (in the gym command):
desc "Build target1-config1"
lane :deployTarget1 do
gym(
workspace: "myProj-ios.xcworkspace",
scheme: "target1-config1",
configuration: "target1-Release",
export_method: "ad-hoc",
export_options: {
provisioningProfiles: {
"com.target1.config1" => "AdHocProvProfile1"
}
},
output_directory: "./build",
output_name: "target1-config1.ipa"
)
firebase_app_distribution(
app: "xxxxxxxx",
groups: "ios_app_testers",
release_notes: "Automatic dev build from develop",
firebase_cli_path: "/usr/local/bin/firebase",
debug: true
)
end
When trying to build target2 with AdhocProvProfile2, I receive an error. It looks like fastlane is not properly selecting the provProfile (and bundleID!). Additionally, in project settings the profiles are selected properly. What could be causing the issue? There is no external gym file.
There seems to be a mismatch between your provided `export_method` in gym
[11:15:55]: and the selected provisioning profiles. You passed the following options:
[11:15:55]: export_method: ad-hoc
[11:15:55]: Bundle identifier: com.target1.config1
[11:15:55]: Profile name: Target1 Development ProvProfile
[11:15:55]: Profile type: development

iOS and Firebase app distribution doesn't want to sign app with development profile and distribute it

I have problem with firebase app distribution.
I am using Xcode 11 and there are new iOS Development certificates, namely Apple Development certificates.
I have added fastlane, added plugin to fastlane for firebase-app-distribution.
But when I am executing my lane to distribute application there is error
note: Using new build system
[19:55:21]: ▸ note: Planning build
[19:55:21]: ▸ note: Constructing build description
[19:55:21]: ▸ error: No profile for team 'TEAM_ID' matching 'App Name Development' found: Xcode couldn't find any provisioning profiles matching 'TEAM_ID/App Name Development'. Install the profile (by dragging and dropping it onto Xcode's dock item) or select a different one in the Signing & Capabilities tab of the target editor. (in target 'AppNameDev' from project 'AppName')
I have similar configuration and fastlane lane with this plugin for other app but run in Xcode 10, and I think it has old certificates iOS Development not new one Apple Development and it builds and distribute correctly.
I can build this app using Archive, export .ipa and distribute it manually via firebase console and it works.
I have also such error informations
There seems to be a mismatch between your provided `export_method` in gym
[19:55:21]: and the selected provisioning profiles. You passed the following options:
[19:55:21]: export_method:
[19:55:21]: Bundle identifier: com.company.AppNameDev
[19:55:21]: Profile name: App Name Development
[19:55:21]: Profile type: development
So It just suggest profile name and type and bundle id that I've already correctly types in my Fastfile file in build_ios_app
desc "Firebase App Distribution to testers"
lane :firebase_distribution do
build_ios_app(
workspace: "AppName.xcworkspace",
configuration: "Release",
scheme: "AppName Dev",
silent: true,
clean: true,
output_directory: "firebase-builds",
output_name: "appname.ipa",
sdk: "iphoneos13.1",
export_options: {
method: "development",
provisioningProfiles: {
"com.company.AppNameDev" => "App Name Development"
}
}
)
firebase_app_distribution(
app: "<id goes here>",
testers_file: "fastlane/crashlytics_testers.txt",
release_notes: "Lots of amazing new features to test out!",
firebase_cli_path: "/usr/local/bin/firebase"
)
end
end

Fastlane Gym change provisioning profile only for one target

I am trying to setup Jenkins with fastlane. I got two targets in my project - main app and watch kit extension. When I try to change profile for Ad Hoc signing with xcargs, gym change profile for all targets and my builds fail.
This is my gym command.
gym(scheme: "MyApp",
workspace: "MyApp.xcworkspace",
xcargs: "PROVISIONING_PROFILE_SPECIFIER='MyApp Ad Hoc'")
This is output.
Building MyApp/MyApp WatchKit App [Release]
[08:34:48]: ▸ Check Dependencies
[08:34:48]: ▸ ❌ Provisioning profile "MyApp Ad Hoc" doesn't match the entitlements file's value for the application-identifier entitlement.
How to change profile only for a specific target?
Thank you.
You should use the provisioningProfiles option as follows:
gym(
...
export_options:{
signingStyle: "manual",
provisioningProfiles:{
"com.myapp.iosapp": "match AdHoc com.myapp.iosapp"
}
You do not need export_options at all, if you correctly define sigh for every target.
cert()
sigh(
adhoc: options[:adhoc],
app_identifier: options[:bundle_id],
provisioning_name: options[:provisioning],
ignore_profiles_with_different_name: true,
)
sigh(
adhoc: options[:adhoc],
app_identifier: options[:share_bundle_id],
provisioning_name: options[:share_provisioning],
ignore_profiles_with_different_name: true,
)
build_ios_app(
workspace: PLZ_WORKSPACE,
scheme: options[:scheme],
clean: true,
export_method: options[:adhoc] ? "ad-hoc" : "app-store",
export_xcargs: "-allowProvisioningUpdates",
output_directory: OUTPUT_PATH,
)
Remember that this way you need to manually install your provisioning profiles on CI machine or wherever you gonna run this out.

Can you pass environment variables into xcodebuild?

I have two Jenkins jobs that run our functional tests. One job is for whenever something is submitted for code review and the other job runs whenever something is pushed to master.
Because these are functional tests they test entire flows of the application which end up modifiying the user state. The issue we are having right is that every job uses the same account so whenever two Jenkins jobs are running in parallel they modify the same account which can put them in an unexpected state and fail the test.
My plan was to use Jenkins' BUILD_NUMBER environment variable and by applying a bit of arthimetic to it I could have a guaranteed unique number for the job. This unique number could then be passed into xcodebuild as an environment variable and the tests could use this number to ensure that every Jenkins' is working on a unique account.
The problem is that I cannot find any way to pass environment variables into xcodebuild. I know it is possible for you to pass in user-defined build settings via xcodebuild (or xcargs if you're using Fastlane) but those values do not seem to be accessible as environment variables. They are accessible by the preprocessor and so you could use it to export the value to your Info.plist and then read it from there. But then you have baked these value into your binary and it cannot be changed unless you rebuild it which is not ideal. Also at this point in time I could just have Jenkins write to a file on disk and have the tests read from it. It is essentially the same functionality and saves me from having to pass in build settings.
I remember using something like GCC_PREPROCESSOR_DEFINITIONS to pass my own var
I had to shell escape the quotes. I ended up coding it into my fastlane build file.
in ruby it looked like this:
tmp_other_flags = {
GCC_PREPROCESSOR_DEFINITIONS: '"DISABLE_PUSH_NOTIFICATIONS=1"',
TARGETED_DEVICE_FAMILY: '1',
DEBUG: '1'
}
other_flags = tmp_other_flags.map do |k, v|
"#{k.to_s.shellescape}=#{v.shellescape}"
end.join ' '
puts "___ Custom Flags also know as xcargs:"
puts other_flags
gym(
clean: true,
silent: false,
project: proj_xcodeproj_file,
archive_path: "build-ios-xcarchive",
destination: 'generic/platform=iOS',
use_legacy_build_api: true,
output_directory: 'build-ios',
output_name: "MyApp.ipa",
export_method: 'ad-hoc',
codesigning_identity: 'iPhone Distribution: company (12345)',
provisioning_profile_path: './dl_profile_com.company.myapp.iphone.prod_ad_hoc.mobileprovision',
scheme: 'MyApp',
configuration: 'Debug',
xcargs: other_flags
)
it ended up getting called in the shell something like this:
set -o pipefail && xcodebuild -scheme 'MyApp' -project 'platforms/ios/MyApp.xcodeproj' -configuration 'Debug' -destination 'generic/platform=iOS' -archivePath 'build-ios-xcarchive.xcarchive' GCC_PREPROCESSOR_DEFINITIONS=\"DISABLE_PUSH_NOTIFICATIONS\=1\" TARGETED_DEVICE_FAMILY=1 DEBUG=1 clean archive CODE_SIGN_IDENTITY='iPhone Distribution: My Company (Blah)' | tee '/Users/andxyz/Library/Logs/gym/MyApp-MyApp.log' | xcpretty
xcodebuild - how to define preprocessor macro?
So, perhaps you could pull in your own environment variable using ruby inside of fastlane. by adding your var into the GCC_PREPROCESSOR_DEFINITIONS section
ruby can access the environment, for example:
ENV.fetch('TERM_PROGRAM') #returns "iTerm.app" on my machine
so following along with above:
tmp_other_flags = {
GCC_PREPROCESSOR_DEFINITIONS: "MY_VARIABLE=#{ENV.fetch('MY_VARIABLE')}" ,
TARGETED_DEVICE_FAMILY: '1',
DEBUG: '1'
}
HTH
Via #alisoftware, you can use xcargs to pass additional variables in:
gym(
scheme: scheme,
xcargs: {
:PROVISIONING_PROFILE => 'profile-uuid',
:PROVISIONING_PROFILE_SPECIFIER => 'match AppStore com.bigco.App'
},
codesigning_identity: "iPhone Distribution: BigCo, Inc. ()",
)
emits this during the build:
+---------------------+-------------------------------------------------------------------------------------------------+
| Summary for gym 2.53.1 |
+---------------------+-------------------------------------------------------------------------------------------------+
| scheme | Bespoke-iOS |
| xcargs | PROVISIONING_PROFILE=profile-uuid PROVISIONING_PROFILE_SPECIFIER=match\ AppStore\ com.bigco.App |
…

Resources