nebius/SWE-rebench-V2-PRs huggingface dataset:
Repository: xanzy/go-gitlab
Pull request #1793 (2023-09-14 12:14:56)

Add report_type to CreateProjectLevelRuleOptions
This PR adds a missing `report_type` to `CreateProjectLevelRuleOptions`.

GitLab API docs: https://docs.gitlab.com/ee/api/merge_request_approvals.html#create-project-level-rule



Patch:
diff --git a/projects.go b/projects.go
index 6d4cfe7..00a0dee 100644
--- a/projects.go
+++ b/projects.go
@@ -1809,6 +1809,7 @@ func (s *ProjectsService) GetProjectApprovalRule(pid interface{}, ruleID int, op
 type CreateProjectLevelRuleOptions struct {
 	Name                          *string `url:"name,omitempty" json:"name,omitempty"`
 	ApprovalsRequired             *int    `url:"approvals_required,omitempty" json:"approvals_required,omitempty"`
+	ReportType                    *string `url:"report_type,omitempty" json:"report_type,omitempty"`
 	RuleType                      *string `url:"rule_type,omitempty" json:"rule_type,omitempty"`
 	UserIDs                       *[]int  `url:"user_ids,omitempty" json:"user_ids,omitempty"`
 	GroupIDs                      *[]int  `url:"group_ids,omitempty" json:"group_ids,omitempty"`


Test patch:
diff --git a/projects_test.go b/projects_test.go
index 7500357..b31d0df 100644
--- a/projects_test.go
+++ b/projects_test.go
@@ -1194,6 +1194,7 @@ func TestCreateProjectApprovalRule(t *testing.T) {
 		ApprovalsRequired: Int(3),
 		UserIDs:           &[]int{5, 50},
 		GroupIDs:          &[]int{5},
+		ReportType:        String("code_coverage"),
 	}
 
 	rule, _, err := client.Projects.CreateProjectApprovalRule(1, opt)
Repository: xanzy/go-gitlab
Pull request #1818 (2023-10-05 12:49:20)

Add summary support in AddSpentTimeOptions
# Goal

This PR is adding a `summary` field in the `AddSpentTimeOptions` structure.

This structure is used to call the add spent API endpoints for merge requests and issues. 

Today we can only pass the duration of the time spent when calling gitlab API, however the 2 endpoints also accept a `summary` optional field (see [merge request][1] and [issues][2]).

Adding this new field in the structure will allow users to set a specific `summary` value while calling gitlab API.

[1]: https://docs.gitlab.com/ee/api/merge_requests.html#add-spent-time-for-a-merge-request
[2]: https://docs.gitlab.com/ee/api/issues.html#add-spent-time-for-an-issue


Patch:
diff --git a/time_stats.go b/time_stats.go
index c1256b9..0ce2d67 100644
--- a/time_stats.go
+++ b/time_stats.go
@@ -104,6 +104,7 @@ func (s *timeStatsService) resetTimeEstimate(pid interface{}, entity string, iss
 // GitLab docs: https://docs.gitlab.com/ee/workflow/time_tracking.html
 type AddSpentTimeOptions struct {
 	Duration *string `url:"duration,omitempty" json:"duration,omitempty"`
+	Summary  *string `url:"summary,omitempty" json:"summary,omitempty"`
 }
 
 // addSpentTime adds spent time for a single project issue.


Test patch:
diff --git a/issues_test.go b/issues_test.go
index 1025756..16f52c6 100644
--- a/issues_test.go
+++ b/issues_test.go
@@ -775,10 +775,12 @@ func TestAddSpentTime(t *testing.T) {
 	mux.HandleFunc("/api/v4/projects/1/issues/5/add_spent_time", func(w http.ResponseWriter, r *http.Request) {
 		testMethod(t, r, http.MethodPost)
 		testURL(t, r, "/api/v4/projects/1/issues/5/add_spent_time")
+		testBody(t, r, `{"duration":"1h","summary":"test"}`)
 		fmt.Fprint(w, `{"human_time_estimate": null, "human_total_time_spent": "1h", "time_estimate": 0, "total_time_spent": 3600}`)
 	})
 	addSpentTimeOpt := &AddSpentTimeOptions{
 		Duration: String("1h"),
+		Summary:  String("test"),
 	}
 
 	timeState, _, err := client.Issues.AddSpentTime("1", 5, addSpentTimeOpt)
Repository: xanzy/go-gitlab
Pull request #1844 (2023-12-06 16:44:42)

Added missing fields for flexibleRollout feature flag strategy
Feature flag model is missing a few fields for `flexibleRollout` strategy.

These fields aren't documented in Gitlab API docs for some reason, but they are described in [Unleash docs](https://docs.getunleash.io/reference/activation-strategies#gradual-rollout) and [Gitlab documentation](https://docs.gitlab.com/ee/api/feature_flags.html#create-a-feature-flag) has link to it (see `strategies:name`).


Patch:
diff --git a/project_feature_flags.go b/project_feature_flags.go
index 9f75611..98c3588 100644
--- a/project_feature_flags.go
+++ b/project_feature_flags.go
@@ -53,6 +53,12 @@ type ProjectFeatureFlagStrategyParameter struct {
 	GroupID    string `json:"groupId,omitempty"`
 	UserIDs    string `json:"userIds,omitempty"`
 	Percentage string `json:"percentage,omitempty"`
+
+	// Following fields aren't documented in Gitlab API docs,
+	// but are present in Gitlab API since 13.5.
+	// Docs: https://docs.getunleash.io/reference/activation-strategies#gradual-rollout
+	Rollout    string `json:"rollout,omitempty"`
+	Stickiness string `json:"stickiness,omitempty"`
 }
 
 func (i ProjectFeatureFlag) String() string {


Test patch:
diff --git a/project_feature_flags_test.go b/project_feature_flags_test.go
index 7db8e92..b660f00 100644
--- a/project_feature_flags_test.go
+++ b/project_feature_flags_test.go
@@ -117,6 +117,21 @@ func TestGetProjectFeatureFlag(t *testing.T) {
 					},
 				},
 			},
+			{
+				ID:   24,
+				Name: "flexibleRollout",
+				Parameters: &ProjectFeatureFlagStrategyParameter{
+					GroupID:    "default",
+					Rollout:    "50",
+					Stickiness: "default",
+				},
+				Scopes: []*ProjectFeatureFlagScope{
+					{
+						ID:               52,
+						EnvironmentScope: "*",
+					},
+				},
+			},
 		},
 	}
 
diff --git a/testdata/get_project_feature_flag.json b/testdata/get_project_feature_flag.json
index e460627..9b7129b 100644
--- a/testdata/get_project_feature_flag.json
+++ b/testdata/get_project_feature_flag.json
@@ -17,6 +17,21 @@
           "environment_scope": "production"
         }
       ]
+    },
+    {
+      "id": 24,
+      "name": "flexibleRollout",
+      "parameters": {
+        "groupId": "default",
+        "rollout": "50",
+        "stickiness": "default"
+      },
+      "scopes": [
+        {
+          "id": 52,
+          "environment_scope": "*"
+        }
+      ]
     }
   ]
 }
Repository: xanzy/go-gitlab
Pull request #1846 (2023-12-07 20:43:24)

Add delete group milestone functionality and tests
Added a new function, DeleteGroupMilestone, to the GroupMilestonesService which allows for the deletion of a specified group milestone.

Ref: https://docs.gitlab.com/ee/api/group_milestones.html#delete-group-milestone


Patch:
diff --git a/group_milestones.go b/group_milestones.go
index 60aa2e9..179d059 100644
--- a/group_milestones.go
+++ b/group_milestones.go
@@ -188,6 +188,24 @@ func (s *GroupMilestonesService) UpdateGroupMilestone(gid interface{}, milestone
 	return m, resp, nil
 }
 
+// DeleteGroupMilestone deletes a specified group milestone.
+//
+// GitLab API docs:
+// https://docs.gitlab.com/ee/api/group_milestones.html#delete-group-milestone
+func (s *GroupMilestonesService) DeleteGroupMilestone(pid interface{}, milestone int, options ...RequestOptionFunc) (*Response, error) {
+	project, err := parseID(pid)
+	if err != nil {
+		return nil, err
+	}
+	u := fmt.Sprintf("groups/%s/milestones/%d", PathEscape(project), milestone)
+
+	req, err := s.client.NewRequest(http.MethodDelete, u, nil, options)
+	if err != nil {
+		return nil, err
+	}
+	return s.client.Do(req, nil)
+}
+
 // GetGroupMilestoneIssuesOptions represents the available GetGroupMilestoneIssues() options.
 //
 // GitLab API docs:


Test patch:
diff --git a/group_milestones_test.go b/group_milestones_test.go
index c16b5bf..3f840a5 100644
--- a/group_milestones_test.go
+++ b/group_milestones_test.go
@@ -210,6 +210,30 @@ func TestGroupMilestonesService_UpdateGroupMilestone(t *testing.T) {
 	require.Equal(t, http.StatusNotFound, resp.StatusCode)
 }
 
+func TestGroupMilestonesService_DeleteGroupMilestone(t *testing.T) {
+	mux, client := setup(t)
+
+	mux.HandleFunc("/api/v4/groups/5/milestones/12", func(w http.ResponseWriter, r *http.Request) {
+		testMethod(t, r, http.MethodDelete)
+	})
+
+	resp, err := client.GroupMilestones.DeleteGroupMilestone(5, 12, nil)
+	require.NoError(t, err)
+	require.NotNil(t, resp)
+
+	resp, err = client.GroupMilestones.DeleteGroupMilestone(5.01, 12, nil)
+	require.EqualError(t, err, "invalid ID type 5.01, the ID must be an int or a string")
+	require.Nil(t, resp)
+
+	resp, err = client.GroupMilestones.DeleteGroupMilestone(5, 12, nil, errorOption)
+	require.EqualError(t, err, "RequestOptionFunc returns an error")
+	require.Nil(t, resp)
+
+	resp, err = client.GroupMilestones.DeleteGroupMilestone(3, 12, nil)
+	require.Error(t, err)
+	require.Equal(t, http.StatusNotFound, resp.StatusCode)
+}
+
 func TestGroupMilestonesService_GetGroupMilestoneIssues(t *testing.T) {
 	mux, client := setup(t)
Repository: xanzy/go-gitlab
Pull request #1848 (2023-12-08 13:12:07)

Add CreateServiceAccountUser
See https://docs.gitlab.com/ee/api/users.html#create-service-account-user

This is complementary to #1842


Patch:
diff --git a/users.go b/users.go
index 4489034..5ad87ca 100644
--- a/users.go
+++ b/users.go
@@ -103,6 +103,7 @@ type User struct {
 	UsingLicenseSeat               bool               `json:"using_license_seat"`
 	CustomAttributes               []*CustomAttribute `json:"custom_attributes"`
 	NamespaceID                    int                `json:"namespace_id"`
+	Locked                         bool               `json:"locked"`
 }
 
 // UserIdentity represents a user identity.
@@ -1488,3 +1489,21 @@ func (s *UsersService) CreateUserRunner(opts *CreateUserRunnerOptions, options .
 
 	return r, resp, nil
 }
+
+// CreateServiceAccountUser creates a new service account user. Note only administrators can create new service account users.
+//
+// GitLab API docs: https://docs.gitlab.com/ee/api/users.html#create-service-account-user
+func (s *UsersService) CreateServiceAccountUser(options ...RequestOptionFunc) (*User, *Response, error) {
+	req, err := s.client.NewRequest(http.MethodPost, "service_accounts", nil, options)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	usr := new(User)
+	resp, err := s.client.Do(req, usr)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return usr, resp, nil
+}


Test patch:
diff --git a/testdata/create_service_account_user.json b/testdata/create_service_account_user.json
new file mode 100644
index 0000000..e5354e5
--- /dev/null
+++ b/testdata/create_service_account_user.json
@@ -0,0 +1,9 @@
+{
+  "id": 999,
+  "username": "service_account_94e556c44d40d5a710ca59e3a0f40a3d",
+  "name": "Service account user",
+  "state": "active",
+  "locked": false,
+  "avatar_url": "http://localhost:3000/uploads/user/avatar/999/cd8.jpeg",
+  "web_url": "http://localhost:3000/service_account_94e556c44d40d5a710ca59e3a0f40a3d"
+}
diff --git a/users_test.go b/users_test.go
index 2fca55d..9a2afcc 100644
--- a/users_test.go
+++ b/users_test.go
@@ -716,3 +716,28 @@ func TestCreatePersonalAccessTokenForCurrentUser(t *testing.T) {
 	}
 	require.Equal(t, want, user)
 }
+
+func TestCreateServiceAccountUser(t *testing.T) {
+	mux, client := setup(t)
+
+	path := "/api/v4/service_accounts"
+
+	mux.HandleFunc(path, func(w http.ResponseWriter, r *http.Request) {
+		testMethod(t, r, http.MethodPost)
+		mustWriteHTTPResponse(t, w, "testdata/create_service_account_user.json")
+	})
+
+	user, _, err := client.Users.CreateServiceAccountUser()
+	require.NoError(t, err)
+
+	want := &User{
+		ID:        999,
+		Username:  "service_account_94e556c44d40d5a710ca59e3a0f40a3d",
+		Name:      "Service account user",
+		State:     "active",
+		Locked:    false,
+		AvatarURL: "http://localhost:3000/uploads/user/avatar/999/cd8.jpeg",
+		WebURL:    "http://localhost:3000/service_account_94e556c44d40d5a710ca59e3a0f40a3d",
+	}
+	require.Equal(t, want, user)
+}
Repository: xanzy/go-gitlab
Pull request #1849 (2023-12-08 16:45:46)

Update StopEnvironment to accept a StopEnvironmentOptions struct to support the `force` boolean
Closes https://github.com/xanzy/go-gitlab/issues/1836.


Patch:
diff --git a/environments.go b/environments.go
index cee6aaf..b6d902f 100644
--- a/environments.go
+++ b/environments.go
@@ -204,18 +204,26 @@ func (s *EnvironmentsService) DeleteEnvironment(pid interface{}, environment int
 	return s.client.Do(req, nil)
 }
 
-// StopEnvironment stop an environment from a project team.
+// StopEnvironmentOptions represents the available StopEnvironment() options.
 //
 // GitLab API docs:
 // https://docs.gitlab.com/ee/api/environments.html#stop-an-environment
-func (s *EnvironmentsService) StopEnvironment(pid interface{}, environmentID int, options ...RequestOptionFunc) (*Environment, *Response, error) {
+type StopEnvironmentOptions struct {
+	Force *bool `url:"force,omitempty" json:"force,omitempty"`
+}
+
+// StopEnvironment stops an environment within a specific project.
+//
+// GitLab API docs:
+// https://docs.gitlab.com/ee/api/environments.html#stop-an-environment
+func (s *EnvironmentsService) StopEnvironment(pid interface{}, environmentID int, opt *StopEnvironmentOptions, options ...RequestOptionFunc) (*Environment, *Response, error) {
 	project, err := parseID(pid)
 	if err != nil {
 		return nil, nil, err
 	}
 	u := fmt.Sprintf("projects/%s/environments/%d/stop", PathEscape(project), environmentID)
 
-	req, err := s.client.NewRequest(http.MethodPost, u, nil, options)
+	req, err := s.client.NewRequest(http.MethodPost, u, opt, options)
 	if err != nil {
 		return nil, nil, err
 	}


Test patch:
diff --git a/environments_test.go b/environments_test.go
index bdfb4bf..717ac8f 100644
--- a/environments_test.go
+++ b/environments_test.go
@@ -185,7 +185,7 @@ func TestStopEnvironment(t *testing.T) {
       "tier": "staging"
     }`)
 	})
-	_, _, err := client.Environments.StopEnvironment(1, 1)
+	_, _, err := client.Environments.StopEnvironment(1, 1, &StopEnvironmentOptions{})
 	if err != nil {
 		log.Fatal(err)
 	}
Repository: xanzy/go-gitlab
Pull request #1869 (2024-01-18 21:20:11)

Fix an issue with environment names not being encoded
This PR fixes an issue where environments that have slashes in their name cause an error because the URL isn't encoded. 

Upstream TF provider issue: https://gitlab.com/gitlab-org/terraform-provider-gitlab/-/issues/6198


Patch:
diff --git a/protected_environments.go b/protected_environments.go
index 3dc7fbd..9b0fd62 100644
--- a/protected_environments.go
+++ b/protected_environments.go
@@ -242,7 +242,7 @@ func (s *ProtectedEnvironmentsService) UpdateProtectedEnvironments(pid interface
 	if err != nil {
 		return nil, nil, err
 	}
-	u := fmt.Sprintf("projects/%s/protected_environments/%s", PathEscape(project), environment)
+	u := fmt.Sprintf("projects/%s/protected_environments/%s", PathEscape(project), PathEscape(environment))
 
 	req, err := s.client.NewRequest(http.MethodPut, u, opt, options)
 	if err != nil {


Test patch:
diff --git a/protected_environments_test.go b/protected_environments_test.go
index dda3b38..dca6d9d 100644
--- a/protected_environments_test.go
+++ b/protected_environments_test.go
@@ -557,6 +557,30 @@ func TestUpdateProtectedEnvironments(t *testing.T) {
 	assert.Equal(t, expected, environment)
 }
 
+func TestUpdateRepositoryEnvironmentsEscapesURL(t *testing.T) {
+	mux, client := setup(t)
+
+	rawRequest := ""
+
+	// Use a "/" in the environment name, so it needs encoding
+	// Note: Mux requires the path to be unencoded for some reason. Using %2F will never intercept the request.
+	mux.HandleFunc("/api/v4/projects/1/protected_environments/test/environment", func(w http.ResponseWriter, r *http.Request) {
+		testMethod(t, r, http.MethodPut)
+
+		// Store the raw request so we're sure it's encoded properly
+		rawRequest = r.URL.RawPath
+
+		fmt.Fprintf(w, `{
+			"name": "test/environment"
+		}`)
+	})
+
+	_, resp, err := client.ProtectedEnvironments.UpdateProtectedEnvironments(1, "test/environment", &UpdateProtectedEnvironmentsOptions{})
+	assert.NoError(t, err, "failed to get response")
+	assert.Equal(t, http.StatusOK, resp.StatusCode)
+	assert.Equal(t, rawRequest, "/api/v4/projects/1/protected_environments/test%2Fenvironment")
+}
+
 func TestUnprotectRepositoryEnvironments(t *testing.T) {
 	mux, client := setup(t)
Repository: xanzy/go-gitlab
Pull request #1903 (2024-03-22 19:14:20)

Add missing params to ProjectLint
Adds some missing parameters to `ProjectLint`


Patch:
diff --git a/validate.go b/validate.go
index 1a0f56a..cb79ac8 100644
--- a/validate.go
+++ b/validate.go
@@ -121,6 +121,8 @@ func (s *ValidateService) ProjectNamespaceLint(pid interface{}, opt *ProjectName
 // GitLab API docs:
 // https://docs.gitlab.com/ee/api/lint.html#validate-a-projects-ci-configuration
 type ProjectLintOptions struct {
+	ContentRef  *string `url:"content_ref,omitempty" json:"content_ref,omitempty"`
+	DryRunRef   *string `url:"dry_run_ref,omitempty" json:"dry_run_ref,omitempty"`
 	DryRun      *bool   `url:"dry_run,omitempty" json:"dry_run,omitempty"`
 	IncludeJobs *bool   `url:"include_jobs,omitempty" json:"include_jobs,omitempty"`
 	Ref         *string `url:"ref,omitempty" json:"ref,omitempty"`


Test patch:
diff --git a/validate_test.go b/validate_test.go
index ab4bfc3..20171e2 100644
--- a/validate_test.go
+++ b/validate_test.go
@@ -223,3 +223,54 @@ func TestValidateProjectNamespace(t *testing.T) {
 		})
 	}
 }
+
+func TestValidateProjectLint(t *testing.T) {
+	testCases := []struct {
+		description string
+		request     *ProjectLintOptions
+		response    string
+		want        *ProjectLintResult
+	}{
+		{
+			description: "valid",
+			request: &ProjectLintOptions{
+				DryRun:      Ptr(false),
+				IncludeJobs: Ptr(true),
+				ContentRef:  Ptr("foo"),
+			},
+			response: `{
+				"valid": true,
+				"errors": [],
+				"warnings": [],
+				"merged_yaml": 	"---\n:build:\n  :script:\n  - echo build"
+			}`,
+			want: &ProjectLintResult{
+				Valid:      true,
+				Warnings:   []string{},
+				Errors:     []string{},
+				MergedYaml: "---\n:build:\n  :script:\n  - echo build",
+			},
+		},
+	}
+
+	for _, tc := range testCases {
+		t.Run(tc.description, func(t *testing.T) {
+			mux, client := setup(t)
+
+			mux.HandleFunc("/api/v4/projects/1/ci/lint", func(w http.ResponseWriter, r *http.Request) {
+				testMethod(t, r, http.MethodGet)
+				fmt.Fprint(w, tc.response)
+			})
+
+			got, _, err := client.Validate.ProjectLint(1, tc.request)
+			if err != nil {
+				t.Errorf("Validate returned error: %v", err)
+			}
+
+			want := tc.want
+			if !reflect.DeepEqual(got, want) {
+				t.Errorf("Validate returned \ngot:\n%v\nwant:\n%v", Stringify(got), Stringify(want))
+			}
+		})
+	}
+}
Repository: xanzy/go-gitlab
Pull request #1907 (2024-04-02 13:52:58)

Add support for service account token expiration
When creating a Personal Access Token for a Service Account, it's possible to also pass an expiry date (optional).
This PR adds support for this.


Patch:
diff --git a/group_serviceaccounts.go b/group_serviceaccounts.go
index 4acb0b1..3ccb41b 100644
--- a/group_serviceaccounts.go
+++ b/group_serviceaccounts.go
@@ -62,8 +62,9 @@ func (s *GroupsService) CreateServiceAccount(gid interface{}, options ...Request
 // GitLab API docs:
 // https://docs.gitlab.com/ee/api/groups.html#create-personal-access-token-for-service-account-user
 type CreateServiceAccountPersonalAccessTokenOptions struct {
-	Scopes *[]string `url:"scopes,omitempty" json:"scopes,omitempty"`
-	Name   *string   `url:"name,omitempty" json:"name,omitempty"`
+	Scopes    *[]string `url:"scopes,omitempty" json:"scopes,omitempty"`
+	Name      *string   `url:"name,omitempty" json:"name,omitempty"`
+	ExpiresAt *ISOTime  `url:"expires_at,omitempty" json:"expires_at,omitempty"`
 }
 
 // CreateServiceAccountPersonalAccessToken add a new Personal Access Token for a


Test patch:
diff --git a/group_serviceaccounts_test.go b/group_serviceaccounts_test.go
index e4793f6..b878c8e 100644
--- a/group_serviceaccounts_test.go
+++ b/group_serviceaccounts_test.go
@@ -22,6 +22,8 @@ import (
 	"reflect"
 	"testing"
 	"time"
+
+	"github.com/stretchr/testify/require"
 )
 
 func TestCreateServiceAccount(t *testing.T) {
@@ -72,9 +74,14 @@ func TestCreateServiceAccountPersonalAccessToken(t *testing.T) {
       	"token":"random_token"
       }`)
 	})
+
+	expireTime, err := ParseISOTime("2024-06-12")
+	require.NoError(t, err)
+
 	options := &CreateServiceAccountPersonalAccessTokenOptions{
-		Scopes: Ptr([]string{"api"}),
-		Name:   Ptr("service_account_token"),
+		Scopes:    Ptr([]string{"api"}),
+		Name:      Ptr("service_account_token"),
+		ExpiresAt: Ptr(expireTime),
 	}
 	pat, _, err := client.Groups.CreateServiceAccountPersonalAccessToken(1, 57, options)
 	if err != nil {
Repository: xanzy/go-gitlab
Pull request #1937 (2024-05-09 15:07:53)

Issue: #1936 fix Missing MemberRoleId for group link creation
Change to allow setting the MemberRoleID in the AddGroupSAMLLink api.

Fix issue #1936 


Patch:
diff --git a/groups.go b/groups.go
index 23241f4..00c36c3 100644
--- a/groups.go
+++ b/groups.go
@@ -881,6 +881,7 @@ func (s *GroupsService) GetGroupSAMLLink(gid interface{}, samlGroupName string,
 type AddGroupSAMLLinkOptions struct {
 	SAMLGroupName *string           `url:"saml_group_name,omitempty" json:"saml_group_name,omitempty"`
 	AccessLevel   *AccessLevelValue `url:"access_level,omitempty" json:"access_level,omitempty"`
+	MemberRoleID  *int              `url:"member_role_id,omitempty" json:"member_role_id,omitempty"`
 }
 
 // AddGroupSAMLLink creates a new group SAML link. Available only for users who


Test patch:
diff --git a/groups_test.go b/groups_test.go
index c272e07..3c778be 100644
--- a/groups_test.go
+++ b/groups_test.go
@@ -569,6 +569,7 @@ func TestAddGroupSAMLLinkCustomRole(t *testing.T) {
 	opt := &AddGroupSAMLLinkOptions{
 		SAMLGroupName: Ptr("gitlab_group_example_developer"),
 		AccessLevel:   Ptr(DeveloperPermissions),
+		MemberRoleID:  Ptr(123),
 	}
 
 	link, _, err := client.Groups.AddGroupSAMLLink(1, opt)