diff --git a/github/actions_workflows.go b/github/actions_workflows.go index e0bcde35115..582949f4d8f 100644 --- a/github/actions_workflows.go +++ b/github/actions_workflows.go @@ -51,9 +51,20 @@ type CreateWorkflowDispatchEventRequest struct { // Ref is required when creating a workflow dispatch event. Ref string `json:"ref"` // Inputs represents input keys and values configured in the workflow file. - // The maximum number of properties is 10. + // The maximum number of properties is 25. // Default: Any default properties configured in the workflow file will be used when `inputs` are omitted. Inputs map[string]any `json:"inputs,omitempty"` + // ReturnRunDetails specifies whether the response should include + // the workflow run ID and URLs. + ReturnRunDetails *bool `json:"return_run_details,omitempty"` +} + +// WorkflowDispatchRunDetails represents the response from creating +// a workflow dispatch event when ReturnRunDetails is set to true. +type WorkflowDispatchRunDetails struct { + WorkflowRunID *int64 `json:"workflow_run_id,omitempty"` + RunURL *string `json:"run_url,omitempty"` + HTMLURL *string `json:"html_url,omitempty"` } // WorkflowsPermissions represents the permissions for workflows in a repository. @@ -191,7 +202,7 @@ func (s *ActionsService) getWorkflowUsage(ctx context.Context, url string) (*Wor // GitHub API docs: https://docs.github.com/rest/actions/workflows#create-a-workflow-dispatch-event // //meta:operation POST /repos/{owner}/{repo}/actions/workflows/{workflow_id}/dispatches -func (s *ActionsService) CreateWorkflowDispatchEventByID(ctx context.Context, owner, repo string, workflowID int64, event CreateWorkflowDispatchEventRequest) (*Response, error) { +func (s *ActionsService) CreateWorkflowDispatchEventByID(ctx context.Context, owner, repo string, workflowID int64, event CreateWorkflowDispatchEventRequest) (*WorkflowDispatchRunDetails, *Response, error) { u := fmt.Sprintf("repos/%v/%v/actions/workflows/%v/dispatches", owner, repo, workflowID) return s.createWorkflowDispatchEvent(ctx, u, &event) @@ -202,19 +213,25 @@ func (s *ActionsService) CreateWorkflowDispatchEventByID(ctx context.Context, ow // GitHub API docs: https://docs.github.com/rest/actions/workflows#create-a-workflow-dispatch-event // //meta:operation POST /repos/{owner}/{repo}/actions/workflows/{workflow_id}/dispatches -func (s *ActionsService) CreateWorkflowDispatchEventByFileName(ctx context.Context, owner, repo, workflowFileName string, event CreateWorkflowDispatchEventRequest) (*Response, error) { +func (s *ActionsService) CreateWorkflowDispatchEventByFileName(ctx context.Context, owner, repo, workflowFileName string, event CreateWorkflowDispatchEventRequest) (*WorkflowDispatchRunDetails, *Response, error) { u := fmt.Sprintf("repos/%v/%v/actions/workflows/%v/dispatches", owner, repo, workflowFileName) return s.createWorkflowDispatchEvent(ctx, u, &event) } -func (s *ActionsService) createWorkflowDispatchEvent(ctx context.Context, url string, event *CreateWorkflowDispatchEventRequest) (*Response, error) { +func (s *ActionsService) createWorkflowDispatchEvent(ctx context.Context, url string, event *CreateWorkflowDispatchEventRequest) (*WorkflowDispatchRunDetails, *Response, error) { req, err := s.client.NewRequest("POST", url, event) if err != nil { - return nil, err + return nil, nil, err } - return s.client.Do(ctx, req, nil) + var dispatchRunDetails *WorkflowDispatchRunDetails + resp, err := s.client.Do(ctx, req, &dispatchRunDetails) + if err != nil { + return nil, resp, err + } + + return dispatchRunDetails, resp, nil } // EnableWorkflowByID enables a workflow and sets the state of the workflow to "active". diff --git a/github/actions_workflows_test.go b/github/actions_workflows_test.go index d6fb4615e1c..594906b269a 100644 --- a/github/actions_workflows_test.go +++ b/github/actions_workflows_test.go @@ -235,12 +235,13 @@ func TestActionsService_CreateWorkflowDispatchEventByID(t *testing.T) { client, mux, _ := setup(t) event := CreateWorkflowDispatchEventRequest{ - Ref: "d4cfb6e7", + Ref: "d4cfb6e7", + ReturnRunDetails: Ptr(true), Inputs: map[string]any{ "key": "value", }, } - mux.HandleFunc("/repos/o/r/actions/workflows/72844/dispatches", func(_ http.ResponseWriter, r *http.Request) { + mux.HandleFunc("/repos/o/r/actions/workflows/72844/dispatches", func(w http.ResponseWriter, r *http.Request) { var v CreateWorkflowDispatchEventRequest assertNilError(t, json.NewDecoder(r.Body).Decode(&v)) @@ -248,29 +249,45 @@ func TestActionsService_CreateWorkflowDispatchEventByID(t *testing.T) { if !cmp.Equal(v, event) { t.Errorf("Request body = %+v, want %+v", v, event) } + + w.WriteHeader(http.StatusOK) + fmt.Fprint(w, `{"workflow_run_id":1,"run_url":"https://api.github.com/repos/o/r/actions/runs/1","html_url":"https://github.com/o/r/actions/runs/1"}`) }) ctx := t.Context() - _, err := client.Actions.CreateWorkflowDispatchEventByID(ctx, "o", "r", 72844, event) + dispatchResponse, _, err := client.Actions.CreateWorkflowDispatchEventByID(ctx, "o", "r", 72844, event) if err != nil { t.Errorf("Actions.CreateWorkflowDispatchEventByID returned error: %v", err) } + want := &WorkflowDispatchRunDetails{ + WorkflowRunID: Ptr(int64(1)), + RunURL: Ptr("https://api.github.com/repos/o/r/actions/runs/1"), + HTMLURL: Ptr("https://github.com/o/r/actions/runs/1"), + } + if !cmp.Equal(dispatchResponse, want) { + t.Errorf("Actions.CreateWorkflowDispatchEventByID = %+v, want %+v", dispatchResponse, want) + } + // Test s.client.NewRequest failure client.BaseURL.Path = "" - _, err = client.Actions.CreateWorkflowDispatchEventByID(ctx, "o", "r", 72844, event) + _, _, err = client.Actions.CreateWorkflowDispatchEventByID(ctx, "o", "r", 72844, event) if err == nil { t.Error("client.BaseURL.Path='' CreateWorkflowDispatchEventByID err = nil, want error") } const methodName = "CreateWorkflowDispatchEventByID" testBadOptions(t, methodName, func() (err error) { - _, err = client.Actions.CreateWorkflowDispatchEventByID(ctx, "o", "r", 72844, event) + _, _, err = client.Actions.CreateWorkflowDispatchEventByID(ctx, "o", "r", 72844, event) return err }) testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { - return client.Actions.CreateWorkflowDispatchEventByID(ctx, "o", "r", 72844, event) + got, resp, err := client.Actions.CreateWorkflowDispatchEventByID(ctx, "o", "r", 72844, event) + if got != nil { + t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) + } + return resp, err }) } @@ -279,12 +296,13 @@ func TestActionsService_CreateWorkflowDispatchEventByFileName(t *testing.T) { client, mux, _ := setup(t) event := CreateWorkflowDispatchEventRequest{ - Ref: "d4cfb6e7", + Ref: "d4cfb6e7", + ReturnRunDetails: Ptr(true), Inputs: map[string]any{ "key": "value", }, } - mux.HandleFunc("/repos/o/r/actions/workflows/main.yml/dispatches", func(_ http.ResponseWriter, r *http.Request) { + mux.HandleFunc("/repos/o/r/actions/workflows/main.yml/dispatches", func(w http.ResponseWriter, r *http.Request) { var v CreateWorkflowDispatchEventRequest assertNilError(t, json.NewDecoder(r.Body).Decode(&v)) @@ -292,30 +310,112 @@ func TestActionsService_CreateWorkflowDispatchEventByFileName(t *testing.T) { if !cmp.Equal(v, event) { t.Errorf("Request body = %+v, want %+v", v, event) } + + w.WriteHeader(http.StatusOK) + fmt.Fprint(w, `{"workflow_run_id":1,"run_url":"https://api.github.com/repos/o/r/actions/runs/1","html_url":"https://github.com/o/r/actions/runs/1"}`) }) ctx := t.Context() - _, err := client.Actions.CreateWorkflowDispatchEventByFileName(ctx, "o", "r", "main.yml", event) + dispatchResponse, _, err := client.Actions.CreateWorkflowDispatchEventByFileName(ctx, "o", "r", "main.yml", event) if err != nil { t.Errorf("Actions.CreateWorkflowDispatchEventByFileName returned error: %v", err) } + want := &WorkflowDispatchRunDetails{ + WorkflowRunID: Ptr(int64(1)), + RunURL: Ptr("https://api.github.com/repos/o/r/actions/runs/1"), + HTMLURL: Ptr("https://github.com/o/r/actions/runs/1"), + } + if !cmp.Equal(dispatchResponse, want) { + t.Errorf("Actions.CreateWorkflowDispatchEventByFileName = %+v, want %+v", dispatchResponse, want) + } + // Test s.client.NewRequest failure client.BaseURL.Path = "" - _, err = client.Actions.CreateWorkflowDispatchEventByFileName(ctx, "o", "r", "main.yml", event) + _, _, err = client.Actions.CreateWorkflowDispatchEventByFileName(ctx, "o", "r", "main.yml", event) if err == nil { t.Error("client.BaseURL.Path='' CreateWorkflowDispatchEventByFileName err = nil, want error") } const methodName = "CreateWorkflowDispatchEventByFileName" testBadOptions(t, methodName, func() (err error) { - _, err = client.Actions.CreateWorkflowDispatchEventByFileName(ctx, "o", "r", "main.yml", event) + _, _, err = client.Actions.CreateWorkflowDispatchEventByFileName(ctx, "o", "r", "main.yml", event) return err }) testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { - return client.Actions.CreateWorkflowDispatchEventByFileName(ctx, "o", "r", "main.yml", event) + got, resp, err := client.Actions.CreateWorkflowDispatchEventByFileName(ctx, "o", "r", "main.yml", event) + if got != nil { + t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) + } + return resp, err + }) +} + +func TestActionsService_CreateWorkflowDispatchEventByID_noRunDetails(t *testing.T) { + t.Parallel() + client, mux, _ := setup(t) + + event := CreateWorkflowDispatchEventRequest{ + Ref: "d4cfb6e7", + Inputs: map[string]any{ + "key": "value", + }, + } + mux.HandleFunc("/repos/o/r/actions/workflows/72844/dispatches", func(w http.ResponseWriter, r *http.Request) { + var v CreateWorkflowDispatchEventRequest + assertNilError(t, json.NewDecoder(r.Body).Decode(&v)) + + testMethod(t, r, "POST") + if !cmp.Equal(v, event) { + t.Errorf("Request body = %+v, want %+v", v, event) + } + + w.WriteHeader(http.StatusNoContent) + }) + + ctx := t.Context() + dispatchResponse, _, err := client.Actions.CreateWorkflowDispatchEventByID(ctx, "o", "r", 72844, event) + if err != nil { + t.Errorf("Actions.CreateWorkflowDispatchEventByID returned error: %v", err) + } + + if dispatchResponse != nil { + t.Errorf("Actions.CreateWorkflowDispatchEventByID = %+v, want nil", dispatchResponse) + } +} + +func TestActionsService_CreateWorkflowDispatchEventByFileName_noRunDetails(t *testing.T) { + t.Parallel() + client, mux, _ := setup(t) + + event := CreateWorkflowDispatchEventRequest{ + Ref: "d4cfb6e7", + Inputs: map[string]any{ + "key": "value", + }, + } + mux.HandleFunc("/repos/o/r/actions/workflows/main.yml/dispatches", func(w http.ResponseWriter, r *http.Request) { + var v CreateWorkflowDispatchEventRequest + assertNilError(t, json.NewDecoder(r.Body).Decode(&v)) + + testMethod(t, r, "POST") + if !cmp.Equal(v, event) { + t.Errorf("Request body = %+v, want %+v", v, event) + } + + w.WriteHeader(http.StatusNoContent) }) + + ctx := t.Context() + dispatchResponse, _, err := client.Actions.CreateWorkflowDispatchEventByFileName(ctx, "o", "r", "main.yml", event) + if err != nil { + t.Errorf("Actions.CreateWorkflowDispatchEventByFileName returned error: %v", err) + } + + if dispatchResponse != nil { + t.Errorf("Actions.CreateWorkflowDispatchEventByFileName = %+v, want nil", dispatchResponse) + } } func TestActionsService_EnableWorkflowByID(t *testing.T) { diff --git a/github/github-accessors.go b/github/github-accessors.go index ec77299f2fe..6d8dcb7fd30 100644 --- a/github/github-accessors.go +++ b/github/github-accessors.go @@ -7174,6 +7174,14 @@ func (c *CreateWorkflowDispatchEventRequest) GetInputs() map[string]any { return c.Inputs } +// GetReturnRunDetails returns the ReturnRunDetails field if it's non-nil, zero value otherwise. +func (c *CreateWorkflowDispatchEventRequest) GetReturnRunDetails() bool { + if c == nil || c.ReturnRunDetails == nil { + return false + } + return *c.ReturnRunDetails +} + // GetCreated returns the Created field if it's non-nil, zero value otherwise. func (c *CreationInfo) GetCreated() Timestamp { if c == nil || c.Created == nil { @@ -31686,6 +31694,30 @@ func (w *WorkflowDispatchEvent) GetWorkflow() string { return *w.Workflow } +// GetHTMLURL returns the HTMLURL field if it's non-nil, zero value otherwise. +func (w *WorkflowDispatchRunDetails) GetHTMLURL() string { + if w == nil || w.HTMLURL == nil { + return "" + } + return *w.HTMLURL +} + +// GetRunURL returns the RunURL field if it's non-nil, zero value otherwise. +func (w *WorkflowDispatchRunDetails) GetRunURL() string { + if w == nil || w.RunURL == nil { + return "" + } + return *w.RunURL +} + +// GetWorkflowRunID returns the WorkflowRunID field if it's non-nil, zero value otherwise. +func (w *WorkflowDispatchRunDetails) GetWorkflowRunID() int64 { + if w == nil || w.WorkflowRunID == nil { + return 0 + } + return *w.WorkflowRunID +} + // GetCheckRunURL returns the CheckRunURL field if it's non-nil, zero value otherwise. func (w *WorkflowJob) GetCheckRunURL() string { if w == nil || w.CheckRunURL == nil { diff --git a/github/github-accessors_test.go b/github/github-accessors_test.go index 08332e3776d..891957bd3e4 100644 --- a/github/github-accessors_test.go +++ b/github/github-accessors_test.go @@ -9395,6 +9395,17 @@ func TestCreateWorkflowDispatchEventRequest_GetInputs(tt *testing.T) { c.GetInputs() } +func TestCreateWorkflowDispatchEventRequest_GetReturnRunDetails(tt *testing.T) { + tt.Parallel() + var zeroValue bool + c := &CreateWorkflowDispatchEventRequest{ReturnRunDetails: &zeroValue} + c.GetReturnRunDetails() + c = &CreateWorkflowDispatchEventRequest{} + c.GetReturnRunDetails() + c = nil + c.GetReturnRunDetails() +} + func TestCreationInfo_GetCreated(tt *testing.T) { tt.Parallel() var zeroValue Timestamp @@ -40912,6 +40923,39 @@ func TestWorkflowDispatchEvent_GetWorkflow(tt *testing.T) { w.GetWorkflow() } +func TestWorkflowDispatchRunDetails_GetHTMLURL(tt *testing.T) { + tt.Parallel() + var zeroValue string + w := &WorkflowDispatchRunDetails{HTMLURL: &zeroValue} + w.GetHTMLURL() + w = &WorkflowDispatchRunDetails{} + w.GetHTMLURL() + w = nil + w.GetHTMLURL() +} + +func TestWorkflowDispatchRunDetails_GetRunURL(tt *testing.T) { + tt.Parallel() + var zeroValue string + w := &WorkflowDispatchRunDetails{RunURL: &zeroValue} + w.GetRunURL() + w = &WorkflowDispatchRunDetails{} + w.GetRunURL() + w = nil + w.GetRunURL() +} + +func TestWorkflowDispatchRunDetails_GetWorkflowRunID(tt *testing.T) { + tt.Parallel() + var zeroValue int64 + w := &WorkflowDispatchRunDetails{WorkflowRunID: &zeroValue} + w.GetWorkflowRunID() + w = &WorkflowDispatchRunDetails{} + w.GetWorkflowRunID() + w = nil + w.GetWorkflowRunID() +} + func TestWorkflowJob_GetCheckRunURL(tt *testing.T) { tt.Parallel() var zeroValue string