Commit 80bd3240 authored by Rémy Coutable's avatar Rémy Coutable

Merge branch 'edit-group-push-rules' into 'master'

API to edit group push rules

See merge request gitlab-org/gitlab!40136
parents 4ad688f6 5860e93f
......@@ -1170,7 +1170,7 @@ DELETE /groups/:id/share/:group_id
## Push Rules **(STARTER)**
### Get group push rules
### Get group push rules **(STARTER)**
Get the [push rules](../user/group/index.md#group-push-rules-starter) of a group.
......@@ -1233,3 +1233,70 @@ POST /groups/:id/push_rule
| `max_file_size` **(STARTER)** | integer | no | Maximum file size (MB) allowed |
| `commit_committer_check` **(PREMIUM)** | boolean | no | Only commits pushed using verified emails will be allowed |
| `reject_unsigned_commits` **(PREMIUM)** | boolean | no | Only commits signed through GPG will be allowed |
```shell
curl --request POST --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/groups/19/push_rule"
```
Response:
```json
{
"id": 19,
"created_at": "2020-08-31T15:53:00.073Z",
"commit_message_regex": "[a-zA-Z]",
"commit_message_negative_regex": "[x+]",
"branch_name_regex": null,
"deny_delete_tag": false,
"member_check": false,
"prevent_secrets": false,
"author_email_regex": "^[A-Za-z0-9.]+@gitlab.com$",
"file_name_regex": null,
"max_file_size": 100
}
```
### Edit group push rule **(STARTER)**
Edit push rules for a specified group.
```plaintext
PUT /groups/:id/push_rule
```
| Attribute | Type | Required | Description |
| --------------------------------------------- | -------------- | -------- | ----------- |
| `id` | integer/string | yes | The ID or [URL-encoded path of the group](README.md#namespaced-path-encoding) |
| `deny_delete_tag` **(STARTER)** | boolean | no | Deny deleting a tag |
| `member_check` **(STARTER)** | boolean | no | Restricts commits to be authored by existing GitLab users only |
| `prevent_secrets` **(STARTER)** | boolean | no | [Files that are likely to contain secrets](https://gitlab.com/gitlab-org/gitlab/-/blob/master/ee/lib/gitlab/checks/files_denylist.yml) will be rejected |
| `commit_message_regex` **(STARTER)** | string | no | All commit messages must match the regular expression provided in this attribute, e.g. `Fixed \d+\..*` |
| `commit_message_negative_regex` **(STARTER)** | string | no | Commit messages matching the regular expression provided in this attribute will not be allowed, e.g. `ssh\:\/\/` |
| `branch_name_regex` **(STARTER)** | string | no | All branch names must match the regular expression provided in this attribute, e.g. `(feature|hotfix)\/*` |
| `author_email_regex` **(STARTER)** | string | no | All commit author emails must match the regular expression provided in this attribute, e.g. `@my-company.com$` |
| `file_name_regex` **(STARTER)** | string | no | Filenames matching the regular expression provided in this attribute will **not** be allowed, e.g. `(jar|exe)$` |
| `max_file_size` **(STARTER)** | integer | no | Maximum file size (MB) allowed |
| `commit_committer_check` **(PREMIUM)** | boolean | no | Only commits pushed using verified emails will be allowed |
| `reject_unsigned_commits` **(PREMIUM)** | boolean | no | Only commits signed through GPG will be allowed |
```shell
curl --request PUT --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/groups/19/push_rule"
```
Response:
```json
{
"id": 19,
"created_at": "2020-08-31T15:53:00.073Z",
"commit_message_regex": "[a-zA-Z]",
"commit_message_negative_regex": "[x+]",
"branch_name_regex": null,
"deny_delete_tag": false,
"member_check": false,
"prevent_secrets": false,
"author_email_regex": "^[A-Za-z0-9.]+@staging.gitlab.com$",
"file_name_regex": null,
"max_file_size": 100
}
```
---
title: API to edit group push rules
merge_request: 40136
author:
type: added
......@@ -64,6 +64,24 @@ module API
user_group.update!(push_rule: PushRule.create!(allowed_params))
present user_group.push_rule, with: EE::API::Entities::GroupPushRule, user: current_user
end
desc 'Edit push rule of a group' do
detail 'This feature was introduced in GitLab 13.4.'
success EE::API::Entities::GroupPushRule
end
params do
use :push_rule_params
end
put ":id/push_rule" do
push_rule = user_group.push_rule
not_found! unless push_rule
if push_rule.update(declared_params(include_missing: false))
present push_rule, with: EE::API::Entities::GroupPushRule, user: current_user
else
render_validation_error!(push_rule)
end
end
end
end
end
......@@ -257,4 +257,113 @@ RSpec.describe API::GroupPushRule, 'GroupPushRule', api: true do
end
end
end
describe 'PUT /groups/:id/push_rule' do
subject { put api("/groups/#{group.id}/push_rule", admin), params: attributes_for_update }
let(:group) { create(:group) }
let_it_be(:attributes_for_update) do
{
author_email_regex: '^[A-Za-z0-9.]+@disney.com$',
reject_unsigned_commits: true,
commit_committer_check: false
}
end
before do
push_rule = create(:push_rule, **attributes)
group.update!(push_rule: push_rule)
end
context 'when unlicensed' do
it_behaves_like 'not found when feature is unavailable'
end
context 'authorized user' do
context 'when licensed' do
include_context 'licensed features available'
it do
subject
expect(response).to have_gitlab_http_status(:ok)
end
it 'updates attributes as expected' do
expect { subject }.to change { group.reload.push_rule.author_email_regex }
.from(attributes[:author_email_regex])
.to(attributes_for_update[:author_email_regex])
end
context 'when push rule does not exist for group' do
let_it_be(:group_without_push_rule) { create(:group) }
it 'returns not found' do
put api("/groups/#{group_without_push_rule.id}/push_rule", admin), params: attributes_for_update
expect(response).to have_gitlab_http_status(:not_found)
expect(json_response['message']).to include('Not Found')
end
end
context 'permissions' do
subject { put api("/groups/#{group.id}/push_rule", user), params: attributes_for_update }
it_behaves_like 'allow access to api based on role'
end
context 'when no rule is specified' do
it do
put api("/groups/#{group.id}/push_rule", admin), params: {}
expect(response).to have_gitlab_http_status(:bad_request)
expect(json_response['error']).to include('at least one parameter must be provided')
end
end
end
context 'when reject_unsigned_commits is unavailable' do
before do
stub_licensed_features(reject_unsigned_commits: false)
stub_licensed_features(push_rules: true, commit_committer_check: true)
end
it 'returns forbidden' do
subject
expect(response).to have_gitlab_http_status(:forbidden)
end
context 'and reject_unsigned_commits is not set' do
it 'returns status ok' do
put api("/groups/#{group.id}/push_rule", admin), params: attributes_for_update.except(:reject_unsigned_commits)
expect(response).to have_gitlab_http_status(:ok)
end
end
end
context 'when commit_committer_check is unavailable' do
before do
stub_licensed_features(commit_committer_check: false)
stub_licensed_features(push_rules: true, reject_unsigned_commits: true)
end
it do
subject
expect(response).to have_gitlab_http_status(:forbidden)
end
context 'and commit_committer_check is not set' do
it 'returns status ok' do
put api("/groups/#{group.id}/push_rule", admin), params: attributes_for_update.except(:commit_committer_check)
expect(response).to have_gitlab_http_status(:ok)
end
end
end
end
end
end
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment