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
6package github
7
8import (
9	"context"
10	"fmt"
11)
12
13// Workflow represents a repository action workflow.
14type Workflow struct {
15	ID        *int64     `json:"id,omitempty"`
16	NodeID    *string    `json:"node_id,omitempty"`
17	Name      *string    `json:"name,omitempty"`
18	Path      *string    `json:"path,omitempty"`
19	State     *string    `json:"state,omitempty"`
20	CreatedAt *Timestamp `json:"created_at,omitempty"`
21	UpdatedAt *Timestamp `json:"updated_at,omitempty"`
22	URL       *string    `json:"url,omitempty"`
23	HTMLURL   *string    `json:"html_url,omitempty"`
24	BadgeURL  *string    `json:"badge_url,omitempty"`
25}
26
27// Workflows represents a slice of repository action workflows.
28type Workflows struct {
29	TotalCount *int        `json:"total_count,omitempty"`
30	Workflows  []*Workflow `json:"workflows,omitempty"`
31}
32
33// WorkflowUsage represents a usage of a specific workflow.
34type WorkflowUsage struct {
35	Billable *WorkflowEnvironment `json:"billable,omitempty"`
36}
37
38// WorkflowEnvironment represents different runner environments available for a workflow.
39type WorkflowEnvironment struct {
40	Ubuntu  *WorkflowBill `json:"UBUNTU,omitempty"`
41	MacOS   *WorkflowBill `json:"MACOS,omitempty"`
42	Windows *WorkflowBill `json:"WINDOWS,omitempty"`
43}
44
45// WorkflowBill specifies billable time for a specific environment in a workflow.
46type WorkflowBill struct {
47	TotalMS *int64 `json:"total_ms,omitempty"`
48}
49
50// ListWorkflows lists all workflows in a repository.
51//
52// GitHub API docs: https://developer.github.com/v3/actions/workflows/#list-repository-workflows
53func (s *ActionsService) ListWorkflows(ctx context.Context, owner, repo string, opts *ListOptions) (*Workflows, *Response, error) {
54	u := fmt.Sprintf("repos/%s/%s/actions/workflows", owner, repo)
55	u, err := addOptions(u, opts)
56	if err != nil {
57		return nil, nil, err
58	}
59
60	req, err := s.client.NewRequest("GET", u, nil)
61	if err != nil {
62		return nil, nil, err
63	}
64
65	workflows := new(Workflows)
66	resp, err := s.client.Do(ctx, req, &workflows)
67	if err != nil {
68		return nil, resp, err
69	}
70
71	return workflows, resp, nil
72}
73
74// GetWorkflowByID gets a specific workflow by ID.
75//
76// GitHub API docs: https://developer.github.com/v3/actions/workflows/#get-a-workflow
77func (s *ActionsService) GetWorkflowByID(ctx context.Context, owner, repo string, workflowID int64) (*Workflow, *Response, error) {
78	u := fmt.Sprintf("repos/%v/%v/actions/workflows/%v", owner, repo, workflowID)
79
80	return s.getWorkflow(ctx, u)
81}
82
83// GetWorkflowByFileName gets a specific workflow by file name.
84//
85// GitHub API docs: https://developer.github.com/v3/actions/workflows/#get-a-workflow
86func (s *ActionsService) GetWorkflowByFileName(ctx context.Context, owner, repo, workflowFileName string) (*Workflow, *Response, error) {
87	u := fmt.Sprintf("repos/%v/%v/actions/workflows/%v", owner, repo, workflowFileName)
88
89	return s.getWorkflow(ctx, u)
90}
91
92func (s *ActionsService) getWorkflow(ctx context.Context, url string) (*Workflow, *Response, error) {
93	req, err := s.client.NewRequest("GET", url, nil)
94	if err != nil {
95		return nil, nil, err
96	}
97
98	workflow := new(Workflow)
99	resp, err := s.client.Do(ctx, req, workflow)
100	if err != nil {
101		return nil, resp, err
102	}
103
104	return workflow, resp, nil
105}
106
107// GetWorkflowUsageByID gets a specific workflow usage by ID in the unit of billable milliseconds.
108//
109// GitHub API docs: https://developer.github.com/v3/actions/workflows/#get-workflow-usage
110func (s *ActionsService) GetWorkflowUsageByID(ctx context.Context, owner, repo string, workflowID int64) (*WorkflowUsage, *Response, error) {
111	u := fmt.Sprintf("repos/%v/%v/actions/workflows/%v/timing", owner, repo, workflowID)
112
113	return s.getWorkflowUsage(ctx, u)
114}
115
116// GetWorkflowUsageByFileName gets a specific workflow usage by file name in the unit of billable milliseconds.
117//
118// GitHub API docs: https://developer.github.com/v3/actions/workflows/#get-workflow-usage
119func (s *ActionsService) GetWorkflowUsageByFileName(ctx context.Context, owner, repo, workflowFileName string) (*WorkflowUsage, *Response, error) {
120	u := fmt.Sprintf("repos/%v/%v/actions/workflows/%v/timing", owner, repo, workflowFileName)
121
122	return s.getWorkflowUsage(ctx, u)
123}
124
125func (s *ActionsService) getWorkflowUsage(ctx context.Context, url string) (*WorkflowUsage, *Response, error) {
126	req, err := s.client.NewRequest("GET", url, nil)
127	if err != nil {
128		return nil, nil, err
129	}
130
131	workflowUsage := new(WorkflowUsage)
132	resp, err := s.client.Do(ctx, req, workflowUsage)
133	if err != nil {
134		return nil, resp, err
135	}
136
137	return workflowUsage, resp, nil
138}
139