fastlane 2.238.0 → 2.239.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (45) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +96 -96
  3. data/bin/fastlane +2 -2
  4. data/deliver/lib/deliver/html_generator.rb +1 -1
  5. data/deliver/lib/deliver/options.rb +8 -0
  6. data/deliver/lib/deliver/upload_metadata.rb +22 -0
  7. data/deliver/lib/deliver/upload_screenshots.rb +12 -4
  8. data/fastlane/lib/fastlane/actions/changelog_from_git_commits.rb +7 -2
  9. data/fastlane/lib/fastlane/actions/docs/get_push_certificate.md +6 -0
  10. data/fastlane/lib/fastlane/helper/git_helper.rb +4 -2
  11. data/fastlane/lib/fastlane/helper/sh_helper.rb +9 -1
  12. data/fastlane/lib/fastlane/plugins/template/%gem_name%.gemspec.erb +1 -1
  13. data/fastlane/lib/fastlane/plugins/template/.rubocop.yml +5 -1
  14. data/fastlane/lib/fastlane/version.rb +1 -1
  15. data/fastlane/swift/Deliverfile.swift +1 -1
  16. data/fastlane/swift/DeliverfileProtocol.swift +8 -1
  17. data/fastlane/swift/Fastlane.swift +38 -2
  18. data/fastlane/swift/Gymfile.swift +1 -1
  19. data/fastlane/swift/GymfileProtocol.swift +1 -1
  20. data/fastlane/swift/Matchfile.swift +1 -1
  21. data/fastlane/swift/MatchfileProtocol.swift +1 -1
  22. data/fastlane/swift/Precheckfile.swift +1 -1
  23. data/fastlane/swift/PrecheckfileProtocol.swift +1 -1
  24. data/fastlane/swift/Scanfile.swift +1 -1
  25. data/fastlane/swift/ScanfileProtocol.swift +1 -1
  26. data/fastlane/swift/Screengrabfile.swift +1 -1
  27. data/fastlane/swift/ScreengrabfileProtocol.swift +1 -1
  28. data/fastlane/swift/Snapshotfile.swift +1 -1
  29. data/fastlane/swift/SnapshotfileProtocol.swift +1 -1
  30. data/match/lib/match/nuke.rb +2 -2
  31. data/match/lib/match/storage/git_storage.rb +1 -4
  32. data/match/lib/match/storage/google_cloud_storage.rb +6 -1
  33. data/pem/lib/pem/manager.rb +5 -1
  34. data/pem/lib/pem/options.rb +6 -0
  35. data/pilot/lib/pilot/build_manager.rb +32 -0
  36. data/pilot/lib/pilot/options.rb +8 -0
  37. data/sigh/lib/assets/resign.sh +21 -9
  38. data/spaceship/lib/spaceship/connect_api/models/app_store_version.rb +16 -0
  39. data/spaceship/lib/spaceship/connect_api/models/routing_app_coverage.rb +75 -0
  40. data/spaceship/lib/spaceship/connect_api/token.rb +6 -1
  41. data/spaceship/lib/spaceship/connect_api/tunes/tunes.rb +45 -0
  42. data/spaceship/lib/spaceship/connect_api.rb +1 -0
  43. data/supply/lib/supply/client.rb +6 -0
  44. data/supply/lib/supply/reader.rb +15 -0
  45. metadata +26 -42
@@ -702,6 +702,7 @@ public func appledoc(input: [String],
702
702
  - appReviewInformation: Metadata: A hash containing the review information
703
703
  - appClipReviewInformation: Metadata: A hash containing the app clip review information
704
704
  - appReviewAttachmentFile: Metadata: Path to the app review attachment file
705
+ - routingAppCoverageFile: Metadata: Path to the routing app coverage file (`.geojson`) that is required for routing apps
705
706
  - description: Metadata: The localised app description
706
707
  - name: Metadata: The localised app name
707
708
  - subtitle: Metadata: The localised app subtitle
@@ -785,6 +786,7 @@ public func appstore(apiKeyPath: OptionalConfigValue<String?> = .fastlaneDefault
785
786
  appReviewInformation: OptionalConfigValue<[String: Any]?> = .fastlaneDefault(nil),
786
787
  appClipReviewInformation: OptionalConfigValue<[String: Any]?> = .fastlaneDefault(nil),
787
788
  appReviewAttachmentFile: OptionalConfigValue<String?> = .fastlaneDefault(nil),
789
+ routingAppCoverageFile: OptionalConfigValue<String?> = .fastlaneDefault(nil),
788
790
  description: OptionalConfigValue<[String: Any]?> = .fastlaneDefault(nil),
789
791
  name: OptionalConfigValue<[String: Any]?> = .fastlaneDefault(nil),
790
792
  subtitle: OptionalConfigValue<[String: Any]?> = .fastlaneDefault(nil),
@@ -861,6 +863,7 @@ public func appstore(apiKeyPath: OptionalConfigValue<String?> = .fastlaneDefault
861
863
  let appReviewInformationArg = appReviewInformation.asRubyArgument(name: "app_review_information", type: nil)
862
864
  let appClipReviewInformationArg = appClipReviewInformation.asRubyArgument(name: "app_clip_review_information", type: nil)
863
865
  let appReviewAttachmentFileArg = appReviewAttachmentFile.asRubyArgument(name: "app_review_attachment_file", type: nil)
866
+ let routingAppCoverageFileArg = routingAppCoverageFile.asRubyArgument(name: "routing_app_coverage_file", type: nil)
864
867
  let descriptionArg = description.asRubyArgument(name: "description", type: nil)
865
868
  let nameArg = name.asRubyArgument(name: "name", type: nil)
866
869
  let subtitleArg = subtitle.asRubyArgument(name: "subtitle", type: nil)
@@ -936,6 +939,7 @@ public func appstore(apiKeyPath: OptionalConfigValue<String?> = .fastlaneDefault
936
939
  appReviewInformationArg,
937
940
  appClipReviewInformationArg,
938
941
  appReviewAttachmentFileArg,
942
+ routingAppCoverageFileArg,
939
943
  descriptionArg,
940
944
  nameArg,
941
945
  subtitleArg,
@@ -2848,6 +2852,7 @@ public func cert(development: OptionalConfigValue<Bool> = .fastlaneDefault(false
2848
2852
  - commitsCount: Number of commits to include in changelog, you mustn't use it with :between key at the same time
2849
2853
  - path: Path of the git repository
2850
2854
  - pretty: The format applied to each commit while generating the collected value
2855
+ - matchingPattern: A regexp pattern to filter only the commits matching the pattern
2851
2856
  - dateFormat: The date format applied to each commit while generating the collected value
2852
2857
  - ancestryPath: Whether or not to use ancestry-path param
2853
2858
  - tagMatchPattern: A glob(7) pattern to match against when finding the last git tag
@@ -2865,6 +2870,7 @@ public func cert(development: OptionalConfigValue<Bool> = .fastlaneDefault(false
2865
2870
  commitsCount: OptionalConfigValue<Int?> = .fastlaneDefault(nil),
2866
2871
  path: String = "./",
2867
2872
  pretty: String = "%B",
2873
+ matchingPattern: OptionalConfigValue<String?> = .fastlaneDefault(nil),
2868
2874
  dateFormat: OptionalConfigValue<String?> = .fastlaneDefault(nil),
2869
2875
  ancestryPath: OptionalConfigValue<Bool> = .fastlaneDefault(false),
2870
2876
  tagMatchPattern: OptionalConfigValue<String?> = .fastlaneDefault(nil),
@@ -2878,6 +2884,7 @@ public func cert(development: OptionalConfigValue<Bool> = .fastlaneDefault(false
2878
2884
  let commitsCountArg = commitsCount.asRubyArgument(name: "commits_count", type: nil)
2879
2885
  let pathArg = RubyCommand.Argument(name: "path", value: path, type: nil)
2880
2886
  let prettyArg = RubyCommand.Argument(name: "pretty", value: pretty, type: nil)
2887
+ let matchingPatternArg = matchingPattern.asRubyArgument(name: "matching_pattern", type: nil)
2881
2888
  let dateFormatArg = dateFormat.asRubyArgument(name: "date_format", type: nil)
2882
2889
  let ancestryPathArg = ancestryPath.asRubyArgument(name: "ancestry_path", type: nil)
2883
2890
  let tagMatchPatternArg = tagMatchPattern.asRubyArgument(name: "tag_match_pattern", type: nil)
@@ -2890,6 +2897,7 @@ public func cert(development: OptionalConfigValue<Bool> = .fastlaneDefault(false
2890
2897
  commitsCountArg,
2891
2898
  pathArg,
2892
2899
  prettyArg,
2900
+ matchingPatternArg,
2893
2901
  dateFormatArg,
2894
2902
  ancestryPathArg,
2895
2903
  tagMatchPatternArg,
@@ -3865,6 +3873,7 @@ public func deleteKeychain(name: OptionalConfigValue<String?> = .fastlaneDefault
3865
3873
  - appReviewInformation: Metadata: A hash containing the review information
3866
3874
  - appClipReviewInformation: Metadata: A hash containing the app clip review information
3867
3875
  - appReviewAttachmentFile: Metadata: Path to the app review attachment file
3876
+ - routingAppCoverageFile: Metadata: Path to the routing app coverage file (`.geojson`) that is required for routing apps
3868
3877
  - description: Metadata: The localised app description
3869
3878
  - name: Metadata: The localised app name
3870
3879
  - subtitle: Metadata: The localised app subtitle
@@ -3948,6 +3957,7 @@ public func deliver(apiKeyPath: OptionalConfigValue<String?> = .fastlaneDefault(
3948
3957
  appReviewInformation: OptionalConfigValue<[String: Any]?> = .fastlaneDefault(deliverfile.appReviewInformation),
3949
3958
  appClipReviewInformation: OptionalConfigValue<[String: Any]?> = .fastlaneDefault(deliverfile.appClipReviewInformation),
3950
3959
  appReviewAttachmentFile: OptionalConfigValue<String?> = .fastlaneDefault(deliverfile.appReviewAttachmentFile),
3960
+ routingAppCoverageFile: OptionalConfigValue<String?> = .fastlaneDefault(deliverfile.routingAppCoverageFile),
3951
3961
  description: OptionalConfigValue<[String: Any]?> = .fastlaneDefault(deliverfile.description),
3952
3962
  name: OptionalConfigValue<[String: Any]?> = .fastlaneDefault(deliverfile.name),
3953
3963
  subtitle: OptionalConfigValue<[String: Any]?> = .fastlaneDefault(deliverfile.subtitle),
@@ -4024,6 +4034,7 @@ public func deliver(apiKeyPath: OptionalConfigValue<String?> = .fastlaneDefault(
4024
4034
  let appReviewInformationArg = appReviewInformation.asRubyArgument(name: "app_review_information", type: nil)
4025
4035
  let appClipReviewInformationArg = appClipReviewInformation.asRubyArgument(name: "app_clip_review_information", type: nil)
4026
4036
  let appReviewAttachmentFileArg = appReviewAttachmentFile.asRubyArgument(name: "app_review_attachment_file", type: nil)
4037
+ let routingAppCoverageFileArg = routingAppCoverageFile.asRubyArgument(name: "routing_app_coverage_file", type: nil)
4027
4038
  let descriptionArg = description.asRubyArgument(name: "description", type: nil)
4028
4039
  let nameArg = name.asRubyArgument(name: "name", type: nil)
4029
4040
  let subtitleArg = subtitle.asRubyArgument(name: "subtitle", type: nil)
@@ -4099,6 +4110,7 @@ public func deliver(apiKeyPath: OptionalConfigValue<String?> = .fastlaneDefault(
4099
4110
  appReviewInformationArg,
4100
4111
  appClipReviewInformationArg,
4101
4112
  appReviewAttachmentFileArg,
4113
+ routingAppCoverageFileArg,
4102
4114
  descriptionArg,
4103
4115
  nameArg,
4104
4116
  subtitleArg,
@@ -5311,6 +5323,7 @@ public func getManagedPlayStorePublishingRights(jsonKey: OptionalConfigValue<Str
5311
5323
  - platform: Set certificate's platform. Used for creation of production & development certificates. Supported platforms: ios, macos
5312
5324
  - development: Renew the development push certificate instead of the production one
5313
5325
  - websitePush: Create a Website Push certificate
5326
+ - voipPush: Create a VoIP Services certificate
5314
5327
  - generateP12: Generate a p12 file additionally to a PEM file
5315
5328
  - activeDaysLimit: If the current certificate is active for less than this number of days, generate a new one
5316
5329
  - force: Create a new push certificate, even if the current one is active for 30 (or PEM_ACTIVE_DAYS_LIMIT) more days
@@ -5339,6 +5352,7 @@ public func getManagedPlayStorePublishingRights(jsonKey: OptionalConfigValue<Str
5339
5352
  public func getPushCertificate(platform: String = "ios",
5340
5353
  development: OptionalConfigValue<Bool> = .fastlaneDefault(false),
5341
5354
  websitePush: OptionalConfigValue<Bool> = .fastlaneDefault(false),
5355
+ voipPush: OptionalConfigValue<Bool> = .fastlaneDefault(false),
5342
5356
  generateP12: OptionalConfigValue<Bool> = .fastlaneDefault(true),
5343
5357
  activeDaysLimit: Int = 30,
5344
5358
  force: OptionalConfigValue<Bool> = .fastlaneDefault(false),
@@ -5355,6 +5369,7 @@ public func getPushCertificate(platform: String = "ios",
5355
5369
  let platformArg = RubyCommand.Argument(name: "platform", value: platform, type: nil)
5356
5370
  let developmentArg = development.asRubyArgument(name: "development", type: nil)
5357
5371
  let websitePushArg = websitePush.asRubyArgument(name: "website_push", type: nil)
5372
+ let voipPushArg = voipPush.asRubyArgument(name: "voip_push", type: nil)
5358
5373
  let generateP12Arg = generateP12.asRubyArgument(name: "generate_p12", type: nil)
5359
5374
  let activeDaysLimitArg = RubyCommand.Argument(name: "active_days_limit", value: activeDaysLimit, type: nil)
5360
5375
  let forceArg = force.asRubyArgument(name: "force", type: nil)
@@ -5370,6 +5385,7 @@ public func getPushCertificate(platform: String = "ios",
5370
5385
  let array: [RubyCommand.Argument?] = [platformArg,
5371
5386
  developmentArg,
5372
5387
  websitePushArg,
5388
+ voipPushArg,
5373
5389
  generateP12Arg,
5374
5390
  activeDaysLimitArg,
5375
5391
  forceArg,
@@ -6648,7 +6664,7 @@ public func jazzy(config: OptionalConfigValue<String?> = .fastlaneDefault(nil),
6648
6664
  /**
6649
6665
  Return last git commit hash, abbreviated commit hash, commit message and author
6650
6666
 
6651
- - returns: Returns the following dict: {commit_hash: "commit hash", abbreviated_commit_hash: "abbreviated commit hash" author: "Author", author_email: "author email", message: "commit message"}. Example: {:message=>"message", :author=>"author", :author_email=>"author_email", :commit_hash=>"commit_hash", :abbreviated_commit_hash=>"short_hash"}
6667
+ - returns: Returns the following dict: {commit_hash: "commit hash", abbreviated_commit_hash: "abbreviated commit hash" author: "Author", author_email: "author email", message: "commit message"}. Example: {message: "message", author: "author", author_email: "author_email", commit_hash: "commit_hash", abbreviated_commit_hash: "short_hash"}
6652
6668
  */
6653
6669
  @discardableResult public func lastGitCommit() -> [String: String] {
6654
6670
  let args: [RubyCommand.Argument] = []
@@ -7786,6 +7802,7 @@ public func optOutUsage() {
7786
7802
  - platform: Set certificate's platform. Used for creation of production & development certificates. Supported platforms: ios, macos
7787
7803
  - development: Renew the development push certificate instead of the production one
7788
7804
  - websitePush: Create a Website Push certificate
7805
+ - voipPush: Create a VoIP Services certificate
7789
7806
  - generateP12: Generate a p12 file additionally to a PEM file
7790
7807
  - activeDaysLimit: If the current certificate is active for less than this number of days, generate a new one
7791
7808
  - force: Create a new push certificate, even if the current one is active for 30 (or PEM_ACTIVE_DAYS_LIMIT) more days
@@ -7814,6 +7831,7 @@ public func optOutUsage() {
7814
7831
  public func pem(platform: String = "ios",
7815
7832
  development: OptionalConfigValue<Bool> = .fastlaneDefault(false),
7816
7833
  websitePush: OptionalConfigValue<Bool> = .fastlaneDefault(false),
7834
+ voipPush: OptionalConfigValue<Bool> = .fastlaneDefault(false),
7817
7835
  generateP12: OptionalConfigValue<Bool> = .fastlaneDefault(true),
7818
7836
  activeDaysLimit: Int = 30,
7819
7837
  force: OptionalConfigValue<Bool> = .fastlaneDefault(false),
@@ -7830,6 +7848,7 @@ public func pem(platform: String = "ios",
7830
7848
  let platformArg = RubyCommand.Argument(name: "platform", value: platform, type: nil)
7831
7849
  let developmentArg = development.asRubyArgument(name: "development", type: nil)
7832
7850
  let websitePushArg = websitePush.asRubyArgument(name: "website_push", type: nil)
7851
+ let voipPushArg = voipPush.asRubyArgument(name: "voip_push", type: nil)
7833
7852
  let generateP12Arg = generateP12.asRubyArgument(name: "generate_p12", type: nil)
7834
7853
  let activeDaysLimitArg = RubyCommand.Argument(name: "active_days_limit", value: activeDaysLimit, type: nil)
7835
7854
  let forceArg = force.asRubyArgument(name: "force", type: nil)
@@ -7845,6 +7864,7 @@ public func pem(platform: String = "ios",
7845
7864
  let array: [RubyCommand.Argument?] = [platformArg,
7846
7865
  developmentArg,
7847
7866
  websitePushArg,
7867
+ voipPushArg,
7848
7868
  generateP12Arg,
7849
7869
  activeDaysLimitArg,
7850
7870
  forceArg,
@@ -7888,6 +7908,7 @@ public func pem(platform: String = "ios",
7888
7908
  - updateBuildInfoOnUpload: **DEPRECATED!** Update build info immediately after validation. This is deprecated and will be removed in a future release. App Store Connect no longer supports setting build info until after build processing has completed, which is when build info is updated by default
7889
7909
  - appClipInvocations: Add beta app clip invocations to your builds in TestFlight
7890
7910
  - overwriteAppClipInvocations: Clear all previous beta app clip invocations before adding new ones
7911
+ - routingAppCoverageFile: Path to the routing app coverage file (`.geojson`) that is required for routing apps. It will be uploaded to the editable App Store version of the app
7891
7912
  - distributeOnly: Distribute a previously uploaded build (equivalent to the `fastlane pilot distribute` command)
7892
7913
  - usesNonExemptEncryption: Provide the 'Uses Non-Exempt Encryption' for export compliance. This is used if there is 'ITSAppUsesNonExemptEncryption' is not set in the Info.plist
7893
7914
  - distributeExternal: Should the build be distributed to external testers? If set to true, use of `groups` option is required
@@ -7934,6 +7955,7 @@ public func pilot(apiKeyPath: OptionalConfigValue<String?> = .fastlaneDefault(ni
7934
7955
  updateBuildInfoOnUpload: OptionalConfigValue<Bool> = .fastlaneDefault(false),
7935
7956
  appClipInvocations: OptionalConfigValue<[String]?> = .fastlaneDefault(nil),
7936
7957
  overwriteAppClipInvocations: OptionalConfigValue<Bool> = .fastlaneDefault(false),
7958
+ routingAppCoverageFile: OptionalConfigValue<String?> = .fastlaneDefault(nil),
7937
7959
  distributeOnly: OptionalConfigValue<Bool> = .fastlaneDefault(false),
7938
7960
  usesNonExemptEncryption: OptionalConfigValue<Bool> = .fastlaneDefault(false),
7939
7961
  distributeExternal: OptionalConfigValue<Bool> = .fastlaneDefault(false),
@@ -7977,6 +7999,7 @@ public func pilot(apiKeyPath: OptionalConfigValue<String?> = .fastlaneDefault(ni
7977
7999
  let updateBuildInfoOnUploadArg = updateBuildInfoOnUpload.asRubyArgument(name: "update_build_info_on_upload", type: nil)
7978
8000
  let appClipInvocationsArg = appClipInvocations.asRubyArgument(name: "app_clip_invocations", type: nil)
7979
8001
  let overwriteAppClipInvocationsArg = overwriteAppClipInvocations.asRubyArgument(name: "overwrite_app_clip_invocations", type: nil)
8002
+ let routingAppCoverageFileArg = routingAppCoverageFile.asRubyArgument(name: "routing_app_coverage_file", type: nil)
7980
8003
  let distributeOnlyArg = distributeOnly.asRubyArgument(name: "distribute_only", type: nil)
7981
8004
  let usesNonExemptEncryptionArg = usesNonExemptEncryption.asRubyArgument(name: "uses_non_exempt_encryption", type: nil)
7982
8005
  let distributeExternalArg = distributeExternal.asRubyArgument(name: "distribute_external", type: nil)
@@ -8019,6 +8042,7 @@ public func pilot(apiKeyPath: OptionalConfigValue<String?> = .fastlaneDefault(ni
8019
8042
  updateBuildInfoOnUploadArg,
8020
8043
  appClipInvocationsArg,
8021
8044
  overwriteAppClipInvocationsArg,
8045
+ routingAppCoverageFileArg,
8022
8046
  distributeOnlyArg,
8023
8047
  usesNonExemptEncryptionArg,
8024
8048
  distributeExternalArg,
@@ -11832,6 +11856,7 @@ public func testfairy(apiKey: String,
11832
11856
  - updateBuildInfoOnUpload: **DEPRECATED!** Update build info immediately after validation. This is deprecated and will be removed in a future release. App Store Connect no longer supports setting build info until after build processing has completed, which is when build info is updated by default
11833
11857
  - appClipInvocations: Add beta app clip invocations to your builds in TestFlight
11834
11858
  - overwriteAppClipInvocations: Clear all previous beta app clip invocations before adding new ones
11859
+ - routingAppCoverageFile: Path to the routing app coverage file (`.geojson`) that is required for routing apps. It will be uploaded to the editable App Store version of the app
11835
11860
  - distributeOnly: Distribute a previously uploaded build (equivalent to the `fastlane pilot distribute` command)
11836
11861
  - usesNonExemptEncryption: Provide the 'Uses Non-Exempt Encryption' for export compliance. This is used if there is 'ITSAppUsesNonExemptEncryption' is not set in the Info.plist
11837
11862
  - distributeExternal: Should the build be distributed to external testers? If set to true, use of `groups` option is required
@@ -11878,6 +11903,7 @@ public func testflight(apiKeyPath: OptionalConfigValue<String?> = .fastlaneDefau
11878
11903
  updateBuildInfoOnUpload: OptionalConfigValue<Bool> = .fastlaneDefault(false),
11879
11904
  appClipInvocations: OptionalConfigValue<[String]?> = .fastlaneDefault(nil),
11880
11905
  overwriteAppClipInvocations: OptionalConfigValue<Bool> = .fastlaneDefault(false),
11906
+ routingAppCoverageFile: OptionalConfigValue<String?> = .fastlaneDefault(nil),
11881
11907
  distributeOnly: OptionalConfigValue<Bool> = .fastlaneDefault(false),
11882
11908
  usesNonExemptEncryption: OptionalConfigValue<Bool> = .fastlaneDefault(false),
11883
11909
  distributeExternal: OptionalConfigValue<Bool> = .fastlaneDefault(false),
@@ -11921,6 +11947,7 @@ public func testflight(apiKeyPath: OptionalConfigValue<String?> = .fastlaneDefau
11921
11947
  let updateBuildInfoOnUploadArg = updateBuildInfoOnUpload.asRubyArgument(name: "update_build_info_on_upload", type: nil)
11922
11948
  let appClipInvocationsArg = appClipInvocations.asRubyArgument(name: "app_clip_invocations", type: nil)
11923
11949
  let overwriteAppClipInvocationsArg = overwriteAppClipInvocations.asRubyArgument(name: "overwrite_app_clip_invocations", type: nil)
11950
+ let routingAppCoverageFileArg = routingAppCoverageFile.asRubyArgument(name: "routing_app_coverage_file", type: nil)
11924
11951
  let distributeOnlyArg = distributeOnly.asRubyArgument(name: "distribute_only", type: nil)
11925
11952
  let usesNonExemptEncryptionArg = usesNonExemptEncryption.asRubyArgument(name: "uses_non_exempt_encryption", type: nil)
11926
11953
  let distributeExternalArg = distributeExternal.asRubyArgument(name: "distribute_external", type: nil)
@@ -11963,6 +11990,7 @@ public func testflight(apiKeyPath: OptionalConfigValue<String?> = .fastlaneDefau
11963
11990
  updateBuildInfoOnUploadArg,
11964
11991
  appClipInvocationsArg,
11965
11992
  overwriteAppClipInvocationsArg,
11993
+ routingAppCoverageFileArg,
11966
11994
  distributeOnlyArg,
11967
11995
  usesNonExemptEncryptionArg,
11968
11996
  distributeExternalArg,
@@ -12844,6 +12872,7 @@ public func uploadSymbolsToSentry(apiHost: String = "https://app.getsentry.com/a
12844
12872
  - appReviewInformation: Metadata: A hash containing the review information
12845
12873
  - appClipReviewInformation: Metadata: A hash containing the app clip review information
12846
12874
  - appReviewAttachmentFile: Metadata: Path to the app review attachment file
12875
+ - routingAppCoverageFile: Metadata: Path to the routing app coverage file (`.geojson`) that is required for routing apps
12847
12876
  - description: Metadata: The localised app description
12848
12877
  - name: Metadata: The localised app name
12849
12878
  - subtitle: Metadata: The localised app subtitle
@@ -12927,6 +12956,7 @@ public func uploadToAppStore(apiKeyPath: OptionalConfigValue<String?> = .fastlan
12927
12956
  appReviewInformation: OptionalConfigValue<[String: Any]?> = .fastlaneDefault(nil),
12928
12957
  appClipReviewInformation: OptionalConfigValue<[String: Any]?> = .fastlaneDefault(nil),
12929
12958
  appReviewAttachmentFile: OptionalConfigValue<String?> = .fastlaneDefault(nil),
12959
+ routingAppCoverageFile: OptionalConfigValue<String?> = .fastlaneDefault(nil),
12930
12960
  description: OptionalConfigValue<[String: Any]?> = .fastlaneDefault(nil),
12931
12961
  name: OptionalConfigValue<[String: Any]?> = .fastlaneDefault(nil),
12932
12962
  subtitle: OptionalConfigValue<[String: Any]?> = .fastlaneDefault(nil),
@@ -13003,6 +13033,7 @@ public func uploadToAppStore(apiKeyPath: OptionalConfigValue<String?> = .fastlan
13003
13033
  let appReviewInformationArg = appReviewInformation.asRubyArgument(name: "app_review_information", type: nil)
13004
13034
  let appClipReviewInformationArg = appClipReviewInformation.asRubyArgument(name: "app_clip_review_information", type: nil)
13005
13035
  let appReviewAttachmentFileArg = appReviewAttachmentFile.asRubyArgument(name: "app_review_attachment_file", type: nil)
13036
+ let routingAppCoverageFileArg = routingAppCoverageFile.asRubyArgument(name: "routing_app_coverage_file", type: nil)
13006
13037
  let descriptionArg = description.asRubyArgument(name: "description", type: nil)
13007
13038
  let nameArg = name.asRubyArgument(name: "name", type: nil)
13008
13039
  let subtitleArg = subtitle.asRubyArgument(name: "subtitle", type: nil)
@@ -13078,6 +13109,7 @@ public func uploadToAppStore(apiKeyPath: OptionalConfigValue<String?> = .fastlan
13078
13109
  appReviewInformationArg,
13079
13110
  appClipReviewInformationArg,
13080
13111
  appReviewAttachmentFileArg,
13112
+ routingAppCoverageFileArg,
13081
13113
  descriptionArg,
13082
13114
  nameArg,
13083
13115
  subtitleArg,
@@ -13353,6 +13385,7 @@ public func uploadToPlayStoreInternalAppSharing(packageName: String,
13353
13385
  - updateBuildInfoOnUpload: **DEPRECATED!** Update build info immediately after validation. This is deprecated and will be removed in a future release. App Store Connect no longer supports setting build info until after build processing has completed, which is when build info is updated by default
13354
13386
  - appClipInvocations: Add beta app clip invocations to your builds in TestFlight
13355
13387
  - overwriteAppClipInvocations: Clear all previous beta app clip invocations before adding new ones
13388
+ - routingAppCoverageFile: Path to the routing app coverage file (`.geojson`) that is required for routing apps. It will be uploaded to the editable App Store version of the app
13356
13389
  - distributeOnly: Distribute a previously uploaded build (equivalent to the `fastlane pilot distribute` command)
13357
13390
  - usesNonExemptEncryption: Provide the 'Uses Non-Exempt Encryption' for export compliance. This is used if there is 'ITSAppUsesNonExemptEncryption' is not set in the Info.plist
13358
13391
  - distributeExternal: Should the build be distributed to external testers? If set to true, use of `groups` option is required
@@ -13399,6 +13432,7 @@ public func uploadToTestflight(apiKeyPath: OptionalConfigValue<String?> = .fastl
13399
13432
  updateBuildInfoOnUpload: OptionalConfigValue<Bool> = .fastlaneDefault(false),
13400
13433
  appClipInvocations: OptionalConfigValue<[String]?> = .fastlaneDefault(nil),
13401
13434
  overwriteAppClipInvocations: OptionalConfigValue<Bool> = .fastlaneDefault(false),
13435
+ routingAppCoverageFile: OptionalConfigValue<String?> = .fastlaneDefault(nil),
13402
13436
  distributeOnly: OptionalConfigValue<Bool> = .fastlaneDefault(false),
13403
13437
  usesNonExemptEncryption: OptionalConfigValue<Bool> = .fastlaneDefault(false),
13404
13438
  distributeExternal: OptionalConfigValue<Bool> = .fastlaneDefault(false),
@@ -13442,6 +13476,7 @@ public func uploadToTestflight(apiKeyPath: OptionalConfigValue<String?> = .fastl
13442
13476
  let updateBuildInfoOnUploadArg = updateBuildInfoOnUpload.asRubyArgument(name: "update_build_info_on_upload", type: nil)
13443
13477
  let appClipInvocationsArg = appClipInvocations.asRubyArgument(name: "app_clip_invocations", type: nil)
13444
13478
  let overwriteAppClipInvocationsArg = overwriteAppClipInvocations.asRubyArgument(name: "overwrite_app_clip_invocations", type: nil)
13479
+ let routingAppCoverageFileArg = routingAppCoverageFile.asRubyArgument(name: "routing_app_coverage_file", type: nil)
13445
13480
  let distributeOnlyArg = distributeOnly.asRubyArgument(name: "distribute_only", type: nil)
13446
13481
  let usesNonExemptEncryptionArg = usesNonExemptEncryption.asRubyArgument(name: "uses_non_exempt_encryption", type: nil)
13447
13482
  let distributeExternalArg = distributeExternal.asRubyArgument(name: "distribute_external", type: nil)
@@ -13484,6 +13519,7 @@ public func uploadToTestflight(apiKeyPath: OptionalConfigValue<String?> = .fastl
13484
13519
  updateBuildInfoOnUploadArg,
13485
13520
  appClipInvocationsArg,
13486
13521
  overwriteAppClipInvocationsArg,
13522
+ routingAppCoverageFileArg,
13487
13523
  distributeOnlyArg,
13488
13524
  usesNonExemptEncryptionArg,
13489
13525
  distributeExternalArg,
@@ -14143,4 +14179,4 @@ public let snapshotfile: Snapshotfile = .init()
14143
14179
 
14144
14180
  // Please don't remove the lines below
14145
14181
  // They are used to detect outdated files
14146
- // FastlaneRunnerAPIVersion [0.9.205]
14182
+ // FastlaneRunnerAPIVersion [0.9.206]
@@ -17,4 +17,4 @@ public class Gymfile: GymfileProtocol {
17
17
  // during the `init` process, and you won't see this message
18
18
  }
19
19
 
20
- // Generated with fastlane 2.238.0
20
+ // Generated with fastlane 2.239.0
@@ -392,4 +392,4 @@ public extension GymfileProtocol {
392
392
 
393
393
  // Please don't remove the lines below
394
394
  // They are used to detect outdated files
395
- // FastlaneRunnerAPIVersion [0.9.155]
395
+ // FastlaneRunnerAPIVersion [0.9.156]
@@ -17,4 +17,4 @@ public class Matchfile: MatchfileProtocol {
17
17
  // during the `init` process, and you won't see this message
18
18
  }
19
19
 
20
- // Generated with fastlane 2.238.0
20
+ // Generated with fastlane 2.239.0
@@ -413,4 +413,4 @@ public extension MatchfileProtocol {
413
413
 
414
414
  // Please don't remove the lines below
415
415
  // They are used to detect outdated files
416
- // FastlaneRunnerAPIVersion [0.9.149]
416
+ // FastlaneRunnerAPIVersion [0.9.150]
@@ -17,4 +17,4 @@ public class Precheckfile: PrecheckfileProtocol {
17
17
  // during the `init` process, and you won't see this message
18
18
  }
19
19
 
20
- // Generated with fastlane 2.238.0
20
+ // Generated with fastlane 2.239.0
@@ -84,4 +84,4 @@ public extension PrecheckfileProtocol {
84
84
 
85
85
  // Please don't remove the lines below
86
86
  // They are used to detect outdated files
87
- // FastlaneRunnerAPIVersion [0.9.148]
87
+ // FastlaneRunnerAPIVersion [0.9.149]
@@ -17,4 +17,4 @@ public class Scanfile: ScanfileProtocol {
17
17
  // during the `init` process, and you won't see this message
18
18
  }
19
19
 
20
- // Generated with fastlane 2.238.0
20
+ // Generated with fastlane 2.239.0
@@ -581,4 +581,4 @@ public extension ScanfileProtocol {
581
581
 
582
582
  // Please don't remove the lines below
583
583
  // They are used to detect outdated files
584
- // FastlaneRunnerAPIVersion [0.9.160]
584
+ // FastlaneRunnerAPIVersion [0.9.161]
@@ -17,4 +17,4 @@ public class Screengrabfile: ScreengrabfileProtocol {
17
17
  // during the `init` process, and you won't see this message
18
18
  }
19
19
 
20
- // Generated with fastlane 2.238.0
20
+ // Generated with fastlane 2.239.0
@@ -161,4 +161,4 @@ public extension ScreengrabfileProtocol {
161
161
 
162
162
  // Please don't remove the lines below
163
163
  // They are used to detect outdated files
164
- // FastlaneRunnerAPIVersion [0.9.150]
164
+ // FastlaneRunnerAPIVersion [0.9.151]
@@ -17,4 +17,4 @@ public class Snapshotfile: SnapshotfileProtocol {
17
17
  // during the `init` process, and you won't see this message
18
18
  }
19
19
 
20
- // Generated with fastlane 2.238.0
20
+ // Generated with fastlane 2.239.0
@@ -378,4 +378,4 @@ public extension SnapshotfileProtocol {
378
378
 
379
379
  // Please don't remove the lines below
380
380
  // They are used to detect outdated files
381
- // FastlaneRunnerAPIVersion [0.9.144]
381
+ // FastlaneRunnerAPIVersion [0.9.145]
@@ -341,9 +341,9 @@ module Match
341
341
  def filter_profiles_and_files_by_selected_certificates
342
342
  # Do profile selection logic
343
343
  cert_ids = self.certs.map { |cert| cert.id.to_s }
344
- self.profiles = self.profiles.reject do |profile|
344
+ self.profiles = self.profiles.select do |profile|
345
345
  profile_cert_ids = profile.certificates.map { |cert| cert.id.to_s }
346
- (cert_ids & profile_cert_ids).empty?
346
+ cert_ids.intersect?(profile_cert_ids)
347
347
  end
348
348
 
349
349
  profile_uuids = self.profiles.map do |profile|
@@ -117,13 +117,10 @@ module Match
117
117
  print_command: FastlaneCore::Globals.verbose?)
118
118
  end
119
119
  rescue
120
- UI.error("Error cloning certificates repo, please make sure you have read access to the repository you want to use")
121
120
  if self.branch && self.clone_branch_directly
122
121
  UI.error("You passed '#{self.branch}' as branch in combination with the `clone_branch_directly` flag. Please remove `clone_branch_directly` flag on the first run for _match_ to create the branch.")
123
122
  end
124
- UI.error("Run the following command manually to make sure you're properly authenticated:")
125
- UI.command(command)
126
- UI.user_error!("Error cloning certificates git repo, please make sure you have access to the repository - see instructions above")
123
+ UI.user_error!("Error cloning certificates repo, please make sure you have read access to the repository you want to use")
127
124
  end
128
125
 
129
126
  add_user_config(self.git_full_name, self.git_user_email)
@@ -82,7 +82,12 @@ module Match
82
82
  if self.google_cloud_keys_file.to_s.length > 0
83
83
  # Extract the Project ID from the `JSON` file
84
84
  # so the user doesn't have to provide it manually
85
- keys_file_content = JSON.parse(File.read(self.google_cloud_keys_file))
85
+ begin
86
+ keys_file_content = JSON.parse(File.read(self.google_cloud_keys_file))
87
+ rescue JSON::ParserError
88
+ # Don't dump secret into logs in case a secret (p8) is passed. See fastlane/fastlane#21017
89
+ UI.user_error!("Provided keys file on path #{File.expand_path(self.google_cloud_keys_file)} is not a valid JSON file")
90
+ end
86
91
  if google_cloud_project_id.to_s.length > 0 && google_cloud_project_id != keys_file_content["project_id"]
87
92
  UI.important("The google_cloud_keys_file's project ID ('#{keys_file_content['project_id']}') doesn't match the google_cloud_project_id ('#{google_cloud_project_id}'). This may be the wrong keys file.")
88
93
  end
@@ -20,7 +20,7 @@ module PEM
20
20
  remaining_days = (existing_certificate.expires - Time.now) / 60 / 60 / 24
21
21
 
22
22
  display_platform = ''
23
- unless PEM.config[:website_push]
23
+ unless PEM.config[:website_push] || PEM.config[:voip_push]
24
24
  display_platform = "#{PEM.config[:platform]} "
25
25
  end
26
26
 
@@ -94,6 +94,8 @@ module PEM
94
94
  def certificate
95
95
  if PEM.config[:website_push]
96
96
  Spaceship.certificate.website_push
97
+ elsif PEM.config[:voip_push]
98
+ Spaceship.certificate.voip_push
97
99
  else
98
100
  platform = PEM.config[:platform]
99
101
  UI.user_error!('platform parameter is unspecified.') unless platform
@@ -123,6 +125,8 @@ module PEM
123
125
  'development'
124
126
  elsif PEM.config[:website_push]
125
127
  'website'
128
+ elsif PEM.config[:voip_push]
129
+ 'voip'
126
130
  else
127
131
  'production'
128
132
  end
@@ -30,6 +30,12 @@ module PEM
30
30
  is_string: false,
31
31
  conflicting_options: [:development],
32
32
  default_value: false),
33
+ FastlaneCore::ConfigItem.new(key: :voip_push,
34
+ env_name: "PEM_VOIP_PUSH",
35
+ description: "Create a VoIP Services certificate",
36
+ is_string: false,
37
+ conflicting_options: [:development, :website_push],
38
+ default_value: false),
33
39
  FastlaneCore::ConfigItem.new(key: :generate_p12,
34
40
  env_name: "PEM_GENERATE_P12_FILE",
35
41
  description: "Generate a p12 file additionally to a PEM file",
@@ -296,6 +296,9 @@ module Pilot
296
296
 
297
297
  # Handle beta app clip invocations
298
298
  update_app_clip_invocations(options: options, build: build)
299
+
300
+ # Handle routing app coverage file
301
+ update_routing_app_coverage(options)
299
302
  end
300
303
 
301
304
  def self.truncate_changelog(changelog)
@@ -679,6 +682,35 @@ module Pilot
679
682
  end
680
683
  end
681
684
  end
685
+
686
+ def update_routing_app_coverage(options)
687
+ # Skip logic entirely if no coverage file passed. So status-quo stays the same.
688
+ return unless options[:routing_app_coverage_file]
689
+
690
+ # We can only attach a coverage file to build upload - so pick the most recent edit.
691
+ platform = Spaceship::ConnectAPI::Platform.map(fetch_app_platform)
692
+ version = app.get_edit_app_store_version(platform: platform)
693
+ unless version
694
+ UI.important("Skipping upload of routing app coverage file - could not find an editable app store version")
695
+ return
696
+ end
697
+
698
+ routing_app_coverage =
699
+ begin
700
+ version.fetch_routing_app_coverage
701
+ rescue => error
702
+ UI.important("Error fetching routing app coverage - #{error.message}")
703
+ nil
704
+ end
705
+
706
+ if routing_app_coverage
707
+ UI.message("Removing previous routing app coverage file from App Store Connect")
708
+ routing_app_coverage.delete!
709
+ end
710
+
711
+ UI.message("Uploading routing app coverage file to App Store Connect")
712
+ version.upload_routing_app_coverage(path: options[:routing_app_coverage_file])
713
+ end
682
714
  end
683
715
  # rubocop:enable Metrics/ClassLength
684
716
  end
@@ -201,6 +201,14 @@ module Pilot
201
201
  optional: true,
202
202
  type: Boolean,
203
203
  default_value: false),
204
+ FastlaneCore::ConfigItem.new(key: :routing_app_coverage_file,
205
+ env_name: "PILOT_ROUTING_APP_COVERAGE_FILE",
206
+ description: "Path to the routing app coverage file (`.geojson`) that is required for routing apps. It will be uploaded to the editable App Store version of the app",
207
+ optional: true,
208
+ verify_block: proc do |value|
209
+ UI.user_error!("Could not find routing app coverage file at path '#{File.expand_path(value)}'") unless File.exist?(value)
210
+ UI.user_error!("Routing app coverage file must be a .geojson file") unless File.extname(value).casecmp(".geojson").zero?
211
+ end),
204
212
 
205
213
  # distribution
206
214
  FastlaneCore::ConfigItem.new(key: :distribute_only,
@@ -665,9 +665,18 @@ function resign {
665
665
  # Get the old and the new team ID
666
666
  # Old team ID is not part of app entitlements, have to get it from old embedded provisioning profile
667
667
  security cms -D -i "$TEMP_DIR/old-embedded.mobileprovision" > "$TEMP_DIR/old-embedded-profile.plist"
668
- OLD_TEAM_ID=$(PlistBuddy -c "Print :TeamIdentifier:0" "$TEMP_DIR/old-embedded-profile.plist")
668
+ OLD_TEAM_ID=$(PlistBuddy -c "Print :TeamIdentifier:0" "$TEMP_DIR/old-embedded-profile.plist" 2>/dev/null)
669
+ if [ "$OLD_TEAM_ID" == "" ]; then
670
+ OLD_TEAM_ID="$OLD_APP_ID"
671
+ fi
669
672
  # New team ID is part of profile entitlements
670
- NEW_TEAM_ID=$(PlistBuddy -c "Print com.apple.developer.team-identifier" "$PROFILE_ENTITLEMENTS" | grep -E '^[A-Z0-9]*' -o | tr -d '\n')
673
+ NEW_TEAM_ID=$(PlistBuddy -c "Print :com.apple.developer.team-identifier" "$PROFILE_ENTITLEMENTS" 2>/dev/null | grep -E '^[A-Z0-9]*' -o | tr -d '\n')
674
+ if [ "$NEW_TEAM_ID" == "" ]; then
675
+ NEW_TEAM_ID="$TEAM_IDENTIFIER"
676
+ fi
677
+ if [ "$NEW_TEAM_ID" == "" ]; then
678
+ NEW_TEAM_ID="$NEW_APP_ID"
679
+ fi
671
680
 
672
681
  log "Patching profile entitlements with values from app entitlements"
673
682
  PATCHED_ENTITLEMENTS="$TEMP_DIR/patchedEntitlements"
@@ -866,13 +875,16 @@ function resign {
866
875
  OLD_BUNDLE_ID="$(PlistBuddy -c "Print :CFBundleIdentifier" "$TEMP_DIR/oldInfo.plist")"
867
876
  NEW_BUNDLE_ID="$(bundle_id_for_provision "$NEW_PROVISION")"
868
877
  log "Replacing old bundle ID '$OLD_BUNDLE_ID' with new bundle ID '$NEW_BUNDLE_ID' in patched entitlements"
869
- # Note: ideally we'd match against the opening <string> tag too, but this isn't possible
870
- # because $OLD_BUNDLE_ID and $NEW_BUNDLE_ID do not include the team ID prefix which is
871
- # present in the entitlements file.
872
- # e.g. <string>AB1GP98Q19.com.example.foo</string>
873
- # vs
874
- # com.example.foo
875
- /usr/bin/sed -i .bak "s!${OLD_BUNDLE_ID}</string>!${NEW_BUNDLE_ID}</string>!g" "$PATCHED_ENTITLEMENTS"
878
+ # Anchor the replacement to OLD_TEAM_ID prefix, app group prefix, or the opening <string> tag
879
+ # so that if NEW_BUNDLE_ID contains OLD_BUNDLE_ID as a suffix (e.g. enterprise.com.example.foo),
880
+ # the already-correct values (like <TEAM_ID>.enterprise.com.example.foo) do not have their
881
+ # suffix duplicated.
882
+ ESCAPED_OLD_BUNDLE_ID="${OLD_BUNDLE_ID//./\\.}"
883
+ if [ -n "$OLD_TEAM_ID" ] && [ -n "$NEW_TEAM_ID" ]; then
884
+ /usr/bin/sed -i .bak "s!<string>${OLD_TEAM_ID}\.${ESCAPED_OLD_BUNDLE_ID}</string>!<string>${NEW_TEAM_ID}.${NEW_BUNDLE_ID}</string>!g" "$PATCHED_ENTITLEMENTS"
885
+ fi
886
+ /usr/bin/sed -i .bak "s!<string>group\.${ESCAPED_OLD_BUNDLE_ID}</string>!<string>group.${NEW_BUNDLE_ID}</string>!g" "$PATCHED_ENTITLEMENTS"
887
+ /usr/bin/sed -i .bak "s!<string>${ESCAPED_OLD_BUNDLE_ID}</string>!<string>${NEW_BUNDLE_ID}</string>!g" "$PATCHED_ENTITLEMENTS"
876
888
 
877
889
  log "Resigning application using certificate: '$CERTIFICATE'"
878
890
  log "and patched entitlements:"
@@ -1,6 +1,7 @@
1
1
  require_relative '../model'
2
2
  require_relative './app_store_review_detail'
3
3
  require_relative './app_store_version_localization'
4
+ require_relative './routing_app_coverage'
4
5
 
5
6
  module Spaceship
6
7
  class ConnectAPI
@@ -243,6 +244,21 @@ module Spaceship
243
244
  return resp.to_models.first
244
245
  end
245
246
 
247
+ #
248
+ # Routing App Coverages
249
+ #
250
+
251
+ def fetch_routing_app_coverage(client: nil)
252
+ client ||= Spaceship::ConnectAPI
253
+ resp = client.get_routing_app_coverage(app_store_version_id: id)
254
+ return resp.to_models.first
255
+ end
256
+
257
+ def upload_routing_app_coverage(client: nil, path: nil)
258
+ client ||= Spaceship::ConnectAPI
259
+ return Spaceship::ConnectAPI::RoutingAppCoverage.create(client: client, app_store_version_id: id, path: path)
260
+ end
261
+
246
262
  #
247
263
  # Reset Ratings Requests
248
264
  #