你可以将环境变量传递给xcodebuild吗?

Posted

技术标签:

【中文标题】你可以将环境变量传递给xcodebuild吗?【英文标题】:Can you pass environment variables into xcodebuild? 【发布时间】:2016-09-13 20:59:31 【问题描述】:

我有两个 Jenkins 作业来运行我们的功能测试。一个作业是在提交代码审查时运行,另一个作业是在推送到 master 时运行。

因为这些是功能测试,所以它们会测试最终修改用户状态的应用程序的整个流程。我们遇到的问题是每个作业都使用同一个帐户,因此每当两个 Jenkins 作业并行运行时,它们都会修改同一个帐户,这可能会使它们处于意外状态并导致测试失败。

我的计划是使用 Jenkins 的 BUILD_NUMBER 环境变量,并通过对它应用一点算法,我可以保证工作的唯一编号。然后可以将此唯一编号作为环境变量传递给 xcodebuild,测试可以使用此编号来确保每个 Jenkins 都在使用唯一帐户。

问题是我找不到将环境变量传递到 xcodebuild 的任何方法。我知道您可以通过 xcodebuild(或 xcargs,如果您使用 Fastlane)传递用户定义的构建设置,但这些值似乎无法作为环境变量访问。预处理器可以访问它们,因此您可以使用它将值导出到 Info.plist,然后从那里读取它。但是随后您已将这些值烘焙到您的二进制文件中,除非您重建它,否则它无法更改,这并不理想。同样在这个时间点,我可以让 Jenkins 写入磁盘上的文件并从中读取测试。它本质上是相同的功能,让我不必传递构建设置。

【问题讨论】:

【参考方案1】:

我记得使用类似 GCC_PREPROCESSOR_DEFINITIONS 的东西来传递我自己的 var

我不得不壳转义引号。我最终将它编码到我的 fastlane 构建文件中。

在 ruby​​ 中它看起来像这样:

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
)

它最终在 shell 中被调用,如下所示:

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?

所以,也许您可​​以在 fastlane 中使用 ruby​​ 来引入您自己的环境变量。通过将您的 var 添加到 GCC_PREPROCESSOR_DEFINITIONS 部分

ruby可以访问环境,例如:

ENV.fetch('TERM_PROGRAM') #returns "iTerm.app" on my machine

所以跟着上面的:

tmp_other_flags = 
  GCC_PREPROCESSOR_DEFINITIONS: "MY_VARIABLE=#ENV.fetch('MY_VARIABLE')" ,
  TARGETED_DEVICE_FAMILY: '1',
  DEBUG: '1'

HTH

【讨论】:

我们在 Fastfile gym( scheme: options[:scheme], configuration: options[:config], use_legacy_build_api: options[:ad_hoc], clean: true, xcargs: "GCC_PREPROCESSOR_DEFINITIONS='$inherited GIT_BRANCH=#branch'" ) 中使用了类似的东西至于使用 NSProcessInfo 访问的运行时变量,我可以发誓有办法,但似乎找不到它 这是我所指的机制“我发现的唯一能力是传递用户定义的构建设置,然后您可以将其输出到 Info.plist 并从那里提取信息” .我也在 Fastfile 中使用了 xcargs 参数,但无论如何我都找不到,因此我传递给 xcargs 的是环境变量,而不是只能由预处理器宏访问的东西。【参考方案2】:

通过@alisoftware,你可以使用xcargs来传递额外的变量:

gym(
  scheme: scheme,
  xcargs: 
    :PROVISIONING_PROFILE => 'profile-uuid',
    :PROVISIONING_PROFILE_SPECIFIER => 'match AppStore com.bigco.App'
  ,
  codesigning_identity: "iPhone Distribution: BigCo, Inc. ()",
)

在构建期间发出这个:

+---------------------+-------------------------------------------------------------------------------------------------+
|                                             Summary for gym 2.53.1                                                    |
+---------------------+-------------------------------------------------------------------------------------------------+
| scheme              | Bespoke-iOS                                                                                     |
| xcargs              | PROVISIONING_PROFILE=profile-uuid PROVISIONING_PROFILE_SPECIFIER=match\ AppStore\ com.bigco.App |
…

【讨论】:

以上是关于你可以将环境变量传递给xcodebuild吗?的主要内容,如果未能解决你的问题,请参考以下文章

将环境变量传递给多个命令

XCUITests - 通过命令行传递环境变量

将环境变量传递给 application.yml

将环境变量传递给 XCUITest

将用户定义的环境变量传递给 tomcat

如何将环境变量传递给前端 Web 应用程序?