diff --git a/github/actions_secrets.go b/github/actions_secrets.go index d660663e139..1640b5a02cc 100644 --- a/github/actions_secrets.go +++ b/github/actions_secrets.go @@ -52,9 +52,9 @@ type Secrets struct { // without revealing their encrypted values. // // GitHub API docs: https://developer.github.com/v3/actions/secrets/#list-secrets-for-a-repository -func (s *ActionsService) ListSecrets(ctx context.Context, owner, repo string, opt *ListOptions) (*Secrets, *Response, error) { +func (s *ActionsService) ListSecrets(ctx context.Context, owner, repo string, opts *ListOptions) (*Secrets, *Response, error) { u := fmt.Sprintf("repos/%s/%s/actions/secrets", owner, repo) - u, err := addOptions(u, opt) + u, err := addOptions(u, opts) if err != nil { return nil, nil, err } diff --git a/github/actions_secrets_test.go b/github/actions_secrets_test.go index 07f911fd7d8..0a17e583512 100644 --- a/github/actions_secrets_test.go +++ b/github/actions_secrets_test.go @@ -44,8 +44,8 @@ func TestActionsService_ListSecrets(t *testing.T) { fmt.Fprint(w, `{"total_count":4,"secrets":[{"name":"A","created_at":"2019-01-02T15:04:05Z","updated_at":"2020-01-02T15:04:05Z"},{"name":"B","created_at":"2019-01-02T15:04:05Z","updated_at":"2020-01-02T15:04:05Z"}]}`) }) - opt := &ListOptions{Page: 2, PerPage: 2} - secrets, _, err := client.Actions.ListSecrets(context.Background(), "o", "r", opt) + opts := &ListOptions{Page: 2, PerPage: 2} + secrets, _, err := client.Actions.ListSecrets(context.Background(), "o", "r", opts) if err != nil { t.Errorf("Actions.ListSecrets returned error: %v", err) } diff --git a/github/actions_workflows.go b/github/actions_workflows.go new file mode 100644 index 00000000000..fc4cf4a531a --- /dev/null +++ b/github/actions_workflows.go @@ -0,0 +1,88 @@ +// Copyright 2020 The go-github AUTHORS. All rights reserved. +// +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package github + +import ( + "context" + "fmt" +) + +// Workflow represents a repository action workflow. +type Workflow struct { + ID int64 `json:"id"` + NodeID string `json:"node_id"` + Name string `json:"name"` + Path string `json:"path"` + State string `json:"state"` + CreatedAt Timestamp `json:"created_at"` + UpdatedAt Timestamp `json:"updated_at"` + URL string `json:"url"` + HTMLURL string `json:"html_url"` + BadgeURL string `json:"badge_url"` +} + +// Workflows represents a slice of repository action workflows. +type Workflows struct { + TotalCount int `json:"total_count"` + Workflows []*Workflow `json:"workflows"` +} + +// ListWorkflows lists all workflows in a repository. +// +// GitHub API docs: https://developer.github.com/v3/actions/workflows/#list-repository-workflows +func (s *ActionsService) ListWorkflows(ctx context.Context, owner, repo string, opts *ListOptions) (*Workflows, *Response, error) { + u := fmt.Sprintf("repos/%s/%s/actions/workflows", owner, repo) + u, err := addOptions(u, opts) + if err != nil { + return nil, nil, err + } + + req, err := s.client.NewRequest("GET", u, nil) + if err != nil { + return nil, nil, err + } + + workflows := new(Workflows) + resp, err := s.client.Do(ctx, req, &workflows) + if err != nil { + return nil, resp, err + } + + return workflows, resp, nil +} + +// GetWorkflowByID gets a specific workflow by ID. +// +// GitHub API docs: https://developer.github.com/v3/actions/workflows/#get-a-workflow +func (s *ActionsService) GetWorkflowByID(ctx context.Context, owner, repo string, workflowID int64) (*Workflow, *Response, error) { + u := fmt.Sprintf("repos/%v/%v/actions/workflows/%v", owner, repo, workflowID) + + return s.getWorkflow(ctx, u) +} + +// GetWorkflowByFileName gets a specific workflow by file name. +// +// GitHub API docs: https://developer.github.com/v3/actions/workflows/#get-a-workflow +func (s *ActionsService) GetWorkflowByFileName(ctx context.Context, owner, repo, workflowFileName string) (*Workflow, *Response, error) { + u := fmt.Sprintf("repos/%v/%v/actions/workflows/%v", owner, repo, workflowFileName) + + return s.getWorkflow(ctx, u) +} + +func (s *ActionsService) getWorkflow(ctx context.Context, url string) (*Workflow, *Response, error) { + req, err := s.client.NewRequest("GET", url, nil) + if err != nil { + return nil, nil, err + } + + workflow := new(Workflow) + resp, err := s.client.Do(ctx, req, workflow) + if err != nil { + return nil, resp, err + } + + return workflow, resp, nil +} diff --git a/github/actions_workflows_test.go b/github/actions_workflows_test.go new file mode 100644 index 00000000000..8d9f9232487 --- /dev/null +++ b/github/actions_workflows_test.go @@ -0,0 +1,91 @@ +// Copyright 2020 The go-github AUTHORS. All rights reserved. +// +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package github + +import ( + "context" + "fmt" + "net/http" + "reflect" + "testing" + "time" +) + +func TestActionsService_ListWorkflows(t *testing.T) { + client, mux, _, teardown := setup() + defer teardown() + + mux.HandleFunc("/repos/o/r/actions/workflows", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "GET") + testFormValues(t, r, values{"per_page": "2", "page": "2"}) + fmt.Fprint(w, `{"total_count":4,"workflows":[{"id":72844,"created_at":"2019-01-02T15:04:05Z","updated_at":"2020-01-02T15:04:05Z"},{"id":72845,"created_at":"2019-01-02T15:04:05Z","updated_at":"2020-01-02T15:04:05Z"}]}`) + }) + + opts := &ListOptions{Page: 2, PerPage: 2} + workflows, _, err := client.Actions.ListWorkflows(context.Background(), "o", "r", opts) + if err != nil { + t.Errorf("Actions.ListWorkflows returned error: %v", err) + } + + want := &Workflows{ + TotalCount: 4, + Workflows: []*Workflow{ + {ID: 72844, CreatedAt: Timestamp{time.Date(2019, time.January, 02, 15, 04, 05, 0, time.UTC)}, UpdatedAt: Timestamp{time.Date(2020, time.January, 02, 15, 04, 05, 0, time.UTC)}}, + {ID: 72845, CreatedAt: Timestamp{time.Date(2019, time.January, 02, 15, 04, 05, 0, time.UTC)}, UpdatedAt: Timestamp{time.Date(2020, time.January, 02, 15, 04, 05, 0, time.UTC)}}, + }, + } + if !reflect.DeepEqual(workflows, want) { + t.Errorf("Actions.ListWorkflows returned %+v, want %+v", workflows, want) + } +} + +func TestActionsService_GetWorkflowByID(t *testing.T) { + client, mux, _, teardown := setup() + defer teardown() + + mux.HandleFunc("/repos/o/r/actions/workflows/72844", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "GET") + fmt.Fprint(w, `{"id":72844,"created_at":"2019-01-02T15:04:05Z","updated_at":"2020-01-02T15:04:05Z"}`) + }) + + workflow, _, err := client.Actions.GetWorkflowByID(context.Background(), "o", "r", 72844) + if err != nil { + t.Errorf("Actions.GetWorkflowByID returned error: %v", err) + } + + want := &Workflow{ + ID: 72844, + CreatedAt: Timestamp{time.Date(2019, time.January, 02, 15, 04, 05, 0, time.UTC)}, + UpdatedAt: Timestamp{time.Date(2020, time.January, 02, 15, 04, 05, 0, time.UTC)}, + } + if !reflect.DeepEqual(workflow, want) { + t.Errorf("Actions.GetWorkflowByID returned %+v, want %+v", workflow, want) + } +} + +func TestActionsService_GetWorkflowByFileName(t *testing.T) { + client, mux, _, teardown := setup() + defer teardown() + + mux.HandleFunc("/repos/o/r/actions/workflows/main.yml", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "GET") + fmt.Fprint(w, `{"id":72844,"created_at":"2019-01-02T15:04:05Z","updated_at":"2020-01-02T15:04:05Z"}`) + }) + + workflow, _, err := client.Actions.GetWorkflowByFileName(context.Background(), "o", "r", "main.yml") + if err != nil { + t.Errorf("Actions.GetWorkflowByFileName returned error: %v", err) + } + + want := &Workflow{ + ID: 72844, + CreatedAt: Timestamp{time.Date(2019, time.January, 02, 15, 04, 05, 0, time.UTC)}, + UpdatedAt: Timestamp{time.Date(2020, time.January, 02, 15, 04, 05, 0, time.UTC)}, + } + if !reflect.DeepEqual(workflow, want) { + t.Errorf("Actions.GetWorkflowByFileName returned %+v, want %+v", workflow, want) + } +}