feat(pr): surface merged_at in pr +view
Signed-off-by: 林晨 (Leo Cheng) <chengkelfan@qq.com>
This commit is contained in:
parent
9749a4c832
commit
c4a0ac1f13
|
|
@ -0,0 +1,28 @@
|
|||
# PR View Merged Timestamp
|
||||
|
||||
## Summary
|
||||
|
||||
`pr +view` now surfaces the merge timestamp at the top level of its output.
|
||||
|
||||
The non-v1 detail endpoint `/{owner}/{repo}/pulls/{id}` nests the merge time under
|
||||
`pull_request.merged_at` (an ISO-8601 string such as `2026-07-05T12:52:05+08:00`),
|
||||
but the CLI previously only lifted `closed_at`. Merged PRs therefore showed no merge
|
||||
time, mirroring upstream issue #14.
|
||||
|
||||
The `closed_at` enrichment is renamed to `enrichPullRequestTimestamps` and extended so
|
||||
that, when `pull_request.merged_at` is present, it is copied to `merged_at` at the top
|
||||
level (and the boolean `merged`, when present, is surfaced alongside it). This matches
|
||||
`gh pr view`, which exposes `mergedAt`. The existing `closed_at` behavior is unchanged.
|
||||
|
||||
## Example
|
||||
|
||||
```bash
|
||||
gitlink-cli pr +view --owner Gitlink --repo forgeplus --id 42
|
||||
```
|
||||
|
||||
```json
|
||||
{
|
||||
"merged_at": "2026-07-05T12:52:05+08:00",
|
||||
"merged": true
|
||||
}
|
||||
```
|
||||
|
|
@ -138,7 +138,7 @@ func Shortcuts(translators ...*i18n.Translator) []*common.Shortcut {
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err := enrichPullRequestClosedAt(ctx, env); err != nil {
|
||||
if err := enrichPullRequestTimestamps(ctx, env); err != nil {
|
||||
return err
|
||||
}
|
||||
return ctx.Output(env)
|
||||
|
|
@ -470,13 +470,22 @@ func extractIssueID(env *output.Envelope) (int64, error) {
|
|||
return int64(idFloat), nil
|
||||
}
|
||||
|
||||
func enrichPullRequestClosedAt(ctx *common.RuntimeContext, env *output.Envelope) error {
|
||||
func enrichPullRequestTimestamps(ctx *common.RuntimeContext, env *output.Envelope) error {
|
||||
data, ok := env.Data.(map[string]interface{})
|
||||
if !ok {
|
||||
return nil
|
||||
}
|
||||
pr, ok := data["pull_request"].(map[string]interface{})
|
||||
if !ok || !isClosedPullRequest(pr) || stringField(pr, "closed_at") != "" {
|
||||
if !ok {
|
||||
return nil
|
||||
}
|
||||
if mergedAt := stringField(pr, "merged_at"); mergedAt != "" {
|
||||
data["merged_at"] = mergedAt
|
||||
if merged, ok := pr["merged"].(bool); ok {
|
||||
data["merged"] = merged
|
||||
}
|
||||
}
|
||||
if !isClosedPullRequest(pr) || stringField(pr, "closed_at") != "" {
|
||||
return nil
|
||||
}
|
||||
issue, ok := data["issue"].(map[string]interface{})
|
||||
|
|
|
|||
|
|
@ -249,6 +249,44 @@ func TestPRView(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestPRViewSurfacesMergedAt(t *testing.T) {
|
||||
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
if r.URL.Path != "/owner/repo/pulls/42.json" {
|
||||
t.Fatalf("unexpected path: %s", r.URL.Path)
|
||||
}
|
||||
writeJSON(t, w, map[string]interface{}{
|
||||
"id": float64(42),
|
||||
"pull_request": map[string]interface{}{
|
||||
"merged_at": "2026-07-05T12:52:05+08:00",
|
||||
"merged": true,
|
||||
"pull_request_staus": "merged",
|
||||
},
|
||||
})
|
||||
}))
|
||||
defer server.Close()
|
||||
|
||||
ctx := &common.RuntimeContext{
|
||||
Client: &client.Client{HTTP: server.Client(), BaseURL: server.URL},
|
||||
Owner: "owner",
|
||||
Repo: "repo",
|
||||
Format: "json",
|
||||
}
|
||||
env, err := ctx.CallAPI("GET", "/owner/repo/pulls/42", nil)
|
||||
if err != nil {
|
||||
t.Fatalf("CallAPI error: %v", err)
|
||||
}
|
||||
if err := enrichPullRequestTimestamps(ctx, env); err != nil {
|
||||
t.Fatalf("enrich error: %v", err)
|
||||
}
|
||||
|
||||
data, ok := env.Data.(map[string]interface{})
|
||||
if !ok {
|
||||
t.Fatalf("unexpected data type: %T", env.Data)
|
||||
}
|
||||
assertEqual(t, data["merged_at"], "2026-07-05T12:52:05+08:00")
|
||||
assertEqual(t, data["merged"], true)
|
||||
}
|
||||
|
||||
// --- merge ---
|
||||
|
||||
func TestPRMerge(t *testing.T) {
|
||||
|
|
|
|||
Loading…
Reference in New Issue