Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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.

like image 615
Reid Main Avatar asked Sep 13 '16 20:09

Reid Main


2 Answers

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

like image 178
andxyz Avatar answered Oct 23 '22 07:10

andxyz


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 |
…
like image 39
cbowns Avatar answered Oct 23 '22 08:10

cbowns