cpl 0.5.1 → 0.6.0

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: c5989a3c887eb311dcfb8bffe88e8519172b21efd21e715c363e7a166b73dbc3
4
- data.tar.gz: b9fc9896cdd99a38b89389866f0f0825cb3944099e4579f4641ee221f2302a92
3
+ metadata.gz: cfd7383099c36f633d327424fcb36561e2b925120e63f1b814158a43bd55103f
4
+ data.tar.gz: eafdf0607fe28d3c24f8132e3a116085020c94639d5b05a5accec4d4de651ca5
5
5
  SHA512:
6
- metadata.gz: c73027a84228c2371999bdff122d3bab5a3970d5f11c54f55a4b47a0fae77f83903e8d5702ecdd6baa5ac9fe6346f8e433f395a6fc3e22ee3a7225ed661038c3
7
- data.tar.gz: a2734ae8f9969be0d523dd547783284774ad461fa1dee36174a5c6bc6b653ec7a020c2c07301e31c787d5d4f7b04c4a6d983fe1e544d2d20410a54f19896d7ff
6
+ metadata.gz: b443d26a3fa91400dbb6d2e71b730a26bd1405df2f03e7f9446179323e2becb532ec69d81d93f22578fe8793dbabec9a2283efc16a107decdb5aaa9e4a615281
7
+ data.tar.gz: 34ab7670bc372af9b8991678de9d99a9c60429b3caebeeeb2775046a9be3d4a7fb7335d9cbeb3a6c2ba06bb29ef40ab7c2cffbcd20737cfb62eb4048b07a8926
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- cpl (0.5.1)
4
+ cpl (0.6.0)
5
5
  debug (~> 1.7.1)
6
6
  dotenv (~> 2.8.1)
7
7
  psych (~> 5.1.0)
@@ -20,7 +20,7 @@ GEM
20
20
  dotenv (2.8.1)
21
21
  iniparse (1.5.0)
22
22
  io-console (0.6.0)
23
- irb (1.6.3)
23
+ irb (1.6.4)
24
24
  reline (>= 0.3.0)
25
25
  json (2.6.3)
26
26
  overcommit (0.60.0)
@@ -77,7 +77,7 @@ GEM
77
77
  simplecov_json_formatter (~> 0.1)
78
78
  simplecov-html (0.12.3)
79
79
  simplecov_json_formatter (0.1.4)
80
- stringio (3.0.5)
80
+ stringio (3.0.6)
81
81
  thor (1.2.1)
82
82
  unicode-display_width (2.4.2)
83
83
 
data/docs/commands.md CHANGED
@@ -11,6 +11,30 @@ This `-a` option is used in most of the commands and will pick all other app con
11
11
 
12
12
  ### Commands
13
13
 
14
+ ### `apply-template`
15
+
16
+ - Applies application-specific configs from templates (e.g., for every review-app)
17
+ - Publishes (creates or updates) those at Control Plane infrastructure
18
+ - Picks templates from the `.controlplane/templates` directory
19
+ - Templates are ordinary Control Plane templates but with variable preprocessing
20
+
21
+ **Preprocessed template variables:**
22
+
23
+ ```
24
+ APP_GVC - basically GVC or app name
25
+ APP_LOCATION - default location
26
+ APP_ORG - organization
27
+ APP_IMAGE - will use latest app image
28
+ ```
29
+
30
+ ```sh
31
+ # Applies single template.
32
+ cpl apply-template redis -a $APP_NAME
33
+
34
+ # Applies several templates (practically creating full app).
35
+ cpl apply-template gvc postgres redis rails -a $APP_NAME
36
+ ```
37
+
14
38
  ### `build-image`
15
39
 
16
40
  - Builds and pushes the image to Control Plane
@@ -238,6 +262,13 @@ cpl run rails c -a $APP_NAME
238
262
  # Uses a different image (which may not be promoted yet).
239
263
  cpl run rails db:migrate -a $APP_NAME --image appimage:123 # Exact image name
240
264
  cpl run rails db:migrate -a $APP_NAME --image latest # Latest sequential image
265
+
266
+ # Uses a different workload
267
+ cpl run bash -a $APP_NAME -w other-workload
268
+
269
+ # Overrides remote CPLN_TOKEN env variable with local token.
270
+ # Useful when need superuser rights in remote container
271
+ cpl run bash -a $APP_NAME --use-local-token
241
272
  ```
242
273
 
243
274
  ### `run:detached`
@@ -263,30 +294,19 @@ cpl run:detached rails db:migrate -a $APP_NAME --image latest
263
294
  # Uses a different image (which may not be promoted yet).
264
295
  cpl run:detached rails db:migrate -a $APP_NAME --image appimage:123 # Exact image name
265
296
  cpl run:detached rails db:migrate -a $APP_NAME --image latest # Latest sequential image
266
- ```
267
-
268
- ### `setup`
269
297
 
270
- - Applies application-specific configs from templates (e.g., for every review-app)
271
- - Publishes (creates or updates) those at Control Plane infrastructure
272
- - Picks templates from the `.controlplane/templates` directory
273
- - Templates are ordinary Control Plane templates but with variable preprocessing
298
+ # Uses a different workload
299
+ cpl run:detached rails db:migrate:status -a $APP_NAME -w other-workload
300
+ ```
274
301
 
275
- **Preprocessed template variables:**
302
+ ### `setup-app`
276
303
 
277
- ```
278
- APP_GVC - basically GVC or app name
279
- APP_LOCATION - default location
280
- APP_ORG - organization
281
- APP_IMAGE - will use latest app image
282
- ```
304
+ - Creates an app and all its workloads
305
+ - Specify the templates for the app and workloads through `setup` in the `.controlplane/controlplane.yml` file
306
+ - This should should only be used for temporary apps like review apps, never for persistent apps like production (to update workloads for those, use 'cpl apply-template' instead)
283
307
 
284
308
  ```sh
285
- # Applies single template.
286
- cpl setup redis -a $APP_NAME
287
-
288
- # Applies several templates (practically creating full app).
289
- cpl setup gvc postgres redis rails -a $APP_NAME
309
+ cpl setup-app -a $APP_NAME
290
310
  ```
291
311
 
292
312
  ### `version`
@@ -1,12 +1,13 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Command
4
- class Setup < Base
5
- NAME = "setup"
6
- USAGE = "setup TEMPLATE [TEMPLATE] ... [TEMPLATE]"
4
+ class ApplyTemplate < Base # rubocop:disable Metrics/ClassLength
5
+ NAME = "apply-template"
6
+ USAGE = "apply-template TEMPLATE [TEMPLATE] ... [TEMPLATE]"
7
7
  REQUIRES_ARGS = true
8
8
  OPTIONS = [
9
- app_option(required: true)
9
+ app_option(required: true),
10
+ skip_confirm_option
10
11
  ].freeze
11
12
  DESCRIPTION = "Applies application-specific configs from templates"
12
13
  LONG_DESCRIPTION = <<~DESC
@@ -27,28 +28,35 @@ module Command
27
28
  EXAMPLES = <<~EX
28
29
  ```sh
29
30
  # Applies single template.
30
- cpl setup redis -a $APP_NAME
31
+ cpl apply-template redis -a $APP_NAME
31
32
 
32
33
  # Applies several templates (practically creating full app).
33
- cpl setup gvc postgres redis rails -a $APP_NAME
34
+ cpl apply-template gvc postgres redis rails -a $APP_NAME
34
35
  ```
35
36
  EX
36
37
 
37
38
  def call # rubocop:disable Metrics/MethodLength
39
+ ensure_templates!
40
+
38
41
  @app_status = :existing
39
42
  @created_workloads = []
40
43
  @failed_workloads = []
44
+ @skipped_workloads = []
41
45
 
42
- config.args.each do |template|
43
- filename = "#{config.app_cpln_dir}/templates/#{template}.yml"
46
+ @asked_for_confirmation = false
44
47
 
45
- step("Applying template '#{template}'", abort_on_error: false) do
46
- unless File.exist?(filename)
47
- report_failure(template)
48
+ pending_templates = templates.select do |template|
49
+ if template == "gvc"
50
+ confirm_app(template)
51
+ else
52
+ confirm_workload(template)
53
+ end
54
+ end
48
55
 
49
- raise "Can't find template '#{template}' at '#{filename}', please create it."
50
- end
56
+ progress.puts if @asked_for_confirmation
51
57
 
58
+ pending_templates.each do |template, filename|
59
+ step("Applying template '#{template}'", abort_on_error: false) do
52
60
  apply_template(filename)
53
61
  if $CHILD_STATUS.success?
54
62
  report_success(template)
@@ -63,10 +71,58 @@ module Command
63
71
  print_app_status
64
72
  print_created_workloads
65
73
  print_failed_workloads
74
+ print_skipped_workloads
66
75
  end
67
76
 
68
77
  private
69
78
 
79
+ def templates
80
+ @templates ||= config.args.to_h do |template|
81
+ [template, "#{config.app_cpln_dir}/templates/#{template}.yml"]
82
+ end
83
+ end
84
+
85
+ def ensure_templates!
86
+ missing_templates = templates.filter { |_template, filename| !File.exist?(filename) }.to_h
87
+ return if missing_templates.empty?
88
+
89
+ missing_templates_str = missing_templates.map do |template, filename|
90
+ " - #{template} (#{filename})"
91
+ end.join("\n")
92
+ progress.puts("#{Shell.color('Missing templates:', :red)}\n#{missing_templates_str}\n\n")
93
+
94
+ raise "Can't find templates above, please create them."
95
+ end
96
+
97
+ def confirm_apply(message)
98
+ return true if config.options[:yes]
99
+
100
+ @asked_for_confirmation = true
101
+ Shell.confirm(message)
102
+ end
103
+
104
+ def confirm_app(template)
105
+ app = cp.fetch_gvc
106
+ return true unless app
107
+
108
+ confirmed = confirm_apply("App '#{config.app}' already exists, do you want to re-create it?")
109
+ return true if confirmed
110
+
111
+ report_skipped(template)
112
+ false
113
+ end
114
+
115
+ def confirm_workload(template)
116
+ workload = cp.fetch_workload(template)
117
+ return true unless workload
118
+
119
+ confirmed = confirm_apply("Workload '#{template}' already exists, do you want to re-create it?")
120
+ return true if confirmed
121
+
122
+ report_skipped(template)
123
+ false
124
+ end
125
+
70
126
  def apply_template(filename)
71
127
  data = File.read(filename)
72
128
  .gsub("APP_GVC", config.app)
@@ -93,13 +149,24 @@ module Command
93
149
  end
94
150
  end
95
151
 
152
+ def report_skipped(template)
153
+ if template == "gvc"
154
+ @app_status = :skipped
155
+ else
156
+ @skipped_workloads.push(template)
157
+ end
158
+ end
159
+
96
160
  def print_app_status
97
161
  return if @app_status == :existing
98
162
 
99
- if @app_status == :success
163
+ case @app_status
164
+ when :success
100
165
  progress.puts("\n#{Shell.color("Created app '#{config.app}'.", :green)}")
101
- else
166
+ when :failure
102
167
  progress.puts("\n#{Shell.color("Failed to create app '#{config.app}'.", :red)}")
168
+ when :skipped
169
+ progress.puts("\n#{Shell.color("Skipped app '#{config.app}' (already exists).", :blue)}")
103
170
  end
104
171
  end
105
172
 
@@ -116,5 +183,12 @@ module Command
116
183
  workloads = @failed_workloads.map { |template| " - #{template}" }.join("\n")
117
184
  progress.puts("\n#{Shell.color('Failed to create workloads:', :red)}\n#{workloads}")
118
185
  end
186
+
187
+ def print_skipped_workloads
188
+ return unless @skipped_workloads.any?
189
+
190
+ workloads = @skipped_workloads.map { |template| " - #{template}" }.join("\n")
191
+ progress.puts("\n#{Shell.color('Skipped workloads (already exist):', :blue)}\n#{workloads}")
192
+ end
119
193
  end
120
194
  end
data/lib/command/base.rb CHANGED
@@ -142,13 +142,24 @@ module Command
142
142
  }
143
143
  end
144
144
 
145
+ def self.use_local_token_option(required: false)
146
+ {
147
+ name: :use_local_token,
148
+ params: {
149
+ desc: "Override remote CPLN_TOKEN with local token",
150
+ type: :boolean,
151
+ required: required
152
+ }
153
+ }
154
+ end
155
+
145
156
  def self.all_options
146
157
  methods.grep(/_option$/).map { |method| send(method.to_s) }
147
158
  end
148
159
 
149
160
  def self.all_options_by_key_name
150
161
  all_options.each_with_object({}) do |option, result|
151
- option[:params][:aliases].each { |current_alias| result[current_alias.to_s] = option }
162
+ option[:params][:aliases]&.each { |current_alias| result[current_alias.to_s] = option }
152
163
  result["--#{option[:name]}"] = option
153
164
  end
154
165
  end
@@ -168,7 +179,7 @@ module Command
168
179
 
169
180
  def wait_for_replica(workload, location)
170
181
  wait_for("replica") do
171
- cp.workload_get_replicas(workload, location: location)&.dig("items", 0)
182
+ cp.workload_get_replicas_safely(workload, location: location)&.dig("items", 0)
172
183
  end
173
184
  end
174
185
 
data/lib/command/run.rb CHANGED
@@ -8,7 +8,9 @@ module Command
8
8
  DEFAULT_ARGS = ["bash"].freeze
9
9
  OPTIONS = [
10
10
  app_option(required: true),
11
- image_option
11
+ image_option,
12
+ workload_option,
13
+ use_local_token_option
12
14
  ].freeze
13
15
  DESCRIPTION = "Runs one-off **_interactive_** replicas (analog of `heroku run`)"
14
16
  LONG_DESCRIPTION = <<~DESC
@@ -34,19 +36,25 @@ module Command
34
36
  # Uses a different image (which may not be promoted yet).
35
37
  cpl run rails db:migrate -a $APP_NAME --image appimage:123 # Exact image name
36
38
  cpl run rails db:migrate -a $APP_NAME --image latest # Latest sequential image
39
+
40
+ # Uses a different workload
41
+ cpl run bash -a $APP_NAME -w other-workload
42
+
43
+ # Overrides remote CPLN_TOKEN env variable with local token.
44
+ # Useful when need superuser rights in remote container
45
+ cpl run bash -a $APP_NAME --use-local-token
37
46
  ```
38
47
  EX
39
48
 
40
- attr_reader :location, :workload, :one_off
49
+ attr_reader :location, :workload, :one_off, :container
41
50
 
42
51
  def call
43
52
  @location = config[:default_location]
44
- @workload = config[:one_off_workload]
53
+ @workload = config.options["workload"] || config[:one_off_workload]
45
54
  @one_off = "#{workload}-run-#{rand(1000..9999)}"
46
55
 
47
56
  clone_workload
48
57
  wait_for_workload(one_off)
49
- sleep 2 # sometimes replica query lags workload creation, despite ok by prev query
50
58
  wait_for_replica(one_off, location)
51
59
  run_in_replica
52
60
  ensure
@@ -60,15 +68,16 @@ module Command
60
68
 
61
69
  # Create a base copy of workload props
62
70
  spec = cp.fetch_workload!(workload).fetch("spec")
63
- container = spec["containers"].detect { _1["name"] == workload } || spec["containers"].first
71
+ container_spec = spec["containers"].detect { _1["name"] == workload } || spec["containers"].first
72
+ @container = container_spec["name"]
64
73
 
65
74
  # remove other containers if any
66
- spec["containers"] = [container]
75
+ spec["containers"] = [container_spec]
67
76
 
68
77
  # Stub workload command with dummy server that just responds to port
69
78
  # Needed to avoid execution of ENTRYPOINT and CMD of Dockerfile
70
- container["command"] = "ruby"
71
- container["args"] = ["-e", Scripts.http_dummy_server_ruby]
79
+ container_spec["command"] = "ruby"
80
+ container_spec["args"] = ["-e", Scripts.http_dummy_server_ruby]
72
81
 
73
82
  # Ensure one-off workload will be running
74
83
  spec["defaultOptions"]["suspend"] = false
@@ -81,11 +90,15 @@ module Command
81
90
  # Override image if specified
82
91
  image = config.options[:image]
83
92
  image = "/org/#{config.org}/image/#{latest_image}" if image == "latest"
84
- container["image"] = image if image
93
+ container_spec["image"] = image if image
85
94
 
86
95
  # Set runner
87
- container["env"] ||= []
88
- container["env"] << { "name" => "CONTROLPLANE_RUNNER", "value" => runner_script }
96
+ container_spec["env"] ||= []
97
+ container_spec["env"] << { "name" => "CONTROLPLANE_RUNNER", "value" => runner_script }
98
+
99
+ if config.options["use_local_token"]
100
+ container_spec["env"] << { "name" => "CONTROLPLANE_TOKEN", "value" => ControlplaneApiDirect.new.api_token }
101
+ end
89
102
 
90
103
  # Create workload clone
91
104
  cp.apply("kind" => "workload", "name" => one_off, "spec" => spec)
@@ -93,6 +106,14 @@ module Command
93
106
 
94
107
  def runner_script
95
108
  script = Scripts.helpers_cleanup
109
+
110
+ if config.options["use_local_token"]
111
+ script += <<~SHELL
112
+ CPLN_TOKEN=$CONTROLPLANE_TOKEN
113
+ unset CONTROLPLANE_TOKEN
114
+ SHELL
115
+ end
116
+
96
117
  script += args_join(config.args)
97
118
  script
98
119
  end
@@ -100,7 +121,7 @@ module Command
100
121
  def run_in_replica
101
122
  progress.puts "- Connecting"
102
123
  command = %(bash -c 'eval "$CONTROLPLANE_RUNNER"')
103
- cp.workload_exec(one_off, location: location, container: workload, command: command)
124
+ cp.workload_exec(one_off, location: location, container: container, command: command)
104
125
  end
105
126
  end
106
127
  end
@@ -7,7 +7,8 @@ module Command
7
7
  REQUIRES_ARGS = true
8
8
  OPTIONS = [
9
9
  app_option(required: true),
10
- image_option
10
+ image_option,
11
+ workload_option
11
12
  ].freeze
12
13
  DESCRIPTION = "Runs one-off **_non-interactive_** replicas (close analog of `heroku run:detached`)"
13
14
  LONG_DESCRIPTION = <<~DESC
@@ -33,16 +34,19 @@ module Command
33
34
  # Uses a different image (which may not be promoted yet).
34
35
  cpl run:detached rails db:migrate -a $APP_NAME --image appimage:123 # Exact image name
35
36
  cpl run:detached rails db:migrate -a $APP_NAME --image latest # Latest sequential image
37
+
38
+ # Uses a different workload
39
+ cpl run:detached rails db:migrate:status -a $APP_NAME -w other-workload
36
40
  ```
37
41
  EX
38
42
 
39
43
  WORKLOAD_SLEEP_CHECK = 2
40
44
 
41
- attr_reader :location, :workload, :one_off
45
+ attr_reader :location, :workload, :one_off, :container
42
46
 
43
47
  def call
44
48
  @location = config[:default_location]
45
- @workload = config[:one_off_workload]
49
+ @workload = config.options["workload"] || config[:one_off_workload]
46
50
  @one_off = "#{workload}-runner-#{rand(1000..9999)}"
47
51
 
48
52
  clone_workload
@@ -60,14 +64,15 @@ module Command
60
64
 
61
65
  # Get base specs of workload
62
66
  spec = cp.fetch_workload!(workload).fetch("spec")
63
- container = spec["containers"].detect { _1["name"] == workload } || spec["containers"].first
67
+ container_spec = spec["containers"].detect { _1["name"] == workload } || spec["containers"].first
68
+ @container = container_spec["name"]
64
69
 
65
70
  # remove other containers if any
66
- spec["containers"] = [container]
71
+ spec["containers"] = [container_spec]
67
72
 
68
73
  # Set runner
69
- container["command"] = "bash"
70
- container["args"] = ["-c", 'eval "$CONTROLPLANE_RUNNER"']
74
+ container_spec["command"] = "bash"
75
+ container_spec["args"] = ["-c", 'eval "$CONTROLPLANE_RUNNER"']
71
76
 
72
77
  # Ensure one-off workload will be running
73
78
  spec["defaultOptions"]["suspend"] = false
@@ -80,17 +85,17 @@ module Command
80
85
  # Override image if specified
81
86
  image = config.options[:image]
82
87
  image = "/org/#{config.org}/image/#{latest_image}" if image == "latest"
83
- container["image"] = image if image
88
+ container_spec["image"] = image if image
84
89
 
85
90
  # Set cron job props
86
91
  spec["type"] = "cron"
87
92
  spec["job"] = { "schedule" => "* * * * *", "restartPolicy" => "Never" }
88
93
  spec["defaultOptions"]["autoscaling"] = {}
89
- container.delete("ports")
94
+ container_spec.delete("ports")
90
95
 
91
- container["env"] ||= []
92
- container["env"] << { "name" => "CONTROLPLANE_TOKEN", "value" => ControlplaneApiDirect.new.api_token }
93
- container["env"] << { "name" => "CONTROLPLANE_RUNNER", "value" => runner_script }
96
+ container_spec["env"] ||= []
97
+ container_spec["env"] << { "name" => "CONTROLPLANE_TOKEN", "value" => ControlplaneApiDirect.new.api_token }
98
+ container_spec["env"] << { "name" => "CONTROLPLANE_RUNNER", "value" => runner_script }
94
99
 
95
100
  # Create workload clone
96
101
  cp.apply("kind" => "workload", "name" => one_off, "spec" => spec)
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Command
4
+ class SetupApp < Base
5
+ NAME = "setup-app"
6
+ OPTIONS = [
7
+ app_option(required: true)
8
+ ].freeze
9
+ DESCRIPTION = "Creates an app and all its workloads"
10
+ LONG_DESCRIPTION = <<~DESC
11
+ - Creates an app and all its workloads
12
+ - Specify the templates for the app and workloads through `setup` in the `.controlplane/controlplane.yml` file
13
+ - This should should only be used for temporary apps like review apps, never for persistent apps like production (to update workloads for those, use 'cpl apply-template' instead)
14
+ DESC
15
+
16
+ def call
17
+ templates = config[:setup].join(" ")
18
+
19
+ app = cp.fetch_gvc
20
+ if app
21
+ raise "App '#{config.app}' already exists. If you want to update this app, " \
22
+ "either run 'cpl delete -a #{config.app}' and then re-run this command, " \
23
+ "or run 'cpl apply-template #{templates} -a #{config.app}'."
24
+ end
25
+
26
+ perform("cpl apply-template #{templates} -a #{config.app}")
27
+ end
28
+ end
29
+ end
@@ -130,6 +130,12 @@ class Controlplane # rubocop:disable Metrics/ClassLength
130
130
  perform_yaml(cmd)
131
131
  end
132
132
 
133
+ def workload_get_replicas_safely(workload, location:)
134
+ cmd = "cpln workload get-replicas #{workload} #{gvc_org} --location #{location} -o yaml 2> /dev/null"
135
+ result = `#{cmd}`
136
+ $CHILD_STATUS.success? ? YAML.safe_load(result) : nil
137
+ end
138
+
133
139
  def workload_set_image_ref(workload, container:, image:)
134
140
  cmd = "cpln workload update #{workload} #{gvc_org}"
135
141
  cmd += " --set spec.containers.#{container}.image=/org/#{config.org}/image/#{image}"
data/lib/cpl/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Cpl
4
- VERSION = "0.5.1"
4
+ VERSION = "0.6.0"
5
5
  end
data/lib/cpl.rb CHANGED
@@ -9,7 +9,12 @@ require "tempfile"
9
9
  require "thor"
10
10
  require "yaml"
11
11
 
12
- modules = Dir["#{__dir__}/**/*.rb"].reject { |file| file == __FILE__ || file.end_with?("main.rb") }
12
+ # We need to require base before all commands, since the commands inherit from it
13
+ require_relative "command/base"
14
+
15
+ modules = Dir["#{__dir__}/**/*.rb"].reject do |file|
16
+ file == __FILE__ || file.end_with?("main.rb") || file.end_with?("base.rb")
17
+ end
13
18
  modules.sort.each { require(_1) }
14
19
 
15
20
  # Fix for https://github.com/erikhuda/thor/issues/398
@@ -2,5 +2,6 @@
2
2
  "build": "build-image",
3
3
  "promote": "deploy-image",
4
4
  "promote_image": "deploy-image",
5
- "runner": "run:detached"
5
+ "runner": "run:detached",
6
+ "setup": "apply-template"
6
7
  }
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cpl
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.1
4
+ version: 0.6.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Justin Gordon
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2023-04-07 00:00:00.000000000 Z
12
+ date: 2023-04-27 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: debug
@@ -183,6 +183,7 @@ files:
183
183
  - examples/circleci.yml
184
184
  - examples/controlplane.yml
185
185
  - googlee2da545df05d92f9.html
186
+ - lib/command/apply_template.rb
186
187
  - lib/command/base.rb
187
188
  - lib/command/build_image.rb
188
189
  - lib/command/cleanup_old_images.rb
@@ -205,7 +206,7 @@ files:
205
206
  - lib/command/ps_stop.rb
206
207
  - lib/command/run.rb
207
208
  - lib/command/run_detached.rb
208
- - lib/command/setup.rb
209
+ - lib/command/setup_app.rb
209
210
  - lib/command/test.rb
210
211
  - lib/command/version.rb
211
212
  - lib/core/config.rb
@@ -250,7 +251,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
250
251
  - !ruby/object:Gem::Version
251
252
  version: '0'
252
253
  requirements: []
253
- rubygems_version: 3.4.6
254
+ rubygems_version: 3.4.12
254
255
  signing_key:
255
256
  specification_version: 4
256
257
  summary: Heroku to Control Plane