fastlane-plugin-screenshotslive 0.2.0 → 0.3.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: ce2cfed932ddc0db4dd72bda4f1c52c70bad9947f0c6ba26a6e0ecc668123a1a
4
- data.tar.gz: d6167244e7000e719e9e509dcea29e83bcbf00cc58d0a34fd4e9c36c15ef967e
3
+ metadata.gz: f00c007f6960d7fc53e58e9a90ba27058429a589659d80c0972f7b12fcb7d1dc
4
+ data.tar.gz: a442519945397411c7d5cf172407346cebea2de0b3d3036d57899a24a71b36d3
5
5
  SHA512:
6
- metadata.gz: 32961972f18262e02291362bf2d105851912fabbc766a32452114ee079649980823502df0391db4a1856818c67b4a71d1e49e27747c0ecd8848c320ffa973d23
7
- data.tar.gz: 6ba93c22b4ff5a4106f300c56e51039f848ffee6ff8032ea0d6b54d33c75e55f05be51a46fbaf01586ef7b0c7400014432f6e591877096d3151c35758696d758
6
+ metadata.gz: 5adc773e2c4f2d30f6674f9524dee239354632c5228f778edb9be08a9bfdecea9c5f331665d640580d0ff8daaf7149a26f383f688fb713a484c345763743fa6f
7
+ data.tar.gz: 5af4ac8b2f226a8be2ab2a4d4b9d985db5007fe61360c429ea74252208c6deaf90cdd68b827e2e654bf003dfee09df510e9864b3d807a597f37de4050e247d26
@@ -1,3 +1,4 @@
1
+ require "yaml"
1
2
  require "zip"
2
3
  require "fileutils"
3
4
  require_relative "../helper/api_client"
@@ -5,18 +6,37 @@ require_relative "../helper/api_client"
5
6
  module Fastlane
6
7
  module Actions
7
8
  class ScreenshotsliveAction < Action
9
+ PICTURE_REF_PREFIX = "picture://"
10
+
8
11
  def self.run(params)
9
12
  api_key = params[:api_key]
10
13
  yaml_path = params[:yaml_config]
11
14
  output_dir = params[:output_directory]
12
15
  base_url = params[:base_url]
16
+ overrides = params[:overrides] || {}
17
+ screenshots = params[:screenshots] || {}
13
18
 
14
19
  yaml_config = File.read(yaml_path)
20
+
21
+ if !overrides.empty? || !screenshots.empty?
22
+ yaml_config = apply_overrides(yaml_config, overrides, screenshots)
23
+ end
24
+
15
25
  UI.message("Dispatching render via Screenshots.live API...")
16
26
 
17
27
  client = Screenshotslive::ApiClient.new(api_key: api_key, base_url: base_url)
18
28
 
19
- result = client.render(yaml_config: yaml_config)
29
+ if screenshots.empty?
30
+ result = client.render(yaml_config: yaml_config)
31
+ else
32
+ picture_files = {}
33
+ screenshots.each do |_item_id, path|
34
+ filename = File.basename(path)
35
+ picture_files[filename] = path
36
+ end
37
+ result = client.render_with_pictures(yaml_config: yaml_config, picture_files: picture_files)
38
+ end
39
+
20
40
  job_id = result.dig("data", "jobId") || result.dig("data", "id")
21
41
  UI.message("Render job dispatched: #{job_id}")
22
42
 
@@ -38,18 +58,42 @@ module Fastlane
38
58
  UI.message("Extracting to #{output_dir}...")
39
59
  Zip::File.open(zip_path) do |zip_file|
40
60
  zip_file.each do |entry|
41
- dest = File.join(output_dir, entry.name)
42
- FileUtils.mkdir_p(File.dirname(dest))
61
+ next if entry.directory?
62
+ filename = File.basename(entry.name)
63
+ dest = File.join(output_dir, filename)
43
64
  entry.extract(dest) { true }
44
65
  end
45
66
  end
46
67
 
47
68
  File.delete(zip_path)
48
69
 
49
- UI.success("Screenshots rendered and extracted to #{output_dir}")
70
+ file_count = Dir.glob(File.join(output_dir, "*.png")).length
71
+ UI.success("#{file_count} screenshots rendered and saved to #{output_dir}")
50
72
  output_dir
51
73
  end
52
74
 
75
+ def self.apply_overrides(yaml_string, overrides, screenshots)
76
+ data = YAML.safe_load(yaml_string)
77
+
78
+ items = data["items"] || []
79
+ items.each do |item|
80
+ item_id = item["itemId"]
81
+
82
+ if overrides.key?(item_id)
83
+ overrides[item_id].each do |field, value|
84
+ item[field.to_s] = value
85
+ end
86
+ end
87
+
88
+ if screenshots.key?(item_id)
89
+ filename = File.basename(screenshots[item_id])
90
+ item["screenshotUrl"] = "#{PICTURE_REF_PREFIX}#{filename}"
91
+ end
92
+ end
93
+
94
+ data.to_yaml
95
+ end
96
+
53
97
  def self.description
54
98
  "Generate app store screenshots via the Screenshots.live REST API"
55
99
  end
@@ -59,14 +103,14 @@ module Fastlane
59
103
  end
60
104
 
61
105
  def self.return_value
62
- "Path to the output directory containing rendered screenshots in Fastlane-compatible folder structure"
106
+ "Path to the output directory containing rendered screenshot files"
63
107
  end
64
108
 
65
109
  def self.details
66
110
  "Sends a YAML configuration to the Screenshots.live render API, polls for completion, " \
67
- "downloads the rendered ZIP, and extracts it into a Fastlane-compatible folder structure " \
68
- "(iPhone 6.5, iPad 12.9, phoneScreenshots, tenInchScreenshots). " \
69
- "Use this as a drop-in replacement for frameit with full template customization."
111
+ "downloads the rendered ZIP, and extracts flat screenshot PNGs into the output directory. " \
112
+ "Supports overriding YAML values (text, colors) and injecting local screenshot files " \
113
+ "via the render-with-pictures endpoint."
70
114
  end
71
115
 
72
116
  def self.available_options
@@ -88,10 +132,24 @@ module Fastlane
88
132
  ),
89
133
  FastlaneCore::ConfigItem.new(
90
134
  key: :output_directory,
91
- description: "Directory to extract rendered screenshots into",
135
+ description: "Directory to save rendered screenshot PNGs (flat, no subdirectories)",
92
136
  default_value: "./screenshots",
93
137
  type: String
94
138
  ),
139
+ FastlaneCore::ConfigItem.new(
140
+ key: :overrides,
141
+ description: "Hash of itemId => { field => value } overrides to apply to the YAML before rendering",
142
+ optional: true,
143
+ default_value: {},
144
+ type: Hash
145
+ ),
146
+ FastlaneCore::ConfigItem.new(
147
+ key: :screenshots,
148
+ description: "Hash of itemId => local_file_path to inject screenshots via render-with-pictures",
149
+ optional: true,
150
+ default_value: {},
151
+ type: Hash
152
+ ),
95
153
  FastlaneCore::ConfigItem.new(
96
154
  key: :base_url,
97
155
  env_name: "SCREENSHOTSLIVE_BASE_URL",
@@ -112,11 +170,24 @@ module Fastlane
112
170
 
113
171
  def self.example_code
114
172
  [
115
- 'screenshotslive(
116
- api_key: ENV["SCREENSHOTSLIVE_API_KEY"],
117
- yaml_config: "./screenshots.yml",
118
- output_directory: "./fastlane/screenshots"
119
- )',
173
+ '# Basic render from YAML
174
+ screenshotslive(
175
+ api_key: ENV["SCREENSHOTSLIVE_API_KEY"],
176
+ yaml_config: "./screenshots.yml",
177
+ output_directory: "./fastlane/screenshots/en-US"
178
+ )',
179
+ '# Override text and inject local screenshots
180
+ screenshotslive(
181
+ api_key: ENV["SCREENSHOTSLIVE_API_KEY"],
182
+ yaml_config: "./screenshots.yml",
183
+ output_directory: "./fastlane/screenshots/de-DE",
184
+ overrides: {
185
+ "abc-item-id" => { "content" => "Neue Funktion" },
186
+ },
187
+ screenshots: {
188
+ "def-device-frame-id" => "./screens/de/home.png",
189
+ }
190
+ )',
120
191
  ]
121
192
  end
122
193
  end
@@ -1,4 +1,5 @@
1
1
  require "faraday"
2
+ require "faraday/multipart"
2
3
  require "json"
3
4
 
4
5
  module Fastlane
@@ -6,13 +7,15 @@ module Fastlane
6
7
  class ApiClient
7
8
  BASE_URL = "https://api.screenshots.live"
8
9
  RENDER_PATH = "/render/api"
10
+ RENDER_WITH_PICTURES_PATH = "/render/render-with-pictures"
9
11
  POLL_PATH_PREFIX = "/render/get-render/"
10
12
  POLL_INTERVAL = 3
11
13
  MAX_POLL_ATTEMPTS = 200
12
14
 
13
15
  def initialize(api_key:, base_url: nil)
14
16
  @api_key = api_key
15
- @conn = Faraday.new(url: base_url || BASE_URL) do |f|
17
+ @base_url = base_url || BASE_URL
18
+ @conn = Faraday.new(url: @base_url) do |f|
16
19
  f.adapter Faraday.default_adapter
17
20
  end
18
21
  end
@@ -32,6 +35,32 @@ module Fastlane
32
35
  JSON.parse(response.body)
33
36
  end
34
37
 
38
+ def render_with_pictures(yaml_config:, picture_files:)
39
+ multipart_conn = Faraday.new(url: @base_url) do |f|
40
+ f.request :multipart
41
+ f.adapter Faraday.default_adapter
42
+ end
43
+
44
+ payload = { "yaml" => yaml_config }
45
+ picture_files.each do |filename, path|
46
+ mime = "image/png"
47
+ mime = "image/jpeg" if path.end_with?(".jpg", ".jpeg")
48
+ payload[filename] = Faraday::Multipart::FilePart.new(path, mime, filename)
49
+ end
50
+
51
+ response = multipart_conn.post(RENDER_WITH_PICTURES_PATH) do |req|
52
+ req.headers["Authorization"] = "Bearer #{@api_key}"
53
+ req.body = payload
54
+ end
55
+
56
+ unless response.success?
57
+ body = JSON.parse(response.body) rescue {}
58
+ raise "Screenshots.live API error (#{response.status}): #{body["message"] || response.body}"
59
+ end
60
+
61
+ JSON.parse(response.body)
62
+ end
63
+
35
64
  def poll_job(job_id:)
36
65
  attempts = 0
37
66
  loop do
@@ -1,5 +1,5 @@
1
1
  module Fastlane
2
2
  module Screenshotslive
3
- VERSION = "0.2.0"
3
+ VERSION = "0.3.0"
4
4
  end
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fastlane-plugin-screenshotslive
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Eric Isensee
@@ -13,60 +13,65 @@ dependencies:
13
13
  name: faraday
14
14
  requirement: !ruby/object:Gem::Requirement
15
15
  requirements:
16
- - - ">="
17
- - !ruby/object:Gem::Version
18
- version: '1.0'
19
- - - "<"
16
+ - - "~>"
20
17
  - !ruby/object:Gem::Version
21
- version: '3.0'
18
+ version: '2.14'
22
19
  type: :runtime
23
20
  prerelease: false
24
21
  version_requirements: !ruby/object:Gem::Requirement
25
22
  requirements:
26
- - - ">="
23
+ - - "~>"
27
24
  - !ruby/object:Gem::Version
28
- version: '1.0'
29
- - - "<"
25
+ version: '2.14'
26
+ - !ruby/object:Gem::Dependency
27
+ name: faraday-multipart
28
+ requirement: !ruby/object:Gem::Requirement
29
+ requirements:
30
+ - - "~>"
30
31
  - !ruby/object:Gem::Version
31
- version: '3.0'
32
+ version: '1.1'
33
+ type: :runtime
34
+ prerelease: false
35
+ version_requirements: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - "~>"
38
+ - !ruby/object:Gem::Version
39
+ version: '1.1'
32
40
  - !ruby/object:Gem::Dependency
33
41
  name: rubyzip
34
42
  requirement: !ruby/object:Gem::Requirement
35
43
  requirements:
36
- - - ">="
37
- - !ruby/object:Gem::Version
38
- version: '2.0'
39
- - - "<"
44
+ - - "~>"
40
45
  - !ruby/object:Gem::Version
41
- version: '3.0'
46
+ version: '2.4'
42
47
  type: :runtime
43
48
  prerelease: false
44
49
  version_requirements: !ruby/object:Gem::Requirement
45
50
  requirements:
46
- - - ">="
47
- - !ruby/object:Gem::Version
48
- version: '2.0'
49
- - - "<"
51
+ - - "~>"
50
52
  - !ruby/object:Gem::Version
51
- version: '3.0'
53
+ version: '2.4'
52
54
  - !ruby/object:Gem::Dependency
53
55
  name: bundler
54
56
  requirement: !ruby/object:Gem::Requirement
55
57
  requirements:
56
- - - ">="
58
+ - - "~>"
57
59
  - !ruby/object:Gem::Version
58
- version: '0'
60
+ version: '2.0'
59
61
  type: :development
60
62
  prerelease: false
61
63
  version_requirements: !ruby/object:Gem::Requirement
62
64
  requirements:
63
- - - ">="
65
+ - - "~>"
64
66
  - !ruby/object:Gem::Version
65
- version: '0'
67
+ version: '2.0'
66
68
  - !ruby/object:Gem::Dependency
67
69
  name: fastlane
68
70
  requirement: !ruby/object:Gem::Requirement
69
71
  requirements:
72
+ - - "~>"
73
+ - !ruby/object:Gem::Version
74
+ version: '2.200'
70
75
  - - ">="
71
76
  - !ruby/object:Gem::Version
72
77
  version: 2.200.0
@@ -74,6 +79,9 @@ dependencies:
74
79
  prerelease: false
75
80
  version_requirements: !ruby/object:Gem::Requirement
76
81
  requirements:
82
+ - - "~>"
83
+ - !ruby/object:Gem::Version
84
+ version: '2.200'
77
85
  - - ">="
78
86
  - !ruby/object:Gem::Version
79
87
  version: 2.200.0
@@ -81,16 +89,16 @@ dependencies:
81
89
  name: rspec
82
90
  requirement: !ruby/object:Gem::Requirement
83
91
  requirements:
84
- - - ">="
92
+ - - "~>"
85
93
  - !ruby/object:Gem::Version
86
- version: '0'
94
+ version: '3.0'
87
95
  type: :development
88
96
  prerelease: false
89
97
  version_requirements: !ruby/object:Gem::Requirement
90
98
  requirements:
91
- - - ">="
99
+ - - "~>"
92
100
  - !ruby/object:Gem::Version
93
- version: '0'
101
+ version: '3.0'
94
102
  email: contact@screenshots.live
95
103
  executables: []
96
104
  extensions: []