fastlane 2.142.0 → 2.143.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +84 -84
- data/fastlane/lib/fastlane/actions/.hockey.rb.swp +0 -0
- data/fastlane/lib/fastlane/actions/.slack.rb.swp +0 -0
- data/fastlane/lib/fastlane/actions/.update_project_provisioning.rb.swp +0 -0
- data/fastlane/lib/fastlane/actions/docs/frame_screenshots.md +22 -6
- data/fastlane/lib/fastlane/actions/docs/sync_code_signing.md +20 -4
- data/fastlane/lib/fastlane/actions/frame_screenshots.rb +2 -1
- data/fastlane/lib/fastlane/actions/s3.rb +3 -289
- data/fastlane/lib/fastlane/helper/s3_client_helper.rb +56 -0
- data/fastlane/lib/fastlane/version.rb +1 -1
- data/fastlane/swift/Deliverfile.swift +1 -1
- data/fastlane/swift/Fastlane.swift +59 -5
- data/fastlane/swift/FastlaneSwiftRunner/FastlaneSwiftRunner.xcodeproj/project.xcworkspace/xcuserdata/josh.xcuserdatad/UserInterfaceState.xcuserstate +0 -0
- data/fastlane/swift/Gymfile.swift +1 -1
- data/fastlane/swift/Matchfile.swift +1 -1
- data/fastlane/swift/MatchfileProtocol.swift +17 -1
- data/fastlane/swift/Precheckfile.swift +1 -1
- data/fastlane/swift/Scanfile.swift +1 -1
- data/fastlane/swift/Screengrabfile.swift +1 -1
- data/fastlane/swift/Snapshotfile.swift +1 -1
- data/fastlane_core/lib/fastlane_core/ipa_file_analyser.rb +1 -0
- data/frameit/lib/frameit/commands_generator.rb +25 -0
- data/frameit/lib/frameit/config_parser.rb +31 -9
- data/frameit/lib/frameit/device.rb +90 -0
- data/frameit/lib/frameit/device_types.rb +121 -5
- data/frameit/lib/frameit/editor.rb +28 -40
- data/frameit/lib/frameit/offsets.rb +8 -1
- data/frameit/lib/frameit/options.rb +81 -54
- data/frameit/lib/frameit/runner.rb +17 -7
- data/frameit/lib/frameit/screenshot.rb +35 -47
- data/frameit/lib/frameit/template_finder.rb +15 -12
- data/match/lib/match/change_password.rb +1 -1
- data/match/lib/match/encryption.rb +4 -0
- data/match/lib/match/importer.rb +2 -2
- data/match/lib/match/module.rb +1 -1
- data/match/lib/match/nuke.rb +5 -1
- data/match/lib/match/options.rb +18 -0
- data/match/lib/match/runner.rb +4 -0
- data/match/lib/match/setup.rb +1 -1
- data/match/lib/match/storage.rb +4 -0
- data/match/lib/match/storage/s3_storage.rb +162 -0
- data/pilot/lib/pilot/.manager.rb.swp +0 -0
- data/scan/lib/scan/test_command_generator.rb +2 -1
- data/screengrab/lib/screengrab/runner.rb +11 -3
- data/spaceship/lib/spaceship/connect_api/.DS_Store +0 -0
- data/spaceship/lib/spaceship/connect_api/models/build.rb +1 -2
- data/spaceship/lib/spaceship/connect_api/models/certificate.rb +2 -0
- data/spaceship/lib/spaceship/portal/.certificate.rb.swp +0 -0
- metadata +42 -19
- data/gym/lib/gym/.code_signing_mapping.rb.swp +0 -0
@@ -14,9 +14,8 @@ module Frameit
|
|
14
14
|
end
|
15
15
|
end
|
16
16
|
|
17
|
-
def run(path, color = nil)
|
17
|
+
def run(path, color = nil, platform = nil)
|
18
18
|
unless color
|
19
|
-
color = Frameit::Color::BLACK
|
20
19
|
color = Frameit::Color::SILVER if Frameit.config[:white] || Frameit.config[:silver]
|
21
20
|
color = Frameit::Color::GOLD if Frameit.config[:gold]
|
22
21
|
color = Frameit::Color::ROSE_GOLD if Frameit.config[:rose_gold]
|
@@ -29,11 +28,12 @@ module Frameit
|
|
29
28
|
next if skip_path?(full_path)
|
30
29
|
|
31
30
|
begin
|
32
|
-
|
31
|
+
config = create_config(full_path)
|
32
|
+
screenshot = Screenshot.new(full_path, color, config, platform)
|
33
33
|
|
34
34
|
next if skip_up_to_date?(screenshot)
|
35
35
|
|
36
|
-
editor = editor(screenshot)
|
36
|
+
editor = editor(screenshot, config)
|
37
37
|
|
38
38
|
if editor.should_skip?
|
39
39
|
UI.message("Skipping framing of screenshot #{screenshot.path}. No title provided in your Framefile.json or title.strings.")
|
@@ -71,12 +71,22 @@ module Frameit
|
|
71
71
|
false
|
72
72
|
end
|
73
73
|
|
74
|
-
def editor(screenshot)
|
74
|
+
def editor(screenshot, config)
|
75
75
|
if screenshot.mac?
|
76
|
-
return MacEditor.new(screenshot)
|
76
|
+
return MacEditor.new(screenshot, config)
|
77
77
|
else
|
78
|
-
return Editor.new(screenshot, Frameit.config[:debug_mode])
|
78
|
+
return Editor.new(screenshot, config, Frameit.config[:debug_mode])
|
79
79
|
end
|
80
80
|
end
|
81
|
+
|
82
|
+
# Loads the config (colors, background, texts, etc.)
|
83
|
+
# Don't use this method to access the actual text and use `fetch_texts` instead
|
84
|
+
def create_config(screenshot_path)
|
85
|
+
config_path = File.join(File.expand_path("..", screenshot_path), "Framefile.json")
|
86
|
+
config_path = File.join(File.expand_path("../..", screenshot_path), "Framefile.json") unless File.exist?(config_path)
|
87
|
+
file = ConfigParser.new.load(config_path)
|
88
|
+
return {} unless file # no config file at all
|
89
|
+
file.fetch_value(screenshot_path)
|
90
|
+
end
|
81
91
|
end
|
82
92
|
end
|
@@ -1,87 +1,75 @@
|
|
1
|
-
require 'deliver/app_screenshot'
|
2
|
-
|
3
1
|
require_relative 'editor'
|
4
2
|
require_relative 'mac_editor'
|
5
3
|
require_relative 'device_types'
|
6
4
|
require_relative 'module'
|
5
|
+
require_relative 'device'
|
7
6
|
|
8
7
|
module Frameit
|
9
8
|
# Represents one screenshot
|
10
9
|
class Screenshot
|
11
10
|
attr_accessor :path # path to the screenshot
|
12
11
|
attr_accessor :size # size in px array of 2 elements: height and width
|
13
|
-
attr_accessor :
|
12
|
+
attr_accessor :device # device detected according to resolution, priority and settings
|
14
13
|
attr_accessor :color # the color to use for the frame (from Frameit::Color)
|
15
14
|
|
16
15
|
# path: Path to screenshot
|
17
16
|
# color: Color to use for the frame
|
18
|
-
def initialize(path, color)
|
17
|
+
def initialize(path, color, config, platform_command)
|
19
18
|
UI.user_error!("Couldn't find file at path '#{path}'") unless File.exist?(path)
|
20
19
|
@color = color
|
21
20
|
@path = path
|
22
21
|
@size = FastImage.size(path)
|
23
22
|
|
24
|
-
|
23
|
+
# There are three ways how we can get settings to Frameit:
|
24
|
+
# - options.rb
|
25
|
+
# - gets parameters via CLI (e. g. fastlane run frameit use_platform:"android") or fastfile (Fastlane's global
|
26
|
+
# settings for a given project)
|
27
|
+
# - see Parameters in the doc
|
28
|
+
# - contains default values and validates values
|
29
|
+
# - accessed via Frameit.config[:key]
|
30
|
+
# - lowest priority
|
31
|
+
# - commands_generator.rb
|
32
|
+
# - commands entered directly to CLI (e. g. fastlane frameit android)
|
33
|
+
# - they are passed via constructors to other classes
|
34
|
+
# - higher priority than options.rb (user may enter a command to override fastfile's global setting)
|
35
|
+
# - config_parser.rb
|
36
|
+
# - gets key / values from Framefile.json
|
37
|
+
# - see Advanced usage in the doc
|
38
|
+
# - both default and specific values can be entered in the file (filtered by file name)
|
39
|
+
# - accessed via ConfigParser.fetch_value(screenshot.path)[key] (the ConfigParser's instance is passed
|
40
|
+
# to Screenshot's constructor as config, i.e. we call config[key])
|
41
|
+
# - should have the highest priority, because user might set a specific value for a specific screenshot which
|
42
|
+
# should override CLI parameters and fastfile global setting
|
43
|
+
platform = config['use_platform'] || platform_command || Frameit.config[:use_platform]
|
44
|
+
@device = Device.find_device_by_id_or_name(config['force_device_type'] || Frameit.config[:force_device_type]) || Device.detect_device(path, platform)
|
25
45
|
end
|
26
46
|
|
27
47
|
# Device name for a given screen size. Used to use the correct template
|
28
48
|
def device_name
|
29
|
-
|
30
|
-
sizes = Deliver::AppScreenshot::ScreenSize
|
31
|
-
case @screen_size
|
32
|
-
when sizes::IOS_65
|
33
|
-
return 'iPhone XS Max'
|
34
|
-
when sizes::IOS_61
|
35
|
-
return 'iPhone XR'
|
36
|
-
when sizes::IOS_58
|
37
|
-
return Frameit.config[:use_legacy_iphonex] ? 'iPhone X' : 'iPhone XS'
|
38
|
-
when sizes::IOS_55
|
39
|
-
return Frameit.config[:use_legacy_iphone6s] ? 'iPhone 6s Plus' : 'iPhone 7 Plus'
|
40
|
-
when sizes::IOS_47
|
41
|
-
return Frameit.config[:use_legacy_iphone6s] ? 'iPhone 6s' : 'iPhone 7'
|
42
|
-
when sizes::IOS_40
|
43
|
-
return Frameit.config[:use_legacy_iphone5s] ? 'iPhone 5s' : 'iPhone SE'
|
44
|
-
when sizes::IOS_35
|
45
|
-
return 'iPhone 4'
|
46
|
-
when sizes::IOS_IPAD
|
47
|
-
return 'iPad Air 2'
|
48
|
-
when sizes::IOS_IPAD_10_5
|
49
|
-
return 'iPad Pro (10.5-inch)'
|
50
|
-
when sizes::IOS_IPAD_11
|
51
|
-
return 'iPad Pro (11-inch)'
|
52
|
-
when sizes::IOS_IPAD_PRO
|
53
|
-
return 'iPad Pro'
|
54
|
-
when sizes::IOS_IPAD_PRO_12_9
|
55
|
-
return 'iPad Pro (12.9-inch) (3rd generation)'
|
56
|
-
when sizes::MAC
|
57
|
-
return 'MacBook'
|
58
|
-
else
|
59
|
-
UI.error("Unknown device type for size #{@screen_size} for path '#{path}'")
|
60
|
-
end
|
49
|
+
@device.formatted_name
|
61
50
|
# rubocop:enable Require/MissingRequireStatement
|
62
51
|
end
|
63
52
|
|
64
|
-
def
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
return @color
|
53
|
+
def default_color
|
54
|
+
@device.default_color
|
55
|
+
end
|
56
|
+
|
57
|
+
def deliver_screen_id
|
58
|
+
@device.deliver_screen_id
|
71
59
|
end
|
72
60
|
|
73
61
|
# Is the device a 3x device? (e.g. iPhone 6 Plus, iPhone X)
|
74
62
|
def triple_density?
|
75
|
-
|
63
|
+
!device.density_ppi.nil? && device.density_ppi > 400
|
76
64
|
end
|
77
65
|
|
78
66
|
# Super old devices (iPhone 4)
|
79
67
|
def mini?
|
80
|
-
|
68
|
+
!device.density_ppi.nil? && device.density_ppi < 300
|
81
69
|
end
|
82
70
|
|
83
71
|
def mac?
|
84
|
-
|
72
|
+
device_name == 'MacBook'
|
85
73
|
end
|
86
74
|
|
87
75
|
# The name of the orientation of a screenshot. Used to find the correct template
|
@@ -1,5 +1,4 @@
|
|
1
1
|
require 'deliver/app_screenshot'
|
2
|
-
|
3
2
|
require_relative 'module'
|
4
3
|
require_relative 'device_types'
|
5
4
|
require_relative 'frame_downloader'
|
@@ -11,32 +10,36 @@ module Frameit
|
|
11
10
|
def self.get_template(screenshot)
|
12
11
|
return nil if screenshot.mac?
|
13
12
|
|
14
|
-
filename =
|
15
|
-
|
13
|
+
filename = create_file_name(screenshot.device_name, screenshot.color.nil? ? screenshot.default_color : screenshot.color)
|
16
14
|
templates = Dir["#{FrameDownloader.templates_path}/#{filename}.{png,jpg}"] # ~/.frameit folder
|
17
15
|
|
18
16
|
UI.verbose("Looking for #{filename} and found #{templates.count} template(s)")
|
19
17
|
|
18
|
+
return filename if Helper.test?
|
19
|
+
if templates.count == 0 && !screenshot.color.nil? && screenshot.color != screenshot.default_color
|
20
|
+
filename = create_file_name(screenshot.device_name, screenshot.default_color)
|
21
|
+
UI.important("Unfortunately device type '#{screenshot.device_name}' is not available in #{screenshot.color}, falling back to " + (screenshot.default_color.nil? ? "default" : screenshot.default_color) + "...")
|
22
|
+
templates = Dir["#{FrameDownloader.templates_path}/#{filename}.{png,jpg}"] # ~/.frameit folder
|
23
|
+
UI.verbose("Looking for #{filename} and found #{templates.count} template(s)")
|
24
|
+
end
|
25
|
+
|
20
26
|
if templates.count == 0
|
21
|
-
if screenshot.
|
27
|
+
if screenshot.deliver_screen_id == Deliver::AppScreenshot::ScreenSize::IOS_35
|
22
28
|
UI.important("Unfortunately 3.5\" device frames were discontinued. Skipping screen '#{screenshot.path}'")
|
23
29
|
UI.error("Looked for: '#{filename}.png'")
|
24
|
-
elsif screenshot.color == Frameit::Color::ROSE_GOLD || screenshot.color == Frameit::Color::GOLD
|
25
|
-
# Unfortunately not every device type is available in rose gold or gold
|
26
|
-
# This is why we can't have nice things #yatusabes
|
27
|
-
# fallback to a white iPhone, which looks similar
|
28
|
-
UI.important("Unfortunately device type '#{screenshot.device_name}' is not available in #{screenshot.color}, falling back to silver...")
|
29
|
-
screenshot.color = Frameit::Color::SILVER
|
30
|
-
return self.get_template(screenshot)
|
31
30
|
else
|
32
31
|
UI.error("Couldn't find template for screenshot type '#{filename}'")
|
33
32
|
UI.error("Please run `fastlane frameit download_frames` to download the latest frames")
|
34
33
|
end
|
35
|
-
return filename if Helper.test?
|
36
34
|
return nil
|
37
35
|
else
|
38
36
|
return templates.first.tr(" ", "\ ")
|
39
37
|
end
|
40
38
|
end
|
39
|
+
|
40
|
+
def self.create_file_name(device_name, color)
|
41
|
+
return "#{device_name} #{color}" unless color.nil?
|
42
|
+
return device_name
|
43
|
+
end
|
41
44
|
end
|
42
45
|
end
|
@@ -45,7 +45,7 @@ module Match
|
|
45
45
|
end
|
46
46
|
|
47
47
|
# This method is called from both here, and from `openssl.rb`
|
48
|
-
def self.ask_password(message: "Passphrase for
|
48
|
+
def self.ask_password(message: "Passphrase for Match storage: ", confirm: nil)
|
49
49
|
ensure_ui_interactive
|
50
50
|
loop do
|
51
51
|
password = UI.password(message)
|
data/match/lib/match/importer.rb
CHANGED
@@ -54,9 +54,9 @@ module Match
|
|
54
54
|
|
55
55
|
case cert_type
|
56
56
|
when :development
|
57
|
-
certificate_type = Spaceship::ConnectAPI::Certificate::CertificateType::IOS_DEVELOPMENT
|
57
|
+
certificate_type = Spaceship::ConnectAPI::Certificate::CertificateType::IOS_DEVELOPMENT + "," + Spaceship::ConnectAPI::Certificate::CertificateType::DEVELOPMENT
|
58
58
|
when :distribution, :enterprise
|
59
|
-
certificate_type = Spaceship::ConnectAPI::Certificate::CertificateType::IOS_DISTRIBUTION
|
59
|
+
certificate_type = Spaceship::ConnectAPI::Certificate::CertificateType::IOS_DISTRIBUTION + "," + Spaceship::ConnectAPI::Certificate::CertificateType::DISTRIBUTION
|
60
60
|
else
|
61
61
|
UI.user_error!("Cert type '#{cert_type}' is not supported")
|
62
62
|
end
|
data/match/lib/match/module.rb
CHANGED
data/match/lib/match/nuke.rb
CHANGED
@@ -37,7 +37,11 @@ module Match
|
|
37
37
|
clone_branch_directly: params[:clone_branch_directly],
|
38
38
|
google_cloud_bucket_name: params[:google_cloud_bucket_name].to_s,
|
39
39
|
google_cloud_keys_file: params[:google_cloud_keys_file].to_s,
|
40
|
-
google_cloud_project_id: params[:google_cloud_project_id].to_s
|
40
|
+
google_cloud_project_id: params[:google_cloud_project_id].to_s,
|
41
|
+
s3_region: params[:s3_region].to_s,
|
42
|
+
s3_access_key: params[:s3_access_key].to_s,
|
43
|
+
s3_secret_access_key: params[:s3_secret_access_key].to_s,
|
44
|
+
s3_bucket: params[:s3_bucket].to_s
|
41
45
|
})
|
42
46
|
self.storage.download
|
43
47
|
|
data/match/lib/match/options.rb
CHANGED
@@ -159,6 +159,24 @@ module Match
|
|
159
159
|
description: "ID of the Google Cloud project to use for authentication",
|
160
160
|
optional: true),
|
161
161
|
|
162
|
+
# Storage: S3
|
163
|
+
FastlaneCore::ConfigItem.new(key: :s3_region,
|
164
|
+
env_name: "MATCH_S3_REGION",
|
165
|
+
description: "Name of the S3 region",
|
166
|
+
optional: true),
|
167
|
+
FastlaneCore::ConfigItem.new(key: :s3_access_key,
|
168
|
+
env_name: "MATCH_S3_ACCESS_KEY",
|
169
|
+
description: "S3 access key",
|
170
|
+
optional: true),
|
171
|
+
FastlaneCore::ConfigItem.new(key: :s3_secret_access_key,
|
172
|
+
env_name: "MATCH_S3_SECRET_ACCESS_KEY",
|
173
|
+
description: "S3 secret secret access key",
|
174
|
+
optional: true),
|
175
|
+
FastlaneCore::ConfigItem.new(key: :s3_bucket,
|
176
|
+
env_name: "MATCH_S3_BUCKET",
|
177
|
+
description: "Name of the S3 bucket",
|
178
|
+
optional: true),
|
179
|
+
|
162
180
|
# Keychain
|
163
181
|
FastlaneCore::ConfigItem.new(key: :keychain_name,
|
164
182
|
short_option: "-s",
|
data/match/lib/match/runner.rb
CHANGED
@@ -46,6 +46,10 @@ module Match
|
|
46
46
|
google_cloud_bucket_name: params[:google_cloud_bucket_name].to_s,
|
47
47
|
google_cloud_keys_file: params[:google_cloud_keys_file].to_s,
|
48
48
|
google_cloud_project_id: params[:google_cloud_project_id].to_s,
|
49
|
+
s3_region: params[:s3_region].to_s,
|
50
|
+
s3_access_key: params[:s3_access_key].to_s,
|
51
|
+
s3_secret_access_key: params[:s3_secret_access_key].to_s,
|
52
|
+
s3_bucket: params[:s3_bucket].to_s,
|
49
53
|
readonly: params[:readonly],
|
50
54
|
username: params[:readonly] ? nil : params[:username], # only pass username if not readonly
|
51
55
|
team_id: params[:team_id],
|
data/match/lib/match/setup.rb
CHANGED
data/match/lib/match/storage.rb
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
require_relative 'storage/interface'
|
2
2
|
require_relative 'storage/git_storage'
|
3
3
|
require_relative 'storage/google_cloud_storage'
|
4
|
+
require_relative 'storage/s3_storage'
|
4
5
|
|
5
6
|
module Match
|
6
7
|
module Storage
|
@@ -12,6 +13,9 @@ module Match
|
|
12
13
|
},
|
13
14
|
"google_cloud" => lambda { |params|
|
14
15
|
return Storage::GoogleCloudStorage.configure(params)
|
16
|
+
},
|
17
|
+
"s3" => lambda { |params|
|
18
|
+
return Storage::S3Storage.configure(params)
|
15
19
|
}
|
16
20
|
}
|
17
21
|
end
|
@@ -0,0 +1,162 @@
|
|
1
|
+
require 'fastlane_core/command_executor'
|
2
|
+
require 'fastlane_core/configuration/configuration'
|
3
|
+
require 'fastlane/helper/s3_client_helper'
|
4
|
+
|
5
|
+
require_relative '../options'
|
6
|
+
require_relative '../module'
|
7
|
+
require_relative '../spaceship_ensure'
|
8
|
+
require_relative './interface'
|
9
|
+
|
10
|
+
module Match
|
11
|
+
module Storage
|
12
|
+
# Store the code signing identities on AWS S3
|
13
|
+
class S3Storage < Interface
|
14
|
+
attr_reader :s3_bucket
|
15
|
+
attr_reader :s3_region
|
16
|
+
attr_reader :s3_client
|
17
|
+
attr_reader :readonly
|
18
|
+
attr_reader :username
|
19
|
+
attr_reader :team_id
|
20
|
+
attr_reader :team_name
|
21
|
+
|
22
|
+
def self.configure(params)
|
23
|
+
s3_region = params[:s3_region]
|
24
|
+
s3_access_key = params[:s3_access_key]
|
25
|
+
s3_secret_access_key = params[:s3_secret_access_key]
|
26
|
+
s3_bucket = params[:s3_bucket]
|
27
|
+
|
28
|
+
if params[:git_url].to_s.length > 0
|
29
|
+
UI.important("Looks like you still define a `git_url` somewhere, even though")
|
30
|
+
UI.important("you use S3 Storage. You can remove the `git_url`")
|
31
|
+
UI.important("from your Matchfile and Fastfile")
|
32
|
+
UI.message("The above is just a warning, fastlane will continue as usual now...")
|
33
|
+
end
|
34
|
+
|
35
|
+
return self.new(
|
36
|
+
s3_region: s3_region,
|
37
|
+
s3_access_key: s3_access_key,
|
38
|
+
s3_secret_access_key: s3_secret_access_key,
|
39
|
+
s3_bucket: s3_bucket,
|
40
|
+
readonly: params[:readonly],
|
41
|
+
username: params[:username],
|
42
|
+
team_id: params[:team_id],
|
43
|
+
team_name: params[:team_name]
|
44
|
+
)
|
45
|
+
end
|
46
|
+
|
47
|
+
def initialize(s3_region: nil,
|
48
|
+
s3_access_key: nil,
|
49
|
+
s3_secret_access_key: nil,
|
50
|
+
s3_bucket: nil,
|
51
|
+
readonly: nil,
|
52
|
+
username: nil,
|
53
|
+
team_id: nil,
|
54
|
+
team_name: nil)
|
55
|
+
@s3_bucket = s3_bucket
|
56
|
+
@s3_region = s3_region
|
57
|
+
@s3_client = Fastlane::Helper::S3ClientHelper.new(access_key: s3_access_key, secret_access_key: s3_secret_access_key, region: s3_region)
|
58
|
+
@readonly = readonly
|
59
|
+
@username = username
|
60
|
+
@team_id = team_id
|
61
|
+
@team_name = team_name
|
62
|
+
end
|
63
|
+
|
64
|
+
# To make debugging easier, we have a custom exception here
|
65
|
+
def prefixed_working_directory
|
66
|
+
# We fall back to "*", which means certificates and profiles
|
67
|
+
# from all teams that use this bucket would be installed. This is not ideal, but
|
68
|
+
# unless the user provides a `team_id`, we can't know which one to use
|
69
|
+
# This only happens if `readonly` is activated, and no `team_id` was provided
|
70
|
+
@_folder_prefix ||= currently_used_team_id
|
71
|
+
if @_folder_prefix.nil?
|
72
|
+
# We use a `@_folder_prefix` variable, to keep state between multiple calls of this
|
73
|
+
# method, as the value won't change. This way the warning is only printed once
|
74
|
+
UI.important("Looks like you run `match` in `readonly` mode, and didn't provide a `team_id`. This will still work, however it is recommended to provide a `team_id` in your Appfile or Matchfile")
|
75
|
+
@_folder_prefix = "*"
|
76
|
+
end
|
77
|
+
return File.join(working_directory, @_folder_prefix)
|
78
|
+
end
|
79
|
+
|
80
|
+
# Call this method for the initial clone/download of the
|
81
|
+
# user's certificates & profiles
|
82
|
+
# As part of this method, the `self.working_directory` attribute
|
83
|
+
# will be set
|
84
|
+
def download
|
85
|
+
# Check if we already have a functional working_directory
|
86
|
+
return if @working_directory && Dir.exist?(@working_directory)
|
87
|
+
|
88
|
+
# No existing working directory, creating a new one now
|
89
|
+
self.working_directory = Dir.mktmpdir
|
90
|
+
|
91
|
+
s3_client.find_bucket!(s3_bucket).objects.each do |object|
|
92
|
+
file_path = object.public_url.to_s.split("s3.amazonaws.com/").last
|
93
|
+
download_path = File.join(self.working_directory, file_path)
|
94
|
+
|
95
|
+
FileUtils.mkdir_p(File.expand_path("..", download_path))
|
96
|
+
UI.verbose("Downloading file from S3 '#{file_path}' on bucket #{self.s3_bucket}")
|
97
|
+
|
98
|
+
object.download_file(download_path)
|
99
|
+
end
|
100
|
+
UI.verbose("Successfully downloaded files from S3 to #{self.working_directory}")
|
101
|
+
end
|
102
|
+
|
103
|
+
# Returns a short string describing + identifing the current
|
104
|
+
# storage backend. This will be printed when nuking a storage
|
105
|
+
def human_readable_description
|
106
|
+
return "S3 Bucket [#{s3_bucket}] on region #{s3_region}"
|
107
|
+
end
|
108
|
+
|
109
|
+
def upload_files(files_to_upload: [], custom_message: nil)
|
110
|
+
# `files_to_upload` is an array of files that need to be uploaded to S3
|
111
|
+
# Those doesn't mean they're new, it might just be they're changed
|
112
|
+
# Either way, we'll upload them using the same technique
|
113
|
+
|
114
|
+
files_to_upload.each do |current_file|
|
115
|
+
# Go from
|
116
|
+
# "/var/folders/px/bz2kts9n69g8crgv4jpjh6b40000gn/T/d20181026-96528-1av4gge/profiles/development/Development_me.mobileprovision"
|
117
|
+
# to
|
118
|
+
# "profiles/development/Development_me.mobileprovision"
|
119
|
+
#
|
120
|
+
|
121
|
+
target_path = current_file.gsub(self.working_directory + "/", "")
|
122
|
+
UI.verbose("Uploading '#{target_path}' to S3 Storage...")
|
123
|
+
|
124
|
+
body = File.read(current_file)
|
125
|
+
acl = 'private'
|
126
|
+
s3_url = s3_client.upload_file(s3_bucket, target_path, body, acl)
|
127
|
+
UI.verbose("Uploaded '#{s3_url}' to S3 Storage.")
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
def delete_files(files_to_delete: [], custom_message: nil)
|
132
|
+
files_to_delete.each do |file_name|
|
133
|
+
s3_client.delete_file(s3_bucket, file_name)
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
137
|
+
def skip_docs
|
138
|
+
false
|
139
|
+
end
|
140
|
+
|
141
|
+
# Implement this for the `fastlane match init` command
|
142
|
+
# This method must return the content of the Matchfile
|
143
|
+
# that should be generated
|
144
|
+
def generate_matchfile_content(template: nil)
|
145
|
+
return "s3_bucket(\"#{self.s3_bucket}\")"
|
146
|
+
end
|
147
|
+
|
148
|
+
private
|
149
|
+
|
150
|
+
def currently_used_team_id
|
151
|
+
if self.readonly
|
152
|
+
# In readonly mode, we still want to see if the user provided a team_id
|
153
|
+
# see `prefixed_working_directory` comments for more details
|
154
|
+
return self.team_id
|
155
|
+
else
|
156
|
+
spaceship = SpaceshipEnsure.new(self.username, self.team_id, self.team_name)
|
157
|
+
return spaceship.team_id
|
158
|
+
end
|
159
|
+
end
|
160
|
+
end
|
161
|
+
end
|
162
|
+
end
|