1// Copyright (c) 2015 Ableton AG, Berlin. All rights reserved. 2// 3// Use of this source code is governed by a BSD-style 4// license that can be found in the LICENSE file. 5 6package travis 7 8import ( 9 "context" 10 "fmt" 11 "net/http" 12 "net/url" 13) 14 15// RequestsService handles communication with the requests 16// related methods of the Travis CI API. 17type RequestsService struct { 18 client *Client 19} 20 21// Request represents a Travis CI request. 22// They can be used to see if and why a GitHub even has or has not triggered a new build. 23// 24// // Travis CI API docs: https://developer.travis-ci.com/resource/request#standard-representation 25type Request struct { 26 // Value uniquely identifying the request 27 Id uint `json:"id,omitempty"` 28 // The state of a request (eg. whether it has been processed or not) 29 State string `json:"state,omitempty"` 30 // The result of the request (eg. rejected or approved) 31 Result string `json:"result,omitempty"` 32 // Travis-ci status message attached to the request. 33 Message string `json:"message,omitempty"` 34 // GitHub user or organization the request belongs to 35 Repository *Repository `json:"repository,omitempty"` 36 // Name of the branch requested to be built 37 BranchName string `json:"branch_name,omitempty"` 38 // The commit the request is associated with 39 Commit *Commit `json:"commit,omitempty"` 40 // The request's builds 41 Builds []*Build `json:"builds,omitempty"` 42 // GitHub user or organization the request belongs to 43 Owner *Owner `json:"owner,omitempty"` 44 // When Travis CI created the request 45 CreatedAt string `json:"created_at,omitempty"` 46 // Origin of request (push, pull request, api) 47 EventType string `json:"event_type,omitempty"` 48 *Metadata 49} 50 51// ListRequestsOption specifies options for 52// FindRequests request. 53type ListRequestsOption struct { 54 // How many requests to include in the response 55 Limit int `url:"limit,omitempty"` 56 // How many requests to skip before the first entry in the response 57 Offset int `url:"offset,omitempty"` 58} 59 60// RequestBody specifies body for 61// creating request. 62type RequestBody struct { 63 // Build configuration (as parsed from .travis.yml) 64 Config interface{} `json:"config,omitempty"` 65 // Travis-ci status message attached to the request 66 Message string `json:"message,omitempty"` 67 // Branch requested to be built 68 Branch string `json:"branch,omitempty"` 69 // Travis token associated with webhook on GitHub (DEPRECATED) 70 Token string `json:"token,omitempty"` 71} 72 73type getRequestsResponse struct { 74 Requests []*Request `json:"requests"` 75} 76 77// FindByRepoId fetches request of given repository id and request id 78// 79// Travis CI API docs: https://developer.travis-ci.com/resource/request#find 80func (rs *RequestsService) FindByRepoId(ctx context.Context, repoId uint, id uint) (*Request, *http.Response, error) { 81 u, err := urlWithOptions(fmt.Sprintf("/repo/%d/request/%d", repoId, id), nil) 82 if err != nil { 83 return nil, nil, err 84 } 85 86 req, err := rs.client.NewRequest(http.MethodGet, u, nil, nil) 87 if err != nil { 88 return nil, nil, err 89 } 90 91 var request Request 92 resp, err := rs.client.Do(ctx, req, &request) 93 if err != nil { 94 return nil, resp, err 95 } 96 97 return &request, resp, err 98} 99 100// FindByRepoSlug fetches request of given repository slug and request id 101// 102// Travis CI API docs: https://developer.travis-ci.com/resource/request#find 103func (rs *RequestsService) FindByRepoSlug(ctx context.Context, repoSlug string, id uint) (*Request, *http.Response, error) { 104 u, err := urlWithOptions(fmt.Sprintf("/repo/%s/request/%d", url.QueryEscape(repoSlug), id), nil) 105 if err != nil { 106 return nil, nil, err 107 } 108 109 req, err := rs.client.NewRequest(http.MethodGet, u, nil, nil) 110 if err != nil { 111 return nil, nil, err 112 } 113 114 var request Request 115 resp, err := rs.client.Do(ctx, req, &request) 116 if err != nil { 117 return nil, resp, err 118 } 119 120 return &request, resp, err 121} 122 123// Create endpoints actually returns following form of response. 124// It is different from standard nor minimal representation of a request. 125// So far, I'm not going to create a special struct to parse it, and 126// just use the minimal representation of request. 127// 128//{ 129// "@type": "pending", 130// "remaining_requests": 1, 131// "repository": { 132// "@type": "repository", 133// "@href": "/repo/1", 134// "@representation": "minimal", 135// "id": 1, 136// "name": "test", 137// "slug": "owner/repo" 138// }, 139// "request": { 140// "repository": { 141// "id": 1, 142// "owner_name": "owner", 143// "name": "repo" 144// }, 145// "user": { 146// "id": 1 147// }, 148// "id": 1, 149// "message": "Override the commit message: this is an api request", 150// "branch": "master", 151// "config": { } 152// }, 153// "resource_type": "request" 154//} 155type createRequestResponse struct { 156 Request Request `json:"request"` 157} 158 159// ListByRepoId fetches requests of given repository id 160// 161// Travis CI API docs: https://developer.travis-ci.com/resource/requests#find 162func (rs *RequestsService) ListByRepoId(ctx context.Context, repoId uint, opt *ListRequestsOption) ([]*Request, *http.Response, error) { 163 u, err := urlWithOptions(fmt.Sprintf("/repo/%d/requests", repoId), opt) 164 if err != nil { 165 return nil, nil, err 166 } 167 168 req, err := rs.client.NewRequest(http.MethodGet, u, nil, nil) 169 if err != nil { 170 return nil, nil, err 171 } 172 173 var getRequestsResponse getRequestsResponse 174 resp, err := rs.client.Do(ctx, req, &getRequestsResponse) 175 if err != nil { 176 return nil, resp, err 177 } 178 179 return getRequestsResponse.Requests, resp, err 180} 181 182// ListByRepoSlug fetches requests of given repository slug 183// 184// Travis CI API docs: https://developer.travis-ci.com/resource/requests#find 185func (rs *RequestsService) ListByRepoSlug(ctx context.Context, repoSlug string, opt *ListRequestsOption) ([]*Request, *http.Response, error) { 186 u, err := urlWithOptions(fmt.Sprintf("/repo/%s/requests", url.QueryEscape(repoSlug)), opt) 187 if err != nil { 188 return nil, nil, err 189 } 190 191 req, err := rs.client.NewRequest(http.MethodGet, u, nil, nil) 192 if err != nil { 193 return nil, nil, err 194 } 195 196 var getRequestsResponse getRequestsResponse 197 resp, err := rs.client.Do(ctx, req, &getRequestsResponse) 198 if err != nil { 199 return nil, resp, err 200 } 201 202 return getRequestsResponse.Requests, resp, err 203} 204 205// CreateByRepoId create requests of given repository id and provided options 206// 207// Travis CI API docs: https://developer.travis-ci.com/resource/requests#create 208func (rs *RequestsService) CreateByRepoId(ctx context.Context, repoId uint, request *RequestBody) (*Request, *http.Response, error) { 209 u, err := urlWithOptions(fmt.Sprintf("/repo/%d/requests", repoId), nil) 210 if err != nil { 211 return nil, nil, err 212 } 213 214 req, err := rs.client.NewRequest(http.MethodPost, u, request, nil) 215 if err != nil { 216 return nil, nil, err 217 } 218 219 var createRequestResponse createRequestResponse 220 resp, err := rs.client.Do(ctx, req, &createRequestResponse) 221 if err != nil { 222 return nil, resp, err 223 } 224 225 return &createRequestResponse.Request, resp, err 226} 227 228// CreateByRepoSlug create requests of given repository slug and provided options 229// 230// Travis CI API docs: https://developer.travis-ci.com/resource/requests#create 231func (rs *RequestsService) CreateByRepoSlug(ctx context.Context, repoSlug string, request *RequestBody) (*Request, *http.Response, error) { 232 u, err := urlWithOptions(fmt.Sprintf("/repo/%s/requests", url.QueryEscape(repoSlug)), nil) 233 if err != nil { 234 return nil, nil, err 235 } 236 237 req, err := rs.client.NewRequest(http.MethodPost, u, request, nil) 238 if err != nil { 239 return nil, nil, err 240 } 241 242 var createRequestResponse createRequestResponse 243 resp, err := rs.client.Do(ctx, req, &createRequestResponse) 244 if err != nil { 245 return nil, resp, err 246 } 247 248 return &createRequestResponse.Request, resp, err 249} 250