Merge pull request #11755 from cli/babakks/polish-agent-task-view

`gh agent-task view`: polish and fix some issues
This commit is contained in:
Babak K. Shandiz 2025-09-18 10:38:15 +01:00 committed by GitHub
commit 151b971933
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
7 changed files with 542 additions and 303 deletions

View file

@ -27,21 +27,22 @@ var ErrSessionNotFound = errors.New("not found")
// session is an in-flight agent task
type session struct {
ID string `json:"id"`
Name string `json:"name"`
UserID int64 `json:"user_id"`
AgentID int64 `json:"agent_id"`
Logs string `json:"logs"`
State string `json:"state"`
OwnerID uint64 `json:"owner_id"`
RepoID uint64 `json:"repo_id"`
ResourceType string `json:"resource_type"`
ResourceID int64 `json:"resource_id"`
LastUpdatedAt time.Time `json:"last_updated_at,omitempty"`
CreatedAt time.Time `json:"created_at,omitempty"`
CompletedAt time.Time `json:"completed_at,omitempty"`
EventURL string `json:"event_url"`
EventType string `json:"event_type"`
ID string `json:"id"`
Name string `json:"name"`
UserID int64 `json:"user_id"`
AgentID int64 `json:"agent_id"`
Logs string `json:"logs"`
State string `json:"state"`
OwnerID uint64 `json:"owner_id"`
RepoID uint64 `json:"repo_id"`
ResourceType string `json:"resource_type"`
ResourceID int64 `json:"resource_id"`
LastUpdatedAt time.Time `json:"last_updated_at,omitempty"`
CreatedAt time.Time `json:"created_at,omitempty"`
CompletedAt time.Time `json:"completed_at,omitempty"`
EventURL string `json:"event_url"`
EventType string `json:"event_type"`
PremiumRequests float64 `json:"premium_requests"`
}
// A shim of a full pull request because looking up by node ID
@ -66,21 +67,22 @@ type sessionPullRequest struct {
// Session is a hydrated in-flight agent task
type Session struct {
ID string
Name string
UserID int64
AgentID int64
Logs string
State string
OwnerID uint64
RepoID uint64
ResourceType string
ResourceID int64
LastUpdatedAt time.Time
CreatedAt time.Time
CompletedAt time.Time
EventURL string
EventType string
ID string
Name string
UserID int64
AgentID int64
Logs string
State string
OwnerID uint64
RepoID uint64
ResourceType string
ResourceID int64
LastUpdatedAt time.Time
CreatedAt time.Time
CompletedAt time.Time
EventURL string
EventType string
PremiumRequests float64
PullRequest *api.PullRequest
User *api.GitHubUser
@ -475,20 +477,21 @@ func generateUserNodeID(userID int64) string {
func fromAPISession(s session) *Session {
return &Session{
ID: s.ID,
Name: s.Name,
UserID: s.UserID,
AgentID: s.AgentID,
Logs: s.Logs,
State: s.State,
OwnerID: s.OwnerID,
RepoID: s.RepoID,
ResourceType: s.ResourceType,
ResourceID: s.ResourceID,
LastUpdatedAt: s.LastUpdatedAt,
CreatedAt: s.CreatedAt,
CompletedAt: s.CompletedAt,
EventURL: s.EventURL,
EventType: s.EventType,
ID: s.ID,
Name: s.Name,
UserID: s.UserID,
AgentID: s.AgentID,
Logs: s.Logs,
State: s.State,
OwnerID: s.OwnerID,
RepoID: s.RepoID,
ResourceType: s.ResourceType,
ResourceID: s.ResourceID,
LastUpdatedAt: s.LastUpdatedAt,
CreatedAt: s.CreatedAt,
CompletedAt: s.CompletedAt,
EventURL: s.EventURL,
EventType: s.EventType,
PremiumRequests: s.PremiumRequests,
}
}

View file

@ -77,7 +77,8 @@ func TestListSessionsForViewer(t *testing.T) {
"repo_id": 1000,
"resource_type": "pull",
"resource_id": 2000,
"created_at": "%[1]s"
"created_at": "%[1]s",
"premium_requests": 0.1
}
]
}`,
@ -125,17 +126,18 @@ func TestListSessionsForViewer(t *testing.T) {
wantOut: []*Session{
{
ID: "sess1",
Name: "Build artifacts",
UserID: 1,
AgentID: 2,
Logs: "",
State: "completed",
OwnerID: 10,
RepoID: 1000,
ResourceType: "pull",
ResourceID: 2000,
CreatedAt: sampleDate,
ID: "sess1",
Name: "Build artifacts",
UserID: 1,
AgentID: 2,
Logs: "",
State: "completed",
OwnerID: 10,
RepoID: 1000,
ResourceType: "pull",
ResourceID: 2000,
CreatedAt: sampleDate,
PremiumRequests: 0.1,
PullRequest: &api.PullRequest{
ID: "PR_node",
FullDatabaseID: "2000",
@ -186,7 +188,8 @@ func TestListSessionsForViewer(t *testing.T) {
"repo_id": 1000,
"resource_type": "",
"resource_id": 0,
"created_at": "%[1]s"
"created_at": "%[1]s",
"premium_requests": 0.1
}
]
}`,
@ -218,17 +221,18 @@ func TestListSessionsForViewer(t *testing.T) {
wantOut: []*Session{
{
ID: "sess1",
Name: "Build artifacts",
UserID: 1,
AgentID: 2,
Logs: "",
State: "completed",
OwnerID: 10,
RepoID: 1000,
ResourceType: "",
ResourceID: 0,
CreatedAt: sampleDate,
ID: "sess1",
Name: "Build artifacts",
UserID: 1,
AgentID: 2,
Logs: "",
State: "completed",
OwnerID: 10,
RepoID: 1000,
ResourceType: "",
ResourceID: 0,
CreatedAt: sampleDate,
PremiumRequests: 0.1,
User: &api.GitHubUser{
Login: "octocat",
Name: "Octocat",
@ -264,7 +268,8 @@ func TestListSessionsForViewer(t *testing.T) {
"repo_id": 1000,
"resource_type": "pull",
"resource_id": 2000,
"created_at": "%[1]s"
"created_at": "%[1]s",
"premium_requests": 0.1
}
]
}`,
@ -295,7 +300,8 @@ func TestListSessionsForViewer(t *testing.T) {
"repo_id": 1000,
"resource_type": "pull",
"resource_id": 2001,
"created_at": "%[1]s"
"created_at": "%[1]s",
"premium_requests": 0.1
}
]
}`,
@ -358,17 +364,18 @@ func TestListSessionsForViewer(t *testing.T) {
},
wantOut: []*Session{
{
ID: "sess1",
Name: "Build artifacts",
UserID: 1,
AgentID: 2,
Logs: "",
State: "completed",
OwnerID: 10,
RepoID: 1000,
ResourceType: "pull",
ResourceID: 2000,
CreatedAt: sampleDate,
ID: "sess1",
Name: "Build artifacts",
UserID: 1,
AgentID: 2,
Logs: "",
State: "completed",
OwnerID: 10,
RepoID: 1000,
ResourceType: "pull",
ResourceID: 2000,
CreatedAt: sampleDate,
PremiumRequests: 0.1,
PullRequest: &api.PullRequest{
ID: "PR_node",
FullDatabaseID: "2000",
@ -391,17 +398,18 @@ func TestListSessionsForViewer(t *testing.T) {
},
},
{
ID: "sess2",
Name: "Build artifacts",
UserID: 1,
AgentID: 2,
Logs: "",
State: "completed",
OwnerID: 10,
RepoID: 1000,
ResourceType: "pull",
ResourceID: 2001,
CreatedAt: sampleDate,
ID: "sess2",
Name: "Build artifacts",
UserID: 1,
AgentID: 2,
Logs: "",
State: "completed",
OwnerID: 10,
RepoID: 1000,
ResourceType: "pull",
ResourceID: 2001,
CreatedAt: sampleDate,
PremiumRequests: 0.1,
PullRequest: &api.PullRequest{
ID: "PR_node",
FullDatabaseID: "2001",
@ -467,7 +475,8 @@ func TestListSessionsForViewer(t *testing.T) {
"repo_id": 1000,
"resource_type": "pull",
"resource_id": 2000,
"created_at": "%[1]s"
"created_at": "%[1]s",
"premium_requests": 0.1
}
]
}`,
@ -591,7 +600,8 @@ func TestListSessionsForRepo(t *testing.T) {
"repo_id": 1000,
"resource_type": "pull",
"resource_id": 2000,
"created_at": "%[1]s"
"created_at": "%[1]s",
"premium_requests": 0.1
}
]
}`,
@ -638,17 +648,18 @@ func TestListSessionsForRepo(t *testing.T) {
},
wantOut: []*Session{
{
ID: "sess1",
Name: "Build artifacts",
UserID: 1,
AgentID: 2,
Logs: "",
State: "completed",
OwnerID: 10,
RepoID: 1000,
ResourceType: "pull",
ResourceID: 2000,
CreatedAt: sampleDate,
ID: "sess1",
Name: "Build artifacts",
UserID: 1,
AgentID: 2,
Logs: "",
State: "completed",
OwnerID: 10,
RepoID: 1000,
ResourceType: "pull",
ResourceID: 2000,
CreatedAt: sampleDate,
PremiumRequests: 0.1,
PullRequest: &api.PullRequest{
ID: "PR_node",
FullDatabaseID: "2000",
@ -699,7 +710,8 @@ func TestListSessionsForRepo(t *testing.T) {
"repo_id": 1000,
"resource_type": "",
"resource_id": 0,
"created_at": "%[1]s"
"created_at": "%[1]s",
"premium_requests": 0.1
}
]
}`,
@ -731,17 +743,18 @@ func TestListSessionsForRepo(t *testing.T) {
wantOut: []*Session{
{
ID: "sess1",
Name: "Build artifacts",
UserID: 1,
AgentID: 2,
Logs: "",
State: "completed",
OwnerID: 10,
RepoID: 1000,
ResourceType: "",
ResourceID: 0,
CreatedAt: sampleDate,
ID: "sess1",
Name: "Build artifacts",
UserID: 1,
AgentID: 2,
Logs: "",
State: "completed",
OwnerID: 10,
RepoID: 1000,
ResourceType: "",
ResourceID: 0,
CreatedAt: sampleDate,
PremiumRequests: 0.1,
User: &api.GitHubUser{
Login: "octocat",
Name: "Octocat",
@ -777,7 +790,8 @@ func TestListSessionsForRepo(t *testing.T) {
"repo_id": 1000,
"resource_type": "pull",
"resource_id": 2000,
"created_at": "%[1]s"
"created_at": "%[1]s",
"premium_requests": 0.1
}
]
}`,
@ -808,7 +822,8 @@ func TestListSessionsForRepo(t *testing.T) {
"repo_id": 1000,
"resource_type": "pull",
"resource_id": 2001,
"created_at": "%[1]s"
"created_at": "%[1]s",
"premium_requests": 0.1
}
]
}`,
@ -871,17 +886,18 @@ func TestListSessionsForRepo(t *testing.T) {
},
wantOut: []*Session{
{
ID: "sess1",
Name: "Build artifacts",
UserID: 1,
AgentID: 2,
Logs: "",
State: "completed",
OwnerID: 10,
RepoID: 1000,
ResourceType: "pull",
ResourceID: 2000,
CreatedAt: sampleDate,
ID: "sess1",
Name: "Build artifacts",
UserID: 1,
AgentID: 2,
Logs: "",
State: "completed",
OwnerID: 10,
RepoID: 1000,
ResourceType: "pull",
ResourceID: 2000,
CreatedAt: sampleDate,
PremiumRequests: 0.1,
PullRequest: &api.PullRequest{
ID: "PR_node",
FullDatabaseID: "2000",
@ -904,17 +920,18 @@ func TestListSessionsForRepo(t *testing.T) {
},
},
{
ID: "sess2",
Name: "Build artifacts",
UserID: 1,
AgentID: 2,
Logs: "",
State: "completed",
OwnerID: 10,
RepoID: 1000,
ResourceType: "pull",
ResourceID: 2001,
CreatedAt: sampleDate,
ID: "sess2",
Name: "Build artifacts",
UserID: 1,
AgentID: 2,
Logs: "",
State: "completed",
OwnerID: 10,
RepoID: 1000,
ResourceType: "pull",
ResourceID: 2001,
CreatedAt: sampleDate,
PremiumRequests: 0.1,
PullRequest: &api.PullRequest{
ID: "PR_node",
FullDatabaseID: "2001",
@ -980,7 +997,8 @@ func TestListSessionsForRepo(t *testing.T) {
"repo_id": 1000,
"resource_type": "pull",
"resource_id": 2000,
"created_at": "%[1]s"
"created_at": "%[1]s",
"premium_requests": 0.1
}
]
}`,
@ -1107,7 +1125,8 @@ func TestListSessionsByResourceID(t *testing.T) {
"repo_id": 1000,
"resource_type": "pull",
"resource_id": 2000,
"created_at": "%[1]s"
"created_at": "%[1]s",
"premium_requests": 0.1
}
]
}`,
@ -1155,17 +1174,18 @@ func TestListSessionsByResourceID(t *testing.T) {
wantOut: []*Session{
{
ID: "sess1",
Name: "Build artifacts",
UserID: 1,
AgentID: 2,
Logs: "",
State: "completed",
OwnerID: 10,
RepoID: 1000,
ResourceType: "pull",
ResourceID: 2000,
CreatedAt: sampleDate,
ID: "sess1",
Name: "Build artifacts",
UserID: 1,
AgentID: 2,
Logs: "",
State: "completed",
OwnerID: 10,
RepoID: 1000,
ResourceType: "pull",
ResourceID: 2000,
CreatedAt: sampleDate,
PremiumRequests: 0.1,
PullRequest: &api.PullRequest{
ID: "PR_node",
FullDatabaseID: "2000",
@ -1216,7 +1236,8 @@ func TestListSessionsByResourceID(t *testing.T) {
"repo_id": 1000,
"resource_type": "pull",
"resource_id": 2000,
"created_at": "%[1]s"
"created_at": "%[1]s",
"premium_requests": 0.1
}
]
}`,
@ -1247,7 +1268,8 @@ func TestListSessionsByResourceID(t *testing.T) {
"repo_id": 1000,
"resource_type": "pull",
"resource_id": 2001,
"created_at": "%[1]s"
"created_at": "%[1]s",
"premium_requests": 0.1
}
]
}`,
@ -1310,17 +1332,18 @@ func TestListSessionsByResourceID(t *testing.T) {
},
wantOut: []*Session{
{
ID: "sess1",
Name: "Build artifacts",
UserID: 1,
AgentID: 2,
Logs: "",
State: "completed",
OwnerID: 10,
RepoID: 1000,
ResourceType: "pull",
ResourceID: 2000,
CreatedAt: sampleDate,
ID: "sess1",
Name: "Build artifacts",
UserID: 1,
AgentID: 2,
Logs: "",
State: "completed",
OwnerID: 10,
RepoID: 1000,
ResourceType: "pull",
ResourceID: 2000,
CreatedAt: sampleDate,
PremiumRequests: 0.1,
PullRequest: &api.PullRequest{
ID: "PR_node",
FullDatabaseID: "2000",
@ -1343,17 +1366,18 @@ func TestListSessionsByResourceID(t *testing.T) {
},
},
{
ID: "sess2",
Name: "Build artifacts",
UserID: 1,
AgentID: 2,
Logs: "",
State: "completed",
OwnerID: 10,
RepoID: 1000,
ResourceType: "pull",
ResourceID: 2001,
CreatedAt: sampleDate,
ID: "sess2",
Name: "Build artifacts",
UserID: 1,
AgentID: 2,
Logs: "",
State: "completed",
OwnerID: 10,
RepoID: 1000,
ResourceType: "pull",
ResourceID: 2001,
CreatedAt: sampleDate,
PremiumRequests: 0.1,
PullRequest: &api.PullRequest{
ID: "PR_node",
FullDatabaseID: "2001",
@ -1419,7 +1443,8 @@ func TestListSessionsByResourceID(t *testing.T) {
"repo_id": 1000,
"resource_type": "pull",
"resource_id": 2000,
"created_at": "%[1]s"
"created_at": "%[1]s",
"premium_requests": 0.1
}
]
}`,
@ -1538,7 +1563,8 @@ func TestGetSession(t *testing.T) {
"repo_id": 1000,
"resource_type": "pull",
"resource_id": 2000,
"created_at": "%[1]s"
"created_at": "%[1]s",
"premium_requests": 0.1
}`,
sampleDateString,
)),
@ -1582,17 +1608,18 @@ func TestGetSession(t *testing.T) {
)
},
wantOut: &Session{
ID: "some-uuid",
Name: "Build artifacts",
UserID: 1,
AgentID: 2,
Logs: "",
State: "completed",
OwnerID: 10,
RepoID: 1000,
ResourceType: "pull",
ResourceID: 2000,
CreatedAt: sampleDate,
ID: "some-uuid",
Name: "Build artifacts",
UserID: 1,
AgentID: 2,
Logs: "",
State: "completed",
OwnerID: 10,
RepoID: 1000,
ResourceType: "pull",
ResourceID: 2000,
CreatedAt: sampleDate,
PremiumRequests: 0.1,
PullRequest: &api.PullRequest{
ID: "PR_node",
FullDatabaseID: "2000",
@ -1633,7 +1660,8 @@ func TestGetSession(t *testing.T) {
"repo_id": 1000,
"resource_type": "",
"resource_id": 0,
"created_at": "%[1]s"
"created_at": "%[1]s",
"premium_requests": 0.1
}`,
sampleDateString,
)),
@ -1661,17 +1689,18 @@ func TestGetSession(t *testing.T) {
)
},
wantOut: &Session{
ID: "some-uuid",
Name: "Build artifacts",
UserID: 1,
AgentID: 2,
Logs: "",
State: "completed",
OwnerID: 10,
RepoID: 1000,
ResourceType: "",
ResourceID: 0,
CreatedAt: sampleDate,
ID: "some-uuid",
Name: "Build artifacts",
UserID: 1,
AgentID: 2,
Logs: "",
State: "completed",
OwnerID: 10,
RepoID: 1000,
ResourceType: "",
ResourceID: 0,
CreatedAt: sampleDate,
PremiumRequests: 0.1,
User: &api.GitHubUser{
Login: "octocat",
Name: "Octocat",
@ -1696,7 +1725,8 @@ func TestGetSession(t *testing.T) {
"repo_id": 1000,
"resource_type": "pull",
"resource_id": 2000,
"created_at": "%[1]s"
"created_at": "%[1]s",
"premium_requests": 0.1
}`,
sampleDateString,
)),

View file

@ -30,17 +30,17 @@ func SessionStateString(state string) string {
case "queued":
return "Queued"
case "in_progress":
return "In Progress"
return "In progress"
case "completed":
return "Completed"
return "Ready for review"
case "failed":
return "Failed"
case "idle":
return "Idle"
case "waiting_for_user":
return "Waiting for User"
return "Waiting for user"
case "timed_out":
return "Timed Out"
return "Timed out"
case "cancelled":
return "Cancelled"
default:

View file

@ -7,6 +7,7 @@ import (
"net/http"
"net/url"
"strconv"
"strings"
"time"
"github.com/MakeNowJust/heredoc"
@ -200,8 +201,9 @@ func viewRun(opts *ViewOptions) error {
if prID == 0 {
findOptions := prShared.FindOptions{
Selector: opts.SelectorArg,
Fields: []string{"id", "url", "fullDatabaseId"},
Selector: opts.SelectorArg,
Fields: []string{"id", "url", "fullDatabaseId"},
DisableProgress: true,
}
pr, repo, err := opts.Finder.Find(findOptions)
@ -275,11 +277,11 @@ func viewRun(opts *ViewOptions) error {
}
}
printSession(opts, session)
if opts.Log {
return printLogs(opts, capiClient, session.ID)
}
printSession(opts, session)
return nil
}
@ -305,6 +307,16 @@ func printSession(opts *ViewOptions, session *capi.Session) {
fmt.Fprintf(opts.IO.Out, "Started %s\n", text.FuzzyAgo(time.Now(), session.CreatedAt))
}
usedPremiumRequests := strings.TrimSuffix(fmt.Sprintf("%.1f", session.PremiumRequests), ".0")
usedPremiumRequestsNote := fmt.Sprintf("Used %s premium request(s)", usedPremiumRequests)
var durationNote string
if session.CompletedAt.After(session.CreatedAt) {
durationNote = fmt.Sprintf(" • Duration %s", session.CompletedAt.Sub(session.CreatedAt).Round(time.Second).String())
}
fmt.Fprintf(opts.IO.Out, "%s%s\n", cs.Muted(usedPremiumRequestsNote), cs.Muted(durationNote))
if !opts.Log {
fmt.Fprintln(opts.IO.Out, "")
fmt.Fprintf(opts.IO.Out, "For detailed session logs, try:\ngh agent-task view '%s' --log\n", session.ID)
@ -345,7 +357,6 @@ func printLogs(opts *ViewOptions, capiClient capi.CapiClient, sessionID string)
return raw, nil
}
fmt.Fprintln(opts.IO.Out, "")
return renderer.Follow(fetcher, opts.IO.Out, opts.IO)
}
@ -354,7 +365,6 @@ func printLogs(opts *ViewOptions, capiClient capi.CapiClient, sessionID string)
return fmt.Errorf("failed to fetch session logs: %w", err)
}
fmt.Fprintln(opts.IO.Out, "")
_, err = renderer.Render(raw, opts.IO.Out, opts.IO)
return err
}

View file

@ -159,6 +159,7 @@ func TestNewCmdList(t *testing.T) {
func Test_viewRun(t *testing.T) {
sampleDate := time.Now().Add(-6 * time.Hour) // 6h ago
sampleCompletedAt := sampleDate.Add(5 * time.Minute)
tests := []struct {
name string
@ -212,9 +213,11 @@ func Test_viewRun(t *testing.T) {
m.GetSessionFunc = func(_ context.Context, id string) (*capi.Session, error) {
assert.Equal(t, "some-session-id", id)
return &capi.Session{
ID: "some-session-id",
State: "completed",
CreatedAt: sampleDate,
ID: "some-session-id",
State: "completed",
CreatedAt: sampleDate,
CompletedAt: sampleCompletedAt,
PremiumRequests: 1.5,
PullRequest: &api.PullRequest{
Title: "fix something",
Number: 101,
@ -230,8 +233,9 @@ func Test_viewRun(t *testing.T) {
}
},
wantOut: heredoc.Doc(`
Completed fix something OWNER/REPO#101
Ready for review fix something OWNER/REPO#101
Started on behalf of octocat about 6 hours ago
Used 1.5 premium request(s) Duration 5m0s
For detailed session logs, try:
gh agent-task view 'some-session-id' --log
@ -252,9 +256,11 @@ func Test_viewRun(t *testing.T) {
m.GetSessionFunc = func(_ context.Context, id string) (*capi.Session, error) {
assert.Equal(t, "some-session-id", id)
return &capi.Session{
ID: "some-session-id",
State: "completed",
CreatedAt: sampleDate,
ID: "some-session-id",
State: "completed",
CreatedAt: sampleDate,
CompletedAt: sampleCompletedAt,
PremiumRequests: 1.5,
PullRequest: &api.PullRequest{
Title: "fix something",
Number: 101,
@ -267,8 +273,9 @@ func Test_viewRun(t *testing.T) {
}
},
wantOut: heredoc.Doc(`
Completed fix something OWNER/REPO#101
Ready for review fix something OWNER/REPO#101
Started about 6 hours ago
Used 1.5 premium request(s) Duration 5m0s
For detailed session logs, try:
gh agent-task view 'some-session-id' --log
@ -289,9 +296,11 @@ func Test_viewRun(t *testing.T) {
m.GetSessionFunc = func(_ context.Context, id string) (*capi.Session, error) {
assert.Equal(t, "some-session-id", id)
return &capi.Session{
ID: "some-session-id",
State: "completed",
CreatedAt: sampleDate,
ID: "some-session-id",
State: "completed",
CreatedAt: sampleDate,
CompletedAt: sampleCompletedAt,
PremiumRequests: 1.5,
User: &api.GitHubUser{
Login: "octocat",
},
@ -299,8 +308,9 @@ func Test_viewRun(t *testing.T) {
}
},
wantOut: heredoc.Doc(`
Completed
Ready for review
Started on behalf of octocat about 6 hours ago
Used 1.5 premium request(s) Duration 5m0s
For detailed session logs, try:
gh agent-task view 'some-session-id' --log
@ -318,20 +328,106 @@ func Test_viewRun(t *testing.T) {
m.GetSessionFunc = func(_ context.Context, id string) (*capi.Session, error) {
assert.Equal(t, "some-session-id", id)
return &capi.Session{
ID: "some-session-id",
State: "completed",
CreatedAt: sampleDate,
ID: "some-session-id",
State: "completed",
CreatedAt: sampleDate,
CompletedAt: sampleCompletedAt,
PremiumRequests: 1.5,
}, nil
}
},
wantOut: heredoc.Doc(`
Completed
Ready for review
Started about 6 hours ago
Used 1.5 premium request(s) Duration 5m0s
For detailed session logs, try:
gh agent-task view 'some-session-id' --log
`),
},
{
name: "with session id, success, with zero premium requests (tty)",
tty: true,
opts: ViewOptions{
SelectorArg: "some-session-id",
SessionID: "some-session-id",
},
capiStubs: func(t *testing.T, m *capi.CapiClientMock) {
m.GetSessionFunc = func(_ context.Context, id string) (*capi.Session, error) {
assert.Equal(t, "some-session-id", id)
return &capi.Session{
ID: "some-session-id",
State: "completed",
CreatedAt: sampleDate,
CompletedAt: sampleCompletedAt,
PremiumRequests: 0,
PullRequest: &api.PullRequest{
Title: "fix something",
Number: 101,
URL: "https://github.com/OWNER/REPO/pull/101",
Repository: &api.PRRepository{
NameWithOwner: "OWNER/REPO",
},
},
User: &api.GitHubUser{
Login: "octocat",
},
}, nil
}
},
wantOut: heredoc.Doc(`
Ready for review fix something OWNER/REPO#101
Started on behalf of octocat about 6 hours ago
Used 0 premium request(s) Duration 5m0s
For detailed session logs, try:
gh agent-task view 'some-session-id' --log
View this session on GitHub:
https://github.com/OWNER/REPO/pull/101/agent-sessions/some-session-id
`),
},
{
name: "with session id, success, duration not available (tty)",
tty: true,
opts: ViewOptions{
SelectorArg: "some-session-id",
SessionID: "some-session-id",
},
capiStubs: func(t *testing.T, m *capi.CapiClientMock) {
m.GetSessionFunc = func(_ context.Context, id string) (*capi.Session, error) {
assert.Equal(t, "some-session-id", id)
return &capi.Session{
ID: "some-session-id",
State: "in_progress",
CreatedAt: sampleDate,
PremiumRequests: 1.5,
PullRequest: &api.PullRequest{
Title: "fix something",
Number: 101,
URL: "https://github.com/OWNER/REPO/pull/101",
Repository: &api.PRRepository{
NameWithOwner: "OWNER/REPO",
},
},
User: &api.GitHubUser{
Login: "octocat",
},
}, nil
}
},
wantOut: heredoc.Doc(`
In progress fix something OWNER/REPO#101
Started on behalf of octocat about 6 hours ago
Used 1.5 premium request(s)
For detailed session logs, try:
gh agent-task view 'some-session-id' --log
View this session on GitHub:
https://github.com/OWNER/REPO/pull/101/agent-sessions/some-session-id
`),
},
{
name: "with session id, not found, web mode (tty)",
tty: true,
@ -360,9 +456,11 @@ func Test_viewRun(t *testing.T) {
m.GetSessionFunc = func(_ context.Context, id string) (*capi.Session, error) {
assert.Equal(t, "some-session-id", id)
return &capi.Session{
ID: "some-session-id",
State: "completed",
CreatedAt: sampleDate,
ID: "some-session-id",
State: "completed",
CreatedAt: sampleDate,
CompletedAt: sampleCompletedAt,
PremiumRequests: 1.5,
// User data is irrelevant in this case
}, nil
}
@ -382,9 +480,11 @@ func Test_viewRun(t *testing.T) {
m.GetSessionFunc = func(_ context.Context, id string) (*capi.Session, error) {
assert.Equal(t, "some-session-id", id)
return &capi.Session{
ID: "some-session-id",
State: "completed",
CreatedAt: sampleDate,
ID: "some-session-id",
State: "completed",
CreatedAt: sampleDate,
CompletedAt: sampleCompletedAt,
PremiumRequests: 1.5,
PullRequest: &api.PullRequest{
Title: "fix something",
Number: 101,
@ -488,9 +588,11 @@ func Test_viewRun(t *testing.T) {
assert.Equal(t, defaultLimit, limit)
return []*capi.Session{
{
ID: "some-session-id",
State: "completed",
CreatedAt: sampleDate,
ID: "some-session-id",
State: "completed",
CreatedAt: sampleDate,
CompletedAt: sampleCompletedAt,
PremiumRequests: 1.5,
PullRequest: &api.PullRequest{
Title: "fix something",
Number: 101,
@ -507,8 +609,9 @@ func Test_viewRun(t *testing.T) {
}
},
wantOut: heredoc.Doc(`
Completed fix something OWNER/REPO#101
Ready for review fix something OWNER/REPO#101
Started on behalf of octocat about 6 hours ago
Used 1.5 premium request(s) Duration 5m0s
For detailed session logs, try:
gh agent-task view 'some-session-id' --log
@ -538,10 +641,12 @@ func Test_viewRun(t *testing.T) {
assert.Equal(t, defaultLimit, limit)
return []*capi.Session{
{
ID: "some-session-id",
Name: "session one",
State: "completed",
CreatedAt: sampleDate,
ID: "some-session-id",
Name: "session one",
State: "completed",
CreatedAt: sampleDate,
CompletedAt: sampleCompletedAt,
PremiumRequests: 1.5,
PullRequest: &api.PullRequest{
Title: "fix something",
Number: 101,
@ -555,10 +660,12 @@ func Test_viewRun(t *testing.T) {
},
},
{
ID: "some-other-session-id",
Name: "session two",
State: "completed",
CreatedAt: sampleDate,
ID: "some-other-session-id",
Name: "session two",
State: "completed",
CreatedAt: sampleDate,
CompletedAt: sampleCompletedAt,
PremiumRequests: 1.5,
PullRequest: &api.PullRequest{
Title: "fix something",
Number: 101,
@ -587,8 +694,9 @@ func Test_viewRun(t *testing.T) {
)
},
wantOut: heredoc.Doc(`
Completed fix something OWNER/REPO#101
Ready for review fix something OWNER/REPO#101
Started on behalf of octocat about 6 hours ago
Used 1.5 premium request(s) Duration 5m0s
For detailed session logs, try:
gh agent-task view 'some-session-id' --log
@ -620,10 +728,12 @@ func Test_viewRun(t *testing.T) {
assert.Equal(t, defaultLimit, limit)
return []*capi.Session{
{
ID: "some-session-id",
Name: "session one",
State: "completed",
CreatedAt: sampleDate,
ID: "some-session-id",
Name: "session one",
State: "completed",
CreatedAt: sampleDate,
CompletedAt: sampleCompletedAt,
PremiumRequests: 1.5,
PullRequest: &api.PullRequest{
Title: "fix something",
Number: 101,
@ -637,10 +747,12 @@ func Test_viewRun(t *testing.T) {
},
},
{
ID: "some-other-session-id",
Name: "session two",
State: "completed",
CreatedAt: sampleDate,
ID: "some-other-session-id",
Name: "session two",
State: "completed",
CreatedAt: sampleDate,
CompletedAt: sampleCompletedAt,
PremiumRequests: 1.5,
PullRequest: &api.PullRequest{
Title: "fix something",
Number: 101,
@ -669,8 +781,9 @@ func Test_viewRun(t *testing.T) {
)
},
wantOut: heredoc.Doc(`
Completed fix something OWNER/REPO#101
Ready for review fix something OWNER/REPO#101
Started on behalf of octocat about 6 hours ago
Used 1.5 premium request(s) Duration 5m0s
For detailed session logs, try:
gh agent-task view 'some-session-id' --log
@ -723,9 +836,11 @@ func Test_viewRun(t *testing.T) {
assert.Equal(t, defaultLimit, limit)
return []*capi.Session{
{
ID: "some-session-id",
State: "completed",
CreatedAt: sampleDate,
ID: "some-session-id",
State: "completed",
CreatedAt: sampleDate,
CompletedAt: sampleCompletedAt,
PremiumRequests: 1.5,
PullRequest: &api.PullRequest{
Title: "fix something",
Number: 101,
@ -764,10 +879,12 @@ func Test_viewRun(t *testing.T) {
assert.Equal(t, defaultLimit, limit)
return []*capi.Session{
{
ID: "some-session-id",
Name: "session one",
State: "completed",
CreatedAt: sampleDate,
ID: "some-session-id",
Name: "session one",
State: "completed",
CreatedAt: sampleDate,
CompletedAt: sampleCompletedAt,
PremiumRequests: 1.5,
PullRequest: &api.PullRequest{
Title: "fix something",
Number: 101,
@ -779,10 +896,12 @@ func Test_viewRun(t *testing.T) {
// User data is irrelevant in this case
},
{
ID: "some-other-session-id",
Name: "session two",
State: "completed",
CreatedAt: sampleDate,
ID: "some-other-session-id",
Name: "session two",
State: "completed",
CreatedAt: sampleDate,
CompletedAt: sampleCompletedAt,
PremiumRequests: 1.5,
PullRequest: &api.PullRequest{
Title: "fix something",
Number: 101,
@ -823,10 +942,12 @@ func Test_viewRun(t *testing.T) {
assert.Equal(t, defaultLimit, limit)
return []*capi.Session{
{
ID: "some-session-id",
Name: "session one",
State: "completed",
CreatedAt: sampleDate,
ID: "some-session-id",
Name: "session one",
State: "completed",
CreatedAt: sampleDate,
CompletedAt: sampleCompletedAt,
PremiumRequests: 1.5,
PullRequest: &api.PullRequest{
Title: "fix something",
Number: 101,
@ -838,10 +959,12 @@ func Test_viewRun(t *testing.T) {
// User data is irrelevant in this case
},
{
ID: "some-other-session-id",
Name: "session two",
State: "completed",
CreatedAt: sampleDate,
ID: "some-other-session-id",
Name: "session two",
State: "completed",
CreatedAt: sampleDate,
CompletedAt: sampleCompletedAt,
PremiumRequests: 1.5,
PullRequest: &api.PullRequest{
Title: "fix something",
Number: 101,
@ -870,9 +993,11 @@ func Test_viewRun(t *testing.T) {
m.GetSessionFunc = func(_ context.Context, id string) (*capi.Session, error) {
assert.Equal(t, "some-session-id", id)
return &capi.Session{
ID: "some-session-id",
State: "completed",
CreatedAt: sampleDate,
ID: "some-session-id",
State: "completed",
CreatedAt: sampleDate,
CompletedAt: sampleCompletedAt,
PremiumRequests: 1.5,
User: &api.GitHubUser{
Login: "octocat",
},
@ -890,12 +1015,6 @@ func Test_viewRun(t *testing.T) {
}
},
wantOut: heredoc.Doc(`
Completed
Started on behalf of octocat about 6 hours ago
To follow session logs, try:
gh agent-task view 'some-session-id' --log --follow
(rendered:) <raw-logs>
`),
},
@ -913,9 +1032,11 @@ func Test_viewRun(t *testing.T) {
m.GetSessionFunc = func(_ context.Context, id string) (*capi.Session, error) {
assert.Equal(t, "some-session-id", id)
return &capi.Session{
ID: "some-session-id",
State: "completed",
CreatedAt: sampleDate,
ID: "some-session-id",
State: "completed",
CreatedAt: sampleDate,
CompletedAt: sampleCompletedAt,
PremiumRequests: 1.5,
User: &api.GitHubUser{
Login: "octocat",
},
@ -947,9 +1068,6 @@ func Test_viewRun(t *testing.T) {
}
},
wantOut: heredoc.Doc(`
Completed
Started on behalf of octocat about 6 hours ago
(rendered:) <raw-logs-one>
(rendered:) <raw-logs-two>
`),

View file

@ -103,6 +103,8 @@ type FindOptions struct {
// States lists the possible PR states to scope the PR-for-branch lookup to.
States []string
DisableProgress bool
Detector fd.Detector
}
@ -196,8 +198,9 @@ func (f *finder) Find(opts FindOptions) (*api.PullRequest, ghrepo.Interface, err
return nil, nil, err
}
// TODO: Decouple the PR finder from IO
// TODO(josebalius): Should we be guarding here?
if f.progress != nil {
if !opts.DisableProgress && f.progress != nil {
f.progress.StartProgressIndicator()
defer f.progress.StopProgressIndicator()
}

View file

@ -190,9 +190,11 @@ type args struct {
baseRepoFn func() (ghrepo.Interface, error)
branchFn func() (string, error)
gitConfigClient stubGitConfigClient
progress *stubProgressIndicator
selector string
fields []string
baseBranch string
disableProgress bool
}
func TestFind(t *testing.T) {
@ -228,12 +230,13 @@ func TestFind(t *testing.T) {
}
tests := []struct {
name string
args args
httpStub func(*httpmock.Registry)
wantPR int
wantRepo string
wantErr bool
name string
args args
httpStub func(*httpmock.Registry)
wantUseProgress bool
wantPR int
wantRepo string
wantErr bool
}{
{
name: "number argument",
@ -824,6 +827,51 @@ func TestFind(t *testing.T) {
wantPR: 13,
wantRepo: "https://github.com/OWNER/REPO",
},
{
name: "number argument, with non nil-progress indicator",
args: args{
selector: "13",
fields: []string{"id", "number"},
baseRepoFn: stubBaseRepoFn(ghrepo.New("ORIGINOWNER", "REPO"), nil),
branchFn: func() (string, error) {
return "blueberries", nil
},
progress: &stubProgressIndicator{},
},
httpStub: func(r *httpmock.Registry) {
r.Register(
httpmock.GraphQL(`query PullRequestByNumber\b`),
httpmock.StringResponse(`{"data":{"repository":{
"pullRequest":{"number":13}
}}}`))
},
wantPR: 13,
wantRepo: "https://github.com/ORIGINOWNER/REPO",
wantUseProgress: true,
},
{
name: "number argument, with non-nil progress indicator and DisableProgress set",
args: args{
selector: "13",
fields: []string{"id", "number"},
baseRepoFn: stubBaseRepoFn(ghrepo.New("ORIGINOWNER", "REPO"), nil),
branchFn: func() (string, error) {
return "blueberries", nil
},
progress: &stubProgressIndicator{},
disableProgress: true,
},
httpStub: func(r *httpmock.Registry) {
r.Register(
httpmock.GraphQL(`query PullRequestByNumber\b`),
httpmock.StringResponse(`{"data":{"repository":{
"pullRequest":{"number":13}
}}}`))
},
wantPR: 13,
wantRepo: "https://github.com/ORIGINOWNER/REPO",
wantUseProgress: false,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
@ -847,11 +895,25 @@ func TestFind(t *testing.T) {
}, nil),
}
if tt.args.progress != nil {
f.progress = tt.args.progress
}
pr, repo, err := f.Find(FindOptions{
Selector: tt.args.selector,
Fields: tt.args.fields,
BaseBranch: tt.args.baseBranch,
Selector: tt.args.selector,
Fields: tt.args.fields,
BaseBranch: tt.args.baseBranch,
DisableProgress: tt.args.disableProgress,
})
if tt.args.progress != nil {
if tt.args.progress.startCalled != tt.wantUseProgress {
t.Errorf("progress was (not) used as expected")
} else if tt.args.progress.startCalled != tt.args.progress.stopCalled {
t.Errorf("progress was started but not stopped")
}
}
if (err != nil) != tt.wantErr {
t.Errorf("Find() error = %v, wantErr %v", err, tt.wantErr)
return
@ -947,3 +1009,16 @@ func (s stubGitConfigClient) PushRevision(ctx context.Context, branchName string
}
return s.pushRevisionFn(ctx, branchName)
}
type stubProgressIndicator struct {
startCalled bool
stopCalled bool
}
func (s *stubProgressIndicator) StartProgressIndicator() {
s.startCalled = true
}
func (s *stubProgressIndicator) StopProgressIndicator() {
s.stopCalled = true
}