diff --git a/github/dependabot_alerts.go b/github/dependabot_alerts.go index 177316b1dc..9ea1f0396a 100644 --- a/github/dependabot_alerts.go +++ b/github/dependabot_alerts.go @@ -67,6 +67,17 @@ type DependabotAlert struct { Repository *Repository `json:"repository,omitempty"` } +// DependabotAlertState represents the state of a Dependabot alert to update. +type DependabotAlertState struct { + // The state of the Dependabot alert. A dismissed_reason must be provided when setting the state to dismissed. + State string `json:"state"` + // Required when state is dismissed. A reason for dismissing the alert. + // Can be one of: fix_started, inaccurate, no_bandwidth, not_used, tolerable_risk + DismissedReason *string `json:"dismissed_reason,omitempty"` + // An optional comment associated with dismissing the alert. + DismissedComment *string `json:"dismissed_comment,omitempty"` +} + // ListAlertsOptions specifies the optional parameters to the DependabotService.ListRepoAlerts // and DependabotService.ListOrgAlerts methods. type ListAlertsOptions struct { @@ -136,3 +147,22 @@ func (s *DependabotService) GetRepoAlert(ctx context.Context, owner, repo string return alert, resp, nil } + +// UpdateAlert updates a Dependabot alert. +// +// GitHub API docs: https://docs.github.com/en/rest/dependabot/alerts?apiVersion=2022-11-28#update-a-dependabot-alert +func (s *DependabotService) UpdateAlert(ctx context.Context, owner, repo string, number int, stateInfo *DependabotAlertState) (*DependabotAlert, *Response, error) { + url := fmt.Sprintf("repos/%v/%v/dependabot/alerts/%v", owner, repo, number) + req, err := s.client.NewRequest("PATCH", url, stateInfo) + if err != nil { + return nil, nil, err + } + + alert := new(DependabotAlert) + resp, err := s.client.Do(ctx, req, alert) + if err != nil { + return nil, resp, err + } + + return alert, resp, nil +} diff --git a/github/dependabot_alerts_test.go b/github/dependabot_alerts_test.go index a7c3b14788..45fd11ee41 100644 --- a/github/dependabot_alerts_test.go +++ b/github/dependabot_alerts_test.go @@ -131,3 +131,49 @@ func TestDependabotService_ListOrgAlerts(t *testing.T) { return resp, err }) } + +func TestDependabotService_UpdateAlert(t *testing.T) { + client, mux, _, teardown := setup() + defer teardown() + + state := String("dismissed") + dismissedReason := String("no_bandwidth") + dismissedComment := String("no time to fix this") + + alertState := &DependabotAlertState{State: *state, DismissedReason: dismissedReason, DismissedComment: dismissedComment} + + mux.HandleFunc("/repos/o/r/dependabot/alerts/42", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "PATCH") + fmt.Fprint(w, `{"number":42,"state":"dismissed","dismissed_reason":"no_bandwidth","dismissed_comment":"no time to fix this"}`) + }) + + ctx := context.Background() + alert, _, err := client.Dependabot.UpdateAlert(ctx, "o", "r", 42, alertState) + if err != nil { + t.Errorf("Dependabot.UpdateAlert returned error: %v", err) + } + + want := &DependabotAlert{ + Number: Int(42), + State: String("dismissed"), + DismissedReason: String("no_bandwidth"), + DismissedComment: String("no time to fix this"), + } + if !cmp.Equal(alert, want) { + t.Errorf("Dependabot.UpdateAlert returned %+v, want %+v", alert, want) + } + + const methodName = "UpdateAlert" + testBadOptions(t, methodName, func() (err error) { + _, _, err = client.Dependabot.UpdateAlert(ctx, "\n", "\n", 0, alertState) + return err + }) + + testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { + got, resp, err := client.Dependabot.UpdateAlert(ctx, "o", "r", 42, alertState) + if got != nil { + t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) + } + return resp, err + }) +}