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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: doploy-cli
3
- Version: 0.2.1
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>` | Recent builds for a project. `--type development\|staging\|production`, `--limit` |
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>` | Recent builds for a project. `--type development\|staging\|production`, `--limit` |
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 > 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
@@ -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.1
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>` | Recent builds for a project. `--type development\|staging\|production`, `--limit` |
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 |
@@ -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,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "doploy-cli"
7
- version = "0.2.1"
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