diff --git a/protected_environments.go b/protected_environments.go index 5e5962bd4..21820ab39 100644 --- a/protected_environments.go +++ b/protected_environments.go @@ -38,6 +38,7 @@ type ProtectedEnvironment struct { Name string `json:"name"` DeployAccessLevels []*EnvironmentAccessDescription `json:"deploy_access_levels"` RequiredApprovalCount int `json:"required_approval_count"` + ApprovalRules []*EnvironmentApprovalRule `json:"approval_rules"` } // EnvironmentAccessDescription represents the access decription for a protected @@ -46,12 +47,28 @@ type ProtectedEnvironment struct { // GitLab API docs: // https://docs.gitlab.com/ee/api/protected_environments.html type EnvironmentAccessDescription struct { + ID int `json:"id"` AccessLevel AccessLevelValue `json:"access_level"` AccessLevelDescription string `json:"access_level_description"` UserID int `json:"user_id"` GroupID int `json:"group_id"` } +// EnvironmentApprovalRule represents the approval rules for a protected +// environment. +// +// GitLab API docs: +// https://docs.gitlab.com/ee/api/protected_environments.html#protect-a-single-environment +type EnvironmentApprovalRule struct { + ID int `json:"id"` + UserID int `json:"user_id"` + GroupID int `json:"group_id"` + AccessLevel AccessLevelValue `json:"access_level"` + AccessLevelDescription string `json:"access_level_description"` + RequiredApprovalCount int `json:"required_approvals"` + GroupInheritanceType int `json:"group_inheritance_type"` +} + // ListProtectedEnvironmentsOptions represents the available // ListProtectedEnvironments() options. // @@ -117,9 +134,10 @@ func (s *ProtectedEnvironmentsService) GetProtectedEnvironment(pid interface{}, // GitLab API docs: // https://docs.gitlab.com/ee/api/protected_environments.html#protect-a-single-environment type ProtectRepositoryEnvironmentsOptions struct { - Name *string `url:"name,omitempty" json:"name,omitempty"` - DeployAccessLevels *[]*EnvironmentAccessOptions `url:"deploy_access_levels,omitempty" json:"deploy_access_levels,omitempty"` - RequiredApprovalCount *int `url:"required_approval_count,omitempty" json:"required_approval_count,omitempty"` + Name *string `url:"name,omitempty" json:"name,omitempty"` + DeployAccessLevels *[]*EnvironmentAccessOptions `url:"deploy_access_levels,omitempty" json:"deploy_access_levels,omitempty"` + RequiredApprovalCount *int `url:"required_approval_count,omitempty" json:"required_approval_count,omitempty"` + ApprovalRules *[]*EnvironmentApprovalRuleOptions `url:"approval_rules,omitempty" json:"approval_rules,omitempty"` } // EnvironmentAccessOptions represents the options for an access decription for @@ -133,6 +151,20 @@ type EnvironmentAccessOptions struct { GroupID *int `url:"group_id,omitempty" json:"group_id,omitempty"` } +// EnvironmentApprovalRuleOptions represents the approval rules for a protected +// environment. +// +// GitLab API docs: +// https://docs.gitlab.com/ee/api/protected_environments.html#protect-a-single-environment +type EnvironmentApprovalRuleOptions struct { + UserID *int `url:"user_id,omitempty" json:"user_id,omitempty"` + GroupID *int `url:"group_id,omitempty" json:"group_id,omitempty"` + AccessLevel *AccessLevelValue `url:"access_level,omitempty" json:"access_level,omitempty"` + AccessLevelDescription *string `url:"access_level_description,omitempty" json:"access_level_description,omitempty"` + RequiredApprovalCount *int `url:"required_approvals,omitempty" json:"required_approvals,omitempty"` + GroupInheritanceType *int `url:"group_inheritance_type,omitempty" json:"group_inheritance_type,omitempty"` +} + // ProtectRepositoryEnvironments protects a single repository environment or // several project repository environments using wildcard protected environment. // diff --git a/protected_environments_test.go b/protected_environments_test.go index dac5e24bc..4dd8a80db 100644 --- a/protected_environments_test.go +++ b/protected_environments_test.go @@ -37,7 +37,27 @@ func TestListProtectedEnvironments(t *testing.T) { "access_level_description": "Maintainers" } ], - "required_approval_count": 1 + "required_approval_count": 1, + "approval_rules": [ + { + "id": 38, + "user_id": 42, + "group_id": null, + "access_level": null, + "access_level_description": "qa-group", + "required_approvals": 1, + "group_inheritance_type": 0 + }, + { + "id": 39, + "user_id": null, + "group_id": 135, + "access_level": 30, + "access_level_description": "security-group", + "required_approvals": 2, + "group_inheritance_type": 1 + } + ] },{ "name":"*-release", "deploy_access_levels": [ @@ -59,6 +79,22 @@ func TestListProtectedEnvironments(t *testing.T) { }, }, RequiredApprovalCount: 1, + ApprovalRules: []*EnvironmentApprovalRule{ + { + ID: 38, + UserID: 42, + AccessLevelDescription: "qa-group", + RequiredApprovalCount: 1, + }, + { + ID: 39, + GroupID: 135, + AccessLevel: 30, + AccessLevelDescription: "security-group", + RequiredApprovalCount: 2, + GroupInheritanceType: 1, + }, + }, }, { Name: "*-release", @@ -93,7 +129,18 @@ func TestGetProtectedEnvironment(t *testing.T) { "access_level_description": "Developers + Maintainers" } ], - "required_approval_count": 1 + "required_approval_count": 1, + "approval_rules": [ + { + "id": 1, + "user_id": null, + "group_id": 10, + "access_level": 5, + "access_level_description": "devops", + "required_approvals": 0, + "group_inheritance_type": 0 + } + ] }`) }) @@ -106,13 +153,21 @@ func TestGetProtectedEnvironment(t *testing.T) { }, }, RequiredApprovalCount: 1, + ApprovalRules: []*EnvironmentApprovalRule{ + { + ID: 1, + GroupID: 10, + AccessLevel: 5, + AccessLevelDescription: "devops", + }, + }, } environment, _, err := client.ProtectedEnvironments.GetProtectedEnvironment(1, environmentName) assert.NoError(t, err, "failed to get response") assert.Equal(t, expected, environment) - // Test without RequiredApprovalCount + // Test without RequiredApprovalCount nor ApprovalRules environmentName = "my-awesome-environment2" mux.HandleFunc(fmt.Sprintf("/api/v4/projects/2/protected_environments/%s", environmentName), func(w http.ResponseWriter, r *http.Request) { @@ -146,7 +201,7 @@ func TestGetProtectedEnvironment(t *testing.T) { func TestProtectRepositoryEnvironments(t *testing.T) { mux, client := setup(t) - // Test with RequiredApprovalCount + // Test with RequiredApprovalCount and ApprovalRules mux.HandleFunc("/api/v4/projects/1/protected_environments", func(w http.ResponseWriter, r *http.Request) { testMethod(t, r, http.MethodPost) fmt.Fprint(w, `{ @@ -157,7 +212,18 @@ func TestProtectRepositoryEnvironments(t *testing.T) { "access_level_description": "Developers + Maintainers" } ], - "required_approval_count": 2 + "required_approval_count": 2, + "approval_rules": [ + { + "id": 1, + "user_id": null, + "group_id": 10, + "access_level": 5, + "access_level_description": "devops", + "required_approvals": 0, + "group_inheritance_type": 0 + } + ] }`) }) @@ -170,6 +236,14 @@ func TestProtectRepositoryEnvironments(t *testing.T) { }, }, RequiredApprovalCount: 2, + ApprovalRules: []*EnvironmentApprovalRule{ + { + ID: 1, + GroupID: 10, + AccessLevel: 5, + AccessLevelDescription: "devops", + }, + }, } opt := &ProtectRepositoryEnvironmentsOptions{ @@ -178,13 +252,20 @@ func TestProtectRepositoryEnvironments(t *testing.T) { {AccessLevel: AccessLevel(30)}, }, RequiredApprovalCount: Int(2), + ApprovalRules: &[]*EnvironmentApprovalRuleOptions{ + { + GroupID: Int(10), + AccessLevel: AccessLevel(0), + AccessLevelDescription: String("devops"), + }, + }, } environment, _, err := client.ProtectedEnvironments.ProtectRepositoryEnvironments(1, opt) assert.NoError(t, err, "failed to get response") assert.Equal(t, expected, environment) - // Test without RequiredApprovalCount + // Test without RequiredApprovalCount nor ApprovalRules mux.HandleFunc("/api/v4/projects/2/protected_environments", func(w http.ResponseWriter, r *http.Request) { testMethod(t, r, http.MethodPost) fmt.Fprint(w, `{