fastlane 2.160.0 → 2.165.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (101) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +78 -78
  3. data/cert/lib/cert/options.rb +28 -1
  4. data/cert/lib/cert/runner.rb +51 -34
  5. data/deliver/lib/deliver/app_screenshot_iterator.rb +4 -4
  6. data/deliver/lib/deliver/module.rb +2 -0
  7. data/deliver/lib/deliver/options.rb +5 -5
  8. data/deliver/lib/deliver/queue_worker.rb +14 -29
  9. data/deliver/lib/deliver/upload_metadata.rb +20 -5
  10. data/deliver/lib/deliver/upload_screenshots.rb +28 -13
  11. data/fastlane/lib/fastlane/actions/.download_dsyms.rb.swp +0 -0
  12. data/fastlane/lib/fastlane/actions/actions_helper.rb +20 -1
  13. data/fastlane/lib/fastlane/actions/app_store_build_number.rb +39 -3
  14. data/fastlane/lib/fastlane/actions/app_store_connect_api_key.rb +15 -1
  15. data/fastlane/lib/fastlane/actions/check_app_store_metadata.rb +1 -0
  16. data/fastlane/lib/fastlane/actions/docs/capture_android_screenshots.md +2 -2
  17. data/fastlane/lib/fastlane/actions/docs/capture_ios_screenshots.md +2 -2
  18. data/fastlane/lib/fastlane/actions/docs/create_app_online.md +1 -1
  19. data/fastlane/lib/fastlane/actions/docs/frame_screenshots.md +2 -2
  20. data/fastlane/lib/fastlane/actions/docs/run_tests.md +2 -2
  21. data/fastlane/lib/fastlane/actions/docs/sync_code_signing.md +12 -3
  22. data/fastlane/lib/fastlane/actions/docs/upload_to_play_store.md +2 -2
  23. data/fastlane/lib/fastlane/actions/docs/upload_to_testflight.md +1 -1
  24. data/fastlane/lib/fastlane/actions/download_dsyms.rb +1 -0
  25. data/fastlane/lib/fastlane/actions/ensure_git_status_clean.rb +13 -2
  26. data/fastlane/lib/fastlane/actions/get_certificates.rb +1 -0
  27. data/fastlane/lib/fastlane/actions/get_provisioning_profile.rb +1 -0
  28. data/fastlane/lib/fastlane/actions/import_from_git.rb +9 -1
  29. data/fastlane/lib/fastlane/actions/is_ci.rb +1 -1
  30. data/fastlane/lib/fastlane/actions/latest_testflight_build_number.rb +15 -0
  31. data/fastlane/lib/fastlane/actions/register_device.rb +46 -5
  32. data/fastlane/lib/fastlane/actions/register_devices.rb +50 -16
  33. data/fastlane/lib/fastlane/actions/set_changelog.rb +31 -3
  34. data/fastlane/lib/fastlane/actions/sync_code_signing.rb +1 -0
  35. data/fastlane/lib/fastlane/actions/upload_to_app_store.rb +3 -2
  36. data/fastlane/lib/fastlane/fast_file.rb +74 -23
  37. data/fastlane/lib/fastlane/plugins/template/.rubocop.yml +1 -0
  38. data/fastlane/lib/fastlane/version.rb +1 -1
  39. data/fastlane/swift/Deliverfile.swift +1 -1
  40. data/fastlane/swift/DeliverfileProtocol.swift +4 -4
  41. data/fastlane/swift/Fastlane.swift +120 -27
  42. data/fastlane/swift/Gymfile.swift +1 -1
  43. data/fastlane/swift/GymfileProtocol.swift +1 -1
  44. data/fastlane/swift/LaneFileProtocol.swift +28 -36
  45. data/fastlane/swift/MainProcess.swift +1 -1
  46. data/fastlane/swift/Matchfile.swift +1 -1
  47. data/fastlane/swift/MatchfileProtocol.swift +21 -5
  48. data/fastlane/swift/Precheckfile.swift +1 -1
  49. data/fastlane/swift/PrecheckfileProtocol.swift +1 -1
  50. data/fastlane/swift/Scanfile.swift +1 -1
  51. data/fastlane/swift/ScanfileProtocol.swift +1 -1
  52. data/fastlane/swift/Screengrabfile.swift +1 -1
  53. data/fastlane/swift/ScreengrabfileProtocol.swift +1 -1
  54. data/fastlane/swift/Snapshotfile.swift +1 -1
  55. data/fastlane/swift/SnapshotfileProtocol.swift +1 -1
  56. data/fastlane/swift/main.swift +1 -1
  57. data/fastlane_core/lib/fastlane_core/analytics/analytics_session.rb +6 -7
  58. data/fastlane_core/lib/fastlane_core/device_manager.rb +8 -4
  59. data/fastlane_core/lib/fastlane_core/helper.rb +1 -1
  60. data/fastlane_core/lib/fastlane_core/keychain_importer.rb +3 -3
  61. data/gym/lib/gym/generators/package_command_generator_xcode7.rb +2 -2
  62. data/match/lib/match/generator.rb +6 -1
  63. data/match/lib/match/importer.rb +63 -18
  64. data/match/lib/match/migrate.rb +13 -2
  65. data/match/lib/match/nuke.rb +65 -22
  66. data/match/lib/match/options.rb +34 -3
  67. data/match/lib/match/runner.rb +38 -10
  68. data/match/lib/match/spaceship_ensure.rb +27 -21
  69. data/match/lib/match/storage/google_cloud_storage.rb +20 -3
  70. data/match/lib/match/storage/s3_storage.rb +19 -3
  71. data/scan/lib/scan/detect_values.rb +5 -8
  72. data/scan/lib/scan/runner.rb +2 -1
  73. data/sigh/lib/assets/resign.sh +1 -1
  74. data/sigh/lib/sigh/download_all.rb +16 -4
  75. data/sigh/lib/sigh/options.rb +21 -0
  76. data/sigh/lib/sigh/runner.rb +83 -41
  77. data/snapshot/lib/assets/SnapshotHelper.swift +4 -0
  78. data/snapshot/lib/snapshot/simulator_launchers/simulator_launcher_base.rb +2 -1
  79. data/spaceship/README.md +1 -1
  80. data/spaceship/lib/spaceship/client.rb +9 -4
  81. data/spaceship/lib/spaceship/connect_api.rb +27 -0
  82. data/spaceship/lib/spaceship/connect_api/api_client.rb +12 -3
  83. data/spaceship/lib/spaceship/connect_api/client.rb +20 -7
  84. data/spaceship/lib/spaceship/connect_api/models/app.rb +51 -0
  85. data/spaceship/lib/spaceship/connect_api/models/app_screenshot.rb +3 -1
  86. data/spaceship/lib/spaceship/connect_api/models/beta_tester.rb +2 -1
  87. data/spaceship/lib/spaceship/connect_api/models/certificate.rb +42 -0
  88. data/spaceship/lib/spaceship/connect_api/models/custom_app_organization.rb +43 -0
  89. data/spaceship/lib/spaceship/connect_api/models/custom_app_user.rb +41 -0
  90. data/spaceship/lib/spaceship/connect_api/models/device.rb +5 -0
  91. data/spaceship/lib/spaceship/connect_api/models/profile.rb +7 -1
  92. data/spaceship/lib/spaceship/connect_api/models/user_invitation.rb +59 -0
  93. data/spaceship/lib/spaceship/connect_api/provisioning/provisioning.rb +45 -2
  94. data/spaceship/lib/spaceship/connect_api/spaceship.rb +7 -4
  95. data/spaceship/lib/spaceship/connect_api/testflight/testflight.rb +13 -0
  96. data/spaceship/lib/spaceship/connect_api/token.rb +6 -1
  97. data/spaceship/lib/spaceship/connect_api/tunes/tunes.rb +75 -1
  98. data/spaceship/lib/spaceship/connect_api/users/users.rb +40 -0
  99. data/spaceship/lib/spaceship/helper/net_http_generic_request.rb +11 -5
  100. data/supply/lib/supply/uploader.rb +1 -1
  101. metadata +19 -15
@@ -7,6 +7,7 @@ module Fastlane
7
7
  def self.run(config)
8
8
  require 'precheck'
9
9
  Precheck.config = config
10
+ Precheck.config[:api_key] ||= Actions.lane_context[SharedValues::APP_STORE_CONNECT_API_KEY]
10
11
  return Precheck::Runner.new.run
11
12
  end
12
13
 
@@ -198,7 +198,7 @@ class JUnit4StyleTests {
198
198
 
199
199
  ```
200
200
 
201
- There is an [example project](https://github.com/fastlane/fastlane/tree/master/screengrab/example/src/androidTest/java/tools/fastlane/localetester) showing how to use use JUnit 3 or 4 and Espresso with the screengrab Java library to capture screenshots during a UI test run.
201
+ There is an [example project](https://github.com/fastlane/fastlane/tree/master/screengrab/example/src/androidTest/java/tools/fastlane/localetester) showing how to use JUnit 3 or 4 and Espresso with the screengrab Java library to capture screenshots during a UI test run.
202
202
 
203
203
  Using JUnit 4 is preferable because of its ability to perform actions before and after the entire test class is run. This means you will change the device's locale far fewer times when compared with JUnit 3 running those commands before and after each test method.
204
204
 
@@ -251,7 +251,7 @@ new CleanStatusBar()
251
251
  <details>
252
252
  <summary>Launch Arguments</summary>
253
253
 
254
- You can provide additional arguments to your testcases on launch. These strings will be available in your tests through `InstrumentationRegistry.getArguments()`.
254
+ You can provide additional arguments to your test cases on launch. These strings will be available in your tests through `InstrumentationRegistry.getArguments()`.
255
255
 
256
256
  ```ruby
257
257
  screengrab(
@@ -106,7 +106,7 @@ app.launch()
106
106
 
107
107
  ```objective-c
108
108
  XCUIApplication *app = [[XCUIApplication alloc] init];
109
- [Snapshot setupSnapshot:app];
109
+ [Snapshot setupSnapshot:app waitForAnimations:NO];
110
110
  [app launch];
111
111
  ```
112
112
 
@@ -251,7 +251,7 @@ to update your `SnapshotHelper.swift` files. In case you modified your `Snapshot
251
251
 
252
252
  ## Launch Arguments
253
253
 
254
- You can provide additional arguments to your app on launch. These strings will be available in your app (eg. not in the testing target) through `ProcessInfo.processInfo.arguments`. Alternatively, use user-default syntax (`-key value`) and they will be available as key-value pairs in `UserDefaults.standard`.
254
+ You can provide additional arguments to your app on launch. These strings will be available in your app (e.g. not in the testing target) through `ProcessInfo.processInfo.arguments`. Alternatively, use user-default syntax (`-key value`) and they will be available as key-value pairs in `UserDefaults.standard`.
255
255
 
256
256
  ```ruby-skip-tests
257
257
  launch_arguments([
@@ -2,7 +2,7 @@
2
2
  <img src="/img/actions/produce.png" width="250">
3
3
  </p>
4
4
 
5
- ###### Create new iOS apps on App Store Connect and Dev Portal using your command line
5
+ ###### Create new iOS apps on App Store Connect and Apple Developer Portal using your command line
6
6
 
7
7
  _produce_ creates new iOS apps on both the Apple Developer Portal and App Store Connect with the minimum required information.
8
8
 
@@ -133,7 +133,7 @@ The general parameters are defined in the `default` key and can be:
133
133
  | `stack_title` | Specifies whether _frameit_ should display the keyword above the title when both keyword and title are defined. If it is false, the title and keyword will be displayed side by side when both keyword and title are defined. | `false` |
134
134
  | `title_below_image` | Specifies whether _frameit_ should place the title and optional keyword below the device frame. If it is false, it will be placed above the device frame. | `false` |
135
135
  | `show_complete_frame` | Specifies whether _frameit_ should shrink the device frame so that it is completely shown in the framed screenshot. If it is false, clipping of the device frame might occur at the bottom (when `title_below_image` is `false`) or top (when `title_below_image` is `true`) of the framed screenshot. | `false` |
136
- | `padding` | The content of the framed screenshot will be resized to match the specified `padding` around all edges. The vertical padding is also applied between the text and the top or bottom (depending on `title_below_image`) of the device frame. <p> There are 3 different options of specyfying the padding: <p> 1. Default: An integer value that defines both horizontal and vertical padding in pixels. <br> 2. A string that defines (different) padding values in pixels for horizontal and vertical padding. The syntax is `"<horizontal>x<vertical>"`, e.g. `"30x60"`. <br> 3. A string that defines (different) padding values in percentage for horizontal and vertical padding. The syntax is `"<horizontal>%x<vertical>%"`, e.g. `"5%x10%"`. <br> **Note:** The percentage is calculated from the smallest image dimension (height or width). <p> A combination of option 2 and 3 is possible, e.g. `"5%x40"`. | `50` |
136
+ | `padding` | The content of the framed screenshot will be resized to match the specified `padding` around all edges. The vertical padding is also applied between the text and the top or bottom (depending on `title_below_image`) of the device frame. <p> There are 3 different options of specifying the padding: <p> 1. Default: An integer value that defines both horizontal and vertical padding in pixels. <br> 2. A string that defines (different) padding values in pixels for horizontal and vertical padding. The syntax is `"<horizontal>x<vertical>"`, e.g. `"30x60"`. <br> 3. A string that defines (different) padding values in percentage for horizontal and vertical padding. The syntax is `"<horizontal>%x<vertical>%"`, e.g. `"5%x10%"`. <br> **Note:** The percentage is calculated from the smallest image dimension (height or width). <p> A combination of option 2 and 3 is possible, e.g. `"5%x40"`. | `50` |
137
137
  | `interline_spacing` | Specifies whether _frameit_ should add or subtract this many pixels between the individual lines of text. This only applies to a multi-line `title` and/or `keyword` to expand or squash together the individual lines of text. | `0` |
138
138
  | `font_scale_factor` | Specifies whether _frameit_ should increase or decrease the font size of the text. Is ignored for `keyword` or `title`, if `font_size` is specified. | `0.1` |
139
139
  | `frame` | Overrides the color of the frame to be used. (Valid values are `BLACK`, `WHITE`, `GOLD` and `ROSE_GOLD`) | NA |
@@ -161,7 +161,7 @@ The `keyword` and `title` parameters are both used in `default` and `data`. They
161
161
 
162
162
  | Key | Description | Default value |
163
163
  |-----|-------------|---------------|
164
- | `color` | The font color for the text. Specify a hex/html color code. | `#000000` (black) |
164
+ | `color` | The font color for the text. Specify a HEX/HTML color code. | `#000000` (black) |
165
165
  | `font` | The font family for the text. Specify the (relative) path to the font file (e.g. an OpenType Font). | The default `imagemagick` font, which is system dependent. |
166
166
  | `font_size` | The font size for the text specified in points. If not specified or `0`, font will be scaled automatically to fit the available space. _frameit_ still shrinks the text, if it would not fit. | NA |
167
167
  | `font_weight` | The [font weight for the text](https://imagemagick.org/script/command-line-options.php#weight). Specify an integer value (e.g. 900). | NA |
@@ -81,7 +81,7 @@ _scan_ uses the latest APIs and tools to make running tests plain simple and off
81
81
  👱 | Automatically switches to the [travis formatter](https://github.com/kattrali/xcpretty-travis-formatter) when running on Travis
82
82
  📖 | Helps you resolve common test errors like simulator not responding
83
83
 
84
- _scan_ uses a plain `xcodebuild` command, therefore keeping 100% compatible with `xcodebuild`. To generate the nice output, _scan_ uses [xcpretty](https://github.com/supermarin/xcpretty). You can alway access the raw output in `~/Library/Logs/scan`.
84
+ _scan_ uses a plain `xcodebuild` command, therefore keeping 100% compatible with `xcodebuild`. To generate the nice output, _scan_ uses [xcpretty](https://github.com/supermarin/xcpretty). You can always access the raw output in `~/Library/Logs/scan`.
85
85
 
86
86
  ![img/actions/scanScreenshot.png](/img/actions/scanScreenshot.png)
87
87
  ![img/actions/slack.png](/img/actions/slack.png)
@@ -100,7 +100,7 @@ That's all you need to run your tests. If you want more control, here are some a
100
100
  fastlane scan --workspace "Example.xcworkspace" --scheme "AppName" --device "iPhone 6" --clean
101
101
  ```
102
102
 
103
- If you need to use a different xcode install, use `xcode-select` or define `DEVELOPER_DIR`:
103
+ If you need to use a different Xcode install, use `xcode-select` or define `DEVELOPER_DIR`:
104
104
 
105
105
  ```no-highlight
106
106
  DEVELOPER_DIR="/Applications/Xcode6.2.app" scan
@@ -130,9 +130,9 @@ match
130
130
 
131
131
  You can find more information about GitHub basic authentication and personal token generation here: [https://developer.github.com/v3/auth/#basic-authentication](https://developer.github.com/v3/auth/#basic-authentication)
132
132
 
133
- ##### Git Storage on Azure Devops
133
+ ##### Git Storage on Azure DevOps
134
134
 
135
- If you're running a pipeline on Azure Devops and using git storage in a another repository on the same project, you might want to use `bearer` token authentication.
135
+ If you're running a pipeline on Azure DevOps and using git storage in a another repository on the same project, you might want to use `bearer` token authentication.
136
136
 
137
137
  Using parameter:
138
138
 
@@ -492,6 +492,15 @@ fastlane match import
492
492
 
493
493
  You'll be prompted for the certificate (`.cer`), the private key (`.p12`) and the provisioning profiles (`.mobileprovision` or `.provisionprofile`) paths. _match_ will first validate the certificate (`.cer`) against the Developer Portal before importing the certificate, the private key and the provisioning profiles into the specified _match_ repository.
494
494
 
495
+ However if there is no access to the developer portal but there are certificates, private keys and profiles provided, you can use the `skip_certificate_matching` option to tell _match_ not to verify the certificates. Like this:
496
+
497
+ ```no-highlight
498
+ fastlane match import --skip_certificate_matching true
499
+ ```
500
+ This will skip login to Apple Developer Portal and will import the provided certificate, private key and profile directly to the certificates repo.
501
+
502
+ Please be careful when using this option and ensure the certificates and profiles match the type (development, adhoc, appstore, enterprise, developer_id) and are not revoked or expired.
503
+
495
504
  ### Manual Decrypt
496
505
 
497
506
  If you want to manually decrypt a file you can.
@@ -533,7 +542,7 @@ Storing your private keys in a Git repo may sound off-putting at first. We did a
533
542
 
534
543
  ### Google Cloud Storage
535
544
 
536
- All your keys and provisioning profiles are encrypted using Google managed keys.
545
+ All your keys and provisioning profiles are encrypted using Google managed keys.
537
546
 
538
547
  ### What could happen if someone stole a private key?
539
548
 
@@ -49,7 +49,7 @@ The previous p12 configuration is still currently supported.
49
49
 
50
50
  ## Quick Start
51
51
 
52
- > Before using _supply_ to connect to Google Play Store, you'll need to set up your app manually first by uploading at least one build to Google Play Store. See [fastane/fastlane#14686](https://github.com/fastlane/fastlane/issues/14686) for more info.
52
+ > Before using _supply_ to connect to Google Play Store, you'll need to set up your app manually first by uploading at least one build to Google Play Store. See [fastlane/fastlane#14686](https://github.com/fastlane/fastlane/issues/14686) for more info.
53
53
 
54
54
  - `cd [your_project_folder]`
55
55
  - `fastlane supply init`
@@ -198,6 +198,6 @@ For more information, see the `fastlane action google_play_track_version_codes`
198
198
  - `:check_superseded_tracks`
199
199
  - Google Play will automatically remove releases that are superseded now
200
200
  - `:deactivate_on_promote`
201
- - Google Play will automatically deactive a release from its previous track on promote
201
+ - Google Play will automatically deactivate a release from its previous track on promote
202
202
 
203
203
  :
@@ -244,7 +244,7 @@ If you are on multiple App Store Connect teams, iTunes Transporter may need a pr
244
244
 
245
245
  ## Use an Application Specific Password to upload
246
246
 
247
- _pilot_/`upload_to_testflight` can use an [Application Specific Password via the `FASTLANE_APPLE_APPLICATION_SPECIFIC_PASSWORD` envirionment variable](https://docs.fastlane.tools/best-practices/continuous-integration/#application-specific-passwords) to upload a binary if both the `skip_waiting_for_build_processing` and `apple_id` options are set. (If any of those are not set, it will use the normal Apple login process that might require 2FA authentication.)
247
+ _pilot_/`upload_to_testflight` can use an [Application Specific Password via the `FASTLANE_APPLE_APPLICATION_SPECIFIC_PASSWORD` environment variable](https://docs.fastlane.tools/best-practices/continuous-integration/#application-specific-passwords) to upload a binary if both the `skip_waiting_for_build_processing` and `apple_id` options are set. (If any of those are not set, it will use the normal Apple login process that might require 2FA authentication.)
248
248
 
249
249
  ## Role for App Store Connect User
250
250
  _pilot_/`upload_to_testflight` updates build information and testers after the build has finished processing. App Store Connect requires the "App Manager" or "Admin" role for your Apple account to update this information. The "Developer" role will allow builds to be uploaded but _will not_ allow updating of build information and testers.
@@ -208,6 +208,7 @@ module Fastlane
208
208
  else
209
209
  http = Net::HTTP.new(uri.host, uri.port)
210
210
  end
211
+ http.read_timeout = 300
211
212
  http.use_ssl = (uri.scheme == "https")
212
213
  res = http.get(uri.request_uri)
213
214
  res.body
@@ -7,7 +7,13 @@ module Fastlane
7
7
  # Raises an exception and stop the lane execution if the repo is not in a clean state
8
8
  class EnsureGitStatusCleanAction < Action
9
9
  def self.run(params)
10
- repo_status = Actions.sh("git status --porcelain")
10
+ if params[:ignored]
11
+ ignored_file = params[:ignored]
12
+ repo_status = Actions.sh("git status --porcelain --ignored #{ignored_file}")
13
+ else
14
+ repo_status = Actions.sh("git status --porcelain")
15
+ end
16
+
11
17
  repo_clean = repo_status.empty?
12
18
 
13
19
  if repo_clean
@@ -65,7 +71,12 @@ module Fastlane
65
71
  description: "The flag whether to show the git diff if the repo is dirty",
66
72
  optional: true,
67
73
  default_value: false,
68
- is_string: false)
74
+ is_string: false),
75
+ FastlaneCore::ConfigItem.new(key: :ignored,
76
+ env_name: "FL_ENSURE_GIT_STATUS_CLEAN_IGNORED_FILE",
77
+ description: "The flag whether to ignore file the git status if the repo is dirty",
78
+ optional: true,
79
+ is_string: true)
69
80
  ]
70
81
  end
71
82
 
@@ -13,6 +13,7 @@ module Fastlane
13
13
 
14
14
  begin
15
15
  Cert.config = params # we alread have the finished config
16
+ Cert.config[:api_key] ||= Actions.lane_context[SharedValues::APP_STORE_CONNECT_API_KEY]
16
17
 
17
18
  Cert::Runner.new.launch
18
19
  cert_file_path = ENV["CER_FILE_PATH"]
@@ -15,6 +15,7 @@ module Fastlane
15
15
  require 'credentials_manager/appfile_config'
16
16
 
17
17
  Sigh.config = values # we already have the finished config
18
+ Sigh.config[:api_key] ||= Actions.lane_context[SharedValues::APP_STORE_CONNECT_API_KEY]
18
19
 
19
20
  path = Sigh::Manager.start
20
21
 
@@ -19,6 +19,9 @@ module Fastlane
19
19
 
20
20
  def self.available_options
21
21
  [
22
+ # Because the `run` method is actually implemented in `fast_file.rb`,
23
+ # and because magic, some of the parameters on `ConfigItem`s (e.g.
24
+ # `conflicting_options`, `verify_block`) are completely ignored.
22
25
  FastlaneCore::ConfigItem.new(key: :url,
23
26
  description: "The URL of the repository to import the Fastfile from",
24
27
  default_value: nil),
@@ -38,6 +41,10 @@ module Fastlane
38
41
  description: "The version to checkout on the repository. Optimistic match operator or multiple conditions can be used to select the latest version within constraints",
39
42
  default_value: nil,
40
43
  is_string: false,
44
+ optional: true),
45
+ FastlaneCore::ConfigItem.new(key: :cache_path,
46
+ description: "The path to a directory where the repository should be cloned into. This is ignored if `version` is not specified. Defaults to `nil`, which causes the repository to be cloned on every call, to a temporary directory",
47
+ default_value: nil,
41
48
  optional: true)
42
49
  ]
43
50
  end
@@ -62,7 +69,8 @@ module Fastlane
62
69
  url: "git@github.com:fastlane/fastlane.git", # The URL of the repository to import the Fastfile from.
63
70
  branch: "HEAD", # The branch to checkout on the repository
64
71
  path: "fastlane/Fastfile", # The path of the Fastfile in the repository
65
- version: [">= 1.1.0", "< 2.0.0"] # The version to checkout on the repository. Multiple conditions can be used to select the latest version within constraints.
72
+ version: [">= 1.1.0", "< 2.0.0"], # The version to checkout on the repository. Multiple conditions can be used to select the latest version within constraints.
73
+ cache_path: "~/.cache/fastlane/imported" # A directory in which the repository will be added, which means that it will not be cloned again on subsequent calls.
66
74
  )'
67
75
  ]
68
76
  end
@@ -35,7 +35,7 @@ module Fastlane
35
35
 
36
36
  def self.example_code
37
37
  [
38
- 'if is_ci?
38
+ 'if is_ci
39
39
  puts "I\'m a computer"
40
40
  else
41
41
  say "Hi Human!"
@@ -37,6 +37,21 @@ module Fastlane
37
37
  user ||= CredentialsManager::AppfileConfig.try_fetch_value(:apple_id)
38
38
 
39
39
  [
40
+ FastlaneCore::ConfigItem.new(key: :api_key_path,
41
+ env_name: "APPSTORE_BUILD_NUMBER_API_KEY_PATH",
42
+ description: "Path to your App Store Connect API Key JSON file (https://docs.fastlane.tools/app-store-connect-api/#using-fastlane-api-key-json-file)",
43
+ optional: true,
44
+ conflicting_options: [:api_key],
45
+ verify_block: proc do |value|
46
+ UI.user_error!("Couldn't find API key JSON file at path '#{value}'") unless File.exist?(value)
47
+ end),
48
+ FastlaneCore::ConfigItem.new(key: :api_key,
49
+ env_name: "APPSTORE_BUILD_NUMBER_API_KEY",
50
+ description: "Your App Store Connect API Key information (https://docs.fastlane.tools/app-store-connect-api/#use-return-value-and-pass-in-as-an-option)",
51
+ type: Hash,
52
+ optional: true,
53
+ sensitive: true,
54
+ conflicting_options: [:api_key_path]),
40
55
  FastlaneCore::ConfigItem.new(key: :live,
41
56
  short_option: "-l",
42
57
  env_name: "CURRENT_BUILD_NUMBER_LIVE",
@@ -11,23 +11,39 @@ module Fastlane
11
11
  require 'spaceship'
12
12
 
13
13
  name = params[:name]
14
+ platform = params[:platform]
14
15
  udid = params[:udid]
15
16
 
16
- credentials = CredentialsManager::AccountManager.new(user: params[:username])
17
- Spaceship.login(credentials.user, credentials.password)
18
- Spaceship.select_team
17
+ platform = Spaceship::ConnectAPI::BundleIdPlatform.map(platform)
18
+
19
+ if (token = api_token(params))
20
+ UI.message("Using App Store Connect API token...")
21
+ Spaceship::ConnectAPI.token = token
22
+ else
23
+ UI.message("Login to App Store Connect (#{params[:username]})")
24
+ credentials = CredentialsManager::AccountManager.new(user: params[:username])
25
+ Spaceship::ConnectAPI.login(credentials.user, credentials.password, use_portal: true, use_tunes: false)
26
+ UI.message("Login successful")
27
+ end
19
28
 
20
29
  begin
21
- Spaceship::Device.create!(name: name, udid: udid)
30
+ Spaceship::ConnectAPI::Device.create(name: name, platform: platform, udid: udid)
22
31
  rescue => ex
23
32
  UI.error(ex.to_s)
24
- UI.crash!("Failed to register new device (name: #{name}, UDID: #{udid})")
33
+ UI.crash!("Failed to register new device (name: #{name}, platform: #{platform}, UDID: #{udid})")
25
34
  end
26
35
 
27
36
  UI.success("Successfully registered new device")
28
37
  return udid
29
38
  end
30
39
 
40
+ def self.api_token(params)
41
+ params[:api_key] ||= Actions.lane_context[SharedValues::APP_STORE_CONNECT_API_KEY]
42
+ api_token ||= Spaceship::ConnectAPI::Token.create(params[:api_key]) if params[:api_key]
43
+ api_token ||= Spaceship::ConnectAPI::Token.from_json_file(params[:api_key_path]) if params[:api_key_path]
44
+ return api_token
45
+ end
46
+
31
47
  def self.description
32
48
  "Registers a new device to the Apple Dev Portal"
33
49
  end
@@ -35,14 +51,38 @@ module Fastlane
35
51
  def self.available_options
36
52
  user = CredentialsManager::AppfileConfig.try_fetch_value(:apple_dev_portal_id)
37
53
  user ||= CredentialsManager::AppfileConfig.try_fetch_value(:apple_id)
54
+ platform = Actions.lane_context[Actions::SharedValues::PLATFORM_NAME].to_s
38
55
 
39
56
  [
40
57
  FastlaneCore::ConfigItem.new(key: :name,
41
58
  env_name: "FL_REGISTER_DEVICE_NAME",
42
59
  description: "Provide the name of the device to register as"),
60
+ FastlaneCore::ConfigItem.new(key: :platform,
61
+ env_name: "FL_REGISTER_DEVICE_PLATFORM",
62
+ description: "Provide the platform of the device to register as (ios, mac)",
63
+ optional: true,
64
+ default_value: platform.empty? ? "ios" : platform,
65
+ verify_block: proc do |value|
66
+ UI.user_error!("The platform can only be ios or mac") unless %('ios', 'mac').include?(value)
67
+ end),
43
68
  FastlaneCore::ConfigItem.new(key: :udid,
44
69
  env_name: "FL_REGISTER_DEVICE_UDID",
45
70
  description: "Provide the UDID of the device to register as"),
71
+ FastlaneCore::ConfigItem.new(key: :api_key_path,
72
+ env_name: "FL_REGISTER_DEVICE_API_KEY_PATH",
73
+ description: "Path to your App Store Connect API Key JSON file (https://docs.fastlane.tools/app-store-connect-api/#using-fastlane-api-key-json-file)",
74
+ optional: true,
75
+ conflicting_options: [:api_key],
76
+ verify_block: proc do |value|
77
+ UI.user_error!("Couldn't find API key JSON file at path '#{value}'") unless File.exist?(value)
78
+ end),
79
+ FastlaneCore::ConfigItem.new(key: :api_key,
80
+ env_name: "FL_REGISTER_DEVICE_API_KEY",
81
+ description: "Your App Store Connect API Key information (https://docs.fastlane.tools/app-store-connect-api/#use-return-value-and-pass-in-as-an-option)",
82
+ type: Hash,
83
+ optional: true,
84
+ sensitive: true,
85
+ conflicting_options: [:api_key_path]),
46
86
  FastlaneCore::ConfigItem.new(key: :team_id,
47
87
  env_name: "REGISTER_DEVICE_TEAM_ID",
48
88
  code_gen_sensitive: true,
@@ -66,6 +106,7 @@ module Fastlane
66
106
  FastlaneCore::ConfigItem.new(key: :username,
67
107
  env_name: "DELIVER_USER",
68
108
  description: "Optional: Your Apple ID",
109
+ optional: true,
69
110
  default_value: user,
70
111
  default_value_dynamic: true)
71
112
  ]
@@ -12,6 +12,8 @@ module Fastlane
12
12
  end
13
13
 
14
14
  def self.run(params)
15
+ platform = Spaceship::ConnectAPI::BundleIdPlatform.map(params[:platform])
16
+
15
17
  if params[:devices]
16
18
  new_devices = params[:devices].map do |name, udid|
17
19
  [udid, name]
@@ -37,40 +39,57 @@ module Fastlane
37
39
  end
38
40
 
39
41
  require 'spaceship'
40
- credentials = CredentialsManager::AccountManager.new(user: params[:username])
41
- Spaceship.login(credentials.user, credentials.password)
42
- Spaceship.select_team
43
-
44
- UI.message("Fetching list of currently registered devices...")
45
- all_platforms = Set[params[:platform]]
46
- new_devices.each do |device|
47
- next if device[2].nil?
48
- all_platforms.add(device[2])
42
+ if (token = api_token(params))
43
+ UI.message("Using App Store Connect API token...")
44
+ Spaceship::ConnectAPI.token = token
45
+ else
46
+ UI.message("Login to App Store Connect (#{params[:username]})")
47
+ credentials = CredentialsManager::AccountManager.new(user: params[:username])
48
+ Spaceship::ConnectAPI.login(credentials.user, credentials.password, use_portal: true, use_tunes: false)
49
+ UI.message("Login successful")
49
50
  end
50
- supported_platforms = all_platforms.select { |platform| self.is_supported?(platform.to_sym) }
51
51
 
52
- existing_devices = supported_platforms.flat_map { |platform| Spaceship::Device.all(mac: platform == "mac") }
52
+ UI.message("Fetching list of currently registered devices...")
53
+ existing_devices = Spaceship::ConnectAPI::Device.all
53
54
 
54
55
  device_objs = new_devices.map do |device|
55
- next if existing_devices.map(&:udid).include?(device[0])
56
+ if existing_devices.map(&:udid).map(&:downcase).include?(device[0].downcase)
57
+ UI.verbose("UDID #{device[0]} already exists - Skipping...")
58
+ next
59
+ end
60
+
61
+ device_platform = platform
56
62
 
57
63
  device_platform_supported = !device[2].nil? && self.is_supported?(device[2].to_sym)
58
- mac = (device_platform_supported ? device[2] : params[:platform]) == "mac"
64
+ if device_platform_supported
65
+ if device[2] == "mac"
66
+ device_platform = Spaceship::ConnectAPI::BundleIdPlatform::MAC_OS
67
+ else
68
+ device_platform = Spaceship::ConnectAPI::BundleIdPlatform::IOS
69
+ end
70
+ end
59
71
 
60
- try_create_device(name: device[1], udid: device[0], mac: mac)
72
+ try_create_device(name: device[1], platform: device_platform, udid: device[0])
61
73
  end
62
74
 
63
75
  UI.success("Successfully registered new devices.")
64
76
  return device_objs
65
77
  end
66
78
 
67
- def self.try_create_device(name: nil, udid: nil, mac: false)
68
- Spaceship::Device.create!(name: name, udid: udid, mac: mac)
79
+ def self.try_create_device(name: nil, platform: nil, udid: nil)
80
+ Spaceship::ConnectAPI::Device.create(name: name, platform: platform, udid: udid)
69
81
  rescue => ex
70
82
  UI.error(ex.to_s)
71
83
  UI.crash!("Failed to register new device (name: #{name}, UDID: #{udid})")
72
84
  end
73
85
 
86
+ def self.api_token(params)
87
+ params[:api_key] ||= Actions.lane_context[SharedValues::APP_STORE_CONNECT_API_KEY]
88
+ api_token ||= Spaceship::ConnectAPI::Token.create(params[:api_key]) if params[:api_key]
89
+ api_token ||= Spaceship::ConnectAPI::Token.from_json_file(params[:api_key_path]) if params[:api_key_path]
90
+ return api_token
91
+ end
92
+
74
93
  #####################################################
75
94
  # @!group Documentation
76
95
  #####################################################
@@ -98,6 +117,21 @@ module Fastlane
98
117
  verify_block: proc do |value|
99
118
  UI.user_error!("Could not find file '#{value}'") unless File.exist?(value)
100
119
  end),
120
+ FastlaneCore::ConfigItem.new(key: :api_key_path,
121
+ env_name: "FL_REGISTER_DEVICES_API_KEY_PATH",
122
+ description: "Path to your App Store Connect API Key JSON file (https://docs.fastlane.tools/app-store-connect-api/#using-fastlane-api-key-json-file)",
123
+ optional: true,
124
+ conflicting_options: [:api_key],
125
+ verify_block: proc do |value|
126
+ UI.user_error!("Couldn't find API key JSON file at path '#{value}'") unless File.exist?(value)
127
+ end),
128
+ FastlaneCore::ConfigItem.new(key: :api_key,
129
+ env_name: "FL_REGISTER_DEVICES_API_KEY",
130
+ description: "Your App Store Connect API Key information (https://docs.fastlane.tools/app-store-connect-api/#use-return-value-and-pass-in-as-an-option)",
131
+ type: Hash,
132
+ optional: true,
133
+ sensitive: true,
134
+ conflicting_options: [:api_key_path]),
101
135
  FastlaneCore::ConfigItem.new(key: :team_id,
102
136
  env_name: "REGISTER_DEVICES_TEAM_ID",
103
137
  code_gen_sensitive: true,