doploy-cli 0.2.1__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.
- {doploy_cli-0.2.1 → doploy_cli-0.2.2}/PKG-INFO +14 -2
- {doploy_cli-0.2.1 → doploy_cli-0.2.2}/README.md +13 -1
- doploy_cli-0.2.2/doploy_cli/SKILL.md +63 -0
- {doploy_cli-0.2.1 → doploy_cli-0.2.2}/doploy_cli/main.py +80 -11
- {doploy_cli-0.2.1 → doploy_cli-0.2.2}/doploy_cli.egg-info/PKG-INFO +14 -2
- {doploy_cli-0.2.1 → doploy_cli-0.2.2}/doploy_cli.egg-info/SOURCES.txt +1 -0
- {doploy_cli-0.2.1 → doploy_cli-0.2.2}/pyproject.toml +4 -1
- {doploy_cli-0.2.1 → doploy_cli-0.2.2}/LICENSE +0 -0
- {doploy_cli-0.2.1 → doploy_cli-0.2.2}/doploy_cli/__init__.py +0 -0
- {doploy_cli-0.2.1 → doploy_cli-0.2.2}/doploy_cli.egg-info/dependency_links.txt +0 -0
- {doploy_cli-0.2.1 → doploy_cli-0.2.2}/doploy_cli.egg-info/entry_points.txt +0 -0
- {doploy_cli-0.2.1 → doploy_cli-0.2.2}/doploy_cli.egg-info/requires.txt +0 -0
- {doploy_cli-0.2.1 → doploy_cli-0.2.2}/doploy_cli.egg-info/top_level.txt +0 -0
- {doploy_cli-0.2.1 → doploy_cli-0.2.2}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: doploy-cli
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.2
|
|
4
4
|
Summary: doploy CLI: watch builds, read logs, and drive Odoo deployments from a terminal
|
|
5
5
|
License: MIT
|
|
6
6
|
Project-URL: Homepage, https://doploy.io
|
|
@@ -55,6 +55,16 @@ uv tool install doploy-cli
|
|
|
55
55
|
|
|
56
56
|
Requires Python 3.10 or newer.
|
|
57
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
|
+
|
|
58
68
|
## Sign in
|
|
59
69
|
|
|
60
70
|
```bash
|
|
@@ -83,9 +93,11 @@ doploy logs <build-id> --source test -f # follow the test log until the bui
|
|
|
83
93
|
| Command | Description |
|
|
84
94
|
|---|---|
|
|
85
95
|
| `login` | Sign in with your browser |
|
|
96
|
+
| `skill install` | Teach Claude Code to use doploy (`skill print` for AGENTS.md) |
|
|
86
97
|
| `logout` | Forget the saved session |
|
|
87
98
|
| `projects` | List your projects |
|
|
88
|
-
| `builds <project>` |
|
|
99
|
+
| `builds <project>` | Live builds for a project. `--type development\|staging\|production`, `--limit`, `--all` |
|
|
100
|
+
| `branches <project>` | Live branches with their ids |
|
|
89
101
|
| `build <id>` | One build: status, commit, versions, error summary |
|
|
90
102
|
| `tests <build>` | Test failures for a build. `--details` prints tracebacks, `--warnings` includes warnings |
|
|
91
103
|
| `logs <build>` | Tail logs. `--source build\|test\|odoo`, `--lines`, `--filter TEXT`, `-f` to follow |
|
|
@@ -33,6 +33,16 @@ uv tool install doploy-cli
|
|
|
33
33
|
|
|
34
34
|
Requires Python 3.10 or newer.
|
|
35
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
|
+
|
|
36
46
|
## Sign in
|
|
37
47
|
|
|
38
48
|
```bash
|
|
@@ -61,9 +71,11 @@ doploy logs <build-id> --source test -f # follow the test log until the bui
|
|
|
61
71
|
| Command | Description |
|
|
62
72
|
|---|---|
|
|
63
73
|
| `login` | Sign in with your browser |
|
|
74
|
+
| `skill install` | Teach Claude Code to use doploy (`skill print` for AGENTS.md) |
|
|
64
75
|
| `logout` | Forget the saved session |
|
|
65
76
|
| `projects` | List your projects |
|
|
66
|
-
| `builds <project>` |
|
|
77
|
+
| `builds <project>` | Live builds for a project. `--type development\|staging\|production`, `--limit`, `--all` |
|
|
78
|
+
| `branches <project>` | Live branches with their ids |
|
|
67
79
|
| `build <id>` | One build: status, commit, versions, error summary |
|
|
68
80
|
| `tests <build>` | Test failures for a build. `--details` prints tracebacks, `--warnings` includes warnings |
|
|
69
81
|
| `logs <build>` | Tail logs. `--source build\|test\|odoo`, `--lines`, `--filter TEXT`, `-f` to follow |
|
|
@@ -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 >
|
|
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 >
|
|
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', '
|
|
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']
|
|
303
|
+
if r['error_type'] not in ('ERROR', 'FAIL') and not args.warnings:
|
|
280
304
|
continue
|
|
281
|
-
|
|
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
|
|
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
|
|
@@ -443,6 +468,34 @@ def cmd_backup(args):
|
|
|
443
468
|
sys.exit(1)
|
|
444
469
|
|
|
445
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
|
+
|
|
446
499
|
def main(argv=None):
|
|
447
500
|
p = argparse.ArgumentParser(prog='doploy', description=__doc__.splitlines()[0])
|
|
448
501
|
p.add_argument('--token', help=argparse.SUPPRESS)
|
|
@@ -457,17 +510,33 @@ def main(argv=None):
|
|
|
457
510
|
sp = sub.add_parser('logout', help='forget saved credentials')
|
|
458
511
|
sp.set_defaults(func=cmd_logout)
|
|
459
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
|
+
|
|
460
522
|
sp = sub.add_parser('projects', help='list your projects')
|
|
461
523
|
sp.add_argument('--json', action='store_true')
|
|
462
524
|
sp.set_defaults(func=cmd_projects)
|
|
463
525
|
|
|
464
|
-
sp = sub.add_parser('builds', help='list builds for a project')
|
|
526
|
+
sp = sub.add_parser('builds', help='list live builds for a project')
|
|
465
527
|
sp.add_argument('project', help='project id (from `doploy projects`)')
|
|
466
528
|
sp.add_argument('--type', choices=['development', 'staging', 'production'])
|
|
467
529
|
sp.add_argument('--limit', type=int, default=20)
|
|
530
|
+
sp.add_argument('--all', action='store_true', help='include torn-down builds')
|
|
468
531
|
sp.add_argument('--json', action='store_true')
|
|
469
532
|
sp.set_defaults(func=cmd_builds)
|
|
470
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
|
+
|
|
471
540
|
sp = sub.add_parser('build', help='show one build')
|
|
472
541
|
sp.add_argument('build_id', type=int)
|
|
473
542
|
sp.set_defaults(func=cmd_build)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: doploy-cli
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.2
|
|
4
4
|
Summary: doploy CLI: watch builds, read logs, and drive Odoo deployments from a terminal
|
|
5
5
|
License: MIT
|
|
6
6
|
Project-URL: Homepage, https://doploy.io
|
|
@@ -55,6 +55,16 @@ uv tool install doploy-cli
|
|
|
55
55
|
|
|
56
56
|
Requires Python 3.10 or newer.
|
|
57
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
|
+
|
|
58
68
|
## Sign in
|
|
59
69
|
|
|
60
70
|
```bash
|
|
@@ -83,9 +93,11 @@ doploy logs <build-id> --source test -f # follow the test log until the bui
|
|
|
83
93
|
| Command | Description |
|
|
84
94
|
|---|---|
|
|
85
95
|
| `login` | Sign in with your browser |
|
|
96
|
+
| `skill install` | Teach Claude Code to use doploy (`skill print` for AGENTS.md) |
|
|
86
97
|
| `logout` | Forget the saved session |
|
|
87
98
|
| `projects` | List your projects |
|
|
88
|
-
| `builds <project>` |
|
|
99
|
+
| `builds <project>` | Live builds for a project. `--type development\|staging\|production`, `--limit`, `--all` |
|
|
100
|
+
| `branches <project>` | Live branches with their ids |
|
|
89
101
|
| `build <id>` | One build: status, commit, versions, error summary |
|
|
90
102
|
| `tests <build>` | Test failures for a build. `--details` prints tracebacks, `--warnings` includes warnings |
|
|
91
103
|
| `logs <build>` | Tail logs. `--source build\|test\|odoo`, `--lines`, `--filter TEXT`, `-f` to follow |
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "doploy-cli"
|
|
7
|
-
version = "0.2.
|
|
7
|
+
version = "0.2.2"
|
|
8
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" }
|
|
@@ -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"]
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|