Commit 1b98b5ab authored by Valery Sizov's avatar Valery Sizov

Rename git hooks to push rules

parent 4d8cd1e8
Please view this file on the master branch, on stable branches it's out of date.
v 8.10.0 (unreleased)
- Rename Git Hooks to Push Rules
v 8.9.4
- Improve how File Lock feature works with nested items. !497
......
class Admin::GitHooksController < Admin::ApplicationController
before_action :git_hook
class Admin::PushRulesController < Admin::ApplicationController
before_action :push_rule
respond_to :html
......@@ -7,10 +7,10 @@ class Admin::GitHooksController < Admin::ApplicationController
end
def update
@git_hook.update_attributes(git_hook_params.merge(is_sample: true))
@push_rule.update_attributes(push_rule_params.merge(is_sample: true))
if @git_hook.valid?
redirect_to admin_git_hooks_path, notice: 'Git Hooks updated successfully.'
if @push_rule.valid?
redirect_to admin_push_rules_path, notice: 'Push Rules updated successfully.'
else
render :index
end
......@@ -18,12 +18,12 @@ class Admin::GitHooksController < Admin::ApplicationController
private
def git_hook_params
params.require(:git_hook).permit(:deny_delete_tag, :delete_branch_regex,
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)
end
def git_hook
@git_hook ||= GitHook.find_or_create_by(is_sample: true)
def push_rule
@push_rule ||= PushRule.find_or_create_by(is_sample: true)
end
end
class Projects::GitHooksController < Projects::ApplicationController
class Projects::PushRulesController < Projects::ApplicationController
# Authorize
before_action :authorize_admin_project!
......@@ -7,17 +7,17 @@ class Projects::GitHooksController < Projects::ApplicationController
layout "project_settings"
def index
project.create_git_hook unless project.git_hook
project.create_push_rule unless project.push_rule
@git_hook = project.git_hook
@push_rule = project.push_rule
end
def update
@git_hook = project.git_hook
@git_hook.update_attributes(git_hook_params)
@push_rule = project.push_rule
@push_rule.update_attributes(push_rule_params)
if @git_hook.valid?
redirect_to namespace_project_git_hooks_path(@project.namespace, @project), notice: 'Git Hooks updated successfully.'
if @push_rule.valid?
redirect_to namespace_project_push_rules_path(@project.namespace, @project), notice: 'Push Rules updated successfully.'
else
render :index
end
......@@ -26,8 +26,8 @@ class Projects::GitHooksController < Projects::ApplicationController
private
# Only allow a trusted parameter "white list" through.
def git_hook_params
params.require(:git_hook).permit(:deny_delete_tag, :delete_branch_regex,
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)
end
end
......@@ -99,7 +99,7 @@ module TabHelper
return 'active'
end
if ['services', 'hooks', 'deploy_keys', 'protected_branches', 'git_hooks'].include? controller.controller_name
if ['services', 'hooks', 'deploy_keys', 'protected_branches', 'push_rules'].include? controller.controller_name
"active"
end
end
......
......@@ -57,7 +57,7 @@ class Project < ActiveRecord::Base
belongs_to :namespace
belongs_to :mirror_user, foreign_key: 'mirror_user_id', class_name: 'User'
has_one :git_hook, dependent: :destroy
has_one :push_rule, dependent: :destroy
has_one :last_event, -> {order 'events.created_at DESC'}, class_name: 'Event', foreign_key: 'project_id'
# Project services
......
class GitHook < ActiveRecord::Base
class PushRule < ActiveRecord::Base
belongs_to :project
validates :project, presence: true, unless: "is_sample?"
......
......@@ -70,8 +70,8 @@ module Files
end
end
def git_hook
project.git_hook
def push_rule
project.push_rule
end
end
end
......@@ -31,16 +31,16 @@ module MergeRequests
def hooks_validation_pass?(merge_request)
return true if project.merge_requests_ff_only_enabled
git_hook = merge_request.project.git_hook
return true unless git_hook
push_rule = merge_request.project.push_rule
return true unless push_rule
unless git_hook.commit_message_allowed?(params[:commit_message])
merge_request.update(merge_error: "Commit message does not follow the pattern '#{git_hook.commit_message_regex}'")
unless push_rule.commit_message_allowed?(params[:commit_message])
merge_request.update(merge_error: "Commit message does not follow the pattern '#{push_rule.commit_message_regex}'")
return false
end
unless git_hook.author_email_allowed?(current_user.email)
merge_request.update(merge_error: "Commit author's email '#{current_user.email}' does not follow the pattern '#{git_hook.author_email_regex}'")
unless push_rule.author_email_allowed?(current_user.email)
merge_request.update(merge_error: "Commit author's email '#{current_user.email}' does not follow the pattern '#{push_rule.author_email_regex}'")
return false
end
......
......@@ -95,11 +95,11 @@ module Projects
@project.team << [current_user, :master, current_user]
end
predefined_git_hook = GitHook.find_by(is_sample: true)
predefined_push_rule = PushRule.find_by(is_sample: true)
if predefined_git_hook
git_hook = predefined_git_hook.dup.tap{ |gh| gh.is_sample = false }
project.git_hook = git_hook
if predefined_push_rule
push_rule = predefined_push_rule.dup.tap{ |gh| gh.is_sample = false }
project.push_rule = push_rule
end
end
......
- page_title "Git Hooks"
- page_title "Push Rules"
%h3.page-title
Pre-defined git hooks.
Pre-defined push rules.
%p.light
Rules that define what git pushes are accepted for a project. All newly created projects will use this settings. Request new rules for free by creating an issue on the <a href="https://gitlab.com/gitlab-org/gitlab-ee/issues/">GitLab EE issue tracker</a> and labeling it 'Feature proposal'. Or if you can please contribute a tested merge request.
%hr.clearfix
= form_for [:admin, @git_hook] do |f|
-if @git_hook.errors.any?
= form_for [:admin, @push_rule] do |f|
-if @push_rule.errors.any?
.alert.alert-danger
- @git_hook.errors.full_messages.each do |msg|
- @push_rule.errors.full_messages.each do |msg|
%p= msg
= render "shared/git_hooks_form", f: f
= render "shared/push_rules_form", f: f
......@@ -46,10 +46,10 @@
%span
Spam Logs
= nav_link(controller: :git_hooks) do
= link_to admin_git_hooks_path, title: 'Git Hooks' do
= nav_link(controller: :push_rules) do
= link_to admin_push_rules_path, title: 'Push Rules' do
%span
Git Hooks
Push Rules
= nav_link(controller: :geo_nodes) do
= link_to admin_geo_nodes_path, title: 'Geo Nodes' do
......
......@@ -43,10 +43,10 @@
= link_to namespace_project_badges_path(@project.namespace, @project), title: 'Badges' do
%span
Badges
= nav_link(controller: :git_hooks) do
= link_to namespace_project_git_hooks_path(@project.namespace, @project), title: "Git Hooks" do
= nav_link(controller: :push_rules) do
= link_to namespace_project_push_rules_path(@project.namespace, @project), title: "Push Rules" do
%span
Git Hooks
Push Rules
= nav_link(controller: :mirrors) do
= link_to namespace_project_mirror_path(@project.namespace, @project), title: 'Mirror Repository', data: {placement: 'right'} do
%span
......
- page_title "Git Hooks"
- page_title "Push Rules"
.row.prepend-top-default.append-bottom-default
.col-lg-3
%h4.prepend-top-0
= page_title
%p.light
Git Hooks outline what is accepted for this project. You can request new rules (for free) by creating an issue on our
Push Rules outline what is accepted for this project. You can request new rules (for free) by creating an issue on our
= succeed '.' do
%a{ href: "https://gitlab.com/gitlab-org/gitlab-ee/issues/" }GitLab EE issue tracker
Alternatively, submit a merge request to GitLab EE.
.col-lg-9
%h5.prepend-top-0
Add new web hook
= form_for [@project.namespace.becomes(Namespace), @project, @git_hook] do |f|
= form_errors(@git_hook)
Add new push rule
= form_for [@project.namespace.becomes(Namespace), @project, @push_rule] do |f|
= form_errors(@push_rule)
= render "shared/git_hooks_form", f: f
= render "shared/push_rules_form", f: f
......@@ -49,4 +49,4 @@
Pushes that contain added or updated files that exceed this file size are rejected.
Set to 0 to allow files of any size.
= f.submit "Save Git hooks", class: "btn btn-create"
= f.submit "Save Push Rules", class: "btn btn-create"
......@@ -262,7 +262,7 @@ Rails.application.routes.draw do
end
end
resources :git_hooks, only: [:index, :update]
resources :push_rules, only: [:index, :update]
resource :impersonation, only: :destroy
......@@ -783,7 +783,7 @@ Rails.application.routes.draw do
post :update_now
end
end
resources :git_hooks, constraints: { id: /\d+/ }
resources :push_rules, constraints: { id: /\d+/ }
resources :pipelines, only: [:index, :new, :create, :show] do
member do
......
# See http://doc.gitlab.com/ce/development/migration_style_guide.html
# for more information on how to write migrations for GitLab.
class RenameGitHooksToPushRules < ActiveRecord::Migration
include Gitlab::Database::MigrationHelpers
# When using the methods "add_concurrent_index" or "add_column_with_default"
# you must disable the use of transactions as these methods can not run in an
# existing transaction. When using "add_concurrent_index" make sure that this
# method is the _only_ method called in the migration, any other changes
# should go in a separate migration. This ensures that upon failure _only_ the
# index creation fails and can be retried or reverted easily.
#
# To disable transactions uncomment the following line and remove these
# comments:
# disable_ddl_transaction!
def change
rename_table :git_hooks, :push_rules
end
end
......@@ -11,7 +11,7 @@
#
# It's strongly recommended that you check this file into your version control system.
ActiveRecord::Schema.define(version: 20160628085157) do
ActiveRecord::Schema.define(version: 20160705111606) do
# These are extensions that must be enabled in order to support this database
enable_extension "plpgsql"
......@@ -493,23 +493,6 @@ ActiveRecord::Schema.define(version: 20160628085157) do
add_index "geo_nodes", ["host"], name: "index_geo_nodes_on_host", using: :btree
add_index "geo_nodes", ["primary"], name: "index_geo_nodes_on_primary", using: :btree
create_table "git_hooks", force: :cascade do |t|
t.string "force_push_regex"
t.string "delete_branch_regex"
t.string "commit_message_regex"
t.boolean "deny_delete_tag"
t.integer "project_id"
t.datetime "created_at"
t.datetime "updated_at"
t.string "author_email_regex"
t.boolean "member_check", default: false, null: false
t.string "file_name_regex"
t.boolean "is_sample", default: false
t.integer "max_file_size", default: 0, null: false
end
add_index "git_hooks", ["project_id"], name: "index_git_hooks_on_project_id", using: :btree
create_table "historical_data", force: :cascade do |t|
t.date "date", null: false
t.integer "active_user_count"
......@@ -918,43 +901,45 @@ ActiveRecord::Schema.define(version: 20160628085157) do
t.datetime "created_at"
t.datetime "updated_at"
t.integer "creator_id"
t.boolean "issues_enabled", default: true, null: false
t.boolean "merge_requests_enabled", default: true, null: false
t.boolean "wiki_enabled", default: true, null: false
t.boolean "issues_enabled", default: true, null: false
t.boolean "merge_requests_enabled", default: true, null: false
t.boolean "wiki_enabled", default: true, null: false
t.integer "namespace_id"
t.boolean "snippets_enabled", default: true, null: false
t.string "issues_tracker", default: "gitlab", null: false
t.string "issues_tracker_id"
t.boolean "snippets_enabled", default: true, null: false
t.datetime "last_activity_at"
t.string "import_url"
t.integer "visibility_level", default: 0, null: false
t.boolean "archived", default: false, null: false
t.integer "visibility_level", default: 0, null: false
t.boolean "archived", default: false, null: false
t.string "avatar"
t.string "import_status"
t.float "repository_size", default: 0.0
t.text "merge_requests_template"
t.integer "star_count", default: 0, null: false
t.integer "star_count", default: 0, null: false
t.boolean "merge_requests_rebase_enabled", default: false
t.string "import_type"
t.string "import_source"
t.integer "approvals_before_merge", default: 0, null: false
t.integer "approvals_before_merge", default: 0, null: false
t.boolean "reset_approvals_on_push", default: true
t.integer "commit_count", default: 0
t.boolean "merge_requests_ff_only_enabled", default: false
t.text "issues_template"
t.boolean "mirror", default: false, null: false
t.boolean "mirror", default: false, null: false
t.datetime "mirror_last_update_at"
t.datetime "mirror_last_successful_update_at"
t.integer "mirror_user_id"
t.text "import_error"
t.integer "ci_id"
t.boolean "builds_enabled", default: true, null: false
t.boolean "shared_runners_enabled", default: true, null: false
t.boolean "builds_enabled", default: true, null: false
t.boolean "shared_runners_enabled", default: true, null: false
t.string "runners_token"
t.string "build_coverage_regex"
t.boolean "build_allow_git_fetch", default: true, null: false
t.integer "build_timeout", default: 3600, null: false
t.boolean "mirror_trigger_builds", default: false, null: false
t.boolean "build_allow_git_fetch", default: true, null: false
t.integer "build_timeout", default: 3600, null: false
t.boolean "mirror_trigger_builds", default: false, null: false
t.boolean "pending_delete", default: false
t.boolean "public_builds", default: true, null: false
t.boolean "public_builds", default: true, null: false
t.integer "pushes_since_gc", default: 0
t.boolean "last_repository_check_failed"
t.datetime "last_repository_check_at"
......@@ -991,6 +976,23 @@ ActiveRecord::Schema.define(version: 20160628085157) do
add_index "protected_branches", ["project_id"], name: "index_protected_branches_on_project_id", using: :btree
create_table "push_rules", force: :cascade do |t|
t.string "force_push_regex"
t.string "delete_branch_regex"
t.string "commit_message_regex"
t.boolean "deny_delete_tag"
t.integer "project_id"
t.datetime "created_at"
t.datetime "updated_at"
t.string "author_email_regex"
t.boolean "member_check", default: false, null: false
t.string "file_name_regex"
t.boolean "is_sample", default: false
t.integer "max_file_size", default: 0, null: false
end
add_index "push_rules", ["project_id"], name: "index_push_rules_on_project_id", using: :btree
create_table "releases", force: :cascade do |t|
t.string "tag"
t.text "description"
......
......@@ -30,7 +30,7 @@
- [Changing the appearance of the login page](customization/branded_login_page.md) Make the login page branded for your GitLab instance.
- [Custom git hooks](hooks/custom_hooks.md) Custom git hooks (on the filesystem) for when webhooks aren't enough.
- [Email](tools/email.md) Email GitLab users from GitLab
- [Git Hooks](git_hooks/git_hooks.md) Advanced push rules for your project.
- [Push Rules](push_rules/push_rules.md) Advanced push rules for your project.
- [Help message](customization/help_message.md) Set information about administrators of your GitLab instance.
- [Install](install/README.md) Requirements, directory structures and installation from source.
- [Installing your license](license/README.md)
......
......@@ -1177,14 +1177,14 @@ Parameters:
- `order_by` (optional) - Return requests ordered by `id`, `name`, `created_at` or `last_activity_at` fields
- `sort` (optional) - Return requests sorted in `asc` or `desc` order
## Git Hooks (EE only)
## Push Rules (EE only)
### Show project git hooks
### Show project push rules
Get a project git hook.
Get a project push rule.
```
GET /projects/:id/git_hook
GET /projects/:id/push_rule
```
Parameters:
......@@ -1202,12 +1202,12 @@ Parameters:
}
```
### Add project git hook
### Add project push rule
Adds a git hook to a specified project.
Adds a push rule to a specified project.
```
POST /projects/:id/git_hook
POST /projects/:id/push_rule
```
Parameters:
......@@ -1216,12 +1216,12 @@ Parameters:
- `deny_delete_tag` - Do not allow users to remove git tags with git push
- `commit_message_regex` - Commit message regex
### Edit project git hook
### Edit project push rule
Edits a git hook for a specified project.
Edits a push rule for a specified project.
```
PUT /projects/:id/git_hook
PUT /projects/:id/push_rule
```
Parameters:
......@@ -1230,18 +1230,18 @@ Parameters:
- `deny_delete_tag` - Do not allow users to remove git tags with git push
- `commit_message_regex` - Commit message regex
### Delete project git hook
### Delete project push rule
Removes a git hook from a project. This is an idempotent method and can be called multiple times.
Either the git hook is available or not.
Removes a push rule from a project. This is an idempotent method and can be called multiple times.
Either the push rule is available or not.
```
DELETE /projects/:id/git_hook
DELETE /projects/:id/push_rule
```
Parameters:
- `id` (required) - The ID of a project
Note the JSON response differs if the hook is available or not. If the project hook
Note the JSON response differs if the push rule is available or not. If the project push rule
is available before it is returned in the JSON response or an empty response is returned.
# Git Hooks
Sometimes you need additional control over pushes to your repository.
GitLab already offers protected branches.
But there are cases when you need some specific rules like preventing git tag removal or enforcing a special format for commit messages.
GitLab Enterprise Edition offers a user-friendly interface for such cases.
Git hooks are defined per project so you can have different rules applied to different projects depends on your needs.
Git hooks settings can be found at Project settings -> Git Hooks page.
## New hooks
If you are a subscriber and need a hook that is not there yet we would be glad to add it for free, please contact support to request one.
## How to use
Let's assume you have the following requirements for your workflow:
* every commit should reference a reference JIRA issue. For example: `Refactored css. Fixes JIRA-123. `
* users should not be able to remove git tags with `git push`
All you need to do is write simple regular expression that requires mention of JIRA issue in a commit message.
It can be something like this `/JIRA\-\d+/`.
Just paste regular expression into commit message textfield(without start and ending slash) and save changes.
See the screenshot below:
![screenshot](git_hooks.png)
Now when a user tries to push a commit like `Bugfix` - their push will be declined.
And pushing commit with message like `Bugfix according to JIRA-123` will be accepted.
\ No newline at end of file
Git Hooks have been renamed to [Push Rules](../push_rules/push_rules.md)
......@@ -2,7 +2,7 @@
**Note: Custom git hooks must be configured on the filesystem of the GitLab
server. Only GitLab server administrators will be able to complete these tasks.
Please explore [webhooks](../web_hooks/web_hooks.md) as an option if you do not have filesystem access. For a user configurable Git Hooks interface, please see [GitLab Enterprise Edition Git Hooks](http://docs.gitlab.com/ee/git_hooks/git_hooks.html).**
Please explore [webhooks](../web_hooks/web_hooks.md) as an option if you do not have filesystem access. For a user configurable Push Rules interface, please see [GitLab Enterprise Edition Push Rules](http://docs.gitlab.com/ee/push_rules/push_rules.html).**
Git natively supports hooks that are executed on different actions.
Examples of server-side git hooks include pre-receive, post-receive, and update.
......
# Push Rules
Sometimes you need additional control over pushes to your repository.
GitLab already offers protected branches.
But there are cases when you need some specific rules like preventing git tag removal or enforcing a special format for commit messages.
GitLab Enterprise Edition offers a user-friendly interface for such cases.
Push Rules are defined per project so you can have different rules applied to different projects depends on your needs.
Push Rules settings can be found at Project settings -> Push Rules page.
## New hooks
If you are a subscriber and need a hook that is not there yet we would be glad to add it for free, please contact support to request one.
## How to use
Let's assume you have the following requirements for your workflow:
* every commit should reference a reference JIRA issue. For example: `Refactored css. Fixes JIRA-123. `
* users should not be able to remove git tags with `git push`
All you need to do is write simple regular expression that requires mention of JIRA issue in a commit message.
It can be something like this `/JIRA\-\d+/`.
Just paste regular expression into commit message textfield(without start and ending slash) and save changes.
See the screenshot below:
![screenshot](push_rules.png)
Now when a user tries to push a commit like `Bugfix` - their push will be declined.
And pushing commit with message like `Bugfix according to JIRA-123` will be accepted.
@admin
Feature: Admin git hooks sample
Feature: Admin push rules sample
Background:
Given I sign in as an admin
And I visit git hooks page
And I visit push rules page
Scenario: I can create git hook sample
Scenario: I can create push rule sample
When I fill in a form and submit
Then I see my git hook saved
\ No newline at end of file
Then I see my push rule saved
Feature: Git Hooks
Feature: Push Rules
Background:
Given I sign in as a user
And I own project "Shop"
Scenario: I should see git hook form
When I visit project git hooks page
Then I should see git hook form
\ No newline at end of file
Scenario: I should see push rule form
When I visit project push rules page
Then I should see push rule form
......@@ -10,11 +10,11 @@ class Spinach::Features::AdminGitHooksSample < Spinach::FeatureSteps
step 'I fill in a form and submit' do
fill_in "Commit message", with: "my_string"
click_button "Save Git hooks"
click_button "Save Push Rules"
end
step 'I see my git hook saved' do
visit admin_git_hooks_path
step 'I see my push rule saved' do
visit admin_push_rules_path
expect(page).to have_selector("input[value='my_string']")
end
end
require 'webmock'
class Spinach::Features::GitHooks < Spinach::FeatureSteps
class Spinach::Features::PushRules < Spinach::FeatureSteps
include SharedAuthentication
include SharedProject
include SharedPaths
......@@ -8,12 +8,9 @@ class Spinach::Features::GitHooks < Spinach::FeatureSteps
include RSpec::Mocks::ExampleMethods
include WebMock::API
step 'I should see git hook form' do
expect(page).to have_selector('input#git_hook_commit_message_regex')
step 'I should see push rule form' do
expect(page).to have_selector('input#push_rule_commit_message_regex')
expect(page).to have_content "Commit message"
expect(page).to have_content "Commit author's email"
end
end
......@@ -223,8 +223,8 @@ module SharedPaths
visit admin_applications_path
end
step 'I visit git hooks page' do
visit admin_git_hooks_path
step 'I visit push rules page' do
visit admin_push_rules_path
end
step 'I visit admin license page' do
......@@ -295,8 +295,8 @@ module SharedPaths
visit group_hooks_path(@group)
end
step 'I visit project git hooks page' do
visit namespace_project_git_hooks_path(@project.namespace, @project)
step 'I visit project push rules page' do
visit namespace_project_push_rules_path(@project.namespace, @project)
end
step 'I visit project deploy keys page' do
......
......@@ -49,7 +49,8 @@ module API
mount ::API::Namespaces
mount ::API::Notes
mount ::API::ProjectHooks
mount ::API::ProjectGitHook
mount ::API::ProjectGitHook # TODO: Should be removed after 8.11 is released
mount ::API::ProjectPushRule
mount ::API::ProjectMembers
mount ::API::ProjectSnippets
mount ::API::Projects
......
......@@ -52,7 +52,7 @@ module API
expose :enable_ssl_verification
end
class ProjectGitHook < Grape::Entity
class ProjectPushRule < Grape::Entity
expose :id, :project_id, :created_at
expose :commit_message_regex, :deny_delete_tag
end
......
# TODO: These end-points are deprecated and replaced with push_rules
# and should be removed after GitLab 9.0 is released
module API
# Projects git hook API
# Projects push rule API
class ProjectGitHook < Grape::API
before { authenticate! }
before { authorize_admin_project }
resource :projects do
# Get project git hook
# Get project push rule
#
# Parameters:
# id (required) - The ID of a project
# Example Request:
# GET /projects/:id/git_hook
# GET /projects/:id/push_rule
get ":id/git_hook" do
@git_hooks = user_project.git_hook
present @git_hooks, with: Entities::ProjectGitHook
@push_rule = user_project.push_rule
present @push_rule, with: Entities::ProjectPushRule
end
# Add git hook to project
# Add push rule to project
#
# Parameters:
# id (required) - The ID of a project
# Example Request:
# POST /projects/:id/git_hook
# POST /projects/:id/push_rule
post ":id/git_hook" do
attrs = attributes_for_keys [
:commit_message_regex,
:deny_delete_tag
]
if user_project.git_hook
error!("Project git hook exists", 422)
if user_project.push_rule
error!("Project push rule exists", 422)
else
@git_hook = user_project.create_git_hook(attrs)
present @git_hook, with: Entities::ProjectGitHook
@push_rule = user_project.create_push_rule(attrs)
present @push_rule, with: Entities::ProjectPushRule
end
end
# Update an existing project git hook
# Update an existing project push rule
#
# Parameters:
# id (required) - The ID of a project
# Example Request:
# PUT /projects/:id/git_hook
# PUT /projects/:id/push_rule
put ":id/git_hook" do
@git_hook = user_project.git_hook
@push_rule = user_project.push_rule
attrs = attributes_for_keys [
:commit_message_regex,
:deny_delete_tag
]
if @git_hook && @git_hook.update_attributes(attrs)
present @git_hook, with: Entities::ProjectGitHook
if @push_rule && @push_rule.update_attributes(attrs)
present @push_rule, with: Entities::ProjectPushRule
else
not_found!
end
end
# Deletes project git hook. This is an idempotent function.
# Deletes project push rule. This is an idempotent function.
#
# Parameters:
# id (required) - The ID of a project
# Example Request:
# DELETE /projects/:id/git_hook
# DELETE /projects/:id/push_rule
delete ":id/git_hook" do
@git_hook = user_project.git_hook
if @git_hook
@git_hook.destroy
@push_rule = user_project.push_rule
if @push_rule
@push_rule.destroy
else
not_found!
end
......
module API
# Projects push rule API
class ProjectPushRule < Grape::API
before { authenticate! }
before { authorize_admin_project }
resource :projects do
# Get project push rule
#
# Parameters:
# id (required) - The ID of a project
# Example Request:
# GET /projects/:id/push_rule
get ":id/push_rule" do
@push_rule = user_project.push_rule
present @push_rule, with: Entities::ProjectPushRule
end
# Add push rule to project
#
# Parameters:
# id (required) - The ID of a project
# Example Request:
# POST /projects/:id/push_rule
post ":id/push_rule" do
attrs = attributes_for_keys [
:commit_message_regex,
:deny_delete_tag
]
if user_project.push_rule
error!("Project push rule exists", 422)
else
@push_rule = user_project.create_push_rule(attrs)
present @push_rule, with: Entities::ProjectPushRule
end
end
# Update an existing project push rule
#
# Parameters:
# id (required) - The ID of a project
# Example Request:
# PUT /projects/:id/push_rule
put ":id/push_rule" do
@push_rule = user_project.push_rule
attrs = attributes_for_keys [
:commit_message_regex,
:deny_delete_tag
]
if @push_rule && @push_rule.update_attributes(attrs)
present @push_rule, with: Entities::ProjectPushRule
else
not_found!
end
end
# Deletes project push rule. This is an idempotent function.
#
# Parameters:
# id (required) - The ID of a project
# Example Request:
# DELETE /projects/:id/push_rule
delete ":id/push_rule" do
@push_rule = user_project.push_rule
if @push_rule
@push_rule.destroy
else
not_found!
end
end
end
end
end
......@@ -185,9 +185,9 @@ module Gitlab
return status
end
# Return build_status_object(true) if all git hook checks passed successfully
# Return build_status_object(true) if all push rule checks passed successfully
# or build_status_object(false) if any hook fails
result = git_hook_check(user, project, ref, oldrev, newrev)
result = push_rule_check(user, project, ref, oldrev, newrev)
if result.status && license_allows_file_locks?
result = path_locks_check(user, project, ref, oldrev, newrev)
......@@ -227,21 +227,21 @@ module Gitlab
build_status_object(true)
end
def git_hook_check(user, project, ref, oldrev, newrev)
unless project.git_hook && newrev && oldrev
def push_rule_check(user, project, ref, oldrev, newrev)
unless project.push_rule && newrev && oldrev
return build_status_object(true)
end
git_hook = project.git_hook
push_rule = project.push_rule
# Prevent tag removal
if Gitlab::Git.tag_ref?(ref)
if git_hook.deny_delete_tag && protected_tag?(tag_name(ref)) && Gitlab::Git.blank_ref?(newrev)
if push_rule.deny_delete_tag && protected_tag?(tag_name(ref)) && Gitlab::Git.blank_ref?(newrev)
return build_status_object(false, "You can not delete tag")
end
else
# if newrev is blank, the branch was deleted
if Gitlab::Git.blank_ref?(newrev) || !git_hook.commit_validation?
if Gitlab::Git.blank_ref?(newrev) || !push_rule.commit_validation?
return build_status_object(true)
end
......@@ -251,7 +251,7 @@ module Gitlab
commits(newrev, oldrev, project).each do |commit|
next if commit_from_annex_sync?(commit.safe_message) || old_commit?(commit)
if status_object = check_commit(commit, git_hook)
if status_object = check_commit(commit, push_rule)
return status_object
end
end
......@@ -270,24 +270,24 @@ module Gitlab
end
end
# If commit does not pass git hook validation the whole push should be rejected.
# If commit does not pass push rule validation the whole push should be rejected.
# This method should return nil if no error found or status object if there are some errors.
# In case of errors - all other checks will be canceled and push will be rejected.
def check_commit(commit, git_hook)
unless git_hook.commit_message_allowed?(commit.safe_message)
return build_status_object(false, "Commit message does not follow the pattern '#{git_hook.commit_message_regex}'")
def check_commit(commit, push_rule)
unless push_rule.commit_message_allowed?(commit.safe_message)
return build_status_object(false, "Commit message does not follow the pattern '#{push_rule.commit_message_regex}'")
end
unless git_hook.author_email_allowed?(commit.committer_email)
return build_status_object(false, "Committer's email '#{commit.committer_email}' does not follow the pattern '#{git_hook.author_email_regex}'")
unless push_rule.author_email_allowed?(commit.committer_email)
return build_status_object(false, "Committer's email '#{commit.committer_email}' does not follow the pattern '#{push_rule.author_email_regex}'")
end
unless git_hook.author_email_allowed?(commit.author_email)
return build_status_object(false, "Author's email '#{commit.author_email}' does not follow the pattern '#{git_hook.author_email_regex}'")
unless push_rule.author_email_allowed?(commit.author_email)
return build_status_object(false, "Author's email '#{commit.author_email}' does not follow the pattern '#{push_rule.author_email_regex}'")
end
# Check whether author is a GitLab member
if git_hook.member_check
if push_rule.member_check
unless User.existing_member?(commit.author_email.downcase)
return build_status_object(false, "Author '#{commit.author_email}' is not a member of team")
end
......@@ -299,29 +299,29 @@ module Gitlab
end
end
if status_object = check_commit_diff(commit, git_hook)
if status_object = check_commit_diff(commit, push_rule)
return status_object
end
nil
end
def check_commit_diff(commit, git_hook)
if git_hook.file_name_regex.present?
def check_commit_diff(commit, push_rule)
if push_rule.file_name_regex.present?
commit.diffs.each do |diff|
if (diff.renamed_file || diff.new_file) && diff.new_path =~ Regexp.new(git_hook.file_name_regex)
return build_status_object(false, "File name #{diff.new_path.inspect} is prohibited by the pattern '#{git_hook.file_name_regex}'")
if (diff.renamed_file || diff.new_file) && diff.new_path =~ Regexp.new(push_rule.file_name_regex)
return build_status_object(false, "File name #{diff.new_path.inspect} is prohibited by the pattern '#{push_rule.file_name_regex}'")
end
end
end
if git_hook.max_file_size > 0
if push_rule.max_file_size > 0
commit.diffs.each do |diff|
next if diff.deleted_file
blob = project.repository.blob_at(commit.id, diff.new_path)
if blob && blob.size && blob.size > git_hook.max_file_size.megabytes
return build_status_object(false, "File #{diff.new_path.inspect} is larger than the allowed size of #{git_hook.max_file_size} MB")
if blob && blob.size && blob.size > push_rule.max_file_size.megabytes
return build_status_object(false, "File #{diff.new_path.inspect} is larger than the allowed size of #{push_rule.max_file_size} MB")
end
end
end
......@@ -414,7 +414,7 @@ module Gitlab
def commit_from_annex_sync?(commit_message)
return false unless Gitlab.config.gitlab_shell.git_annex_enabled
# Commit message starting with <git-annex in > so avoid git hooks on this
# Commit message starting with <git-annex in > so avoid push rules on this
commit_message.start_with?('git-annex in')
end
......
# Read about factories at https://github.com/thoughtbot/factory_girl
FactoryGirl.define do
factory :git_hook do
factory :push_rule do
force_push_regex 'feature\/.*'
deny_delete_tag false
delete_branch_regex 'bug\/.*'
......@@ -15,7 +15,7 @@ FactoryGirl.define do
author_email_regex '.*@veryspecificedomain.com'
end
factory :git_hook_sample do
factory :push_rule_sample do
is_sample true
end
end
......
require 'spec_helper'
feature 'Merge With Git Hooks Validation', feature: true, js: true do
feature 'Merge With Push Rules Validation', feature: true, js: true do
let(:user) { create(:user) }
let(:project) { create(:project, :public, git_hook: git_hook) }
let(:project) { create(:project, :public, push_rule: push_rule) }
let(:merge_request) { create(:merge_request_with_diffs, source_project: project, author: user, title: 'Bug NS-04') }
before do
......@@ -10,7 +10,7 @@ feature 'Merge With Git Hooks Validation', feature: true, js: true do
end
context 'commit message is invalid' do
let(:git_hook) { create(:git_hook, :commit_message) }
let(:push_rule) { create(:push_rule, :commit_message) }
before do
login_as user
......@@ -22,12 +22,12 @@ feature 'Merge With Git Hooks Validation', feature: true, js: true do
expect(page).to have_content('Merge in progress')
expect(page).to have_content('This merge request failed to be merged automatically')
expect(page).to have_content("Commit message does not follow the pattern '#{git_hook.commit_message_regex}'")
expect(page).to have_content("Commit message does not follow the pattern '#{push_rule.commit_message_regex}'")
end
end
context 'author email is invalid' do
let(:git_hook) { create(:git_hook, :author_email) }
let(:push_rule) { create(:push_rule, :author_email) }
before do
login_as user
......@@ -39,7 +39,7 @@ feature 'Merge With Git Hooks Validation', feature: true, js: true do
expect(page).to have_content('Merge in progress')
expect(page).to have_content('This merge request failed to be merged automatically')
expect(page).to have_content("Commit author's email '#{user.email}' does not follow the pattern '#{git_hook.author_email_regex}'")
expect(page).to have_content("Commit author's email '#{user.email}' does not follow the pattern '#{push_rule.author_email_regex}'")
end
end
......
......@@ -309,12 +309,12 @@ describe Gitlab::GitAccess, lib: true do
end
end
describe 'and git hooks set' do
before { project.create_git_hook }
describe 'and push rules set' do
before { project.create_push_rule }
describe 'check commit author email' do
before do
project.git_hook.update(author_email_regex: "@only.com")
project.push_rule.update(author_email_regex: "@only.com")
end
describe 'git annex enabled' do
......@@ -342,7 +342,7 @@ describe Gitlab::GitAccess, lib: true do
describe 'check max file size' do
before do
allow_any_instance_of(Gitlab::Git::Blob).to receive(:size).and_return(5.megabytes.to_i)
project.git_hook.update(max_file_size: 2)
project.push_rule.update(max_file_size: 2)
end
describe 'git annex enabled' do
......@@ -361,22 +361,22 @@ describe Gitlab::GitAccess, lib: true do
end
end
describe "git_hook_check" do
describe "push_rule_check" do
describe "author email check" do
it 'returns true' do
expect(access.git_hook_check(user, project, 'refs/heads/master', '6f6d7e7ed97bb5f0054f2b1df789b39ca89b6ff9', '570e7b2abdd848b95f2f578043fc23bd6f6fd24d')).to be_truthy
expect(access.push_rule_check(user, project, 'refs/heads/master', '6f6d7e7ed97bb5f0054f2b1df789b39ca89b6ff9', '570e7b2abdd848b95f2f578043fc23bd6f6fd24d')).to be_truthy
end
it 'returns false' do
project.create_git_hook
project.git_hook.update(commit_message_regex: "@only.com")
expect(access.git_hook_check(user, project, 'refs/heads/master', '6f6d7e7ed97bb5f0054f2b1df789b39ca89b6ff9', '570e7b2abdd848b95f2f578043fc23bd6f6fd24d')).not_to be_allowed
project.create_push_rule
project.push_rule.update(commit_message_regex: "@only.com")
expect(access.push_rule_check(user, project, 'refs/heads/master', '6f6d7e7ed97bb5f0054f2b1df789b39ca89b6ff9', '570e7b2abdd848b95f2f578043fc23bd6f6fd24d')).not_to be_allowed
end
it 'returns true for tags' do
project.create_git_hook
project.git_hook.update(commit_message_regex: "@only.com")
expect(access.git_hook_check(user, project, 'refs/tags/v1', '6f6d7e7ed97bb5f0054f2b1df789b39ca89b6ff9', '570e7b2abdd848b95f2f578043fc23bd6f6fd24d')).to be_allowed
project.create_push_rule
project.push_rule.update(commit_message_regex: "@only.com")
expect(access.push_rule_check(user, project, 'refs/tags/v1', '6f6d7e7ed97bb5f0054f2b1df789b39ca89b6ff9', '570e7b2abdd848b95f2f578043fc23bd6f6fd24d')).to be_allowed
end
it 'allows githook for new branch with an old bad commit' do
......@@ -385,11 +385,11 @@ describe Gitlab::GitAccess, lib: true do
allow(bad_commit).to receive(:refs).and_return([ref_object])
allow_any_instance_of(Repository).to receive(:commits_between).and_return([bad_commit])
project.create_git_hook
project.git_hook.update(commit_message_regex: "Change some files")
project.create_push_rule
project.push_rule.update(commit_message_regex: "Change some files")
# push to new branch, so use a blank old rev and new ref
expect(access.git_hook_check(user, project, 'refs/heads/new-branch', Gitlab::Git::BLANK_SHA, '570e7b2abdd848b95f2f578043fc23bd6f6fd24d')).to be_allowed
expect(access.push_rule_check(user, project, 'refs/heads/new-branch', Gitlab::Git::BLANK_SHA, '570e7b2abdd848b95f2f578043fc23bd6f6fd24d')).to be_allowed
end
it 'allows githook for any change with an old bad commit' do
......@@ -398,11 +398,11 @@ describe Gitlab::GitAccess, lib: true do
allow(bad_commit).to receive(:refs).and_return([ref_object])
allow_any_instance_of(Repository).to receive(:commits_between).and_return([bad_commit])
project.create_git_hook
project.git_hook.update(commit_message_regex: "Change some files")
project.create_push_rule
project.push_rule.update(commit_message_regex: "Change some files")
# push to new branch, so use a blank old rev and new ref
expect(access.git_hook_check(user, project, 'refs/heads/master', '6f6d7e7ed97bb5f0054f2b1df789b39ca89b6ff9', '570e7b2abdd848b95f2f578043fc23bd6f6fd24d')).to be_allowed
expect(access.push_rule_check(user, project, 'refs/heads/master', '6f6d7e7ed97bb5f0054f2b1df789b39ca89b6ff9', '570e7b2abdd848b95f2f578043fc23bd6f6fd24d')).to be_allowed
end
it 'does not allow any change from Web UI with bad commit' do
......@@ -412,41 +412,41 @@ describe Gitlab::GitAccess, lib: true do
allow(bad_commit).to receive(:refs).and_return([ref_object])
allow_any_instance_of(Repository).to receive(:commits_between).and_return([bad_commit])
project.create_git_hook
project.git_hook.update(commit_message_regex: "Change some files")
project.create_push_rule
project.push_rule.update(commit_message_regex: "Change some files")
# push to new branch, so use a blank old rev and new ref
expect(access.git_hook_check(user, project, 'refs/heads/master', '6f6d7e7ed97bb5f0054f2b1df789b39ca89b6ff9', '570e7b2abdd848b95f2f578043fc23bd6f6fd24d')).not_to be_allowed
expect(access.push_rule_check(user, project, 'refs/heads/master', '6f6d7e7ed97bb5f0054f2b1df789b39ca89b6ff9', '570e7b2abdd848b95f2f578043fc23bd6f6fd24d')).not_to be_allowed
end
end
describe "member_check" do
before do
project.create_git_hook
project.git_hook.update(member_check: true)
project.create_push_rule
project.push_rule.update(member_check: true)
end
it 'returns false for non-member user' do
expect(access.git_hook_check(user, project, 'refs/heads/master', '6f6d7e7ed97bb5f0054f2b1df789b39ca89b6ff9', '570e7b2abdd848b95f2f578043fc23bd6f6fd24d')).not_to be_allowed
expect(access.push_rule_check(user, project, 'refs/heads/master', '6f6d7e7ed97bb5f0054f2b1df789b39ca89b6ff9', '570e7b2abdd848b95f2f578043fc23bd6f6fd24d')).not_to be_allowed
end
it 'returns true if committer is a gitlab member' do
create(:user, email: 'dmitriy.zaporozhets@gmail.com')
expect(access.git_hook_check(user, project, 'refs/heads/master', '6f6d7e7ed97bb5f0054f2b1df789b39ca89b6ff9', '570e7b2abdd848b95f2f578043fc23bd6f6fd24d')).to be_allowed
expect(access.push_rule_check(user, project, 'refs/heads/master', '6f6d7e7ed97bb5f0054f2b1df789b39ca89b6ff9', '570e7b2abdd848b95f2f578043fc23bd6f6fd24d')).to be_allowed
end
end
describe "file names check" do
it 'returns false when filename is prohibited' do
project.create_git_hook
project.git_hook.update(file_name_regex: "jpg$")
expect(access.git_hook_check(user, project, 'refs/heads/master', '913c66a37b4a45b9769037c55c2d238bd0942d2e', '33f3729a45c02fc67d00adb1b8bca394b0e761d9')).not_to be_allowed
project.create_push_rule
project.push_rule.update(file_name_regex: "jpg$")
expect(access.push_rule_check(user, project, 'refs/heads/master', '913c66a37b4a45b9769037c55c2d238bd0942d2e', '33f3729a45c02fc67d00adb1b8bca394b0e761d9')).not_to be_allowed
end
it 'returns true if file name is allowed' do
project.create_git_hook
project.git_hook.update(file_name_regex: "exe$")
expect(access.git_hook_check(user, project, 'refs/heads/master', '913c66a37b4a45b9769037c55c2d238bd0942d2e', '33f3729a45c02fc67d00adb1b8bca394b0e761d9')).to be_allowed
project.create_push_rule
project.push_rule.update(file_name_regex: "exe$")
expect(access.push_rule_check(user, project, 'refs/heads/master', '913c66a37b4a45b9769037c55c2d238bd0942d2e', '33f3729a45c02fc67d00adb1b8bca394b0e761d9')).to be_allowed
end
end
......@@ -456,22 +456,22 @@ describe Gitlab::GitAccess, lib: true do
end
it "returns false when size is too large" do
project.create_git_hook
project.git_hook.update(max_file_size: 1)
expect(access.git_hook_check(user, project, 'refs/heads/master', 'cfe32cf61b73a0d5e9f13e774abde7ff789b1660', '913c66a37b4a45b9769037c55c2d238bd0942d2e')).not_to be_allowed
project.create_push_rule
project.push_rule.update(max_file_size: 1)
expect(access.push_rule_check(user, project, 'refs/heads/master', 'cfe32cf61b73a0d5e9f13e774abde7ff789b1660', '913c66a37b4a45b9769037c55c2d238bd0942d2e')).not_to be_allowed
end
it "returns true when size is allowed" do
project.create_git_hook
project.git_hook.update(max_file_size: 2)
expect(access.git_hook_check(user, project, 'refs/heads/master', 'cfe32cf61b73a0d5e9f13e774abde7ff789b1660', '913c66a37b4a45b9769037c55c2d238bd0942d2e')).to be_allowed
project.create_push_rule
project.push_rule.update(max_file_size: 2)
expect(access.push_rule_check(user, project, 'refs/heads/master', 'cfe32cf61b73a0d5e9f13e774abde7ff789b1660', '913c66a37b4a45b9769037c55c2d238bd0942d2e')).to be_allowed
end
it "returns true when size is nil" do
allow_any_instance_of(Gitlab::Git::Blob).to receive(:size).and_return(nil)
project.create_git_hook
project.git_hook.update(max_file_size: 2)
expect(access.git_hook_check(user, project, 'refs/heads/master', 'cfe32cf61b73a0d5e9f13e774abde7ff789b1660', '913c66a37b4a45b9769037c55c2d238bd0942d2e')).to be_allowed
project.create_push_rule
project.push_rule.update(max_file_size: 2)
expect(access.push_rule_check(user, project, 'refs/heads/master', 'cfe32cf61b73a0d5e9f13e774abde7ff789b1660', '913c66a37b4a45b9769037c55c2d238bd0942d2e')).to be_allowed
end
end
end
......
require 'spec_helper'
describe GitHook do
describe PushRule do
describe "Associations" do
it { should belong_to(:project) }
end
......
require 'spec_helper'
describe API::API, 'ProjectGitHook', api: true do
describe API::API, 'ProjectPushRule', api: true do
include ApiHelpers
let(:user) { create(:user) }
let(:user3) { create(:user) }
......@@ -11,14 +11,14 @@ describe API::API, 'ProjectGitHook', api: true do
project.team << [user3, :developer]
end
describe "GET /projects/:id/git_hook" do
describe "GET /projects/:id/push_rule" do
before do
create(:git_hook, project: project)
create(:push_rule, project: project)
end
context "authorized user" do
it "should return project git hook" do
get api("/projects/#{project.id}/git_hook", user)
it "should return project push rule" do
get api("/projects/#{project.id}/push_rule", user)
expect(response.status).to eq(200)
expect(json_response).to be_an Hash
......@@ -27,17 +27,17 @@ describe API::API, 'ProjectGitHook', api: true do
end
context "unauthorized user" do
it "should not access project git hooks" do
get api("/projects/#{project.id}/git_hook", user3)
it "should not access project push rule" do
get api("/projects/#{project.id}/push_rule", user3)
expect(response.status).to eq(403)
end
end
end
describe "POST /projects/:id/git_hook" do
describe "POST /projects/:id/push_rule" do
context "authorized user" do
it "should add git hook to project" do
post api("/projects/#{project.id}/git_hook", user),
it "should add push rule to project" do
post api("/projects/#{project.id}/push_rule", user),
deny_delete_tag: true
expect(response.status).to eq(201)
......@@ -48,35 +48,35 @@ describe API::API, 'ProjectGitHook', api: true do
end
context "unauthorized user" do
it "should not add git hook to project" do
post api("/projects/#{project.id}/git_hook", user3),
it "should not add push rule to project" do
post api("/projects/#{project.id}/push_rule", user3),
deny_delete_tag: true
expect(response.status).to eq(403)
end
end
end
describe "POST /projects/:id/git_hook" do
describe "POST /projects/:id/push_rule" do
before do
create(:git_hook, project: project)
create(:push_rule, project: project)
end
context "with existing git hook" do
it "should not add git hook to project" do
post api("/projects/#{project.id}/git_hook", user),
context "with existing push rule" do
it "should not add push rule to project" do
post api("/projects/#{project.id}/push_rule", user),
deny_delete_tag: true
expect(response.status).to eq(422)
end
end
end
describe "PUT /projects/:id/git_hook" do
describe "PUT /projects/:id/push_rule" do
before do
create(:git_hook, project: project)
create(:push_rule, project: project)
end
it "should update an existing project git hook" do
put api("/projects/#{project.id}/git_hook", user),
it "should update an existing project push rule" do
put api("/projects/#{project.id}/push_rule", user),
deny_delete_tag: false, commit_message_regex: 'Fixes \d+\..*'
expect(response.status).to eq(200)
......@@ -85,28 +85,28 @@ describe API::API, 'ProjectGitHook', api: true do
end
end
describe "PUT /projects/:id/git_hook" do
it "should error on non existing project git hook" do
put api("/projects/#{project.id}/git_hook", user),
describe "PUT /projects/:id/push_rule" do
it "should error on non existing project push rule" do
put api("/projects/#{project.id}/push_rule", user),
deny_delete_tag: false, commit_message_regex: 'Fixes \d+\..*'
expect(response.status).to eq(404)
end
it "should not update git hook for unauthorized user" do
post api("/projects/#{project.id}/git_hook", user3),
it "should not update push rule for unauthorized user" do
post api("/projects/#{project.id}/push_rule", user3),
deny_delete_tag: true
expect(response.status).to eq(403)
end
end
describe "DELETE /projects/:id/git_hook" do
describe "DELETE /projects/:id/push_rule" do
before do
create(:git_hook, project: project)
create(:push_rule, project: project)
end
context "authorized user" do
it "should delete git hook from project" do
delete api("/projects/#{project.id}/git_hook", user)
it "should delete push rule from project" do
delete api("/projects/#{project.id}/push_rule", user)
expect(response.status).to eq(200)
expect(json_response).to be_an Hash
......@@ -115,16 +115,16 @@ describe API::API, 'ProjectGitHook', api: true do
context "unauthorized user" do
it "should return a 403 error" do
delete api("/projects/#{project.id}/git_hook", user3)
delete api("/projects/#{project.id}/push_rule", user3)
expect(response.status).to eq(403)
end
end
end
describe "DELETE /projects/:id/git_hook" do
context "for non existing git hook" do
it "should delete git hook from project" do
delete api("/projects/#{project.id}/git_hook", user)
describe "DELETE /projects/:id/push_rule" do
context "for non existing push rule" do
it "should delete push rule from project" do
delete api("/projects/#{project.id}/push_rule", user)
expect(response.status).to eq(404)
expect(json_response).to be_an Hash
......@@ -132,7 +132,7 @@ describe API::API, 'ProjectGitHook', api: true do
end
it "should return a 403 error if not authorized" do
delete api("/projects/#{project.id}/git_hook", user3)
delete api("/projects/#{project.id}/push_rule", user3)
expect(response.status).to eq(403)
end
end
......
......@@ -75,7 +75,7 @@ describe 'Git HTTP requests', lib: true do
context "with correct credentials" do
let(:env) { { user: user.username, password: user.password } }
it "uploads get status 200 (because Git hooks do the real check)" do
it "uploads get status 200 (because Push rules do the real check)" do
upload(path, env) do |response|
expect(response).to have_http_status(200)
end
......@@ -324,7 +324,7 @@ describe 'Git HTTP requests', lib: true do
end
end
it "uploads get status 200 (because Git hooks do the real check)" do
it "uploads get status 200 (because Push rules do the real check)" do
upload(path, user: user.username, password: user.password) do |response|
expect(response).to have_http_status(200)
end
......
......@@ -87,7 +87,7 @@ describe MergeRequests::MergeService, services: true do
context 'commit message validation' do
before do
allow(project).to receive(:git_hook) { build(:git_hook, commit_message_regex: 'unmatched pattern .*') }
allow(project).to receive(:push_rule) { build(:push_rule, commit_message_regex: 'unmatched pattern .*') }
end
it 'returns false and saves error when invalid' do
......@@ -98,7 +98,7 @@ describe MergeRequests::MergeService, services: true do
context 'authors email validation' do
before do
allow(project).to receive(:git_hook) { build(:git_hook, author_email_regex: '.*@unmatchedemaildomain.com') }
allow(project).to receive(:push_rule) { build(:push_rule, author_email_regex: '.*@unmatchedemaildomain.com') }
end
it 'returns false and saves error when invalid' do
......
......@@ -129,13 +129,13 @@ describe Projects::CreateService, services: true do
context "git hook sample" do
before do
@git_hook_sample = create :git_hook_sample
@push_rule_sample = create :push_rule_sample
end
it "creates git hook from sample" do
git_hook = create_project(@user, @opts).git_hook
push_rule = create_project(@user, @opts).push_rule
[:force_push_regex, :deny_delete_tag, :delete_branch_regex, :commit_message_regex].each do |attr_name|
expect(git_hook.send(attr_name)).to eq @git_hook_sample.send(attr_name)
expect(push_rule.send(attr_name)).to eq @push_rule_sample.send(attr_name)
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