fastlane-plugin-buildstash 1.0.3 → 1.0.4
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:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 865912b0b34c569272752e0984eeb58bfef8192f1135f83b4516ea2bb29d6c8e
|
|
4
|
+
data.tar.gz: b724cb7648c198a26520918f0c015df43c32788b76d2ad2f5ef226c12f8dc2ce
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 4e36e107f079f2badb955736328b0b61baa9d6493fffd18b065aa7de55341df29f3fc2b7b7fb5c0c45c7a0ba085399746ea79475d4ac2579790495b9d21315d4
|
|
7
|
+
data.tar.gz: b5dca4d6c339e86346e208dcb25e528a4b8e42b4ada7d65cd5353fdb361baa441935e3f54a4a49c0fe73fac86f3f35e20d12d11c44be99fa8744f25615004f0a
|
data/README.md
CHANGED
|
@@ -52,6 +52,7 @@ lane :run_buildstash_upload do |options|
|
|
|
52
52
|
structure: 'file',
|
|
53
53
|
primary_file_path: './path/to/file.apk',
|
|
54
54
|
platform: 'android',
|
|
55
|
+
custom_target: 'Galaxy Store',
|
|
55
56
|
stream: 'default',
|
|
56
57
|
version_component_1_major: 0,
|
|
57
58
|
version_component_2_minor: 0,
|
|
@@ -66,17 +67,47 @@ lane :run_buildstash_upload do |options|
|
|
|
66
67
|
ci_pipeline: options[:ci_pipeline],
|
|
67
68
|
ci_run_id: options[:ci_run_id],
|
|
68
69
|
ci_run_url: options[:ci_run_url],
|
|
70
|
+
ci_build_duration: '00:05:00',
|
|
69
71
|
vc_host_type: 'git',
|
|
70
72
|
vc_host: 'github',
|
|
71
73
|
vc_repo_name: options[:vc_repo_name],
|
|
72
74
|
vc_repo_url: options[:vc_repo_url],
|
|
73
75
|
vc_branch: options[:vc_branch],
|
|
74
76
|
vc_commit_sha: options[:vc_commit_sha],
|
|
75
|
-
vc_commit_url: options[:vc_commit_url]
|
|
77
|
+
vc_commit_url: options[:vc_commit_url],
|
|
78
|
+
metadata_artifacts: [
|
|
79
|
+
{ path: './build.log', description: 'Xcode build log' },
|
|
80
|
+
{ path: './test-results.xml', description: 'Unit test results' }
|
|
81
|
+
]
|
|
76
82
|
)
|
|
77
83
|
end
|
|
78
84
|
```
|
|
79
85
|
|
|
86
|
+
### Uploading metadata artifacts
|
|
87
|
+
|
|
88
|
+
The `metadata_artifacts` parameter lets you attach supplementary files (logs, test results, crash reports, etc.) to a build. Each entry is a Hash with a `:path` key and an optional `:description`:
|
|
89
|
+
|
|
90
|
+
```ruby
|
|
91
|
+
buildstash_upload(
|
|
92
|
+
api_key: ENV['BUILDSTASH_API_KEY'],
|
|
93
|
+
primary_file_path: './MyApp.ipa',
|
|
94
|
+
platform: 'ios',
|
|
95
|
+
stream: 'nightly',
|
|
96
|
+
version_component_1_major: 2,
|
|
97
|
+
version_component_2_minor: 1,
|
|
98
|
+
version_component_3_patch: 0,
|
|
99
|
+
metadata_artifacts: [
|
|
100
|
+
{ path: './build.log', description: 'Build log' },
|
|
101
|
+
{ path: './test-results.xml', description: 'Unit test results' },
|
|
102
|
+
{ path: './crash-report.txt' }
|
|
103
|
+
]
|
|
104
|
+
)
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
**Limits:**
|
|
108
|
+
- Maximum **10** metadata artifacts per upload — if more are provided, only the first 10 are uploaded and a warning is logged for the rest
|
|
109
|
+
- Maximum **5 MB** per file — files exceeding this limit are skipped with a warning
|
|
110
|
+
|
|
80
111
|
## Parameters
|
|
81
112
|
| Parameter | Description | Required |
|
|
82
113
|
|-----------------------------|--------------------------------------------------------------------------------------------------------------|----------|
|
|
@@ -84,6 +115,7 @@ end
|
|
|
84
115
|
| `structure` | 'file' for single file, 'file+expansion' to include Android expansion file. will default to 'file' | ✖ |
|
|
85
116
|
| `primary_file_path` | './path/to/file.apk' | ✅ |
|
|
86
117
|
| `platform` | 'android' or 'ios' (see [Buildstash docs for full list](https://docs.buildstash.com/integrations/platforms)) | ✅ |
|
|
118
|
+
| `custom_target` | Custom target for this build — must exactly match a target defined in your Buildstash app | ✖️ |
|
|
87
119
|
| `stream` | Exact name of a build stream in your app | ✅ |
|
|
88
120
|
| `version_component_1_major` | Semantic version (major component) | ✅ |
|
|
89
121
|
| `version_component_2_minor` | Semantic version (minor component) | ✅ |
|
|
@@ -94,10 +126,13 @@ end
|
|
|
94
126
|
| `labels` | Array of labels to attach to build (will be created if they do not already exist) | ✖ |
|
|
95
127
|
| `architectures` | Array of architectures this build supports (must be supported by platform) | ✖ |
|
|
96
128
|
| `notes` | Changelog or additional notes | ✖️ |
|
|
129
|
+
| `expansion_file_path` | Path to the expansion file (only used when `structure` is `'file+expansion'`) | ✖️ |
|
|
130
|
+
| `metadata_artifacts` | Array of supplementary files to upload with the build (e.g. logs). See [Metadata artifacts](#uploading-metadata-artifacts) | ✖️ |
|
|
97
131
|
| `source` | Where build was produced (`ghactions`, `jenkins`, etc) defaults to cli-upload | ✖️ |
|
|
98
132
|
| `ci_pipeline` | CI pipeline name | ✖️ |
|
|
99
133
|
| `ci_run_id` | CI run ID | ✖️ |
|
|
100
134
|
| `ci_run_url` | CI run URL | ✖️ |
|
|
135
|
+
| `ci_build_duration` | CI build duration (e.g. `'00:05:00'`) | ✖️ |
|
|
101
136
|
| `vc_host_type` | Version control host type (git, svn, hg, perforce, etc) | ✖️ |
|
|
102
137
|
| `vc_host` | Version control host (github, gitlab, etc) | ✖️ |
|
|
103
138
|
| `vc_repo_name` | Repository name | ✖️ |
|
|
@@ -17,6 +17,7 @@ module Fastlane
|
|
|
17
17
|
version_component_meta = params[:version_component_meta]
|
|
18
18
|
custom_build_number = params[:custom_build_number]
|
|
19
19
|
platform = params[:platform]
|
|
20
|
+
custom_target = params[:custom_target]
|
|
20
21
|
stream = params[:stream]
|
|
21
22
|
notes = params[:notes]
|
|
22
23
|
|
|
@@ -28,6 +29,7 @@ module Fastlane
|
|
|
28
29
|
ci_pipeline = params[:ci_pipeline]
|
|
29
30
|
ci_run_id = params[:ci_run_id]
|
|
30
31
|
ci_run_url = params[:ci_run_url]
|
|
32
|
+
ci_build_duration = params[:ci_build_duration]
|
|
31
33
|
|
|
32
34
|
vc_host_type = params[:vc_host_type]
|
|
33
35
|
vc_host = params[:vc_host]
|
|
@@ -37,6 +39,8 @@ module Fastlane
|
|
|
37
39
|
vc_commit_sha = params[:vc_commit_sha]
|
|
38
40
|
vc_commit_url = params[:vc_commit_url]
|
|
39
41
|
|
|
42
|
+
metadata_artifacts = params[:metadata_artifacts] || []
|
|
43
|
+
|
|
40
44
|
if !structure
|
|
41
45
|
structure = "file"
|
|
42
46
|
end
|
|
@@ -67,12 +71,14 @@ module Fastlane
|
|
|
67
71
|
version_component_meta: version_component_meta,
|
|
68
72
|
custom_build_number: custom_build_number,
|
|
69
73
|
platform: platform,
|
|
74
|
+
custom_target: custom_target,
|
|
70
75
|
stream: stream,
|
|
71
76
|
notes: notes,
|
|
72
77
|
source: source,
|
|
73
78
|
ci_pipeline: ci_pipeline,
|
|
74
79
|
ci_run_id: ci_run_id,
|
|
75
80
|
ci_run_url: ci_run_url,
|
|
81
|
+
ci_build_duration: ci_build_duration,
|
|
76
82
|
vc_host_type: vc_host_type,
|
|
77
83
|
vc_host: vc_host,
|
|
78
84
|
vc_repo_name: vc_repo_name,
|
|
@@ -267,6 +273,128 @@ module Fastlane
|
|
|
267
273
|
else
|
|
268
274
|
UI.success("✅ Upload to Buildstash successful!")
|
|
269
275
|
end
|
|
276
|
+
|
|
277
|
+
# Upload metadata artifacts if provided
|
|
278
|
+
unless metadata_artifacts.empty?
|
|
279
|
+
upload_metadata_artifacts(
|
|
280
|
+
metadata_artifacts: metadata_artifacts,
|
|
281
|
+
pending_upload_id: pending_upload_id,
|
|
282
|
+
api_key: api_key
|
|
283
|
+
)
|
|
284
|
+
end
|
|
285
|
+
end
|
|
286
|
+
|
|
287
|
+
def self.upload_metadata_artifacts(metadata_artifacts:, pending_upload_id:, api_key:)
|
|
288
|
+
max_files = 10
|
|
289
|
+
max_size_bytes = 5 * 1024 * 1024
|
|
290
|
+
|
|
291
|
+
artifacts_to_upload = metadata_artifacts.first(max_files)
|
|
292
|
+
skipped_count = metadata_artifacts.length - artifacts_to_upload.length
|
|
293
|
+
|
|
294
|
+
if skipped_count > 0
|
|
295
|
+
UI.important("⚠️ Skipping #{skipped_count} metadata artifact(s) — maximum of #{max_files} files allowed per upload.")
|
|
296
|
+
end
|
|
297
|
+
|
|
298
|
+
UI.message("Uploading #{artifacts_to_upload.length} metadata artifact(s)...")
|
|
299
|
+
|
|
300
|
+
artifacts_to_upload.each_with_index do |artifact, index|
|
|
301
|
+
file_path = artifact[:path] || artifact["path"]
|
|
302
|
+
description = artifact[:description] || artifact["description"]
|
|
303
|
+
|
|
304
|
+
unless file_path
|
|
305
|
+
UI.important("⚠️ Metadata artifact at index #{index} has no path — skipping.")
|
|
306
|
+
next
|
|
307
|
+
end
|
|
308
|
+
|
|
309
|
+
unless File.exist?(file_path)
|
|
310
|
+
UI.important("⚠️ Metadata artifact not found at path: #{file_path} — skipping.")
|
|
311
|
+
next
|
|
312
|
+
end
|
|
313
|
+
|
|
314
|
+
file_size = File.size(file_path)
|
|
315
|
+
if file_size > max_size_bytes
|
|
316
|
+
size_mb = (file_size.to_f / (1024 * 1024)).round(2)
|
|
317
|
+
UI.important("⚠️ Metadata artifact '#{File.basename(file_path)}' is #{size_mb}MB — exceeds the 5MB limit, skipping.")
|
|
318
|
+
next
|
|
319
|
+
end
|
|
320
|
+
|
|
321
|
+
filename = File.basename(file_path)
|
|
322
|
+
desc_text = description ? " (#{description})" : ""
|
|
323
|
+
UI.message("Uploading metadata artifact #{index + 1}/#{artifacts_to_upload.length}: #{filename}#{desc_text}")
|
|
324
|
+
|
|
325
|
+
# Request presigned upload URL for this metadata artifact
|
|
326
|
+
meta_request_response = Helper::BuildstashHelper.post_json(
|
|
327
|
+
url: "https://app.buildstash.com/api/v1/upload/metadata/request",
|
|
328
|
+
body: {
|
|
329
|
+
primary_pending_upload_id: pending_upload_id,
|
|
330
|
+
filename: filename,
|
|
331
|
+
size_bytes: file_size
|
|
332
|
+
},
|
|
333
|
+
headers: {
|
|
334
|
+
"Authorization" => "Bearer #{api_key}",
|
|
335
|
+
"Content-Type" => "application/json",
|
|
336
|
+
"Accept" => "application/json"
|
|
337
|
+
}
|
|
338
|
+
)
|
|
339
|
+
|
|
340
|
+
unless meta_request_response.is_a?(Net::HTTPSuccess)
|
|
341
|
+
UI.error("Failed to request metadata upload for '#{filename}': #{meta_request_response.code} #{meta_request_response.body} — skipping.")
|
|
342
|
+
next
|
|
343
|
+
end
|
|
344
|
+
|
|
345
|
+
meta_request_data = JSON.parse(meta_request_response.body)
|
|
346
|
+
metadata_pending_upload_id = meta_request_data["metadata_pending_upload_id"]
|
|
347
|
+
presigned_data = meta_request_data["presigned_upload_data"]
|
|
348
|
+
|
|
349
|
+
unless presigned_data && presigned_data["url"]
|
|
350
|
+
UI.error("No presigned upload URL returned for metadata artifact '#{filename}' — skipping.")
|
|
351
|
+
next
|
|
352
|
+
end
|
|
353
|
+
|
|
354
|
+
upload_headers = presigned_data["headers"] || {}
|
|
355
|
+
|
|
356
|
+
# Upload the metadata file to the presigned URL
|
|
357
|
+
upload_response = Helper::BuildstashHelper.upload_file(
|
|
358
|
+
url: presigned_data["url"],
|
|
359
|
+
file_path: file_path,
|
|
360
|
+
headers: {
|
|
361
|
+
"Content-Type" => upload_headers["Content-Type"] || "application/octet-stream",
|
|
362
|
+
"Content-Length" => (upload_headers["Content-Length"] || file_size).to_s,
|
|
363
|
+
"Content-Disposition" => upload_headers["Content-Disposition"] || "attachment; filename=\"#{filename}\"",
|
|
364
|
+
"x-amz-acl" => "private"
|
|
365
|
+
}
|
|
366
|
+
)
|
|
367
|
+
|
|
368
|
+
unless upload_response.is_a?(Net::HTTPSuccess)
|
|
369
|
+
UI.error("Metadata artifact upload failed for '#{filename}': #{upload_response.code} #{upload_response.body} — skipping.")
|
|
370
|
+
next
|
|
371
|
+
end
|
|
372
|
+
|
|
373
|
+
# Verify the metadata artifact upload
|
|
374
|
+
verify_body = { pending_upload_id: metadata_pending_upload_id }
|
|
375
|
+
verify_body[:file_description] = description if description
|
|
376
|
+
|
|
377
|
+
meta_verify_response = Helper::BuildstashHelper.post_json(
|
|
378
|
+
url: "https://app.buildstash.com/api/v1/upload/metadata/verify",
|
|
379
|
+
body: verify_body,
|
|
380
|
+
headers: {
|
|
381
|
+
"Authorization" => "Bearer #{api_key}",
|
|
382
|
+
"Content-Type" => "application/json",
|
|
383
|
+
"Accept" => "application/json"
|
|
384
|
+
}
|
|
385
|
+
)
|
|
386
|
+
|
|
387
|
+
unless meta_verify_response.is_a?(Net::HTTPSuccess)
|
|
388
|
+
UI.error("Metadata artifact verification failed for '#{filename}': #{meta_verify_response.code} #{meta_verify_response.body} — skipping.")
|
|
389
|
+
next
|
|
390
|
+
end
|
|
391
|
+
|
|
392
|
+
meta_verify_data = JSON.parse(meta_verify_response.body)
|
|
393
|
+
artifact_id = meta_verify_data["metadata_artifact_id"]
|
|
394
|
+
UI.success("Metadata artifact '#{filename}' uploaded successfully (ID: #{artifact_id}).")
|
|
395
|
+
end
|
|
396
|
+
|
|
397
|
+
UI.success("✅ All metadata artifacts processed.")
|
|
270
398
|
end
|
|
271
399
|
|
|
272
400
|
def self.description
|
|
@@ -307,6 +435,13 @@ module Fastlane
|
|
|
307
435
|
type: String
|
|
308
436
|
),
|
|
309
437
|
|
|
438
|
+
FastlaneCore::ConfigItem.new(
|
|
439
|
+
key: :custom_target,
|
|
440
|
+
description: "Custom target for this build (must exactly match a target defined in your Buildstash app)",
|
|
441
|
+
optional: true,
|
|
442
|
+
type: String
|
|
443
|
+
),
|
|
444
|
+
|
|
310
445
|
FastlaneCore::ConfigItem.new(
|
|
311
446
|
key: :stream,
|
|
312
447
|
description: "Buildstash stream",
|
|
@@ -412,6 +547,13 @@ module Fastlane
|
|
|
412
547
|
type: String,
|
|
413
548
|
),
|
|
414
549
|
|
|
550
|
+
FastlaneCore::ConfigItem.new(
|
|
551
|
+
key: :ci_build_duration,
|
|
552
|
+
description: "CI build duration (e.g. '00:05:00')",
|
|
553
|
+
optional: true,
|
|
554
|
+
type: String,
|
|
555
|
+
),
|
|
556
|
+
|
|
415
557
|
FastlaneCore::ConfigItem.new(
|
|
416
558
|
key: :vc_host_type,
|
|
417
559
|
description: "Version control host type (git, svn, hg, perforce, etc)",
|
|
@@ -461,6 +603,14 @@ module Fastlane
|
|
|
461
603
|
type: String,
|
|
462
604
|
),
|
|
463
605
|
|
|
606
|
+
FastlaneCore::ConfigItem.new(
|
|
607
|
+
key: :metadata_artifacts,
|
|
608
|
+
description: "List of supplementary files to upload alongside the build (e.g. logs). Each entry is a Hash with a required `:path` key and an optional `:description` key. Maximum 10 files, 5MB per file",
|
|
609
|
+
optional: true,
|
|
610
|
+
type: Array,
|
|
611
|
+
default_value: []
|
|
612
|
+
),
|
|
613
|
+
|
|
464
614
|
]
|
|
465
615
|
end
|
|
466
616
|
|