Repository: xanzy/go-gitlab
Pull request #2007 (2024-09-07 21:56:30)

Add support for the Redmine Integration
Adds support for the following endpoints: https://docs.gitlab.com/ee/api/integrations.html#redmine


Patch:
diff --git a/services.go b/services.go
index fcaa71e..0059714 100644
--- a/services.go
+++ b/services.go
@@ -1758,6 +1758,101 @@ func (s *ServicesService) DeletePrometheusService(pid interface{}, options ...Re
 	return s.client.Do(req, nil)
 }
 
+// RedmineService represents the Redmine service settings.
+//
+// GitLab API docs:
+// https://docs.gitlab.com/ee/api/integrations.html#redmine
+type RedmineService struct {
+	Service
+	Properties *RedmineServiceProperties `json:"properties"`
+}
+
+// RedmineServiceProperties represents Redmine specific properties.
+//
+// GitLab API docs:
+// https://docs.gitlab.com/ee/api/integrations.html#redmine
+type RedmineServiceProperties struct {
+	NewIssueURL          string    `json:"new_issue_url"`
+	ProjectURL           string    `json:"project_url"`
+	IssuesURL            string    `json:"issues_url"`
+	UseInheritedSettings BoolValue `json:"use_inherited_settings"`
+}
+
+// GetRedmineService gets Redmine service settings for a project.
+//
+// GitLab API docs:
+// https://docs.gitlab.com/ee/api/integrations.html#get-redmine-settings
+func (s *ServicesService) GetRedmineService(pid interface{}, options ...RequestOptionFunc) (*RedmineService, *Response, error) {
+	project, err := parseID(pid)
+	if err != nil {
+		return nil, nil, err
+	}
+	u := fmt.Sprintf("projects/%s/integrations/redmine", PathEscape(project))
+
+	req, err := s.client.NewRequest(http.MethodGet, u, nil, options)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	svc := new(RedmineService)
+	resp, err := s.client.Do(req, svc)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return svc, resp, nil
+}
+
+// SetRedmineServiceOptions represents the available SetRedmineService().
+// options.
+//
+// GitLab API docs:
+// https://docs.gitlab.com/ee/api/integrations.html#set-up-redmine
+type SetRedmineServiceOptions struct {
+	NewIssueURL          *string `url:"new_issue_url,omitempty" json:"new_issue_url,omitempty"`
+	ProjectURL           *string `url:"project_url,omitempty" json:"project_url,omitempty"`
+	IssuesURL            *string `url:"issues_url,omitempty" json:"issues_url,omitempty"`
+	UseInheritedSettings *bool   `url:"use_inherited_settings,omitempty" json:"use_inherited_settings,omitempty"`
+}
+
+// SetRedmineService sets Redmine service for a project.
+//
+// GitLab API docs:
+// https://docs.gitlab.com/ee/api/integrations.html#set-up-redmine
+func (s *ServicesService) SetRedmineService(pid interface{}, opt *SetRedmineServiceOptions, options ...RequestOptionFunc) (*Response, error) {
+	project, err := parseID(pid)
+	if err != nil {
+		return nil, err
+	}
+	u := fmt.Sprintf("projects/%s/integrations/redmine", PathEscape(project))
+
+	req, err := s.client.NewRequest(http.MethodPut, u, opt, options)
+	if err != nil {
+		return nil, err
+	}
+
+	return s.client.Do(req, nil)
+}
+
+// DeleteRedmineService deletes Redmine service for project.
+//
+// GitLab API docs:
+// https://docs.gitlab.com/ee/api/integrations.html#disable-redmine
+func (s *ServicesService) DeleteRedmineService(pid interface{}, options ...RequestOptionFunc) (*Response, error) {
+	project, err := parseID(pid)
+	if err != nil {
+		return nil, err
+	}
+	u := fmt.Sprintf("projects/%s/integrations/redmine", PathEscape(project))
+
+	req, err := s.client.NewRequest(http.MethodDelete, u, nil, options)
+	if err != nil {
+		return nil, err
+	}
+
+	return s.client.Do(req, nil)
+}
+
 // SlackService represents Slack service settings.
 //
 // GitLab API docs:


Test patch:
diff --git a/services_test.go b/services_test.go
index a698bc8..36614ce 100644
--- a/services_test.go
+++ b/services_test.go
@@ -756,6 +756,52 @@ func TestDeletePrometheusService(t *testing.T) {
 	}
 }
 
+func TestGetRedmineService(t *testing.T) {
+	mux, client := setup(t)
+
+	mux.HandleFunc("/api/v4/projects/1/integrations/redmine", func(w http.ResponseWriter, r *http.Request) {
+		testMethod(t, r, http.MethodGet)
+		fmt.Fprint(w, `{"id":1}`)
+	})
+	want := &RedmineService{Service: Service{ID: 1}}
+
+	service, _, err := client.Services.GetRedmineService(1)
+	if err != nil {
+		t.Fatalf("Services.GetRedmineService returns an error: %v", err)
+	}
+	if !reflect.DeepEqual(want, service) {
+		t.Errorf("Services.GetRedmineService returned %+v, want %+v", service, want)
+	}
+}
+
+func TestSetRedmineService(t *testing.T) {
+	mux, client := setup(t)
+
+	mux.HandleFunc("/api/v4/projects/1/integrations/redmine", func(w http.ResponseWriter, r *http.Request) {
+		testMethod(t, r, http.MethodPut)
+	})
+
+	opt := &SetRedmineServiceOptions{Ptr("t"), Ptr("u"), Ptr("a"), Ptr(false)}
+
+	_, err := client.Services.SetRedmineService(1, opt)
+	if err != nil {
+		t.Fatalf("Services.SetRedmineService returns an error: %v", err)
+	}
+}
+
+func TestDeleteRedmineService(t *testing.T) {
+	mux, client := setup(t)
+
+	mux.HandleFunc("/api/v4/projects/1/integrations/redmine", func(w http.ResponseWriter, r *http.Request) {
+		testMethod(t, r, http.MethodDelete)
+	})
+
+	_, err := client.Services.DeleteRedmineService(1)
+	if err != nil {
+		t.Fatalf("Services.DeleteRedmineService returns an error: %v", err)
+	}
+}
+
 func TestGetSlackService(t *testing.T) {
 	mux, client := setup(t)