github.com/google/go-github/v71@v71.0.0/github/actions_workflow_runs.go (about)

     1  // Copyright 2020 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  
     6  package github
     7  
     8  import (
     9  	"context"
    10  	"fmt"
    11  	"net/http"
    12  	"net/url"
    13  )
    14  
    15  // WorkflowRun represents a repository action workflow run.
    16  type WorkflowRun struct {
    17  	ID                  *int64                `json:"id,omitempty"`
    18  	Name                *string               `json:"name,omitempty"`
    19  	NodeID              *string               `json:"node_id,omitempty"`
    20  	HeadBranch          *string               `json:"head_branch,omitempty"`
    21  	HeadSHA             *string               `json:"head_sha,omitempty"`
    22  	Path                *string               `json:"path,omitempty"`
    23  	RunNumber           *int                  `json:"run_number,omitempty"`
    24  	RunAttempt          *int                  `json:"run_attempt,omitempty"`
    25  	Event               *string               `json:"event,omitempty"`
    26  	DisplayTitle        *string               `json:"display_title,omitempty"`
    27  	Status              *string               `json:"status,omitempty"`
    28  	Conclusion          *string               `json:"conclusion,omitempty"`
    29  	WorkflowID          *int64                `json:"workflow_id,omitempty"`
    30  	CheckSuiteID        *int64                `json:"check_suite_id,omitempty"`
    31  	CheckSuiteNodeID    *string               `json:"check_suite_node_id,omitempty"`
    32  	URL                 *string               `json:"url,omitempty"`
    33  	HTMLURL             *string               `json:"html_url,omitempty"`
    34  	PullRequests        []*PullRequest        `json:"pull_requests,omitempty"`
    35  	CreatedAt           *Timestamp            `json:"created_at,omitempty"`
    36  	UpdatedAt           *Timestamp            `json:"updated_at,omitempty"`
    37  	RunStartedAt        *Timestamp            `json:"run_started_at,omitempty"`
    38  	JobsURL             *string               `json:"jobs_url,omitempty"`
    39  	LogsURL             *string               `json:"logs_url,omitempty"`
    40  	CheckSuiteURL       *string               `json:"check_suite_url,omitempty"`
    41  	ArtifactsURL        *string               `json:"artifacts_url,omitempty"`
    42  	CancelURL           *string               `json:"cancel_url,omitempty"`
    43  	RerunURL            *string               `json:"rerun_url,omitempty"`
    44  	PreviousAttemptURL  *string               `json:"previous_attempt_url,omitempty"`
    45  	HeadCommit          *HeadCommit           `json:"head_commit,omitempty"`
    46  	WorkflowURL         *string               `json:"workflow_url,omitempty"`
    47  	Repository          *Repository           `json:"repository,omitempty"`
    48  	HeadRepository      *Repository           `json:"head_repository,omitempty"`
    49  	Actor               *User                 `json:"actor,omitempty"`
    50  	TriggeringActor     *User                 `json:"triggering_actor,omitempty"`
    51  	ReferencedWorkflows []*ReferencedWorkflow `json:"referenced_workflows,omitempty"`
    52  }
    53  
    54  // WorkflowRuns represents a slice of repository action workflow run.
    55  type WorkflowRuns struct {
    56  	TotalCount   *int           `json:"total_count,omitempty"`
    57  	WorkflowRuns []*WorkflowRun `json:"workflow_runs,omitempty"`
    58  }
    59  
    60  // ListWorkflowRunsOptions specifies optional parameters to ListWorkflowRuns.
    61  type ListWorkflowRunsOptions struct {
    62  	Actor               string `url:"actor,omitempty"`
    63  	Branch              string `url:"branch,omitempty"`
    64  	Event               string `url:"event,omitempty"`
    65  	Status              string `url:"status,omitempty"`
    66  	Created             string `url:"created,omitempty"`
    67  	HeadSHA             string `url:"head_sha,omitempty"`
    68  	ExcludePullRequests bool   `url:"exclude_pull_requests,omitempty"`
    69  	CheckSuiteID        int64  `url:"check_suite_id,omitempty"`
    70  	ListOptions
    71  }
    72  
    73  // WorkflowRunUsage represents a usage of a specific workflow run.
    74  type WorkflowRunUsage struct {
    75  	Billable      *WorkflowRunBillMap `json:"billable,omitempty"`
    76  	RunDurationMS *int64              `json:"run_duration_ms,omitempty"`
    77  }
    78  
    79  // WorkflowRunBillMap represents different runner environments available for a workflow run.
    80  // Its key is the name of its environment, e.g. "UBUNTU", "MACOS", "WINDOWS", etc.
    81  type WorkflowRunBillMap map[string]*WorkflowRunBill
    82  
    83  // WorkflowRunBill specifies billable time for a specific environment in a workflow run.
    84  type WorkflowRunBill struct {
    85  	TotalMS *int64               `json:"total_ms,omitempty"`
    86  	Jobs    *int                 `json:"jobs,omitempty"`
    87  	JobRuns []*WorkflowRunJobRun `json:"job_runs,omitempty"`
    88  }
    89  
    90  // WorkflowRunJobRun represents a usage of individual jobs of a specific workflow run.
    91  type WorkflowRunJobRun struct {
    92  	JobID      *int   `json:"job_id,omitempty"`
    93  	DurationMS *int64 `json:"duration_ms,omitempty"`
    94  }
    95  
    96  // WorkflowRunAttemptOptions specifies optional parameters to GetWorkflowRunAttempt.
    97  type WorkflowRunAttemptOptions struct {
    98  	ExcludePullRequests *bool `url:"exclude_pull_requests,omitempty"`
    99  }
   100  
   101  // PendingDeploymentsRequest specifies body parameters to PendingDeployments.
   102  type PendingDeploymentsRequest struct {
   103  	EnvironmentIDs []int64 `json:"environment_ids"`
   104  	// State can be one of: "approved", "rejected".
   105  	State   string `json:"state"`
   106  	Comment string `json:"comment"`
   107  }
   108  
   109  type ReferencedWorkflow struct {
   110  	Path *string `json:"path,omitempty"`
   111  	SHA  *string `json:"sha,omitempty"`
   112  	Ref  *string `json:"ref,omitempty"`
   113  }
   114  
   115  // PendingDeployment represents the pending_deployments response.
   116  type PendingDeployment struct {
   117  	Environment           *PendingDeploymentEnvironment `json:"environment,omitempty"`
   118  	WaitTimer             *int64                        `json:"wait_timer,omitempty"`
   119  	WaitTimerStartedAt    *Timestamp                    `json:"wait_timer_started_at,omitempty"`
   120  	CurrentUserCanApprove *bool                         `json:"current_user_can_approve,omitempty"`
   121  	Reviewers             []*RequiredReviewer           `json:"reviewers,omitempty"`
   122  }
   123  
   124  // PendingDeploymentEnvironment represents pending deployment environment properties.
   125  type PendingDeploymentEnvironment struct {
   126  	ID      *int64  `json:"id,omitempty"`
   127  	NodeID  *string `json:"node_id,omitempty"`
   128  	Name    *string `json:"name,omitempty"`
   129  	URL     *string `json:"url,omitempty"`
   130  	HTMLURL *string `json:"html_url,omitempty"`
   131  }
   132  
   133  // ReviewCustomDeploymentProtectionRuleRequest specifies the parameters to ReviewCustomDeploymentProtectionRule.
   134  type ReviewCustomDeploymentProtectionRuleRequest struct {
   135  	EnvironmentName string `json:"environment_name"`
   136  	State           string `json:"state"`
   137  	Comment         string `json:"comment"`
   138  }
   139  
   140  func (s *ActionsService) listWorkflowRuns(ctx context.Context, endpoint string, opts *ListWorkflowRunsOptions) (*WorkflowRuns, *Response, error) {
   141  	u, err := addOptions(endpoint, opts)
   142  	if err != nil {
   143  		return nil, nil, err
   144  	}
   145  
   146  	req, err := s.client.NewRequest("GET", u, nil)
   147  	if err != nil {
   148  		return nil, nil, err
   149  	}
   150  
   151  	runs := new(WorkflowRuns)
   152  	resp, err := s.client.Do(ctx, req, &runs)
   153  	if err != nil {
   154  		return nil, resp, err
   155  	}
   156  
   157  	return runs, resp, nil
   158  }
   159  
   160  // ListWorkflowRunsByID lists all workflow runs by workflow ID.
   161  //
   162  // GitHub API docs: https://docs.github.com/rest/actions/workflow-runs#list-workflow-runs-for-a-workflow
   163  //
   164  //meta:operation GET /repos/{owner}/{repo}/actions/workflows/{workflow_id}/runs
   165  func (s *ActionsService) ListWorkflowRunsByID(ctx context.Context, owner, repo string, workflowID int64, opts *ListWorkflowRunsOptions) (*WorkflowRuns, *Response, error) {
   166  	u := fmt.Sprintf("repos/%s/%s/actions/workflows/%v/runs", owner, repo, workflowID)
   167  	return s.listWorkflowRuns(ctx, u, opts)
   168  }
   169  
   170  // ListWorkflowRunsByFileName lists all workflow runs by workflow file name.
   171  //
   172  // GitHub API docs: https://docs.github.com/rest/actions/workflow-runs#list-workflow-runs-for-a-workflow
   173  //
   174  //meta:operation GET /repos/{owner}/{repo}/actions/workflows/{workflow_id}/runs
   175  func (s *ActionsService) ListWorkflowRunsByFileName(ctx context.Context, owner, repo, workflowFileName string, opts *ListWorkflowRunsOptions) (*WorkflowRuns, *Response, error) {
   176  	u := fmt.Sprintf("repos/%s/%s/actions/workflows/%v/runs", owner, repo, workflowFileName)
   177  	return s.listWorkflowRuns(ctx, u, opts)
   178  }
   179  
   180  // ListRepositoryWorkflowRuns lists all workflow runs for a repository.
   181  //
   182  // GitHub API docs: https://docs.github.com/rest/actions/workflow-runs#list-workflow-runs-for-a-repository
   183  //
   184  //meta:operation GET /repos/{owner}/{repo}/actions/runs
   185  func (s *ActionsService) ListRepositoryWorkflowRuns(ctx context.Context, owner, repo string, opts *ListWorkflowRunsOptions) (*WorkflowRuns, *Response, error) {
   186  	u := fmt.Sprintf("repos/%s/%s/actions/runs", owner, repo)
   187  	u, err := addOptions(u, opts)
   188  	if err != nil {
   189  		return nil, nil, err
   190  	}
   191  
   192  	req, err := s.client.NewRequest("GET", u, nil)
   193  	if err != nil {
   194  		return nil, nil, err
   195  	}
   196  
   197  	runs := new(WorkflowRuns)
   198  	resp, err := s.client.Do(ctx, req, &runs)
   199  	if err != nil {
   200  		return nil, resp, err
   201  	}
   202  
   203  	return runs, resp, nil
   204  }
   205  
   206  // GetWorkflowRunByID gets a specific workflow run by ID.
   207  // You can use the helper function *DeploymentProtectionRuleEvent.GetRunID() to easily retrieve the workflow run ID from a DeploymentProtectionRuleEvent.
   208  //
   209  // GitHub API docs: https://docs.github.com/rest/actions/workflow-runs#get-a-workflow-run
   210  //
   211  //meta:operation GET /repos/{owner}/{repo}/actions/runs/{run_id}
   212  func (s *ActionsService) GetWorkflowRunByID(ctx context.Context, owner, repo string, runID int64) (*WorkflowRun, *Response, error) {
   213  	u := fmt.Sprintf("repos/%v/%v/actions/runs/%v", owner, repo, runID)
   214  
   215  	req, err := s.client.NewRequest("GET", u, nil)
   216  	if err != nil {
   217  		return nil, nil, err
   218  	}
   219  
   220  	run := new(WorkflowRun)
   221  	resp, err := s.client.Do(ctx, req, run)
   222  	if err != nil {
   223  		return nil, resp, err
   224  	}
   225  
   226  	return run, resp, nil
   227  }
   228  
   229  // GetWorkflowRunAttempt gets a specific workflow run attempt.
   230  // You can use the helper function *DeploymentProtectionRuleEvent.GetRunID() to easily retrieve the workflow run ID from a DeploymentProtectionRuleEvent.
   231  //
   232  // GitHub API docs: https://docs.github.com/rest/actions/workflow-runs#get-a-workflow-run-attempt
   233  //
   234  //meta:operation GET /repos/{owner}/{repo}/actions/runs/{run_id}/attempts/{attempt_number}
   235  func (s *ActionsService) GetWorkflowRunAttempt(ctx context.Context, owner, repo string, runID int64, attemptNumber int, opts *WorkflowRunAttemptOptions) (*WorkflowRun, *Response, error) {
   236  	u := fmt.Sprintf("repos/%v/%v/actions/runs/%v/attempts/%v", owner, repo, runID, attemptNumber)
   237  	u, err := addOptions(u, opts)
   238  	if err != nil {
   239  		return nil, nil, err
   240  	}
   241  
   242  	req, err := s.client.NewRequest("GET", u, nil)
   243  	if err != nil {
   244  		return nil, nil, err
   245  	}
   246  
   247  	run := new(WorkflowRun)
   248  	resp, err := s.client.Do(ctx, req, run)
   249  	if err != nil {
   250  		return nil, resp, err
   251  	}
   252  
   253  	return run, resp, nil
   254  }
   255  
   256  // GetWorkflowRunAttemptLogs gets a redirect URL to download a plain text file of logs for a workflow run for attempt number.
   257  // You can use the helper function *DeploymentProtectionRuleEvent.GetRunID() to easily retrieve a workflow run ID from the DeploymentProtectionRuleEvent.
   258  //
   259  // GitHub API docs: https://docs.github.com/rest/actions/workflow-runs#download-workflow-run-attempt-logs
   260  //
   261  //meta:operation GET /repos/{owner}/{repo}/actions/runs/{run_id}/attempts/{attempt_number}/logs
   262  func (s *ActionsService) GetWorkflowRunAttemptLogs(ctx context.Context, owner, repo string, runID int64, attemptNumber int, maxRedirects int) (*url.URL, *Response, error) {
   263  	u := fmt.Sprintf("repos/%v/%v/actions/runs/%v/attempts/%v/logs", owner, repo, runID, attemptNumber)
   264  
   265  	if s.client.RateLimitRedirectionalEndpoints {
   266  		return s.getWorkflowRunAttemptLogsWithRateLimit(ctx, u, maxRedirects)
   267  	}
   268  
   269  	return s.getWorkflowRunAttemptLogsWithoutRateLimit(ctx, u, maxRedirects)
   270  }
   271  
   272  func (s *ActionsService) getWorkflowRunAttemptLogsWithoutRateLimit(ctx context.Context, u string, maxRedirects int) (*url.URL, *Response, error) {
   273  	resp, err := s.client.roundTripWithOptionalFollowRedirect(ctx, u, maxRedirects)
   274  	if err != nil {
   275  		return nil, nil, err
   276  	}
   277  	defer resp.Body.Close()
   278  
   279  	if resp.StatusCode != http.StatusFound {
   280  		return nil, newResponse(resp), fmt.Errorf("unexpected status code: %v", resp.Status)
   281  	}
   282  
   283  	parsedURL, err := url.Parse(resp.Header.Get("Location"))
   284  	return parsedURL, newResponse(resp), err
   285  }
   286  
   287  func (s *ActionsService) getWorkflowRunAttemptLogsWithRateLimit(ctx context.Context, u string, maxRedirects int) (*url.URL, *Response, error) {
   288  	req, err := s.client.NewRequest("GET", u, nil)
   289  	if err != nil {
   290  		return nil, nil, err
   291  	}
   292  
   293  	url, resp, err := s.client.bareDoUntilFound(ctx, req, maxRedirects)
   294  	if err != nil {
   295  		return nil, resp, err
   296  	}
   297  	defer resp.Body.Close()
   298  
   299  	// If we didn't receive a valid Location in a 302 response
   300  	if url == nil {
   301  		return nil, resp, fmt.Errorf("unexpected status code: %v", resp.Status)
   302  	}
   303  
   304  	return url, resp, nil
   305  }
   306  
   307  // RerunWorkflowByID re-runs a workflow by ID.
   308  // You can use the helper function *DeploymentProtectionRuleEvent.GetRunID() to easily retrieve the workflow run ID a the DeploymentProtectionRuleEvent.
   309  //
   310  // GitHub API docs: https://docs.github.com/rest/actions/workflow-runs#re-run-a-workflow
   311  //
   312  //meta:operation POST /repos/{owner}/{repo}/actions/runs/{run_id}/rerun
   313  func (s *ActionsService) RerunWorkflowByID(ctx context.Context, owner, repo string, runID int64) (*Response, error) {
   314  	u := fmt.Sprintf("repos/%v/%v/actions/runs/%v/rerun", owner, repo, runID)
   315  
   316  	req, err := s.client.NewRequest("POST", u, nil)
   317  	if err != nil {
   318  		return nil, err
   319  	}
   320  
   321  	return s.client.Do(ctx, req, nil)
   322  }
   323  
   324  // RerunFailedJobsByID re-runs all of the failed jobs and their dependent jobs in a workflow run by ID.
   325  // You can use the helper function *DeploymentProtectionRuleEvent.GetRunID() to easily retrieve the workflow run ID from a DeploymentProtectionRuleEvent.
   326  //
   327  // GitHub API docs: https://docs.github.com/rest/actions/workflow-runs#re-run-failed-jobs-from-a-workflow-run
   328  //
   329  //meta:operation POST /repos/{owner}/{repo}/actions/runs/{run_id}/rerun-failed-jobs
   330  func (s *ActionsService) RerunFailedJobsByID(ctx context.Context, owner, repo string, runID int64) (*Response, error) {
   331  	u := fmt.Sprintf("repos/%v/%v/actions/runs/%v/rerun-failed-jobs", owner, repo, runID)
   332  
   333  	req, err := s.client.NewRequest("POST", u, nil)
   334  	if err != nil {
   335  		return nil, err
   336  	}
   337  
   338  	return s.client.Do(ctx, req, nil)
   339  }
   340  
   341  // RerunJobByID re-runs a job and its dependent jobs in a workflow run by ID.
   342  //
   343  // You can use the helper function *DeploymentProtectionRuleEvent.GetRunID() to easily retrieve the workflow run ID from a DeploymentProtectionRuleEvent.
   344  //
   345  // GitHub API docs: https://docs.github.com/rest/actions/workflow-runs#re-run-a-job-from-a-workflow-run
   346  //
   347  //meta:operation POST /repos/{owner}/{repo}/actions/jobs/{job_id}/rerun
   348  func (s *ActionsService) RerunJobByID(ctx context.Context, owner, repo string, jobID int64) (*Response, error) {
   349  	u := fmt.Sprintf("repos/%v/%v/actions/jobs/%v/rerun", owner, repo, jobID)
   350  
   351  	req, err := s.client.NewRequest("POST", u, nil)
   352  	if err != nil {
   353  		return nil, err
   354  	}
   355  
   356  	return s.client.Do(ctx, req, nil)
   357  }
   358  
   359  // CancelWorkflowRunByID cancels a workflow run by ID.
   360  // You can use the helper function *DeploymentProtectionRuleEvent.GetRunID() to easily retrieve the workflow run ID from a DeploymentProtectionRuleEvent.
   361  //
   362  // GitHub API docs: https://docs.github.com/rest/actions/workflow-runs#cancel-a-workflow-run
   363  //
   364  //meta:operation POST /repos/{owner}/{repo}/actions/runs/{run_id}/cancel
   365  func (s *ActionsService) CancelWorkflowRunByID(ctx context.Context, owner, repo string, runID int64) (*Response, error) {
   366  	u := fmt.Sprintf("repos/%v/%v/actions/runs/%v/cancel", owner, repo, runID)
   367  
   368  	req, err := s.client.NewRequest("POST", u, nil)
   369  	if err != nil {
   370  		return nil, err
   371  	}
   372  
   373  	return s.client.Do(ctx, req, nil)
   374  }
   375  
   376  // GetWorkflowRunLogs gets a redirect URL to download a plain text file of logs for a workflow run.
   377  // You can use the helper function *DeploymentProtectionRuleEvent.GetRunID() to easily retrieve the workflow run ID from a DeploymentProtectionRuleEvent.
   378  //
   379  // GitHub API docs: https://docs.github.com/rest/actions/workflow-runs#download-workflow-run-logs
   380  //
   381  //meta:operation GET /repos/{owner}/{repo}/actions/runs/{run_id}/logs
   382  func (s *ActionsService) GetWorkflowRunLogs(ctx context.Context, owner, repo string, runID int64, maxRedirects int) (*url.URL, *Response, error) {
   383  	u := fmt.Sprintf("repos/%v/%v/actions/runs/%v/logs", owner, repo, runID)
   384  
   385  	if s.client.RateLimitRedirectionalEndpoints {
   386  		return s.getWorkflowRunLogsWithRateLimit(ctx, u, maxRedirects)
   387  	}
   388  
   389  	return s.getWorkflowRunLogsWithoutRateLimit(ctx, u, maxRedirects)
   390  }
   391  
   392  func (s *ActionsService) getWorkflowRunLogsWithoutRateLimit(ctx context.Context, u string, maxRedirects int) (*url.URL, *Response, error) {
   393  	resp, err := s.client.roundTripWithOptionalFollowRedirect(ctx, u, maxRedirects)
   394  	if err != nil {
   395  		return nil, nil, err
   396  	}
   397  	defer resp.Body.Close()
   398  
   399  	if resp.StatusCode != http.StatusFound {
   400  		return nil, newResponse(resp), fmt.Errorf("unexpected status code: %s", resp.Status)
   401  	}
   402  
   403  	parsedURL, err := url.Parse(resp.Header.Get("Location"))
   404  	return parsedURL, newResponse(resp), err
   405  }
   406  
   407  func (s *ActionsService) getWorkflowRunLogsWithRateLimit(ctx context.Context, u string, maxRedirects int) (*url.URL, *Response, error) {
   408  	req, err := s.client.NewRequest("GET", u, nil)
   409  	if err != nil {
   410  		return nil, nil, err
   411  	}
   412  
   413  	url, resp, err := s.client.bareDoUntilFound(ctx, req, maxRedirects)
   414  	if err != nil {
   415  		return nil, resp, err
   416  	}
   417  	defer resp.Body.Close()
   418  
   419  	// If we didn't receive a valid Location in a 302 response
   420  	if url == nil {
   421  		return nil, resp, fmt.Errorf("unexpected status code: %v", resp.Status)
   422  	}
   423  
   424  	return url, resp, nil
   425  }
   426  
   427  // DeleteWorkflowRun deletes a workflow run by ID.
   428  // You can use the helper function *DeploymentProtectionRuleEvent.GetRunID() to easily retrieve the workflow run ID from a DeploymentProtectionRuleEvent.
   429  //
   430  // GitHub API docs: https://docs.github.com/rest/actions/workflow-runs#delete-a-workflow-run
   431  //
   432  //meta:operation DELETE /repos/{owner}/{repo}/actions/runs/{run_id}
   433  func (s *ActionsService) DeleteWorkflowRun(ctx context.Context, owner, repo string, runID int64) (*Response, error) {
   434  	u := fmt.Sprintf("repos/%v/%v/actions/runs/%v", owner, repo, runID)
   435  
   436  	req, err := s.client.NewRequest("DELETE", u, nil)
   437  	if err != nil {
   438  		return nil, err
   439  	}
   440  
   441  	return s.client.Do(ctx, req, nil)
   442  }
   443  
   444  // DeleteWorkflowRunLogs deletes all logs for a workflow run.
   445  // You can use the helper function *DeploymentProtectionRuleEvent.GetRunID() to easily retrieve the workflow run ID from a DeploymentProtectionRuleEvent.
   446  //
   447  // GitHub API docs: https://docs.github.com/rest/actions/workflow-runs#delete-workflow-run-logs
   448  //
   449  //meta:operation DELETE /repos/{owner}/{repo}/actions/runs/{run_id}/logs
   450  func (s *ActionsService) DeleteWorkflowRunLogs(ctx context.Context, owner, repo string, runID int64) (*Response, error) {
   451  	u := fmt.Sprintf("repos/%v/%v/actions/runs/%v/logs", owner, repo, runID)
   452  
   453  	req, err := s.client.NewRequest("DELETE", u, nil)
   454  	if err != nil {
   455  		return nil, err
   456  	}
   457  
   458  	return s.client.Do(ctx, req, nil)
   459  }
   460  
   461  // GetWorkflowRunUsageByID gets a specific workflow usage run by run ID in the unit of billable milliseconds.
   462  // You can use the helper function *DeploymentProtectionRuleEvent.GetRunID() to easily retrieve the workflow run ID from a DeploymentProtectionRuleEvent.
   463  //
   464  // GitHub API docs: https://docs.github.com/rest/actions/workflow-runs#get-workflow-run-usage
   465  //
   466  //meta:operation GET /repos/{owner}/{repo}/actions/runs/{run_id}/timing
   467  func (s *ActionsService) GetWorkflowRunUsageByID(ctx context.Context, owner, repo string, runID int64) (*WorkflowRunUsage, *Response, error) {
   468  	u := fmt.Sprintf("repos/%v/%v/actions/runs/%v/timing", owner, repo, runID)
   469  
   470  	req, err := s.client.NewRequest("GET", u, nil)
   471  	if err != nil {
   472  		return nil, nil, err
   473  	}
   474  
   475  	workflowRunUsage := new(WorkflowRunUsage)
   476  	resp, err := s.client.Do(ctx, req, workflowRunUsage)
   477  	if err != nil {
   478  		return nil, resp, err
   479  	}
   480  
   481  	return workflowRunUsage, resp, nil
   482  }
   483  
   484  // GetPendingDeployments get all deployment environments for a workflow run that are waiting for protection rules to pass.
   485  // You can use the helper function *DeploymentProtectionRuleEvent.GetRunID() to easily retrieve the workflow run ID from a DeploymentProtectionRuleEvent.
   486  //
   487  // GitHub API docs: https://docs.github.com/rest/actions/workflow-runs#get-pending-deployments-for-a-workflow-run
   488  //
   489  //meta:operation GET /repos/{owner}/{repo}/actions/runs/{run_id}/pending_deployments
   490  func (s *ActionsService) GetPendingDeployments(ctx context.Context, owner, repo string, runID int64) ([]*PendingDeployment, *Response, error) {
   491  	u := fmt.Sprintf("repos/%v/%v/actions/runs/%v/pending_deployments", owner, repo, runID)
   492  
   493  	req, err := s.client.NewRequest("GET", u, nil)
   494  	if err != nil {
   495  		return nil, nil, err
   496  	}
   497  
   498  	var deployments []*PendingDeployment
   499  	resp, err := s.client.Do(ctx, req, &deployments)
   500  	if err != nil {
   501  		return nil, resp, err
   502  	}
   503  
   504  	return deployments, resp, nil
   505  }
   506  
   507  // PendingDeployments approve or reject pending deployments that are waiting on approval by a required reviewer.
   508  // You can use the helper function *DeploymentProtectionRuleEvent.GetRunID() to easily retrieve the workflow run ID from a DeploymentProtectionRuleEvent.
   509  //
   510  // GitHub API docs: https://docs.github.com/rest/actions/workflow-runs#review-pending-deployments-for-a-workflow-run
   511  //
   512  //meta:operation POST /repos/{owner}/{repo}/actions/runs/{run_id}/pending_deployments
   513  func (s *ActionsService) PendingDeployments(ctx context.Context, owner, repo string, runID int64, request *PendingDeploymentsRequest) ([]*Deployment, *Response, error) {
   514  	u := fmt.Sprintf("repos/%v/%v/actions/runs/%v/pending_deployments", owner, repo, runID)
   515  
   516  	req, err := s.client.NewRequest("POST", u, request)
   517  	if err != nil {
   518  		return nil, nil, err
   519  	}
   520  
   521  	var deployments []*Deployment
   522  	resp, err := s.client.Do(ctx, req, &deployments)
   523  	if err != nil {
   524  		return nil, resp, err
   525  	}
   526  
   527  	return deployments, resp, nil
   528  }
   529  
   530  // ReviewCustomDeploymentProtectionRule approves or rejects custom deployment protection rules provided by a GitHub App for a workflow run.
   531  // You can use the helper function *DeploymentProtectionRuleEvent.GetRunID() to easily retrieve the workflow run ID from a DeploymentProtectionRuleEvent.
   532  //
   533  // GitHub API docs: https://docs.github.com/rest/actions/workflow-runs#review-custom-deployment-protection-rules-for-a-workflow-run
   534  //
   535  //meta:operation POST /repos/{owner}/{repo}/actions/runs/{run_id}/deployment_protection_rule
   536  func (s *ActionsService) ReviewCustomDeploymentProtectionRule(ctx context.Context, owner, repo string, runID int64, request *ReviewCustomDeploymentProtectionRuleRequest) (*Response, error) {
   537  	u := fmt.Sprintf("repos/%v/%v/actions/runs/%v/deployment_protection_rule", owner, repo, runID)
   538  
   539  	req, err := s.client.NewRequest("POST", u, request)
   540  	if err != nil {
   541  		return nil, err
   542  	}
   543  
   544  	resp, err := s.client.Do(ctx, req, nil)
   545  	return resp, err
   546  }