1// Copyright 2018 The go-github AUTHORS. 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 github 7 8import ( 9 "context" 10 "fmt" 11) 12 13// ChecksService provides access to the Checks API in the 14// GitHub API. 15// 16// GitHub API docs: https://docs.github.com/en/free-pro-team@latest/rest/reference/checks/ 17type ChecksService service 18 19// CheckRun represents a GitHub check run on a repository associated with a GitHub app. 20type CheckRun struct { 21 ID *int64 `json:"id,omitempty"` 22 NodeID *string `json:"node_id,omitempty"` 23 HeadSHA *string `json:"head_sha,omitempty"` 24 ExternalID *string `json:"external_id,omitempty"` 25 URL *string `json:"url,omitempty"` 26 HTMLURL *string `json:"html_url,omitempty"` 27 DetailsURL *string `json:"details_url,omitempty"` 28 Status *string `json:"status,omitempty"` 29 Conclusion *string `json:"conclusion,omitempty"` 30 StartedAt *Timestamp `json:"started_at,omitempty"` 31 CompletedAt *Timestamp `json:"completed_at,omitempty"` 32 Output *CheckRunOutput `json:"output,omitempty"` 33 Name *string `json:"name,omitempty"` 34 CheckSuite *CheckSuite `json:"check_suite,omitempty"` 35 App *App `json:"app,omitempty"` 36 PullRequests []*PullRequest `json:"pull_requests,omitempty"` 37} 38 39// CheckRunOutput represents the output of a CheckRun. 40type CheckRunOutput struct { 41 Title *string `json:"title,omitempty"` 42 Summary *string `json:"summary,omitempty"` 43 Text *string `json:"text,omitempty"` 44 AnnotationsCount *int `json:"annotations_count,omitempty"` 45 AnnotationsURL *string `json:"annotations_url,omitempty"` 46 Annotations []*CheckRunAnnotation `json:"annotations,omitempty"` 47 Images []*CheckRunImage `json:"images,omitempty"` 48} 49 50// CheckRunAnnotation represents an annotation object for a CheckRun output. 51type CheckRunAnnotation struct { 52 Path *string `json:"path,omitempty"` 53 StartLine *int `json:"start_line,omitempty"` 54 EndLine *int `json:"end_line,omitempty"` 55 StartColumn *int `json:"start_column,omitempty"` 56 EndColumn *int `json:"end_column,omitempty"` 57 AnnotationLevel *string `json:"annotation_level,omitempty"` 58 Message *string `json:"message,omitempty"` 59 Title *string `json:"title,omitempty"` 60 RawDetails *string `json:"raw_details,omitempty"` 61} 62 63// CheckRunImage represents an image object for a CheckRun output. 64type CheckRunImage struct { 65 Alt *string `json:"alt,omitempty"` 66 ImageURL *string `json:"image_url,omitempty"` 67 Caption *string `json:"caption,omitempty"` 68} 69 70// CheckSuite represents a suite of check runs. 71type CheckSuite struct { 72 ID *int64 `json:"id,omitempty"` 73 NodeID *string `json:"node_id,omitempty"` 74 HeadBranch *string `json:"head_branch,omitempty"` 75 HeadSHA *string `json:"head_sha,omitempty"` 76 URL *string `json:"url,omitempty"` 77 BeforeSHA *string `json:"before,omitempty"` 78 AfterSHA *string `json:"after,omitempty"` 79 Status *string `json:"status,omitempty"` 80 Conclusion *string `json:"conclusion,omitempty"` 81 App *App `json:"app,omitempty"` 82 Repository *Repository `json:"repository,omitempty"` 83 PullRequests []*PullRequest `json:"pull_requests,omitempty"` 84 85 // The following fields are only populated by Webhook events. 86 HeadCommit *Commit `json:"head_commit,omitempty"` 87} 88 89func (c CheckRun) String() string { 90 return Stringify(c) 91} 92 93func (c CheckSuite) String() string { 94 return Stringify(c) 95} 96 97// GetCheckRun gets a check-run for a repository. 98// 99// GitHub API docs: https://docs.github.com/en/free-pro-team@latest/rest/reference/checks/#get-a-check-run 100func (s *ChecksService) GetCheckRun(ctx context.Context, owner, repo string, checkRunID int64) (*CheckRun, *Response, error) { 101 u := fmt.Sprintf("repos/%v/%v/check-runs/%v", owner, repo, checkRunID) 102 req, err := s.client.NewRequest("GET", u, nil) 103 if err != nil { 104 return nil, nil, err 105 } 106 107 checkRun := new(CheckRun) 108 resp, err := s.client.Do(ctx, req, checkRun) 109 if err != nil { 110 return nil, resp, err 111 } 112 113 return checkRun, resp, nil 114} 115 116// GetCheckSuite gets a single check suite. 117// 118// GitHub API docs: https://docs.github.com/en/free-pro-team@latest/rest/reference/checks/#get-a-check-suite 119func (s *ChecksService) GetCheckSuite(ctx context.Context, owner, repo string, checkSuiteID int64) (*CheckSuite, *Response, error) { 120 u := fmt.Sprintf("repos/%v/%v/check-suites/%v", owner, repo, checkSuiteID) 121 req, err := s.client.NewRequest("GET", u, nil) 122 if err != nil { 123 return nil, nil, err 124 } 125 126 checkSuite := new(CheckSuite) 127 resp, err := s.client.Do(ctx, req, checkSuite) 128 if err != nil { 129 return nil, resp, err 130 } 131 132 return checkSuite, resp, nil 133} 134 135// CreateCheckRunOptions sets up parameters needed to create a CheckRun. 136type CreateCheckRunOptions struct { 137 Name string `json:"name"` // The name of the check (e.g., "code-coverage"). (Required.) 138 HeadSHA string `json:"head_sha"` // The SHA of the commit. (Required.) 139 DetailsURL *string `json:"details_url,omitempty"` // The URL of the integrator's site that has the full details of the check. (Optional.) 140 ExternalID *string `json:"external_id,omitempty"` // A reference for the run on the integrator's system. (Optional.) 141 Status *string `json:"status,omitempty"` // The current status. Can be one of "queued", "in_progress", or "completed". Default: "queued". (Optional.) 142 Conclusion *string `json:"conclusion,omitempty"` // Can be one of "success", "failure", "neutral", "cancelled", "skipped", "timed_out", or "action_required". (Optional. Required if you provide a status of "completed".) 143 StartedAt *Timestamp `json:"started_at,omitempty"` // The time that the check run began. (Optional.) 144 CompletedAt *Timestamp `json:"completed_at,omitempty"` // The time the check completed. (Optional. Required if you provide conclusion.) 145 Output *CheckRunOutput `json:"output,omitempty"` // Provide descriptive details about the run. (Optional) 146 Actions []*CheckRunAction `json:"actions,omitempty"` // Possible further actions the integrator can perform, which a user may trigger. (Optional.) 147} 148 149// CheckRunAction exposes further actions the integrator can perform, which a user may trigger. 150type CheckRunAction struct { 151 Label string `json:"label"` // The text to be displayed on a button in the web UI. The maximum size is 20 characters. (Required.) 152 Description string `json:"description"` // A short explanation of what this action would do. The maximum size is 40 characters. (Required.) 153 Identifier string `json:"identifier"` // A reference for the action on the integrator's system. The maximum size is 20 characters. (Required.) 154} 155 156// CreateCheckRun creates a check run for repository. 157// 158// GitHub API docs: https://docs.github.com/en/free-pro-team@latest/rest/reference/checks/#create-a-check-run 159func (s *ChecksService) CreateCheckRun(ctx context.Context, owner, repo string, opts CreateCheckRunOptions) (*CheckRun, *Response, error) { 160 u := fmt.Sprintf("repos/%v/%v/check-runs", owner, repo) 161 req, err := s.client.NewRequest("POST", u, opts) 162 if err != nil { 163 return nil, nil, err 164 } 165 166 checkRun := new(CheckRun) 167 resp, err := s.client.Do(ctx, req, checkRun) 168 if err != nil { 169 return nil, resp, err 170 } 171 172 return checkRun, resp, nil 173} 174 175// UpdateCheckRunOptions sets up parameters needed to update a CheckRun. 176type UpdateCheckRunOptions struct { 177 Name string `json:"name"` // The name of the check (e.g., "code-coverage"). (Required.) 178 DetailsURL *string `json:"details_url,omitempty"` // The URL of the integrator's site that has the full details of the check. (Optional.) 179 ExternalID *string `json:"external_id,omitempty"` // A reference for the run on the integrator's system. (Optional.) 180 Status *string `json:"status,omitempty"` // The current status. Can be one of "queued", "in_progress", or "completed". Default: "queued". (Optional.) 181 Conclusion *string `json:"conclusion,omitempty"` // Can be one of "success", "failure", "neutral", "cancelled", "skipped", "timed_out", or "action_required". (Optional. Required if you provide a status of "completed".) 182 CompletedAt *Timestamp `json:"completed_at,omitempty"` // The time the check completed. (Optional. Required if you provide conclusion.) 183 Output *CheckRunOutput `json:"output,omitempty"` // Provide descriptive details about the run. (Optional) 184 Actions []*CheckRunAction `json:"actions,omitempty"` // Possible further actions the integrator can perform, which a user may trigger. (Optional.) 185} 186 187// UpdateCheckRun updates a check run for a specific commit in a repository. 188// 189// GitHub API docs: https://docs.github.com/en/free-pro-team@latest/rest/reference/checks/#update-a-check-run 190func (s *ChecksService) UpdateCheckRun(ctx context.Context, owner, repo string, checkRunID int64, opts UpdateCheckRunOptions) (*CheckRun, *Response, error) { 191 u := fmt.Sprintf("repos/%v/%v/check-runs/%v", owner, repo, checkRunID) 192 req, err := s.client.NewRequest("PATCH", u, opts) 193 if err != nil { 194 return nil, nil, err 195 } 196 197 checkRun := new(CheckRun) 198 resp, err := s.client.Do(ctx, req, checkRun) 199 if err != nil { 200 return nil, resp, err 201 } 202 203 return checkRun, resp, nil 204} 205 206// ListCheckRunAnnotations lists the annotations for a check run. 207// 208// GitHub API docs: https://docs.github.com/en/free-pro-team@latest/rest/reference/checks/#list-check-run-annotations 209func (s *ChecksService) ListCheckRunAnnotations(ctx context.Context, owner, repo string, checkRunID int64, opts *ListOptions) ([]*CheckRunAnnotation, *Response, error) { 210 u := fmt.Sprintf("repos/%v/%v/check-runs/%v/annotations", owner, repo, checkRunID) 211 u, err := addOptions(u, opts) 212 if err != nil { 213 return nil, nil, err 214 } 215 216 req, err := s.client.NewRequest("GET", u, nil) 217 if err != nil { 218 return nil, nil, err 219 } 220 221 var checkRunAnnotations []*CheckRunAnnotation 222 resp, err := s.client.Do(ctx, req, &checkRunAnnotations) 223 if err != nil { 224 return nil, resp, err 225 } 226 227 return checkRunAnnotations, resp, nil 228} 229 230// ListCheckRunsOptions represents parameters to list check runs. 231type ListCheckRunsOptions struct { 232 CheckName *string `url:"check_name,omitempty"` // Returns check runs with the specified name. 233 Status *string `url:"status,omitempty"` // Returns check runs with the specified status. Can be one of "queued", "in_progress", or "completed". 234 Filter *string `url:"filter,omitempty"` // Filters check runs by their completed_at timestamp. Can be one of "latest" (returning the most recent check runs) or "all". Default: "latest" 235 236 ListOptions 237} 238 239// ListCheckRunsResults represents the result of a check run list. 240type ListCheckRunsResults struct { 241 Total *int `json:"total_count,omitempty"` 242 CheckRuns []*CheckRun `json:"check_runs,omitempty"` 243} 244 245// ListCheckRunsForRef lists check runs for a specific ref. 246// 247// GitHub API docs: https://docs.github.com/en/free-pro-team@latest/rest/reference/checks/#list-check-runs-for-a-git-reference 248func (s *ChecksService) ListCheckRunsForRef(ctx context.Context, owner, repo, ref string, opts *ListCheckRunsOptions) (*ListCheckRunsResults, *Response, error) { 249 u := fmt.Sprintf("repos/%v/%v/commits/%v/check-runs", owner, repo, refURLEscape(ref)) 250 u, err := addOptions(u, opts) 251 if err != nil { 252 return nil, nil, err 253 } 254 255 req, err := s.client.NewRequest("GET", u, nil) 256 if err != nil { 257 return nil, nil, err 258 } 259 260 var checkRunResults *ListCheckRunsResults 261 resp, err := s.client.Do(ctx, req, &checkRunResults) 262 if err != nil { 263 return nil, resp, err 264 } 265 266 return checkRunResults, resp, nil 267} 268 269// ListCheckRunsCheckSuite lists check runs for a check suite. 270// 271// GitHub API docs: https://docs.github.com/en/free-pro-team@latest/rest/reference/checks/#list-check-runs-in-a-check-suite 272func (s *ChecksService) ListCheckRunsCheckSuite(ctx context.Context, owner, repo string, checkSuiteID int64, opts *ListCheckRunsOptions) (*ListCheckRunsResults, *Response, error) { 273 u := fmt.Sprintf("repos/%v/%v/check-suites/%v/check-runs", owner, repo, checkSuiteID) 274 u, err := addOptions(u, opts) 275 if err != nil { 276 return nil, nil, err 277 } 278 279 req, err := s.client.NewRequest("GET", u, nil) 280 if err != nil { 281 return nil, nil, err 282 } 283 284 var checkRunResults *ListCheckRunsResults 285 resp, err := s.client.Do(ctx, req, &checkRunResults) 286 if err != nil { 287 return nil, resp, err 288 } 289 290 return checkRunResults, resp, nil 291} 292 293// ListCheckSuiteOptions represents parameters to list check suites. 294type ListCheckSuiteOptions struct { 295 CheckName *string `url:"check_name,omitempty"` // Filters checks suites by the name of the check run. 296 AppID *int `url:"app_id,omitempty"` // Filters check suites by GitHub App id. 297 298 ListOptions 299} 300 301// ListCheckSuiteResults represents the result of a check run list. 302type ListCheckSuiteResults struct { 303 Total *int `json:"total_count,omitempty"` 304 CheckSuites []*CheckSuite `json:"check_suites,omitempty"` 305} 306 307// ListCheckSuitesForRef lists check suite for a specific ref. 308// 309// GitHub API docs: https://docs.github.com/en/free-pro-team@latest/rest/reference/checks/#list-check-suites-for-a-git-reference 310func (s *ChecksService) ListCheckSuitesForRef(ctx context.Context, owner, repo, ref string, opts *ListCheckSuiteOptions) (*ListCheckSuiteResults, *Response, error) { 311 u := fmt.Sprintf("repos/%v/%v/commits/%v/check-suites", owner, repo, refURLEscape(ref)) 312 u, err := addOptions(u, opts) 313 if err != nil { 314 return nil, nil, err 315 } 316 317 req, err := s.client.NewRequest("GET", u, nil) 318 if err != nil { 319 return nil, nil, err 320 } 321 322 var checkSuiteResults *ListCheckSuiteResults 323 resp, err := s.client.Do(ctx, req, &checkSuiteResults) 324 if err != nil { 325 return nil, resp, err 326 } 327 328 return checkSuiteResults, resp, nil 329} 330 331// AutoTriggerCheck enables or disables automatic creation of CheckSuite events upon pushes to the repository. 332type AutoTriggerCheck struct { 333 AppID *int64 `json:"app_id,omitempty"` // The id of the GitHub App. (Required.) 334 Setting *bool `json:"setting,omitempty"` // Set to "true" to enable automatic creation of CheckSuite events upon pushes to the repository, or "false" to disable them. Default: "true" (Required.) 335} 336 337// CheckSuitePreferenceOptions set options for check suite preferences for a repository. 338type CheckSuitePreferenceOptions struct { 339 AutoTriggerChecks []*AutoTriggerCheck `json:"auto_trigger_checks,omitempty"` // A slice of auto trigger checks that can be set for a check suite in a repository. 340} 341 342// CheckSuitePreferenceResults represents the results of the preference set operation. 343type CheckSuitePreferenceResults struct { 344 Preferences *PreferenceList `json:"preferences,omitempty"` 345 Repository *Repository `json:"repository,omitempty"` 346} 347 348// PreferenceList represents a list of auto trigger checks for repository 349type PreferenceList struct { 350 AutoTriggerChecks []*AutoTriggerCheck `json:"auto_trigger_checks,omitempty"` // A slice of auto trigger checks that can be set for a check suite in a repository. 351} 352 353// SetCheckSuitePreferences changes the default automatic flow when creating check suites. 354// 355// GitHub API docs: https://docs.github.com/en/free-pro-team@latest/rest/reference/checks/#update-repository-preferences-for-check-suites 356func (s *ChecksService) SetCheckSuitePreferences(ctx context.Context, owner, repo string, opts CheckSuitePreferenceOptions) (*CheckSuitePreferenceResults, *Response, error) { 357 u := fmt.Sprintf("repos/%v/%v/check-suites/preferences", owner, repo) 358 req, err := s.client.NewRequest("PATCH", u, opts) 359 if err != nil { 360 return nil, nil, err 361 } 362 363 var checkSuitePrefResults *CheckSuitePreferenceResults 364 resp, err := s.client.Do(ctx, req, &checkSuitePrefResults) 365 if err != nil { 366 return nil, resp, err 367 } 368 369 return checkSuitePrefResults, resp, nil 370} 371 372// CreateCheckSuiteOptions sets up parameters to manually create a check suites 373type CreateCheckSuiteOptions struct { 374 HeadSHA string `json:"head_sha"` // The sha of the head commit. (Required.) 375 HeadBranch *string `json:"head_branch,omitempty"` // The name of the head branch where the code changes are implemented. 376} 377 378// CreateCheckSuite manually creates a check suite for a repository. 379// 380// GitHub API docs: https://docs.github.com/en/free-pro-team@latest/rest/reference/checks/#create-a-check-suite 381func (s *ChecksService) CreateCheckSuite(ctx context.Context, owner, repo string, opts CreateCheckSuiteOptions) (*CheckSuite, *Response, error) { 382 u := fmt.Sprintf("repos/%v/%v/check-suites", owner, repo) 383 req, err := s.client.NewRequest("POST", u, opts) 384 if err != nil { 385 return nil, nil, err 386 } 387 388 checkSuite := new(CheckSuite) 389 resp, err := s.client.Do(ctx, req, checkSuite) 390 if err != nil { 391 return nil, resp, err 392 } 393 394 return checkSuite, resp, nil 395} 396 397// ReRequestCheckSuite triggers GitHub to rerequest an existing check suite, without pushing new code to a repository. 398// 399// GitHub API docs: https://docs.github.com/en/free-pro-team@latest/rest/reference/checks/#rerequest-a-check-suite 400func (s *ChecksService) ReRequestCheckSuite(ctx context.Context, owner, repo string, checkSuiteID int64) (*Response, error) { 401 u := fmt.Sprintf("repos/%v/%v/check-suites/%v/rerequest", owner, repo, checkSuiteID) 402 403 req, err := s.client.NewRequest("POST", u, nil) 404 if err != nil { 405 return nil, err 406 } 407 408 resp, err := s.client.Do(ctx, req, nil) 409 return resp, err 410} 411