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