doploy-cli 0.2.0__tar.gz → 0.2.2__tar.gz

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.
@@ -0,0 +1,167 @@
1
+ Metadata-Version: 2.4
2
+ Name: doploy-cli
3
+ Version: 0.2.2
4
+ Summary: doploy CLI: watch builds, read logs, and drive Odoo deployments from a terminal
5
+ License: MIT
6
+ Project-URL: Homepage, https://doploy.io
7
+ Project-URL: Documentation, https://docs.doploy.io
8
+ Project-URL: Dashboard, https://cloud.doploy.io
9
+ Keywords: doploy,odoo,deploy,ci,cli
10
+ Classifier: Development Status :: 4 - Beta
11
+ Classifier: Environment :: Console
12
+ Classifier: Intended Audience :: Developers
13
+ Classifier: License :: OSI Approved :: MIT License
14
+ Classifier: Programming Language :: Python :: 3
15
+ Classifier: Programming Language :: Python :: 3 :: Only
16
+ Classifier: Topic :: Software Development :: Build Tools
17
+ Requires-Python: >=3.10
18
+ Description-Content-Type: text/markdown
19
+ License-File: LICENSE
20
+ Requires-Dist: httpx>=0.27
21
+ Dynamic: license-file
22
+
23
+ # doploy CLI
24
+
25
+ [![PyPI](https://img.shields.io/pypi/v/doploy-cli.svg)](https://pypi.org/project/doploy-cli/)
26
+ [![Python](https://img.shields.io/pypi/pyversions/doploy-cli.svg)](https://pypi.org/project/doploy-cli/)
27
+ [![License: MIT](https://img.shields.io/badge/license-MIT-blue.svg)](https://opensource.org/licenses/MIT)
28
+
29
+ The command line for [doploy](https://doploy.io), the Odoo hosting and CI platform.
30
+ Watch builds, read test results and logs, and drive deployments from your terminal.
31
+
32
+ ```console
33
+ $ doploy builds acme --type development
34
+ ID TYPE STATUS FQDN COMMIT_SHA CREATED
35
+ 418 development Active Error doploy-k3j9x2.doploy.site 9f1c2ab 2026-09-11T14:02:11
36
+
37
+ $ doploy tests 418
38
+ build 418 [Active Error] — 1 errors, 0 failures, 2 warnings
39
+
40
+ [ERROR] sale_custom.test_discounts
41
+ ```
42
+
43
+ ## Install
44
+
45
+ ```bash
46
+ pipx install doploy-cli
47
+ ```
48
+
49
+ or with `pip`, `uv`, or `pip install --user`:
50
+
51
+ ```bash
52
+ pip install doploy-cli
53
+ uv tool install doploy-cli
54
+ ```
55
+
56
+ Requires Python 3.10 or newer.
57
+
58
+ ## Using it from a coding agent
59
+
60
+ ```bash
61
+ doploy skill install
62
+ ```
63
+
64
+ Installs a skill file so Claude Code knows when to use `doploy`, how to find ids, and the
65
+ push → build → read failures → fix loop. `doploy skill print >> AGENTS.md` does the same for
66
+ Codex and other agents.
67
+
68
+ ## Sign in
69
+
70
+ ```bash
71
+ doploy login
72
+ ```
73
+
74
+ Your browser opens, you sign in with your doploy account, and the CLI is connected.
75
+ Sessions renew themselves. Sign out with `doploy logout`.
76
+
77
+ What the CLI may do is decided per app in **Settings → Connected apps** on the doploy
78
+ dashboard: read only, or read and deploy, on all projects or only some. Change it there at any
79
+ time; the change applies on the CLI's next command.
80
+
81
+ ## Quick start
82
+
83
+ ```bash
84
+ doploy projects # your projects and their ids
85
+ doploy builds <project-id> --type staging # recent builds
86
+ doploy build <build-id> # one build in full
87
+ doploy tests <build-id> --details # test failures with tracebacks
88
+ doploy logs <build-id> --source test -f # follow the test log until the build settles
89
+ ```
90
+
91
+ ## Commands
92
+
93
+ | Command | Description |
94
+ |---|---|
95
+ | `login` | Sign in with your browser |
96
+ | `skill install` | Teach Claude Code to use doploy (`skill print` for AGENTS.md) |
97
+ | `logout` | Forget the saved session |
98
+ | `projects` | List your projects |
99
+ | `builds <project>` | Live builds for a project. `--type development\|staging\|production`, `--limit`, `--all` |
100
+ | `branches <project>` | Live branches with their ids |
101
+ | `build <id>` | One build: status, commit, versions, error summary |
102
+ | `tests <build>` | Test failures for a build. `--details` prints tracebacks, `--warnings` includes warnings |
103
+ | `logs <build>` | Tail logs. `--source build\|test\|odoo`, `--lines`, `--filter TEXT`, `-f` to follow |
104
+ | `branch create <project> <name>` | Fork a development branch on GitHub and queue its build. `--from <branch-id>` |
105
+ | `rebuild <build>` | Queue a rebuild of a deployment |
106
+ | `restart <build>` | Restart the Odoo service |
107
+ | `update-modules <build> [modules]` | Run `odoo-bin -u` on the modules doploy detected as changed, or the ones you list. `--theme`, `--no-theme`, `--wait` |
108
+ | `operation <id>` | Check a queued module update. `--wait` |
109
+ | `backup <build>` | Take a database and filestore backup. `--comment`, `--wait` |
110
+
111
+ Commands that print tables accept `--json` for machine-readable output.
112
+
113
+ Anything aimed at a **production** deployment requires `--confirm`. Nothing destructive is
114
+ available: no deletes, no restores, no domain changes.
115
+
116
+ ## Examples
117
+
118
+ **Why did my build fail?**
119
+
120
+ ```bash
121
+ doploy builds acme --type development --limit 1
122
+ doploy tests 418 --details
123
+ doploy logs 418 --source test --filter ERROR
124
+ ```
125
+
126
+ **Follow a build as it runs**
127
+
128
+ ```bash
129
+ doploy logs 419 --source test -f
130
+ ```
131
+
132
+ Exits on its own when the build settles. `--source odoo` follows the running container's log
133
+ instead and runs until Ctrl-C.
134
+
135
+ **Ship a change to staging**
136
+
137
+ ```bash
138
+ doploy update-modules 302 --wait
139
+ ```
140
+
141
+ Updates exactly the modules doploy saw change in the last code update, waits for Odoo to finish,
142
+ and exits non-zero if the update failed. Add `--theme` to rebuild website theme assets, or leave it
143
+ out and doploy decides from the module list.
144
+
145
+ **Take a backup first**
146
+
147
+ ```bash
148
+ doploy backup 301 --confirm --wait --comment "before v2.4"
149
+ ```
150
+
151
+ ## Log sources
152
+
153
+ | `--source` | What you get |
154
+ |---|---|
155
+ | `build` | doploy's own build log and error summary. Fast, default. |
156
+ | `test` | The Odoo test run output of a development build. What actually failed. |
157
+ | `odoo` | The running Odoo container's log. Runtime tracebacks on staging and production. |
158
+
159
+ ## Links
160
+
161
+ - Documentation: https://docs.doploy.io/agents/cli
162
+ - Dashboard: https://cloud.doploy.io
163
+ - Support: support@doploy.io
164
+
165
+ ## License
166
+
167
+ MIT
@@ -0,0 +1,145 @@
1
+ # doploy CLI
2
+
3
+ [![PyPI](https://img.shields.io/pypi/v/doploy-cli.svg)](https://pypi.org/project/doploy-cli/)
4
+ [![Python](https://img.shields.io/pypi/pyversions/doploy-cli.svg)](https://pypi.org/project/doploy-cli/)
5
+ [![License: MIT](https://img.shields.io/badge/license-MIT-blue.svg)](https://opensource.org/licenses/MIT)
6
+
7
+ The command line for [doploy](https://doploy.io), the Odoo hosting and CI platform.
8
+ Watch builds, read test results and logs, and drive deployments from your terminal.
9
+
10
+ ```console
11
+ $ doploy builds acme --type development
12
+ ID TYPE STATUS FQDN COMMIT_SHA CREATED
13
+ 418 development Active Error doploy-k3j9x2.doploy.site 9f1c2ab 2026-09-11T14:02:11
14
+
15
+ $ doploy tests 418
16
+ build 418 [Active Error] — 1 errors, 0 failures, 2 warnings
17
+
18
+ [ERROR] sale_custom.test_discounts
19
+ ```
20
+
21
+ ## Install
22
+
23
+ ```bash
24
+ pipx install doploy-cli
25
+ ```
26
+
27
+ or with `pip`, `uv`, or `pip install --user`:
28
+
29
+ ```bash
30
+ pip install doploy-cli
31
+ uv tool install doploy-cli
32
+ ```
33
+
34
+ Requires Python 3.10 or newer.
35
+
36
+ ## Using it from a coding agent
37
+
38
+ ```bash
39
+ doploy skill install
40
+ ```
41
+
42
+ Installs a skill file so Claude Code knows when to use `doploy`, how to find ids, and the
43
+ push → build → read failures → fix loop. `doploy skill print >> AGENTS.md` does the same for
44
+ Codex and other agents.
45
+
46
+ ## Sign in
47
+
48
+ ```bash
49
+ doploy login
50
+ ```
51
+
52
+ Your browser opens, you sign in with your doploy account, and the CLI is connected.
53
+ Sessions renew themselves. Sign out with `doploy logout`.
54
+
55
+ What the CLI may do is decided per app in **Settings → Connected apps** on the doploy
56
+ dashboard: read only, or read and deploy, on all projects or only some. Change it there at any
57
+ time; the change applies on the CLI's next command.
58
+
59
+ ## Quick start
60
+
61
+ ```bash
62
+ doploy projects # your projects and their ids
63
+ doploy builds <project-id> --type staging # recent builds
64
+ doploy build <build-id> # one build in full
65
+ doploy tests <build-id> --details # test failures with tracebacks
66
+ doploy logs <build-id> --source test -f # follow the test log until the build settles
67
+ ```
68
+
69
+ ## Commands
70
+
71
+ | Command | Description |
72
+ |---|---|
73
+ | `login` | Sign in with your browser |
74
+ | `skill install` | Teach Claude Code to use doploy (`skill print` for AGENTS.md) |
75
+ | `logout` | Forget the saved session |
76
+ | `projects` | List your projects |
77
+ | `builds <project>` | Live builds for a project. `--type development\|staging\|production`, `--limit`, `--all` |
78
+ | `branches <project>` | Live branches with their ids |
79
+ | `build <id>` | One build: status, commit, versions, error summary |
80
+ | `tests <build>` | Test failures for a build. `--details` prints tracebacks, `--warnings` includes warnings |
81
+ | `logs <build>` | Tail logs. `--source build\|test\|odoo`, `--lines`, `--filter TEXT`, `-f` to follow |
82
+ | `branch create <project> <name>` | Fork a development branch on GitHub and queue its build. `--from <branch-id>` |
83
+ | `rebuild <build>` | Queue a rebuild of a deployment |
84
+ | `restart <build>` | Restart the Odoo service |
85
+ | `update-modules <build> [modules]` | Run `odoo-bin -u` on the modules doploy detected as changed, or the ones you list. `--theme`, `--no-theme`, `--wait` |
86
+ | `operation <id>` | Check a queued module update. `--wait` |
87
+ | `backup <build>` | Take a database and filestore backup. `--comment`, `--wait` |
88
+
89
+ Commands that print tables accept `--json` for machine-readable output.
90
+
91
+ Anything aimed at a **production** deployment requires `--confirm`. Nothing destructive is
92
+ available: no deletes, no restores, no domain changes.
93
+
94
+ ## Examples
95
+
96
+ **Why did my build fail?**
97
+
98
+ ```bash
99
+ doploy builds acme --type development --limit 1
100
+ doploy tests 418 --details
101
+ doploy logs 418 --source test --filter ERROR
102
+ ```
103
+
104
+ **Follow a build as it runs**
105
+
106
+ ```bash
107
+ doploy logs 419 --source test -f
108
+ ```
109
+
110
+ Exits on its own when the build settles. `--source odoo` follows the running container's log
111
+ instead and runs until Ctrl-C.
112
+
113
+ **Ship a change to staging**
114
+
115
+ ```bash
116
+ doploy update-modules 302 --wait
117
+ ```
118
+
119
+ Updates exactly the modules doploy saw change in the last code update, waits for Odoo to finish,
120
+ and exits non-zero if the update failed. Add `--theme` to rebuild website theme assets, or leave it
121
+ out and doploy decides from the module list.
122
+
123
+ **Take a backup first**
124
+
125
+ ```bash
126
+ doploy backup 301 --confirm --wait --comment "before v2.4"
127
+ ```
128
+
129
+ ## Log sources
130
+
131
+ | `--source` | What you get |
132
+ |---|---|
133
+ | `build` | doploy's own build log and error summary. Fast, default. |
134
+ | `test` | The Odoo test run output of a development build. What actually failed. |
135
+ | `odoo` | The running Odoo container's log. Runtime tracebacks on staging and production. |
136
+
137
+ ## Links
138
+
139
+ - Documentation: https://docs.doploy.io/agents/cli
140
+ - Dashboard: https://cloud.doploy.io
141
+ - Support: support@doploy.io
142
+
143
+ ## License
144
+
145
+ MIT
@@ -0,0 +1,63 @@
1
+ ---
2
+ name: doploy
3
+ description: Use the `doploy` CLI to watch Odoo builds, read test failures and logs, and update modules on doploy-hosted deployments. Use when the repo is an Odoo project deployed on doploy, when a build or test run needs checking, or when the user asks to deploy, update modules, or look at logs.
4
+ ---
5
+
6
+ # doploy
7
+
8
+ `doploy` is the command line for doploy, which builds and hosts Odoo projects from a GitHub
9
+ repo. Every branch push produces a development build with a full Odoo test run. Production and
10
+ staging are long-lived deployments that update in place.
11
+
12
+ Check it is installed and signed in with `doploy projects`. If that fails, tell the user to run
13
+ `pipx install doploy-cli && doploy login` (it opens a browser; do not try to sign in for them).
14
+
15
+ ## Finding ids
16
+
17
+ Ids are stable and worth reusing within a session.
18
+
19
+ ```bash
20
+ doploy projects # project id (short string, e.g. Bx2Nx)
21
+ doploy builds <project> --type development --limit 5 # build ids, newest first
22
+ doploy branches <project> # branch ids, for `branch create --from`
23
+ ```
24
+
25
+ Prefer `--json` when you need to parse output.
26
+
27
+ ## The loop after pushing code
28
+
29
+ 1. Push the commit. doploy builds the branch automatically.
30
+ 2. `doploy builds <project> --type development --limit 3` until the newest build for your
31
+ commit leaves `Building`. Poll every 30 seconds or so; builds take several minutes.
32
+ 3. On `Error` or `Active Error`: `doploy tests <build> --details` shows every failing test with
33
+ its traceback. `doploy logs <build> --source test --filter ERROR` shows the surrounding log.
34
+ 4. Fix, push, repeat. On `Success`, open the pull request.
35
+
36
+ Do not create a new build by hand for a branch you already pushed; the push did it.
37
+
38
+ ## Logs
39
+
40
+ ```bash
41
+ doploy logs <build> --source test -f # follow the test run until the build settles
42
+ doploy logs <build> --source odoo --filter Traceback # the running container (staging/prod)
43
+ doploy logs <build> --source build # doploy's own deploy log
44
+ ```
45
+
46
+ ## After a merge to staging or production
47
+
48
+ Code updates land in place. The changed modules still need `odoo-bin -u`:
49
+
50
+ ```bash
51
+ doploy update-modules <build> --wait # exactly the modules doploy saw change
52
+ ```
53
+
54
+ `--wait` exits non-zero if the update failed; print the tail it shows. Add `--theme` when a
55
+ website theme changed and the user says so.
56
+
57
+ ## Rules
58
+
59
+ - Anything aimed at production needs `--confirm`. Ask the user before adding it.
60
+ - `doploy backup <build> --confirm --wait` before risky production updates.
61
+ - The CLI cannot delete, restore, or change domains. Do not look for a way around that.
62
+ - Deploy commands may return "Deploy actions are not enabled". The user turns that on in
63
+ doploy under Settings → Connected apps. Do not retry until they say it is done.
@@ -232,7 +232,7 @@ def cmd_login(args):
232
232
  _browser_login(base)
233
233
  projects = _client(argparse.Namespace(token=None, base=base)).request('GET', '/projects')
234
234
  print(f'logged in; {len(projects["projects"])} project(s) visible; config saved to {CONFIG_PATH}')
235
- print('Deploy actions: toggle "Allow deploy actions" in Settings > MCP Connections.')
235
+ print('Deploy actions: toggle "Allow deploy actions" in Settings > Connected apps.')
236
236
 
237
237
 
238
238
  def cmd_logout(args):
@@ -240,7 +240,7 @@ def cmd_logout(args):
240
240
  for k in ('token', 'access_token', 'refresh_token', 'client_id', 'expires_at'):
241
241
  cfg.pop(k, None)
242
242
  _save_config(cfg)
243
- print('logged out (revoke the grant in Settings > MCP Connections to kill the session server-side)')
243
+ print('logged out (revoke the grant in Settings > Connected apps to kill the session server-side)')
244
244
 
245
245
 
246
246
  def cmd_projects(args):
@@ -251,15 +251,39 @@ def cmd_projects(args):
251
251
  _table(data['projects'], ['id', 'name', 'odoo_version'])
252
252
 
253
253
 
254
+ def _short(rows: list[dict]) -> list[dict]:
255
+ """Table-friendly copies: 7-char commit, minute-precision timestamps."""
256
+ out = []
257
+ for r in rows:
258
+ r = dict(r)
259
+ if r.get('commit_sha'):
260
+ r['commit'] = r['commit_sha'][:7]
261
+ if r.get('created'):
262
+ r['created'] = r['created'][:16].replace('T', ' ')
263
+ out.append(r)
264
+ return out
265
+
266
+
254
267
  def cmd_builds(args):
255
268
  params = {'limit': str(args.limit)}
256
269
  if args.type:
257
270
  params['type'] = args.type
271
+ if args.all:
272
+ params['all'] = '1'
258
273
  data = _client(args).request('GET', f'/projects/{args.project}/builds', params=params)
259
274
  if args.json:
260
275
  print(json.dumps(data, indent=2))
261
276
  return
262
- _table(data['builds'], ['id', 'type', 'status', 'fqdn', 'commit_sha', 'created'])
277
+ _table(_short(data['builds']), ['id', 'type', 'status', 'fqdn', 'commit', 'created'])
278
+
279
+
280
+ def cmd_branches(args):
281
+ params = {'all': '1'} if args.all else None
282
+ data = _client(args).request('GET', f'/projects/{args.project}/branches', params=params)
283
+ if args.json:
284
+ print(json.dumps(data, indent=2))
285
+ return
286
+ _table(data['branches'], ['id', 'name', 'type'])
263
287
 
264
288
 
265
289
  def cmd_build(args):
@@ -276,9 +300,11 @@ def cmd_tests(args):
276
300
  print(f"build {data['build_id']} [{data['build_status']}] — "
277
301
  f"{c['error']} errors, {c['fail']} failures, {c['warning']} warnings")
278
302
  for r in data['results']:
279
- if r['error_type'] == 'WARNING' and not args.warnings:
303
+ if r['error_type'] not in ('ERROR', 'FAIL') and not args.warnings:
280
304
  continue
281
- print(f"\n[{r['error_type']}] {r['module']}.{r['test']}")
305
+ where = (f"{r['module']}.{r['test']}" if r.get('test') and r['test'] != 'Unknown'
306
+ else '(module loading)')
307
+ print(f"\n[{r['error_type']}] {where}")
282
308
  if args.details:
283
309
  print(r['details'])
284
310
 
@@ -329,15 +355,14 @@ def cmd_logs(args):
329
355
  if args.source == 'build':
330
356
  if data.get('error_summary'):
331
357
  print(f"error summary: {data['error_summary']}\n")
332
- for t in data.get('tasks') or []:
333
- print(f"task {t['id']} [{t['status']}] {t['title']}")
334
- if data.get('tasks'):
335
- print()
336
358
  shown = data['lines']
337
359
  for ln in shown:
338
360
  print(ln)
339
361
  if not args.follow:
340
- if data.get('truncated'):
362
+ if args.filter:
363
+ print(f"... ({len(shown)} matching line(s) in the last {data.get('total_lines', '?')}; "
364
+ f"raise --lines to search further back)", file=sys.stderr)
365
+ elif data.get('truncated'):
341
366
  print(f"... (showing last {len(shown)} lines; use --lines to see more)", file=sys.stderr)
342
367
  return
343
368
  # Follow: poll and print only what is new. Build and test logs end when
@@ -383,27 +408,28 @@ def cmd_update_modules(args):
383
408
  body['install_theme'] = args.theme
384
409
  data = _client(args).request('POST', f'/builds/{args.build_id}/update-modules', json=body)
385
410
  theme = ' with INSTALL_THEME=1' if data.get('install_theme') else ''
386
- print(f"update queued (task {data['task_id']}): {', '.join(data['modules'])}{theme}")
411
+ print(f"update queued (operation {data['operation_id']}): {', '.join(data['modules'])}{theme}")
387
412
  if not args.wait:
388
- print(f"poll with: doploy task {data['task_id']}")
413
+ print(f"check with: doploy operation {data['operation_id']}")
389
414
  return
390
- task = _wait_for_task(_client(args), data['task_id'], args.interval)
391
- _print_task(task)
392
- if task['status'] != 'completed' or (task.get('result') or {}).get('ok') is False:
415
+ op = _wait_for_operation(_client(args), data['operation_id'], args.interval)
416
+ _print_operation(op)
417
+ if op['status'] != 'completed' or (op.get('result') or {}).get('ok') is False:
393
418
  sys.exit(1)
394
419
 
395
420
 
396
- def _wait_for_task(client: Client, task_id: int, interval: float) -> dict:
421
+ def _wait_for_operation(client: Client, operation_id: int, interval: float) -> dict:
397
422
  while True:
398
- task = client.request('GET', f'/tasks/{task_id}')['task']
399
- if task['status'] in ('completed', 'failed', 'cancelled'):
400
- return task
423
+ op = client.request('GET', f'/operations/{operation_id}')['operation']
424
+ if op['status'] in ('completed', 'failed', 'cancelled'):
425
+ return op
401
426
  time.sleep(interval)
402
427
 
403
428
 
404
- def _print_task(task: dict) -> None:
405
- print(f"task {task['id']} [{task['status']}] {task['title']}")
406
- result = task.get('result')
429
+ def _print_operation(op: dict) -> None:
430
+ what = f"update modules {', '.join(op['modules'])}" if op.get('modules') else op.get('kind') or 'operation'
431
+ print(f"operation {op['id']} [{op['status']}] {what}")
432
+ result = op.get('result')
407
433
  if result:
408
434
  if 'exit_code' in result:
409
435
  print(f"exit code: {result['exit_code']}")
@@ -413,14 +439,14 @@ def _print_task(task: dict) -> None:
413
439
  print(result['output'])
414
440
 
415
441
 
416
- def cmd_task(args):
442
+ def cmd_operation(args):
417
443
  client = _client(args)
418
- task = _wait_for_task(client, args.task_id, args.interval) if args.wait \
419
- else client.request('GET', f'/tasks/{args.task_id}')['task']
444
+ op = _wait_for_operation(client, args.operation_id, args.interval) if args.wait \
445
+ else client.request('GET', f'/operations/{args.operation_id}')['operation']
420
446
  if args.json:
421
- print(json.dumps(task, indent=2))
447
+ print(json.dumps(op, indent=2))
422
448
  return
423
- _print_task(task)
449
+ _print_operation(op)
424
450
 
425
451
 
426
452
  def cmd_backup(args):
@@ -442,6 +468,34 @@ def cmd_backup(args):
442
468
  sys.exit(1)
443
469
 
444
470
 
471
+ # --- agent skill ------------------------------------------------------------
472
+ #
473
+ # The skill ships inside the package (doploy_cli/SKILL.md) so no public repo
474
+ # is needed. `doploy skill install` drops it where Claude Code discovers it;
475
+ # `doploy skill print` gives the same text for AGENTS.md / other agents.
476
+
477
+ def _skill_text() -> str:
478
+ from importlib import resources
479
+ return resources.files('doploy_cli').joinpath('SKILL.md').read_text(encoding='utf-8')
480
+
481
+
482
+ def _skill_target(project: bool) -> Path:
483
+ base = Path.cwd() if project else Path.home()
484
+ return base / '.claude' / 'skills' / 'doploy' / 'SKILL.md'
485
+
486
+
487
+ def cmd_skill(args):
488
+ if args.skill_command == 'print':
489
+ print(_skill_text(), end='')
490
+ return
491
+ target = _skill_target(args.project)
492
+ target.parent.mkdir(parents=True, exist_ok=True)
493
+ target.write_text(_skill_text(), encoding='utf-8')
494
+ scope = 'this project' if args.project else 'all projects'
495
+ print(f'installed doploy skill for Claude Code ({scope}): {target}')
496
+ print('Other agents: `doploy skill print >> AGENTS.md`')
497
+
498
+
445
499
  def main(argv=None):
446
500
  p = argparse.ArgumentParser(prog='doploy', description=__doc__.splitlines()[0])
447
501
  p.add_argument('--token', help=argparse.SUPPRESS)
@@ -456,17 +510,33 @@ def main(argv=None):
456
510
  sp = sub.add_parser('logout', help='forget saved credentials')
457
511
  sp.set_defaults(func=cmd_logout)
458
512
 
513
+ sp = sub.add_parser('skill', help='teach coding agents how to use doploy')
514
+ ssub = sp.add_subparsers(dest='skill_command', required=True)
515
+ ip = ssub.add_parser('install', help='install the Claude Code skill (~/.claude/skills/doploy)')
516
+ ip.add_argument('--project', action='store_true',
517
+ help='install into ./.claude/skills instead of your home directory')
518
+ ip.set_defaults(func=cmd_skill)
519
+ pp = ssub.add_parser('print', help='print the skill text, e.g. for AGENTS.md')
520
+ pp.set_defaults(func=cmd_skill)
521
+
459
522
  sp = sub.add_parser('projects', help='list your projects')
460
523
  sp.add_argument('--json', action='store_true')
461
524
  sp.set_defaults(func=cmd_projects)
462
525
 
463
- sp = sub.add_parser('builds', help='list builds for a project')
526
+ sp = sub.add_parser('builds', help='list live builds for a project')
464
527
  sp.add_argument('project', help='project id (from `doploy projects`)')
465
528
  sp.add_argument('--type', choices=['development', 'staging', 'production'])
466
529
  sp.add_argument('--limit', type=int, default=20)
530
+ sp.add_argument('--all', action='store_true', help='include torn-down builds')
467
531
  sp.add_argument('--json', action='store_true')
468
532
  sp.set_defaults(func=cmd_builds)
469
533
 
534
+ sp = sub.add_parser('branches', help='list live branches for a project')
535
+ sp.add_argument('project', help='project id (from `doploy projects`)')
536
+ sp.add_argument('--all', action='store_true', help='include branches whose git ref is gone')
537
+ sp.add_argument('--json', action='store_true')
538
+ sp.set_defaults(func=cmd_branches)
539
+
470
540
  sp = sub.add_parser('build', help='show one build')
471
541
  sp.add_argument('build_id', type=int)
472
542
  sp.set_defaults(func=cmd_build)
@@ -529,12 +599,12 @@ def main(argv=None):
529
599
  sp.add_argument('--interval', type=float, default=10.0, help='poll seconds for --wait')
530
600
  sp.set_defaults(func=cmd_update_modules)
531
601
 
532
- sp = sub.add_parser('task', help='show a queued task (module update)')
533
- sp.add_argument('task_id', type=int)
602
+ sp = sub.add_parser('operation', help='check a queued module update')
603
+ sp.add_argument('operation_id', type=int)
534
604
  sp.add_argument('--wait', action='store_true', help='block until it finishes')
535
605
  sp.add_argument('--interval', type=float, default=10.0)
536
606
  sp.add_argument('--json', action='store_true')
537
- sp.set_defaults(func=cmd_task)
607
+ sp.set_defaults(func=cmd_operation)
538
608
 
539
609
  sp = sub.add_parser('backup', help='start a backup of a deployment (deploy scope)')
540
610
  sp.add_argument('build_id', type=int)
@@ -0,0 +1,167 @@
1
+ Metadata-Version: 2.4
2
+ Name: doploy-cli
3
+ Version: 0.2.2
4
+ Summary: doploy CLI: watch builds, read logs, and drive Odoo deployments from a terminal
5
+ License: MIT
6
+ Project-URL: Homepage, https://doploy.io
7
+ Project-URL: Documentation, https://docs.doploy.io
8
+ Project-URL: Dashboard, https://cloud.doploy.io
9
+ Keywords: doploy,odoo,deploy,ci,cli
10
+ Classifier: Development Status :: 4 - Beta
11
+ Classifier: Environment :: Console
12
+ Classifier: Intended Audience :: Developers
13
+ Classifier: License :: OSI Approved :: MIT License
14
+ Classifier: Programming Language :: Python :: 3
15
+ Classifier: Programming Language :: Python :: 3 :: Only
16
+ Classifier: Topic :: Software Development :: Build Tools
17
+ Requires-Python: >=3.10
18
+ Description-Content-Type: text/markdown
19
+ License-File: LICENSE
20
+ Requires-Dist: httpx>=0.27
21
+ Dynamic: license-file
22
+
23
+ # doploy CLI
24
+
25
+ [![PyPI](https://img.shields.io/pypi/v/doploy-cli.svg)](https://pypi.org/project/doploy-cli/)
26
+ [![Python](https://img.shields.io/pypi/pyversions/doploy-cli.svg)](https://pypi.org/project/doploy-cli/)
27
+ [![License: MIT](https://img.shields.io/badge/license-MIT-blue.svg)](https://opensource.org/licenses/MIT)
28
+
29
+ The command line for [doploy](https://doploy.io), the Odoo hosting and CI platform.
30
+ Watch builds, read test results and logs, and drive deployments from your terminal.
31
+
32
+ ```console
33
+ $ doploy builds acme --type development
34
+ ID TYPE STATUS FQDN COMMIT_SHA CREATED
35
+ 418 development Active Error doploy-k3j9x2.doploy.site 9f1c2ab 2026-09-11T14:02:11
36
+
37
+ $ doploy tests 418
38
+ build 418 [Active Error] — 1 errors, 0 failures, 2 warnings
39
+
40
+ [ERROR] sale_custom.test_discounts
41
+ ```
42
+
43
+ ## Install
44
+
45
+ ```bash
46
+ pipx install doploy-cli
47
+ ```
48
+
49
+ or with `pip`, `uv`, or `pip install --user`:
50
+
51
+ ```bash
52
+ pip install doploy-cli
53
+ uv tool install doploy-cli
54
+ ```
55
+
56
+ Requires Python 3.10 or newer.
57
+
58
+ ## Using it from a coding agent
59
+
60
+ ```bash
61
+ doploy skill install
62
+ ```
63
+
64
+ Installs a skill file so Claude Code knows when to use `doploy`, how to find ids, and the
65
+ push → build → read failures → fix loop. `doploy skill print >> AGENTS.md` does the same for
66
+ Codex and other agents.
67
+
68
+ ## Sign in
69
+
70
+ ```bash
71
+ doploy login
72
+ ```
73
+
74
+ Your browser opens, you sign in with your doploy account, and the CLI is connected.
75
+ Sessions renew themselves. Sign out with `doploy logout`.
76
+
77
+ What the CLI may do is decided per app in **Settings → Connected apps** on the doploy
78
+ dashboard: read only, or read and deploy, on all projects or only some. Change it there at any
79
+ time; the change applies on the CLI's next command.
80
+
81
+ ## Quick start
82
+
83
+ ```bash
84
+ doploy projects # your projects and their ids
85
+ doploy builds <project-id> --type staging # recent builds
86
+ doploy build <build-id> # one build in full
87
+ doploy tests <build-id> --details # test failures with tracebacks
88
+ doploy logs <build-id> --source test -f # follow the test log until the build settles
89
+ ```
90
+
91
+ ## Commands
92
+
93
+ | Command | Description |
94
+ |---|---|
95
+ | `login` | Sign in with your browser |
96
+ | `skill install` | Teach Claude Code to use doploy (`skill print` for AGENTS.md) |
97
+ | `logout` | Forget the saved session |
98
+ | `projects` | List your projects |
99
+ | `builds <project>` | Live builds for a project. `--type development\|staging\|production`, `--limit`, `--all` |
100
+ | `branches <project>` | Live branches with their ids |
101
+ | `build <id>` | One build: status, commit, versions, error summary |
102
+ | `tests <build>` | Test failures for a build. `--details` prints tracebacks, `--warnings` includes warnings |
103
+ | `logs <build>` | Tail logs. `--source build\|test\|odoo`, `--lines`, `--filter TEXT`, `-f` to follow |
104
+ | `branch create <project> <name>` | Fork a development branch on GitHub and queue its build. `--from <branch-id>` |
105
+ | `rebuild <build>` | Queue a rebuild of a deployment |
106
+ | `restart <build>` | Restart the Odoo service |
107
+ | `update-modules <build> [modules]` | Run `odoo-bin -u` on the modules doploy detected as changed, or the ones you list. `--theme`, `--no-theme`, `--wait` |
108
+ | `operation <id>` | Check a queued module update. `--wait` |
109
+ | `backup <build>` | Take a database and filestore backup. `--comment`, `--wait` |
110
+
111
+ Commands that print tables accept `--json` for machine-readable output.
112
+
113
+ Anything aimed at a **production** deployment requires `--confirm`. Nothing destructive is
114
+ available: no deletes, no restores, no domain changes.
115
+
116
+ ## Examples
117
+
118
+ **Why did my build fail?**
119
+
120
+ ```bash
121
+ doploy builds acme --type development --limit 1
122
+ doploy tests 418 --details
123
+ doploy logs 418 --source test --filter ERROR
124
+ ```
125
+
126
+ **Follow a build as it runs**
127
+
128
+ ```bash
129
+ doploy logs 419 --source test -f
130
+ ```
131
+
132
+ Exits on its own when the build settles. `--source odoo` follows the running container's log
133
+ instead and runs until Ctrl-C.
134
+
135
+ **Ship a change to staging**
136
+
137
+ ```bash
138
+ doploy update-modules 302 --wait
139
+ ```
140
+
141
+ Updates exactly the modules doploy saw change in the last code update, waits for Odoo to finish,
142
+ and exits non-zero if the update failed. Add `--theme` to rebuild website theme assets, or leave it
143
+ out and doploy decides from the module list.
144
+
145
+ **Take a backup first**
146
+
147
+ ```bash
148
+ doploy backup 301 --confirm --wait --comment "before v2.4"
149
+ ```
150
+
151
+ ## Log sources
152
+
153
+ | `--source` | What you get |
154
+ |---|---|
155
+ | `build` | doploy's own build log and error summary. Fast, default. |
156
+ | `test` | The Odoo test run output of a development build. What actually failed. |
157
+ | `odoo` | The running Odoo container's log. Runtime tracebacks on staging and production. |
158
+
159
+ ## Links
160
+
161
+ - Documentation: https://docs.doploy.io/agents/cli
162
+ - Dashboard: https://cloud.doploy.io
163
+ - Support: support@doploy.io
164
+
165
+ ## License
166
+
167
+ MIT
@@ -1,6 +1,7 @@
1
1
  LICENSE
2
2
  README.md
3
3
  pyproject.toml
4
+ doploy_cli/SKILL.md
4
5
  doploy_cli/__init__.py
5
6
  doploy_cli/main.py
6
7
  doploy_cli.egg-info/PKG-INFO
@@ -4,8 +4,8 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "doploy-cli"
7
- version = "0.2.0"
8
- description = "doploy CLI: watch builds, read logs, and drive Odoo deployments from a terminal or CI"
7
+ version = "0.2.2"
8
+ description = "doploy CLI: watch builds, read logs, and drive Odoo deployments from a terminal"
9
9
  readme = "README.md"
10
10
  license = { text = "MIT" }
11
11
  requires-python = ">=3.10"
@@ -31,3 +31,6 @@ doploy = "doploy_cli.main:main"
31
31
 
32
32
  [tool.setuptools.packages.find]
33
33
  include = ["doploy_cli*"]
34
+
35
+ [tool.setuptools.package-data]
36
+ doploy_cli = ["SKILL.md"]
doploy_cli-0.2.0/PKG-INFO DELETED
@@ -1,63 +0,0 @@
1
- Metadata-Version: 2.4
2
- Name: doploy-cli
3
- Version: 0.2.0
4
- Summary: doploy CLI: watch builds, read logs, and drive Odoo deployments from a terminal or CI
5
- License: MIT
6
- Project-URL: Homepage, https://doploy.io
7
- Project-URL: Documentation, https://docs.doploy.io
8
- Project-URL: Dashboard, https://cloud.doploy.io
9
- Keywords: doploy,odoo,deploy,ci,cli
10
- Classifier: Development Status :: 4 - Beta
11
- Classifier: Environment :: Console
12
- Classifier: Intended Audience :: Developers
13
- Classifier: License :: OSI Approved :: MIT License
14
- Classifier: Programming Language :: Python :: 3
15
- Classifier: Programming Language :: Python :: 3 :: Only
16
- Classifier: Topic :: Software Development :: Build Tools
17
- Requires-Python: >=3.10
18
- Description-Content-Type: text/markdown
19
- License-File: LICENSE
20
- Requires-Dist: httpx>=0.27
21
- Dynamic: license-file
22
-
23
- # doploy CLI
24
-
25
- Watch builds, read logs, and drive your Odoo deployments on [doploy](https://doploy.io)
26
- from a terminal or a CI pipeline.
27
-
28
- ```bash
29
- pipx install doploy-cli
30
- doploy login # opens your browser; no tokens to paste
31
- doploy projects
32
- doploy builds <project-id> --type production
33
- doploy logs <build-id> --source test -f
34
- doploy update-modules <build-id> --wait
35
- ```
36
-
37
- ## Auth
38
-
39
- `doploy login` signs you in with your doploy account (OAuth, PKCE, loopback
40
- callback). Tokens refresh themselves and live in `~/.config/doploy/config.json`
41
- (mode 0600). Whether the CLI may deploy is controlled per app in
42
- Settings > Connected apps.
43
-
44
-
45
- ## Commands
46
-
47
- | Command | What it does |
48
- |---|---|
49
- | `projects` | List your projects |
50
- | `builds <project>` | Recent builds, filter with `--type` |
51
- | `build <id>` | One build in full |
52
- | `tests <build>` | Test failures, `--details` for tracebacks |
53
- | `logs <build>` | Tail logs; `--source build\|test\|odoo`, `-f` to follow |
54
- | `branch create <project> <name>` | Fork a dev branch and queue its build |
55
- | `rebuild <build>` | Queue a rebuild |
56
- | `restart <build>` | Restart the Odoo service |
57
- | `update-modules <build> [modules]` | Run `odoo-bin -u`; `--theme`, `--wait` |
58
- | `backup <build>` | Start a backup; `--wait` |
59
- | `task <id>` | Poll a queued task |
60
- | `logout` | Forget saved credentials |
61
-
62
- Production targets always need `--confirm`. Destructive operations
63
- (deletes, restores) are not exposed.
@@ -1,41 +0,0 @@
1
- # doploy CLI
2
-
3
- Watch builds, read logs, and drive your Odoo deployments on [doploy](https://doploy.io)
4
- from a terminal or a CI pipeline.
5
-
6
- ```bash
7
- pipx install doploy-cli
8
- doploy login # opens your browser; no tokens to paste
9
- doploy projects
10
- doploy builds <project-id> --type production
11
- doploy logs <build-id> --source test -f
12
- doploy update-modules <build-id> --wait
13
- ```
14
-
15
- ## Auth
16
-
17
- `doploy login` signs you in with your doploy account (OAuth, PKCE, loopback
18
- callback). Tokens refresh themselves and live in `~/.config/doploy/config.json`
19
- (mode 0600). Whether the CLI may deploy is controlled per app in
20
- Settings > Connected apps.
21
-
22
-
23
- ## Commands
24
-
25
- | Command | What it does |
26
- |---|---|
27
- | `projects` | List your projects |
28
- | `builds <project>` | Recent builds, filter with `--type` |
29
- | `build <id>` | One build in full |
30
- | `tests <build>` | Test failures, `--details` for tracebacks |
31
- | `logs <build>` | Tail logs; `--source build\|test\|odoo`, `-f` to follow |
32
- | `branch create <project> <name>` | Fork a dev branch and queue its build |
33
- | `rebuild <build>` | Queue a rebuild |
34
- | `restart <build>` | Restart the Odoo service |
35
- | `update-modules <build> [modules]` | Run `odoo-bin -u`; `--theme`, `--wait` |
36
- | `backup <build>` | Start a backup; `--wait` |
37
- | `task <id>` | Poll a queued task |
38
- | `logout` | Forget saved credentials |
39
-
40
- Production targets always need `--confirm`. Destructive operations
41
- (deletes, restores) are not exposed.
@@ -1,63 +0,0 @@
1
- Metadata-Version: 2.4
2
- Name: doploy-cli
3
- Version: 0.2.0
4
- Summary: doploy CLI: watch builds, read logs, and drive Odoo deployments from a terminal or CI
5
- License: MIT
6
- Project-URL: Homepage, https://doploy.io
7
- Project-URL: Documentation, https://docs.doploy.io
8
- Project-URL: Dashboard, https://cloud.doploy.io
9
- Keywords: doploy,odoo,deploy,ci,cli
10
- Classifier: Development Status :: 4 - Beta
11
- Classifier: Environment :: Console
12
- Classifier: Intended Audience :: Developers
13
- Classifier: License :: OSI Approved :: MIT License
14
- Classifier: Programming Language :: Python :: 3
15
- Classifier: Programming Language :: Python :: 3 :: Only
16
- Classifier: Topic :: Software Development :: Build Tools
17
- Requires-Python: >=3.10
18
- Description-Content-Type: text/markdown
19
- License-File: LICENSE
20
- Requires-Dist: httpx>=0.27
21
- Dynamic: license-file
22
-
23
- # doploy CLI
24
-
25
- Watch builds, read logs, and drive your Odoo deployments on [doploy](https://doploy.io)
26
- from a terminal or a CI pipeline.
27
-
28
- ```bash
29
- pipx install doploy-cli
30
- doploy login # opens your browser; no tokens to paste
31
- doploy projects
32
- doploy builds <project-id> --type production
33
- doploy logs <build-id> --source test -f
34
- doploy update-modules <build-id> --wait
35
- ```
36
-
37
- ## Auth
38
-
39
- `doploy login` signs you in with your doploy account (OAuth, PKCE, loopback
40
- callback). Tokens refresh themselves and live in `~/.config/doploy/config.json`
41
- (mode 0600). Whether the CLI may deploy is controlled per app in
42
- Settings > Connected apps.
43
-
44
-
45
- ## Commands
46
-
47
- | Command | What it does |
48
- |---|---|
49
- | `projects` | List your projects |
50
- | `builds <project>` | Recent builds, filter with `--type` |
51
- | `build <id>` | One build in full |
52
- | `tests <build>` | Test failures, `--details` for tracebacks |
53
- | `logs <build>` | Tail logs; `--source build\|test\|odoo`, `-f` to follow |
54
- | `branch create <project> <name>` | Fork a dev branch and queue its build |
55
- | `rebuild <build>` | Queue a rebuild |
56
- | `restart <build>` | Restart the Odoo service |
57
- | `update-modules <build> [modules]` | Run `odoo-bin -u`; `--theme`, `--wait` |
58
- | `backup <build>` | Start a backup; `--wait` |
59
- | `task <id>` | Poll a queued task |
60
- | `logout` | Forget saved credentials |
61
-
62
- Production targets always need `--confirm`. Destructive operations
63
- (deletes, restores) are not exposed.
File without changes
File without changes