uffizzi-cli 0.12.0 → 1.0.1

Sign up to get free protection for your applications and to get access to all the features.
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