fastlane 2.138.0 → 2.143.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (137) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE +1 -1
  3. data/README.md +75 -62
  4. data/cert/lib/cert/options.rb +12 -5
  5. data/cert/lib/cert/runner.rb +13 -0
  6. data/deliver/lib/deliver/options.rb +2 -2
  7. data/deliver/lib/deliver/runner.rb +13 -2
  8. data/deliver/lib/deliver/submit_for_review.rb +7 -1
  9. data/fastlane/lib/fastlane/action.rb +2 -2
  10. data/fastlane/lib/fastlane/actions/.hockey.rb.swp +0 -0
  11. data/fastlane/lib/fastlane/actions/.slack.rb.swp +0 -0
  12. data/fastlane/lib/fastlane/actions/.update_project_provisioning.rb.swp +0 -0
  13. data/fastlane/lib/fastlane/actions/README.md +2 -0
  14. data/fastlane/lib/fastlane/actions/app_store_build_number.rb +13 -5
  15. data/fastlane/lib/fastlane/actions/build_app.rb +157 -6
  16. data/fastlane/lib/fastlane/actions/build_ios_app.rb +28 -132
  17. data/fastlane/lib/fastlane/actions/build_mac_app.rb +46 -0
  18. data/fastlane/lib/fastlane/actions/cocoapods.rb +2 -2
  19. data/fastlane/lib/fastlane/actions/create_pull_request.rb +71 -2
  20. data/fastlane/lib/fastlane/actions/docs/{build_ios_app.md → build_app.md} +1 -1
  21. data/fastlane/lib/fastlane/actions/docs/frame_screenshots.md +22 -6
  22. data/fastlane/lib/fastlane/actions/docs/sync_code_signing.md +20 -4
  23. data/fastlane/lib/fastlane/actions/docs/upload_to_app_store.md.erb +10 -0
  24. data/fastlane/lib/fastlane/actions/ensure_git_branch.rb +1 -1
  25. data/fastlane/lib/fastlane/actions/ensure_xcode_version.rb +35 -7
  26. data/fastlane/lib/fastlane/actions/frame_screenshots.rb +2 -1
  27. data/fastlane/lib/fastlane/actions/get_github_release.rb +3 -0
  28. data/fastlane/lib/fastlane/actions/gradle.rb +43 -2
  29. data/fastlane/lib/fastlane/actions/gym.rb +3 -7
  30. data/fastlane/lib/fastlane/actions/import_from_git.rb +4 -0
  31. data/fastlane/lib/fastlane/actions/last_git_tag.rb +14 -5
  32. data/fastlane/lib/fastlane/actions/latest_testflight_build_number.rb +9 -3
  33. data/fastlane/lib/fastlane/actions/notarize.rb +183 -0
  34. data/fastlane/lib/fastlane/actions/run_tests.rb +5 -22
  35. data/fastlane/lib/fastlane/actions/s3.rb +5 -291
  36. data/fastlane/lib/fastlane/actions/set_github_release.rb +1 -1
  37. data/fastlane/lib/fastlane/actions/setup_ci.rb +14 -8
  38. data/fastlane/lib/fastlane/actions/spm.rb +8 -0
  39. data/fastlane/lib/fastlane/actions/swiftlint.rb +17 -2
  40. data/fastlane/lib/fastlane/actions/update_plist.rb +37 -2
  41. data/fastlane/lib/fastlane/actions/upload_symbols_to_crashlytics.rb +13 -3
  42. data/fastlane/lib/fastlane/actions/upload_to_app_store.rb +1 -0
  43. data/fastlane/lib/fastlane/actions/upload_to_play_store_internal_app_sharing.rb +78 -0
  44. data/fastlane/lib/fastlane/fast_file.rb +13 -3
  45. data/fastlane/lib/fastlane/helper/adb_helper.rb +1 -1
  46. data/fastlane/lib/fastlane/helper/s3_client_helper.rb +56 -0
  47. data/fastlane/lib/fastlane/plugins/plugin_manager.rb +1 -1
  48. data/fastlane/lib/fastlane/plugins/template/.rubocop.yml +2 -0
  49. data/fastlane/lib/fastlane/runner.rb +23 -18
  50. data/fastlane/lib/fastlane/server/socket_server_action_command_executor.rb +1 -1
  51. data/fastlane/lib/fastlane/version.rb +1 -1
  52. data/fastlane/swift/Deliverfile.swift +1 -1
  53. data/fastlane/swift/DeliverfileProtocol.swift +3 -3
  54. data/fastlane/swift/Fastlane.swift +429 -50
  55. data/fastlane/swift/FastlaneSwiftRunner/FastlaneSwiftRunner.xcodeproj/project.xcworkspace/xcuserdata/josh.xcuserdatad/UserInterfaceState.xcuserstate +0 -0
  56. data/fastlane/swift/Gymfile.swift +1 -1
  57. data/fastlane/swift/GymfileProtocol.swift +17 -1
  58. data/fastlane/swift/Matchfile.swift +1 -1
  59. data/fastlane/swift/MatchfileProtocol.swift +23 -3
  60. data/fastlane/swift/Precheckfile.swift +1 -1
  61. data/fastlane/swift/RubyCommand.swift +1 -1
  62. data/fastlane/swift/Scanfile.swift +1 -1
  63. data/fastlane/swift/ScanfileProtocol.swift +21 -1
  64. data/fastlane/swift/Screengrabfile.swift +1 -1
  65. data/fastlane/swift/Snapshotfile.swift +1 -1
  66. data/fastlane/swift/SnapshotfileProtocol.swift +9 -1
  67. data/fastlane_core/lib/fastlane_core/build_watcher.rb +6 -2
  68. data/fastlane_core/lib/fastlane_core/cert_checker.rb +28 -0
  69. data/fastlane_core/lib/fastlane_core/device_manager.rb +20 -0
  70. data/fastlane_core/lib/fastlane_core/helper.rb +7 -1
  71. data/fastlane_core/lib/fastlane_core/ipa_file_analyser.rb +1 -0
  72. data/fastlane_core/lib/fastlane_core/keychain_importer.rb +2 -0
  73. data/fastlane_core/lib/fastlane_core/project.rb +27 -0
  74. data/frameit/lib/frameit/commands_generator.rb +25 -0
  75. data/frameit/lib/frameit/config_parser.rb +31 -9
  76. data/frameit/lib/frameit/device.rb +90 -0
  77. data/frameit/lib/frameit/device_types.rb +121 -5
  78. data/frameit/lib/frameit/editor.rb +31 -40
  79. data/frameit/lib/frameit/offsets.rb +8 -1
  80. data/frameit/lib/frameit/options.rb +81 -54
  81. data/frameit/lib/frameit/runner.rb +17 -7
  82. data/frameit/lib/frameit/screenshot.rb +35 -47
  83. data/frameit/lib/frameit/template_finder.rb +15 -12
  84. data/gym/lib/gym/code_signing_mapping.rb +32 -3
  85. data/gym/lib/gym/detect_values.rb +34 -2
  86. data/gym/lib/gym/generators/build_command_generator.rb +1 -0
  87. data/gym/lib/gym/generators/package_command_generator.rb +4 -0
  88. data/gym/lib/gym/generators/package_command_generator_xcode7.rb +47 -17
  89. data/gym/lib/gym/module.rb +8 -0
  90. data/gym/lib/gym/options.rb +25 -1
  91. data/gym/lib/gym/runner.rb +64 -24
  92. data/match/lib/match/change_password.rb +1 -1
  93. data/match/lib/match/encryption.rb +4 -0
  94. data/match/lib/match/encryption/openssl.rb +1 -1
  95. data/match/lib/match/generator.rb +17 -3
  96. data/match/lib/match/importer.rb +2 -2
  97. data/match/lib/match/module.rb +5 -2
  98. data/match/lib/match/nuke.rb +59 -17
  99. data/match/lib/match/options.rb +38 -15
  100. data/match/lib/match/runner.rb +24 -8
  101. data/match/lib/match/setup.rb +1 -1
  102. data/match/lib/match/spaceship_ensure.rb +19 -9
  103. data/match/lib/match/storage.rb +4 -0
  104. data/match/lib/match/storage/git_storage.rb +5 -2
  105. data/match/lib/match/storage/google_cloud_storage.rb +2 -2
  106. data/match/lib/match/storage/s3_storage.rb +162 -0
  107. data/pilot/lib/pilot/.manager.rb.swp +0 -0
  108. data/pilot/lib/pilot/build_manager.rb +55 -15
  109. data/pilot/lib/pilot/options.rb +3 -1
  110. data/scan/lib/scan/detect_values.rb +6 -1
  111. data/scan/lib/scan/manager.rb +18 -1
  112. data/scan/lib/scan/options.rb +28 -1
  113. data/scan/lib/scan/runner.rb +11 -3
  114. data/scan/lib/scan/slack_poster.rb +1 -1
  115. data/scan/lib/scan/test_command_generator.rb +9 -5
  116. data/screengrab/lib/screengrab/runner.rb +31 -18
  117. data/snapshot/lib/snapshot/fixes/simulator_shared_pasteboard.rb +16 -0
  118. data/snapshot/lib/snapshot/options.rb +12 -1
  119. data/snapshot/lib/snapshot/simulator_launchers/launcher_configuration.rb +2 -0
  120. data/snapshot/lib/snapshot/simulator_launchers/simulator_launcher_base.rb +13 -0
  121. data/spaceship/lib/spaceship/connect_api/.DS_Store +0 -0
  122. data/spaceship/lib/spaceship/connect_api/models/beta_feedback.rb +4 -0
  123. data/spaceship/lib/spaceship/connect_api/models/build.rb +4 -0
  124. data/spaceship/lib/spaceship/connect_api/models/build_beta_detail.rb +5 -0
  125. data/spaceship/lib/spaceship/connect_api/models/certificate.rb +2 -0
  126. data/spaceship/lib/spaceship/connect_api/testflight/testflight.rb +6 -0
  127. data/spaceship/lib/spaceship/portal/.certificate.rb.swp +0 -0
  128. data/spaceship/lib/spaceship/portal/app.rb +11 -2
  129. data/spaceship/lib/spaceship/tunes/iap.rb +11 -11
  130. data/spaceship/lib/spaceship/tunes/iap_detail.rb +7 -3
  131. data/spaceship/lib/spaceship/tunes/iap_families.rb +12 -1
  132. data/spaceship/lib/spaceship/tunes/iap_family_details.rb +26 -17
  133. data/spaceship/lib/spaceship/tunes/iap_status.rb +5 -1
  134. data/spaceship/lib/spaceship/tunes/tunes_client.rb +2 -2
  135. data/supply/lib/supply/client.rb +26 -0
  136. data/supply/lib/supply/uploader.rb +28 -0
  137. metadata +64 -20
@@ -73,7 +73,7 @@ fastlane match init
73
73
 
74
74
  <img src="/img/actions/match_init.gif" width="550" />
75
75
 
76
- You'll be asked if you want to store your code signing identities inside a **Git repo**, or on **Google Cloud**.
76
+ You'll be asked if you want to store your code signing identities inside a **Git repo**, **Google Cloud** or **Amazon S3**.
77
77
 
78
78
  #### Git Storage
79
79
 
@@ -142,6 +142,18 @@ Example content (for more advanced setups check out the [fastlane section](#fast
142
142
  google_cloud_bucket_name("major-key-certificates")
143
143
  ```
144
144
 
145
+ #### Amazon S3
146
+
147
+ Use [Amazon S3](https://aws.amazon.com/s3/) for a fully hosted solution for your code signing identities. Certificates are stored on S3, inside a storage bucket you provide. You can also directly access the files using the web console.
148
+
149
+ This will create a `Matchfile` in your current directory (or in your `./fastlane/` folder).
150
+
151
+ Example content (for more advanced setups check out the [fastlane section](#fastlane)):
152
+
153
+ ```ruby-skip-tests
154
+ s3_bucket("ios-certificates")
155
+ ```
156
+
145
157
  ### Multiple teams
146
158
 
147
159
  _match_ can store the codesigning files for multiple development teams:
@@ -155,9 +167,9 @@ match(git_branch: "team1", username: "user@team1.com")
155
167
  match(git_branch: "team2", username: "user@team2.com")
156
168
  ```
157
169
 
158
- #### Google Cloud Storage
170
+ #### Google Cloud or Amazon S3 Storage
159
171
 
160
- If you use Google Cloud Storage, you don't need to do anything manually for multiple teams. Just use Google Cloud Storage, and the top level folder will be the team ID.
172
+ If you use Google Cloud or Amazon S3 Storage, you don't need to do anything manually. Just use Google Cloud or Amazon S3 Storage, and the top level folder will be the team ID.
161
173
 
162
174
  ### Run
163
175
 
@@ -194,7 +206,7 @@ fastlane action match
194
206
 
195
207
  #### Handle multiple targets
196
208
 
197
- _match_ can use the same one Git repository or Google Cloud Storage for all bundle identifiers.
209
+ _match_ can use the same one Git repository, Google Cloud, or Amazon S3 Storage for all bundle identifiers.
198
210
 
199
211
  If you have several targets with different bundle identifiers, supply them as a comma-separated list:
200
212
 
@@ -419,6 +431,10 @@ Once you've decided which approach to take, all that's left to do is to set your
419
431
 
420
432
  Accessing Google Cloud Storage from your CI system requires you to provide the `gc_keys.json` file as part of your build. How you implement this is your decision. You can inject that file during build time.
421
433
 
434
+ #### Amazon S3 Storage access
435
+
436
+ Accessing Amazon S3 Storage from your CI system requires you to provide the `s3_region`, `s3_access_key`, `s3_secret_access_key` and `s3_bucket` options (or environment variables), with keys that has read access to the bucket.
437
+
422
438
  ### Nuke
423
439
 
424
440
  If you never really cared about code signing and have a messy Apple Developer account with a lot of invalid, expired or Xcode managed profiles/certificates, you can use the `match nuke` command to revoke your certificates and provisioning profiles. Don't worry, apps that are already available in the App Store / TestFlight will still work. Builds distributed via Ad Hoc or Enterprise will be disabled after nuking your account, so you'll have to re-upload a new build. After clearing your account you'll start from a clean state, and you can run _match_ to generate your certificates and profiles again.
@@ -706,6 +706,16 @@ DELIVER_ITMSTRANSPORTER_ADDITIONAL_UPLOAD_PARAMETERS="-t DAV" fastlane deliver
706
706
  ## HTTP Proxy
707
707
  iTunes Transporter is a Java application bundled with Xcode. In addition to utilizing the `DELIVER_ITMSTRANSPORTER_ADDITIONAL_UPLOAD_PARAMETERS="-t DAV"`, you need to configure the transporter application to use the proxy independently from the system proxy or any environment proxy settings. You can find the configuration file within Xcode:
708
708
 
709
+ **for Xcode11 and later**
710
+
711
+ ```no-highlight
712
+ TOOLS_PATH=$( xcode-select -p )
713
+ REL_PATH='../SharedFrameworks/ContentDeliveryServices.framework/Versions/A/itms/java/lib/net.properties'
714
+ echo "$TOOLS_PATH/$REL_PATH"
715
+ ```
716
+
717
+ **for Xcode10 or earlier**
718
+
709
719
  ```no-highlight
710
720
  TOOLS_PATH=$( xcode-select -p )
711
721
  REL_PATH='../Applications/Application Loader.app/Contents/itms/java/lib/net.properties'
@@ -34,7 +34,7 @@ module Fastlane
34
34
  [
35
35
  FastlaneCore::ConfigItem.new(key: :branch,
36
36
  env_name: "FL_ENSURE_GIT_BRANCH_NAME",
37
- description: "The branch that should be checked for. String that can be either the full name of the branch or a regex to match",
37
+ description: "The branch that should be checked for. String that can be either the full name of the branch or a regex e.g. `^feature\/.*$` to match",
38
38
  is_string: true,
39
39
  default_value: 'master')
40
40
  ]
@@ -4,6 +4,7 @@ module Fastlane
4
4
  def self.run(params)
5
5
  Actions.verify_gem!('xcode-install')
6
6
  required_version = params[:version]
7
+ strict = params[:strict]
7
8
 
8
9
  if required_version.to_s.length == 0
9
10
  # The user didn't provide an Xcode version, let's see
@@ -30,16 +31,38 @@ module Fastlane
30
31
  UI.user_error!("Invalid version number provided, make sure it's valid: #{ex}")
31
32
  end
32
33
 
33
- if selected_version == required_version
34
- UI.success("Selected Xcode version is correct: #{selected_version}")
34
+ if strict == true
35
+ if selected_version == required_version
36
+ success(selected_version)
37
+ else
38
+ error(selected_version, required_version)
39
+ end
35
40
  else
36
- UI.message("Selected Xcode version is not correct: #{selected_version}. You expected #{required_version}.")
37
- UI.message("To correct this, use: `xcode_select(version: #{required_version})`.")
41
+ required_version_numbers = required_version.to_s.split(".")
42
+ selected_version_numbers = selected_version.to_s.split(".")
43
+
44
+ required_version_numbers.each_with_index do |required_version_number, index|
45
+ selected_version_number = selected_version_numbers[index]
46
+ next unless required_version_number != selected_version_number
47
+ error(selected_version, required_version)
48
+ break
49
+ end
38
50
 
39
- UI.user_error!("Selected Xcode version doesn't match your requirement.\nExpected: Xcode #{required_version}\nActual: Xcode #{selected_version}\n")
51
+ success(selected_version)
40
52
  end
41
53
  end
42
54
 
55
+ def self.success(selected_version)
56
+ UI.success("Selected Xcode version is correct: #{selected_version}")
57
+ end
58
+
59
+ def self.error(selected_version, required_version)
60
+ UI.message("Selected Xcode version is not correct: #{selected_version}. You expected #{required_version}.")
61
+ UI.message("To correct this, use: `xcode_select(version: #{required_version})`.")
62
+
63
+ UI.user_error!("Selected Xcode version doesn't match your requirement.\nExpected: Xcode #{required_version}\nActual: Xcode #{selected_version}\n")
64
+ end
65
+
43
66
  #####################################################
44
67
  # @!group Documentation
45
68
  #####################################################
@@ -52,7 +75,8 @@ module Fastlane
52
75
  [
53
76
  "If building your app requires a specific version of Xcode, you can invoke this command before using gym.",
54
77
  "For example, to ensure that a beta version of Xcode is not accidentally selected to build, which would make uploading to TestFlight fail.",
55
- "You can either manually provide a specific version using `version: ` or you make use of the `.xcode-version` file."
78
+ "You can either manually provide a specific version using `version: ` or you make use of the `.xcode-version` file.",
79
+ "Using the `strict` parameter, you can either verify the full set of version numbers strictly (i.e. `11.3.1`) or only a subset of them (i.e. `11.3` or `11`)."
56
80
  ].join("\n")
57
81
  end
58
82
 
@@ -62,7 +86,11 @@ module Fastlane
62
86
  env_name: "FL_ENSURE_XCODE_VERSION",
63
87
  description: "Xcode version to verify that is selected",
64
88
  is_string: true,
65
- optional: true)
89
+ optional: true),
90
+ FastlaneCore::ConfigItem.new(key: :strict,
91
+ description: "Should the version be verified strictly (all 3 version numbers), or matching only the given version numbers (i.e. `11.3` == `11.3.x`)",
92
+ type: Boolean,
93
+ default_value: true)
66
94
  ]
67
95
  end
68
96
 
@@ -45,6 +45,7 @@ module Fastlane
45
45
  [
46
46
  'frame_screenshots',
47
47
  'frameit # alias for "frame_screenshots"',
48
+ 'frame_screenshots(use_platform: "ANDROID")',
48
49
  'frame_screenshots(silver: true)',
49
50
  'frame_screenshots(path: "/screenshots")',
50
51
  'frame_screenshots(rose_gold: true)'
@@ -56,7 +57,7 @@ module Fastlane
56
57
  end
57
58
 
58
59
  def self.is_supported?(platform)
59
- [:ios, :mac].include?(platform)
60
+ [:ios, :mac, :android].include?(platform)
60
61
  end
61
62
  end
62
63
  end
@@ -129,6 +129,9 @@ module Fastlane
129
129
  FastlaneCore::ConfigItem.new(key: :api_token,
130
130
  env_name: "FL_GITHUB_RELEASE_API_TOKEN",
131
131
  sensitive: true,
132
+ code_gen_sensitive: true,
133
+ default_value: ENV["GITHUB_API_TOKEN"],
134
+ default_value_dynamic: true,
132
135
  description: "GitHub Personal Token (required for private repositories)",
133
136
  optional: true)
134
137
  ]
@@ -17,12 +17,16 @@ module Fastlane
17
17
  end
18
18
 
19
19
  class GradleAction < Action
20
+ # rubocop:disable Metrics/PerceivedComplexity
20
21
  def self.run(params)
21
22
  task = params[:task]
22
23
  flavor = params[:flavor]
23
24
  build_type = params[:build_type]
25
+ tasks = params[:tasks]
24
26
 
25
- gradle_task = [task, flavor, build_type].join
27
+ gradle_task = gradle_task(task, flavor, build_type, tasks)
28
+
29
+ UI.user_error!('Please pass a gradle task or tasks') if gradle_task.empty?
26
30
 
27
31
  project_dir = params[:project_dir]
28
32
 
@@ -101,6 +105,28 @@ module Fastlane
101
105
 
102
106
  return result
103
107
  end
108
+ # rubocop:enable Metrics/PerceivedComplexity
109
+
110
+ def self.gradle_task(task, flavor, build_type, tasks)
111
+ gradle_task = [task, flavor, build_type].join
112
+
113
+ if gradle_task.empty? && !tasks.nil?
114
+ gradle_task = tasks.join(' ')
115
+ end
116
+
117
+ gradle_task
118
+ end
119
+
120
+ def self.step_text(params)
121
+ task = params[:task]
122
+ flavor = params[:flavor]
123
+ build_type = params[:build_type]
124
+ tasks = params[:tasks]
125
+
126
+ gradle_task = gradle_task(task, flavor, build_type, tasks)
127
+
128
+ return gradle_task
129
+ end
104
130
 
105
131
  #####################################################
106
132
  # @!group Documentation
@@ -119,7 +145,8 @@ module Fastlane
119
145
  FastlaneCore::ConfigItem.new(key: :task,
120
146
  env_name: 'FL_GRADLE_TASK',
121
147
  description: 'The gradle task you want to execute, e.g. `assemble`, `bundle` or `test`. For tasks such as `assembleMyFlavorRelease` you should use gradle(task: \'assemble\', flavor: \'Myflavor\', build_type: \'Release\')',
122
- optional: false,
148
+ conflicting_options: [:tasks],
149
+ optional: true,
123
150
  is_string: true),
124
151
  FastlaneCore::ConfigItem.new(key: :flavor,
125
152
  env_name: 'FL_GRADLE_FLAVOR',
@@ -131,6 +158,13 @@ module Fastlane
131
158
  description: 'The build type that you want the task for, e.g. `Release`. Useful for some tasks such as `assemble`',
132
159
  optional: true,
133
160
  is_string: true),
161
+ FastlaneCore::ConfigItem.new(key: :tasks,
162
+ type: Array,
163
+ env_name: 'FL_GRADLE_TASKS',
164
+ description: 'The multiple gradle tasks that you want to execute, e.g. `[assembleDebug, bundleDebug]`',
165
+ conflicting_options: [:task],
166
+ optional: true,
167
+ is_string: false),
134
168
  FastlaneCore::ConfigItem.new(key: :flags,
135
169
  env_name: 'FL_GRADLE_FLAGS',
136
170
  description: 'All parameter flags you want to pass to the gradle command, e.g. `--exitcode --xml file.xml`',
@@ -219,6 +253,13 @@ module Fastlane
219
253
  )
220
254
  ```
221
255
 
256
+ You can pass multiple gradle tasks:
257
+ ```ruby
258
+ gradle(
259
+ tasks: ["assembleDebug", "bundleDebug"]
260
+ )
261
+ ```
262
+
222
263
  You can pass properties to gradle:
223
264
  ```ruby
224
265
  gradle(
@@ -1,13 +1,9 @@
1
1
  module Fastlane
2
2
  module Actions
3
- require 'fastlane/actions/build_ios_app'
4
- class GymAction < BuildIosAppAction
5
- #####################################################
6
- # @!group Documentation
7
- #####################################################
8
-
3
+ require 'fastlane/actions/build_app'
4
+ class GymAction < BuildAppAction
9
5
  def self.description
10
- "Alias for the `build_ios_app` action"
6
+ "Alias for the `build_app` action"
11
7
  end
12
8
  end
13
9
  end
@@ -26,6 +26,10 @@ module Fastlane
26
26
  description: "The branch or tag to check-out on the repository",
27
27
  default_value: 'HEAD',
28
28
  optional: true),
29
+ FastlaneCore::ConfigItem.new(key: :dependencies,
30
+ description: "The array of additional Fastfiles in the repository",
31
+ default_value: [],
32
+ optional: true),
29
33
  FastlaneCore::ConfigItem.new(key: :path,
30
34
  description: "The path of the Fastfile in the repository",
31
35
  default_value: 'fastlane/Fastfile',
@@ -2,7 +2,7 @@ module Fastlane
2
2
  module Actions
3
3
  class LastGitTagAction < Action
4
4
  def self.run(params)
5
- Actions.last_git_tag_name
5
+ Actions.last_git_tag_name(true, params[:pattern])
6
6
  end
7
7
 
8
8
  #####################################################
@@ -14,7 +14,12 @@ module Fastlane
14
14
  end
15
15
 
16
16
  def self.available_options
17
- []
17
+ [
18
+ FastlaneCore::ConfigItem.new(key: :pattern,
19
+ description: "Pattern to filter tags when looking for last one. Limit tags to ones matching given shell glob. If pattern lacks ?, *, or [, * at the end is implied",
20
+ default_value: nil,
21
+ optional: true)
22
+ ]
18
23
  end
19
24
 
20
25
  def self.output
@@ -26,7 +31,7 @@ module Fastlane
26
31
  end
27
32
 
28
33
  def self.authors
29
- ["KrauseFx"]
34
+ ["KrauseFx", "wedkarz"]
30
35
  end
31
36
 
32
37
  def self.is_supported?(platform)
@@ -34,12 +39,16 @@ module Fastlane
34
39
  end
35
40
 
36
41
  def self.details
37
- "If you are using this action on a **shallow clone**, *the default with some CI systems like Bamboo*, you need to ensure that you have also pulled all the git tags appropriately. Assuming your git repo has the correct remote set you can issue `sh('git fetch --tags')`."
42
+ [
43
+ "If you are using this action on a **shallow clone**, *the default with some CI systems like Bamboo*, you need to ensure that you have also pulled all the git tags appropriately. Assuming your git repo has the correct remote set you can issue `sh('git fetch --tags')`.",
44
+ "Pattern parameter allows you to filter to a subset of tags."
45
+ ].join("\n")
38
46
  end
39
47
 
40
48
  def self.example_code
41
49
  [
42
- 'last_git_tag'
50
+ 'last_git_tag',
51
+ 'last_git_tag(pattern: "release/v1.0/")'
43
52
  ]
44
53
  end
45
54
 
@@ -4,12 +4,17 @@ module Fastlane
4
4
  module Actions
5
5
  module SharedValues
6
6
  LATEST_TESTFLIGHT_BUILD_NUMBER = :LATEST_TESTFLIGHT_BUILD_NUMBER
7
+ LATEST_TESTFLIGHT_VERSION = :LATEST_TESTFLIGHT_VERSION
7
8
  end
8
9
 
9
10
  class LatestTestflightBuildNumberAction < Action
10
11
  def self.run(params)
11
- build_number = AppStoreBuildNumberAction.run(params)
12
- Actions.lane_context[SharedValues::LATEST_TESTFLIGHT_BUILD_NUMBER] = build_number
12
+ AppStoreBuildNumberAction.run(params)
13
+ build_nr = Actions.lane_context[SharedValues::LATEST_BUILD_NUMBER]
14
+ build_v = Actions.lane_context[SharedValues::LATEST_VERSION]
15
+ Actions.lane_context[SharedValues::LATEST_TESTFLIGHT_BUILD_NUMBER] = build_nr
16
+ Actions.lane_context[SharedValues::LATEST_TESTFLIGHT_VERSION] = build_v
17
+ return build_nr
13
18
  end
14
19
 
15
20
  #####################################################
@@ -93,7 +98,8 @@ module Fastlane
93
98
 
94
99
  def self.output
95
100
  [
96
- ['LATEST_TESTFLIGHT_BUILD_NUMBER', 'The latest build number of the latest version of the app uploaded to TestFlight']
101
+ ['LATEST_TESTFLIGHT_BUILD_NUMBER', 'The latest build number of the latest version of the app uploaded to TestFlight'],
102
+ ['LATEST_TESTFLIGHT_VERSION', 'The version of the latest build number']
97
103
  ]
98
104
  end
99
105
 
@@ -0,0 +1,183 @@
1
+ module Fastlane
2
+ module Actions
3
+ class NotarizeAction < Action
4
+ def self.run(params)
5
+ package_path = params[:package]
6
+ bundle_id = params[:bundle_id]
7
+ try_early_stapling = params[:try_early_stapling]
8
+ print_log = params[:print_log]
9
+ verbose = params[:verbose]
10
+
11
+ # Compress and read bundle identifier only for .app bundle.
12
+ compressed_package_path = nil
13
+ if File.extname(package_path) == '.app'
14
+ compressed_package_path = "#{package_path}.zip"
15
+ Actions.sh(
16
+ "ditto -c -k --rsrc --keepParent \"#{package_path}\" \"#{compressed_package_path}\"",
17
+ log: verbose
18
+ )
19
+
20
+ unless bundle_id
21
+ info_plist_path = File.join(package_path, 'Contents', 'Info.plist')
22
+ bundle_id = Actions.sh(
23
+ "/usr/libexec/PlistBuddy -c \"Print :CFBundleIdentifier\" \"#{info_plist_path}\"",
24
+ log: verbose
25
+ ).strip
26
+ end
27
+ end
28
+
29
+ UI.user_error!('Could not read bundle identifier, provide as a parameter') unless bundle_id
30
+
31
+ apple_id_account = CredentialsManager::AccountManager.new(user: params[:username])
32
+
33
+ # Add password as a temporary environment variable for altool.
34
+ # Use app specific password if specified.
35
+ ENV['FL_NOTARIZE_PASSWORD'] = ENV['FASTLANE_APPLE_APPLICATION_SPECIFIC_PASSWORD'] || apple_id_account.password
36
+
37
+ UI.message('Uploading package to notarization service, might take a while')
38
+
39
+ notarization_upload_command = "xcrun altool --notarize-app -t osx -f \"#{compressed_package_path || package_path}\" --primary-bundle-id #{bundle_id} -u #{apple_id_account.user} -p @env:FL_NOTARIZE_PASSWORD --output-format xml"
40
+ notarization_upload_command << " --asc-provider \"#{params[:asc_provider]}\"" if params[:asc_provider]
41
+
42
+ notarization_upload_response = Actions.sh(
43
+ notarization_upload_command,
44
+ log: verbose
45
+ )
46
+
47
+ FileUtils.rm_rf(compressed_package_path) if compressed_package_path
48
+
49
+ notarization_upload_plist = Plist.parse_xml(notarization_upload_response)
50
+ notarization_request_id = notarization_upload_plist['notarization-upload']['RequestUUID']
51
+
52
+ UI.success("Successfully uploaded package to notarization service with request identifier #{notarization_request_id}")
53
+
54
+ notarization_info = {}
55
+ while notarization_info.empty? || (notarization_info['Status'] == 'in progress')
56
+ if notarization_info.empty?
57
+ UI.message('Waiting to query request status')
58
+ elsif try_early_stapling
59
+ UI.message('Request in progress, trying early staple')
60
+
61
+ begin
62
+ self.staple(package_path, verbose)
63
+ UI.message('Successfully notarized and early stapled package.')
64
+
65
+ return
66
+ rescue
67
+ UI.message('Early staple failed, waiting to query again')
68
+ end
69
+ end
70
+
71
+ sleep(30)
72
+
73
+ UI.message('Querying request status')
74
+
75
+ notarization_info_response = Actions.sh(
76
+ "xcrun altool --notarization-info #{notarization_request_id} -u #{apple_id_account.user} -p @env:FL_NOTARIZE_PASSWORD --output-format xml",
77
+ log: verbose
78
+ )
79
+
80
+ notarization_info_plist = Plist.parse_xml(notarization_info_response)
81
+ notarization_info = notarization_info_plist['notarization-info']
82
+ end
83
+
84
+ log_url = notarization_info['LogFileURL']
85
+ ENV['FL_NOTARIZE_LOG_FILE_URL'] = log_url
86
+ log_suffix = ''
87
+ if log_url && print_log
88
+ log_response = Net::HTTP.get(URI(log_url))
89
+ log_json_object = JSON.parse(log_response)
90
+ log_suffix = ", with log:\n#{JSON.pretty_generate(log_json_object)}"
91
+ end
92
+
93
+ case notarization_info['Status']
94
+ when 'success'
95
+ UI.message('Stapling package')
96
+
97
+ self.staple(package_path, verbose)
98
+
99
+ UI.success("Successfully notarized and stapled package#{log_suffix}")
100
+ when 'invalid'
101
+ UI.user_error!("Could not notarize package with message '#{notarization_info['Status Message']}'#{log_suffix}")
102
+ else
103
+ UI.crash!("Could not notarize package with status '#{notarization_info['Status']}'#{log_suffix}")
104
+ end
105
+ ensure
106
+ ENV.delete('FL_NOTARIZE_PASSWORD')
107
+ end
108
+
109
+ def self.staple(package_path, verbose)
110
+ Actions.sh(
111
+ "xcrun stapler staple \"#{package_path}\"",
112
+ log: verbose
113
+ )
114
+ end
115
+
116
+ def self.description
117
+ 'Notarizes a macOS app'
118
+ end
119
+
120
+ def self.authors
121
+ ['zeplin']
122
+ end
123
+
124
+ def self.available_options
125
+ username = CredentialsManager::AppfileConfig.try_fetch_value(:apple_dev_portal_id)
126
+ username ||= CredentialsManager::AppfileConfig.try_fetch_value(:apple_id)
127
+
128
+ asc_provider = CredentialsManager::AppfileConfig.try_fetch_value(:itc_team_id)
129
+
130
+ [
131
+ FastlaneCore::ConfigItem.new(key: :package,
132
+ env_name: 'FL_NOTARIZE_PACKAGE',
133
+ description: 'Path to package to notarize, e.g. .app bundle or disk image',
134
+ is_string: true,
135
+ verify_block: proc do |value|
136
+ UI.user_error!("Could not find package at '#{value}'") unless File.exist?(value)
137
+ end),
138
+ FastlaneCore::ConfigItem.new(key: :try_early_stapling,
139
+ env_name: 'FL_NOTARIZE_TRY_EARLY_STAPLING',
140
+ description: 'Whether to try early stapling while the notarization request is in progress',
141
+ optional: true,
142
+ default_value: false,
143
+ type: Boolean),
144
+ FastlaneCore::ConfigItem.new(key: :bundle_id,
145
+ env_name: 'FL_NOTARIZE_BUNDLE_ID',
146
+ description: 'Bundle identifier to uniquely identify the package',
147
+ optional: true,
148
+ is_string: true),
149
+ FastlaneCore::ConfigItem.new(key: :username,
150
+ env_name: 'FL_NOTARIZE_USERNAME',
151
+ description: 'Apple ID username',
152
+ default_value: username,
153
+ default_value_dynamic: true),
154
+ FastlaneCore::ConfigItem.new(key: :asc_provider,
155
+ env_name: 'FL_NOTARIZE_ASC_PROVIDER',
156
+ description: 'Provider short name for accounts associated with multiple providers',
157
+ optional: true,
158
+ default_value: asc_provider),
159
+ FastlaneCore::ConfigItem.new(key: :print_log,
160
+ env_name: 'FL_NOTARIZE_PRINT_LOG',
161
+ description: 'Whether to print notarization log file, listing issues on failure and warnings on success',
162
+ optional: true,
163
+ default_value: false,
164
+ type: Boolean),
165
+ FastlaneCore::ConfigItem.new(key: :verbose,
166
+ env_name: 'FL_NOTARIZE_VERBOSE',
167
+ description: 'Whether to log requests',
168
+ optional: true,
169
+ default_value: false,
170
+ type: Boolean)
171
+ ]
172
+ end
173
+
174
+ def self.is_supported?(platform)
175
+ platform == :mac
176
+ end
177
+
178
+ def self.category
179
+ :code_signing
180
+ end
181
+ end
182
+ end
183
+ end