1 | ![](https://cto.ai/static/sdk-banner.png)
|
2 |
|
3 | # ops
|
4 |
|
5 | 💻 CTO.ai Ops - The CLI built for Teams 🚀
|
6 |
|
7 | [![oclif](https://img.shields.io/badge/cli-oclif-brightgreen.svg)](https://oclif.io)
|
8 | [![Version](https://img.shields.io/npm/v/ops.svg)](https://npmjs.org/package/ops)
|
9 | [![Downloads/week](https://img.shields.io/npm/dw/ops.svg)](https://npmjs.org/package/ops)
|
10 | [![License](https://img.shields.io/npm/l/ops.svg)](https://github.com/cto.ai/ops/blob/master/package.json)
|
11 |
|
12 |
|
13 | * [ops](#ops)
|
14 | * [Usage](#usage)
|
15 | * [Commands](#commands)
|
16 | * [Testing](#testing)
|
17 |
|
18 |
|
19 | # Usage
|
20 |
|
21 |
|
22 | ```sh-session
|
23 | $ npm install -g @cto.ai/ops
|
24 | $ ops COMMAND
|
25 | running command...
|
26 | $ ops (-v|--version|version)
|
27 | @cto.ai/ops/1.13.3 darwin-x64 node-v12.18.4
|
28 | $ ops --help [COMMAND]
|
29 | USAGE
|
30 | $ ops COMMAND
|
31 | ...
|
32 | ```
|
33 |
|
34 |
|
35 | # Commands
|
36 |
|
37 |
|
38 | * [`ops account:reset`](#ops-accountreset)
|
39 | * [`ops account:signin`](#ops-accountsignin)
|
40 | * [`ops account:signout`](#ops-accountsignout)
|
41 | * [`ops account:signup`](#ops-accountsignup)
|
42 | * [`ops account:support`](#ops-accountsupport)
|
43 | * [`ops add [OPNAME]`](#ops-add-opname)
|
44 | * [`ops build [PATH]`](#ops-build-path)
|
45 | * [`ops cleanup [OPNAME]`](#ops-cleanup-opname)
|
46 | * [`ops configs:delete`](#ops-configsdelete)
|
47 | * [`ops configs:list`](#ops-configslist)
|
48 | * [`ops configs:set`](#ops-configsset)
|
49 | * [`ops generate:token`](#ops-generatetoken)
|
50 | * [`ops help [COMMAND]`](#ops-help-command)
|
51 | * [`ops init [NAME]`](#ops-init-name)
|
52 | * [`ops list`](#ops-list)
|
53 | * [`ops publish PATH`](#ops-publish-path)
|
54 | * [`ops remove OP`](#ops-remove-op)
|
55 | * [`ops run [NAMEORPATH]`](#ops-run-nameorpath)
|
56 | * [`ops search [FILTER]`](#ops-search-filter)
|
57 | * [`ops secrets:delete`](#ops-secretsdelete)
|
58 | * [`ops secrets:list`](#ops-secretslist)
|
59 | * [`ops secrets:register`](#ops-secretsregister)
|
60 | * [`ops secrets:set`](#ops-secretsset)
|
61 | * [`ops secrets:unregister`](#ops-secretsunregister)
|
62 | * [`ops start [NAMEORPATH]`](#ops-start-nameorpath)
|
63 | * [`ops status`](#ops-status)
|
64 | * [`ops stop [RUNID]`](#ops-stop-runid)
|
65 | * [`ops team:create`](#ops-teamcreate)
|
66 | * [`ops team:info`](#ops-teaminfo)
|
67 | * [`ops team:invite`](#ops-teaminvite)
|
68 | * [`ops team:join`](#ops-teamjoin)
|
69 | * [`ops team:list`](#ops-teamlist)
|
70 | * [`ops team:remove [MEMBER]`](#ops-teamremove-member)
|
71 | * [`ops team:switch`](#ops-teamswitch)
|
72 | * [`ops update`](#ops-update)
|
73 | * [`ops whoami`](#ops-whoami)
|
74 |
|
75 | ## `ops account:reset`
|
76 |
|
77 | Reset your password.
|
78 |
|
79 | ```
|
80 | USAGE
|
81 | $ ops account:reset
|
82 | ```
|
83 |
|
84 | ## `ops account:signin`
|
85 |
|
86 | Log in to your account.
|
87 |
|
88 | ```
|
89 | USAGE
|
90 | $ ops account:signin
|
91 |
|
92 | OPTIONS
|
93 | -h, --help show CLI help
|
94 | -i, --interactive Interactive Mode
|
95 | -p, --password=password Password
|
96 | -u, --user=user Username or email
|
97 | ```
|
98 |
|
99 | ## `ops account:signout`
|
100 |
|
101 | Log out from your account.
|
102 |
|
103 | ```
|
104 | USAGE
|
105 | $ ops account:signout
|
106 |
|
107 | OPTIONS
|
108 | -h, --help show CLI help
|
109 | ```
|
110 |
|
111 | ## `ops account:signup`
|
112 |
|
113 | Creates an account to use with ops CLI.
|
114 |
|
115 | ```
|
116 | USAGE
|
117 | $ ops account:signup
|
118 |
|
119 | OPTIONS
|
120 | -h, --help show CLI help
|
121 | ```
|
122 |
|
123 | ## `ops account:support`
|
124 |
|
125 | Contact our support team with questions.
|
126 |
|
127 | ```
|
128 | USAGE
|
129 | $ ops account:support
|
130 |
|
131 | OPTIONS
|
132 | -h, --help show CLI help
|
133 | ```
|
134 |
|
135 | ## `ops add [OPNAME]`
|
136 |
|
137 | Add an op to your team.
|
138 |
|
139 | ```
|
140 | USAGE
|
141 | $ ops add [OPNAME]
|
142 |
|
143 | ARGUMENTS
|
144 | OPNAME Name of the public op to be added to your team. It should be of the format - @teamname/opName:versionName
|
145 |
|
146 | OPTIONS
|
147 | -h, --help show CLI help
|
148 | ```
|
149 |
|
150 | ## `ops build [PATH]`
|
151 |
|
152 | Build your op for sharing.
|
153 |
|
154 | ```
|
155 | USAGE
|
156 | $ ops build [PATH]
|
157 |
|
158 | ARGUMENTS
|
159 | PATH Path to the op you want to build.
|
160 |
|
161 | OPTIONS
|
162 | -h, --help show CLI help
|
163 | ```
|
164 |
|
165 | ## `ops cleanup [OPNAME]`
|
166 |
|
167 | Clean up locally cached docker images.
|
168 |
|
169 | ```
|
170 | USAGE
|
171 | $ ops cleanup [OPNAME]
|
172 |
|
173 | ARGUMENTS
|
174 | OPNAME Name of the op to be cleaned up
|
175 |
|
176 | OPTIONS
|
177 | -h, --help show CLI help
|
178 | ```
|
179 |
|
180 | ## `ops configs:delete`
|
181 |
|
182 | Delete a config stored for the active team
|
183 |
|
184 | ```
|
185 | USAGE
|
186 | $ ops configs:delete
|
187 |
|
188 | OPTIONS
|
189 | -h, --help show CLI help
|
190 | -k, --key=key Secret Key Name
|
191 | ```
|
192 |
|
193 | ## `ops configs:list`
|
194 |
|
195 | List all the configs that are stored for the active team
|
196 |
|
197 | ```
|
198 | USAGE
|
199 | $ ops configs:list
|
200 |
|
201 | OPTIONS
|
202 | -h, --help show CLI help
|
203 | ```
|
204 |
|
205 | ## `ops configs:set`
|
206 |
|
207 | Add a new config key & value
|
208 |
|
209 | ```
|
210 | USAGE
|
211 | $ ops configs:set
|
212 |
|
213 | OPTIONS
|
214 | -f, --from-file=from-file path to a file containing the value of the config to set
|
215 | -k, --key=key the key of the config to set
|
216 | -v, --value=value the value of the config to set
|
217 | ```
|
218 |
|
219 | ## `ops generate:token`
|
220 |
|
221 | Generate a long live access token.
|
222 |
|
223 | ```
|
224 | USAGE
|
225 | $ ops generate:token
|
226 |
|
227 | OPTIONS
|
228 | -h, --help show CLI help
|
229 | ```
|
230 |
|
231 | ## `ops help [COMMAND]`
|
232 |
|
233 | display help for ops
|
234 |
|
235 | ```
|
236 | USAGE
|
237 | $ ops help [COMMAND]
|
238 |
|
239 | ARGUMENTS
|
240 | COMMAND command to show help for
|
241 |
|
242 | OPTIONS
|
243 | --all see all commands in CLI
|
244 | ```
|
245 |
|
246 | _See code: [@oclif/plugin-help](https://github.com/oclif/plugin-help/blob/v2.2.3/src/commands/help.ts)_
|
247 |
|
248 | ## `ops init [NAME]`
|
249 |
|
250 | Create a new op
|
251 |
|
252 | ```
|
253 | USAGE
|
254 | $ ops init [NAME]
|
255 |
|
256 | ARGUMENTS
|
257 | NAME the name of the op to create
|
258 |
|
259 | OPTIONS
|
260 | -h, --help show CLI help
|
261 | -k, --kind=kind the kind of op to create (command, pipeline, etc.)
|
262 | -t, --template=template the name of the template to use
|
263 | ```
|
264 |
|
265 | ## `ops list`
|
266 |
|
267 | Lists the Ops you have in your team.
|
268 |
|
269 | ```
|
270 | USAGE
|
271 | $ ops list
|
272 |
|
273 | OPTIONS
|
274 | -h, --help show CLI help
|
275 | ```
|
276 |
|
277 | ## `ops publish PATH`
|
278 |
|
279 | Publish an Op to your team.
|
280 |
|
281 | ```
|
282 | USAGE
|
283 | $ ops publish PATH
|
284 |
|
285 | ARGUMENTS
|
286 | PATH Path to the op you want to publish.
|
287 |
|
288 | OPTIONS
|
289 | -h, --help show CLI help
|
290 | ```
|
291 |
|
292 | ## `ops remove OP`
|
293 |
|
294 | Remove an Op from your team.
|
295 |
|
296 | ```
|
297 | USAGE
|
298 | $ ops remove OP
|
299 |
|
300 | ARGUMENTS
|
301 | OP The name and version of the command or workflow you want to remove. E.g. my-command:0.1.0
|
302 |
|
303 | OPTIONS
|
304 | -h, --help show CLI help
|
305 | ```
|
306 |
|
307 | ## `ops run [NAMEORPATH]`
|
308 |
|
309 | Run an Op from your team or the registry.
|
310 |
|
311 | ```
|
312 | USAGE
|
313 | $ ops run [NAMEORPATH]
|
314 |
|
315 | ARGUMENTS
|
316 | NAMEORPATH Name or path of the Op you want to run.
|
317 |
|
318 | OPTIONS
|
319 | -B, --batch Runs the op in non-interactive batch mode.
|
320 | -b, --build Builds the op before running. Must provide a path to the op.
|
321 | -h, --help show CLI help
|
322 | ```
|
323 |
|
324 | ## `ops search [FILTER]`
|
325 |
|
326 | Search for ops in your workspaces.
|
327 |
|
328 | ```
|
329 | USAGE
|
330 | $ ops search [FILTER]
|
331 |
|
332 | ARGUMENTS
|
333 | FILTER Filters Op results which include filter text in Op name or description.
|
334 |
|
335 | OPTIONS
|
336 | -h, --help show CLI help
|
337 | ```
|
338 |
|
339 | ## `ops secrets:delete`
|
340 |
|
341 | Delete a secret stored for the active team
|
342 |
|
343 | ```
|
344 | USAGE
|
345 | $ ops secrets:delete
|
346 |
|
347 | OPTIONS
|
348 | -h, --help show CLI help
|
349 | -k, --key=key Secret Key Name
|
350 | ```
|
351 |
|
352 | ## `ops secrets:list`
|
353 |
|
354 | List all the keys that are stored for the active team
|
355 |
|
356 | ```
|
357 | USAGE
|
358 | $ ops secrets:list
|
359 |
|
360 | OPTIONS
|
361 | -h, --help show CLI help
|
362 | ```
|
363 |
|
364 | ## `ops secrets:register`
|
365 |
|
366 | Register a secrets provider for a team
|
367 |
|
368 | ```
|
369 | USAGE
|
370 | $ ops secrets:register
|
371 | ```
|
372 |
|
373 | ## `ops secrets:set`
|
374 |
|
375 | Add a key & value
|
376 |
|
377 | ```
|
378 | USAGE
|
379 | $ ops secrets:set
|
380 |
|
381 | OPTIONS
|
382 | -f, --from-file=from-file path to a file containing the value of the secret to set
|
383 | -k, --key=key the key of the secret to set
|
384 | -v, --value=value the value of the secret to set
|
385 | ```
|
386 |
|
387 | ## `ops secrets:unregister`
|
388 |
|
389 | Unregister a secrets provider for a team
|
390 |
|
391 | ```
|
392 | USAGE
|
393 | $ ops secrets:unregister
|
394 | ```
|
395 |
|
396 | ## `ops start [NAMEORPATH]`
|
397 |
|
398 | Run a Pipeline remotely in the Ops Cloud.
|
399 |
|
400 | ```
|
401 | USAGE
|
402 | $ ops start [NAMEORPATH]
|
403 |
|
404 | ARGUMENTS
|
405 | NAMEORPATH Name or path of the Op you want to run.
|
406 |
|
407 | OPTIONS
|
408 | -h, --help show CLI help
|
409 | ```
|
410 |
|
411 | ## `ops status`
|
412 |
|
413 | See the status of currently running Ops (currently only services)
|
414 |
|
415 | ```
|
416 | USAGE
|
417 | $ ops status
|
418 |
|
419 | OPTIONS
|
420 | -h, --help show CLI help
|
421 | ```
|
422 |
|
423 | ## `ops stop [RUNID]`
|
424 |
|
425 | Stop a service running in the Ops Cloud
|
426 |
|
427 | ```
|
428 | USAGE
|
429 | $ ops stop [RUNID]
|
430 |
|
431 | ARGUMENTS
|
432 | RUNID Run ID of the service to stop
|
433 |
|
434 | OPTIONS
|
435 | -h, --help show CLI help
|
436 | ```
|
437 |
|
438 | ## `ops team:create`
|
439 |
|
440 | Create your team.
|
441 |
|
442 | ```
|
443 | USAGE
|
444 | $ ops team:create
|
445 |
|
446 | OPTIONS
|
447 | -h, --help show CLI help
|
448 | -n, --name=name
|
449 | ```
|
450 |
|
451 | ## `ops team:info`
|
452 |
|
453 | Shows basic team information for the team you are currently on.
|
454 |
|
455 | ```
|
456 | USAGE
|
457 | $ ops team:info
|
458 |
|
459 | OPTIONS
|
460 | -h, --help show CLI help
|
461 | ```
|
462 |
|
463 | ## `ops team:invite`
|
464 |
|
465 | Invite your team members.
|
466 |
|
467 | ```
|
468 | USAGE
|
469 | $ ops team:invite
|
470 |
|
471 | OPTIONS
|
472 | -h, --help show CLI help
|
473 |
|
474 | -i, --invitees=invitees A comma-separated string of usernames/emails we want to invite. E.g. ("user1,
|
475 | user2@gmail.com, user3@something")
|
476 | ```
|
477 |
|
478 | ## `ops team:join`
|
479 |
|
480 | Accept an invite to join a team.
|
481 |
|
482 | ```
|
483 | USAGE
|
484 | $ ops team:join
|
485 | ```
|
486 |
|
487 | ## `ops team:list`
|
488 |
|
489 | Shows the list of your teams.
|
490 |
|
491 | ```
|
492 | USAGE
|
493 | $ ops team:list
|
494 |
|
495 | OPTIONS
|
496 | -h, --help show CLI help
|
497 | ```
|
498 |
|
499 | ## `ops team:remove [MEMBER]`
|
500 |
|
501 | Remove your team members.
|
502 |
|
503 | ```
|
504 | USAGE
|
505 | $ ops team:remove [MEMBER]
|
506 |
|
507 | ARGUMENTS
|
508 | MEMBER The username of the team member you want to remove from the team.
|
509 |
|
510 | OPTIONS
|
511 | -h, --help show CLI help
|
512 | ```
|
513 |
|
514 | ## `ops team:switch`
|
515 |
|
516 | Switch your currently active team.
|
517 |
|
518 | ```
|
519 | USAGE
|
520 | $ ops team:switch
|
521 |
|
522 | OPTIONS
|
523 | -h, --help show CLI help
|
524 | ```
|
525 |
|
526 | ## `ops update`
|
527 |
|
528 | Update the Ops CLI.
|
529 |
|
530 | ```
|
531 | USAGE
|
532 | $ ops update
|
533 |
|
534 | OPTIONS
|
535 | -h, --help show CLI help
|
536 | ```
|
537 |
|
538 | ## `ops whoami`
|
539 |
|
540 | Display your user information
|
541 |
|
542 | ```
|
543 | USAGE
|
544 | $ ops whoami
|
545 |
|
546 | OPTIONS
|
547 | -h, --help show CLI help
|
548 | ```
|
549 |
|
550 |
|
551 |
|
552 |
|
553 | ### OClif Source Repo
|
554 |
|
555 | Useful reference for writing tests:
|
556 |
|
557 | * https://github.com/oclif/command/blob/master/src/command.ts
|
558 | * https://github.com/oclif/config/blob/master/src/plugin.ts
|
559 |
|
560 |
|
561 | # Testing
|
562 |
|
563 | Isolate tests (run only specific tests in that file):
|
564 |
|
565 | test.only('it should run only tests suffixed with .only', async () => {
|
566 |
|
567 | ## Unit Tests (`test` directory)
|
568 |
|
569 | ### How to run Unit Tests
|
570 |
|
571 | 1. `npm test` or `npm t`
|
572 |
|
573 | ### Tips
|
574 |
|
575 | Run a single unit test, or filter them by filename:
|
576 |
|
577 | npx jest --testPathPattern=keycloak
|
578 |
|
579 | ## E2E Tests (`test_e2e` directory)
|
580 |
|
581 | The CLI has a number of robused E2E tests that are hosted inside of CTO.ai's private CI/CD infra.
|
582 |
|
583 | We are planning to expose this system via Github Actions in the future, but for now, a CTO.ai team member will review your PR and test coverage.
|
584 |
|
585 | ### How to run E2E tests locally
|
586 |
|
587 | The default test server is staging, but you can override this by passing in your own `OPS_REGISTRY_HOST` and `OPS_API_HOST` values from your shell config.
|
588 |
|
589 | Run tests against staging (as part of the CTO.ai platform developer workflow):
|
590 |
|
591 | 1. Run `npm run configdev` to point the ops binary at the development Typescript app (instead of the production Javascript bundle)
|
592 | 2. Ensure you have a `.env.staging` file (you can generate one by running scripts/make-env.sh)
|
593 | 3. Set your `NODE_ENV` to 'staging': `export NODE_ENV=staging`
|
594 | 4. `npm run test:e2e`
|
595 |
|
596 | Run tests against Minikube (as part of the CTO.ai platform developer workflow):
|
597 |
|
598 | 1. Create a user in Keycloak with the following credentials:
|
599 |
|
600 | ```
|
601 | - username: 'existing_user'
|
602 | - email: 'e2e_existing_user1@cto.ai'
|
603 | - password: 'password'
|
604 | ```
|
605 |
|
606 | 2. Change the userID in `test_e2e/utils/constants.ts EXISTING_USER_ID` to Step 1's userID
|
607 | 3. Create `existing_user` team in Database if haven't already
|
608 | 4. Change the teamID in `teste2e/utils/constants.ts EXISTING_TEAM_ID` to step 3's teamID
|
609 | 5. Create a `cto.ai` team in Database if haven't already
|
610 | 6. Publish this following command:
|
611 |
|
612 | ```
|
613 | - Team: ‘cto.ai’
|
614 | - name: ‘github’
|
615 | - version: ‘latest’
|
616 | - public: true
|
617 | ```
|
618 |
|
619 | 7. Publish the `write_a_file_op` command found in `test_e2e/sample_ops/write_a_file_op`
|
620 | 8. Publish the `echo_message_workflow` workflow found in `test_e2e/sample_ops/echo_message_workflow`
|
621 | 9. Add the `ops-cli-confidential` client to Keycloak. The `ops-cli-confidential.json` file can be found in Keybase
|
622 | 10. Run `npm run configdev` to point the ops binary at the development Typescript app (instead of the production Javascript bundle)
|
623 | 11. Ensure you have a `.env.test` file (you can generate one by running scripts/make-env.sh)
|
624 | 12. Modify the vars in `.env.test` to match your minikube IP
|
625 | 13. Set your `NODE_ENV` to 'test': `export NODE_ENV=test`
|
626 | 14. `npm run test:e2e`
|
627 |
|
628 | ### Tips
|
629 |
|
630 | Run a single E2E test, or filter test files by filename:
|
631 |
|
632 | npm run test:e2e --testPathPattern=signin
|