uffizzi-cli 0.12.0 → 1.0.1

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: c27a1f65cd69d407dc2f086733a20baaf6e129b7433322ac61682f6b8a1fa54e
4
- data.tar.gz: 61c6860dbc035009ee6197f353c05d0af95eda6d6f77b67d25f672ba954e114f
3
+ metadata.gz: 88f0a01cdfea0ed8e8d4ad54d776f517f84d74c424f2db15569fb788e7fe3868
4
+ data.tar.gz: e690fe7b2552ae4215687aac32420cb4b39e3cd2dd4b1d4fcf723538e49b213c
5
5
  SHA512:
6
- metadata.gz: 709d000e6701f32d3dcaa3745c68d2eb63695dba2dd8ef939201569605bb121fdd3422d730d3bdc2687a33cc81810b97a3a4f4841187aac68547824293523173
7
- data.tar.gz: 1b0ae241adab3fb770f25cca8709ae779b5c8de16056fa71e6242d470123550b6cacc920f1e2b9474951323b72d1d18160a840ed64c4814469eb89e138d0c3d5
6
+ metadata.gz: 77198a935bf13d106bd191e017094ecc431cc09e307608a4f23ccd3bbd5591b7d12def5f4c3eff77f0389acfe6384f2a80ad63389d7ce8b7f51b9768d8bd0d09
7
+ data.tar.gz: c945bf73973d7a55fae9e3cf9502a1cfacafc65671b292913333c61f644fe0ca9c5402e7ae7ce54ae88bd08de117e016614d72e9474634ff725581828ea288bb
@@ -10,7 +10,8 @@ module Uffizzi
10
10
  desc 'list-credentials', 'List existing credentials for an account'
11
11
  def list_credentials
12
12
  server = ConfigFile.read_option(:server)
13
- response = fetch_credentials(server)
13
+ account_id = ConfigFile.read_option(:account_id)
14
+ response = fetch_credentials(server, account_id)
14
15
  if ResponseHelper.ok?(response)
15
16
  handle_list_credentials_success(response)
16
17
  else
@@ -37,11 +38,12 @@ module Uffizzi
37
38
  type: type,
38
39
  }
39
40
  server = ConfigFile.read_option(:server)
41
+ account_id = ConfigFile.read_option(:account_id)
40
42
 
41
43
  response = if credential_exists
42
- update_credential(server, params, type)
44
+ update_credential(server, account_id, params, type)
43
45
  else
44
- create_credential(server, params)
46
+ create_credential(server, account_id, params)
45
47
  end
46
48
 
47
49
  handle_result_for('Docker Hub', response)
@@ -68,11 +70,12 @@ module Uffizzi
68
70
  type: type,
69
71
  }
70
72
  server = ConfigFile.read_option(:server)
73
+ account_id = ConfigFile.read_option(:account_id)
71
74
 
72
75
  response = if credential_exists
73
- update_credential(server, params, type)
76
+ update_credential(server, account_id, params, type)
74
77
  else
75
- create_credential(server, params)
78
+ create_credential(server, account_id, params)
76
79
  end
77
80
 
78
81
  handle_result_for('Docker Registry', response)
@@ -99,11 +102,12 @@ module Uffizzi
99
102
  type: type,
100
103
  }
101
104
  server = ConfigFile.read_option(:server)
105
+ account_id = ConfigFile.read_option(:account_id)
102
106
 
103
107
  response = if credential_exists
104
- update_credential(server, params, type)
108
+ update_credential(server, account_id, params, type)
105
109
  else
106
- create_credential(server, params)
110
+ create_credential(server, account_id, params)
107
111
  end
108
112
 
109
113
  handle_result_for('ACR', response)
@@ -130,11 +134,12 @@ module Uffizzi
130
134
  type: type,
131
135
  }
132
136
  server = ConfigFile.read_option(:server)
137
+ account_id = ConfigFile.read_option(:account_id)
133
138
 
134
139
  response = if credential_exists
135
- update_credential(server, params, type)
140
+ update_credential(server, account_id, params, type)
136
141
  else
137
- create_credential(server, params)
142
+ create_credential(server, account_id, params)
138
143
  end
139
144
 
140
145
  handle_result_for('ECR', response)
@@ -156,11 +161,12 @@ module Uffizzi
156
161
  type: type,
157
162
  }
158
163
  server = ConfigFile.read_option(:server)
164
+ account_id = ConfigFile.read_option(:account_id)
159
165
 
160
166
  response = if credential_exists
161
- update_credential(server, params, type)
167
+ update_credential(server, account_id, params, type)
162
168
  else
163
- create_credential(server, params)
169
+ create_credential(server, account_id, params)
164
170
  end
165
171
 
166
172
  handle_result_for('GCR', response)
@@ -185,11 +191,12 @@ module Uffizzi
185
191
  type: type,
186
192
  }
187
193
  server = ConfigFile.read_option(:server)
194
+ account_id = ConfigFile.read_option(:account_id)
188
195
 
189
196
  response = if credential_exists
190
- update_credential(server, params, type)
197
+ update_credential(server, account_id, params, type)
191
198
  else
192
- create_credential(server, params)
199
+ create_credential(server, account_id, params)
193
200
  end
194
201
 
195
202
  handle_result_for('GHCR', response)
@@ -221,8 +228,15 @@ module Uffizzi
221
228
 
222
229
  def credential_exists?(type)
223
230
  server = ConfigFile.read_option(:server)
224
- response = check_credential(server, type)
225
- !ResponseHelper.ok?(response)
231
+ account_id = ConfigFile.read_option(:account_id)
232
+ response = check_credential(server, account_id, type)
233
+ return false if ResponseHelper.ok?(response)
234
+ return true if ResponseHelper.unprocessable_entity?(response)
235
+
236
+ if ResponseHelper.forbidden?(response)
237
+ Uffizzi.ui.say('Unauthorized. Skipping credentials action.')
238
+ exit(true)
239
+ end
226
240
  end
227
241
 
228
242
  def handle_existing_credential_options(credential_type_slug)
@@ -24,7 +24,7 @@ module Uffizzi
24
24
  raise Uffizzi::Error.new('Unsupported credential type.')
25
25
  end
26
26
 
27
- response = delete_credential(ConfigFile.read_option(:server), connection_type)
27
+ response = delete_credential(ConfigFile.read_option(:server), ConfigFile.read_option(:account_id), connection_type)
28
28
 
29
29
  if ResponseHelper.no_content?(response)
30
30
  Uffizzi.ui.say("Successfully disconnected from #{connection_name(credential_type)}.")
@@ -34,17 +34,17 @@ module Uffizzi
34
34
 
35
35
  def set_server
36
36
  config_server = ConfigFile.exists? ? read_option_from_config(:server) : nil
37
- server_address = @options[:server] || config_server || Uffizzi.ui.ask('Server: ')
37
+ server_address = (@options[:server] || config_server || Uffizzi.ui.ask('Server:')).sub(/\/+$/, '')
38
38
  server_address.start_with?('http:', 'https:') ? server_address : "https://#{server_address}"
39
39
  end
40
40
 
41
41
  def set_username
42
42
  config_username = ConfigFile.exists? ? read_option_from_config(:username) : nil
43
- @options[:username] || config_username || Uffizzi.ui.ask('Username: ')
43
+ @options[:username] || config_username || Uffizzi.ui.ask('Username:')
44
44
  end
45
45
 
46
46
  def set_password
47
- ENV['UFFIZZI_PASSWORD'] || Uffizzi.ui.ask('Password: ', echo: false)
47
+ ENV['UFFIZZI_PASSWORD'] || Uffizzi.ui.ask('Password:', echo: false)
48
48
  end
49
49
 
50
50
  def read_option_from_config(option)
@@ -61,6 +61,7 @@ module Uffizzi
61
61
  end
62
62
 
63
63
  def handle_succeed_response(response, server, username)
64
+ # TODO Choose a personal account
64
65
  account = response[:body][:user][:accounts].first
65
66
  return Uffizzi.ui.say('No account related to this email') unless account_valid?(account)
66
67
 
@@ -95,9 +96,11 @@ module Uffizzi
95
96
  end
96
97
  all_choices = choices + [{ name: 'Create a new project', value: nil }]
97
98
  answer = Uffizzi.prompt.select(question, all_choices)
98
- return ConfigFile.write_option(:project, answer) if answer
99
+ return create_new_project(server) unless answer
99
100
 
100
- create_new_project(server)
101
+ account_id = projects.detect { |project| project[:slug] == answer }[:account_id]
102
+ ConfigFile.write_option(:project, answer)
103
+ ConfigFile.write_option(:account_id, account_id)
101
104
  end
102
105
 
103
106
  def create_new_project(server)
@@ -116,7 +119,8 @@ module Uffizzi
116
119
  },
117
120
  }
118
121
 
119
- response = create_project(server, params)
122
+ account_id = ConfigFile.read_option(:account_id)
123
+ response = create_project(server, account_id, params)
120
124
 
121
125
  if ResponseHelper.created?(response)
122
126
  handle_create_project_succeess(response)
@@ -139,6 +143,7 @@ module Uffizzi
139
143
  project = response[:body][:project]
140
144
 
141
145
  ConfigFile.write_option(:project, project[:slug])
146
+ ConfigFile.write_option(:account_id, project[:account_id])
142
147
 
143
148
  Uffizzi.ui.say("Project #{project[:name]} was successfully created")
144
149
  end
@@ -0,0 +1,47 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'uffizzi'
4
+ require 'uffizzi/response_helper'
5
+ require 'uffizzi/clients/api/api_client'
6
+
7
+ module Uffizzi
8
+ class Cli::LoginByIdentityToken
9
+ include ApiClient
10
+
11
+ def initialize(options)
12
+ @options = options
13
+ end
14
+
15
+ def run
16
+ token = @options[:token]
17
+ server = @options[:server]
18
+ params = prepare_request_params(token)
19
+ response = create_ci_session(server, params)
20
+
21
+ if ResponseHelper.created?(response)
22
+ handle_succeed_response(response, server)
23
+ else
24
+ ResponseHelper.handle_failed_response(response)
25
+ end
26
+ end
27
+
28
+ private
29
+
30
+ def prepare_request_params(token)
31
+ {
32
+ user: {
33
+ token: token,
34
+ },
35
+ }
36
+ end
37
+
38
+ def handle_succeed_response(response, server)
39
+ ConfigFile.write_option(:server, server)
40
+ ConfigFile.write_option(:cookie, response[:headers])
41
+ ConfigFile.write_option(:account_id, response[:body][:account_id])
42
+ ConfigFile.write_option(:project, response[:body][:project_slug])
43
+
44
+ Uffizzi.ui.say('Successful Login by Identity Token')
45
+ end
46
+ end
47
+ end
@@ -12,19 +12,24 @@ module Uffizzi
12
12
  desc 'service', 'Show the preview services info'
13
13
  require_relative 'preview/service'
14
14
  subcommand 'service', Uffizzi::Cli::Preview::Service
15
+
15
16
  desc 'list', 'List all previews'
17
+ method_option :filter, required: false, type: :string, aliases: '-f'
18
+ method_option :output, required: false, type: :string, aliases: '-o', enum: ['json', 'pretty-json']
16
19
  def list
17
20
  run('list')
18
21
  end
19
22
 
20
23
  desc 'create [COMPOSE_FILE]', 'Create a preview'
21
24
  method_option :output, required: false, type: :string, aliases: '-o', enum: ['json', 'github-action']
25
+ method_option :"set-labels", required: false, type: :string, aliases: '-s'
22
26
  def create(file_path = nil)
23
27
  run('create', file_path: file_path)
24
28
  end
25
29
 
26
30
  desc 'uffizzi preview update [DEPLOYMENT_ID] [COMPOSE_FILE]', 'Update a preview'
27
31
  method_option :output, required: false, type: :string, aliases: '-o', enum: ['json', 'github-action']
32
+ method_option :"set-labels", required: false, type: :string, aliases: '-s'
28
33
  def update(deployment_name, file_path)
29
34
  run('update', deployment_name: deployment_name, file_path: file_path)
30
35
  end
@@ -47,10 +52,7 @@ module Uffizzi
47
52
  private
48
53
 
49
54
  def run(command, file_path: nil, deployment_name: nil)
50
- unless options[:output].nil?
51
- Uffizzi.ui.output_format = options[:output]
52
- Uffizzi.ui.disable_stdout
53
- end
55
+ Uffizzi.ui.output_format = options[:output]
54
56
  raise Uffizzi::Error.new('You are not logged in.') unless Uffizzi::AuthHelper.signed_in?
55
57
  raise Uffizzi::Error.new('This command needs project to be set in config file') unless CommandService.project_set?(options)
56
58
 
@@ -58,11 +60,11 @@ module Uffizzi
58
60
 
59
61
  case command
60
62
  when 'list'
61
- handle_list_command(project_slug)
63
+ handle_list_command(project_slug, options[:filter])
62
64
  when 'create'
63
- handle_create_command(file_path, project_slug)
65
+ handle_create_command(file_path, project_slug, options[:"set-labels"])
64
66
  when 'update'
65
- handle_update_command(deployment_name, file_path, project_slug)
67
+ handle_update_command(deployment_name, file_path, project_slug, options[:"set-labels"])
66
68
  when 'delete'
67
69
  handle_delete_command(deployment_name, project_slug)
68
70
  when 'describe'
@@ -72,8 +74,9 @@ module Uffizzi
72
74
  end
73
75
  end
74
76
 
75
- def handle_list_command(project_slug)
76
- response = fetch_deployments(ConfigFile.read_option(:server), project_slug)
77
+ def handle_list_command(project_slug, filter)
78
+ parsed_filter = filter.nil? ? {} : build_filter_params(filter)
79
+ response = fetch_deployments(ConfigFile.read_option(:server), project_slug, parsed_filter)
77
80
 
78
81
  if ResponseHelper.ok?(response)
79
82
  handle_succeed_list_response(response)
@@ -82,8 +85,11 @@ module Uffizzi
82
85
  end
83
86
  end
84
87
 
85
- def handle_create_command(file_path, project_slug)
86
- params = file_path.nil? ? {} : prepare_params(file_path)
88
+ def handle_create_command(file_path, project_slug, labels)
89
+ Uffizzi.ui.disable_stdout unless options[:output].nil?
90
+
91
+ params = prepare_params(file_path, labels)
92
+
87
93
  response = create_deployment(ConfigFile.read_option(:server), project_slug, params)
88
94
 
89
95
  if !ResponseHelper.created?(response)
@@ -101,12 +107,13 @@ module Uffizzi
101
107
  handle_preview_interruption(deployment_id, ConfigFile.read_option(:server), project_slug)
102
108
  end
103
109
 
104
- def handle_update_command(deployment_name, file_path, project_slug)
110
+ def handle_update_command(deployment_name, file_path, project_slug, labels)
111
+ Uffizzi.ui.disable_stdout unless options[:output].nil?
105
112
  deployment_id = PreviewService.read_deployment_id(deployment_name)
106
113
 
107
114
  raise Uffizzi::Error.new("Preview should be specified in 'deployment-PREVIEW_ID' format") if deployment_id.nil?
108
115
 
109
- params = prepare_params(file_path)
116
+ params = prepare_params(file_path, labels)
110
117
  response = update_deployment(ConfigFile.read_option(:server), project_slug, deployment_id, params)
111
118
 
112
119
  if !ResponseHelper.ok?(response)
@@ -139,7 +146,8 @@ module Uffizzi
139
146
  end
140
147
 
141
148
  def handle_succeed_events_response(response)
142
- Uffizzi.ui.pretty_say(response[:body][:events])
149
+ Uffizzi.ui.output_format = Uffizzi::UI::Shell::PRETTY_JSON
150
+ Uffizzi.ui.say(response[:body][:events])
143
151
  end
144
152
 
145
153
  def handle_delete_command(deployment_name, project_slug)
@@ -174,9 +182,12 @@ module Uffizzi
174
182
  deployments = response[:body][:deployments] || []
175
183
  raise Uffizzi::Error.new('The project has no active deployments') if deployments.empty?
176
184
 
177
- deployments.each do |deployment|
178
- Uffizzi.ui.say("deployment-#{deployment[:id]}")
185
+ if Uffizzi.ui.output_format.nil?
186
+ deployments = deployments.reduce('') do |acc, deployment|
187
+ "#{acc}deployment-#{deployment[:id]}\n"
188
+ end.strip
179
189
  end
190
+ Uffizzi.ui.say(deployments)
180
191
  end
181
192
 
182
193
  def handle_succeed_delete_response(deployment_id)
@@ -192,9 +203,8 @@ module Uffizzi
192
203
 
193
204
  container
194
205
  end
195
- deployment.each_key do |key|
196
- Uffizzi.ui.say("#{key}: #{deployment[key]}")
197
- end
206
+ deployment_data = deployment.reduce('') { |acc, (key, value)| "#{acc}#{key}: #{value}\n" }.strip
207
+ Uffizzi.ui.say(deployment_data)
198
208
  end
199
209
 
200
210
  def hide_secrets(secret_variables)
@@ -205,26 +215,10 @@ module Uffizzi
205
215
  end
206
216
  end
207
217
 
208
- def prepare_params(file_path)
209
- begin
210
- compose_file_data = EnvVariablesService.substitute_env_variables(File.read(file_path))
211
- rescue Errno::ENOENT => e
212
- raise Uffizzi::Error.new(e.message)
213
- end
214
-
215
- compose_file_dir = File.dirname(file_path)
216
- dependencies = ComposeFileService.parse(compose_file_data, compose_file_dir)
217
- absolute_path = File.absolute_path(file_path)
218
- compose_file_params = {
219
- path: absolute_path,
220
- content: Base64.encode64(compose_file_data),
221
- source: absolute_path,
222
- }
223
-
224
- {
225
- compose_file: compose_file_params,
226
- dependencies: dependencies,
227
- }
218
+ def prepare_params(file_path, labels)
219
+ compose_file_params = file_path.nil? ? {} : build_compose_file_params(file_path)
220
+ metadata_params = labels.nil? ? {} : build_metadata_params(labels)
221
+ compose_file_params.merge(metadata_params)
228
222
  end
229
223
 
230
224
  def handle_preview_interruption(deployment_id, server, project_slug)
@@ -246,15 +240,83 @@ module Uffizzi
246
240
  Uffizzi.ui.say(preview_url) if success
247
241
  else
248
242
  deployment_data = build_deployment_data(deployment)
249
- Uffizzi.ui.output(deployment_data)
243
+ Uffizzi.ui.enable_stdout
244
+ Uffizzi.ui.say(deployment_data)
250
245
  end
251
246
  end
252
247
 
253
248
  def build_deployment_data(deployment)
249
+ url_server = ConfigFile.read_option(:server)
250
+
254
251
  {
255
252
  id: "deployment-#{deployment[:id]}",
256
253
  url: "https://#{deployment[:preview_url]}",
254
+ containers_uri: "#{url_server}/projects/#{deployment[:project_id]}/deployments/#{deployment[:id]}/containers",
257
255
  }
258
256
  end
257
+
258
+ def build_compose_file_params(file_path)
259
+ begin
260
+ compose_file_data = EnvVariablesService.substitute_env_variables(File.read(file_path))
261
+ rescue Errno::ENOENT => e
262
+ raise Uffizzi::Error.new(e.message)
263
+ end
264
+
265
+ compose_file_dir = File.dirname(file_path)
266
+ dependencies = ComposeFileService.parse(compose_file_data, compose_file_dir)
267
+ absolute_path = File.absolute_path(file_path)
268
+ compose_file_params = {
269
+ path: absolute_path,
270
+ content: Base64.encode64(compose_file_data),
271
+ source: absolute_path,
272
+ }
273
+
274
+ {
275
+ compose_file: compose_file_params,
276
+ dependencies: dependencies,
277
+ }
278
+ end
279
+
280
+ def build_metadata_params(labels)
281
+ {
282
+ metadata: {
283
+ 'labels' => parse_params(labels, 'Labels'),
284
+ },
285
+ }
286
+ end
287
+
288
+ def build_filter_params(filter_params)
289
+ {
290
+ 'labels' => parse_params(filter_params, 'Filtering parameters'),
291
+ }
292
+ end
293
+
294
+ def parse_params(params, params_type)
295
+ validate_params(params, params_type)
296
+ params.split(' ').reduce({}) do |acc, param|
297
+ stringified_keys, value = param.split('=', 2)
298
+ keys = stringified_keys.split('.', -1)
299
+ inner_pair = { keys.pop => value }
300
+ prepared_param = keys.reverse.reduce(inner_pair) { |res, key| { key => res } }
301
+ merge_params(acc, prepared_param)
302
+ end
303
+ end
304
+
305
+ def validate_params(params, params_type)
306
+ params.split(' ').each do |param|
307
+ stringified_keys, value = param.split('=', 2)
308
+ raise Uffizzi::Error.new("#{params_type} were set in incorrect format.") if value.nil? || stringified_keys.nil? || value.empty?
309
+
310
+ keys = stringified_keys.split('.', -1)
311
+ raise Uffizzi::Error.new("#{params_type} were set in incorrect format.") if keys.empty? || keys.any?(&:empty?)
312
+ end
313
+ end
314
+
315
+ def merge_params(result, param)
316
+ key = param.keys.first
317
+ return result.merge(param) unless result.has_key?(key)
318
+
319
+ { key => result[key].merge(merge_params(result[key], param[key])) }
320
+ end
259
321
  end
260
322
  end
@@ -102,12 +102,13 @@ module Uffizzi
102
102
  raise Uffizzi::Error.new('Slug must not content spaces or special characters') unless slug.match?(/^[a-zA-Z0-9\-_]+\Z/i)
103
103
 
104
104
  server = ConfigFile.read_option(:server)
105
+ account_id = ConfigFile.read_option(:account_id)
105
106
  params = {
106
107
  name: name,
107
108
  description: options[:description],
108
109
  slug: slug,
109
110
  }
110
- response = create_project(server, params)
111
+ response = create_project(server, account_id, params)
111
112
 
112
113
  if ResponseHelper.created?(response)
113
114
  handle_create_success_response(response)
@@ -165,6 +166,7 @@ module Uffizzi
165
166
 
166
167
  def set_default_project(project)
167
168
  ConfigFile.write_option(:project, project[:slug])
169
+ ConfigFile.write_option(:account_id, project[:account_id])
168
170
  end
169
171
  end
170
172
  end
data/lib/uffizzi/cli.rb CHANGED
@@ -24,6 +24,14 @@ module Uffizzi
24
24
  Login.new(options).run
25
25
  end
26
26
 
27
+ desc 'login_by_identity_token [OPTIONS]', 'Login or register to Uffizzi to view and manage your previews'
28
+ method_option :server, required: true, aliases: '-s'
29
+ method_option :token, required: true, aliases: '-t'
30
+ def login_by_identity_token
31
+ require_relative 'cli/login_by_identity_token'
32
+ LoginByIdentityToken.new(options).run
33
+ end
34
+
27
35
  desc 'logout', 'Log out of a Uffizzi user account'
28
36
  def logout
29
37
  require_relative 'cli/logout'
@@ -13,6 +13,13 @@ module ApiClient
13
13
  build_response(response)
14
14
  end
15
15
 
16
+ def create_ci_session(server, params = {})
17
+ uri = ci_session_uri(server)
18
+ response = http_client.make_post_request(uri, params)
19
+
20
+ build_response(response)
21
+ end
22
+
16
23
  def destroy_session(server)
17
24
  uri = session_uri(server)
18
25
  response = http_client.make_delete_request(uri)
@@ -27,16 +34,16 @@ module ApiClient
27
34
  build_response(response)
28
35
  end
29
36
 
30
- def fetch_credentials(server)
31
- uri = credentials_uri(server)
37
+ def fetch_credentials(server, account_id)
38
+ uri = credentials_uri(server, account_id)
32
39
 
33
40
  response = http_client.make_get_request(uri)
34
41
 
35
42
  build_response(response)
36
43
  end
37
44
 
38
- def check_credential(server, type)
39
- uri = check_credential_uri(server, type)
45
+ def check_credential(server, account_id, type)
46
+ uri = check_credential_uri(server, account_id, type)
40
47
  response = http_client.make_get_request(uri)
41
48
 
42
49
  build_response(response)
@@ -49,8 +56,8 @@ module ApiClient
49
56
  build_response(response)
50
57
  end
51
58
 
52
- def create_project(server, params)
53
- uri = projects_uri(server)
59
+ def create_project(server, account_id, params)
60
+ uri = create_projects_uri(server, account_id)
54
61
  response = http_client.make_post_request(uri, params)
55
62
 
56
63
  build_response(response)
@@ -63,15 +70,15 @@ module ApiClient
63
70
  build_response(response)
64
71
  end
65
72
 
66
- def create_credential(server, params)
67
- uri = credentials_uri(server)
73
+ def create_credential(server, account_id, params)
74
+ uri = credentials_uri(server, account_id)
68
75
  response = http_client.make_post_request(uri, params)
69
76
 
70
77
  build_response(response)
71
78
  end
72
79
 
73
- def update_credential(server, params, type)
74
- uri = credential_uri(server, type)
80
+ def update_credential(server, account_id, params, type)
81
+ uri = credential_uri(server, account_id, type)
75
82
  response = http_client.make_put_request(uri, params)
76
83
 
77
84
  build_response(response)
@@ -84,8 +91,8 @@ module ApiClient
84
91
  build_response(response)
85
92
  end
86
93
 
87
- def delete_credential(server, credential_type)
88
- uri = credential_uri(server, credential_type)
94
+ def delete_credential(server, account_id, credential_type)
95
+ uri = credential_uri(server, account_id, credential_type)
89
96
  response = http_client.make_delete_request(uri)
90
97
 
91
98
  build_response(response)
@@ -147,8 +154,8 @@ module ApiClient
147
154
  build_response(response)
148
155
  end
149
156
 
150
- def fetch_deployments(server, project_slug)
151
- uri = deployments_uri(server, project_slug)
157
+ def fetch_deployments(server, project_slug, filter)
158
+ uri = deployments_uri(server, project_slug, filter)
152
159
  response = http_client.make_get_request(uri)
153
160
 
154
161
  build_response(response)
@@ -15,6 +15,10 @@ module ApiRoutes
15
15
  "#{server}/api/cli/v1/projects"
16
16
  end
17
17
 
18
+ def create_projects_uri(server, account_id)
19
+ "#{server}/api/cli/v1/accounts/#{account_id}/projects"
20
+ end
21
+
18
22
  def secret_uri(server, project_slug, id)
19
23
  path_id = CGI.escape(id)
20
24
  "#{server}/api/cli/v1/projects/#{project_slug}/secrets/#{path_id}"
@@ -28,12 +32,18 @@ module ApiRoutes
28
32
  "#{server}/api/cli/v1/session"
29
33
  end
30
34
 
35
+ def ci_session_uri(server)
36
+ "#{server}/api/cli/v1/ci/session"
37
+ end
38
+
31
39
  def validate_compose_file_uri(server, project_slug)
32
40
  "#{compose_files_uri(server, project_slug)}/validate"
33
41
  end
34
42
 
35
- def deployments_uri(server, project_slug)
36
- "#{server}/api/cli/v1/projects/#{project_slug}/deployments"
43
+ def deployments_uri(server, project_slug, filter = nil)
44
+ return "#{server}/api/cli/v1/projects/#{project_slug}/deployments" if filter.nil?
45
+
46
+ "#{server}/api/cli/v1/projects/#{project_slug}/deployments?q=#{filter.to_json}"
37
47
  end
38
48
 
39
49
  def deployment_uri(server, project_slug, deployment_id)
@@ -52,20 +62,20 @@ module ApiRoutes
52
62
  "#{server}/api/cli/v1/projects/#{project_slug}/deployments/#{deployment_id}/events"
53
63
  end
54
64
 
55
- def check_credential_uri(server, type)
56
- "#{server}/api/cli/v1/account/credentials/#{type}/check_credential"
65
+ def check_credential_uri(server, account_id, type)
66
+ "#{server}/api/cli/v1/accounts/#{account_id}/credentials/#{type}/check_credential"
57
67
  end
58
68
 
59
- def credentials_uri(server)
60
- "#{server}/api/cli/v1/account/credentials"
69
+ def credentials_uri(server, account_id)
70
+ "#{server}/api/cli/v1/accounts/#{account_id}/credentials"
61
71
  end
62
72
 
63
73
  def preview_services_uri(server, project_slug, deployment_id)
64
74
  "#{server}/api/cli/v1/projects/#{project_slug}/deployments/#{deployment_id}/containers"
65
75
  end
66
76
 
67
- def credential_uri(server, credential_type)
68
- "#{server}/api/cli/v1/account/credentials/#{credential_type}"
77
+ def credential_uri(server, account_id, credential_type)
78
+ "#{server}/api/cli/v1/accounts/#{account_id}/credentials/#{credential_type}"
69
79
  end
70
80
 
71
81
  def preview_service_logs_uri(server, project_slug, deployment_id, container_name)
@@ -50,13 +50,13 @@ module Uffizzi
50
50
  headers = { 'Content-Type' => 'application/json' }
51
51
  request = case method
52
52
  when :get
53
- Net::HTTP::Get.new(uri.path, headers)
53
+ Net::HTTP::Get.new(uri.request_uri, headers)
54
54
  when :post
55
- Net::HTTP::Post.new(uri.path, headers)
55
+ Net::HTTP::Post.new(uri.request_uri, headers)
56
56
  when :delete
57
- Net::HTTP::Delete.new(uri.path, headers)
57
+ Net::HTTP::Delete.new(uri.request_uri, headers)
58
58
  when :put
59
- Net::HTTP::Put.new(uri.path, headers)
59
+ Net::HTTP::Put.new(uri.request_uri, headers)
60
60
  end
61
61
  if request.instance_of?(Net::HTTP::Post) || request.instance_of?(Net::HTTP::Put)
62
62
  request.body = params.to_json
@@ -24,6 +24,7 @@ class ProjectService
24
24
  Uffizzi.ui.say("Project name: #{project[:name]}")
25
25
  Uffizzi.ui.say("Project slug: #{project[:slug]}")
26
26
  Uffizzi.ui.say("Description: #{project[:description]}".strip)
27
+ Uffizzi.ui.say("Account name: #{project[:account][:name]}".strip)
27
28
  Uffizzi.ui.say("Created: #{project[:created_at]}")
28
29
  default_compose = project[:default_compose].nil? ? nil : project[:default_compose][:source]
29
30
  Uffizzi.ui.say("Default compose: #{default_compose}".strip)
data/lib/uffizzi/shell.rb CHANGED
@@ -7,12 +7,26 @@ module Uffizzi
7
7
  class Shell
8
8
  attr_accessor :output_format
9
9
 
10
+ PRETTY_JSON = 'pretty-json'
11
+ REGULAR_JSON = 'json'
12
+ GITHUB_ACTION = 'github-action'
13
+
10
14
  def initialize
11
15
  @shell = Thor::Shell::Basic.new
12
16
  end
13
17
 
14
18
  def say(message)
15
- @shell.say(message)
19
+ formatted_message = case output_format
20
+ when PRETTY_JSON
21
+ format_to_pretty_json(message)
22
+ when REGULAR_JSON
23
+ format_to_json(message)
24
+ when GITHUB_ACTION
25
+ format_to_github_action(message)
26
+ else
27
+ message
28
+ end
29
+ @shell.say(formatted_message)
16
30
  end
17
31
 
18
32
  def print_in_columns(messages)
@@ -34,33 +48,28 @@ module Uffizzi
34
48
  @shell.send(:stdout).string.strip
35
49
  end
36
50
 
37
- def pretty_say(collection, index = true)
38
- ap(collection, { index: index })
39
- end
40
-
41
51
  def disable_stdout
42
52
  $stdout = StringIO.new
43
53
  end
44
54
 
45
- def output(data)
55
+ def enable_stdout
46
56
  $stdout = IO.new(1, 'w')
47
- json_format? ? output_in_json(data) : output_in_github_format(data)
48
57
  end
49
58
 
50
59
  private
51
60
 
52
- def json_format?
53
- output_format == 'json'
61
+ def format_to_json(data)
62
+ data.to_json
54
63
  end
55
64
 
56
- def output_in_json(data)
57
- say(data.to_json)
65
+ def format_to_pretty_json(data)
66
+ JSON.pretty_generate(data)
58
67
  end
59
68
 
60
- def output_in_github_format(data)
61
- data.each_key do |key|
62
- say("::set-output name=#{key}::#{data[key]}")
63
- end
69
+ def format_to_github_action(data)
70
+ return '' unless data.is_a?(Hash)
71
+
72
+ data.reduce('') { |acc, (key, value)| "#{acc}::set-output name=#{key}::#{value}\n" }
64
73
  end
65
74
  end
66
75
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Uffizzi
4
- VERSION = '0.12.0'
4
+ VERSION = '1.0.1'
5
5
  end
@@ -0,0 +1,29 @@
1
+ .\" generated with Ronn-NG/v0.9.1
2
+ .\" http://github.com/apjanke/ronn-ng/tree/0.9.1
3
+ .TH "UFFIZZI\-LOGIN\-BY\-IDENTITY\-TOKEN" "" "August 2022" ""
4
+ .SH "NAME"
5
+ \fBuffizzi\-login\-by\-identity\-token\fR \- login to Uffizzi using a OIDC token provided by a CI/CD pipeline
6
+ .SH "SYNOPSIS"
7
+ .nf
8
+ uffizzi uffizzi\-login\-by\-identity\-token [UFFIZZI_WIDE_FLAG \|\.\|\.\|\.]
9
+ .fi
10
+ .SH "DESCRIPTION"
11
+ .nf
12
+ The uffizzi login command lets you authenticate with Uffizzi from a CI/CD pipeline\.
13
+ If a user/account do not exist, Uffizzi will create them based on token payload\.
14
+
15
+ For more information on authentication and credential types, see:
16
+ https://github\.com/UffizziCloud/uffizzi_cli
17
+ .fi
18
+ .SH "UFFIZZI WIDE FLAGS"
19
+ .nf
20
+ These flags are available to all commands: \-\-project\. Run $ uffizzi
21
+ help for details\.
22
+ .fi
23
+ .SH "EXAMPLES"
24
+ .nf
25
+ To login from the CI/CD pipeline, run:
26
+
27
+ $ uffizzi uffizzi\-login\-by\-identity\-token \-\-server=uffizzi\.example\.com \-\-token=[$CI_JOB_TOKEN]
28
+ .fi
29
+
@@ -0,0 +1,106 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <meta http-equiv='content-type' content='text/html;charset=utf8'>
5
+ <meta name='generator' content='Ronn-NG/v0.9.1 (http://github.com/apjanke/ronn-ng/tree/0.9.1)'>
6
+ <title>login to Uffizzi using a OIDC token provided by a CI/CD pipeline</title>
7
+ <style type='text/css' media='all'>
8
+ /* style: man */
9
+ body#manpage {margin:0}
10
+ .mp {max-width:100ex;padding:0 9ex 1ex 4ex}
11
+ .mp p,.mp pre,.mp ul,.mp ol,.mp dl {margin:0 0 20px 0}
12
+ .mp h2 {margin:10px 0 0 0}
13
+ .mp > p,.mp > pre,.mp > ul,.mp > ol,.mp > dl {margin-left:8ex}
14
+ .mp h3 {margin:0 0 0 4ex}
15
+ .mp dt {margin:0;clear:left}
16
+ .mp dt.flush {float:left;width:8ex}
17
+ .mp dd {margin:0 0 0 9ex}
18
+ .mp h1,.mp h2,.mp h3,.mp h4 {clear:left}
19
+ .mp pre {margin-bottom:20px}
20
+ .mp pre+h2,.mp pre+h3 {margin-top:22px}
21
+ .mp h2+pre,.mp h3+pre {margin-top:5px}
22
+ .mp img {display:block;margin:auto}
23
+ .mp h1.man-title {display:none}
24
+ .mp,.mp code,.mp pre,.mp tt,.mp kbd,.mp samp,.mp h3,.mp h4 {font-family:monospace;font-size:14px;line-height:1.42857142857143}
25
+ .mp h2 {font-size:16px;line-height:1.25}
26
+ .mp h1 {font-size:20px;line-height:2}
27
+ .mp {text-align:justify;background:#fff}
28
+ .mp,.mp code,.mp pre,.mp pre code,.mp tt,.mp kbd,.mp samp {color:#131211}
29
+ .mp h1,.mp h2,.mp h3,.mp h4 {color:#030201}
30
+ .mp u {text-decoration:underline}
31
+ .mp code,.mp strong,.mp b {font-weight:bold;color:#131211}
32
+ .mp em,.mp var {font-style:italic;color:#232221;text-decoration:none}
33
+ .mp a,.mp a:link,.mp a:hover,.mp a code,.mp a pre,.mp a tt,.mp a kbd,.mp a samp {color:#0000ff}
34
+ .mp b.man-ref {font-weight:normal;color:#434241}
35
+ .mp pre {padding:0 4ex}
36
+ .mp pre code {font-weight:normal;color:#434241}
37
+ .mp h2+pre,h3+pre {padding-left:0}
38
+ ol.man-decor,ol.man-decor li {margin:3px 0 10px 0;padding:0;float:left;width:33%;list-style-type:none;text-transform:uppercase;color:#999;letter-spacing:1px}
39
+ ol.man-decor {width:100%}
40
+ ol.man-decor li.tl {text-align:left}
41
+ ol.man-decor li.tc {text-align:center;letter-spacing:4px}
42
+ ol.man-decor li.tr {text-align:right;float:right}
43
+ </style>
44
+ </head>
45
+ <!--
46
+ The following styles are deprecated and will be removed at some point:
47
+ div#man, div#man ol.man, div#man ol.head, div#man ol.man.
48
+
49
+ The .man-page, .man-decor, .man-head, .man-foot, .man-title, and
50
+ .man-navigation should be used instead.
51
+ -->
52
+ <body id='manpage'>
53
+ <div class='mp' id='man'>
54
+
55
+ <div class='man-navigation' style='display:none'>
56
+ <a href="#NAME">NAME</a>
57
+ <a href="#SYNOPSIS">SYNOPSIS</a>
58
+ <a href="#DESCRIPTION">DESCRIPTION</a>
59
+ <a href="#UFFIZZI-WIDE-FLAGS">UFFIZZI WIDE FLAGS</a>
60
+ <a href="#EXAMPLES">EXAMPLES</a>
61
+ </div>
62
+
63
+ <ol class='man-decor man-head man head'>
64
+ <li class='tl'>uffizzi-login-by-identity-token</li>
65
+ <li class='tc'></li>
66
+ <li class='tr'>uffizzi-login-by-identity-token</li>
67
+ </ol>
68
+
69
+
70
+
71
+ <h2 id="NAME">NAME</h2>
72
+ <p class="man-name">
73
+ <code>uffizzi-login-by-identity-token</code> - <span class="man-whatis">login to Uffizzi using a OIDC token provided by a CI/CD pipeline</span>
74
+ </p>
75
+ <h2 id="SYNOPSIS">SYNOPSIS</h2>
76
+ <pre><code>uffizzi uffizzi-login-by-identity-token [UFFIZZI_WIDE_FLAG ...]
77
+ </code></pre>
78
+
79
+ <h2 id="DESCRIPTION">DESCRIPTION</h2>
80
+ <pre><code>The uffizzi login command lets you authenticate with Uffizzi from a CI/CD pipeline.
81
+ If a user/account do not exist, Uffizzi will create them based on token payload.
82
+
83
+ For more information on authentication and credential types, see:
84
+ https://github.com/UffizziCloud/uffizzi_cli
85
+ </code></pre>
86
+
87
+ <h2 id="UFFIZZI-WIDE-FLAGS">UFFIZZI WIDE FLAGS</h2>
88
+ <pre><code>These flags are available to all commands: --project. Run $ uffizzi
89
+ help for details.
90
+ </code></pre>
91
+
92
+ <h2 id="EXAMPLES">EXAMPLES</h2>
93
+ <pre><code>To login from the CI/CD pipeline, run:
94
+
95
+ $ uffizzi uffizzi-login-by-identity-token --server=uffizzi.example.com --token=[$CI_JOB_TOKEN]
96
+ </code></pre>
97
+
98
+ <ol class='man-decor man-foot man foot'>
99
+ <li class='tl'></li>
100
+ <li class='tc'>August 2022</li>
101
+ <li class='tr'>uffizzi-login-by-identity-token</li>
102
+ </ol>
103
+
104
+ </div>
105
+ </body>
106
+ </html>
@@ -0,0 +1,21 @@
1
+ uffizzi-login-by-identity-token - login to Uffizzi using a OIDC token provided by a CI/CD pipeline
2
+ ================================================================
3
+
4
+ ## SYNOPSIS
5
+ uffizzi uffizzi-login-by-identity-token [UFFIZZI_WIDE_FLAG ...]
6
+
7
+ ## DESCRIPTION
8
+ The uffizzi login command lets you authenticate with Uffizzi from a CI/CD pipeline.
9
+ If a user/account do not exist, Uffizzi will create them based on token payload.
10
+
11
+ For more information on authentication and credential types, see:
12
+ https://github.com/UffizziCloud/uffizzi_cli
13
+
14
+ ## UFFIZZI WIDE FLAGS
15
+ These flags are available to all commands: --project. Run $ uffizzi
16
+ help for details.
17
+
18
+ ## EXAMPLES
19
+ To login from the CI/CD pipeline, run:
20
+
21
+ $ uffizzi uffizzi-login-by-identity-token --server=uffizzi.example.com --token=[$CI_JOB_TOKEN]
@@ -1,6 +1,6 @@
1
1
  .\" generated with Ronn-NG/v0.9.1
2
2
  .\" http://github.com/apjanke/ronn-ng/tree/0.9.1
3
- .TH "UFFIZZI\-PREVIEW\-CREATE" "" "May 2022" ""
3
+ .TH "UFFIZZI\-PREVIEW\-CREATE" "" "August 2022" ""
4
4
  .SH "NAME"
5
5
  \fBuffizzi\-preview\-create\fR \- create a preview
6
6
  .SH "SYNOPSIS"
@@ -32,6 +32,12 @@ https://github\.com/UffizziCloud/uffizzi_cli
32
32
  the previews they create: when the preview is deleted, the
33
33
  alternate compose is deleted by the Uffizzi API\.
34
34
  .fi
35
+ .SH "FLAGS"
36
+ .nf
37
+ \-\-set\-labels=METADATA
38
+ Metadata of deployment that contains any information which can
39
+ be usefull for filtering deployments\.
40
+ .fi
35
41
  .SH "UFFIZZI WIDE FLAGS"
36
42
  .nf
37
43
  These flags are available to all commands: \-\-project\. Run $ uffizzi
@@ -46,5 +52,14 @@ To create a preview with the project\'s default compose file, run:
46
52
  To create a preview with an alternate compose file, run:
47
53
 
48
54
  $ uffizzi preview create docker\-compose\.uffizzi\.alt\.yml
55
+
56
+ To create a preview with single label, run:
57
+
58
+ $ uffizzi preview create \-\-set\-labels github\.repo=my_repo
59
+
60
+ To create a preview with multiple labels, run:
61
+
62
+ $ uffizzi preview create \e
63
+ \-\-set\-labels="github\.repo=my_repo github\.pull_request\.number=23"
49
64
  .fi
50
65
 
@@ -27,6 +27,11 @@ uffizzi-preview-create - create a preview
27
27
  the previews they create: when the preview is deleted, the
28
28
  alternate compose is deleted by the Uffizzi API.
29
29
 
30
+ ## FLAGS
31
+ --set-labels=METADATA
32
+ Metadata of deployment that contains any information which can
33
+ be usefull for filtering deployments.
34
+
30
35
  ## UFFIZZI WIDE FLAGS
31
36
  These flags are available to all commands: --project. Run $ uffizzi
32
37
  help for details.
@@ -39,3 +44,12 @@ uffizzi-preview-create - create a preview
39
44
  To create a preview with an alternate compose file, run:
40
45
 
41
46
  $ uffizzi preview create docker-compose.uffizzi.alt.yml
47
+
48
+ To create a preview with single label, run:
49
+
50
+ $ uffizzi preview create --set-labels github.repo=my_repo
51
+
52
+ To create a preview with multiple labels, run:
53
+
54
+ $ uffizzi preview create \
55
+ --set-labels="github.repo=my_repo github.pull_request.number=23"
@@ -1,6 +1,6 @@
1
1
  .\" generated with Ronn-NG/v0.9.1
2
2
  .\" http://github.com/apjanke/ronn-ng/tree/0.9.1
3
- .TH "UFFIZZI\-PREVIEW\-LIST" "" "May 2022" ""
3
+ .TH "UFFIZZI\-PREVIEW\-LIST" "" "September 2022" ""
4
4
  .SH "NAME"
5
5
  \fBuffizzi\-preview\-list\fR \- list previews in a project
6
6
  .SH "SYNOPSIS"
@@ -15,6 +15,15 @@ deploying and failed previews\.
15
15
  For more information on Uffizzi previews, see:
16
16
  https://github\.com/UffizziCloud/uffizzi_cli
17
17
  .fi
18
+ .SH "FLAGS"
19
+ .nf
20
+ \-\-filter=METADATA
21
+ Metadata to filtering list of deployments\.
22
+
23
+ \-\-output=pretty\-json
24
+ Use this option for a more detailed description of listed
25
+ deployments\.
26
+ .fi
18
27
  .SH "UFFIZZI WIDE FLAGS"
19
28
  .nf
20
29
  These flags are available to all commands: \-\-project\. Run $ uffizzi
@@ -29,5 +38,20 @@ To list all previews in the default project, run:
29
38
  To list all previews in a project with name my_project, run:
30
39
 
31
40
  $ uffizzi preview list \-\-project="my_project"
41
+
42
+ To list all previews in json format, run:
43
+
44
+ $ uffizzi preview list \-\-output="pretty\-json"
45
+
46
+ To list all previews filtered by metadata using single
47
+ label, run:
48
+
49
+ $ uffizzi preview list \-\-filter github\.repo=my_repo
50
+
51
+ To list all previews filtered by metadata using multiple
52
+ labels, run:
53
+
54
+ $ uffizzi preview list \e
55
+ \-\-filter="github\.repo=my_repo github\.pull_request\.number=23"
32
56
  .fi
33
57
 
@@ -11,6 +11,14 @@ uffizzi-preview-list - list previews in a project
11
11
  For more information on Uffizzi previews, see:
12
12
  https://github.com/UffizziCloud/uffizzi_cli
13
13
 
14
+ ## FLAGS
15
+ --filter=METADATA
16
+ Metadata to filtering list of deployments.
17
+
18
+ --output=pretty-json
19
+ Use this option for a more detailed description of listed
20
+ deployments.
21
+
14
22
  ## UFFIZZI WIDE FLAGS
15
23
  These flags are available to all commands: --project. Run $ uffizzi
16
24
  help for details.
@@ -23,3 +31,18 @@ uffizzi-preview-list - list previews in a project
23
31
  To list all previews in a project with name my_project, run:
24
32
 
25
33
  $ uffizzi preview list --project="my_project"
34
+
35
+ To list all previews in json format, run:
36
+
37
+ $ uffizzi preview list --output="pretty-json"
38
+
39
+ To list all previews filtered by metadata using single
40
+ label, run:
41
+
42
+ $ uffizzi preview list --filter github.repo=my_repo
43
+
44
+ To list all previews filtered by metadata using multiple
45
+ labels, run:
46
+
47
+ $ uffizzi preview list \
48
+ --filter="github.repo=my_repo github.pull_request.number=23"
@@ -1,8 +1,8 @@
1
1
  .\" generated with Ronn-NG/v0.9.1
2
2
  .\" http://github.com/apjanke/ronn-ng/tree/0.9.1
3
- .TH "UPDATE" "" "May 2022" ""
3
+ .TH "UPDATE" "" "August 2022" ""
4
4
  .SH "NAME"
5
- \fBuffizzi preview update\fR \- update a preview
5
+ \fBupdate\fR \- update a preview
6
6
  .SH "SYNOPSIS"
7
7
  .nf
8
8
  uffizzi preview update [PREVIEW_ID] [COMPOSE_FILE] [UFFIZZI_WIDE_FLAG \|\.\|\.\|\.]
@@ -27,6 +27,12 @@ https://github\.com/UffizziCloud/uffizzi_cli
27
27
  [COMPOSE_FILE]
28
28
  The new compose file you want to preview\.
29
29
  .fi
30
+ .SH "FLAGS"
31
+ .nf
32
+ \-\-set\-labels=METADATA
33
+ Metadata of deployment that contains any information which can
34
+ be usefull for filtering deployments\.
35
+ .fi
30
36
  .SH "UFFIZZI WIDE FLAGS"
31
37
  .nf
32
38
  These flags are available to all commands: \-\-project\. Run $ uffizzi
@@ -38,5 +44,17 @@ The following command updates a preview with ID deployment\-67 using
38
44
  compose file docker\-compose\.alt\.yml:
39
45
 
40
46
  $ uffizzi preview update deployment\-67 docker\-compose\.alt\.yml
47
+
48
+ To update a preview with single label, run:
49
+
50
+ $ uffizzi preview update \e
51
+ deployment\-67 docker\-compose\.alt\.yml \e
52
+ \-\-set\-labels github\.repo=my_repo
53
+
54
+ To update a preview with multiple labels, run:
55
+
56
+ $ uffizzi preview update \e
57
+ deployment\-67 docker\-compose\.alt\.yml \e
58
+ \-\-set\-labels="github\.repo=my_repo github\.pull_request\.number=23"
41
59
  .fi
42
60
 
@@ -22,6 +22,11 @@ uffizzi preview update - update a preview
22
22
  [COMPOSE_FILE]
23
23
  The new compose file you want to preview.
24
24
 
25
+ ## FLAGS
26
+ --set-labels=METADATA
27
+ Metadata of deployment that contains any information which can
28
+ be usefull for filtering deployments.
29
+
25
30
  ## UFFIZZI WIDE FLAGS
26
31
  These flags are available to all commands: --project. Run $ uffizzi
27
32
  help for details.
@@ -31,3 +36,15 @@ uffizzi preview update - update a preview
31
36
  compose file docker-compose.alt.yml:
32
37
 
33
38
  $ uffizzi preview update deployment-67 docker-compose.alt.yml
39
+
40
+ To update a preview with single label, run:
41
+
42
+ $ uffizzi preview update \
43
+ deployment-67 docker-compose.alt.yml \
44
+ --set-labels github.repo=my_repo
45
+
46
+ To update a preview with multiple labels, run:
47
+
48
+ $ uffizzi preview update \
49
+ deployment-67 docker-compose.alt.yml \
50
+ --set-labels="github.repo=my_repo github.pull_request.number=23"
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: uffizzi-cli
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.12.0
4
+ version: 1.0.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Josh Thurman
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: exe
11
11
  cert_chain: []
12
- date: 2022-08-08 00:00:00.000000000 Z
12
+ date: 2022-09-08 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: awesome_print
@@ -325,6 +325,7 @@ files:
325
325
  - lib/uffizzi/cli/connect.rb
326
326
  - lib/uffizzi/cli/disconnect.rb
327
327
  - lib/uffizzi/cli/login.rb
328
+ - lib/uffizzi/cli/login_by_identity_token.rb
328
329
  - lib/uffizzi/cli/logout.rb
329
330
  - lib/uffizzi/cli/preview.rb
330
331
  - lib/uffizzi/cli/preview/service.rb
@@ -368,6 +369,9 @@ files:
368
369
  - man/uffizzi-disconnect
369
370
  - man/uffizzi-disconnect.ronn
370
371
  - man/uffizzi-login
372
+ - man/uffizzi-login-by-identity-token
373
+ - man/uffizzi-login-by-identity-token.html
374
+ - man/uffizzi-login-by-identity-token.ronn
371
375
  - man/uffizzi-login.ronn
372
376
  - man/uffizzi-logout
373
377
  - man/uffizzi-logout.ronn