1
2
3
4
5
6 package github
7
8 import (
9 "context"
10 "fmt"
11 "net/http"
12 "net/url"
13 )
14
15
16 type TaskStep struct {
17 Name *string `json:"name,omitempty"`
18 Status *string `json:"status,omitempty"`
19 Conclusion *string `json:"conclusion,omitempty"`
20 Number *int64 `json:"number,omitempty"`
21 StartedAt *Timestamp `json:"started_at,omitempty"`
22 CompletedAt *Timestamp `json:"completed_at,omitempty"`
23 }
24
25
26 type WorkflowJob struct {
27 ID *int64 `json:"id,omitempty"`
28 RunID *int64 `json:"run_id,omitempty"`
29 RunURL *string `json:"run_url,omitempty"`
30 NodeID *string `json:"node_id,omitempty"`
31 HeadSHA *string `json:"head_sha,omitempty"`
32 URL *string `json:"url,omitempty"`
33 HTMLURL *string `json:"html_url,omitempty"`
34 Status *string `json:"status,omitempty"`
35 Conclusion *string `json:"conclusion,omitempty"`
36 StartedAt *Timestamp `json:"started_at,omitempty"`
37 CompletedAt *Timestamp `json:"completed_at,omitempty"`
38 Name *string `json:"name,omitempty"`
39 Steps []*TaskStep `json:"steps,omitempty"`
40 CheckRunURL *string `json:"check_run_url,omitempty"`
41 }
42
43
44 type Jobs struct {
45 TotalCount *int `json:"total_count,omitempty"`
46 Jobs []*WorkflowJob `json:"jobs,omitempty"`
47 }
48
49
50 type ListWorkflowJobsOptions struct {
51
52
53
54
55
56
57 Filter string `url:"filter,omitempty"`
58 ListOptions
59 }
60
61
62
63
64 func (s *ActionsService) ListWorkflowJobs(ctx context.Context, owner, repo string, runID int64, opts *ListWorkflowJobsOptions) (*Jobs, *Response, error) {
65 u := fmt.Sprintf("repos/%s/%s/actions/runs/%v/jobs", owner, repo, runID)
66 u, err := addOptions(u, opts)
67 if err != nil {
68 return nil, nil, err
69 }
70
71 req, err := s.client.NewRequest("GET", u, nil)
72 if err != nil {
73 return nil, nil, err
74 }
75
76 jobs := new(Jobs)
77 resp, err := s.client.Do(ctx, req, &jobs)
78 if err != nil {
79 return nil, resp, err
80 }
81
82 return jobs, resp, nil
83 }
84
85
86
87
88 func (s *ActionsService) GetWorkflowJobByID(ctx context.Context, owner, repo string, jobID int64) (*WorkflowJob, *Response, error) {
89 u := fmt.Sprintf("repos/%v/%v/actions/jobs/%v", owner, repo, jobID)
90
91 req, err := s.client.NewRequest("GET", u, nil)
92 if err != nil {
93 return nil, nil, err
94 }
95
96 job := new(WorkflowJob)
97 resp, err := s.client.Do(ctx, req, job)
98 if err != nil {
99 return nil, resp, err
100 }
101
102 return job, resp, nil
103 }
104
105
106
107
108 func (s *ActionsService) GetWorkflowJobLogs(ctx context.Context, owner, repo string, jobID int64, followRedirects bool) (*url.URL, *Response, error) {
109 u := fmt.Sprintf("repos/%v/%v/actions/jobs/%v/logs", owner, repo, jobID)
110
111 resp, err := s.getWorkflowLogsFromURL(ctx, u, followRedirects)
112 if err != nil {
113 return nil, nil, err
114 }
115
116 if resp.StatusCode != http.StatusFound {
117 return nil, newResponse(resp), fmt.Errorf("unexpected status code: %s", resp.Status)
118 }
119 parsedURL, err := url.Parse(resp.Header.Get("Location"))
120 return parsedURL, newResponse(resp), err
121 }
122
123 func (s *ActionsService) getWorkflowLogsFromURL(ctx context.Context, u string, followRedirects bool) (*http.Response, error) {
124 req, err := s.client.NewRequest("GET", u, nil)
125 if err != nil {
126 return nil, err
127 }
128
129 var resp *http.Response
130
131 req = withContext(ctx, req)
132 if s.client.client.Transport == nil {
133 resp, err = http.DefaultTransport.RoundTrip(req)
134 } else {
135 resp, err = s.client.client.Transport.RoundTrip(req)
136 }
137 if err != nil {
138 return nil, err
139 }
140 resp.Body.Close()
141
142
143 if followRedirects && resp.StatusCode == http.StatusMovedPermanently {
144 u = resp.Header.Get("Location")
145 resp, err = s.getWorkflowLogsFromURL(ctx, u, false)
146 }
147 return resp, err
148
149 }
150
View as plain text