bmsdna-devtools 0.3.0__tar.gz → 0.4.0__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.
Files changed (30) hide show
  1. {bmsdna_devtools-0.3.0 → bmsdna_devtools-0.4.0}/PKG-INFO +1 -1
  2. {bmsdna_devtools-0.3.0 → bmsdna_devtools-0.4.0}/bmsdna/devtools/cli.py +28 -1
  3. {bmsdna_devtools-0.3.0 → bmsdna_devtools-0.4.0}/bmsdna/devtools/gh_pr.py +10 -2
  4. {bmsdna_devtools-0.3.0 → bmsdna_devtools-0.4.0}/bmsdna/devtools/pr_build.py +7 -0
  5. {bmsdna_devtools-0.3.0 → bmsdna_devtools-0.4.0}/pyproject.toml +1 -1
  6. {bmsdna_devtools-0.3.0 → bmsdna_devtools-0.4.0}/uv.lock +1 -1
  7. {bmsdna_devtools-0.3.0 → bmsdna_devtools-0.4.0}/.github/workflows/python-publish.yml +0 -0
  8. {bmsdna_devtools-0.3.0 → bmsdna_devtools-0.4.0}/.github/workflows/python-test.yml +0 -0
  9. {bmsdna_devtools-0.3.0 → bmsdna_devtools-0.4.0}/.gitignore +0 -0
  10. {bmsdna_devtools-0.3.0 → bmsdna_devtools-0.4.0}/.python-version +0 -0
  11. {bmsdna_devtools-0.3.0 → bmsdna_devtools-0.4.0}/README.md +0 -0
  12. {bmsdna_devtools-0.3.0 → bmsdna_devtools-0.4.0}/bmsdna/devtools/__init__.py +0 -0
  13. {bmsdna_devtools-0.3.0 → bmsdna_devtools-0.4.0}/bmsdna/devtools/ado_auth.py +0 -0
  14. {bmsdna_devtools-0.3.0 → bmsdna_devtools-0.4.0}/bmsdna/devtools/app_service_logs.py +0 -0
  15. {bmsdna_devtools-0.3.0 → bmsdna_devtools-0.4.0}/bmsdna/devtools/cli_tools.py +0 -0
  16. {bmsdna_devtools-0.3.0 → bmsdna_devtools-0.4.0}/bmsdna/devtools/commit.py +0 -0
  17. {bmsdna_devtools-0.3.0 → bmsdna_devtools-0.4.0}/bmsdna/devtools/env_config.py +0 -0
  18. {bmsdna_devtools-0.3.0 → bmsdna_devtools-0.4.0}/bmsdna/devtools/gitrepo.py +0 -0
  19. {bmsdna_devtools-0.3.0 → bmsdna_devtools-0.4.0}/bmsdna/devtools/logs.py +0 -0
  20. {bmsdna_devtools-0.3.0 → bmsdna_devtools-0.4.0}/bmsdna/devtools/pr_markdown.py +0 -0
  21. {bmsdna_devtools-0.3.0 → bmsdna_devtools-0.4.0}/bmsdna/devtools/worktree.py +0 -0
  22. {bmsdna_devtools-0.3.0 → bmsdna_devtools-0.4.0}/justfile +0 -0
  23. {bmsdna_devtools-0.3.0 → bmsdna_devtools-0.4.0}/skills/bmsdna-devtools/SKILL.md +0 -0
  24. {bmsdna_devtools-0.3.0 → bmsdna_devtools-0.4.0}/tests/test_app_service_logs.py +0 -0
  25. {bmsdna_devtools-0.3.0 → bmsdna_devtools-0.4.0}/tests/test_commit.py +0 -0
  26. {bmsdna_devtools-0.3.0 → bmsdna_devtools-0.4.0}/tests/test_env_config.py +0 -0
  27. {bmsdna_devtools-0.3.0 → bmsdna_devtools-0.4.0}/tests/test_gh_pr.py +0 -0
  28. {bmsdna_devtools-0.3.0 → bmsdna_devtools-0.4.0}/tests/test_gitrepo.py +0 -0
  29. {bmsdna_devtools-0.3.0 → bmsdna_devtools-0.4.0}/tests/test_pr_build.py +0 -0
  30. {bmsdna_devtools-0.3.0 → bmsdna_devtools-0.4.0}/tests/test_pr_markdown.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: bmsdna-devtools
3
- Version: 0.3.0
3
+ Version: 0.4.0
4
4
  Summary: Shared Azure DevOps / GitHub / git / Azure Monitor developer tooling for BMS projects
5
5
  Requires-Python: >=3.11
6
6
  Requires-Dist: requests>=2.32.0
@@ -57,6 +57,7 @@ def _attach_screenshots(attach: Callable[[], None]) -> None:
57
57
  @pr_app.command("create")
58
58
  def pr_create(
59
59
  target: str = typer.Option("main", "--target", help="Target branch (e.g. main, test)"),
60
+ draft: bool = typer.Option(False, "--draft", help="Create the PR as a draft (not ready for review)"),
60
61
  screenshot: list[str] = typer.Option(
61
62
  [], "--screenshot", help="Path to an image to attach to the PR description (repeatable)"
62
63
  ),
@@ -77,10 +78,11 @@ def pr_create(
77
78
  source_branch = current_branch()
78
79
  if isinstance(remote, GitHubRemote):
79
80
  gh = require_gh()
80
- returncode = gh_pr.create(gh, target, args or [])
81
+ returncode = gh_pr.create(gh, target, args or [], draft=draft)
81
82
  build_policy = gh_pr.has_build_policy(gh, target)
82
83
  if returncode == 0 and screenshot:
83
84
  _attach_screenshots(lambda: gh_pr.add_screenshots(gh, remote.owner, remote.repo, source_branch, screenshot))
85
+ publish_hint = "`gh pr ready`"
84
86
  else:
85
87
  az = require_az()
86
88
  cmd = [
@@ -88,6 +90,7 @@ def pr_create(
88
90
  "--target-branch", target,
89
91
  "--source-branch", source_branch,
90
92
  "--auto-complete", "false",
93
+ *(["--draft", "true"] if draft else []),
91
94
  *(args or []),
92
95
  ]
93
96
  returncode = subprocess.run(cmd).returncode
@@ -100,6 +103,10 @@ def pr_create(
100
103
  pr_build.add_screenshots(session, remote, pr, screenshot)
101
104
 
102
105
  _attach_screenshots(_add)
106
+ publish_hint = "`az repos pr update --id <PR-ID> --draft false`"
107
+
108
+ if returncode == 0 and draft:
109
+ print(f"\nCreated as a draft PR. Run `bdt pr publish` (or {publish_hint}) to mark it ready for review.")
103
110
 
104
111
  if returncode == 0 and build_policy:
105
112
  print("\nRun `bdt pr status` to check whether the CI build passes.")
@@ -107,6 +114,26 @@ def pr_create(
107
114
  raise typer.Exit(returncode)
108
115
 
109
116
 
117
+ @pr_app.command("publish")
118
+ def pr_publish(
119
+ target: str = typer.Option("main", "--target", help="Target branch of the PR (Azure DevOps only)"),
120
+ pat: str | None = typer.Option(
121
+ None,
122
+ "--pat",
123
+ envvar=["AZURE_DEVOPS_EXT_PAT", "AZURE_DEVOPS_PAT"],
124
+ help="Azure DevOps PAT (else falls back to `az` login)",
125
+ ),
126
+ ) -> None:
127
+ """Mark the draft PR opened from the current branch as ready for review (Azure DevOps or GitHub, auto-detected)."""
128
+ remote = current_remote()
129
+ source_branch = current_branch()
130
+ if isinstance(remote, GitHubRemote):
131
+ gh_pr.publish(require_gh())
132
+ else:
133
+ session, pr = _resolve_ado_pr(pat, remote, source_branch, target)
134
+ pr_build.publish(session, remote, pr)
135
+
136
+
110
137
  @pr_app.command("status")
111
138
  def pr_status(
112
139
  target_branch: str = typer.Option("main", "--target-branch", help="Target branch of the PR (Azure DevOps only — gh has no equivalent filter, it always resolves the PR for the current branch)"),
@@ -140,17 +140,25 @@ def run(gh: str, wait: bool) -> None:
140
140
  return
141
141
 
142
142
 
143
- def create(gh: str, target: str, extra_args: list[str]) -> int:
143
+ def create(gh: str, target: str, extra_args: list[str], draft: bool = False) -> int:
144
144
  """Create a GitHub PR from the current branch into `target`.
145
145
 
146
146
  --fill autofills title/body from commit info so this never blocks on an
147
147
  interactive prompt; pass --title/--body in extra_args to override (gh
148
148
  lets explicit values take precedence over --fill).
149
149
  """
150
- cmd = [gh, "pr", "create", "--base", target, "--fill", *extra_args]
150
+ cmd = [gh, "pr", "create", "--base", target, "--fill", *(["--draft"] if draft else []), *extra_args]
151
151
  return subprocess.run(cmd).returncode
152
152
 
153
153
 
154
+ def publish(gh: str) -> None:
155
+ """Mark the current branch's draft PR as ready for review."""
156
+ r = subprocess.run([gh, "pr", "ready"], capture_output=True, encoding="utf-8")
157
+ if r.returncode != 0:
158
+ sys.exit((r.stderr or r.stdout).strip() or "`gh pr ready` failed")
159
+ print("Marked PR as ready for review")
160
+
161
+
154
162
  def _git(args: list[str], env: dict[str, str] | None = None) -> str:
155
163
  r = subprocess.run(["git", *args], capture_output=True, encoding="utf-8", env=env)
156
164
  if r.returncode != 0:
@@ -189,6 +189,13 @@ def update(
189
189
  print(f"Updated PR #{pr_id}")
190
190
 
191
191
 
192
+ def publish(session: requests.Session, remote: AdoRemote, pr: dict) -> None:
193
+ """Mark a draft PR as ready for review (clears isDraft)."""
194
+ pr_id = pr["pullRequestId"]
195
+ _patch_pr(session, remote, pr_id, {"isDraft": False})
196
+ print(f"Marked PR #{pr_id} as ready for review")
197
+
198
+
192
199
  def add_comment(session: requests.Session, remote: AdoRemote, pr_id: int, content: str) -> None:
193
200
  """Post a new top-level comment thread on the PR."""
194
201
  r = session.post(
@@ -10,7 +10,7 @@ packages = ["bmsdna"]
10
10
 
11
11
  [project]
12
12
  name = "bmsdna-devtools"
13
- version = "0.3.0"
13
+ version = "0.4.0"
14
14
  description = "Shared Azure DevOps / GitHub / git / Azure Monitor developer tooling for BMS projects"
15
15
  readme = "README.md"
16
16
  requires-python = ">=3.11"
@@ -13,7 +13,7 @@ wheels = [
13
13
 
14
14
  [[package]]
15
15
  name = "bmsdna-devtools"
16
- version = "0.3.0"
16
+ version = "0.4.0"
17
17
  source = { editable = "." }
18
18
  dependencies = [
19
19
  { name = "requests" },