Verified Commit 5574bbbf authored by Andreas Böhrnsen's avatar Andreas Böhrnsen Committed by GitLab
Browse files

fix: package protection access level variable type

Changelog: Improvements
parent 1d03b208
Loading
Loading
Loading
Loading
+29 −0
Original line number Diff line number Diff line
@@ -221,3 +221,32 @@ membership := &gitlab.BillableUserMembership{

**Note:** `ISOTime` is used for fields that only support year-month-day formatting, while `*time.Time` is used for full timestamps.

## API Update for PackageProtectionRule

The variable type for `MinimumAccessLevelForDelete` and `MinimumAccessLevelForPush` were previously `int64`, and have been changed to a `string` to align with the documentation. In addition, they use a new `Nullable[string]` type that allows explicit `null` values to be sent to the API, since `null` is a valid and intentional value for this API call.

**Changes:**
- Parameter type: Changed from `*int64` to `Nullable[ProtectionRuleAccessLevel]` ( string, nullable )

```go
// Before (v1.x)
rule, resp, err := client.ProtectedPackages.CreatePackageProtectionRules(1, &CreatePackageProtectionRulesOptions{
		PackageNamePattern:          Ptr("@my-scope/my-package-*"),
		PackageType:                 Ptr("npm"),
		MinimumAccessLevelForDelete: Ptr(int64(MaintainerPermissions)),
		MinimumAccessLevelForPush:   nil, // Ignored when sent to the API, preventing sending "null"
})

// After (v2.0):
rule, resp, err := client.ProtectedPackages.CreatePackageProtectionRules(1, &CreatePackageProtectionRulesOptions{
		PackageNamePattern:          Ptr("@my-scope/my-package-*"),
		PackageType:                 Ptr("npm"),
		MinimumAccessLevelForDelete: NewNullableWithValue(ProtectionRuleAccessLevelMaintainer),
		MinimumAccessLevelForPush:   NewNullNullable[ProtectionRuleAccessLevel](), // sends "null" to the API to reset the value to default
})
```


### Merge Requests That Implement This Change
- [Fix Package Protection Access Level Variable Type](https://gitlab.com/gitlab-org/api/client-go/-/merge_requests/2728) by @deepflame
+8 −8
Original line number Diff line number Diff line
@@ -68,8 +68,8 @@ type ListPackageProtectionRulesOptions struct {
type CreatePackageProtectionRulesOptions struct {
	PackageNamePattern          *string                             `url:"package_name_pattern" json:"package_name_pattern"`
	PackageType                 *string                             `url:"package_type" json:"package_type"`
	MinimumAccessLevelForDelete *int64  `url:"minimum_access_level_for_delete" json:"minimum_access_level_for_delete"`
	MinimumAccessLevelForPush   *int64  `url:"minimum_access_level_for_push" json:"minimum_access_level_for_push"`
	MinimumAccessLevelForDelete Nullable[ProtectionRuleAccessLevel] `url:"minimum_access_level_for_delete,omitempty" json:"minimum_access_level_for_delete,omitempty"`
	MinimumAccessLevelForPush   Nullable[ProtectionRuleAccessLevel] `url:"minimum_access_level_for_push,omitempty" json:"minimum_access_level_for_push,omitempty"`
}

// UpdatePackageProtectionRulesOptions represents the available
@@ -80,8 +80,8 @@ type CreatePackageProtectionRulesOptions struct {
type UpdatePackageProtectionRulesOptions struct {
	PackageNamePattern          *string                             `url:"package_name_pattern" json:"package_name_pattern"`
	PackageType                 *string                             `url:"package_type" json:"package_type"`
	MinimumAccessLevelForDelete *int64  `url:"minimum_access_level_for_delete" json:"minimum_access_level_for_delete"`
	MinimumAccessLevelForPush   *int64  `url:"minimum_access_level_for_push" json:"minimum_access_level_for_push"`
	MinimumAccessLevelForDelete Nullable[ProtectionRuleAccessLevel] `url:"minimum_access_level_for_delete,omitempty" json:"minimum_access_level_for_delete,omitempty"`
	MinimumAccessLevelForPush   Nullable[ProtectionRuleAccessLevel] `url:"minimum_access_level_for_push,omitempty" json:"minimum_access_level_for_push,omitempty"`
}

func (s *ProtectedPackagesService) ListPackageProtectionRules(pid any, opts *ListPackageProtectionRulesOptions, options ...RequestOptionFunc) ([]*PackageProtectionRule, *Response, error) {
+50 −3
Original line number Diff line number Diff line
@@ -73,8 +73,8 @@ func TestProtectedPackagesService_CreatePackageProtectionRules(t *testing.T) {
	opts := &CreatePackageProtectionRulesOptions{
		PackageNamePattern:          Ptr("@my-scope/my-package-*"),
		PackageType:                 Ptr("npm"),
		MinimumAccessLevelForDelete: Ptr(int64(MaintainerPermissions)),
		MinimumAccessLevelForPush:   Ptr(int64(OwnerPermissions)),
		MinimumAccessLevelForDelete: NewNullableWithValue(ProtectionRuleAccessLevelMaintainer),
		MinimumAccessLevelForPush:   NewNullableWithValue(ProtectionRuleAccessLevelOwner),
	}

	rule, resp, err := client.ProtectedPackages.CreatePackageProtectionRules(1, opts)
@@ -112,7 +112,54 @@ func TestProtectedPackagesService_UpdatePackageProtectionRules(t *testing.T) {

	opts := &UpdatePackageProtectionRulesOptions{
		PackageNamePattern:        Ptr("@my-scope/my-package-updated"),
		MinimumAccessLevelForPush: Ptr(int64(OwnerPermissions)),
		MinimumAccessLevelForPush: NewNullableWithValue(ProtectionRuleAccessLevelOwner),
	}

	rule, resp, err := client.ProtectedPackages.UpdatePackageProtectionRules(1, int64(123), opts)
	require.NoError(t, err)
	require.NotNil(t, resp)
	require.Equal(t, want, rule)
}

func TestProtectedPackagesService_UpdatePackageProtectionRulesWithNullValues(t *testing.T) {
	t.Parallel()
	mux, client := setup(t)

	mux.HandleFunc("/api/v4/projects/1/packages/protection/rules/123", func(w http.ResponseWriter, r *http.Request) {
		testMethod(t, r, http.MethodPatch)
		testJSONBody(t, r, `{
			"package_name_pattern": "@my-scope/my-package-updated",
			"package_type": "npm",
			"minimum_access_level_for_delete": null,
			"minimum_access_level_for_push": null
		}`)

		fmt.Fprint(w, `
			{
				"id": 123,
				"project_id": 1,
				"package_name_pattern": "@my-scope/my-package-updated",
				"package_type": "npm",
				"minimum_access_level_for_delete": "maintainer",
				"minimum_access_level_for_push": "developer"
			}
		`)
	})

	want := &PackageProtectionRule{
		ID:                          123,
		ProjectID:                   1,
		PackageNamePattern:          "@my-scope/my-package-updated",
		PackageType:                 "npm",
		MinimumAccessLevelForDelete: "maintainer",
		MinimumAccessLevelForPush:   "developer",
	}

	opts := &UpdatePackageProtectionRulesOptions{
		PackageNamePattern:          Ptr("@my-scope/my-package-updated"),
		PackageType:                 Ptr("npm"),
		MinimumAccessLevelForPush:   NewNullNullable[ProtectionRuleAccessLevel](),
		MinimumAccessLevelForDelete: NewNullNullable[ProtectionRuleAccessLevel](),
	}

	rule, resp, err := client.ProtectedPackages.UpdatePackageProtectionRules(1, int64(123), opts)