Commit eae6778a authored by Rémy Coutable's avatar Rémy Coutable

Merge branch 'feature/2293-branch-name-push-rule' into 'master'

Create a push rule to check branch name

Closes #2293

See merge request !1896
parents e530453d 2fb820e1
......@@ -25,6 +25,6 @@ class Projects::PushRulesController < Projects::ApplicationController
# Only allow a trusted parameter "white list" through.
def push_rule_params
params.require(:push_rule).permit(:deny_delete_tag, :delete_branch_regex,
:commit_message_regex, :force_push_regex, :author_email_regex, :member_check, :file_name_regex, :max_file_size, :prevent_secrets)
:commit_message_regex, :branch_name_regex, :force_push_regex, :author_email_regex, :member_check, :file_name_regex, :max_file_size, :prevent_secrets)
end
end
......@@ -8,6 +8,7 @@ class PushRule < ActiveRecord::Base
def commit_validation?
commit_message_regex.present? ||
branch_name_regex.present? ||
author_email_regex.present? ||
member_check ||
file_name_regex.present? ||
......@@ -19,6 +20,10 @@ class PushRule < ActiveRecord::Base
data_match?(message, commit_message_regex)
end
def branch_name_allowed?(branch)
data_match?(branch, branch_name_regex)
end
def author_email_allowed?(email)
data_match?(email, author_email_regex)
end
......
......@@ -35,6 +35,15 @@
If this field is empty it allows any commit message.
For example you can require that an issue number is always mentioned in the commit message.
.form-group
= f.label :branch_name_regex, "Branch name", class: 'label-light'
= f.text_field :branch_name_regex, class: "form-control", placeholder: 'Example: (feature|hotfix)\/*'
.help-block
All branch names must match this
= link_to 'Ruby regular expression', 'http://www.ruby-doc.org/core-2.1.1/Regexp.html'
to be pushed.
If this field is empty it allows any branch name.
.form-group
= f.label :author_email_regex, "Commit author's email", class: 'label-light'
= f.text_field :author_email_regex, class: "form-control", placeholder: 'Example: @my-company.com$'
......
---
title: Create a push rule to check the branch name
merge_request: 1896
author: Riccardo Padovani
# See http://doc.gitlab.com/ce/development/migration_style_guide.html
# for more information on how to write migrations for GitLab.
class AddPushRuleBranchName < ActiveRecord::Migration
include Gitlab::Database::MigrationHelpers
# Set this constant to true if this migration requires downtime.
DOWNTIME = false
def up
add_column :push_rules, :branch_name_regex, :string
end
def down
remove_column :push_rules, :branch_name_regex
end
end
......@@ -1228,6 +1228,7 @@ ActiveRecord::Schema.define(version: 20170523091700) do
t.string "force_push_regex"
t.string "delete_branch_regex"
t.string "commit_message_regex"
t.string "branch_name_regex"
t.boolean "deny_delete_tag"
t.integer "project_id"
t.datetime "created_at"
......
......@@ -1263,6 +1263,7 @@ Parameters:
"id": 1,
"project_id": 3,
"commit_message_regex": "Fixes \d +\",
"branch_name_regex": "",
"deny_delete_tag": false,
"created_at": "2012-10-12T17:04:47Z",
"member_check": false,
......@@ -1290,6 +1291,7 @@ Parameters:
| `member_check` | boolean | no | Restrict commits by author (email) to existing GitLab users |
| `prevent_secrets` | boolean | no | GitLab will reject any files that are likely to contain secrets |
| `commit_message_regex` | string | no | All commit messages must match this, e.g. `Fixed \d+\..*` |
| `branch_name_regex` | string | no | All branch names must match this, e.g. `(feature|hotfix)\/*` |
| `author_email_regex` | string | no | All commit author emails must match this, e.g. `@my-company.com$` |
| `file_name_regex` | string | no | All commited filenames must **not** match this, e.g. `(jar|exe)$` |
| `max_file_size` | integer | no | Maximum file size (MB) |
......@@ -1311,6 +1313,7 @@ Parameters:
| `member_check` | boolean | no | Restrict commits by author (email) to existing GitLab users |
| `prevent_secrets` | boolean | no | GitLab will reject any files that are likely to contain secrets |
| `commit_message_regex` | string | no | All commit messages must match this, e.g. `Fixed \d+\..*` |
| `branch_name_regex` | string | no | All branch names must match this, e.g. `(feature|hotfix)\/*` |
| `author_email_regex` | string | no | All commit author emails must match this, e.g. `@my-company.com$` |
| `file_name_regex` | string | no | All commited filenames must **not** match this, e.g. `(jar|exe)$` |
| `max_file_size` | integer | no | Maximum file size (MB) |
......
doc/push_rules/push_rules.png

349 KB | W: | H:

doc/push_rules/push_rules.png

121 KB | W: | H:

doc/push_rules/push_rules.png
doc/push_rules/push_rules.png
doc/push_rules/push_rules.png
doc/push_rules/push_rules.png
  • 2-up
  • Swipe
  • Onion skin
......@@ -65,7 +65,7 @@ module API
class ProjectPushRule < Grape::Entity
expose :id, :project_id, :created_at
expose :commit_message_regex, :deny_delete_tag
expose :commit_message_regex, :branch_name_regex, :deny_delete_tag
expose :member_check, :prevent_secrets, :author_email_regex
expose :file_name_regex, :max_file_size
end
......
......@@ -13,11 +13,12 @@ module API
optional :member_check, type: Boolean, desc: 'Restrict commits by author (email) to existing GitLab users'
optional :prevent_secrets, type: Boolean, desc: 'GitLab will reject any files that are likely to contain secrets'
optional :commit_message_regex, type: String, desc: 'All commit messages must match this'
optional :branch_name_regex, type: String, desc: 'All branches names must match this'
optional :author_email_regex, type: String, desc: 'All commit author emails must match this'
optional :file_name_regex, type: String, desc: 'All commited filenames must not match this'
optional :max_file_size, type: Integer, desc: 'Maximum file size (MB)'
at_least_one_of :deny_delete_tag, :member_check, :prevent_secrets,
:commit_message_regex, :author_email_regex,
:commit_message_regex, :branch_name_regex, :author_email_regex,
:file_name_regex, :max_file_size
end
end
......
......@@ -174,6 +174,10 @@ module Gitlab
return "Commit message does not follow the pattern '#{push_rule.commit_message_regex}'"
end
if @branch_name && !push_rule.branch_name_allowed?(@branch_name)
return "Branch name does not follow the pattern '#{push_rule.branch_name_regex}'"
end
unless push_rule.author_email_allowed?(commit.committer_email)
return "Committer's email '#{commit.committer_email}' does not follow the pattern '#{push_rule.author_email_regex}'"
end
......
......@@ -41,6 +41,7 @@ describe API::ProjectPushRule, 'ProjectPushRule', api: true do
post api("/projects/#{project.id}/push_rule", user),
deny_delete_tag: true, member_check: true, prevent_secrets: true,
commit_message_regex: 'JIRA\-\d+',
branch_name_regex: '(feature|hotfix)\/*',
author_email_regex: '[a-zA-Z0-9]+@gitlab.com',
file_name_regex: '[a-zA-Z0-9]+.key',
max_file_size: 5
......@@ -51,6 +52,7 @@ describe API::ProjectPushRule, 'ProjectPushRule', api: true do
expect(json_response['member_check']).to eq(true)
expect(json_response['prevent_secrets']).to eq(true)
expect(json_response['commit_message_regex']).to eq('JIRA\-\d+')
expect(json_response['branch_name_regex']).to eq('(feature|hotfix)\/*')
expect(json_response['author_email_regex']).to eq('[a-zA-Z0-9]+@gitlab.com')
expect(json_response['file_name_regex']).to eq('[a-zA-Z0-9]+.key')
expect(json_response['max_file_size']).to eq(5)
......
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