Load PR metadata and the ordered commit list. The list is every commit GitHub attributes to the PR, in order. It may include merge commits when the author merged the base branch in; `squash_pr` drops those before cherry-picking.
(repo: str, number: int)
| 169 | |
| 170 | |
| 171 | def fetch_pr(repo: str, number: int) -> PatchPr: |
| 172 | """Load PR metadata and the ordered commit list. |
| 173 | |
| 174 | The list is every commit GitHub attributes to the PR, in order. It may |
| 175 | include merge commits when the author merged the base branch in; |
| 176 | `squash_pr` drops those before cherry-picking. |
| 177 | """ |
| 178 | data = gh_json( |
| 179 | [ |
| 180 | "pr", |
| 181 | "view", |
| 182 | str(number), |
| 183 | "--repo", |
| 184 | repo, |
| 185 | "--json", |
| 186 | "number,url,title,headRefOid,commits", |
| 187 | ] |
| 188 | ) |
| 189 | if not isinstance(data, dict): |
| 190 | raise ReleaseError(f"unexpected gh pr view payload for {repo}#{number}") |
| 191 | commits: list[str] = [] |
| 192 | for entry in data.get("commits") or []: |
| 193 | if not isinstance(entry, dict): |
| 194 | continue |
| 195 | oid = entry.get("oid") |
| 196 | if isinstance(oid, str): |
| 197 | commits.append(oid.lower()) |
| 198 | if not commits: |
| 199 | raise ReleaseError(f"{repo}#{number} has no commits to squash") |
| 200 | head = data.get("headRefOid") |
| 201 | url = data.get("url") |
| 202 | title = data.get("title") |
| 203 | if not isinstance(head, str) or not isinstance(url, str) or not isinstance(title, str): |
| 204 | raise ReleaseError(f"{repo}#{number} is missing url, title, or headRefOid") |
| 205 | return PatchPr( |
| 206 | number=int(data.get("number") or number), |
| 207 | repo=repo, |
| 208 | url=url, |
| 209 | title=title, |
| 210 | head=head.lower(), |
| 211 | commits=tuple(commits), |
| 212 | ) |
| 213 | |
| 214 | |
| 215 | def ensure_fork_clone(root: Path, fork_url: str, upstream_url: str) -> Path: |
no test coverage detected