cpl 0.6.0 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: cfd7383099c36f633d327424fcb36561e2b925120e63f1b814158a43bd55103f
4
- data.tar.gz: eafdf0607fe28d3c24f8132e3a116085020c94639d5b05a5accec4d4de651ca5
3
+ metadata.gz: 410e8bfdc923cabc36b900bb6cc3bb98e586cc2789579ec01cc33fe9c9c39fe1
4
+ data.tar.gz: a7428c35cff0dabcd1c68469561b82e2c3f24282b92dba9b1eeeb94c51d9d654
5
5
  SHA512:
6
- metadata.gz: b443d26a3fa91400dbb6d2e71b730a26bd1405df2f03e7f9446179323e2becb532ec69d81d93f22578fe8793dbabec9a2283efc16a107decdb5aaa9e4a615281
7
- data.tar.gz: 34ab7670bc372af9b8991678de9d99a9c60429b3caebeeeb2775046a9be3d4a7fb7335d9cbeb3a6c2ba06bb29ef40ab7c2cffbcd20737cfb62eb4048b07a8926
6
+ metadata.gz: 9c09fb9477e7dd638220e4ad711161a176daab7e82ed7224d584b6617989e3dd789ae5f66eb75e0086bdcd9690d680e2de668b5698ce322184ecdd23522835a3
7
+ data.tar.gz: 82f3a8aaf6b465850f9b577c5f7aed1b8b4313bf0224d52f058fc94e17f334a9cb9f51bb2638600c150184714fb254c2edeea1bb1f77b40a976fe20d0db11b54
@@ -0,0 +1,24 @@
1
+ name: Command Docs
2
+
3
+ on:
4
+ push:
5
+ branches:
6
+ - main
7
+ pull_request:
8
+
9
+ jobs:
10
+ rspec:
11
+ runs-on: ubuntu-latest
12
+ name: Command Docs
13
+ steps:
14
+ - name: Checkout code
15
+ uses: actions/checkout@v3
16
+ - name: Set up Ruby
17
+ uses: ruby/setup-ruby@v1
18
+ with:
19
+ ruby-version: "3.0"
20
+ bundler-cache: true
21
+ - name: Install dependencies
22
+ run: bundle install
23
+ - name: Check if command docs are up to date
24
+ run: bundle exec rake check_command_docs
@@ -8,15 +8,18 @@ on:
8
8
 
9
9
  jobs:
10
10
  rspec:
11
- runs-on: ubuntu-latest
12
- name: RSpec
13
- env:
14
- RAILS_ENV: test
15
11
  strategy:
16
12
  matrix:
13
+ os:
14
+ - ubuntu-latest
15
+ - macos-latest
17
16
  ruby:
18
17
  - "2.7"
19
18
  - "3.0"
19
+ runs-on: ${{ matrix.os }}
20
+ name: RSpec
21
+ env:
22
+ RAILS_ENV: test
20
23
  steps:
21
24
  - name: Checkout code
22
25
  uses: actions/checkout@v3
@@ -28,7 +31,7 @@ jobs:
28
31
  - name: Install dependencies
29
32
  run: bundle install
30
33
  - name: Run tests
31
- run: bundle exec rspec spec
34
+ run: bundle exec rspec
32
35
  - name: Upload coverage results
33
36
  uses: actions/upload-artifact@master
34
37
  if: always()
@@ -8,13 +8,16 @@ on:
8
8
 
9
9
  jobs:
10
10
  rubocop:
11
- runs-on: ubuntu-latest
12
- name: Rubocop
13
11
  strategy:
14
12
  matrix:
13
+ os:
14
+ - ubuntu-latest
15
+ - macos-latest
15
16
  ruby:
16
17
  - "2.7"
17
18
  - "3.0"
19
+ runs-on: ${{ matrix.os }}
20
+ name: Rubocop
18
21
  steps:
19
22
  - name: Checkout code
20
23
  uses: actions/checkout@v3
data/.overcommit.yml CHANGED
@@ -1,4 +1,7 @@
1
1
  PreCommit:
2
+ CommandDocs:
3
+ enabled: true
4
+ command: ["bundle", "exec", "rake", "check_command_docs"]
2
5
  RuboCop:
3
6
  enabled: true
4
7
  on_warn: fail
data/.rubocop.yml CHANGED
@@ -14,3 +14,9 @@ Style/Documentation:
14
14
 
15
15
  Style/StringLiterals:
16
16
  EnforcedStyle: double_quotes
17
+
18
+ RSpec/ExampleLength:
19
+ Enabled: false
20
+
21
+ RSpec/MultipleExpectations:
22
+ Enabled: false
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- cpl (0.6.0)
4
+ cpl (1.0.0)
5
5
  debug (~> 1.7.1)
6
6
  dotenv (~> 2.8.1)
7
7
  psych (~> 5.1.0)
@@ -10,14 +10,19 @@ PATH
10
10
  GEM
11
11
  remote: https://rubygems.org/
12
12
  specs:
13
+ addressable (2.8.4)
14
+ public_suffix (>= 2.0.2, < 6.0)
13
15
  ast (2.4.2)
14
16
  childprocess (4.1.0)
17
+ crack (0.4.5)
18
+ rexml
15
19
  debug (1.7.2)
16
20
  irb (>= 1.5.0)
17
21
  reline (>= 0.3.1)
18
22
  diff-lcs (1.5.0)
19
23
  docile (1.4.0)
20
24
  dotenv (2.8.1)
25
+ hashdiff (1.0.1)
21
26
  iniparse (1.5.0)
22
27
  io-console (0.6.0)
23
28
  irb (1.6.4)
@@ -32,10 +37,11 @@ GEM
32
37
  ast (~> 2.4.1)
33
38
  psych (5.1.0)
34
39
  stringio
40
+ public_suffix (5.0.1)
35
41
  rainbow (3.1.1)
36
42
  rake (13.0.6)
37
43
  regexp_parser (2.6.2)
38
- reline (0.3.3)
44
+ reline (0.3.4)
39
45
  io-console (~> 0.5)
40
46
  rexml (3.2.5)
41
47
  rspec (3.12.0)
@@ -78,8 +84,14 @@ GEM
78
84
  simplecov-html (0.12.3)
79
85
  simplecov_json_formatter (0.1.4)
80
86
  stringio (3.0.6)
81
- thor (1.2.1)
87
+ thor (1.2.2)
88
+ timecop (0.9.6)
82
89
  unicode-display_width (2.4.2)
90
+ vcr (6.1.0)
91
+ webmock (3.18.1)
92
+ addressable (>= 2.8.0)
93
+ crack (>= 0.3.2)
94
+ hashdiff (>= 0.4.0, < 2.0.0)
83
95
 
84
96
  PLATFORMS
85
97
  ruby
@@ -94,6 +106,9 @@ DEPENDENCIES
94
106
  rubocop-rake (~> 0.6.0)
95
107
  rubocop-rspec (~> 2.18.1)
96
108
  simplecov (~> 0.22.0)
109
+ timecop (~> 0.9.6)
110
+ vcr (~> 6.1.0)
111
+ webmock (~> 3.18.1)
97
112
 
98
113
  BUNDLED WITH
99
114
  2.3.26
data/README.md CHANGED
@@ -28,11 +28,12 @@ To simplify migration to and usage of Control Plane for Heroku users, this repos
28
28
  6. [Environment](#environment)
29
29
  7. [Database](#database)
30
30
  8. [In-memory databases](#in-memory-databases)
31
- 9. [CLI commands reference](#cli-commands-reference)
32
- 10. [Mapping of Heroku Commands to `cpl` and `cpln`](#mapping-of-heroku-commands-to-cpl-and-cpln)
33
- 11. [Examples](#examples)
34
- 12. [Migrating Postgres database from Heroku infrastructure](/docs/postgres.md)
35
- 13. [Migrating Redis database from Heroku infrastructure](/docs/redis.md)
31
+ 9. [Scheduled jobs](#scheduled-jobs)
32
+ 10. [CLI commands reference](#cli-commands-reference)
33
+ 11. [Mapping of Heroku Commands to `cpl` and `cpln`](#mapping-of-heroku-commands-to-cpl-and-cpln)
34
+ 12. [Examples](#examples)
35
+ 13. [Migrating Postgres database from Heroku infrastructure](/docs/postgres.md)
36
+ 14. [Migrating Redis database from Heroku infrastructure](/docs/redis.md)
36
37
 
37
38
  ## Key features
38
39
 
@@ -105,14 +106,28 @@ Do not confuse the `cpl` CLI with the `cpln` CLI. The `cpl` CLI is the Heroku to
105
106
  **Notes:**
106
107
 
107
108
  1. `myapp` is an app name defined in the `.controlplane/controlplane.yml` file, such as `ror-tutorial` in [this `controlplane.yml` file](https://github.com/shakacode/react-webpack-rails-tutorial/blob/master/.controlplane/controlplane.yml).
108
- 2. Other files in the `.controlplane/templates` directory are used by the `cpl setup` command.
109
+ 2. Other files in the `.controlplane/templates` directory are used by the `cpl setup-app` and `cpl apply-template` commands.
109
110
 
110
111
  ### Initial Setup and Deployment
111
112
 
113
+ Before the initial setup, add the templates for the app to `.controlplane/controlplane.yml`, using the `setup` key:
114
+
115
+ ```yaml
116
+ myapp:
117
+ setup:
118
+ - gvc
119
+ - postgres
120
+ - redis
121
+ - memcached
122
+ - rails
123
+ - sidekiq
124
+ ```
125
+
126
+ Note how the templates correspond to files in the `.controlplane/templates` directory.
127
+
112
128
  ```sh
113
129
  # Provision infrastructure (one-time-only for new apps) using templates.
114
- # Note how the arguments correspond to files in the `.controlplane/templates` directory.
115
- cpl setup gvc postgres redis memcached rails sidekiq -a myapp
130
+ cpl setup-app -a myapp
116
131
 
117
132
  # Build and push image with auto-tagging "myapp:1_456".
118
133
  cpl build-image -a myapp --commit 456
@@ -214,7 +229,7 @@ apps:
214
229
  <<: *common
215
230
  # Use a different organization for production.
216
231
  cpln_org: my-org-production
217
- # Allows running the command `cpl pipeline-promote my-app-staging` to promote the staging app to production.
232
+ # Allows running the command `cpl promote-app-from-upstream -a my-app-production` to promote the staging app to production.
218
233
  upstream: my-app-staging
219
234
  my-app-other:
220
235
  <<: *common
@@ -313,6 +328,38 @@ For production purposes or where restarts are not an option, you should use exte
313
328
  We provide default `redis` and `memcached` templates in this repo optimized for Control Plane and suitable
314
329
  for development purposes.
315
330
 
331
+ ## Scheduled jobs
332
+
333
+ Control Plane supports scheduled jobs via [cron workloads](https://docs.controlplane.com/reference/workload#cron).
334
+
335
+ Here's a partial example of a template for a cron workload, using the app image:
336
+
337
+ ```yaml
338
+ kind: workload
339
+ name: daily-task
340
+ spec:
341
+ type: cron
342
+ job:
343
+ # Run daily job at 2am
344
+ schedule: 0 2 * * *
345
+ # Never or OnFailure
346
+ restartPolicy: Never
347
+ containers:
348
+ - name: daily-task
349
+ args:
350
+ - bundle
351
+ - exec
352
+ - rails
353
+ - db:prepare
354
+ image: "/org/APP_ORG/image/APP_IMAGE"
355
+ ```
356
+
357
+ A complete example can be found at [templates/daily-task.yml](templates/daily-task.yml), optimized for Control Plane and suitable for development purposes.
358
+
359
+ You can create the cron workload by adding the template for it to the `.controlplane/templates` folder and running `cpl apply-template my-template -a my-app`, where `my-template` is the name of the template file (`my-template.yml`).
360
+
361
+ Then to view the logs of the cron workload, you can run `cpl logs -a my-app -w my-template`.
362
+
316
363
  ## CLI commands reference:
317
364
 
318
365
  Click [here](/docs/commands.md) to see the commands.
@@ -327,17 +374,17 @@ cpl --help
327
374
 
328
375
  **`[WIP]`**
329
376
 
330
- | Heroku Command | `cpl` or `cpln` |
331
- | -------------------------------------------------------------------------------------------------------------- | --------------- |
332
- | [heroku ps](https://devcenter.heroku.com/articles/heroku-cli-commands#heroku-ps-type-type) | `cpl ps` |
333
- | [heroku config](https://devcenter.heroku.com/articles/heroku-cli-commands#heroku-config) | ? |
334
- | [heroku maintenance](https://devcenter.heroku.com/articles/heroku-cli-commands#heroku-maintenance) | ? |
335
- | [heroku logs](https://devcenter.heroku.com/articles/heroku-cli-commands#heroku-logs) | `cpl logs` |
336
- | [heroku pg](https://devcenter.heroku.com/articles/heroku-cli-commands#heroku-pg-database) | ? |
337
- | [heroku pipelines:promote](https://devcenter.heroku.com/articles/heroku-cli-commands#heroku-pipelines-promote) | `cpl promote` |
338
- | [heroku psql](https://devcenter.heroku.com/articles/heroku-cli-commands#heroku-psql-database) | ? |
339
- | [heroku redis](https://devcenter.heroku.com/articles/heroku-cli-commands#heroku-redis-database) | ? |
340
- | [heroku releases](https://devcenter.heroku.com/articles/heroku-cli-commands#heroku-releases) | ? |
377
+ | Heroku Command | `cpl` or `cpln` |
378
+ | -------------------------------------------------------------------------------------------------------------- | ------------------------------- |
379
+ | [heroku ps](https://devcenter.heroku.com/articles/heroku-cli-commands#heroku-ps-type-type) | `cpl ps` |
380
+ | [heroku config](https://devcenter.heroku.com/articles/heroku-cli-commands#heroku-config) | ? |
381
+ | [heroku maintenance](https://devcenter.heroku.com/articles/heroku-cli-commands#heroku-maintenance) | `cpl maintenance` |
382
+ | [heroku logs](https://devcenter.heroku.com/articles/heroku-cli-commands#heroku-logs) | `cpl logs` |
383
+ | [heroku pg](https://devcenter.heroku.com/articles/heroku-cli-commands#heroku-pg-database) | ? |
384
+ | [heroku pipelines:promote](https://devcenter.heroku.com/articles/heroku-cli-commands#heroku-pipelines-promote) | `cpl promote-app-from-upstream` |
385
+ | [heroku psql](https://devcenter.heroku.com/articles/heroku-cli-commands#heroku-psql-database) | ? |
386
+ | [heroku redis](https://devcenter.heroku.com/articles/heroku-cli-commands#heroku-redis-database) | ? |
387
+ | [heroku releases](https://devcenter.heroku.com/articles/heroku-cli-commands#heroku-releases) | ? |
341
388
 
342
389
  ## Examples
343
390
 
data/Rakefile CHANGED
@@ -4,13 +4,18 @@ require "bundler/gem_tasks"
4
4
  require "rspec/core/rake_task"
5
5
  require "rubocop/rake_task"
6
6
 
7
- RSpec::Core::RakeTask.new(:spec)
7
+ RSpec::Core::RakeTask.new(:rspec)
8
8
 
9
9
  RuboCop::RakeTask.new
10
10
 
11
- task default: %i[spec rubocop]
11
+ task default: %i[rspec rubocop]
12
+
13
+ desc "Checks if commands.md file is up to date"
14
+ task :check_command_docs do
15
+ sh "./script/check_command_docs"
16
+ end
12
17
 
13
18
  desc "Updates commands.md file"
14
- task :command_docs do
15
- sh "./script/generate_commands_docs"
19
+ task :update_command_docs do
20
+ sh "./script/update_command_docs"
16
21
  end
data/cpl.gemspec CHANGED
@@ -26,6 +26,9 @@ Gem::Specification.new do |spec|
26
26
  spec.add_development_dependency "rubocop-rake", "~> 0.6.0"
27
27
  spec.add_development_dependency "rubocop-rspec", "~> 2.18.1"
28
28
  spec.add_development_dependency "simplecov", "~> 0.22.0"
29
+ spec.add_development_dependency "timecop", "~> 0.9.6"
30
+ spec.add_development_dependency "vcr", "~> 6.1.0"
31
+ spec.add_development_dependency "webmock", "~> 3.18.1"
29
32
 
30
33
  spec.files = `git ls-files -z`.split("\x0").reject do |file|
31
34
  file.match(%r{^(coverage|pkg|spec|tmp)/})
data/docs/commands.md CHANGED
@@ -39,7 +39,8 @@ cpl apply-template gvc postgres redis rails -a $APP_NAME
39
39
 
40
40
  - Builds and pushes the image to Control Plane
41
41
  - Automatically assigns image numbers, e.g., `app:1`, `app:2`, etc.
42
- - Uses `.controlplane/Dockerfile`
42
+ - Uses `.controlplane/Dockerfile` or a different Dockerfile specified through `dockerfile` in the `.controlplane/controlplane.yml` file
43
+ - If a commit is provided through `--commit` or `-c`, it will be set as the runtime env var `GIT_COMMIT`
43
44
 
44
45
  ```sh
45
46
  cpl build-image -a $APP_NAME
@@ -167,6 +168,51 @@ cpl logs -a $APP_NAME
167
168
  cpl logs -a $APP_NAME -w $WORKLOAD_NAME
168
169
  ```
169
170
 
171
+ ### `maintenance`
172
+
173
+ - Checks if maintenance mode is on or off for an app
174
+ - Outputs 'on' or 'off'
175
+ - Specify the one-off workload through `one_off_workload` in the `.controlplane/controlplane.yml` file
176
+ - Optionally specify the maintenance workload through `maintenance_workload` in the `.controlplane/controlplane.yml` file (defaults to 'maintenance')
177
+ - Maintenance mode is only supported for domains that use path based routing mode and have a route configured for the prefix '/' on either port 80 or 443
178
+
179
+ ```sh
180
+ cpl maintenance -a $APP_NAME
181
+ ```
182
+
183
+ ### `maintenance:off`
184
+
185
+ - Disables maintenance mode for an app
186
+ - Specify the one-off workload through `one_off_workload` in the `.controlplane/controlplane.yml` file
187
+ - Optionally specify the maintenance workload through `maintenance_workload` in the `.controlplane/controlplane.yml` file (defaults to 'maintenance')
188
+ - Maintenance mode is only supported for domains that use path based routing mode and have a route configured for the prefix '/' on either port 80 or 443
189
+
190
+ ```sh
191
+ cpl maintenance:off -a $APP_NAME
192
+ ```
193
+
194
+ ### `maintenance:on`
195
+
196
+ - Enables maintenance mode for an app
197
+ - Specify the one-off workload through `one_off_workload` in the `.controlplane/controlplane.yml` file
198
+ - Optionally specify the maintenance workload through `maintenance_workload` in the `.controlplane/controlplane.yml` file (defaults to 'maintenance')
199
+ - Maintenance mode is only supported for domains that use path based routing mode and have a route configured for the prefix '/' on either port 80 or 443
200
+
201
+ ```sh
202
+ cpl maintenance:on -a $APP_NAME
203
+ ```
204
+
205
+ ### `maintenance:set-page`
206
+
207
+ - Sets the page for maintenance mode
208
+ - Only works if the maintenance workload uses the `shakacode/maintenance-mode` image
209
+ - Will set the URL as an env var `PAGE_URL` on the maintenance workload
210
+ - Optionally specify the maintenance workload through `maintenance_workload` in the `.controlplane/controlplane.yml` file (defaults to 'maintenance')
211
+
212
+ ```sh
213
+ cpl maintenance:set-page PAGE_URL -a $APP_NAME
214
+ ```
215
+
170
216
  ### `open`
171
217
 
172
218
  - Opens the app endpoint URL in the default browser
@@ -244,6 +290,7 @@ cpl ps:stop -a $APP_NAME -w $WORKLOAD_NAME
244
290
  - Runs one-off **_interactive_** replicas (analog of `heroku run`)
245
291
  - Uses `Standard` workload type and `cpln exec` as the execution method, with CLI streaming
246
292
  - May not work correctly with tasks that last over 5 minutes (there's a Control Plane scaling bug at the moment)
293
+ - If `fix_terminal_size` is `true` in the `.controlplane/controlplane.yml` file, the remote terminal size will be fixed to match the local terminal size (may also be overriden through `--terminal-size`)
247
294
 
248
295
  > **IMPORTANT:** Useful for development where it's needed for interaction, and where network connection drops and
249
296
  > task crashing are tolerable. For production tasks, it's better to use `cpl run:detached`.
@@ -252,6 +299,12 @@ cpl ps:stop -a $APP_NAME -w $WORKLOAD_NAME
252
299
  # Opens shell (bash by default).
253
300
  cpl run -a $APP_NAME
254
301
 
302
+ # Need to quote COMMAND if setting ENV value or passing args.
303
+ cpl run 'LOG_LEVEL=warn rails db:migrate' -a $APP_NAME
304
+
305
+ # COMMAND may also be passed at the end (in this case, no need to quote).
306
+ cpl run -a $APP_NAME -- rails db:migrate
307
+
255
308
  # Runs command, displays output, and exits shell.
256
309
  cpl run ls / -a $APP_NAME
257
310
  cpl run rails db:migrate:status -a $APP_NAME
@@ -263,14 +316,25 @@ cpl run rails c -a $APP_NAME
263
316
  cpl run rails db:migrate -a $APP_NAME --image appimage:123 # Exact image name
264
317
  cpl run rails db:migrate -a $APP_NAME --image latest # Latest sequential image
265
318
 
266
- # Uses a different workload
319
+ # Uses a different workload than `one_off_workload` from `.controlplane/controlplane.yml`.
267
320
  cpl run bash -a $APP_NAME -w other-workload
268
321
 
269
322
  # Overrides remote CPLN_TOKEN env variable with local token.
270
- # Useful when need superuser rights in remote container
323
+ # Useful when superuser rights are needed in remote container.
271
324
  cpl run bash -a $APP_NAME --use-local-token
272
325
  ```
273
326
 
327
+ ### `run:cleanup`
328
+
329
+ - Deletes stale run workloads for an app
330
+ - Workloads are considered stale based on how many days since created
331
+ - `stale_run_workload_created_days` in the `.controlplane/controlplane.yml` file specifies the number of days after created that the workload is considered stale
332
+ - Will ask for explicit user confirmation of deletion
333
+
334
+ ```sh
335
+ cpl run:cleanup -a $APP_NAME
336
+ ```
337
+
274
338
  ### `run:detached`
275
339
 
276
340
  - Runs one-off **_non-interactive_** replicas (close analog of `heroku run:detached`)
@@ -282,9 +346,12 @@ cpl run bash -a $APP_NAME --use-local-token
282
346
  ```sh
283
347
  cpl run:detached rails db:prepare -a $APP_NAME
284
348
 
285
- # Need to quote COMMAND if setting ENV value or passing args to command to run
349
+ # Need to quote COMMAND if setting ENV value or passing args.
286
350
  cpl run:detached 'LOG_LEVEL=warn rails db:migrate' -a $APP_NAME
287
351
 
352
+ # COMMAND may also be passed at the end (in this case, no need to quote).
353
+ cpl run:detached -a $APP_NAME -- rails db:migrate
354
+
288
355
  # Uses some other image.
289
356
  cpl run:detached rails db:migrate -a $APP_NAME --image /some/full/image/path
290
357
 
@@ -295,7 +362,7 @@ cpl run:detached rails db:migrate -a $APP_NAME --image latest
295
362
  cpl run:detached rails db:migrate -a $APP_NAME --image appimage:123 # Exact image name
296
363
  cpl run:detached rails db:migrate -a $APP_NAME --image latest # Latest sequential image
297
364
 
298
- # Uses a different workload
365
+ # Uses a different workload than `one_off_workload` from `.controlplane/controlplane.yml`.
299
366
  cpl run:detached rails db:migrate:status -a $APP_NAME -w other-workload
300
367
  ```
301
368
 
@@ -66,7 +66,7 @@ build-review-app:
66
66
  name: Provision review app if needed
67
67
  command: |
68
68
  if ! cpl exist -a ${APP_NAME}; then
69
- cpl setup gvc postgres redis memcached rails sidekiq -a ${APP_NAME}
69
+ cpl setup-app -a ${APP_NAME}
70
70
  echo "export NEW_APP=true" >> $BASH_ENV
71
71
  fi
72
72
  - run:
@@ -23,6 +23,9 @@ aliases:
23
23
  - postgres
24
24
  - memcached
25
25
 
26
+ # Configure the workload name used when maintenance mode is on (defaults to 'maintenance')
27
+ maintenance_workload: maintenance
28
+
26
29
  apps:
27
30
  my-app-staging:
28
31
  # Use the values from the common section above
data/lib/command/base.rb CHANGED
@@ -153,6 +153,29 @@ module Command
153
153
  }
154
154
  end
155
155
 
156
+ def self.terminal_size_option(required: false)
157
+ {
158
+ name: :terminal_size,
159
+ params: {
160
+ banner: "ROWS,COLS",
161
+ desc: "Override remote terminal size (e.g. `--terminal-size 10,20`)",
162
+ type: :string,
163
+ required: required
164
+ }
165
+ }
166
+ end
167
+
168
+ def self.wait_option(title = "", required: false)
169
+ {
170
+ name: :wait,
171
+ params: {
172
+ desc: "Waits for #{title}",
173
+ type: :boolean,
174
+ required: required
175
+ }
176
+ }
177
+ end
178
+
156
179
  def self.all_options
157
180
  methods.grep(/_option$/).map { |method| send(method.to_s) }
158
181
  end
@@ -164,28 +187,22 @@ module Command
164
187
  end
165
188
  end
166
189
 
167
- def wait_for(title)
168
- progress.print "- Waiting for #{title}"
169
- until yield
170
- progress.print(".")
171
- sleep(1)
172
- end
173
- progress.puts
174
- end
175
-
176
190
  def wait_for_workload(workload)
177
- wait_for("workload to start") { cp.fetch_workload(workload) }
191
+ step("Waiting for workload", retry_on_failure: true) do
192
+ cp.fetch_workload(workload)
193
+ end
178
194
  end
179
195
 
180
196
  def wait_for_replica(workload, location)
181
- wait_for("replica") do
197
+ step("Waiting for replica", retry_on_failure: true) do
182
198
  cp.workload_get_replicas_safely(workload, location: location)&.dig("items", 0)
183
199
  end
184
200
  end
185
201
 
186
202
  def ensure_workload_deleted(workload)
187
- progress.puts "- Ensure workload is deleted"
188
- cp.workload_delete(workload)
203
+ step("Deleting workload") do
204
+ cp.delete_workload(workload)
205
+ end
189
206
  end
190
207
 
191
208
  def latest_image_from(items, app_name: config.app, name_only: true)
@@ -212,8 +229,9 @@ module Command
212
229
  def latest_image_next(app = config.app, org = config.org)
213
230
  @latest_image_next ||= {}
214
231
  @latest_image_next[app] ||= begin
215
- image = latest_image(app, org).split(":").first
216
- image += ":#{extract_image_number(latest_image) + 1}"
232
+ latest_image_name = latest_image(app, org)
233
+ image = latest_image_name.split(":").first
234
+ image += ":#{extract_image_number(latest_image_name) + 1}"
217
235
  image += "_#{config.options[:commit]}" if config.options[:commit]
218
236
  image
219
237
  end
@@ -229,29 +247,44 @@ module Command
229
247
  $stderr
230
248
  end
231
249
 
232
- def step(message, abort_on_error: true) # rubocop:disable Metrics/MethodLength
250
+ def step_error(error, abort_on_error: true)
251
+ message = error.message
252
+ if abort_on_error
253
+ progress.puts(" #{Shell.color('failed!', :red)}\n\n")
254
+ Shell.abort(message)
255
+ else
256
+ Shell.write_to_tmp_stderr(message)
257
+ end
258
+ end
259
+
260
+ def step_finish(success)
261
+ if success
262
+ progress.puts(" #{Shell.color('done!', :green)}")
263
+ else
264
+ progress.puts(" #{Shell.color('failed!', :red)}\n\n#{Shell.read_from_tmp_stderr}\n\n")
265
+ end
266
+ end
267
+
268
+ def step(message, abort_on_error: true, retry_on_failure: false) # rubocop:disable Metrics/MethodLength
233
269
  progress.print("#{message}...")
234
270
 
235
271
  Shell.use_tmp_stderr do
236
272
  success = false
237
273
 
238
274
  begin
239
- success = yield
240
- rescue RuntimeError => e
241
- message = e.message
242
- if abort_on_error
243
- progress.puts(" #{Shell.color('failed!', :red)}\n\n")
244
- Shell.abort(message)
275
+ if retry_on_failure
276
+ until (success = yield)
277
+ progress.print(".")
278
+ sleep 1
279
+ end
245
280
  else
246
- Shell.write_to_tmp_stderr(message)
281
+ success = yield
247
282
  end
283
+ rescue RuntimeError => e
284
+ step_error(e, abort_on_error: abort_on_error)
248
285
  end
249
286
 
250
- if success
251
- progress.puts(" #{Shell.color('done!', :green)}")
252
- else
253
- progress.puts(" #{Shell.color('failed!', :red)}\n\n#{Shell.read_from_tmp_stderr}\n\n")
254
- end
287
+ step_finish(success)
255
288
  end
256
289
  end
257
290
 
@@ -11,18 +11,30 @@ module Command
11
11
  LONG_DESCRIPTION = <<~DESC
12
12
  - Builds and pushes the image to Control Plane
13
13
  - Automatically assigns image numbers, e.g., `app:1`, `app:2`, etc.
14
- - Uses `.controlplane/Dockerfile`
14
+ - Uses `.controlplane/Dockerfile` or a different Dockerfile specified through `dockerfile` in the `.controlplane/controlplane.yml` file
15
+ - If a commit is provided through `--commit` or `-c`, it will be set as the runtime env var `GIT_COMMIT`
15
16
  DESC
16
17
 
17
- def call
18
+ def call # rubocop:disable Metrics/MethodLength
18
19
  ensure_docker_running!
19
20
 
20
21
  dockerfile = config.current[:dockerfile] || "Dockerfile"
21
22
  dockerfile = "#{config.app_cpln_dir}/#{dockerfile}"
22
23
 
24
+ raise "Can't find Dockerfile at '#{dockerfile}'." unless File.exist?(dockerfile)
25
+
23
26
  progress.puts("Building image from Dockerfile '#{dockerfile}'...\n\n")
24
27
 
25
- cp.image_build(latest_image_next, dockerfile: dockerfile)
28
+ image_name = latest_image_next
29
+ image_url = "#{config.org}.registry.cpln.io/#{image_name}"
30
+
31
+ commit = config.options[:commit]
32
+ build_args = []
33
+ build_args.push("GIT_COMMIT=#{commit}") if commit
34
+
35
+ cp.image_build(image_url, dockerfile: dockerfile, build_args: build_args)
36
+
37
+ progress.puts("\nPushed image to '/org/#{config.org}/image/#{image_name}'.")
26
38
  end
27
39
 
28
40
  private
@@ -29,7 +29,7 @@ module Command
29
29
  ensure_docker_running!
30
30
 
31
31
  @upstream = config[:upstream]
32
- @upstream_org = config.apps[@upstream.to_sym][:cpln_org] || config.apps[@upstream.to_sym][:org]
32
+ @upstream_org = config.apps[@upstream.to_sym][:cpln_org]
33
33
  ensure_upstream_org!
34
34
 
35
35
  create_upstream_profile