fastlane-plugin-circle_ci 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 +4 -4
- data/README.md +272 -3
- data/lib/fastlane/plugin/circle_ci/actions/circleci_add_context_env_var.rb +117 -0
- data/lib/fastlane/plugin/circle_ci/actions/circleci_add_project_collaborator.rb +109 -0
- data/lib/fastlane/plugin/circle_ci/actions/circleci_approve_job.rb +95 -0
- data/lib/fastlane/plugin/circle_ci/actions/circleci_cancel_job.rb +96 -0
- data/lib/fastlane/plugin/circle_ci/actions/circleci_cancel_workflow.rb +85 -0
- data/lib/fastlane/plugin/circle_ci/actions/circleci_continue_pipeline.rb +104 -0
- data/lib/fastlane/plugin/circle_ci/actions/circleci_create_checkout_key.rb +110 -0
- data/lib/fastlane/plugin/circle_ci/actions/circleci_create_pipeline_definition.rb +126 -0
- data/lib/fastlane/plugin/circle_ci/actions/circleci_create_pipeline_definition_trigger.rb +133 -0
- data/lib/fastlane/plugin/circle_ci/actions/circleci_create_pipeline_schedule.rb +160 -0
- data/lib/fastlane/plugin/circle_ci/actions/circleci_create_project.rb +105 -0
- data/lib/fastlane/plugin/circle_ci/actions/circleci_create_webhook.rb +155 -0
- data/lib/fastlane/plugin/circle_ci/actions/circleci_delete_checkout_key.rb +93 -0
- data/lib/fastlane/plugin/circle_ci/actions/circleci_delete_context_env_var.rb +110 -0
- data/lib/fastlane/plugin/circle_ci/actions/circleci_delete_env_var.rb +86 -0
- data/lib/fastlane/plugin/circle_ci/actions/circleci_delete_pipeline_definition.rb +91 -0
- data/lib/fastlane/plugin/circle_ci/actions/circleci_delete_pipeline_schedule.rb +95 -0
- data/lib/fastlane/plugin/circle_ci/actions/circleci_delete_trigger.rb +92 -0
- data/lib/fastlane/plugin/circle_ci/actions/circleci_delete_webhook.rb +86 -0
- data/lib/fastlane/plugin/circle_ci/actions/circleci_download_artifact.rb +119 -0
- data/lib/fastlane/plugin/circle_ci/actions/circleci_download_workflow_artifacts.rb +400 -0
- data/lib/fastlane/plugin/circle_ci/actions/circleci_get_checkout_key.rb +101 -0
- data/lib/fastlane/plugin/circle_ci/actions/circleci_get_checkout_keys.rb +96 -0
- data/lib/fastlane/plugin/circle_ci/actions/circleci_get_context_env_vars.rb +114 -0
- data/lib/fastlane/plugin/circle_ci/actions/circleci_get_env_vars.rb +95 -0
- data/lib/fastlane/plugin/circle_ci/actions/circleci_get_flaky_tests.rb +99 -0
- data/lib/fastlane/plugin/circle_ci/actions/circleci_get_job_artifacts.rb +111 -0
- data/lib/fastlane/plugin/circle_ci/actions/circleci_get_job_details.rb +110 -0
- data/lib/fastlane/plugin/circle_ci/actions/circleci_get_job_tests.rb +111 -0
- data/lib/fastlane/plugin/circle_ci/actions/circleci_get_job_timeseries.rb +131 -0
- data/lib/fastlane/plugin/circle_ci/actions/circleci_get_my_pipelines.rb +100 -0
- data/lib/fastlane/plugin/circle_ci/actions/circleci_get_org_summary.rb +113 -0
- data/lib/fastlane/plugin/circle_ci/actions/circleci_get_pipeline.rb +104 -0
- data/lib/fastlane/plugin/circle_ci/actions/circleci_get_pipeline_by_number.rb +105 -0
- data/lib/fastlane/plugin/circle_ci/actions/circleci_get_pipeline_config.rb +92 -0
- data/lib/fastlane/plugin/circle_ci/actions/circleci_get_pipeline_definition.rb +99 -0
- data/lib/fastlane/plugin/circle_ci/actions/circleci_get_pipeline_definitions.rb +94 -0
- data/lib/fastlane/plugin/circle_ci/actions/circleci_get_pipeline_values.rb +91 -0
- data/lib/fastlane/plugin/circle_ci/actions/circleci_get_pipeline_workflows.rb +108 -0
- data/lib/fastlane/plugin/circle_ci/actions/circleci_get_project_branches.rb +105 -0
- data/lib/fastlane/plugin/circle_ci/actions/circleci_get_project_config.rb +104 -0
- data/lib/fastlane/plugin/circle_ci/actions/circleci_get_project_workflow_metrics.rb +121 -0
- data/lib/fastlane/plugin/circle_ci/actions/circleci_get_trigger.rb +99 -0
- data/lib/fastlane/plugin/circle_ci/actions/circleci_get_user_info.rb +83 -0
- data/lib/fastlane/plugin/circle_ci/actions/circleci_get_workflow.rb +121 -0
- data/lib/fastlane/plugin/circle_ci/actions/circleci_get_workflow_insights.rb +157 -0
- data/lib/fastlane/plugin/circle_ci/actions/circleci_get_workflow_job_metrics.rb +123 -0
- data/lib/fastlane/plugin/circle_ci/actions/circleci_get_workflow_jobs.rb +109 -0
- data/lib/fastlane/plugin/circle_ci/actions/circleci_get_workflow_runs.rb +129 -0
- data/lib/fastlane/plugin/circle_ci/actions/circleci_get_workflow_summary.rb +118 -0
- data/lib/fastlane/plugin/circle_ci/actions/circleci_get_workflow_test_metrics.rb +115 -0
- data/lib/fastlane/plugin/circle_ci/actions/circleci_list_all_pipelines.rb +94 -0
- data/lib/fastlane/plugin/circle_ci/actions/circleci_list_contexts.rb +132 -0
- data/lib/fastlane/plugin/circle_ci/actions/circleci_list_pipeline_definition_triggers.rb +101 -0
- data/lib/fastlane/plugin/circle_ci/actions/circleci_list_pipeline_schedules.rb +99 -0
- data/lib/fastlane/plugin/circle_ci/actions/circleci_list_projects.rb +89 -0
- data/lib/fastlane/plugin/circle_ci/actions/circleci_list_webhooks.rb +111 -0
- data/lib/fastlane/plugin/circle_ci/actions/circleci_rerun_workflow.rb +101 -0
- data/lib/fastlane/plugin/circle_ci/actions/circleci_set_env_var.rb +102 -0
- data/lib/fastlane/plugin/circle_ci/actions/circleci_trigger_pipeline.rb +130 -0
- data/lib/fastlane/plugin/circle_ci/actions/circleci_update_pipeline_definition.rb +127 -0
- data/lib/fastlane/plugin/circle_ci/actions/circleci_update_pipeline_schedule.rb +134 -0
- data/lib/fastlane/plugin/circle_ci/actions/circleci_update_trigger.rb +114 -0
- data/lib/fastlane/plugin/circle_ci/actions/circleci_wait_for_pipeline.rb +152 -0
- data/lib/fastlane/plugin/circle_ci/helper/circle_ci_helper.rb +102 -1
- data/lib/fastlane/plugin/circle_ci/version.rb +1 -1
- metadata +99 -7
@@ -0,0 +1,400 @@
|
|
1
|
+
require 'fastlane/action'
|
2
|
+
require 'fileutils'
|
3
|
+
require_relative '../helper/circle_ci_helper'
|
4
|
+
|
5
|
+
module Fastlane
|
6
|
+
module Actions
|
7
|
+
module SharedValues
|
8
|
+
CIRCLECI_DOWNLOADED_ARTIFACTS = :CIRCLECI_DOWNLOADED_ARTIFACTS
|
9
|
+
end
|
10
|
+
|
11
|
+
class CircleciDownloadWorkflowArtifactsAction < Action
|
12
|
+
def self.run(params)
|
13
|
+
UI.message("Downloading artifacts from CircleCI workflow...")
|
14
|
+
|
15
|
+
# Extract parameters
|
16
|
+
api_token, project_slug, branch, workflow_name, job_name, destination_dir, file_extensions = extract_params(params)
|
17
|
+
|
18
|
+
# Create destination directory if it doesn't exist
|
19
|
+
FileUtils.mkdir_p(destination_dir)
|
20
|
+
|
21
|
+
# Find the target pipeline and workflow
|
22
|
+
target_pipeline, target_workflow = find_target_pipeline_and_workflow(api_token, project_slug, branch, workflow_name)
|
23
|
+
|
24
|
+
# Get the jobs for the workflow and download artifacts
|
25
|
+
downloaded_artifacts, total_artifacts = download_job_artifacts(
|
26
|
+
api_token,
|
27
|
+
project_slug,
|
28
|
+
target_workflow,
|
29
|
+
workflow_name,
|
30
|
+
destination_dir,
|
31
|
+
file_extensions,
|
32
|
+
job_name
|
33
|
+
)
|
34
|
+
|
35
|
+
# Store values in lane context
|
36
|
+
Actions.lane_context[SharedValues::CIRCLECI_DOWNLOADED_ARTIFACTS] = downloaded_artifacts
|
37
|
+
|
38
|
+
# Prepare and return the result
|
39
|
+
result = prepare_result(
|
40
|
+
target_workflow,
|
41
|
+
workflow_name,
|
42
|
+
target_pipeline,
|
43
|
+
branch,
|
44
|
+
total_artifacts,
|
45
|
+
downloaded_artifacts,
|
46
|
+
destination_dir
|
47
|
+
)
|
48
|
+
|
49
|
+
UI.success("Downloaded #{total_artifacts} artifacts from the '#{workflow_name}' workflow on #{branch} branch to #{destination_dir}")
|
50
|
+
|
51
|
+
return result
|
52
|
+
end
|
53
|
+
|
54
|
+
def self.extract_params(params)
|
55
|
+
[
|
56
|
+
params[:api_token],
|
57
|
+
params[:project_slug],
|
58
|
+
params[:branch],
|
59
|
+
params[:workflow_name],
|
60
|
+
params[:job_name],
|
61
|
+
params[:destination_dir],
|
62
|
+
params[:file_extensions]
|
63
|
+
]
|
64
|
+
end
|
65
|
+
|
66
|
+
def self.find_target_pipeline_and_workflow(api_token, project_slug, branch, workflow_name)
|
67
|
+
UI.important("Looking for the latest pipeline on #{branch} branch...")
|
68
|
+
|
69
|
+
# Get recent pipelines for the project
|
70
|
+
pipelines = Helper::CircleCiHelper.get_v2("project/#{project_slug}/pipeline", api_token)
|
71
|
+
|
72
|
+
# Find the latest pipeline for the specified branch
|
73
|
+
target_pipeline = nil
|
74
|
+
target_workflow = nil
|
75
|
+
|
76
|
+
# Continue searching for pipelines until we find one with the target workflow
|
77
|
+
pipeline_page = 1
|
78
|
+
max_pages_to_search = 10 # Limit how far back we search to avoid excessive API calls
|
79
|
+
|
80
|
+
while target_workflow.nil? && pipeline_page <= max_pages_to_search
|
81
|
+
if pipeline_page > 1
|
82
|
+
UI.important("Workflow '#{workflow_name}' not found in recent pipelines. Checking older pipelines (page #{pipeline_page})...")
|
83
|
+
# Get older pipelines with pagination
|
84
|
+
pipelines = Helper::CircleCiHelper.get_v2("project/#{project_slug}/pipeline", api_token, { page: pipeline_page })
|
85
|
+
end
|
86
|
+
|
87
|
+
# Check each pipeline on this page for the target branch and workflow
|
88
|
+
pipelines["items"].each do |pipeline|
|
89
|
+
next unless pipeline["vcs"] && pipeline["vcs"]["branch"] == branch
|
90
|
+
|
91
|
+
UI.message("Checking pipeline ##{pipeline['number']} on #{branch} branch...")
|
92
|
+
|
93
|
+
# Get the workflows for this pipeline
|
94
|
+
workflows = Helper::CircleCiHelper.get_v2("pipeline/#{pipeline["id"]}/workflow", api_token)
|
95
|
+
|
96
|
+
# Find the target workflow with status "success"
|
97
|
+
workflow = workflows["items"].find { |w| w["name"] == workflow_name && w["status"] == "success" }
|
98
|
+
|
99
|
+
if workflow
|
100
|
+
target_pipeline = pipeline
|
101
|
+
target_workflow = workflow
|
102
|
+
UI.success("Found #{workflow_name} workflow with status 'success' in pipeline ##{pipeline["number"]}")
|
103
|
+
break
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
pipeline_page += 1
|
108
|
+
end
|
109
|
+
|
110
|
+
if target_pipeline.nil?
|
111
|
+
UI.user_error!("No pipeline found for #{branch} branch")
|
112
|
+
end
|
113
|
+
|
114
|
+
if target_workflow.nil?
|
115
|
+
UI.user_error!("No successful '#{workflow_name}' workflow found in any recent pipelines for #{branch} branch")
|
116
|
+
else
|
117
|
+
UI.success("Using #{workflow_name} workflow: #{target_workflow["id"]} from pipeline ##{target_pipeline["number"]}")
|
118
|
+
end
|
119
|
+
|
120
|
+
return [target_pipeline, target_workflow]
|
121
|
+
end
|
122
|
+
|
123
|
+
def self.download_job_artifacts(api_token, project_slug, target_workflow, workflow_name, destination_dir, file_extensions = nil, job_name = nil)
|
124
|
+
# Get the jobs for the workflow
|
125
|
+
jobs_result = Helper::CircleCiHelper.get_v2("workflow/#{target_workflow["id"]}/job", api_token)
|
126
|
+
jobs = jobs_result["items"]
|
127
|
+
|
128
|
+
UI.important("Found #{jobs.count} jobs in the #{workflow_name} workflow")
|
129
|
+
|
130
|
+
# Filter jobs by name if specified
|
131
|
+
if job_name
|
132
|
+
jobs = jobs.select { |job| job["name"] == job_name }
|
133
|
+
if jobs.empty?
|
134
|
+
UI.user_error!("No job found with name '#{job_name}' in the #{workflow_name} workflow")
|
135
|
+
end
|
136
|
+
UI.important("Filtering to only download artifacts from job: #{job_name}")
|
137
|
+
end
|
138
|
+
|
139
|
+
# Download artifacts for each job
|
140
|
+
downloaded_artifacts = []
|
141
|
+
total_artifacts = 0
|
142
|
+
|
143
|
+
jobs.each do |job|
|
144
|
+
job_artifacts = download_artifacts_for_job(api_token, project_slug, job, destination_dir, file_extensions)
|
145
|
+
|
146
|
+
if !job_artifacts.empty?
|
147
|
+
downloaded_artifacts << {
|
148
|
+
job_name: job["name"],
|
149
|
+
job_number: job["job_number"],
|
150
|
+
artifacts: job_artifacts
|
151
|
+
}
|
152
|
+
total_artifacts += job_artifacts.count
|
153
|
+
end
|
154
|
+
end
|
155
|
+
|
156
|
+
return [downloaded_artifacts, total_artifacts]
|
157
|
+
end
|
158
|
+
|
159
|
+
def self.download_artifacts_for_job(api_token, project_slug, job, destination_dir, file_extensions = nil)
|
160
|
+
UI.message("Getting artifacts for job: #{job["name"]}")
|
161
|
+
|
162
|
+
# Skip jobs with no number (haven't run yet)
|
163
|
+
return [] unless job["job_number"]
|
164
|
+
|
165
|
+
# Get artifacts for this job
|
166
|
+
artifacts_result = Helper::CircleCiHelper.get_v2("project/#{project_slug}/#{job["job_number"]}/artifacts", api_token)
|
167
|
+
artifacts = artifacts_result["items"]
|
168
|
+
|
169
|
+
if artifacts.empty?
|
170
|
+
UI.message("No artifacts found for job: #{job["name"]}")
|
171
|
+
return []
|
172
|
+
end
|
173
|
+
|
174
|
+
# Filter artifacts by extension if specified
|
175
|
+
if file_extensions
|
176
|
+
extensions = file_extensions.is_a?(Array) ? file_extensions : [file_extensions.to_s]
|
177
|
+
filtered_artifacts = filter_artifacts_by_extension(artifacts, extensions)
|
178
|
+
|
179
|
+
if filtered_artifacts.empty?
|
180
|
+
UI.message("No artifacts with extensions #{extensions.join(', ')} found for job: #{job["name"]}")
|
181
|
+
return []
|
182
|
+
end
|
183
|
+
|
184
|
+
UI.success("Found #{filtered_artifacts.count} artifacts with extensions #{extensions.join(', ')} for job: #{job["name"]}")
|
185
|
+
artifacts = filtered_artifacts
|
186
|
+
else
|
187
|
+
UI.success("Found #{artifacts.count} artifacts for job: #{job["name"]}")
|
188
|
+
end
|
189
|
+
|
190
|
+
# Download each artifact
|
191
|
+
download_artifacts(api_token, job["name"], artifacts, destination_dir)
|
192
|
+
end
|
193
|
+
|
194
|
+
def self.filter_artifacts_by_extension(artifacts, extensions)
|
195
|
+
artifacts.select do |artifact|
|
196
|
+
# Get the file extension from the path
|
197
|
+
ext = File.extname(artifact["path"]).delete('.')
|
198
|
+
extensions.include?(ext.downcase)
|
199
|
+
end
|
200
|
+
end
|
201
|
+
|
202
|
+
def self.download_artifacts(api_token, job_name, artifacts, destination_dir)
|
203
|
+
job_artifacts = []
|
204
|
+
|
205
|
+
artifacts.each do |artifact|
|
206
|
+
download_path = prepare_download_path(destination_dir, job_name, artifact)
|
207
|
+
|
208
|
+
if download_artifact(api_token, artifact, download_path)
|
209
|
+
job_artifacts << {
|
210
|
+
job_name: job_name,
|
211
|
+
artifact_path: artifact["path"],
|
212
|
+
url: artifact["url"],
|
213
|
+
download_path: download_path
|
214
|
+
}
|
215
|
+
end
|
216
|
+
end
|
217
|
+
|
218
|
+
return job_artifacts
|
219
|
+
end
|
220
|
+
|
221
|
+
def self.prepare_download_path(destination_dir, job_name, artifact)
|
222
|
+
job_dir = File.join(destination_dir, job_name)
|
223
|
+
FileUtils.mkdir_p(job_dir)
|
224
|
+
|
225
|
+
artifact_filename = File.basename(artifact["path"])
|
226
|
+
File.join(job_dir, artifact_filename)
|
227
|
+
end
|
228
|
+
|
229
|
+
def self.download_artifact(api_token, artifact, download_path)
|
230
|
+
UI.message("Downloading artifact: #{artifact["path"]} to #{download_path}")
|
231
|
+
|
232
|
+
# Configure Faraday
|
233
|
+
conn = Faraday.new do |f|
|
234
|
+
f.headers['Circle-Token'] = api_token if api_token
|
235
|
+
f.response :follow_redirects
|
236
|
+
f.adapter Faraday.default_adapter
|
237
|
+
end
|
238
|
+
|
239
|
+
# Download the file
|
240
|
+
begin
|
241
|
+
response = conn.get(artifact["url"])
|
242
|
+
|
243
|
+
if response.status >= 200 && response.status < 300
|
244
|
+
# Write the response body to the destination file
|
245
|
+
File.open(download_path, "wb") do |file|
|
246
|
+
file.write(response.body)
|
247
|
+
end
|
248
|
+
UI.success("Successfully downloaded artifact to #{download_path}")
|
249
|
+
return true
|
250
|
+
else
|
251
|
+
UI.error("Failed to download artifact: HTTP #{response.status}")
|
252
|
+
return false
|
253
|
+
end
|
254
|
+
rescue => e
|
255
|
+
UI.error("Error downloading artifact: #{e.message}")
|
256
|
+
return false
|
257
|
+
end
|
258
|
+
end
|
259
|
+
|
260
|
+
def self.prepare_result(target_workflow, workflow_name, target_pipeline, branch, total_artifacts, downloaded_artifacts, destination_dir)
|
261
|
+
{
|
262
|
+
workflow_id: target_workflow["id"],
|
263
|
+
workflow_name: workflow_name,
|
264
|
+
pipeline_number: target_pipeline["number"],
|
265
|
+
pipeline_id: target_pipeline["id"],
|
266
|
+
branch: branch,
|
267
|
+
total_artifacts: total_artifacts,
|
268
|
+
downloaded_artifacts: downloaded_artifacts,
|
269
|
+
destination_dir: destination_dir
|
270
|
+
}
|
271
|
+
end
|
272
|
+
|
273
|
+
def self.description
|
274
|
+
"Downloads artifacts from a specific CircleCI workflow"
|
275
|
+
end
|
276
|
+
|
277
|
+
def self.details
|
278
|
+
"This action downloads all artifacts from a specific CircleCI workflow. By default, it targets the most recent 'test' workflow from the master branch, but you can customize all parameters. Artifacts are downloaded to the specified directory, organized by job name."
|
279
|
+
end
|
280
|
+
|
281
|
+
def self.available_options
|
282
|
+
[
|
283
|
+
FastlaneCore::ConfigItem.new(key: :api_token,
|
284
|
+
env_name: "CIRCLE_CI_API_TOKEN",
|
285
|
+
description: "API Token for CircleCI API",
|
286
|
+
sensitive: true,
|
287
|
+
code_gen_sensitive: true,
|
288
|
+
is_string: true,
|
289
|
+
default_value: ENV["CIRCLE_CI_API_TOKEN"],
|
290
|
+
default_value_dynamic: true,
|
291
|
+
optional: false),
|
292
|
+
FastlaneCore::ConfigItem.new(key: :project_slug,
|
293
|
+
env_name: "CIRCLE_CI_PROJECT_SLUG",
|
294
|
+
description: "Project slug in the form of :vcs-type/:org-name/:project-name (e.g. github/myorg/myrepo)",
|
295
|
+
is_string: true,
|
296
|
+
default_value: ENV["CIRCLE_CI_PROJECT_SLUG"],
|
297
|
+
default_value_dynamic: true,
|
298
|
+
optional: false),
|
299
|
+
FastlaneCore::ConfigItem.new(key: :branch,
|
300
|
+
env_name: "CIRCLE_CI_BRANCH",
|
301
|
+
description: "The name of the branch to search for workflows",
|
302
|
+
is_string: true,
|
303
|
+
default_value: "master",
|
304
|
+
optional: true),
|
305
|
+
FastlaneCore::ConfigItem.new(key: :workflow_name,
|
306
|
+
env_name: "CIRCLE_CI_WORKFLOW_NAME",
|
307
|
+
description: "The name of the workflow to download artifacts from",
|
308
|
+
is_string: true,
|
309
|
+
default_value: "test",
|
310
|
+
optional: true),
|
311
|
+
FastlaneCore::ConfigItem.new(key: :job_name,
|
312
|
+
env_name: "CIRCLE_CI_JOB_NAME",
|
313
|
+
description: "The name of a specific job to download artifacts from (if not provided, artifacts from all jobs will be downloaded)",
|
314
|
+
is_string: true,
|
315
|
+
optional: true),
|
316
|
+
FastlaneCore::ConfigItem.new(key: :destination_dir,
|
317
|
+
env_name: "CIRCLE_CI_ARTIFACT_DESTINATION_DIR",
|
318
|
+
description: "Directory where artifacts should be saved",
|
319
|
+
is_string: true,
|
320
|
+
default_value: "./artifacts",
|
321
|
+
optional: true),
|
322
|
+
FastlaneCore::ConfigItem.new(key: :file_extensions,
|
323
|
+
env_name: "CIRCLE_CI_ARTIFACT_FILE_EXTENSIONS",
|
324
|
+
description: "File extensions to download (e.g. 'json' or ['json', 'xml']). If provided, only files with these extensions will be downloaded",
|
325
|
+
is_string: false,
|
326
|
+
default_value: "json",
|
327
|
+
optional: true)
|
328
|
+
]
|
329
|
+
end
|
330
|
+
|
331
|
+
def self.output
|
332
|
+
[
|
333
|
+
['CIRCLECI_DOWNLOADED_ARTIFACTS', 'An array of downloaded artifacts information grouped by job']
|
334
|
+
]
|
335
|
+
end
|
336
|
+
|
337
|
+
def self.return_value
|
338
|
+
"Returns a hash containing information about the download process, including workflow ID, pipeline details, branch, and downloaded artifacts."
|
339
|
+
end
|
340
|
+
|
341
|
+
def self.authors
|
342
|
+
["crazymanish"]
|
343
|
+
end
|
344
|
+
|
345
|
+
def self.example_code
|
346
|
+
[
|
347
|
+
'# Download only JSON files (default)
|
348
|
+
circleci_download_workflow_artifacts(
|
349
|
+
project_slug: "github/myorg/myrepo"
|
350
|
+
)',
|
351
|
+
'# Download only XML files
|
352
|
+
circleci_download_workflow_artifacts(
|
353
|
+
project_slug: "github/myorg/myrepo",
|
354
|
+
file_extensions: "xml"
|
355
|
+
)',
|
356
|
+
'# Download both JSON and XML files
|
357
|
+
circleci_download_workflow_artifacts(
|
358
|
+
project_slug: "github/myorg/myrepo",
|
359
|
+
file_extensions: ["json", "xml"]
|
360
|
+
)',
|
361
|
+
'# Download artifacts from a specific job only
|
362
|
+
circleci_download_workflow_artifacts(
|
363
|
+
project_slug: "github/myorg/myrepo",
|
364
|
+
job_name: "build"
|
365
|
+
)',
|
366
|
+
'circleci_download_workflow_artifacts(
|
367
|
+
project_slug: "github/myorg/myrepo"
|
368
|
+
)',
|
369
|
+
'artifacts_info = circleci_download_workflow_artifacts(
|
370
|
+
project_slug: "github/myorg/myrepo",
|
371
|
+
branch: "feature/my-branch",
|
372
|
+
workflow_name: "integration",
|
373
|
+
destination_dir: "./my-artifacts"
|
374
|
+
)
|
375
|
+
|
376
|
+
# Print summary of downloaded artifacts
|
377
|
+
UI.message("Downloaded #{artifacts_info[:total_artifacts]} artifacts from #{artifacts_info[:workflow_name]} workflow")
|
378
|
+
|
379
|
+
# Process downloaded artifacts
|
380
|
+
artifacts_info[:downloaded_artifacts].each do |job_artifacts|
|
381
|
+
job_name = job_artifacts[:job_name]
|
382
|
+
job_artifacts[:artifacts].each do |artifact|
|
383
|
+
path = artifact[:download_path]
|
384
|
+
# Process artifact files as needed
|
385
|
+
puts "Processing #{path} from job #{job_name}"
|
386
|
+
end
|
387
|
+
end'
|
388
|
+
]
|
389
|
+
end
|
390
|
+
|
391
|
+
def self.is_supported?(platform)
|
392
|
+
true
|
393
|
+
end
|
394
|
+
|
395
|
+
def self.category
|
396
|
+
:ci
|
397
|
+
end
|
398
|
+
end
|
399
|
+
end
|
400
|
+
end
|
@@ -0,0 +1,101 @@
|
|
1
|
+
require 'fastlane/action'
|
2
|
+
require_relative '../helper/circle_ci_helper'
|
3
|
+
|
4
|
+
module Fastlane
|
5
|
+
module Actions
|
6
|
+
module SharedValues
|
7
|
+
CIRCLECI_CHECKOUT_KEY_INFO = :CIRCLECI_CHECKOUT_KEY_INFO
|
8
|
+
end
|
9
|
+
|
10
|
+
class CircleciGetCheckoutKeyAction < Action
|
11
|
+
def self.run(params)
|
12
|
+
UI.message("Getting CircleCI project checkout key via API v2...")
|
13
|
+
|
14
|
+
api_token = params[:api_token]
|
15
|
+
project_slug = params[:project_slug]
|
16
|
+
fingerprint = params[:fingerprint]
|
17
|
+
|
18
|
+
# Make API request
|
19
|
+
result = Helper::CircleCiHelper.get_v2("project/#{project_slug}/checkout-key/#{fingerprint}", api_token)
|
20
|
+
|
21
|
+
# Store values in lane context
|
22
|
+
Actions.lane_context[SharedValues::CIRCLECI_CHECKOUT_KEY_INFO] = result
|
23
|
+
|
24
|
+
UI.success("Successfully retrieved checkout key with fingerprint #{fingerprint} for project #{project_slug}")
|
25
|
+
|
26
|
+
return result
|
27
|
+
end
|
28
|
+
|
29
|
+
def self.description
|
30
|
+
"Gets a specific checkout key for a CircleCI project using API v2"
|
31
|
+
end
|
32
|
+
|
33
|
+
def self.details
|
34
|
+
"This action retrieves details for a specific checkout key for a CircleCI project using the CircleCI API v2. You need to provide the fingerprint of the key you want to retrieve."
|
35
|
+
end
|
36
|
+
|
37
|
+
def self.available_options
|
38
|
+
[
|
39
|
+
FastlaneCore::ConfigItem.new(key: :api_token,
|
40
|
+
env_name: "CIRCLE_CI_API_TOKEN",
|
41
|
+
description: "API Token for CircleCI API",
|
42
|
+
sensitive: true,
|
43
|
+
code_gen_sensitive: true,
|
44
|
+
is_string: true,
|
45
|
+
default_value: ENV["CIRCLE_CI_API_TOKEN"],
|
46
|
+
default_value_dynamic: true,
|
47
|
+
optional: false),
|
48
|
+
FastlaneCore::ConfigItem.new(key: :project_slug,
|
49
|
+
env_name: "CIRCLE_CI_PROJECT_SLUG",
|
50
|
+
description: "Project slug in the form of :vcs-type/:org-name/:project-name (e.g. github/myorg/myrepo)",
|
51
|
+
is_string: true,
|
52
|
+
default_value: ENV["CIRCLE_CI_PROJECT_SLUG"],
|
53
|
+
default_value_dynamic: true,
|
54
|
+
optional: false),
|
55
|
+
FastlaneCore::ConfigItem.new(key: :fingerprint,
|
56
|
+
description: "The fingerprint of the checkout key to retrieve",
|
57
|
+
is_string: true,
|
58
|
+
optional: false)
|
59
|
+
]
|
60
|
+
end
|
61
|
+
|
62
|
+
def self.output
|
63
|
+
[
|
64
|
+
['CIRCLECI_CHECKOUT_KEY_INFO', 'A hash containing the checkout key information']
|
65
|
+
]
|
66
|
+
end
|
67
|
+
|
68
|
+
def self.return_value
|
69
|
+
"Returns a hash containing the checkout key information including type, fingerprint, and preferred status."
|
70
|
+
end
|
71
|
+
|
72
|
+
def self.authors
|
73
|
+
["crazymanish", "copilot"]
|
74
|
+
end
|
75
|
+
|
76
|
+
def self.example_code
|
77
|
+
[
|
78
|
+
'circleci_get_checkout_key(
|
79
|
+
project_slug: "gh/MyOrg/my-project",
|
80
|
+
fingerprint: "c9:0b:1c:4f:d5:65:56:b9:ad:88:f9:81:2b:37:74:2f"
|
81
|
+
)',
|
82
|
+
'key_info = circleci_get_checkout_key(
|
83
|
+
project_slug: "gh/MyOrg/my-project",
|
84
|
+
fingerprint: "c9:0b:1c:4f:d5:65:56:b9:ad:88:f9:81:2b:37:74:2f"
|
85
|
+
)
|
86
|
+
|
87
|
+
# Use the key information
|
88
|
+
UI.message("Key type: #{key_info["type"]}, Public key: #{key_info["public_key"]}")'
|
89
|
+
]
|
90
|
+
end
|
91
|
+
|
92
|
+
def self.is_supported?(platform)
|
93
|
+
true
|
94
|
+
end
|
95
|
+
|
96
|
+
def self.category
|
97
|
+
:ci
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
@@ -0,0 +1,96 @@
|
|
1
|
+
require 'fastlane/action'
|
2
|
+
require_relative '../helper/circle_ci_helper'
|
3
|
+
|
4
|
+
module Fastlane
|
5
|
+
module Actions
|
6
|
+
module SharedValues
|
7
|
+
CIRCLECI_CHECKOUT_KEYS = :CIRCLECI_CHECKOUT_KEYS
|
8
|
+
end
|
9
|
+
|
10
|
+
class CircleciGetCheckoutKeysAction < Action
|
11
|
+
def self.run(params)
|
12
|
+
UI.message("Getting CircleCI project checkout keys via API v2...")
|
13
|
+
|
14
|
+
api_token = params[:api_token]
|
15
|
+
project_slug = params[:project_slug]
|
16
|
+
|
17
|
+
# Make API request
|
18
|
+
result = Helper::CircleCiHelper.get_v2("project/#{project_slug}/checkout-key", api_token)
|
19
|
+
|
20
|
+
# Store values in lane context
|
21
|
+
Actions.lane_context[SharedValues::CIRCLECI_CHECKOUT_KEYS] = result
|
22
|
+
|
23
|
+
UI.success("Successfully retrieved checkout keys for project #{project_slug}")
|
24
|
+
|
25
|
+
return result
|
26
|
+
end
|
27
|
+
|
28
|
+
def self.description
|
29
|
+
"Gets all checkout keys for a CircleCI project using API v2"
|
30
|
+
end
|
31
|
+
|
32
|
+
def self.details
|
33
|
+
"This action retrieves all checkout keys for a specific CircleCI project using the CircleCI API v2. Checkout keys are used to check out code from your version control system."
|
34
|
+
end
|
35
|
+
|
36
|
+
def self.available_options
|
37
|
+
[
|
38
|
+
FastlaneCore::ConfigItem.new(key: :api_token,
|
39
|
+
env_name: "CIRCLE_CI_API_TOKEN",
|
40
|
+
description: "API Token for CircleCI API",
|
41
|
+
sensitive: true,
|
42
|
+
code_gen_sensitive: true,
|
43
|
+
is_string: true,
|
44
|
+
default_value: ENV["CIRCLE_CI_API_TOKEN"],
|
45
|
+
default_value_dynamic: true,
|
46
|
+
optional: false),
|
47
|
+
FastlaneCore::ConfigItem.new(key: :project_slug,
|
48
|
+
env_name: "CIRCLE_CI_PROJECT_SLUG",
|
49
|
+
description: "Project slug in the form of :vcs-type/:org-name/:project-name (e.g. github/myorg/myrepo)",
|
50
|
+
is_string: true,
|
51
|
+
default_value: ENV["CIRCLE_CI_PROJECT_SLUG"],
|
52
|
+
default_value_dynamic: true,
|
53
|
+
optional: false)
|
54
|
+
]
|
55
|
+
end
|
56
|
+
|
57
|
+
def self.output
|
58
|
+
[
|
59
|
+
['CIRCLECI_CHECKOUT_KEYS', 'A hash containing checkout keys information']
|
60
|
+
]
|
61
|
+
end
|
62
|
+
|
63
|
+
def self.return_value
|
64
|
+
"Returns a hash containing checkout keys information including type, fingerprint, and preferred status."
|
65
|
+
end
|
66
|
+
|
67
|
+
def self.authors
|
68
|
+
["crazymanish", "copilot"]
|
69
|
+
end
|
70
|
+
|
71
|
+
def self.example_code
|
72
|
+
[
|
73
|
+
'circleci_get_checkout_keys(
|
74
|
+
project_slug: "gh/MyOrg/my-project"
|
75
|
+
)',
|
76
|
+
'keys = circleci_get_checkout_keys(
|
77
|
+
project_slug: "gh/MyOrg/my-project"
|
78
|
+
)
|
79
|
+
|
80
|
+
# Use the checkout keys
|
81
|
+
keys["items"].each do |key|
|
82
|
+
UI.message("Found key: #{key["type"]} with fingerprint #{key["fingerprint"]}")
|
83
|
+
end'
|
84
|
+
]
|
85
|
+
end
|
86
|
+
|
87
|
+
def self.is_supported?(platform)
|
88
|
+
true
|
89
|
+
end
|
90
|
+
|
91
|
+
def self.category
|
92
|
+
:ci
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|