Merge pull request 'feat(pr): add patchset version shortcuts' (#24) from wangyue111/gitlink-cli:feat/pr-patchset-versions into master
This commit is contained in:
commit
2b64b8efa7
|
|
@ -203,6 +203,12 @@ gitlink-cli pr +merge --owner Gitlink --repo forgeplus -i 42
|
|||
|
||||
# View changed files
|
||||
gitlink-cli pr +files --owner Gitlink --repo forgeplus -i 42
|
||||
|
||||
# List PR patchset versions
|
||||
gitlink-cli pr +versions --owner Gitlink --repo forgeplus -i 42
|
||||
|
||||
# View a patchset version diff
|
||||
gitlink-cli pr +version-diff --owner Gitlink --repo forgeplus -i 42 --version-id 16040
|
||||
```
|
||||
|
||||
### Branch Management
|
||||
|
|
|
|||
|
|
@ -214,6 +214,12 @@ gitlink-cli pr +merge --owner Gitlink --repo forgeplus -i 42
|
|||
|
||||
# 查看 PR 变更文件
|
||||
gitlink-cli pr +files --owner Gitlink --repo forgeplus -i 42
|
||||
|
||||
# 查看 PR patchset/version 列表
|
||||
gitlink-cli pr +versions --owner Gitlink --repo forgeplus -i 42
|
||||
|
||||
# 查看指定 patchset/version diff
|
||||
gitlink-cli pr +version-diff --owner Gitlink --repo forgeplus -i 42 --version-id 16040
|
||||
```
|
||||
|
||||
### 发布管理
|
||||
|
|
|
|||
|
|
@ -167,6 +167,64 @@ func Shortcuts() []*common.Shortcut {
|
|||
return ctx.Output(env)
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "versions",
|
||||
Description: "List pull request patchset versions",
|
||||
Flags: []common.Flag{
|
||||
{Name: "id", Short: "i", Usage: "PR number", Required: true},
|
||||
},
|
||||
Run: func(ctx *common.RuntimeContext) error {
|
||||
if err := ctx.ResolveOwnerRepo(); err != nil {
|
||||
return err
|
||||
}
|
||||
id, err := ctx.RequireArg("id")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
env, err := ctx.CallAPI("GET", prV1Path(ctx, id)+"/versions", nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return ctx.Output(env)
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "version-diff",
|
||||
Description: "Show diff for a pull request patchset version",
|
||||
Flags: []common.Flag{
|
||||
{Name: "id", Short: "i", Usage: "PR number", Required: true},
|
||||
{Name: "version-id", Short: "v", Usage: "Patchset version ID", Required: true},
|
||||
{Name: "file", Short: "f", Usage: "Filter diff by file path"},
|
||||
},
|
||||
Run: func(ctx *common.RuntimeContext) error {
|
||||
if err := ctx.ResolveOwnerRepo(); err != nil {
|
||||
return err
|
||||
}
|
||||
id, err := ctx.RequireArg("id")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
versionID, err := ctx.RequireArg("version-id")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
path := fmt.Sprintf("%s/versions/%s/diff", prV1Path(ctx, id), versionID)
|
||||
if file := ctx.Arg("file"); file != "" {
|
||||
q := url.Values{}
|
||||
q.Set("filepath", file)
|
||||
env, err := ctx.CallAPIWithQuery("GET", path, q)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return ctx.Output(env)
|
||||
}
|
||||
env, err := ctx.CallAPI("GET", path, nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return ctx.Output(env)
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "comment",
|
||||
Description: "Add a comment to a pull request",
|
||||
|
|
@ -203,6 +261,10 @@ func Shortcuts() []*common.Shortcut {
|
|||
}
|
||||
}
|
||||
|
||||
func prV1Path(ctx *common.RuntimeContext, id string) string {
|
||||
return fmt.Sprintf("/v1/%s/%s/pulls/%s", ctx.Owner, ctx.Repo, id)
|
||||
}
|
||||
|
||||
func extractIssueID(env *output.Envelope) (int64, error) {
|
||||
data, ok := env.Data.(map[string]interface{})
|
||||
if !ok {
|
||||
|
|
|
|||
|
|
@ -91,6 +91,79 @@ func TestPRCommentFailsWhenIssueFieldMissing(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestPRVersionsUsesV1Endpoint(t *testing.T) {
|
||||
var calledPath string
|
||||
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
if r.Method != "GET" || r.URL.Path != "/v1/owner/repo/pulls/13/versions.json" {
|
||||
t.Fatalf("unexpected request: %s %s?%s", r.Method, r.URL.Path, r.URL.RawQuery)
|
||||
}
|
||||
calledPath = r.URL.Path
|
||||
writeJSON(t, w, map[string]interface{}{
|
||||
"total_count": float64(2),
|
||||
"versions": []map[string]interface{}{
|
||||
{
|
||||
"id": float64(16039),
|
||||
"head_commit_sha": "aaaaaaaa",
|
||||
},
|
||||
{
|
||||
"id": float64(16040),
|
||||
"head_commit_sha": "bbbbbbbb",
|
||||
},
|
||||
},
|
||||
})
|
||||
}))
|
||||
defer server.Close()
|
||||
|
||||
err := runPRShortcut(t, server, "versions", map[string]string{
|
||||
"id": "13",
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("versions shortcut failed: %v", err)
|
||||
}
|
||||
assertEqual(t, calledPath, "/v1/owner/repo/pulls/13/versions.json")
|
||||
}
|
||||
|
||||
func TestPRVersionDiffUsesV1EndpointWithFileFilter(t *testing.T) {
|
||||
var calledPath string
|
||||
var filepath string
|
||||
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
if r.Method != "GET" || r.URL.Path != "/v1/owner/repo/pulls/13/versions/16040/diff.json" {
|
||||
t.Fatalf("unexpected request: %s %s?%s", r.Method, r.URL.Path, r.URL.RawQuery)
|
||||
}
|
||||
calledPath = r.URL.Path
|
||||
filepath = r.URL.Query().Get("filepath")
|
||||
writeJSON(t, w, map[string]interface{}{
|
||||
"diff": "--- a/shortcuts/pr/pr.go\n+++ b/shortcuts/pr/pr.go\n",
|
||||
})
|
||||
}))
|
||||
defer server.Close()
|
||||
|
||||
err := runPRShortcut(t, server, "version-diff", map[string]string{
|
||||
"id": "13",
|
||||
"version-id": "16040",
|
||||
"file": "shortcuts/pr/pr.go",
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("version-diff shortcut failed: %v", err)
|
||||
}
|
||||
assertEqual(t, calledPath, "/v1/owner/repo/pulls/13/versions/16040/diff.json")
|
||||
assertEqual(t, filepath, "shortcuts/pr/pr.go")
|
||||
}
|
||||
|
||||
func TestPRVersionDiffRequiresVersionID(t *testing.T) {
|
||||
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
t.Fatalf("server should not be called when version-id is missing: %s %s", r.Method, r.URL.Path)
|
||||
}))
|
||||
defer server.Close()
|
||||
|
||||
err := runPRShortcut(t, server, "version-diff", map[string]string{
|
||||
"id": "13",
|
||||
})
|
||||
if err == nil {
|
||||
t.Fatal("expected error when version-id is missing, got nil")
|
||||
}
|
||||
}
|
||||
|
||||
func runPRShortcut(t *testing.T, server *httptest.Server, name string, args map[string]string) error {
|
||||
t.Helper()
|
||||
shortcut := findPRShortcut(t, name)
|
||||
|
|
|
|||
|
|
@ -123,7 +123,7 @@ skills/
|
|||
| **gitlink-shared** | 认证、全局参数、API 参考、安全规则、分支约定 | `auth login`, `auth status` |
|
||||
| **gitlink-repo** | 仓库管理 | `repo +list`, `repo +create`, `repo +info`, `repo +fork` |
|
||||
| **gitlink-issue** | Issue 管理 | `issue +create`, `issue +list`, `issue +view`, `issue +close`, `issue +batch-close` |
|
||||
| **gitlink-pr** | Pull Request | `pr +list`, `pr +create`, `pr +view`, `pr +merge`, `pr +review` |
|
||||
| **gitlink-pr** | Pull Request | `pr +list`, `pr +create`, `pr +view`, `pr +merge`, `pr +versions`, `pr +version-diff` |
|
||||
| **gitlink-branch** | 分支管理 | `branch +list`, `branch +create`, `branch +delete`, `branch +protect` |
|
||||
| **gitlink-release** | 版本发布 | `release +list`, `release +create`, `release +view` |
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
---
|
||||
name: gitlink-pr
|
||||
version: 1.0.0
|
||||
description: "Pull Request 管理:创建、查看、合并、关闭 PR,查看变更文件和 Diff。当用户需要操作 GitLink PR 时触发。"
|
||||
description: "Pull Request 管理:创建、查看、合并、关闭 PR,查看变更文件、Diff 和 patchset/version。当用户需要操作 GitLink PR 时触发。"
|
||||
metadata:
|
||||
requires:
|
||||
bins: ["gitlink-cli"]
|
||||
|
|
@ -25,7 +25,9 @@ metadata:
|
|||
| `pr +merge` | 合并 PR | 是 |
|
||||
| `pr +close` | 关闭 PR | 是 |
|
||||
| `pr +files` | 变更文件列表 | 否 |
|
||||
| `pr +diff` | 查看提交列表 | 否 |
|
||||
| `pr +diff` | 查看变更文件和 diff 内容 | 否 |
|
||||
| `pr +versions` | 查看 PR patchset/version 列表 | 否 |
|
||||
| `pr +version-diff` | 查看指定 patchset/version diff | 否 |
|
||||
| `pr +comment` | 给 PR 添加评论 | 是 |
|
||||
|
||||
## 使用示例
|
||||
|
|
@ -50,6 +52,13 @@ gitlink-cli pr +close --id 3
|
|||
# 查看变更文件(含 diff 内容)
|
||||
gitlink-cli pr +files --id 3
|
||||
|
||||
# 查看 PR patchset/version 列表
|
||||
gitlink-cli pr +versions --id 3
|
||||
|
||||
# 查看指定 patchset/version diff
|
||||
gitlink-cli pr +version-diff --id 3 --version-id 16040
|
||||
gitlink-cli pr +version-diff --id 3 --version-id 16040 --file shortcuts/pr/pr.go
|
||||
|
||||
# 给 PR 添加评论
|
||||
gitlink-cli pr +comment --id 3 --body "LGTM, ready to merge"
|
||||
```
|
||||
|
|
@ -120,6 +129,12 @@ gitlink-cli api POST /:owner/:repo/pulls/:id/reviews --body '{"body":"LGTM","eve
|
|||
|
||||
# 获取可用分支
|
||||
gitlink-cli api GET /:owner/:repo/pulls/get_branches
|
||||
|
||||
# 查看 PR patchset/version 列表(v1 API)
|
||||
gitlink-cli api GET /v1/:owner/:repo/pulls/:id/versions
|
||||
|
||||
# 查看指定 patchset/version diff(可通过 filepath 过滤文件)
|
||||
gitlink-cli api GET /v1/:owner/:repo/pulls/:id/versions/:version_id/diff
|
||||
```
|
||||
|
||||
## 注意事项
|
||||
|
|
@ -131,6 +146,8 @@ gitlink-cli api GET /:owner/:repo/pulls/get_branches
|
|||
- PR 查看/合并/关闭需要使用 `pull_request_number`(即网页 URL `/pulls/N` 中的序号,从 `pr +list` 返回)
|
||||
- `pr +merge` 默认使用 merge 方式,可通过 `--method` 指定 rebase 或 squash
|
||||
- `pr +diff` 实际调用 `/pulls/:id/files` 端点,返回变更文件列表和 diff 内容
|
||||
- `pr +versions` / `pr +version-diff` 使用 v1 API,`--id` 为网页 URL `/pulls/N` 中的 PR 序号,`--version-id` 为 patchset/version id
|
||||
- 同一个 PR 分支继续 push 新 commit 会生成新的 patchset/version;正常根据 review 修改代码时,应优先在原 PR 分支继续 push,不要关闭 PR 重开
|
||||
- `pr +list` 的 `--state` 参数(open/merged/closed)仅影响统计计数,API 返回的列表可能包含所有状态的 PR
|
||||
- PR 状态值:`pull_request_status` 0=open, 1=merged, 2=closed
|
||||
- 关联已有 Issue 时,把 Issue 编号或 URL 写入 PR `--body`,或使用 `issue +comment` 留痕;不要用 Raw API 对 Issue 做不完整更新,否则可能清空 Issue 描述
|
||||
|
|
|
|||
|
|
@ -0,0 +1,67 @@
|
|||
# pr +version-diff
|
||||
|
||||
> **前置条件:** 先阅读 [`../../gitlink-shared/SKILL.md`](../../gitlink-shared/SKILL.md) 了解认证、全局参数和安全规则。
|
||||
|
||||
查看 Pull Request 指定 patchset/version 的 diff。可选 `--file` 只查看某个文件的 diff,适合 Agent 或维护者针对 review 反馈定位变更。
|
||||
|
||||
## 命令
|
||||
|
||||
```bash
|
||||
# 查看指定 patchset/version diff
|
||||
gitlink-cli pr +version-diff --id 3 --version-id 16040
|
||||
|
||||
# 简写
|
||||
gitlink-cli pr +version-diff -i 3 -v 16040
|
||||
|
||||
# 只查看某个文件的 diff
|
||||
gitlink-cli pr +version-diff -i 3 -v 16040 --file shortcuts/pr/pr.go
|
||||
|
||||
# 指定仓库并输出 JSON
|
||||
gitlink-cli pr +version-diff --owner Gitlink --repo forgeplus -i 3 -v 16040 --format json
|
||||
```
|
||||
|
||||
## 参数
|
||||
|
||||
| 参数 | 必填 | 说明 |
|
||||
|------|------|------|
|
||||
| `--id` / `-i` | 是 | PR 序号(网页 URL `/pulls/N` 中的 `N`,即 `pull_request_number`) |
|
||||
| `--version-id` / `-v` | 是 | patchset/version id,可从 `pr +versions` 返回结果获取 |
|
||||
| `--file` / `-f` | 否 | 按文件路径过滤 diff,对应 API 查询参数 `filepath` |
|
||||
|
||||
## API
|
||||
|
||||
```
|
||||
GET /v1/{owner}/{repo}/pulls/{number}/versions/{version_id}/diff
|
||||
```
|
||||
|
||||
当传入 `--file` 时,会附加查询参数:
|
||||
|
||||
```
|
||||
filepath=<path>
|
||||
```
|
||||
|
||||
## 典型流程
|
||||
|
||||
```bash
|
||||
# 1. 列出 PR 的 patchset/version
|
||||
gitlink-cli pr +versions -i 3 --format json
|
||||
|
||||
# 2. 选择需要查看的 version id
|
||||
# 3. 查看该 version 的 diff
|
||||
gitlink-cli pr +version-diff -i 3 -v 16040
|
||||
|
||||
# 4. 如只关心某个文件,使用 --file 过滤
|
||||
gitlink-cli pr +version-diff -i 3 -v 16040 --file shortcuts/pr/pr.go
|
||||
```
|
||||
|
||||
## 注意事项
|
||||
|
||||
- `--version-id` 是 version id,不是 commit SHA。
|
||||
- 这是只读查询命令,不会修改 PR。
|
||||
- 如果要审查最新一轮变更,先用 `pr +versions` 获取最新 version,再调用本命令。
|
||||
|
||||
## References
|
||||
|
||||
- [gitlink-shared SKILL.md](../../gitlink-shared/SKILL.md) -- 认证与全局参数
|
||||
- [gitlink-pr SKILL.md](../SKILL.md) -- PR 操作总览
|
||||
- [pr +versions](gitlink-pr-versions.md) -- 查看 PR patchset/version 列表
|
||||
|
|
@ -0,0 +1,49 @@
|
|||
# pr +versions
|
||||
|
||||
> **前置条件:** 先阅读 [`../../gitlink-shared/SKILL.md`](../../gitlink-shared/SKILL.md) 了解认证、全局参数和安全规则。
|
||||
|
||||
查看 Pull Request 的 patchset/version 列表。GitLink 会在同一个 PR 分支继续 push 新 commit 时生成新的 version,适合 review 过程中追踪每轮变更。
|
||||
|
||||
## 命令
|
||||
|
||||
```bash
|
||||
# 查看 PR patchset/version 列表
|
||||
gitlink-cli pr +versions --id 3
|
||||
|
||||
# 简写
|
||||
gitlink-cli pr +versions -i 3
|
||||
|
||||
# 指定仓库并输出 JSON
|
||||
gitlink-cli pr +versions --owner Gitlink --repo forgeplus -i 3 --format json
|
||||
```
|
||||
|
||||
## 参数
|
||||
|
||||
| 参数 | 必填 | 说明 |
|
||||
|------|------|------|
|
||||
| `--id` / `-i` | 是 | PR 序号(网页 URL `/pulls/N` 中的 `N`,即 `pull_request_number`) |
|
||||
|
||||
## API
|
||||
|
||||
```
|
||||
GET /v1/{owner}/{repo}/pulls/{number}/versions
|
||||
```
|
||||
|
||||
## 典型流程
|
||||
|
||||
1. `pr +view --id <number>` 确认 PR 状态。
|
||||
2. `pr +versions --id <number>` 查看每轮 patchset/version。
|
||||
3. 选取需要审查的 `version.id`。
|
||||
4. 使用 `pr +version-diff --id <number> --version-id <version_id>` 查看指定版本 diff。
|
||||
|
||||
## 注意事项
|
||||
|
||||
- `--id` 不是数据库 ID,而是网页 URL `/pulls/N` 中的 PR 序号。
|
||||
- patchset/version 是只读查询命令,不会修改线上数据。
|
||||
- 根据 review 修改代码时,优先向原 PR 分支继续 push,GitLink 会生成新的 patchset/version;不要因为描述或代码更新而关闭 PR 重开。
|
||||
|
||||
## References
|
||||
|
||||
- [gitlink-shared SKILL.md](../../gitlink-shared/SKILL.md) -- 认证与全局参数
|
||||
- [gitlink-pr SKILL.md](../SKILL.md) -- PR 操作总览
|
||||
- [pr +version-diff](gitlink-pr-version-diff.md) -- 查看指定 patchset/version diff
|
||||
Loading…
Reference in New Issue